2026-05-26 02:39:46 +08:00

213 lines
9.1 KiB
JavaScript

import Add from "@mui/icons-material/Add";
import EditOutlined from "@mui/icons-material/EditOutlined";
import { AdminSwitch } from "@/shared/ui/AdminSwitch.jsx";
import TextField from "@mui/material/TextField";
import { formatMillis } from "@/shared/utils/time.js";
import { DataState } from "@/shared/ui/DataState.jsx";
import {
AdminActionIconButton,
AdminListBody,
AdminListPage,
AdminListToolbar,
AdminRowActions,
} from "@/shared/ui/AdminListLayout.jsx";
import { countryEnabledFilters } from "@/features/host-org/constants.js";
import { HostOrgActionModal } from "@/features/host-org/components/HostOrgActionModal.jsx";
import { HostOrgTable } from "@/features/host-org/components/HostOrgTable.jsx";
import { useHostCountriesPage } from "@/features/host-org/hooks/useHostCountriesPage.js";
import { createOptionsColumnFilter, createTextColumnFilter } from "@/shared/ui/tableFilters.js";
import styles from "@/features/host-org/host-org.module.css";
const baseCountryColumns = [
{ key: "countryId", label: "国家 ID", width: "minmax(90px, 0.6fr)" },
{
key: "flag",
label: "国旗",
render: (item) => <span className={styles.flagCell}>{item.flag || "-"}</span>,
width: "minmax(70px, 0.4fr)",
},
{ key: "countryCode", label: "国家码", width: "minmax(90px, 0.7fr)" },
{ key: "countryDisplayName", label: "展示名称", width: "minmax(150px, 1fr)" },
{ key: "countryName", label: "国家名称", width: "minmax(150px, 1fr)" },
{ key: "phoneCountryCode", label: "电话区号", width: "minmax(90px, 0.7fr)" },
{ key: "sortOrder", label: "排序", width: "minmax(80px, 0.5fr)" },
{
key: "updatedAtMs",
label: "更新时间",
render: (item) => formatMillis(item.updatedAtMs),
width: "minmax(170px, 1fr)",
},
];
export function HostCountriesPage() {
const page = useHostCountriesPage();
const createDisabled = !page.abilities.canCreate;
const updateDisabled = !page.abilities.canUpdate;
const items = page.data.items || [];
const total = page.data.total || 0;
const countryColumns = [
...baseCountryColumns.slice(0, 6),
{
key: "enabled",
label: "状态",
render: (item) => <CountryStatusSwitch item={item} page={page} />,
filter: createOptionsColumnFilter({
options: countryEnabledFilters,
placeholder: "搜索状态",
value: page.enabledStatus,
onChange: page.changeEnabledStatus,
}),
width: "minmax(90px, 0.6fr)",
},
...baseCountryColumns.slice(6),
].map((column) =>
column.key === "countryCode"
? {
...column,
filter: createTextColumnFilter({
placeholder: "搜索国家码、国家名称",
value: page.query,
onChange: page.changeQuery,
}),
}
: column,
);
const columns = page.abilities.canUpdate
? [
...countryColumns,
{
key: "actions",
label: "操作",
render: (item) => <CountryActions item={item} page={page} />,
width: "minmax(104px, 0.7fr)",
},
]
: countryColumns;
return (
<AdminListPage>
<AdminListToolbar
actions={
page.abilities.canCreate ? (
<AdminActionIconButton label="创建国家" primary onClick={page.openCreateCountry}>
<Add fontSize="small" />
</AdminActionIconButton>
) : null
}
/>
<DataState error={page.error} loading={page.loading} onRetry={page.reload}>
<AdminListBody>
<HostOrgTable
columns={columns}
items={items}
rowKey={(item) => item.countryId}
pagination={{ page: 1, pageSize: Math.max(items.length, 1), total }}
/>
</AdminListBody>
</DataState>
<HostOrgActionModal
disabled={page.activeAction === "edit" ? updateDisabled : createDisabled}
loading={page.loadingAction === "country-create" || page.loadingAction === "country-edit"}
open={page.activeAction === "create" || page.activeAction === "edit"}
sectionTitle="国家信息"
onClose={page.closeAction}
onSubmit={page.submitCountry}
title={page.activeAction === "edit" ? "编辑国家" : "创建国家"}
>
<TextField
disabled={page.activeAction === "edit" || createDisabled}
label="国家码"
required
value={page.countryForm.countryCode}
onChange={(event) => page.setCountryForm({ ...page.countryForm, countryCode: event.target.value })}
/>
<TextField
disabled={page.activeAction === "edit" ? updateDisabled : createDisabled}
label="展示名称"
required
value={page.countryForm.countryDisplayName}
onChange={(event) =>
page.setCountryForm({ ...page.countryForm, countryDisplayName: event.target.value })
}
/>
<TextField
disabled={page.activeAction === "edit" ? updateDisabled : createDisabled}
label="国家名称"
required
value={page.countryForm.countryName}
onChange={(event) => page.setCountryForm({ ...page.countryForm, countryName: event.target.value })}
/>
<TextField
disabled={page.activeAction === "edit" ? updateDisabled : createDisabled}
label="ISO Alpha-3"
value={page.countryForm.isoAlpha3}
onChange={(event) => page.setCountryForm({ ...page.countryForm, isoAlpha3: event.target.value })}
/>
<TextField
disabled={page.activeAction === "edit" ? updateDisabled : createDisabled}
label="ISO Numeric"
value={page.countryForm.isoNumeric}
onChange={(event) => page.setCountryForm({ ...page.countryForm, isoNumeric: event.target.value })}
/>
<TextField
disabled={page.activeAction === "edit" ? updateDisabled : createDisabled}
label="电话区号"
value={page.countryForm.phoneCountryCode}
onChange={(event) =>
page.setCountryForm({ ...page.countryForm, phoneCountryCode: event.target.value })
}
/>
<TextField
disabled={page.activeAction === "edit" ? updateDisabled : createDisabled}
label="国旗"
value={page.countryForm.flag}
onChange={(event) => page.setCountryForm({ ...page.countryForm, flag: event.target.value })}
/>
<TextField
disabled={page.activeAction === "edit" ? updateDisabled : createDisabled}
label="排序"
type="number"
value={page.countryForm.sortOrder}
onChange={(event) => page.setCountryForm({ ...page.countryForm, sortOrder: event.target.value })}
/>
{page.activeAction === "create" ? (
<AdminSwitch
checked={page.countryForm.enabled}
checkedLabel="启用"
disabled={createDisabled}
label="国家状态"
uncheckedLabel="停用"
onChange={(event) =>
page.setCountryForm({ ...page.countryForm, enabled: event.target.checked })
}
/>
) : null}
</HostOrgActionModal>
</AdminListPage>
);
}
function CountryActions({ item, page }) {
return (
<AdminRowActions>
{page.abilities.canUpdate ? (
<AdminActionIconButton label="编辑国家" onClick={() => page.openEditCountry(item)}>
<EditOutlined fontSize="small" />
</AdminActionIconButton>
) : null}
</AdminRowActions>
);
}
function CountryStatusSwitch({ item, page }) {
return (
<AdminSwitch
checked={Boolean(item.enabled)}
disabled={!page.abilities.canStatus || page.loadingAction === `country-status-${item.countryId}`}
inputProps={{ "aria-label": item.enabled ? "禁用国家" : "启用国家" }}
onChange={(event) => page.toggleCountry(item, event.target.checked)}
/>
);
}