"use client"; import { FormEvent, useCallback, useEffect, useMemo, useState } from "react"; import Link from "next/link"; import { AdminPageHeader, Banner, Button, EmptyState, Modal } from "@/components/admin/controls"; import { useMe } from "@/hooks/useMe"; import type { CommercialAdminResourceDef } from "../admin/resources"; import { createAdminRegistryItem, deleteAdminRegistryItem, listAdminRegistry, type RegistryRecord, updateAdminRegistryItem, } from "../adapters/admin"; import type { AdapterResult } from "../types"; import { enumLabel, fieldLabel, friendlyMessage, humanizeCommercialCode, isTechnicalField, } from "../presentation"; const PAGE_SIZE = 10; const FIELD_GROUPS = [ { title: "اطلاعات پایه", keys: ["display_name", "title", "description", "category"] }, { title: "اطلاعات تجاری", keys: ["role", "pricing_model", "amount_minor", "currency", "interval", "trial_days", "duration_days", "grace_period_days"] }, { title: "قیمت‌گذاری", keys: ["pricing_refs", "tax_class_code", "discount_refs", "coupon_code"] }, { title: "قابلیت‌ها", keys: ["product_codes", "capability_codes", "feature_refs", "required_capabilities"] }, { title: "نمایش", keys: ["visibility", "display_order", "trial_eligible"] }, { title: "انتشار", keys: ["status", "published_at", "starts_at", "ends_at"] }, { title: "اطلاعات تکمیلی", keys: ["metadata", "attributes", "parameters", "usage_limits", "feature_limits"] }, ] as const; function recordLabel(item: RegistryRecord, resource: CommercialAdminResourceDef): string { const name = item[resource.nameField]; return humanizeCommercialCode(item[resource.codeField], typeof name === "string" ? name : null); } function recordCode(item: RegistryRecord, resource: CommercialAdminResourceDef): string { const code = item[resource.codeField]; return code == null ? "" : String(code); } function recordTargetId(item: RegistryRecord, resource: CommercialAdminResourceDef): string { const target = item.registry_object_id ?? item.id ?? item[resource.codeField]; return target == null ? "" : String(target); } function defaultRecord(resource: CommercialAdminResourceDef): RegistryRecord { const seed: RegistryRecord = { [resource.codeField]: "", [resource.nameField]: "", status: "draft", }; if (resource.key === "products") Object.assign(seed, { visibility: "public", display_order: 0 }); if (resource.key === "trial-rules") Object.assign(seed, { duration_days: 14, grace_period_days: 3, auto_disable: true }); if (resource.key === "pricing") Object.assign(seed, { pricing_model: "monthly", currency: "IRR", amount_minor: 0 }); if (resource.key === "policies") Object.assign(seed, { effect: "deny", parameters: { custom_domain_allowed: false, subdomain_only: true, ssl_ready: false } }); return seed; } function parseFieldValue(key: string, input: string, current: unknown): unknown { if (Array.isArray(current) || /(_refs|_codes|capabilities)$/.test(key)) { return input.split("،").flatMap((part) => part.split(",")).map((part) => part.trim()).filter(Boolean); } if (typeof current === "number" || /(amount|days|order|percent|limit)$/.test(key)) { return input === "" ? null : Number(input); } return input; } function FieldInput({ name, value, onChange, }: { name: string; value: unknown; onChange: (value: unknown) => void; }) { if (Array.isArray(value)) { return (

{fieldLabel(name)}

{value.length ? value.map((item, index) => ( {humanizeCommercialCode(item)} )) : موردی انتخاب نشده است.}
); } if (typeof value === "boolean") { return ( ); } if (value && typeof value === "object" && !Array.isArray(value)) { return (
{fieldLabel(name)}
{Object.entries(value as Record) .filter(([key]) => !isTechnicalField(key)) .map(([key, nested]) => ( onChange({ ...(value as Record), [key]: next })} /> ))}
); } const displayValue = value == null ? "" : String(value); const selectOptions: Record = { status: ["draft", "active", "published", "inactive"], visibility: ["public", "private", "hidden"], pricing_model: ["monthly", "yearly", "trial", "enterprise_quote"], interval: ["monthly", "yearly"], currency: ["IRR"], }; if (selectOptions[name]) { return ( ); } return (