File size: 3,302 Bytes
9853b20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
'use client'

import { useState } from 'react'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { useRouter, useSearchParams } from 'next/navigation'
import { Button } from 'components/ui/button'
import { pinEntrySchema, type PinEntryForm as PinEntryFormType } from 'lib/validations/code'

export function PinEntryForm() {
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const router = useRouter()
  const searchParams = useSearchParams()
  const code = searchParams.get('code')

  const {
    register,
    handleSubmit,
    formState: { errors }
  } = useForm<PinEntryFormType>({
    resolver: zodResolver(pinEntrySchema)
  })

  const onSubmit = async (data: PinEntryFormType) => {
    if (!code) {
      setError('Chybí kód místnosti')
      return
    }

    try {
      setLoading(true)
      setError(null)

      const response = await fetch('/api/codes/verify-pin', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          code: code.toUpperCase(),
          pin: data.pin
        })
      })

      const result = await response.json()

      if (!response.ok) {
        if (response.status === 401) {
          setError('Neplatný PIN')
        } else if (response.status === 429) {
          setError('Příliš mnoho pokusů. Zkuste to později.')
        } else {
          setError(result.error || 'Nastala chyba při ověřování PIN')
        }
        return
      }

      if (result.roomId) {
        router.push(`/room/${result.roomId}?code=${code}`)
      }
    } catch {
      setError('Došlo k neočekávané chybě')
    } finally {
      setLoading(false)
    }
  }

  return (
    <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">

      <div>

        <label htmlFor="pin" className="block text-sm font-medium text-gray-700 mb-2">

          Zadejte PIN pro kód {code}

        </label>

        <input

          {...register('pin')}

          type="password"

          id="pin"

          maxLength={5}

          placeholder="12345"

          autoComplete="new-password"

          inputMode="numeric"

          pattern="[0-9]*"

          aria-label={`PIN pro kód ${code}`}

          className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-500 focus:border-brand-500 text-center text-2xl font-mono tracking-widest"

        />

        {errors.pin && (

          <p className="mt-1 text-sm text-red-600">{errors.pin.message}</p>

        )}

      </div>



      {error && (

        <div className="p-3 text-sm text-red-600 bg-red-50 rounded-md">

          {error}

        </div>

      )}



      <Button type="submit" className="w-full" disabled={loading}>

        {loading ? 'Ověřuji PIN...' : 'Vstoupit do místnosti'}

      </Button>



      <div className="text-center">

        <button

          type="button"

          onClick={() => router.push('/')}

          className="text-sm text-gray-600 hover:text-gray-800"

        >

          ← Zpět na zadání kódu

        </button>

      </div>

    </form>
  )
}