feat: Implement character avatar upload and refactor character form fields and API calls.

This commit is contained in:
liqupan
2026-02-02 22:48:11 +08:00
parent 6c32d845a7
commit dec5748cca
15 changed files with 369 additions and 197 deletions

View File

@@ -5,10 +5,11 @@ import { zodResolver } from '@hookform/resolvers/zod'
import { Link, useNavigate } from '@tanstack/react-router'
import { Loader2, LogIn } from 'lucide-react'
import { toast } from 'sonner'
import { IconFacebook, IconGithub } from '@/assets/brand-icons'
import { IconFacebook, IconGithub, IconGoogle } from '@/assets/brand-icons'
import { useAuthStore } from '@/stores/auth-store'
import { sleep, cn } from '@/lib/utils'
import { Button } from '@/components/ui/button'
import { supabase } from '@/lib/supabase'
import {
Form,
FormControl,
@@ -51,34 +52,53 @@ export function UserAuthForm({
},
})
function onSubmit(data: z.infer<typeof formSchema>) {
async function onSubmit(data: z.infer<typeof formSchema>) {
setIsLoading(true)
toast.promise(sleep(2000), {
loading: 'Signing in...',
success: () => {
setIsLoading(false)
try {
const { data: authData, error } = await supabase.auth.signInWithPassword({
email: data.email,
password: data.password,
})
// Mock successful authentication with expiry computed at success time
const mockUser = {
accountNo: 'ACC001',
email: data.email,
role: ['user'],
exp: Date.now() + 24 * 60 * 60 * 1000, // 24 hours from now
if (error) throw error
if (authData.session && authData.user) {
setIsLoading(false)
const user = {
accountNo: authData.user.id,
email: authData.user.email || '',
role: ['admin'],
exp: authData.session.expires_at ? authData.session.expires_at * 1000 : Date.now() + 24 * 60 * 60 * 1000,
}
// Set user and access token
auth.setUser(mockUser)
auth.setAccessToken('mock-access-token')
auth.setUser(user)
auth.setAccessToken(authData.session.access_token)
// Redirect to the stored location or default to dashboard
const targetPath = redirectTo || '/'
navigate({ to: targetPath, replace: true })
toast.success(`Welcome back, ${user.email}!`)
}
} catch (error: any) {
setIsLoading(false)
toast.error(error.message || 'Login failed')
}
}
return `Welcome back, ${data.email}!`
},
error: 'Error',
})
const handleGoogleLogin = async () => {
setIsLoading(true)
try {
const { error } = await supabase.auth.signInWithOAuth({
provider: 'google',
options: {
redirectTo: `${window.location.origin}/`,
},
})
if (error) throw error
} catch (error: any) {
toast.error(error.message || 'Google login failed')
setIsLoading(false)
}
}
return (
@@ -136,14 +156,22 @@ export function UserAuthForm({
</div>
</div>
<div className='grid grid-cols-2 gap-2'>
{/* <div className='grid grid-cols-3 gap-2'>
<Button
variant='outline'
type='button'
disabled={isLoading}
onClick={handleGoogleLogin}
>
<IconGoogle className='h-4 w-4' /> Google
</Button>
<Button variant='outline' type='button' disabled={isLoading}>
<IconGithub className='h-4 w-4' /> GitHub
</Button>
<Button variant='outline' type='button' disabled={isLoading}>
<IconFacebook className='h-4 w-4' /> Facebook
</Button>
</div>
</div> */}
</form>
</Form>
)