All files / features/staff/pages StaffLoginPage.tsx

91.3% Statements 21/23
78.94% Branches 15/19
100% Functions 4/4
100% Lines 21/21

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114                    1x 9x 9x 9x 9x 9x 9x 9x   9x 4x 1x       9x 2x 2x 2x   2x 2x 1x       9x   9x                                                                                         2x                                                            
import { useEffect, useState } from 'react'
import { useNavigate, useParams } from 'react-router-dom'
import { useTranslation } from 'react-i18next'
import { Button } from '@core/components/ui/button'
import { Input } from '@core/components/ui/input'
import { Card, CardHeader, CardTitle, CardContent, CardDescription } from '@core/components/ui/card'
import { Label } from '@core/components/ui/label'
import { useStaffAuth } from '../hooks/useStaffAuth'
import { useEvent } from '@features/events/context/EventContext'
 
export const StaffLoginPage = () => {
    const { t } = useTranslation('common')
    const { event } = useEvent()
    const { login, isLoading, isStaffAuthenticated } = useStaffAuth()
    const navigate = useNavigate()
    const { slug } = useParams<{ slug: string }>()
    const [code, setCode] = useState('')
    const [error, setError] = useState<string | null>(null)
 
    useEffect(() => {
        if (event && isStaffAuthenticated(event.id) && slug) {
            navigate(`/${slug}/staff/collect`)
        }
    }, [event, isStaffAuthenticated, navigate, slug])
 
    const handleSubmit = async (e: React.FormEvent) => {
        e.preventDefault()
        setError(null)
        Iif (!event) return
 
        const result = await login(code, event.id)
        if (!result.success) {
            setError(result.error || 'Authentication failed')
        }
    }
 
    Iif (!event) return null
 
    return (
        <div
            className="flex items-center justify-center min-h-screen p-4"
            style={{ backgroundColor: 'var(--auth-page-bg)' }}
        >
            <Card
                className="w-full max-w-md backdrop-blur-md shadow-xl border-t rounded-3xl overflow-hidden"
                style={{
                    borderRadius: 'var(--auth-card-radius)',
                    borderColor: 'var(--auth-input-border)',
                    boxShadow: 'var(--auth-card-shadow)',
                }}
            >
                <CardHeader>
                    <CardTitle
                        className="text-2xl text-center"
                        style={{ color: 'var(--auth-title-color)' }}
                    >
                        {t('staff.login.title', 'Staff Access')}
                    </CardTitle>
                    <CardDescription
                        className="text-center"
                        style={{ color: 'var(--auth-subtitle-color)' }}
                    >
                        {t('staff.login.subtitle', 'Enter your PIN to start collecting donations')}
                    </CardDescription>
                </CardHeader>
                <CardContent>
                    <form onSubmit={handleSubmit} className="space-y-6">
                        <div className="space-y-2 text-center">
                            <Label
                                htmlFor="code"
                                className="text-lg"
                                style={{ color: 'var(--auth-label-color)' }}
                            >
                                {t('staff.login.pin_label', 'PIN Code')}
                            </Label>
                            <Input
                                id="code"
                                type="text"
                                inputMode="numeric"
                                pattern="[0-9]*"
                                placeholder="••••"
                                className="h-16 text-3xl text-center tracking-widest font-mono"
                                value={code}
                                onChange={(e) => setCode(e.target.value)}
                                autoFocus
                                style={{
                                    backgroundColor: 'var(--auth-input-bg)',
                                    color: 'var(--auth-input-text)',
                                    borderColor: 'var(--auth-input-border)',
                                }}
                            />
                            {error && <p className="text-sm text-red-500 mt-2">{error}</p>}
                        </div>
 
                        <Button
                            type="submit"
                            className="w-full h-12 text-lg"
                            disabled={isLoading || !code}
                            style={{
                                backgroundColor: 'var(--auth-button-bg)',
                                color: 'var(--auth-button-text)',
                            }}
                        >
                            {isLoading
                                ? t('staff.login.loading', 'Connecting...')
                                : t('staff.login.submit', 'Connect')}
                        </Button>
                    </form>
                </CardContent>
            </Card>
        </div>
    )
}