81 lines
4.7 KiB
TypeScript
81 lines
4.7 KiB
TypeScript
"use client";
|
|
|
|
import { useState, type FormEvent } from "react";
|
|
import { Alert, AlertDescription } from "@/components/ui/alert";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
|
|
import { Field, FieldGroup, FieldLabel } from "@/components/ui/field";
|
|
import { Input } from "@/components/ui/input";
|
|
import { authClient } from "@/lib/auth/client";
|
|
|
|
export function EmailSettings({ email, verified, callbackCompleted, callbackError }: {
|
|
email: string; verified: boolean; callbackCompleted: boolean; callbackError: boolean;
|
|
}) {
|
|
const [newEmail, setNewEmail] = useState("");
|
|
const [busy, setBusy] = useState(false);
|
|
const [sending, setSending] = useState(false);
|
|
const [error, setError] = useState("");
|
|
const [message, setMessage] = useState("");
|
|
|
|
async function requestVerification() {
|
|
if (sending) return;
|
|
setSending(true);
|
|
setError("");
|
|
setMessage("");
|
|
try {
|
|
const result = await authClient.sendVerificationEmail({ email, callbackURL: "/profile?emailAction=1" });
|
|
if (result.error) throw new Error("ส่งลิงก์ยืนยันไม่สำเร็จ กรุณาลองอีกครั้ง");
|
|
setMessage("ส่งลิงก์ยืนยันแล้ว กรุณาตรวจสอบอีเมลของคุณ");
|
|
} catch (cause) {
|
|
setError(cause instanceof Error ? cause.message : "ส่งลิงก์ยืนยันไม่สำเร็จ");
|
|
} finally { setSending(false); }
|
|
}
|
|
|
|
async function changeEmail(event: FormEvent<HTMLFormElement>) {
|
|
event.preventDefault();
|
|
if (busy) return;
|
|
setBusy(true);
|
|
setError("");
|
|
setMessage("");
|
|
try {
|
|
const targetEmail = newEmail.trim();
|
|
const result = await authClient.changeEmail({ newEmail: targetEmail, callbackURL: "/profile?emailAction=1" });
|
|
if (result.error?.code === "SESSION_NOT_FRESH")
|
|
throw new Error("กรุณาออกจากระบบและเข้าสู่ระบบอีกครั้งก่อนเปลี่ยนอีเมล");
|
|
if (result.error) throw new Error("เปลี่ยนอีเมลไม่สำเร็จ กรุณาลองอีกครั้ง");
|
|
setNewEmail("");
|
|
setMessage(verified
|
|
? `ตรวจสอบ ${email} เพื่ออนุมัติการเปลี่ยนแปลง`
|
|
: `ตรวจสอบ ${targetEmail} เพื่อยืนยันการเปลี่ยนแปลง`);
|
|
} catch (cause) {
|
|
setError(cause instanceof Error ? cause.message : "เปลี่ยนอีเมลไม่สำเร็จ");
|
|
} finally { setBusy(false); }
|
|
}
|
|
|
|
return <Card>
|
|
<CardHeader><CardTitle>อีเมล</CardTitle></CardHeader>
|
|
<CardContent className="flex flex-col gap-4">
|
|
<p className="text-sm">{email} - {verified ? "ยืนยันแล้ว" : "ยังไม่ยืนยัน"}</p>
|
|
{callbackCompleted && <Alert><AlertDescription>ยืนยันขั้นตอนแล้ว หากกำลังเปลี่ยนอีเมล โปรดตรวจสอบกล่องจดหมายสำหรับขั้นตอนถัดไป</AlertDescription></Alert>}
|
|
{callbackError && <Alert variant="destructive"><AlertDescription>ลิงก์ยืนยันไม่ถูกต้องหรือหมดอายุ กรุณาขอลิงก์ใหม่</AlertDescription></Alert>}
|
|
{message && <Alert><AlertDescription>{message}</AlertDescription></Alert>}
|
|
{error && <Alert variant="destructive"><AlertDescription>{error}</AlertDescription></Alert>}
|
|
<form id="change-email-form" onSubmit={changeEmail}>
|
|
<FieldGroup><Field>
|
|
<FieldLabel htmlFor="new-email">อีเมลใหม่</FieldLabel>
|
|
<Input id="new-email" type="email" value={newEmail} onChange={(event) => setNewEmail(event.target.value)}
|
|
autoComplete="email" required disabled={busy || sending} />
|
|
</Field></FieldGroup>
|
|
</form>
|
|
</CardContent>
|
|
<CardFooter className="flex-wrap gap-2">
|
|
<Button type="submit" form="change-email-form" disabled={busy || sending || !newEmail.trim() || newEmail.trim().toLowerCase() === email.toLowerCase()}>
|
|
{busy ? "กำลังดำเนินการ..." : "เปลี่ยนอีเมล"}
|
|
</Button>
|
|
{!verified && <Button variant="outline" onClick={requestVerification} disabled={busy || sending}>
|
|
{sending ? "กำลังส่ง..." : "ขอลิงก์ยืนยันอีเมล"}
|
|
</Button>}
|
|
</CardFooter>
|
|
</Card>;
|
|
}
|