"use client"; import { useState } from "react"; const inp = "w-full rounded-lg border border-[#262b40] bg-[#0c0e1a] px-3 py-2 text-sm text-gray-100 outline-none focus:border-indigo-500"; const lbl = "mb-1 block text-xs font-medium text-gray-400"; const btn = "rounded-lg bg-indigo-600 px-3 py-1.5 text-xs font-medium text-white hover:bg-indigo-500 disabled:opacity-50"; const card = "rounded-xl border border-[#1e2235] bg-[#0f1120]"; /** Per-user admin power-actions + CRM notes, opened as a modal from the Users table. */ export function UserActions({ row }: { row: Record; reload?: () => void }) { const id = String(row.id); const [open, setOpen] = useState(false); const [msg, setMsg] = useState(null); const [busy, setBusy] = useState(false); // form state const [balance, setBalance] = useState(""); const [balanceAdd, setBalanceAdd] = useState(true); const [pw, setPw] = useState(""); const [seconds, setSeconds] = useState(""); const [renders, setRenders] = useState(""); const [planDays, setPlanDays] = useState(""); const [slots, setSlots] = useState(String(row.parallel_rendering_ceiling ?? "1")); const [tags, setTags] = useState(""); const [note, setNote] = useState(""); const [status, setStatus] = useState("new"); // discount / affiliate const [dcCode, setDcCode] = useState(""); const [dcKind, setDcKind] = useState("Percentage"); const [dcValue, setDcValue] = useState(""); const [dcProfit, setDcProfit] = useState(""); const [dcDays, setDcDays] = useState("30"); // videos const [vids, setVids] = useState> | null>(null); const createDiscount = async () => { setBusy(true); setMsg(null); const expires = new Date(Date.now() + (Number(dcDays) || 30) * 864e5).toISOString(); const res = await fetch(`/api/admin/resource/discounts`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name: dcCode || `user-${id.slice(0, 8)}`, code: dcCode, kind: dcKind, value: Number(dcValue) || 0, owner_user_id: id, owner_profit_percentage: Number(dcProfit) || 0, expires_at: expires, }), }); const d = await res.json().catch(() => null); setMsg(res.ok ? (Number(dcProfit) > 0 ? "کد افیلیت ساخته شد ✓" : "کد تخفیف ساخته شد ✓") : (d?.error?.message ?? d?.error ?? "خطا")); setBusy(false); }; const loadVideos = async () => { const r = await fetch(`/api/admin/resource/saved-projects/by-user/${id}?pageSize=50`, { cache: "no-store" }) .then((x) => x.json()).catch(() => null); setVids(r?.data ?? r?.items ?? (Array.isArray(r) ? r : [])); }; const call = async (path: string, body: object, ok: string) => { setBusy(true); setMsg(null); const res = await fetch(`/api/admin/resource/${path}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), }); const d = await res.json().catch(() => null); setMsg(res.ok ? ok : (d?.error?.message ?? d?.error ?? "خطا")); setBusy(false); }; const loadCrm = async () => { const r = await fetch(`/api/admin/resource/users/${id}/crm`, { cache: "no-store" }).then((x) => x.json()).catch(() => null); if (r) { setTags((r.tags ?? []).join(", ")); setNote(r.note ?? ""); setStatus(r.status ?? "new"); } }; const saveCrm = async () => { setBusy(true); setMsg(null); const res = await fetch(`/api/admin/resource/users/${id}/crm`, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ tags: tags.split(",").map((t) => t.trim()).filter(Boolean), note, status }), }); setMsg(res.ok ? "یادداشت ذخیره شد ✓" : "خطا"); setBusy(false); }; return ( <> {open && (
setOpen(false)}>
e.stopPropagation()}>

مدیریت کاربر: {String(row.email ?? row.full_name ?? id)}

{msg &&

{msg}

}
setBalance(e.target.value)} />
setSeconds(e.target.value)} /> setRenders(e.target.value)} />
setPlanDays(e.target.value)} />
setPw(e.target.value)} placeholder="رمز جدید" />

پیش‌فرض ۱. با افزایش این مقدار، کاربر می‌تواند چند رندر هم‌زمان اجرا کند (پس از تازه‌سازی توکن اعمال می‌شود).

setSlots(e.target.value)} />
دسترسی مدیر (مدراتور)
setDcCode(e.target.value)} /> setDcValue(e.target.value)} /> setDcProfit(e.target.value)} /> setDcDays(e.target.value)} />
{vids != null && ( vids.length === 0 ?

ویدیویی یافت نشد.

: (
    {vids.map((v) => (
  • {String(v.name ?? v.original_project_name ?? "—")} {String(v.type ?? "")} · {String(v.resolution ?? "")}
  • ))}
) )}
setTags(e.target.value)} />