"use client"; import { useState } from "react"; import { apiFetch, getApproToken } from "@/lib/api"; import { APPRO_BASE_URL, MEDITATION_BASE_URL } from "@/lib/config"; import { usePaginated } from "@/lib/useResource"; import { DataTable, type Column } from "@/components/DataTable"; import { Badge, Button, Card, Modal, PageHeader, Pagination, Select, Spinner, } from "@/components/ui"; import { EyeIcon } from "@/components/icons"; import { toFa } from "@/lib/utils"; interface MeditationUser { id: number; full_name?: string; first_name?: string; last_name?: string; age?: number | null; gender?: number | null; email?: string | null; mobile?: string | null; identifier?: string | null; created_at?: string; answers_count?: number; questions_answered?: number; } interface ApproUser { id: number; uuid?: string; first_name?: string; last_name?: string; full_name?: string; age?: number | null; gender?: number | null; email?: string | null; mobile?: string | null; birthday?: string | null; created_at?: string; } interface SurveyAnswerItem { question_id: number; question?: string; type?: string; answers: { option_id: number; label: string }[]; } interface DetailData { appro: ApproUser | null; survey_answers: SurveyAnswerItem[]; answers_count?: number; questions_answered?: number; } const GENDER_LABELS: Record = { 1: "مرد", 2: "زن", }; function faDate(value?: string): string { if (!value) return "—"; try { return toFa(new Date(value).toLocaleDateString("fa-IR")); } catch { return "—"; } } export default function UsersPage() { const [answered, setAnswered] = useState(""); const { data, meta, page, setPage, loading, error, reload } = usePaginated("/admin/survey-users", { perPage: 20, query: answered ? { answered } : undefined, }); const [detailUser, setDetailUser] = useState(null); const [detailData, setDetailData] = useState(null); const [detailOpen, setDetailOpen] = useState(false); const [detailLoading, setDetailLoading] = useState(false); async function openDetail(user: MeditationUser) { setDetailOpen(true); setDetailLoading(true); setDetailUser(user); setDetailData(null); const [appro, survey] = await Promise.all([ user.mobile ? apiFetch<{ data: ApproUser[] }>("/admin/users", { query: { mobile: user.mobile, per_page: 1 }, baseUrl: APPRO_BASE_URL, headers: { Authorization: `Bearer ${getApproToken()}` }, }).then((r) => r.data?.[0] ?? null) : Promise.resolve(null), apiFetch<{ survey_answers: SurveyAnswerItem[]; answers_count?: number; questions_answered?: number }>( `/admin/survey-users/${user.identifier || user.id}`, { baseUrl: MEDITATION_BASE_URL }, ).catch(() => ({ survey_answers: [], answers_count: undefined, questions_answered: undefined })), ]); // Sync approagency data back to meditation DB if user has null fields if (appro && user.mobile && (!user.first_name || user.age == null || user.gender == null)) { apiFetch(`/admin/survey-users/${user.identifier || user.id}`, { method: "PATCH", baseUrl: MEDITATION_BASE_URL, body: { first_name: appro.first_name, last_name: appro.last_name, age: appro.age, gender: appro.gender, birthday: appro.birthday, identifier: appro.uuid, email: appro.email, }, }).catch(() => {}); // fire-and-forget } setDetailData({ appro, survey_answers: survey.survey_answers ?? [], answers_count: survey.answers_count, questions_answered: survey.questions_answered, }); setDetailLoading(false); } const columns: Column[] = [ { key: "id", header: "شناسه", render: (r) => toFa(r.id), className: "w-20" }, { key: "full_name", header: "نام", render: (r) => r.full_name || [r.first_name, r.last_name].filter(Boolean).join(" ") || "—", }, { key: "questions_answered", header: "پاسخ به سوالات", className: "w-32", render: (r) => r.questions_answered != null ? toFa(r.questions_answered) : "—", }, { key: "created_at", header: "تاریخ ثبت‌نام", className: "w-32", render: (r) => faDate(r.created_at), }, ]; const a = detailData?.appro; const s = detailData; const userName = a ? a.full_name || [a.first_name, a.last_name].filter(Boolean).join(" ") || "" : detailUser ? detailUser.full_name || [detailUser.first_name, detailUser.last_name].filter(Boolean).join(" ") || "" : ""; return (
( )} /> {meta && ( )} setDetailOpen(false)} title={userName ? `جزئیات کاربر — ${userName}` : "جزئیات کاربر"} footer={ } > {detailLoading && (
)} {s && !detailLoading && (

نام

{userName || "—"}

سن

{(a?.age ?? detailUser?.age) != null ? toFa(a?.age ?? detailUser!.age!) : "—"}

جنسیت

{(a?.gender ?? detailUser?.gender) != null ? GENDER_LABELS[a?.gender ?? detailUser!.gender!] ?? "—" : "—"}

تاریخ تولد

{a?.birthday ? faDate(a.birthday) : "—"}

ایمیل

{(a?.email ?? detailUser?.email) || "—"}

موبایل

{detailUser?.mobile || "—"}

تعداد پاسخ‌ها

{s.answers_count != null ? toFa(s.answers_count) : "—"}

سوالات پاسخ داده شده

{s.questions_answered != null ? toFa(s.questions_answered) : "—"}

{s.survey_answers.length > 0 ? (

پاسخ‌های نظرسنجی

{s.survey_answers.map((item) => (

{item.question}

{item.answers.map((a) => ( {a.label} ))} {item.answers.length === 0 && ( بدون پاسخ )}
))}
) : (

این کاربر هنوز به هیچ سوالی پاسخ نداده است.

)}
)}
); }