shanshanzhong 6b92979c7c
Some checks failed
Build and Release / Build (push) Has been cancelled
feat: 自定义版本功能更新
- 新增家庭共享订阅管理
- 新增用户邀请统计
- 新增签名和订阅模式设置表单
- 更新 API 服务层和国际化文件
- UI 组件优化(enhanced-input、pro-table)
2026-03-19 01:56:13 -07:00

139 lines
4.0 KiB
TypeScript

import { Badge } from "@workspace/ui/components/badge";
import { Button } from "@workspace/ui/components/button";
import {
ProTable,
type ProTableActions,
} from "@workspace/ui/composed/pro-table/pro-table";
import { getFamilyList } from "@workspace/ui/services/admin/user";
import { useRef } from "react";
import { useTranslation } from "react-i18next";
import { formatDate } from "@/utils/common";
import { getFamilyStatusLabel, isFamilyStatusActive } from "./enums";
import { FamilyDetailSheet } from "./family-detail-sheet";
interface FamilyManagementProps {
initialFamilyId?: number;
initialUserId?: number;
onChanged?: () => void;
}
export default function FamilyManagement({
initialFamilyId,
initialUserId,
onChanged,
}: Readonly<FamilyManagementProps>) {
const { t } = useTranslation("user");
const ref = useRef<ProTableActions>(null);
const initialFilters = {
family_id: initialFamilyId || undefined,
user_id: initialUserId || undefined,
};
return (
<ProTable<API.FamilySummary, API.GetFamilyListParams>
action={ref}
actions={{
render: (row) => [
<FamilyDetailSheet
familyId={row.family_id}
key={`detail-${row.family_id}`}
onChanged={() => {
ref.current?.refresh();
onChanged?.();
}}
trigger={<Button>{t("familyDetail", "Family Detail")}</Button>}
/>,
],
}}
columns={[
{
accessorKey: "family_id",
header: t("familyId", "Family ID"),
},
{
accessorKey: "owner_identifier",
header: t("owner", "Owner"),
cell: ({ row }) =>
`${row.original.owner_identifier} (ID: ${row.original.owner_user_id})`,
},
{
accessorKey: "status",
header: t("status", "Status"),
cell: ({ row }) => {
const status = row.getValue("status") as string;
return isFamilyStatusActive(status) ? (
<Badge>{t("statusActive", "Active")}</Badge>
) : (
<Badge variant="secondary">
{getFamilyStatusLabel(t, status)}
</Badge>
);
},
},
{
accessorKey: "active_member_count",
header: t("memberCount", "Member Count"),
cell: ({ row }) =>
`${row.original.active_member_count}/${row.original.max_members}`,
},
{
accessorKey: "max_members",
header: t("familyMaxMembers", "Max Members"),
},
{
accessorKey: "created_at",
header: t("createdAt", "Created At"),
cell: ({ row }) => formatDate(row.getValue("created_at")),
},
{
accessorKey: "updated_at",
header: t("updatedAt", "Updated At"),
cell: ({ row }) => formatDate(row.getValue("updated_at")),
},
]}
header={{
title: t("familyManagement", "Family Group Management"),
}}
initialFilters={initialFilters}
key={String(initialFamilyId || initialUserId || "all")}
params={[
{
key: "keyword",
placeholder: t("search", "Search"),
},
{
key: "status",
placeholder: t("status", "Status"),
options: [
{ label: getFamilyStatusLabel(t, "active"), value: "active" },
{ label: getFamilyStatusLabel(t, "disabled"), value: "disabled" },
],
},
{
key: "owner_user_id",
placeholder: t("familyOwnerUserId", "Owner User ID"),
},
{
key: "family_id",
placeholder: t("familyId", "Family ID"),
},
{
key: "user_id",
placeholder: t("userId", "User ID"),
},
]}
request={async (pagination, filter) => {
const { data } = await getFamilyList({
...pagination,
...filter,
});
return {
list: data.data?.list || [],
total: data.data?.total || 0,
};
}}
/>
);
}