Add the Healthcare platform backend (phases 13.0–13.7) with Alembic migration revision fix, production deploy script, validation reports, shared UI exports, and loyalty list page client directives so Next.js build succeeds. Co-authored-by: Cursor <cursoragent@cursor.com>
92 lines
3.3 KiB
TypeScript
92 lines
3.3 KiB
TypeScript
"use client";
|
|
|
|
import { z } from "zod";
|
|
import { loyaltyApi } from "@/modules/loyalty/services/loyalty-api";
|
|
import { createLoyaltyListPage } from "@/modules/loyalty/components/LoyaltyListCrudPage";
|
|
import { LoyaltyStatusChip } from "@/modules/loyalty/design-system";
|
|
import type { Reward } from "@/modules/loyalty/types";
|
|
|
|
const createSchema = z.object({
|
|
program_id: z.string().uuid(),
|
|
code: z.string().min(1),
|
|
name: z.string().min(1),
|
|
description: z.string().optional(),
|
|
reward_type: z.enum(["custom", "discount", "coupon", "voucher", "cashback", "gift"]).default("custom"),
|
|
status: z.enum(["draft", "active", "inactive", "archived"]).default("draft"),
|
|
points_cost: z.coerce.number().default(0),
|
|
stock_limit: z.coerce.number().optional(),
|
|
max_per_member: z.coerce.number().optional(),
|
|
});
|
|
const editSchema = createSchema.partial().omit({ program_id: true, code: true });
|
|
|
|
export default createLoyaltyListPage<Reward>({
|
|
title: "پاداشها",
|
|
description: "کاتالوگ پاداش قابل معاوضه با امتیاز.",
|
|
breadcrumb: "پاداشها",
|
|
resourceKey: "rewards",
|
|
createSchema,
|
|
editSchema,
|
|
createDefaults: {
|
|
program_id: "",
|
|
code: "",
|
|
name: "",
|
|
description: "",
|
|
reward_type: "custom",
|
|
status: "draft",
|
|
points_cost: 0,
|
|
},
|
|
fields: [
|
|
{ name: "program_id", label: "برنامه", createOnly: true, required: true },
|
|
{ name: "code", label: "کد", createOnly: true, required: true },
|
|
{ name: "name", label: "نام", required: true },
|
|
{ name: "description", label: "توضیحات", type: "textarea" },
|
|
{
|
|
name: "reward_type",
|
|
label: "نوع",
|
|
type: "select",
|
|
options: [
|
|
{ value: "custom", label: "سفارشی" },
|
|
{ value: "discount", label: "تخفیف" },
|
|
{ value: "coupon", label: "کوپن" },
|
|
{ value: "voucher", label: "واچر" },
|
|
{ value: "cashback", label: "کشبک" },
|
|
{ value: "gift", label: "هدیه" },
|
|
],
|
|
},
|
|
{
|
|
name: "status",
|
|
label: "وضعیت",
|
|
type: "select",
|
|
options: [
|
|
{ value: "draft", label: "پیشنویس" },
|
|
{ value: "active", label: "فعال" },
|
|
{ value: "inactive", label: "غیرفعال" },
|
|
{ value: "archived", label: "آرشیو" },
|
|
],
|
|
},
|
|
{ name: "points_cost", label: "هزینه امتیاز", type: "number" },
|
|
],
|
|
columns: [
|
|
{ key: "code", header: "کد" },
|
|
{ key: "name", header: "نام" },
|
|
{ key: "points_cost", header: "امتیاز" },
|
|
{
|
|
key: "reward_type",
|
|
header: "نوع",
|
|
render: (r) => <LoyaltyStatusChip status={r.reward_type} domain="reward_type" />,
|
|
},
|
|
{
|
|
key: "status",
|
|
header: "وضعیت",
|
|
render: (r) => <LoyaltyStatusChip status={r.status} domain="reward" />,
|
|
},
|
|
{ key: "redeemed_count", header: "مصرف" },
|
|
],
|
|
list: (tid) => loyaltyApi.rewards.list(tid, { page: 1, page_size: 500 }),
|
|
create: (tid, d) => loyaltyApi.rewards.create(tid, d),
|
|
update: (tid, id, d) => loyaltyApi.rewards.update(tid, id, d),
|
|
remove: (tid, id) => loyaltyApi.rewards.delete(tid, id),
|
|
filterDeleted: true,
|
|
exportColumns: ["code", "name", "reward_type", "status", "points_cost", "redeemed_count"],
|
|
});
|