{"type":"assistant","message":{"id":"2099424a-0948-4423-a191-3c37d24e52ed","type":"message","role":"assistant","model":"deepseek-v4-flash","content":[{"type":"thinking","thinking":"The user wants me to generate a commit message based on the git diff provided. Let me analyze the changes:
1. **AdminLayout.tsx** - Major changes:
- Added imports for `NavLink`, `useNavigate`, `BookOpenIcon`, `ListIcon`, `LogOutIcon`, `Button`, `useAuthStore`, `usePlatform`
- Added navigation items array with book management and borrow management
- Added admin layout with sidebar navigation, header with username, and logout functionality
- Added responsive layout for desktop/mobile
2. **router/index.tsx** - Changes:
- Removed placeholder components (`AdminBooksPage`, `AdminBorrowsPage`, `AdminIndexPage`)
- Added imports from actual admin feature pages
- Updated routes to use real admin layout and pages
This is clearly a **feat** (new feature) commit, adding admin layout with navigation and routing to real pages. The scope would be **admin** or **ui**.
The key changes are:
- Adding admin sidebar navigation with book/borrow management links
- Adding logout functionality with username display
- Replacing placeholder admin page components with real page implementations
- Integrating admin layout with the router
Let me write a concise commit message following the rules.","signature":"2099424a-0948-4423-a191-3c37d24e52ed"}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":25016,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":0,"service_tier":"standard"},"context_management":null},"parent_tool_use_id":null,"session_id":"bf312622-fae8-446d-8b67-c708b9d3a022","uuid":"50eb9e22-cc58-4b45-8f03-95386c522466"}{"type":"assistant","message":{"id":"2099424a-0948-4423-a191-3c37d24e52ed","type":"message","role":"assistant","model":"deepseek-v4-flash","content":[{"type":"text","text":"<commit>
feat(admin): add sidebar navigation and real page routes
Implement admin layout with sidebar navigation for book and borrow
management, including logout functionality and username display.
Replace placeholder admin page components with actual page routes."}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":25016,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":0,"service_tier":"standard"},"context_management":null},"parent_tool_use_id":null,"session_id":"bf312622-fae8-446d-8b67-c708b9d3a022","uuid":"1ca45e82-b885-4fa0-b886-fdfced0dc2e4"}<commit>
This commit is contained in:
@@ -18,12 +18,14 @@ import {
|
||||
} from "@/components/ui/alert-dialog"
|
||||
import { useAdminBorrows, useSearchBorrows, useAdminReturnBook } from "./hooks"
|
||||
import { usePlatform } from "@/hooks/usePlatform"
|
||||
import { useIsMobile } from "@/hooks/useIsMobile"
|
||||
import { formatDateTime } from "@/lib/formatters"
|
||||
import type { BorrowInfoVo } from "@/types/api"
|
||||
|
||||
export default function AdminBorrowsPage() {
|
||||
const platform = usePlatform()
|
||||
const isDesktop = platform === "web" || platform === "desktop"
|
||||
const isMobile = useIsMobile()
|
||||
const sel = platform === "web" ? ({ "data-selectable": true } as const) : ({} as const)
|
||||
|
||||
const [searchText, setSearchText] = useState("")
|
||||
const [debounced, setDebounced] = useState("")
|
||||
@@ -41,7 +43,7 @@ export default function AdminBorrowsPage() {
|
||||
const returnMutation = useAdminReturnBook()
|
||||
const [returnTarget, setReturnTarget] = useState<BorrowInfoVo | null>(null)
|
||||
|
||||
if (isLoading) return <AdminBorrowsSkeleton isDesktop={isDesktop} />
|
||||
if (isLoading) return <AdminBorrowsSkeleton isMobile={isMobile} />
|
||||
if (error) {
|
||||
return (
|
||||
<div className="rounded-lg border border-destructive/50 bg-destructive/10 px-4 py-3 text-sm text-destructive">
|
||||
@@ -68,7 +70,7 @@ export default function AdminBorrowsPage() {
|
||||
<p className="py-16 text-center text-muted-foreground">
|
||||
{isSearching ? "无匹配记录" : "暂无借阅记录"}
|
||||
</p>
|
||||
) : isDesktop ? (
|
||||
) : !isMobile ? (
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
@@ -86,9 +88,10 @@ export default function AdminBorrowsPage() {
|
||||
<BorrowRow
|
||||
key={r.id}
|
||||
record={r}
|
||||
isDesktop
|
||||
isMobile={false}
|
||||
returning={returnMutation.isPending}
|
||||
onReturn={() => setReturnTarget(r)}
|
||||
sel={sel}
|
||||
/>
|
||||
))}
|
||||
</TableBody>
|
||||
@@ -100,9 +103,10 @@ export default function AdminBorrowsPage() {
|
||||
<CardContent className="space-y-1.5 p-4">
|
||||
<BorrowRow
|
||||
record={r}
|
||||
isDesktop={false}
|
||||
isMobile
|
||||
returning={returnMutation.isPending}
|
||||
onReturn={() => setReturnTarget(r)}
|
||||
sel={sel}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
@@ -136,14 +140,16 @@ export default function AdminBorrowsPage() {
|
||||
|
||||
function BorrowRow({
|
||||
record,
|
||||
isDesktop,
|
||||
isMobile,
|
||||
returning,
|
||||
onReturn,
|
||||
sel,
|
||||
}: {
|
||||
record: BorrowInfoVo
|
||||
isDesktop: boolean
|
||||
isMobile: boolean
|
||||
returning: boolean
|
||||
onReturn: () => void
|
||||
sel: Record<string, unknown>
|
||||
}) {
|
||||
const statusBadge = (
|
||||
<Badge variant={record.status === "BORROWED" ? "default" : "secondary"}>
|
||||
@@ -152,17 +158,17 @@ function BorrowRow({
|
||||
)
|
||||
|
||||
const returnButton = record.status === "BORROWED" && (
|
||||
<Button size={isDesktop ? "xs" : "sm"} variant="outline" disabled={returning} onClick={onReturn}>
|
||||
<Button size={isMobile ? "sm" : "xs"} variant="outline" disabled={returning} onClick={onReturn}>
|
||||
{returning && <Loader2Icon className="animate-spin" />}
|
||||
代为归还
|
||||
</Button>
|
||||
)
|
||||
|
||||
if (isDesktop) {
|
||||
if (!isMobile) {
|
||||
return (
|
||||
<TableRow>
|
||||
<TableCell>{record.id}</TableCell>
|
||||
<TableCell className="font-medium">{record.bookBorrowVo.name}</TableCell>
|
||||
<TableCell className="font-medium" {...sel}>{record.bookBorrowVo?.name ?? "-"}</TableCell>
|
||||
<TableCell>{record.userBorrowVo.username}</TableCell>
|
||||
<TableCell>{formatDateTime(record.borrowTime)}</TableCell>
|
||||
<TableCell>{record.returnTime ? formatDateTime(record.returnTime) : "-"}</TableCell>
|
||||
@@ -178,7 +184,7 @@ function BorrowRow({
|
||||
<span className="text-xs text-muted-foreground">#{record.id}</span>
|
||||
{statusBadge}
|
||||
</div>
|
||||
<div className="font-medium">{record.bookBorrowVo.name}</div>
|
||||
<div className="font-medium" {...sel}>{record.bookBorrowVo?.name ?? "-"}</div>
|
||||
<div className="text-sm text-muted-foreground">借阅人:{record.userBorrowVo.username}</div>
|
||||
<div className="text-sm text-muted-foreground">
|
||||
借阅:{formatDateTime(record.borrowTime)}
|
||||
@@ -189,8 +195,8 @@ function BorrowRow({
|
||||
)
|
||||
}
|
||||
|
||||
function AdminBorrowsSkeleton({ isDesktop }: { isDesktop: boolean }) {
|
||||
if (!isDesktop) {
|
||||
function AdminBorrowsSkeleton({ isMobile }: { isMobile: boolean }) {
|
||||
if (isMobile) {
|
||||
return (
|
||||
<div className="space-y-3">
|
||||
<Skeleton className="h-7 w-24" />
|
||||
|
||||
Reference in New Issue
Block a user