diff --git a/package.json b/package.json
index 9b4eb8dcc..1f2668215 100644
--- a/package.json
+++ b/package.json
@@ -29,26 +29,26 @@
"@next/mdx": "^15.1.3",
"@number-flow/react": "^0.4.2",
"@prisma/client": "6.4.0",
- "@radix-ui/react-accordion": "^1.2.1",
- "@radix-ui/react-alert-dialog": "^1.1.2",
- "@radix-ui/react-avatar": "^1.1.1",
- "@radix-ui/react-checkbox": "^1.1.1",
- "@radix-ui/react-collapsible": "^1.1.1",
- "@radix-ui/react-dialog": "^1.1.2",
- "@radix-ui/react-dropdown-menu": "^2.1.1",
+ "@radix-ui/react-accordion": "^1.2.3",
+ "@radix-ui/react-alert-dialog": "^1.1.6",
+ "@radix-ui/react-avatar": "^1.1.3",
+ "@radix-ui/react-checkbox": "^1.1.4",
+ "@radix-ui/react-collapsible": "^1.1.3",
+ "@radix-ui/react-dialog": "^1.1.6",
+ "@radix-ui/react-dropdown-menu": "^2.1.6",
"@radix-ui/react-hover-card": "1.1.6",
"@radix-ui/react-icons": "^1.3.2",
- "@radix-ui/react-label": "^2.1.0",
- "@radix-ui/react-navigation-menu": "^1.2.1",
- "@radix-ui/react-popover": "^1.1.1",
- "@radix-ui/react-progress": "^1.1.0",
- "@radix-ui/react-scroll-area": "^1.2.2",
- "@radix-ui/react-select": "^2.1.2",
- "@radix-ui/react-separator": "^1.1.0",
+ "@radix-ui/react-label": "^2.1.2",
+ "@radix-ui/react-navigation-menu": "^1.2.5",
+ "@radix-ui/react-popover": "^1.1.6",
+ "@radix-ui/react-progress": "^1.1.2",
+ "@radix-ui/react-scroll-area": "^1.2.3",
+ "@radix-ui/react-select": "^2.1.6",
+ "@radix-ui/react-separator": "^1.1.2",
"@radix-ui/react-slot": "^1.1.2",
- "@radix-ui/react-switch": "^1.1.1",
- "@radix-ui/react-tabs": "^1.1.2",
- "@radix-ui/react-tooltip": "^1.1.3",
+ "@radix-ui/react-switch": "^1.1.3",
+ "@radix-ui/react-tabs": "^1.1.3",
+ "@radix-ui/react-tooltip": "^1.1.8",
"@react-email/components": "0.0.31",
"@stripe/react-stripe-js": "^2.8.1",
"@stripe/stripe-js": "^4.8.0",
@@ -76,7 +76,7 @@
"framer-motion": "^11.18.1",
"lodash": "^4.17.21",
"lowlight": "^3.1.0",
- "lucide-react": "^0.439.0",
+ "lucide-react": "^0.477.0",
"mini-svg-data-uri": "^1.4.4",
"motion": "^11.12.0",
"nanoid": "^5.0.9",
@@ -96,7 +96,7 @@
"react-intersection-observer": "9.15.1",
"react-markdown": "^9.0.3",
"react-timer-hook": "^3.0.7",
- "recharts": "^2.13.0-alpha.5",
+ "recharts": "^2.15.1",
"rehype-autolink-headings": "^7.1.0",
"rehype-pretty-code": "^0.14.0",
"rehype-slug": "^6.0.0",
@@ -105,8 +105,7 @@
"shiki": "^1.24.4",
"sonner": "^1.5.0",
"stripe": "^17.2.1",
- "tailwind-container-break-out": "^2.0.9",
- "tailwind-merge": "^2.6.0",
+ "tailwind-merge": "^3.0.2",
"tailwindcss-animate": "^1.0.7",
"uniqid": "^5.4.0",
"unist-util-visit": "^5.0.0",
@@ -117,6 +116,7 @@
"@content-collections/core": "^0.8.0",
"@content-collections/mdx": "^0.2.0",
"@content-collections/next": "^0.2.4",
+ "@tailwindcss/postcss": "4.0.9",
"@types/dompurify": "^3.0.5",
"@types/lodash": "^4.17.13",
"@types/node": "^20.17.11",
@@ -125,14 +125,13 @@
"@types/uniqid": "^5.3.4",
"eslint": "^8",
"eslint-config-next": "14.2.9",
- "fluid-tailwind": "1.0.4",
"knip": "^5.41.1",
"postcss": "^8.4.47",
"postcss-preset-mantine": "^1.17.0",
"postcss-simple-vars": "^7.0.1",
"prisma": "6.4.0",
"react-email": "3.0.4",
- "tailwindcss": "^3.4.1",
+ "tailwindcss": "^4.0.9",
"turbo": "2.4.2",
"typescript": "^5.7.2"
}
diff --git a/postcss.config.mjs b/postcss.config.mjs
index 7c945caa7..e4b1ccf2d 100644
--- a/postcss.config.mjs
+++ b/postcss.config.mjs
@@ -1,7 +1,7 @@
/** @type {import('postcss-load-config').Config} */
const config = {
plugins: {
- tailwindcss: {},
+ '@tailwindcss/postcss': {},
'postcss-preset-mantine': {},
'postcss-simple-vars': {
variables: {
diff --git a/src/actions/ai/questions/question-help.ts b/src/actions/ai/questions/question-help.ts
index 335e8283e..d8d42ff0b 100644
--- a/src/actions/ai/questions/question-help.ts
+++ b/src/actions/ai/questions/question-help.ts
@@ -40,7 +40,7 @@ export const generateQuestionHelp = async (
if (!user) {
console.error('User not found');
return {
- object: null,
+ object: 'User not found',
content: null,
tokensUsed: 0,
};
@@ -52,7 +52,7 @@ export const generateQuestionHelp = async (
if (!hasTokens) {
console.error('User does not have enough tokens');
return {
- object: null,
+ object: 'User does not have enough tokens',
content: null,
tokensUsed: 0,
};
@@ -94,7 +94,7 @@ export const generateQuestionHelp = async (
if (!question) {
console.error('No question found');
return {
- object: null,
+ object: 'No question found',
content: null,
tokensUsed: 0,
};
@@ -112,7 +112,7 @@ export const generateQuestionHelp = async (
const deducted = await deductUserTokens(user);
if (!deducted) {
return {
- object: null,
+ object: 'Cannot deduct tokens',
content: null,
tokensUsed: 0,
};
@@ -179,17 +179,5 @@ export const generateQuestionHelp = async (
}
})();
- // Determine token count for the response
- const tokensUsed =
- questionType === 'regular'
- ? user.aiQuestionHelpTokens
- ? user.aiQuestionHelpTokens - 1
- : 0
- : Number.POSITIVE_INFINITY;
-
- return {
- object: stream.value,
- content: null,
- tokensUsed: tokensUsed,
- };
+ return { object: stream.value };
};
diff --git a/src/app/(app)/(default_layout)/(roadmaps)/personalized-roadmaps/page.tsx b/src/app/(app)/(default_layout)/(roadmaps)/personalized-roadmaps/page.tsx
index 72ee2964b..2ccc2b427 100644
--- a/src/app/(app)/(default_layout)/(roadmaps)/personalized-roadmaps/page.tsx
+++ b/src/app/(app)/(default_layout)/(roadmaps)/personalized-roadmaps/page.tsx
@@ -118,7 +118,7 @@ export default async function RoadmapPage() {
hasAnsweredEnoughQuestions={hasAnsweredEnoughQuestions}
answeredQuestionsCount={answeredQuestionsCount}
/>
-
+
Enjoying Roadmaps?
diff --git a/src/app/(app)/(default_layout)/(roadmaps)/roadmaps/page.tsx b/src/app/(app)/(default_layout)/(roadmaps)/roadmaps/page.tsx
index 024c17b77..21c8e172d 100644
--- a/src/app/(app)/(default_layout)/(roadmaps)/roadmaps/page.tsx
+++ b/src/app/(app)/(default_layout)/(roadmaps)/roadmaps/page.tsx
@@ -129,8 +129,8 @@ export default async function ExploreQuestionsPage() {
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
-
-
+
+
{Object.entries(studyPathsByCategory).map(([category, paths]) => (
@@ -155,7 +155,7 @@ export default async function ExploreQuestionsPage() {
missionsPromise={missionsPromise}
userMissionRecordsPromise={userMissionRecordsPromise}
/>
-
+
Suggest a roadmap
diff --git a/src/app/(app)/dashboard/page.client.tsx b/src/app/(app)/dashboard/page.client.tsx
index 5b1f10dbb..a0e4c87a5 100644
--- a/src/app/(app)/dashboard/page.client.tsx
+++ b/src/app/(app)/dashboard/page.client.tsx
@@ -95,7 +95,7 @@ export default function ClientPage({
return (
<>
);
diff --git a/src/app/(marketing)/changelog/page.tsx b/src/app/(marketing)/changelog/page.tsx
index e1666b151..3451a516c 100644
--- a/src/app/(marketing)/changelog/page.tsx
+++ b/src/app/(marketing)/changelog/page.tsx
@@ -10,7 +10,7 @@ export default function ChangelogPage() {
Changelog
@@ -32,7 +32,7 @@ export default function ChangelogPage() {
'absolute inset-0 pt-44 [mask-image:radial-gradient(400px_circle_at_center,white,transparent)]'
)}
/>
-
+
diff --git a/src/app/(marketing)/features/leaderboard/page.tsx b/src/app/(marketing)/features/leaderboard/page.tsx
index 06b274700..2f36c50ec 100644
--- a/src/app/(marketing)/features/leaderboard/page.tsx
+++ b/src/app/(marketing)/features/leaderboard/page.tsx
@@ -75,7 +75,7 @@ const faqs = [
answer: (
<>
Yes, TechBlitz is completely open source! Explore our source code on{' '}
-
+
GitHub
{' '}
and join the growing community of developers contributing to our platform.
@@ -87,7 +87,7 @@ const faqs = [
answer: (
<>
You can sign up for a free account{' '}
-
+
here
! We're excited to see you on the leaderboard!
@@ -116,7 +116,7 @@ const featureShowcaseItems: MarketingContentGridProps[] = [
<>
Create custom learning paths tailored to your goals. Whether you're a complete beginner or
advancing your skills, find the perfect route for your journey. Learn more{' '}
-
+
here
.
@@ -140,7 +140,7 @@ const featureShowcaseItems: MarketingContentGridProps[] = [
<>
Keep track of your coding progress with our coding analytics. See your progression, create
custom coding challenges, and more. Learn more{' '}
-
+
here
.
@@ -154,7 +154,7 @@ const featureShowcaseItems: MarketingContentGridProps[] = [
<>
Bite-sized coding challenges to keep you engaged and learning. Perfect for busy developers
who want to stay sharp and improve their skills. You can learn more{' '}
-
+
here
.
diff --git a/src/app/(marketing)/features/roadmap/page.tsx b/src/app/(marketing)/features/roadmap/page.tsx
index 44dab711d..aaac6fca7 100644
--- a/src/app/(marketing)/features/roadmap/page.tsx
+++ b/src/app/(marketing)/features/roadmap/page.tsx
@@ -46,7 +46,7 @@ const faqs = [
<>
To access the roadmaps on techblitz, you need to have a premium account. You can sign up for
a premium account{' '}
-
+
here
.
@@ -66,7 +66,7 @@ const faqs = [
GitHub
{' '}
diff --git a/src/app/(marketing)/layout.tsx b/src/app/(marketing)/layout.tsx
index 660a95ae6..dcd09196b 100644
--- a/src/app/(marketing)/layout.tsx
+++ b/src/app/(marketing)/layout.tsx
@@ -35,7 +35,7 @@ export default function Layout({
-
+
diff --git a/src/app/(marketing)/pricing/page.tsx b/src/app/(marketing)/pricing/page.tsx
index 3455ecb5e..52ecb53ea 100644
--- a/src/app/(marketing)/pricing/page.tsx
+++ b/src/app/(marketing)/pricing/page.tsx
@@ -198,16 +198,16 @@ export default async function PricingPage() {
/>
-
+
Pricing
-
+
{/** Plans that don't the bank */}
Learning to code has
-
+
never{' '}
{' '}
been easier
diff --git a/src/app/(no_nav)/(auth)/signup/page.tsx b/src/app/(no_nav)/(auth)/signup/page.tsx
index cd8d2c857..2c11a76b8 100644
--- a/src/app/(no_nav)/(auth)/signup/page.tsx
+++ b/src/app/(no_nav)/(auth)/signup/page.tsx
@@ -101,7 +101,7 @@ export default async function SignupPage() {
-
+
Create your TechBlitz account
@@ -143,8 +143,8 @@ export default async function SignupPage() {
isFakeCard={true}
/>
))}
-
-
+
+
diff --git a/src/app/(no_nav)/layout.tsx b/src/app/(no_nav)/layout.tsx
index 5c1a22745..f71c027c0 100644
--- a/src/app/(no_nav)/layout.tsx
+++ b/src/app/(no_nav)/layout.tsx
@@ -16,7 +16,7 @@ export default function Layout({
suppressHydrationWarning
>
{/* Scrollable content */}
- {children}
+ {children}