"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 { COMMERCIAL_FIELD_GROUPS, FIELD_ENUM_OPTIONS, commercialDescription, commercialEntityName, enumLabel, fieldLabel, formatDate, friendlyMessage, isTechnicalField, registryKindForField, } from "../presentation"; const PAGE_SIZE = 10; function recordLabel(item: RegistryRecord, resource: CommercialAdminResourceDef): string { const name = item[resource.nameField]; return commercialEntityName( resource.key, 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); } const DEFAULT_RECORD_VALUES: Partial< Record > = { products: { visibility: "public", display_order: 0 }, "trial-rules": { duration_days: 14, grace_period_days: 3, auto_disable: true }, pricing: { pricing_model: "monthly", currency: "IRR", amount_minor: 0 }, policies: { effect: "deny", parameters: { custom_domain_allowed: false, subdomain_only: true, ssl_ready: false, }, }, }; function defaultRecord(resource: CommercialAdminResourceDef): RegistryRecord { const seed: RegistryRecord = { [resource.codeField]: "", [resource.nameField]: "", status: "draft", }; Object.assign(seed, DEFAULT_RECORD_VALUES[resource.key] || {}); 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, resourceKind, entityCode, presentAsName = false, }: { name: string; value: unknown; onChange: (value: unknown) => void; resourceKind: string; entityCode?: unknown; presentAsName?: boolean; }) { if (Array.isArray(value)) { return (

{fieldLabel(name)}

{value.length ? value.map((item, index) => ( {commercialEntityName(registryKindForField(name) || resourceKind, 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 rawValue = value == null ? "" : String(value); const displayValue = !rawValue ? "" : presentAsName ? commercialEntityName(resourceKind, entityCode, rawValue) : name === "description" ? commercialDescription(resourceKind, rawValue) : rawValue; if (FIELD_ENUM_OPTIONS[name]) { return ( ); } return (