From 3dcaf41a4d93ec3d3a7026a7ba07c27f08303e2f Mon Sep 17 00:00:00 2001 From: Nico Date: Sat, 6 Jul 2024 22:42:11 +0200 Subject: [PATCH] feat: adds theming --- package-lock.json | 11 ++ package.json | 1 + public/locales/de/login.json | 3 + public/locales/en/login.json | 3 + src/app/[locale]/login/page.tsx | 23 ++++ src/app/[locale]/page.tsx | 124 +++++++++++++++++- src/app/providers.tsx | 9 +- .../theme-switcher/ThemeSwitcher.tsx | 24 ++++ tailwind.config.ts | 31 ++++- tsconfig.json | 5 +- 10 files changed, 228 insertions(+), 6 deletions(-) create mode 100644 public/locales/de/login.json create mode 100644 public/locales/en/login.json create mode 100644 src/app/[locale]/login/page.tsx create mode 100644 src/components/theme-switcher/ThemeSwitcher.tsx diff --git a/package-lock.json b/package-lock.json index d041691..958243d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "next": "14.2.4", "next-connect": "1.0.0", "next-i18n-router": "5.5.0", + "next-themes": "^0.3.0", "react": "18.3.1", "react-dom": "18.3.1", "react-i18next": "14.1.2", @@ -8337,6 +8338,16 @@ "negotiator": "^0.6.3" } }, + "node_modules/next-themes": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.3.0.tgz", + "integrity": "sha512-/QHIrsYpd6Kfk7xakK4svpDI5mmXP0gfvCoJdGpZQ2TOrQZmsW0QxjaiLn8wbIKjtm4BTSqLoix4lxYYOnLJ/w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8 || ^17 || ^18", + "react-dom": "^16.8 || ^17 || ^18" + } + }, "node_modules/next/node_modules/postcss": { "version": "8.4.31", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", diff --git a/package.json b/package.json index cda3b55..0445d45 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "next": "14.2.4", "next-connect": "1.0.0", "next-i18n-router": "5.5.0", + "next-themes": "^0.3.0", "react": "18.3.1", "react-dom": "18.3.1", "react-i18next": "14.1.2", diff --git a/public/locales/de/login.json b/public/locales/de/login.json new file mode 100644 index 0000000..5fda212 --- /dev/null +++ b/public/locales/de/login.json @@ -0,0 +1,3 @@ +{ + "login": "Anmelden" +} diff --git a/public/locales/en/login.json b/public/locales/en/login.json new file mode 100644 index 0000000..0554935 --- /dev/null +++ b/public/locales/en/login.json @@ -0,0 +1,3 @@ +{ + "login": "Login" +} diff --git a/src/app/[locale]/login/page.tsx b/src/app/[locale]/login/page.tsx new file mode 100644 index 0000000..c32b417 --- /dev/null +++ b/src/app/[locale]/login/page.tsx @@ -0,0 +1,23 @@ +import TranslationsProvider from '@/src/components/translation-provider/TranslationsProvider'; +import initTranslations from '@i18n'; +import { FunctionComponent } from 'react'; + +interface HomeProps { + params: { + locale: string; + }; +} + +const i18nNamespaces = ['login']; + +const Home: FunctionComponent = async ({ params: { locale } }) => { + const { t, resources } = await initTranslations(locale, i18nNamespaces); + + return ( + +

{t('login:login')}

+
+ ); +}; + +export default Home; diff --git a/src/app/[locale]/page.tsx b/src/app/[locale]/page.tsx index b9f9947..81fac6a 100644 --- a/src/app/[locale]/page.tsx +++ b/src/app/[locale]/page.tsx @@ -1,3 +1,4 @@ +import { ThemeSwitcher } from '@/src/components/theme-switcher/ThemeSwitcher'; import TranslationsProvider from '@/src/components/translation-provider/TranslationsProvider'; import { Button } from '@nextui-org/react'; import { FunctionComponent } from 'react'; @@ -15,8 +16,127 @@ const Home: FunctionComponent = async ({ params: { locale } }) => { const { t, resources } = await initTranslations(locale, i18nNamespaces); return ( - - + + +
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+
+ + + + + +
); }; diff --git a/src/app/providers.tsx b/src/app/providers.tsx index c80e3f1..903c244 100644 --- a/src/app/providers.tsx +++ b/src/app/providers.tsx @@ -1,8 +1,15 @@ import { NextUIProvider } from '@nextui-org/react'; +import { ThemeProvider } from 'next-themes'; import { FunctionComponent, PropsWithChildren } from 'react'; const Providers: FunctionComponent = ({ children }) => { - return {children}; + return ( + + + {children} + + + ); }; export default Providers; diff --git a/src/components/theme-switcher/ThemeSwitcher.tsx b/src/components/theme-switcher/ThemeSwitcher.tsx new file mode 100644 index 0000000..7a95f73 --- /dev/null +++ b/src/components/theme-switcher/ThemeSwitcher.tsx @@ -0,0 +1,24 @@ +'use client'; + +import { Button } from '@nextui-org/react'; +import { useTheme } from 'next-themes'; +import { useEffect, useState } from 'react'; + +export function ThemeSwitcher(): React.ReactNode { + const [mounted, setMounted] = useState(false); + const { theme, setTheme } = useTheme(); + + useEffect(() => { + setMounted(true); + }, []); + + if (!mounted) return null; + + return ( +
+ The current theme is: {theme} + + +
+ ); +} diff --git a/tailwind.config.ts b/tailwind.config.ts index 4400753..252d34f 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -12,6 +12,35 @@ const config: Config = { extend: {}, }, darkMode: 'class', - plugins: [nextui()], + plugins: [ + nextui({ + prefix: 'nextui', // prefix for themes variables + themes: { + light: { + colors: { + background: '#f6fefe', + foreground: '#021d1d', + primary: { + DEFAULT: '#0b7779', + foreground: '#021d1d', + }, + secondary: '#f269c0', + }, // light theme colors + }, + dark: { + colors: { + background: '#010909', + foreground: '#e2fdfd', + primary: { + DEFAULT: '#86f2f4', + foreground: '#021d1d', + }, + secondary: '#960d64', + }, // dark theme colors + }, + // ... custom themes + }, + }), + ], }; export default config; diff --git a/tsconfig.json b/tsconfig.json index 97e7b5a..d70d4b7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,9 +19,10 @@ ], "paths": { "@/*": ["./*"], - "@components/*": ["./src/components/*"] + "@components/*": ["./src/components/*"], + "@i18n": ["./src/app/i18n"] } }, "exclude": ["node_modules"], - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"] + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "i18n.config.ts"] }