diff --git a/bun.lockb b/bun.lockb index 7a3b3f5..ab5f3b7 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 7b4afd5..74d8edd 100644 --- a/package.json +++ b/package.json @@ -48,12 +48,12 @@ "@radix-ui/react-toggle": "^1.1.9", "@radix-ui/react-toggle-group": "^1.1.10", "@radix-ui/react-tooltip": "^1.2.7", - "@sentry/nextjs": "^9.32.0", + "@sentry/nextjs": "^9.34.0", "@supabase-cache-helpers/postgrest-react-query": "^1.13.4", "@supabase/ssr": "^0.6.1", "@supabase/supabase-js": "^2.50.2", "@t3-oss/env-nextjs": "^0.12.0", - "@tanstack/react-query": "^5.81.2", + "@tanstack/react-query": "^5.81.5", "@tanstack/react-table": "^8.21.3", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", @@ -71,9 +71,10 @@ "react": "^19.1.0", "react-day-picker": "^9.7.0", "react-dom": "^19.1.0", - "react-hook-form": "^7.58.1", + "react-hook-form": "^7.59.0", + "react-icons": "^5.5.0", "react-resizable-panels": "^3.0.3", - "recharts": "^3.0.1", + "recharts": "^3.0.2", "sonner": "^2.0.5", "tailwind-merge": "^3.3.1", "vaul": "^1.1.2", @@ -84,22 +85,22 @@ "@tailwindcss/postcss": "^4.1.11", "@types/cors": "^2.8.19", "@types/express": "^5.0.3", - "@types/node": "^20.19.1", + "@types/node": "^20.19.4", "@types/react": "^19.1.8", "@types/react-dom": "^19.1.6", "drizzle-kit": "^0.30.6", - "eslint": "^9.29.0", + "eslint": "^9.30.1", "eslint-config-next": "^15.3.4", "eslint-config-prettier": "^10.1.5", "eslint-plugin-drizzle": "^0.2.3", "eslint-plugin-prettier": "^5.5.1", "postcss": "^8.5.6", - "prettier": "^3.6.1", + "prettier": "^3.6.2", "prettier-plugin-tailwindcss": "^0.6.13", "tailwindcss": "^4.1.11", "tw-animate-css": "^1.3.4", "typescript": "^5.8.3", - "typescript-eslint": "^8.35.0" + "typescript-eslint": "^8.35.1" }, "ct3aMetadata": { "initVersion": "7.39.3" diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 3542f7b..116eb1b 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,6 +1,7 @@ import '@/styles/globals.css'; import { type Metadata } from 'next'; -import { Geist } from 'next/font/google'; +import { Inter } from 'next/font/google'; +import { cn } from '@/lib/utils'; import { AuthContextProvider, ThemeProvider, @@ -204,16 +205,20 @@ export const generateMetadata = (): Metadata => { }; }; -const geist = Geist({ +const fontSans = Inter({ subsets: ['latin'], - variable: '--font-geist-sans', -}); + variable: '--font-sans', +}) export default function RootLayout({ children, }: Readonly<{ children: React.ReactNode }>) { return ( - + - - {children} - - + + {children} + + diff --git a/src/app/page.tsx b/src/app/page.tsx index f2b8d37..6ec30b1 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,36 +1,15 @@ -import Link from 'next/link'; +import { SignInCard } from '@/components/default/auth/cards/client/sign-in'; +import { ThemeToggle } from '@/lib/hooks/context'; export default function HomePage() { return ( -
+

Create T3 App

-
- -

First Steps →

-
- Just the basics - Everything you need to know to set up your - database and authentication. -
- - -

Documentation →

-
- Learn more about Create T3 App, the libraries it uses, and how to - deploy it. -
- -
+ +
); diff --git a/src/components/default/auth/buttons/client/index.tsx b/src/components/default/auth/buttons/client/index.tsx index d13fac5..a04ec76 100644 --- a/src/components/default/auth/buttons/client/index.tsx +++ b/src/components/default/auth/buttons/client/index.tsx @@ -1,3 +1,3 @@ export { SignInWithApple } from './sign-in-with-apple'; export { SignInWithMicrosoft } from './sign-in-with-microsoft'; -export { SignInButton } from './sign-in'; +export { SignInLinkButton } from './sign-in-link'; diff --git a/src/components/default/auth/buttons/client/sign-in.tsx b/src/components/default/auth/buttons/client/sign-in-link.tsx similarity index 87% rename from src/components/default/auth/buttons/client/sign-in.tsx rename to src/components/default/auth/buttons/client/sign-in-link.tsx index f28297d..fc7b7d3 100644 --- a/src/components/default/auth/buttons/client/sign-in.tsx +++ b/src/components/default/auth/buttons/client/sign-in-link.tsx @@ -6,7 +6,7 @@ import { type VariantProps } from 'class-variance-authority'; type SignInProps = ComponentProps<'button'> & VariantProps; -export const SignInButton = (props: SignInProps) => { +export const SignInLinkButton = (props: SignInProps) => { return ( + ); +}; diff --git a/src/components/default/auth/buttons/server/sign-in-with-apple.tsx b/src/components/default/auth/buttons/server/sign-in-with-apple.tsx new file mode 100644 index 0000000..76176b4 --- /dev/null +++ b/src/components/default/auth/buttons/server/sign-in-with-apple.tsx @@ -0,0 +1,78 @@ +'use server'; +import { signInWithApple } from '@/lib/queries'; +import { SubmitButton } from '@/components/default/forms'; +import Image from 'next/image'; +import { type buttonVariants } from '@/components/ui'; +import { type ComponentProps } from 'react'; +import { type VariantProps } from 'class-variance-authority'; +import { SupabaseServer } from '@/utils/supabase'; + +type ButtonProps = ComponentProps<'button'> & VariantProps; +type ImageProps = { + src: string; + alt: string; + className?: string; + width?: number; + height?: number; +} +type FormProps = ComponentProps<'form'>; +type TextProps = ComponentProps<'p'>; +type SignInWithAppleProps = { + buttonProps?: ButtonProps; + imageProps?: ImageProps; + formProps?: FormProps; + textProps?: TextProps; +}; + +export const SignInWithApple = async ({ + buttonProps = { + className: 'w-full cursor-pointer', + type: 'submit', + }, + imageProps = { + src: '/icons/auth/apple.svg', + alt: 'Apple', + className: 'invert-75 dark:invert-25', + width: 24, + height: 24, + }, + formProps = { + className: 'my-4', + }, + textProps = { + className: 'text-[1.0rem]', + }, +} : SignInWithAppleProps) => { + const supabase = await SupabaseServer(); + + const handleSignInWithApple = async () => { + try { + if (!supabase) throw new Error('Supabase client not found'); + const result = await signInWithApple(supabase); + if (result.error) throw new Error(`Error Signing in with Apple: ${result.error.message}`); + if (result.data.url) window.location.href = result.data.url; + } catch (error) { + console.error(error); + } + }; + + return ( +
+ +
+ {imageProps.alt} +

Sign In with Apple

+
+
+
+ ); +}; diff --git a/src/components/default/auth/buttons/server/sign-in-with-microsoft.tsx b/src/components/default/auth/buttons/server/sign-in-with-microsoft.tsx new file mode 100644 index 0000000..e4669e4 --- /dev/null +++ b/src/components/default/auth/buttons/server/sign-in-with-microsoft.tsx @@ -0,0 +1,78 @@ +'use server'; +import { signInWithMicrosoft } from '@/lib/queries'; +import { SubmitButton } from '@/components/default/forms'; +import Image from 'next/image'; +import { type buttonVariants } from '@/components/ui'; +import { type ComponentProps } from 'react'; +import { type VariantProps } from 'class-variance-authority'; +import { SupabaseServer } from '@/utils/supabase'; + +type ButtonProps = ComponentProps<'button'> & VariantProps; +type ImageProps = { + src: string; + alt: string; + className?: string; + width?: number; + height?: number; +} +type FormProps = ComponentProps<'form'>; +type TextProps = ComponentProps<'p'>; +type SignInWithMicrosoftProps = { + buttonProps?: ButtonProps; + imageProps?: ImageProps; + formProps?: FormProps; + textProps?: TextProps; +}; + +export const SignInWithMicrosoft = async ({ + buttonProps = { + className: 'w-full cursor-pointer', + type: 'submit', + }, + imageProps = { + src: '/icons/auth/microsoft.svg', + alt: 'Microsoft', + className: 'invert-75 dark:invert-25', + width: 24, + height: 24, + }, + formProps = { + className: 'my-4', + }, + textProps = { + className: 'text-[1.0rem]', + }, +} : SignInWithMicrosoftProps) => { + const supabase = await SupabaseServer(); + + const handleSignInWithMicrosoft = async () => { + try { + if (!supabase) throw new Error('Supabase client not found'); + const result = await signInWithMicrosoft(supabase); + if (result.error) throw new Error(`Error Signing in with Microsoft: ${result.error.message}`); + if (result.data.url) window.location.href = result.data.url; + } catch (error) { + console.error(error); + } + }; + + return ( +
+ +
+ {imageProps.alt} +

Sign In with Microsoft

+
+
+
+ ); +}; diff --git a/src/components/default/auth/cards/client/sign-in.tsx b/src/components/default/auth/cards/client/sign-in.tsx index 83fb989..2979013 100755 --- a/src/components/default/auth/cards/client/sign-in.tsx +++ b/src/components/default/auth/cards/client/sign-in.tsx @@ -43,7 +43,7 @@ const signInFormSchema = z.object({ }), }); -const signUpformSchema = z +const signUpFormSchema = z .object({ name: z.string().min(2, { message: 'Name must be at least 2 characters.', @@ -77,8 +77,8 @@ export const SignInCard = () => { }, }); - const signUpForm = useForm>({ - resolver: zodResolver(signUpformSchema), + const signUpForm = useForm>({ + resolver: zodResolver(signUpFormSchema), defaultValues: { name: '', email: '', @@ -100,11 +100,9 @@ export const SignInCard = () => { if (!supabase) throw new Error('Supabase client not found'); const result = await signIn(supabase, formData); if (result.error) throw new Error(result.error.message); - else if (result.data) { - await refreshUser(); - signInForm.reset(); - router.push(''); - } + await refreshUser(); + signInForm.reset(); + router.push(''); } catch (error) { setStatusMessage(`Error signing in: ${error as string}`); } @@ -112,14 +110,214 @@ export const SignInCard = () => { const handleSignUp = async (values: z.infer) => { try { - - } catch { - + setStatusMessage(''); + const formData = new FormData(); + formData.append('name', values.name); + formData.append('email', values.email); + formData.append('password', values.password); + if (!supabase) throw new Error('Supabase client not found'); + const result = await signUp(supabase, formData); + if (result.error) throw new Error(result.error.message); + await refreshUser(); + signUpForm.reset(); + router.push(''); + } catch (error) { + setStatusMessage(`Error signing up: ${error as string}`); } }; return ( - + + + Sign In + Sign Up + + + + + + Sign In + + + +
+ + ( + + Email + + + + + + )} + /> + ( + +
+ Password + + Forgot Password? + +
+ + + + +
+ )} + /> + {statusMessage && + (statusMessage.includes('Error') || + statusMessage.includes('error') || + statusMessage.includes('failed') || + statusMessage.includes('invalid') ? ( + + ) : ( + + ))} + + Sign In + + + +
+ + or + +
+ + +
+
+
+ + + + + Sign Up + + + +
+ + ( + + Name + + + + + )} + /> + ( + + Email + + + + + )} + /> + ( + + Password + + + + + )} + /> + ( + + Confirm Passsword + + + + + )} + /> + {statusMessage && + (statusMessage.includes('Error') || + statusMessage.includes('error') || + statusMessage.includes('failed') || + statusMessage.includes('invalid') ? ( + + ) : ( + + ))} + + Sign Up + + + +
+ + or + +
+ + +
+
+
+
); }; diff --git a/src/components/default/forms/submit-button.tsx b/src/components/default/forms/submit-button.tsx index ab01a0e..a351af5 100644 --- a/src/components/default/forms/submit-button.tsx +++ b/src/components/default/forms/submit-button.tsx @@ -9,14 +9,14 @@ type SubmitButtonProps = ComponentProps<'button'> & VariantProps & { pendingText?: string; loaderClassName?: ComponentProps<'div'>['className']; - textClassName?: ComponentProps<'p'>['className']; + pendingTextClassName?: ComponentProps<'p'>['className']; }; export const SubmitButton = ({ children, pendingText = 'Submitting...', loaderClassName = 'mr-2 h-4 w-4 animate-spin', - textClassName = 'text-sm font-medium', + pendingTextClassName = 'text-sm font-medium', ...props }: SubmitButtonProps) => { const { pending } = useFormStatus(); @@ -30,7 +30,7 @@ export const SubmitButton = ({ {pending || props.disabled ? ( <> -

{pendingText}

+

{pendingText}

) : ( children diff --git a/src/styles/globals.css b/src/styles/globals.css index abb9401..d7445f0 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -4,7 +4,7 @@ @custom-variant dark (&:is(.dark *)); @theme { - --font-sans: var(--font-geist-sans), ui-sans-serif, system-ui, sans-serif, + --font-sans: var(--font-sans), ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; } @@ -47,72 +47,99 @@ } :root { - --radius: 0.65rem; - --background: oklch(1 0 0); - --foreground: oklch(0.141 0.005 285.823); - --card: oklch(1 0 0); - --card-foreground: oklch(0.141 0.005 285.823); - --popover: oklch(1 0 0); - --popover-foreground: oklch(0.141 0.005 285.823); - --primary: oklch(0.645 0.246 16.439); - --primary-foreground: oklch(0.969 0.015 12.422); - --secondary: oklch(0.967 0.001 286.375); - --secondary-foreground: oklch(0.21 0.006 285.885); - --muted: oklch(0.967 0.001 286.375); - --muted-foreground: oklch(0.552 0.016 285.938); - --accent: oklch(0.967 0.001 286.375); - --accent-foreground: oklch(0.21 0.006 285.885); - --destructive: oklch(0.577 0.245 27.325); - --border: oklch(0.92 0.004 286.32); - --input: oklch(0.92 0.004 286.32); - --ring: oklch(0.645 0.246 16.439); - --chart-1: oklch(0.646 0.222 41.116); - --chart-2: oklch(0.6 0.118 184.704); - --chart-3: oklch(0.398 0.07 227.392); - --chart-4: oklch(0.828 0.189 84.429); - --chart-5: oklch(0.769 0.188 70.08); - --sidebar: oklch(0.985 0 0); - --sidebar-foreground: oklch(0.141 0.005 285.823); - --sidebar-primary: oklch(0.645 0.246 16.439); - --sidebar-primary-foreground: oklch(0.969 0.015 12.422); - --sidebar-accent: oklch(0.967 0.001 286.375); - --sidebar-accent-foreground: oklch(0.21 0.006 285.885); - --sidebar-border: oklch(0.92 0.004 286.32); - --sidebar-ring: oklch(0.645 0.246 16.439); + --background: oklch(0.9785 0.0045 314.8050); + --foreground: oklch(0.3710 0.0333 301.6287); + --card: oklch(0.9940 0 0); + --card-foreground: oklch(0.3710 0.0333 301.6287); + --popover: oklch(0.9940 0 0); + --popover-foreground: oklch(0.3710 0.0333 301.6287); + --primary: oklch(0.4868 0.1488 286.5771); + --primary-foreground: oklch(0.9785 0.0045 314.8050); + --secondary: oklch(0.9139 0.0448 291.0467); + --secondary-foreground: oklch(0.3008 0.0773 288.1551); + --muted: oklch(0.8930 0.0149 312.2335); + --muted-foreground: oklch(0.5361 0.0391 305.8579); + --accent: oklch(0.8514 0.0535 342.1042); + --accent-foreground: oklch(0.3328 0.0528 311.4628); + --destructive: oklch(0.6984 0.1170 47.0382); + --destructive-foreground: oklch(0.9785 0.0045 314.8050); + --border: oklch(0.8488 0.0244 313.1102); + --input: oklch(0.9352 0.0136 314.7562); + --ring: oklch(0.4868 0.1488 286.5771); + --chart-1: oklch(0.4868 0.1488 286.5771); + --chart-2: oklch(0.8514 0.0535 342.1042); + --chart-3: oklch(0.7388 0.0664 194.5709); + --chart-4: oklch(0.9197 0.1140 104.6226); + --chart-5: oklch(0.7409 0.0895 280.3986); + --sidebar: oklch(0.9569 0.0090 314.7812); + --sidebar-foreground: oklch(0.3710 0.0333 301.6287); + --sidebar-primary: oklch(0.4868 0.1488 286.5771); + --sidebar-primary-foreground: oklch(0.9785 0.0045 314.8050); + --sidebar-accent: oklch(0.8514 0.0535 342.1042); + --sidebar-accent-foreground: oklch(0.3328 0.0528 311.4628); + --sidebar-border: oklch(0.8759 0.0218 316.4501); + --sidebar-ring: oklch(0.4868 0.1488 286.5771); + --font-sans: Inter, sans-serif; + --font-serif: "Lora", Georgia, serif; + --font-mono: "Fira Code", "Courier New", monospace; + --radius: 0.5rem; + --shadow-2xs: 1px 2px 5px 1px hsl(0 0% 10.1961% / 0.03); + --shadow-xs: 1px 2px 5px 1px hsl(0 0% 10.1961% / 0.03); + --shadow-sm: 1px 2px 5px 1px hsl(0 0% 10.1961% / 0.06), 1px 1px 2px 0px hsl(0 0% 10.1961% / 0.06); + --shadow: 1px 2px 5px 1px hsl(0 0% 10.1961% / 0.06), 1px 1px 2px 0px hsl(0 0% 10.1961% / 0.06); + --shadow-md: 1px 2px 5px 1px hsl(0 0% 10.1961% / 0.06), 1px 2px 4px 0px hsl(0 0% 10.1961% / 0.06); + --shadow-lg: 1px 2px 5px 1px hsl(0 0% 10.1961% / 0.06), 1px 4px 6px 0px hsl(0 0% 10.1961% / 0.06); + --shadow-xl: 1px 2px 5px 1px hsl(0 0% 10.1961% / 0.06), 1px 8px 10px 0px hsl(0 0% 10.1961% / 0.06); + --shadow-2xl: 1px 2px 5px 1px hsl(0 0% 10.1961% / 0.15); + --tracking-normal: 0em; + --spacing: 0.25rem; } .dark { - --background: oklch(0.141 0.005 285.823); - --foreground: oklch(0.985 0 0); - --card: oklch(0.21 0.006 285.885); - --card-foreground: oklch(0.985 0 0); - --popover: oklch(0.21 0.006 285.885); - --popover-foreground: oklch(0.985 0 0); - --primary: oklch(0.645 0.246 16.439); - --primary-foreground: oklch(0.969 0.015 12.422); - --secondary: oklch(0.274 0.006 286.033); - --secondary-foreground: oklch(0.985 0 0); - --muted: oklch(0.274 0.006 286.033); - --muted-foreground: oklch(0.705 0.015 286.067); - --accent: oklch(0.274 0.006 286.033); - --accent-foreground: oklch(0.985 0 0); - --destructive: oklch(0.704 0.191 22.216); - --border: oklch(1 0 0 / 10%); - --input: oklch(1 0 0 / 15%); - --ring: oklch(0.645 0.246 16.439); - --chart-1: oklch(0.488 0.243 264.376); - --chart-2: oklch(0.696 0.17 162.48); - --chart-3: oklch(0.769 0.188 70.08); - --chart-4: oklch(0.627 0.265 303.9); - --chart-5: oklch(0.645 0.246 16.439); - --sidebar: oklch(0.21 0.006 285.885); - --sidebar-foreground: oklch(0.985 0 0); - --sidebar-primary: oklch(0.645 0.246 16.439); - --sidebar-primary-foreground: oklch(0.969 0.015 12.422); - --sidebar-accent: oklch(0.274 0.006 286.033); - --sidebar-accent-foreground: oklch(0.985 0 0); - --sidebar-border: oklch(1 0 0 / 10%); - --sidebar-ring: oklch(0.645 0.246 16.439); + --background: oklch(0.2213 0.0228 309.2819); + --foreground: oklch(0.9100 0.0260 308.1435); + --card: oklch(0.2671 0.0372 295.2445); + --card-foreground: oklch(0.9100 0.0260 308.1435); + --popover: oklch(0.2671 0.0372 295.2445); + --popover-foreground: oklch(0.9100 0.0260 308.1435); + --primary: oklch(0.6405 0.1338 286.4998); + --primary-foreground: oklch(0.2213 0.0228 309.2819); + --secondary: oklch(0.4071 0.0776 288.3025); + --secondary-foreground: oklch(0.9100 0.0260 308.1435); + --muted: oklch(0.2630 0.0340 310.8818); + --muted-foreground: oklch(0.7026 0.0304 313.2720); + --accent: oklch(0.3328 0.0528 311.4628); + --accent-foreground: oklch(0.8076 0.0881 341.1289); + --destructive: oklch(0.7501 0.1053 47.2117); + --destructive-foreground: oklch(0.2213 0.0228 309.2819); + --border: oklch(0.3139 0.0379 309.3053); + --input: oklch(0.2913 0.0360 305.8978); + --ring: oklch(0.6405 0.1338 286.4998); + --chart-1: oklch(0.6405 0.1338 286.4998); + --chart-2: oklch(0.8076 0.0881 341.1289); + --chart-3: oklch(0.7388 0.0664 194.5709); + --chart-4: oklch(0.9197 0.1140 104.6226); + --chart-5: oklch(0.4868 0.1488 286.5771); + --sidebar: oklch(0.2039 0.0232 309.1750); + --sidebar-foreground: oklch(0.9100 0.0260 308.1435); + --sidebar-primary: oklch(0.6405 0.1338 286.4998); + --sidebar-primary-foreground: oklch(0.2213 0.0228 309.2819); + --sidebar-accent: oklch(0.3328 0.0528 311.4628); + --sidebar-accent-foreground: oklch(0.8076 0.0881 341.1289); + --sidebar-border: oklch(0.2913 0.0360 305.8978); + --sidebar-ring: oklch(0.6405 0.1338 286.4998); + --font-sans: Inter, sans-serif; + --font-serif: "Lora", Georgia, serif; + --font-mono: "Fira Code", "Courier New", monospace; + --radius: 0.5rem; + --shadow-2xs: 1px 2px 5px 1px hsl(0 0% 10.1961% / 0.03); + --shadow-xs: 1px 2px 5px 1px hsl(0 0% 10.1961% / 0.03); + --shadow-sm: 1px 2px 5px 1px hsl(0 0% 10.1961% / 0.06), 1px 1px 2px 0px hsl(0 0% 10.1961% / 0.06); + --shadow: 1px 2px 5px 1px hsl(0 0% 10.1961% / 0.06), 1px 1px 2px 0px hsl(0 0% 10.1961% / 0.06); + --shadow-md: 1px 2px 5px 1px hsl(0 0% 10.1961% / 0.06), 1px 2px 4px 0px hsl(0 0% 10.1961% / 0.06); + --shadow-lg: 1px 2px 5px 1px hsl(0 0% 10.1961% / 0.06), 1px 4px 6px 0px hsl(0 0% 10.1961% / 0.06); + --shadow-xl: 1px 2px 5px 1px hsl(0 0% 10.1961% / 0.06), 1px 8px 10px 0px hsl(0 0% 10.1961% / 0.06); + --shadow-2xl: 1px 2px 5px 1px hsl(0 0% 10.1961% / 0.15); } @layer base { diff --git a/src/utils/supabase/index.ts b/src/utils/supabase/index.ts index 44bc7a5..189b3a3 100644 --- a/src/utils/supabase/index.ts +++ b/src/utils/supabase/index.ts @@ -1,5 +1,5 @@ export { useSupabaseClient } from './client'; export { updateSession } from './middleware'; -export { useSupabaseServer } from './server'; +export { SupabaseServer } from './server'; export type { Database } from './database.types'; export type * from './types'; diff --git a/src/utils/supabase/server.ts b/src/utils/supabase/server.ts index 72fd439..24fd6f2 100644 --- a/src/utils/supabase/server.ts +++ b/src/utils/supabase/server.ts @@ -2,10 +2,10 @@ import 'server-only'; import { createServerClient } from '@supabase/ssr'; -import type { Database, SupabaseClient } from '@/utils/supabase'; +import type { Database } from '@/utils/supabase'; import { cookies } from 'next/headers'; -export const useSupabaseServer = async (): Promise => { +export const SupabaseServer = async () => { const cookieStore = await cookies(); return createServerClient( process.env.NEXT_PUBLIC_SUPABASE_URL!,