Skip to content

Commit b421a25

Browse files
author
Rajat
committed
Next 16.2 + next-themes's alternative (vibe-coded)
1 parent 4f9542b commit b421a25

File tree

19 files changed

+1916
-691
lines changed

19 files changed

+1916
-691
lines changed

apps/web/app/(with-contexts)/layout-with-context.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import {
2020
import { Toaster, useToast } from "@courselit/components-library";
2121
import { TOAST_TITLE_ERROR } from "@ui-config/strings";
2222
import { Theme } from "@courselit/page-models";
23-
import { ThemeProvider as NextThemesProvider } from "@components/next-theme-provider";
23+
import { ThemeProvider } from "@components/next-theme-provider";
2424
import { defaultState } from "@components/default-state";
2525
import { getUserProfile } from "./helpers";
2626
import { auth } from "@/auth";
@@ -92,7 +92,7 @@ function LayoutContent({
9292
<SiteInfoContext.Provider value={siteinfo}>
9393
<ThemeContext.Provider value={{ theme, setTheme }}>
9494
<ServerConfigContext.Provider value={config}>
95-
<NextThemesProvider
95+
<ThemeProvider
9696
attribute="class"
9797
defaultTheme="system"
9898
enableSystem
@@ -105,7 +105,7 @@ function LayoutContent({
105105
{children}
106106
</Suspense>
107107
</ProfileContext.Provider>
108-
</NextThemesProvider>
108+
</ThemeProvider>
109109
</ServerConfigContext.Provider>
110110
</ThemeContext.Provider>
111111
</SiteInfoContext.Provider>

apps/web/app/layout.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { headers } from "next/headers";
88
import { getSiteInfo, getFullSiteSetup } from "@ui-lib/utils";
99
import { getAddressFromHeaders } from "@/app/actions";
1010
import * as fonts from "@/lib/fonts";
11+
import { getThemeBootstrapScript } from "@courselit/theme";
1112
import { generateThemeStyles } from "@/lib/theme-styles";
1213
import { SITE_SETTINGS_DEFAULT_TITLE } from "@ui-config/strings";
1314

@@ -57,6 +58,12 @@ export default async function RootLayout({ children }: RootLayoutProps) {
5758
return (
5859
<html suppressHydrationWarning>
5960
<head>
61+
<script
62+
suppressHydrationWarning
63+
dangerouslySetInnerHTML={{
64+
__html: getThemeBootstrapScript(),
65+
}}
66+
/>
6067
<style>{themeStyles}</style>
6168
</head>
6269
<body

apps/web/components/admin/next-theme-switcher.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { Button } from "@components/ui/button";
22
import { Sun, Moon } from "lucide-react";
3-
import { useTheme } from "next-themes";
43
import {
54
Tooltip,
65
TooltipContent,
76
TooltipTrigger,
87
} from "@components/ui/tooltip";
98
import { BTN_TOGGLE_THEME } from "@ui-config/strings";
9+
import { useTheme } from "@components/next-theme-provider";
1010

1111
export default function NextThemeSwitcher({
1212
variant = "outline",

apps/web/components/admin/page-editor/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ import {
5252
import { ThemeWithDraftState } from "./theme-editor/theme-with-draft-state";
5353
import useThemes from "./use-themes";
5454
import NextThemeSwitcher from "../next-theme-switcher";
55-
import { useTheme } from "next-themes";
55+
import { useTheme } from "@/components/next-theme-provider";
5656

5757
const EditWidget = dynamic(() => import("./edit-widget"));
5858
const AddWidget = dynamic(() => import("./add-widget"));
Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,3 @@
11
"use client";
22

3-
import * as React from "react";
4-
import { ThemeProvider as NextThemesProvider } from "next-themes";
5-
6-
export function ThemeProvider({
7-
children,
8-
...props
9-
}: React.ComponentProps<typeof NextThemesProvider>) {
10-
return <NextThemesProvider {...props}>{children}</NextThemesProvider>;
11-
}
3+
export { ThemeProvider, useTheme } from "@courselit/theme/react";

apps/web/components/public/base-layout/template/widget-by-name.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import React, { useState, useEffect } from "react";
22
import widgets from "@/ui-config/widgets";
33
import { COMPONENT_MISSING_SUFFIX } from "@/ui-config/strings";
44
import WidgetErrorBoundary from "@/components/public/base-layout/template/widget-error-boundary";
5-
import { useTheme } from "next-themes";
65
import { WidgetDefaultSettings, WidgetProps } from "@courselit/common-models";
6+
import { useTheme } from "@/components/next-theme-provider";
77

88
const WidgetByName = ({
99
id,
@@ -17,8 +17,7 @@ const WidgetByName = ({
1717
const [mounted, setMounted] = useState(false);
1818

1919
useEffect(() => {
20-
// This is the recommended pattern from next-themes to avoid hydration mismatch.
21-
// The effect intentionally runs once to trigger a re-render with the correct theme.
20+
// Wait until the client has mounted before depending on the resolved theme.
2221
// eslint-disable-next-line react-hooks/set-state-in-effect
2322
setMounted(true);
2423
}, []);

apps/web/components/ui/sonner.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import {
77
OctagonX,
88
TriangleAlert,
99
} from "lucide-react";
10-
import { useTheme } from "next-themes";
1110
import { Toaster as Sonner } from "sonner";
11+
import { useTheme } from "@/components/next-theme-provider";
1212

1313
type ToasterProps = React.ComponentProps<typeof Sonner>;
1414

apps/web/lib/theme-provider.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { getThemeBootstrapScript } from "@courselit/theme";

apps/web/package.json

Lines changed: 134 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -1,137 +1,137 @@
11
{
2-
"name": "@courselit/web",
3-
"version": "0.73.8",
4-
"private": true,
5-
"scripts": {
6-
"dev": "next dev",
7-
"build": "next build",
8-
"start": "next start",
9-
"prettier": "prettier --write **/*.ts"
10-
},
11-
"browserslist": {
12-
"production": [
13-
"chrome >= 109",
14-
"edge >= 109",
15-
"firefox >= 109",
16-
"safari >= 15.4",
17-
"ios_saf >= 15.4",
18-
"not dead"
19-
],
20-
"development": [
21-
"last 1 chrome version",
22-
"last 1 firefox version",
23-
"last 1 safari version"
24-
]
25-
},
26-
"dependencies": {
27-
"@better-auth/sso": "^1.4.6",
28-
"@courselit/common-logic": "workspace:^",
29-
"@courselit/common-models": "workspace:^",
30-
"@courselit/components-library": "workspace:^",
31-
"@courselit/email-editor": "workspace:^",
32-
"@courselit/icons": "workspace:^",
33-
"@courselit/orm-models": "workspace:^",
34-
"@courselit/page-blocks": "workspace:^",
35-
"@courselit/page-models": "workspace:^",
36-
"@courselit/page-primitives": "workspace:^",
37-
"@courselit/text-editor": "workspace:^",
38-
"@courselit/utils": "workspace:^",
39-
"@dnd-kit/core": "^6.3.1",
40-
"@dnd-kit/sortable": "^8.0.0",
41-
"@dnd-kit/utilities": "^3.2.2",
42-
"@hookform/resolvers": "^3.9.1",
43-
"@radix-ui/react-alert-dialog": "^1.1.11",
44-
"@radix-ui/react-avatar": "^1.1.3",
45-
"@radix-ui/react-checkbox": "^1.1.4",
46-
"@radix-ui/react-collapsible": "^1.1.3",
47-
"@radix-ui/react-compose-refs": "^1.1.1",
48-
"@radix-ui/react-dialog": "^1.1.6",
49-
"@radix-ui/react-dropdown-menu": "^2.1.6",
50-
"@radix-ui/react-label": "^2.1.4",
51-
"@radix-ui/react-popover": "^1.1.6",
52-
"@radix-ui/react-progress": "^1.1.7",
53-
"@radix-ui/react-radio-group": "^1.2.3",
54-
"@radix-ui/react-scroll-area": "^1.2.3",
55-
"@radix-ui/react-select": "^2.1.6",
56-
"@radix-ui/react-separator": "^1.1.4",
57-
"@radix-ui/react-slot": "^1.2.3",
58-
"@radix-ui/react-switch": "^1.1.3",
59-
"@radix-ui/react-tabs": "^1.1.3",
60-
"@radix-ui/react-toast": "^1.2.6",
61-
"@radix-ui/react-toggle": "^1.1.6",
62-
"@radix-ui/react-toggle-group": "^1.1.7",
63-
"@radix-ui/react-tooltip": "^1.1.8",
64-
"@radix-ui/react-visually-hidden": "^1.1.0",
65-
"@stripe/stripe-js": "^5.4.0",
66-
"@types/base-64": "^1.0.0",
67-
"adm-zip": "^0.5.16",
68-
"archiver": "^5.3.1",
69-
"aws4": "^1.13.2",
70-
"base-64": "^1.0.0",
71-
"better-auth": "^1.4.1",
72-
"chart.js": "^4.4.7",
73-
"class-variance-authority": "^0.7.0",
74-
"clsx": "^2.1.1",
75-
"color-convert": "^3.1.0",
76-
"cookie": "^0.4.2",
77-
"date-fns": "^4.1.0",
78-
"graphql": "^16.10.0",
79-
"graphql-type-json": "^0.3.2",
80-
"jsdom": "^26.1.0",
81-
"lodash.debounce": "^4.0.8",
82-
"lucide-react": "^0.553.0",
83-
"medialit": "0.2.0",
84-
"mongodb": "^6.15.0",
85-
"mongoose": "^8.13.1",
86-
"next": "^16.0.10",
87-
"next-themes": "^0.4.6",
88-
"nodemailer": "^6.7.2",
89-
"pug": "^3.0.2",
90-
"razorpay": "^2.9.4",
91-
"react": "19.2.0",
92-
"react-chartjs-2": "^5.3.0",
93-
"react-csv": "^2.2.2",
94-
"react-dom": "19.2.0",
95-
"react-hook-form": "^7.54.1",
96-
"recharts": "^2.15.1",
97-
"remirror": "^3.0.1",
98-
"sharp": "^0.33.2",
99-
"slugify": "^1.6.5",
100-
"sonner": "^2.0.7",
101-
"stripe": "^17.5.0",
102-
"tailwind-merge": "^2.5.4",
103-
"tailwindcss-animate": "^1.0.7",
104-
"xml2js": "^0.6.2",
105-
"zod": "^3.24.1"
106-
},
107-
"devDependencies": {
108-
"@eslint/eslintrc": "^3.3.1",
109-
"@shelf/jest-mongodb": "^5.2.2",
110-
"@types/adm-zip": "^0.5.7",
111-
"@types/bcryptjs": "^2.4.2",
112-
"@types/cookie": "^0.4.1",
113-
"@types/mongodb": "^4.0.7",
114-
"@types/node": "17.0.21",
115-
"@types/nodemailer": "^6.4.4",
116-
"@types/pug": "^2.0.6",
117-
"@types/react": "19.2.4",
118-
"@types/xml2js": "^0.4.14",
119-
"eslint": "^9.12.0",
120-
"eslint-config-next": "16.0.3",
121-
"eslint-config-prettier": "^9.0.0",
122-
"identity-obj-proxy": "^3.0.0",
123-
"mongodb-memory-server": "^10.1.4",
124-
"postcss": "^8.4.27",
125-
"prettier": "^3.0.2",
126-
"tailwind-config": "workspace:^",
127-
"tailwindcss": "^3.4.1",
128-
"ts-jest": "^29.4.4",
129-
"tsconfig": "workspace:^",
130-
"typescript": "^5.6.2"
131-
},
132-
"pnpm": {
133-
"overrides": {
134-
"@types/react": "19.2.4"
2+
"name": "@courselit/web",
3+
"version": "0.73.8",
4+
"private": true,
5+
"scripts": {
6+
"dev": "next dev",
7+
"build": "next build",
8+
"start": "next start",
9+
"prettier": "prettier --write **/*.ts"
10+
},
11+
"browserslist": {
12+
"production": [
13+
"chrome >= 109",
14+
"edge >= 109",
15+
"firefox >= 109",
16+
"safari >= 15.4",
17+
"ios_saf >= 15.4",
18+
"not dead"
19+
],
20+
"development": [
21+
"last 1 chrome version",
22+
"last 1 firefox version",
23+
"last 1 safari version"
24+
]
25+
},
26+
"dependencies": {
27+
"@better-auth/sso": "^1.4.6",
28+
"@courselit/common-logic": "workspace:^",
29+
"@courselit/common-models": "workspace:^",
30+
"@courselit/components-library": "workspace:^",
31+
"@courselit/email-editor": "workspace:^",
32+
"@courselit/icons": "workspace:^",
33+
"@courselit/orm-models": "workspace:^",
34+
"@courselit/page-blocks": "workspace:^",
35+
"@courselit/page-models": "workspace:^",
36+
"@courselit/page-primitives": "workspace:^",
37+
"@courselit/theme": "workspace:^",
38+
"@courselit/text-editor": "workspace:^",
39+
"@courselit/utils": "workspace:^",
40+
"@dnd-kit/core": "^6.3.1",
41+
"@dnd-kit/sortable": "^8.0.0",
42+
"@dnd-kit/utilities": "^3.2.2",
43+
"@hookform/resolvers": "^3.9.1",
44+
"@radix-ui/react-alert-dialog": "^1.1.11",
45+
"@radix-ui/react-avatar": "^1.1.3",
46+
"@radix-ui/react-checkbox": "^1.1.4",
47+
"@radix-ui/react-collapsible": "^1.1.3",
48+
"@radix-ui/react-compose-refs": "^1.1.1",
49+
"@radix-ui/react-dialog": "^1.1.6",
50+
"@radix-ui/react-dropdown-menu": "^2.1.6",
51+
"@radix-ui/react-label": "^2.1.4",
52+
"@radix-ui/react-popover": "^1.1.6",
53+
"@radix-ui/react-progress": "^1.1.7",
54+
"@radix-ui/react-radio-group": "^1.2.3",
55+
"@radix-ui/react-scroll-area": "^1.2.3",
56+
"@radix-ui/react-select": "^2.1.6",
57+
"@radix-ui/react-separator": "^1.1.4",
58+
"@radix-ui/react-slot": "^1.2.3",
59+
"@radix-ui/react-switch": "^1.1.3",
60+
"@radix-ui/react-tabs": "^1.1.3",
61+
"@radix-ui/react-toast": "^1.2.6",
62+
"@radix-ui/react-toggle": "^1.1.6",
63+
"@radix-ui/react-toggle-group": "^1.1.7",
64+
"@radix-ui/react-tooltip": "^1.1.8",
65+
"@radix-ui/react-visually-hidden": "^1.1.0",
66+
"@stripe/stripe-js": "^5.4.0",
67+
"@types/base-64": "^1.0.0",
68+
"adm-zip": "^0.5.16",
69+
"archiver": "^5.3.1",
70+
"aws4": "^1.13.2",
71+
"base-64": "^1.0.0",
72+
"better-auth": "^1.4.1",
73+
"chart.js": "^4.4.7",
74+
"class-variance-authority": "^0.7.0",
75+
"clsx": "^2.1.1",
76+
"color-convert": "^3.1.0",
77+
"cookie": "^0.4.2",
78+
"date-fns": "^4.1.0",
79+
"graphql": "^16.10.0",
80+
"graphql-type-json": "^0.3.2",
81+
"jsdom": "^26.1.0",
82+
"lodash.debounce": "^4.0.8",
83+
"lucide-react": "^0.553.0",
84+
"medialit": "0.2.0",
85+
"mongodb": "^6.15.0",
86+
"mongoose": "^8.13.1",
87+
"next": "16.2.1",
88+
"nodemailer": "^6.7.2",
89+
"pug": "^3.0.2",
90+
"razorpay": "^2.9.4",
91+
"react": "19.2.4",
92+
"react-chartjs-2": "^5.3.0",
93+
"react-csv": "^2.2.2",
94+
"react-dom": "19.2.4",
95+
"react-hook-form": "^7.54.1",
96+
"recharts": "^2.15.1",
97+
"remirror": "^3.0.1",
98+
"sharp": "^0.33.2",
99+
"slugify": "^1.6.5",
100+
"sonner": "^2.0.7",
101+
"stripe": "^17.5.0",
102+
"tailwind-merge": "^2.5.4",
103+
"tailwindcss-animate": "^1.0.7",
104+
"xml2js": "^0.6.2",
105+
"zod": "^3.24.1"
106+
},
107+
"devDependencies": {
108+
"@eslint/eslintrc": "^3.3.1",
109+
"@shelf/jest-mongodb": "^5.2.2",
110+
"@types/adm-zip": "^0.5.7",
111+
"@types/bcryptjs": "^2.4.2",
112+
"@types/cookie": "^0.4.1",
113+
"@types/mongodb": "^4.0.7",
114+
"@types/node": "17.0.21",
115+
"@types/nodemailer": "^6.4.4",
116+
"@types/pug": "^2.0.6",
117+
"@types/react": "19.2.14",
118+
"@types/xml2js": "^0.4.14",
119+
"eslint": "^9.12.0",
120+
"eslint-config-next": "16.2.1",
121+
"eslint-config-prettier": "^9.0.0",
122+
"identity-obj-proxy": "^3.0.0",
123+
"mongodb-memory-server": "^10.1.4",
124+
"postcss": "^8.4.27",
125+
"prettier": "^3.0.2",
126+
"tailwind-config": "workspace:^",
127+
"tailwindcss": "^3.4.1",
128+
"ts-jest": "^29.4.4",
129+
"tsconfig": "workspace:^",
130+
"typescript": "^5.6.2"
131+
},
132+
"pnpm": {
133+
"overrides": {
134+
"@types/react": "19.2.14"
135+
}
135136
}
136-
}
137137
}

packages/theme/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules/
2+
3+
dist/

0 commit comments

Comments
 (0)