├── pnpm-workspace.yaml ├── .eslintignore ├── .vscode ├── extensions.json └── settings.json ├── public ├── logo.png ├── og.png ├── favicon.ico ├── icon-192.png ├── icon-512.png ├── favicon-16x16.png ├── favicon-32x32.png ├── apple-touch-icon.png ├── icon-192-maskable.png └── icon-512-maskable.png ├── app ├── (auth) │ ├── login │ │ ├── layout.tsx │ │ └── page.tsx │ └── api │ │ └── auth │ │ └── [...nextauth] │ │ └── route.ts ├── page.tsx ├── layout.tsx └── globals.css ├── i18n ├── config.ts └── request.ts ├── postcss.config.mjs ├── lib ├── utils.ts ├── auth.ts └── metadata.ts ├── db ├── drizzle.ts └── schema.ts ├── drizzle.config.ts ├── .env.example ├── components ├── logo.tsx ├── theme-provider.tsx ├── tailwind-indicator.tsx ├── header │ ├── theme-switcher.tsx │ ├── sign-in-button.tsx │ ├── header.tsx │ ├── language-switcher.tsx │ └── user-dropdown.tsx ├── ui │ ├── label.tsx │ ├── input.tsx │ ├── toaster.tsx │ ├── button.tsx │ ├── card.tsx │ ├── dialog.tsx │ ├── form.tsx │ ├── toast.tsx │ ├── select.tsx │ └── dropdown-menu.tsx ├── auth │ ├── login-form-dialog.tsx │ └── login-form.tsx ├── hello-form.tsx └── footer.tsx ├── components.json ├── services └── locale.ts ├── actions └── hello-action.ts ├── Dockerfile ├── next.config.ts ├── biome.json ├── messages ├── zh.json └── en.json ├── .gitignore ├── config └── site.ts ├── tsconfig.json ├── package.json ├── README.zh-CN.md ├── README.md ├── hooks └── use-toast.ts └── pnpm-lock.yaml /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | onlyBuiltDependencies: 2 | - '@swc/core' 3 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | dist/* 2 | .cache 3 | public 4 | node_modules 5 | .prettierrc.mjs -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["biomejs.biome"] 3 | } 4 | -------------------------------------------------------------------------------- /public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Przeblysk/next-starter/HEAD/public/logo.png -------------------------------------------------------------------------------- /public/og.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Przeblysk/next-starter/HEAD/public/og.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Przeblysk/next-starter/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Przeblysk/next-starter/HEAD/public/icon-192.png -------------------------------------------------------------------------------- /public/icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Przeblysk/next-starter/HEAD/public/icon-512.png -------------------------------------------------------------------------------- /public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Przeblysk/next-starter/HEAD/public/favicon-16x16.png -------------------------------------------------------------------------------- /public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Przeblysk/next-starter/HEAD/public/favicon-32x32.png -------------------------------------------------------------------------------- /public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Przeblysk/next-starter/HEAD/public/apple-touch-icon.png -------------------------------------------------------------------------------- /public/icon-192-maskable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Przeblysk/next-starter/HEAD/public/icon-192-maskable.png -------------------------------------------------------------------------------- /public/icon-512-maskable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Przeblysk/next-starter/HEAD/public/icon-512-maskable.png -------------------------------------------------------------------------------- /app/(auth)/login/layout.tsx: -------------------------------------------------------------------------------- 1 | export default function Layout({ children }: { children: React.ReactNode }) { 2 | return
17 | {t("HomePage.description")} 18 |
19 |{user?.email}
43 |163 | {body} 164 |
165 | ) 166 | }) 167 | FormMessage.displayName = "FormMessage" 168 | 169 | export { 170 | useFormField, 171 | Form, 172 | FormItem, 173 | FormLabel, 174 | FormControl, 175 | FormDescription, 176 | FormMessage, 177 | FormField, 178 | } 179 | -------------------------------------------------------------------------------- /hooks/use-toast.ts: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | // Inspired by react-hot-toast library 4 | import type { ToastActionElement, ToastProps } from "@/components/ui/toast" 5 | import * as React from "react" 6 | 7 | const TOAST_LIMIT = 1 8 | const TOAST_REMOVE_DELAY = 1000000 9 | 10 | type ToasterToast = ToastProps & { 11 | id: string 12 | title?: React.ReactNode 13 | description?: React.ReactNode 14 | action?: ToastActionElement 15 | } 16 | 17 | export const actionTypes = { 18 | ADD_TOAST: "ADD_TOAST", 19 | UPDATE_TOAST: "UPDATE_TOAST", 20 | DISMISS_TOAST: "DISMISS_TOAST", 21 | REMOVE_TOAST: "REMOVE_TOAST" 22 | } as const 23 | 24 | let count = 0 25 | 26 | function genId() { 27 | count = (count + 1) % Number.MAX_SAFE_INTEGER 28 | return count.toString() 29 | } 30 | 31 | type ActionType = typeof actionTypes 32 | 33 | type Action = 34 | | { 35 | type: ActionType["ADD_TOAST"] 36 | toast: ToasterToast 37 | } 38 | | { 39 | type: ActionType["UPDATE_TOAST"] 40 | toast: Partial