"use client"; import { useState } from "react"; import { useTranslations } from "next-intl"; import { useRouter } from "@/i18n/routing"; import { apiPost, ApiClientError } from "@/lib/api/client"; import type { AuthTokenResponse } from "@/lib/api/types"; import { useAuthStore } from "@/lib/stores/auth.store"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { LabeledField } from "@/components/ui/labeled-field"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; export default function LoginPage() { const t = useTranslations("auth"); const router = useRouter(); const setAuth = useAuthStore((s) => s.setAuth); const [phone, setPhone] = useState("09121234567"); const [code, setCode] = useState(""); const [step, setStep] = useState<"phone" | "otp">("phone"); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const authErrorMessage = (err: unknown) => { if (err instanceof ApiClientError) { switch (err.code) { case "RATE_LIMITED": return t("rateLimited"); case "NOT_FOUND": return t("notFound"); case "SMS_FAILED": return t("smsFailed"); case "INVALID_OTP": return t("invalidOtp"); default: return err.message; } } return err instanceof Error ? err.message : t("title"); }; const sendOtp = async () => { setLoading(true); setError(null); try { await apiPost("/api/auth/send-otp", { phone }); setStep("otp"); } catch (e) { setError(authErrorMessage(e)); } finally { setLoading(false); } }; const verifyOtp = async () => { setLoading(true); setError(null); try { const data = await apiPost("/api/auth/verify-otp", { phone, code, }); setAuth(data); router.push("/pos"); } catch (e) { setError(authErrorMessage(e)); } finally { setLoading(false); } }; return (
{t("title")}

{t("subtitle")}

{step === "phone" ? (
{ e.preventDefault(); if (!loading) void sendOtp(); }} > setPhone(e.target.value)} placeholder={t("phonePlaceholder")} dir="ltr" className="text-end" autoComplete="tel" />
) : (
{ e.preventDefault(); if (!loading) void verifyOtp(); }} > setCode(e.target.value)} placeholder={t("otpPlaceholder")} maxLength={6} dir="ltr" className="text-center tracking-widest" autoComplete="one-time-code" />
)} {error && (

{error}

)}
); }