feat: add A-card operations frontend and backend foundation

This commit is contained in:
郑龙捷
2026-09-02 09:54:03 +08:00
parent 9badd3597f
commit ad71259ba5
106 changed files with 12461 additions and 1796 deletions
+41
View File
@@ -0,0 +1,41 @@
import { LockKeyhole } from "lucide-react";
import { Outlet, useLocation, useNavigate } from "react-router";
import { Button } from "~/components/ui/button";
import { Card, CardContent } from "~/components/ui/card";
import { OperationsDataBoundary, OperationsDataProvider } from "~/features/operations/OperationsDataContext";
import {
isOperationsPageVisibleForRole,
operationsPageFromPath,
useOperationsRole,
} from "~/features/operations/operationsRole";
export default function OperationsLayout() {
const role = useOperationsRole();
const location = useLocation();
const navigate = useNavigate();
const page = operationsPageFromPath(location.pathname);
if (!isOperationsPageVisibleForRole(role, page)) {
return (
<section className="grid h-full place-items-center bg-bg p-6">
<Card className="w-full max-w-xl">
<CardContent className="flex flex-col items-center py-12 text-center">
<span className="grid size-12 place-items-center rounded-2xl bg-warning-soft text-warning"><LockKeyhole className="size-6" /></span>
<h2 className="mt-4 text-xl font-bold text-foreground"></h2>
<p className="mt-2 text-sm leading-6 text-muted-foreground"></p>
<Button className="mt-5" onClick={() => navigate("/operations")}></Button>
</CardContent>
</Card>
</section>
);
}
return (
<OperationsDataProvider>
<OperationsDataBoundary>
<Outlet />
</OperationsDataBoundary>
</OperationsDataProvider>
);
}