File size: 4,615 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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
'use client'

import { useState } from 'react'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { Button } from 'components/ui/button'
import { codeWithPinSchema, type CodeWithPinForm } from 'lib/validations/code'

interface TransferCodeFormProps {
  onSuccess: () => void
  onCancel: () => void
}

export function TransferCodeForm({ onSuccess, onCancel }: TransferCodeFormProps) {
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [needsPin, setNeedsPin] = useState(false)

  const {
    register,
    handleSubmit,
    formState: { errors },
    watch
  } = useForm<CodeWithPinForm>({
    resolver: zodResolver(codeWithPinSchema)
  })

  const codeValue = watch('code')

  const onSubmit = async (data: CodeWithPinForm) => {
    try {
      setLoading(true)
      setError(null)

      const response = await fetch('/api/users/transfer-code', {
        method: 'POST',
        credentials: 'include',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          code: data.code.toUpperCase(),
          pin: data.pin || undefined
        })
      })

      const result = await response.json()

      if (!response.ok) {
        if (response.status === 400 && result.needsPin) {
          setNeedsPin(true)
          return
        } else if (response.status === 401) {
          setError('Neplatný kód nebo PIN')
        } else if (response.status === 409) {
          setError('Kód již máte ve svém profilu')
        } else {
          setError(result.error || 'Nastala chyba při převodu kódu')
        }
        return
      }

      onSuccess()
    } catch {
      setError('Došlo k neočekávané chybě')
    } finally {
      setLoading(false)
    }
  }

  return (
    <div className="bg-white p-6 rounded-lg shadow-md">

      <h3 className="text-lg font-semibold text-gray-900 mb-4">

        Převést anonymní kód

      </h3>



      <p className="text-sm text-gray-600 mb-6">

        Zadejte kód a PIN (pokud je nastaven) pro převedení anonymní místnosti pod váš profil.

      </p>



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

        <div>

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

            Kód místnosti

          </label>

          <input

            {...register('code')}

            type="text"

            id="code"

            maxLength={5}

            placeholder="A1B2C"

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

            style={{ textTransform: 'uppercase' }}

          />

          {errors.code && (

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

          )}

        </div>



        {(needsPin || codeValue?.length === 5) && (

          <div>

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

              PIN (pokud je nastaven)

            </label>

            <input

              {...register('pin')}

              type="password"

              id="pin"

              maxLength={5}

              placeholder="12345"

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

            />

            {errors.pin && (

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

            )}

            <p className="mt-1 text-xs text-gray-500">

              Nechte prázdné, pokud místnost není chráněna PIN

            </p>

          </div>

        )}



        {error && (

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

            {error}

          </div>

        )}



        <div className="flex gap-3">

          <button

            type="submit"

            className="flex-1 bg-gray-800 text-white hover:bg-gray-900 px-4 py-2 rounded-md"

            disabled={loading}

          >

            {loading ? 'Převádím...' : 'Převést kód'}

          </button>

          <button

            type="button"

            className="flex-none px-4 py-2 text-sm text-gray-700 bg-gray-100 hover:bg-gray-200 rounded-md"

            onClick={onCancel}

          >

            Zrušit

          </button>

        </div>

      </form>

    </div>
  )
}