Start adding apple auth
This commit is contained in:
BIN
public/icons/apple.png
Normal file
BIN
public/icons/apple.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 119 KiB |
@ -18,13 +18,14 @@ import {
|
|||||||
Input,
|
Input,
|
||||||
} from '@/components/ui';
|
} from '@/components/ui';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { signIn, signInWithMicrosoft } from '@/lib/actions';
|
import { signIn } from '@/lib/actions';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import { useAuth } from '@/components/context/auth';
|
import { useAuth } from '@/components/context/auth';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { StatusMessage, SubmitButton } from '@/components/default';
|
import { StatusMessage, SubmitButton } from '@/components/default';
|
||||||
import { Separator } from '@/components/ui';
|
import { Separator } from '@/components/ui';
|
||||||
import { SignInWithMicrosoft } from '@/components/default/auth/SignInWithMicrosoft';
|
import { SignInWithMicrosoft } from '@/components/default/auth/SignInWithMicrosoft';
|
||||||
|
import { SignInWithApple } from '@/components/default/auth/SignInWithApple';
|
||||||
|
|
||||||
const formSchema = z.object({
|
const formSchema = z.object({
|
||||||
email: z.string().email({
|
email: z.string().email({
|
||||||
@ -148,6 +149,8 @@ const Login = () => {
|
|||||||
</Form>
|
</Form>
|
||||||
<Separator className='my-4' />
|
<Separator className='my-4' />
|
||||||
<SignInWithMicrosoft />
|
<SignInWithMicrosoft />
|
||||||
|
<Separator className='my-4' />
|
||||||
|
<SignInWithApple />
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
58
src/components/default/auth/SignInWithApple.tsx
Normal file
58
src/components/default/auth/SignInWithApple.tsx
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
'use client';
|
||||||
|
import { signInWithApple } from '@/lib/actions';
|
||||||
|
import { StatusMessage, SubmitButton } from '@/components/default';
|
||||||
|
import { useAuth } from '@/components/context/auth';
|
||||||
|
import { useRouter } from 'next/navigation';
|
||||||
|
import { useState } from 'react';
|
||||||
|
import Image from 'next/image';
|
||||||
|
|
||||||
|
export const SignInWithApple = () => {
|
||||||
|
const router = useRouter();
|
||||||
|
const { isLoading, refreshUserData } = useAuth();
|
||||||
|
const [statusMessage, setStatusMessage] = useState('');
|
||||||
|
const [isSigningIn, setIsSigningIn] = useState(false);
|
||||||
|
|
||||||
|
const handleSignInWithApple = async (e: React.FormEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
try {
|
||||||
|
setStatusMessage('');
|
||||||
|
setIsSigningIn(true);
|
||||||
|
|
||||||
|
const result = await signInWithApple();
|
||||||
|
|
||||||
|
if (result?.success && result.data) {
|
||||||
|
// Redirect to Apple OAuth page
|
||||||
|
window.location.href = result.data;
|
||||||
|
} else {
|
||||||
|
setStatusMessage(`Error: ${result.error}`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
setStatusMessage(
|
||||||
|
`Error: ${error instanceof Error ? error.message : 'Could not sign in!'}`
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
setIsSigningIn(false);
|
||||||
|
await refreshUserData();
|
||||||
|
router.push('');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form onSubmit={handleSignInWithApple}>
|
||||||
|
<SubmitButton
|
||||||
|
className='w-full cursor-pointer'
|
||||||
|
disabled={isLoading || isSigningIn}
|
||||||
|
pendingText='Redirecting...'
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
|
<div className='flex items-center gap-3'>
|
||||||
|
<Image src='/icons/apple.png' alt='Apple logo' className='text-white' width={20} height={20} />
|
||||||
|
<p>Sign in with Apple</p>
|
||||||
|
</div>
|
||||||
|
</SubmitButton>
|
||||||
|
{statusMessage && (
|
||||||
|
<StatusMessage message={{ error: statusMessage }} />
|
||||||
|
)}
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
};
|
@ -1,4 +1,3 @@
|
|||||||
// src/components/default/auth/SignInWithMicrosoft.tsx
|
|
||||||
'use client';
|
'use client';
|
||||||
import { signInWithMicrosoft } from '@/lib/actions';
|
import { signInWithMicrosoft } from '@/lib/actions';
|
||||||
import { StatusMessage, SubmitButton } from '@/components/default';
|
import { StatusMessage, SubmitButton } from '@/components/default';
|
||||||
|
@ -67,7 +67,19 @@ export const signInWithMicrosoft = async (): Promise<Result<string>> => {
|
|||||||
const { data, error } = await supabase.auth.signInWithOAuth({
|
const { data, error } = await supabase.auth.signInWithOAuth({
|
||||||
provider: 'azure',
|
provider: 'azure',
|
||||||
options: {
|
options: {
|
||||||
scopes: 'email',
|
scopes: 'openid, profile email offline_access',
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (error) return { success: false, error: error.message };
|
||||||
|
return { success: true, data: data.url};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const signInWithApple = async (): Promise<Result<string>> => {
|
||||||
|
const supabase = await createServerClient();
|
||||||
|
const { data, error } = await supabase.auth.signInWithOAuth({
|
||||||
|
provider: 'apple',
|
||||||
|
options: {
|
||||||
|
scopes: 'openid, profile email offline_access',
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (error) return { success: false, error: error.message };
|
if (error) return { success: false, error: error.message };
|
||||||
|
Reference in New Issue
Block a user