"use client"; import { FormEvent, useCallback, useEffect, useState } from "react"; import { api, ApiError, type Feature, type Plan } from "@/lib/api"; import { AdminPageHeader, Banner, Button, EmptyState, Modal, SelectField, StatusBadge, TextField, TextareaField, } from "@/components/admin/controls"; export default function AdminPlansPage() { const [plans, setPlans] = useState([]); const [features, setFeatures] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(""); const [createOpen, setCreateOpen] = useState(false); const [attachPlan, setAttachPlan] = useState(null); const load = useCallback(async () => { setLoading(true); setError(""); try { const [plansPage, featuresPage] = await Promise.all([ api.plans.list(1, 100), api.features.list(1, 100), ]); setPlans(plansPage.items); setFeatures(featuresPage.items); } catch (e) { setError(e instanceof ApiError ? e.message : "خطا در بارگذاری پلن‌ها"); } finally { setLoading(false); } }, []); useEffect(() => { void load(); }, [load]); return (
setCreateOpen(true)}>پلن جدید} /> {error && {error}}
{loading ? ( ) : plans.length === 0 ? ( ) : (
{plans.map((p) => ( ))}
نام کد وضعیت عملیات
{p.name} {p.code}
)}
setCreateOpen(false)} onCreated={() => { setCreateOpen(false); void load(); }} /> setAttachPlan(null)} onDone={() => setAttachPlan(null)} />
); } function CreatePlanModal({ open, onClose, onCreated, }: { open: boolean; onClose: () => void; onCreated: () => void; }) { const [code, setCode] = useState(""); const [name, setName] = useState(""); const [description, setDescription] = useState(""); const [isActive, setIsActive] = useState("true"); const [saving, setSaving] = useState(false); const [error, setError] = useState(""); const handleSubmit = async (e: FormEvent) => { e.preventDefault(); setError(""); setSaving(true); try { await api.plans.create({ code: code.trim(), name: name.trim(), description: description.trim() || null, is_active: isActive === "true", }); setCode(""); setName(""); setDescription(""); onCreated(); } catch (err) { setError(err instanceof ApiError ? err.message : "ایجاد پلن ناموفق بود"); } finally { setSaving(false); } }; return (
{error && {error}}
); } function AttachFeatureModal({ plan, features, onClose, onDone, }: { plan: Plan | null; features: Feature[]; onClose: () => void; onDone: () => void; }) { const [featureId, setFeatureId] = useState(""); const [limitValue, setLimitValue] = useState(""); const [limitPeriod, setLimitPeriod] = useState(""); const [saving, setSaving] = useState(false); const [error, setError] = useState(""); const [success, setSuccess] = useState(""); const handleSubmit = async (e: FormEvent) => { e.preventDefault(); if (!plan) return; setError(""); setSuccess(""); const fid = featureId || features[0]?.id; if (!fid) { setError("قابلیتی برای اتصال وجود ندارد."); return; } setSaving(true); try { await api.plans.attachFeature(plan.id, { feature_id: fid, limit_value: limitValue.trim() ? Number(limitValue) : null, limit_period: (limitPeriod || null) as | "day" | "month" | "year" | "total" | null, }); setSuccess("قابلیت با موفقیت متصل شد."); setLimitValue(""); setLimitPeriod(""); } catch (err) { setError(err instanceof ApiError ? err.message : "اتصال قابلیت ناموفق بود"); } finally { setSaving(false); } }; return ( {features.length === 0 ? (

ابتدا از بخش «قابلیت‌ها» یک قابلیت بسازید.

) : (
({ value: f.id, label: `${f.name} (${f.feature_key})`, }))} disabled={saving} /> {error && {error}} {success && {success}}
)}
); }