Continue working on Sign in with Apple button

This commit is contained in:
2025-06-25 16:55:52 -05:00
parent 29ba0d881d
commit ba35e23810
4 changed files with 93 additions and 5 deletions

BIN
bun.lockb

Binary file not shown.

View File

@ -48,10 +48,10 @@
"@radix-ui/react-toggle": "^1.1.9", "@radix-ui/react-toggle": "^1.1.9",
"@radix-ui/react-toggle-group": "^1.1.10", "@radix-ui/react-toggle-group": "^1.1.10",
"@radix-ui/react-tooltip": "^1.2.7", "@radix-ui/react-tooltip": "^1.2.7",
"@sentry/nextjs": "^9.31.0", "@sentry/nextjs": "^9.32.0",
"@supabase-cache-helpers/postgrest-react-query": "^1.13.4", "@supabase-cache-helpers/postgrest-react-query": "^1.13.4",
"@supabase/ssr": "^0.6.1", "@supabase/ssr": "^0.6.1",
"@supabase/supabase-js": "^2.50.1", "@supabase/supabase-js": "^2.50.2",
"@t3-oss/env-nextjs": "^0.12.0", "@t3-oss/env-nextjs": "^0.12.0",
"@tanstack/react-query": "^5.81.2", "@tanstack/react-query": "^5.81.2",
"@tanstack/react-table": "^8.21.3", "@tanstack/react-table": "^8.21.3",
@ -92,9 +92,9 @@
"eslint-config-next": "^15.3.4", "eslint-config-next": "^15.3.4",
"eslint-config-prettier": "^10.1.5", "eslint-config-prettier": "^10.1.5",
"eslint-plugin-drizzle": "^0.2.3", "eslint-plugin-drizzle": "^0.2.3",
"eslint-plugin-prettier": "^5.5.0", "eslint-plugin-prettier": "^5.5.1",
"postcss": "^8.5.6", "postcss": "^8.5.6",
"prettier": "^3.6.0", "prettier": "^3.6.1",
"prettier-plugin-tailwindcss": "^0.6.13", "prettier-plugin-tailwindcss": "^0.6.13",
"tailwindcss": "^4.1.10", "tailwindcss": "^4.1.10",
"tw-animate-css": "^1.3.4", "tw-animate-css": "^1.3.4",

View File

@ -4,3 +4,91 @@ import { StatusMessage, SubmitButton } from '@/components/default/forms';
import { useAuth } from '@/lib/hooks/context'; import { useAuth } from '@/lib/hooks/context';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { useState } from 'react'; import { useState } from 'react';
import Image from 'next/image';
import { type buttonVariants } from '@/components/ui';
import { type ComponentProps } from 'react';
import { type VariantProps } from 'class-variance-authority';
import { useSupabaseClient } from '@/utils/supabase';
type ButtonProps = ComponentProps<'button'> & VariantProps<typeof buttonVariants>;
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 = ({
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 router = useRouter();
const { loading, refreshUser } = useAuth();
const [statusMessage, setStatusMessage] = useState('');
const [ isLoading, setIsLoading ] = useState(false);
const supabase = useSupabaseClient();
const handleSignInWithApple = async (e: React.FormEvent) => {
e.preventDefault();
try {
if (!supabase) throw new Error('Supabase client not found');
setStatusMessage('');
setIsLoading(true);
const result = await signInWithApple(supabase);
if (result.data.url) window.location.href = result.data.url;
else setStatusMessage(`There was a problem signing in with Apple!`);
} catch (error) {
setStatusMessage(`Error signing in: ${error as string}`);
} finally {
setIsLoading(false);
await refreshUser();
router.push('');
}
};
return (
<form onSubmit={handleSignInWithApple} {...formProps}>
<SubmitButton
disabled={isLoading || loading}
pendingText='Signing in...'
{...buttonProps}
>
<div className='flex items-center gap-2'>
<Image
src={imageProps.src}
alt={imageProps.alt}
className={imageProps.className}
width={imageProps.width}
height={imageProps.height}
/>
<p className={textProps.className}>Sign In with Apple</p>
</div>
</SubmitButton>
{statusMessage && <StatusMessage message={{ error: statusMessage }} />}
</form>
);
};

View File

@ -3,7 +3,7 @@ type Message =
| { error: string} | { error: string}
| { message: string} | { message: string}
export const StatusMessage = (message: Message) => { export const StatusMessage = ({message}: {message: Message}) => {
return ( return (
<div className='flex flex-col gap-2 w-full <div className='flex flex-col gap-2 w-full
text-sm bg-accent rounded-md p-2 px-4' text-sm bg-accent rounded-md p-2 px-4'