File size: 4,209 Bytes
769d6f8
 
dff8593
769d6f8
 
 
 
b283b34
7d72a03
769d6f8
 
 
 
 
7d72a03
769d6f8
 
 
 
 
 
 
 
 
 
 
7d72a03
769d6f8
 
 
 
dff8593
 
 
b00f0f1
 
769d6f8
dff8593
 
 
769d6f8
 
 
7447362
 
 
 
 
 
 
 
 
 
 
 
 
b283b34
769d6f8
 
763e887
769d6f8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7d72a03
 
 
 
 
 
769d6f8
 
7d72a03
 
769d6f8
 
 
 
 
 
 
b283b34
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
'use client'

import { useState } from 'react'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { useRouter } from 'next/navigation'
import { loginSchema, type LoginForm } from 'lib/validations/auth'
import { emitAuthChanged } from 'hooks/useAuth'
import { getSupabaseBrowserConfig, isSupabaseBrowserConfigured } from 'lib/supabase/publicEnv'

export function LoginForm() {
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const supabaseReady = isSupabaseBrowserConfigured()
  const supabaseEnv = getSupabaseBrowserConfig()
  const router = useRouter()

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

  const onSubmit = async (data: LoginForm) => {
    console.info('[login] submit', { supabaseReady, email: data.email, supabaseUrl: supabaseEnv.url })
    try {
      setLoading(true)
      setError(null)

      const res = await fetch('/api/auth/login', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(data),
        credentials: 'include'
      })
      const json = await res.json().catch(() => ({}))
      if (!res.ok) {
        setError(json?.error || 'Neplatné přihlašovací údaje')
        return
      }

      // store token from public cookie as fallback for environments where HttpOnly cookie isn't sent
      try {
        if (typeof window !== 'undefined') {
          const match = document.cookie.split(';').map(s => s.trim()).find(c => c.startsWith('letschat_session_pub='))
          if (match) {
            const token = match.split('=')[1]
            window.localStorage.setItem('letschat_session', token)
          }
        }
      } catch (e) {
        // ignore
      }

      emitAuthChanged()
      router.push('/dashboard')
    } catch (e: any) {
      console.error('Login error:', e)
      setError(e?.message || 'Došlo k neočekávané chybě při přihlášení')
    } finally {
      setLoading(false)
    }
  }

  return (
    <form id="form-login" action="#" method="post" className="form" onSubmit={handleSubmit(onSubmit)}>
      <div className="input">
        <div className="text">E-mail</div>
        <div className="insert">
          <input
            {...register('email')}
            type="email"
            maxLength={255}
            placeholder="E-mailová adresa"
            autoComplete="email"
          />
          <div className="error">{errors.email?.message}</div>
        </div>
      </div>

      <div className="input">
        <div className="text">Heslo</div>
        <div className="insert">
          <input
            {...register('password')}
            type="password"
            maxLength={255}
            placeholder="Heslo k přihlášení"
            autoComplete="current-password"
          />
          <div className="error">{errors.password?.message}</div>
          <div className="visible" data-input="password"></div>
        </div>
      </div>

      <div className="input">
        <div className="text"></div>
        <div className="insert">
          {error ? (
            <div
              className="error"
              style={{
                marginBottom: 12,
                padding: '10px 12px',
                background: '#FEE2E2',
                color: '#991B1B',
                borderRadius: 8,
                fontWeight: 600
              }}
            >
              {error}
            </div>
          ) : null}

          <input
            type="submit"
            value={loading ? 'Přihlašuji…' : 'Přihlásit'}
            disabled={loading}
            onClick={() => console.info('[login] button click', { supabaseReady, supabaseUrl: supabaseEnv.url })}
          />
          {!supabaseReady ? (
            <div className="error" style={{ marginTop: 8 }}>
              Přidejte Supabase klíče do prostředí Space (NEXT_PUBLIC_SUPABASE_URL a NEXT_PUBLIC_SUPABASE_ANON_KEY) a znovu
              spusťte build.
            </div>
          ) : null}
        </div>
      </div>
    </form>
  )
}