"use client"; import { useState, useTransition, useEffect, useRef } from "react"; import { grantCourseAccess, getPublishedCourses } from "@/app/admin/users/enroll-action"; interface Course { id: string; title: string; } interface Props { userId: string; userName: string; } export function QuickEnrollButton({ userId, userName }: Props) { const [open, setOpen] = useState(false); const [courses, setCourses] = useState([]); const [loadingCourses, setLoadingCourses] = useState(false); const [courseId, setCourseId] = useState(""); const [expiresAt, setExpiresAt] = useState(""); const [status, setStatus] = useState<"idle" | "success" | "error">("idle"); const [errorMsg, setErrorMsg] = useState(""); const [pending, startTransition] = useTransition(); const dialogRef = useRef(null); // Load courses when modal opens useEffect(() => { if (!open) return; setLoadingCourses(true); getPublishedCourses() .then((data) => { setCourses(data); if (data.length > 0) setCourseId(data[0].id); }) .finally(() => setLoadingCourses(false)); }, [open]); // Close on Escape useEffect(() => { if (!open) return; const handler = (e: KeyboardEvent) => { if (e.key === "Escape") handleClose(); }; window.addEventListener("keydown", handler); return () => window.removeEventListener("keydown", handler); }, [open]); function handleOpen() { setStatus("idle"); setErrorMsg(""); setExpiresAt(""); setCourseId(""); setOpen(true); } function handleClose() { if (pending) return; setOpen(false); } function handleSubmit() { if (!courseId) return; const expiry = expiresAt ? new Date(expiresAt) : null; startTransition(async () => { const result = await grantCourseAccess(userId, courseId, expiry); if ("error" in result) { setStatus("error"); setErrorMsg(result.error); } else { setStatus("success"); setTimeout(() => setOpen(false), 1200); } }); } return ( <> {/* Trigger button */} {/* Modal overlay */} {open && (
{ if (e.target === e.currentTarget) handleClose(); }} >
{/* Header */}

Выдать доступ

{userName}

{/* Course select */}
{loadingCourses ? (

Загрузка…

) : courses.length === 0 ? (

Нет опубликованных курсов

) : ( )}
{/* Expiry date (optional) */}
setExpiresAt(e.target.value)} disabled={pending} min={new Date().toISOString().slice(0, 10)} style={{ width: "100%", border: "2px solid var(--border)", background: "var(--background)", color: expiresAt ? "var(--foreground)" : "var(--muted-foreground)", padding: "0.4rem 0.5rem", fontSize: "13px", fontFamily: "inherit", outline: "none", }} onFocus={(e) => (e.currentTarget.style.borderColor = "var(--foreground)")} onBlur={(e) => (e.currentTarget.style.borderColor = "var(--border)")} />

Оставьте пустым для бессрочного доступа

{/* Error message */} {status === "error" && (

{errorMsg}

)} {/* Success message */} {status === "success" && (

Доступ выдан

)} {/* Actions */}
)} ); }