update:Dialog替换

This commit is contained in:
xiaozhu
2026-08-26 16:48:19 +08:00
parent d7f3db1cc4
commit e326cc1a93
16 changed files with 738 additions and 675 deletions
@@ -1,8 +1,14 @@
import { useEffect, useState } from "react";
import { Plus, Search, X } from "lucide-react";
import { Plus, Search } from "lucide-react";
import { ApiRequestError, type Employee, type Role } from "../../services/api";
import { useApi, useAuth } from "../../context/AuthContext";
import {
AppFormDialog,
dialogPrimaryButtonClass,
dialogSecondaryButtonClass,
} from "~/components/common/AppFormDialog";
import { ConfirmDialog } from "~/components/common/ConfirmDialog";
import { Button } from "~/components/ui/button";
import { Input } from "~/components/ui/input";
import {
@@ -17,13 +23,7 @@ import { AdminColgroup, USER_PROJECT_COL_WIDTHS } from "./AdminTable";
import {
formFieldClass,
formInputClass,
modalBackdropClass,
modalCompactClass,
modalEyebrowClass,
modalFooterClass,
modalFormClass,
modalHeaderClass,
modalTitleClass,
} from "../platform/modalUi";
import "../../styles/admin.css";
@@ -37,10 +37,6 @@ const EMPTY_FORM = {
status: "active" as "active" | "disabled" | "locked",
};
const CLOSE_BUTTON_CLASS =
"size-[34px] rounded-[7px] border border-[#dfe6ed] bg-white hover:bg-[#f7faff] hover:border-[#b9c9da]";
const SECONDARY_BUTTON_CLASS =
"h-[37px] gap-[7px] rounded-md border-[#d8e1e9] bg-white px-[15px] text-xs font-[650] text-[#56687c]";
const PRIMARY_BUTTON_CLASS =
"h-[37px] gap-[7px] rounded-md border border-[#126ac3] bg-gradient-to-br from-[#1881e7] to-[#1268c9] px-[15px] text-xs font-[650] text-white shadow-[0_6px_15px_rgb(20_111_202/18%)] enabled:hover:from-[#1175d8] enabled:hover:to-[#0e5bad]";
const FORM_INPUT_CLASS =
@@ -67,6 +63,7 @@ export function UserManagementPage({
const [dialogOpen, setDialogOpen] = useState(false);
const [form, setForm] = useState(EMPTY_FORM);
const [userSearchTerm, setUserSearchTerm] = useState("");
const [deleteTarget, setDeleteTarget] = useState<Employee | null>(null);
const canManage = user?.role_code === "admin";
@@ -179,8 +176,7 @@ export function UserManagementPage({
}
};
const remove = async (employee: Employee): Promise<void> => {
if (!window.confirm(`确定从平台删除用户"${employee.display_name}"吗?`)) return;
const executeRemove = async (employee: Employee): Promise<void> => {
try {
await api.deletePlatformEmployee(employee.user_id);
setEmployees((current) => current.filter((item) => item.user_id !== employee.user_id));
@@ -274,7 +270,7 @@ export function UserManagementPage({
type="button"
disabled={!canManage || isProtectedAdmin}
title={isProtectedAdmin ? "管理员账号不能删除" : "删除"}
onClick={() => void remove(employee)}
onClick={() => setDeleteTarget(employee)}
className={ROW_DANGER_BUTTON_CLASS}
>
@@ -287,26 +283,15 @@ export function UserManagementPage({
</TableBody>
</Table>
{dialogOpen && (
<div className={modalBackdropClass} role="presentation">
<section className={modalCompactClass} role="dialog" aria-modal="true">
<div className={modalHeaderClass}>
<div>
<span className={modalEyebrowClass}>EMPLOYEE</span>
<h2 className={modalTitleClass}>{editing ? "编辑用户" : "添加用户"}</h2>
</div>
<Button
variant="ghost"
size="icon-sm"
type="button"
aria-label="关闭"
onClick={() => setDialogOpen(false)}
className={CLOSE_BUTTON_CLASS}
>
<X size={16} />
</Button>
</div>
<form className={modalFormClass} onSubmit={(event) => void submit(event)}>
<AppFormDialog
open={dialogOpen}
onOpenChange={(nextOpen) => {
if (!nextOpen) setDialogOpen(false);
}}
eyebrow="EMPLOYEE"
title={editing ? "编辑用户" : "添加用户"}
>
<form className={modalFormClass} onSubmit={(event) => void submit(event)}>
<label className={formFieldClass}>
<span><span className="text-[#e74c3c]">*</span></span>
<Input
@@ -388,13 +373,13 @@ export function UserManagementPage({
</select>
</label>
)}
<div className={modalFooterClass}>
<div className="mt-[3px] flex shrink-0 justify-end gap-2 border-t border-[#e8edf2] bg-white -mx-[22px] px-[22px] py-3.5">
<Button
variant="outline"
size="sm"
type="button"
onClick={() => setDialogOpen(false)}
className={SECONDARY_BUTTON_CLASS}
className={dialogSecondaryButtonClass}
>
</Button>
@@ -403,15 +388,33 @@ export function UserManagementPage({
size="sm"
type="submit"
disabled={saving}
className={PRIMARY_BUTTON_CLASS}
className={dialogPrimaryButtonClass}
>
{saving ? "保存中…" : "保存"}
</Button>
</div>
</form>
</section>
</div>
)}
</AppFormDialog>
<ConfirmDialog
open={deleteTarget !== null}
onOpenChange={(nextOpen) => {
if (!nextOpen) setDeleteTarget(null);
}}
title="确定删除用户?"
description={
deleteTarget
? `确定从平台删除用户"${deleteTarget.display_name}"吗?`
: ""
}
confirmLabel="删除"
destructive
onConfirm={async () => {
if (!deleteTarget) return;
await executeRemove(deleteTarget);
setDeleteTarget(null);
}}
/>
</section>
);
}