DG9 统一全站 UI 布局样板迁移
关联 Issue: DG9-0..DG9-12
这个提交包含在:
@@ -119,25 +119,25 @@ export function MobileNotificationsPage() {
|
||||
|
||||
return (
|
||||
<PageScaffold className="pb-4">
|
||||
<div className="space-y-3" data-testid="mobile-notifications-page">
|
||||
<PageHeader
|
||||
title="通知"
|
||||
meta={<span className="badge-neutral">未读 {listQuery.data?.unreadCount ?? 0}</span>}
|
||||
actions={
|
||||
<Button
|
||||
type="button"
|
||||
variant="secondary"
|
||||
data-testid="mobile-notifications-mark-all-read"
|
||||
disabled={(listQuery.data?.unreadCount ?? 0) === 0 || markAllReadMutation.isPending}
|
||||
onClick={() => markAllReadMutation.mutate()}
|
||||
>
|
||||
全部已读
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
<div className="mobile-page-stack" data-testid="mobile-notifications-page">
|
||||
<PageHeader
|
||||
title="通知"
|
||||
meta={<span className="badge-neutral">未读 {listQuery.data?.unreadCount ?? 0}</span>}
|
||||
actions={
|
||||
<Button
|
||||
type="button"
|
||||
variant="secondary"
|
||||
data-testid="mobile-notifications-mark-all-read"
|
||||
disabled={(listQuery.data?.unreadCount ?? 0) === 0 || markAllReadMutation.isPending}
|
||||
onClick={() => markAllReadMutation.mutate()}
|
||||
>
|
||||
全部已读
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
|
||||
<section className="mobile-card space-y-4" data-testid="mobile-notifications-list">
|
||||
<div className="space-y-3">
|
||||
<section className="mobile-card mobile-page-stack" data-testid="mobile-notifications-list">
|
||||
<div className="mobile-page-stack">
|
||||
<Tabs
|
||||
data-testid="mobile-notifications-filter-tabs"
|
||||
value={unreadOnly ? "unread" : "all"}
|
||||
@@ -158,7 +158,7 @@ export function MobileNotificationsPage() {
|
||||
</TabsList>
|
||||
</Tabs>
|
||||
|
||||
<label className="flex items-center gap-2 text-sm text-zinc-600">
|
||||
<label className="mobile-field-row text-sm text-zinc-600">
|
||||
<span className="shrink-0">类型</span>
|
||||
<select
|
||||
data-testid="mobile-notifications-type-filter"
|
||||
@@ -194,32 +194,42 @@ export function MobileNotificationsPage() {
|
||||
<div className="mobile-empty-state">暂无通知</div>
|
||||
) : null}
|
||||
|
||||
{notificationItems.map((item) => {
|
||||
const targetLink = resolveMobileNotificationTargetLink(item);
|
||||
return (
|
||||
<button
|
||||
data-testid="mobile-notification-card"
|
||||
key={item.id}
|
||||
className="mobile-list-card w-full text-left"
|
||||
type="button"
|
||||
onClick={() => void openNotificationTarget(item, targetLink)}
|
||||
>
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<div className="min-w-0">
|
||||
<div className="text-xs font-medium text-primary">{notificationTypeLabel(item.type)}</div>
|
||||
<div className="text-sm font-semibold text-zinc-900">{item.title}</div>
|
||||
{item.body ? <div className="mt-1 text-xs leading-5 text-zinc-500">{item.body}</div> : null}
|
||||
<div className="mobile-page-stack">
|
||||
{notificationItems.map((item) => {
|
||||
const targetLink = resolveMobileNotificationTargetLink(item);
|
||||
return (
|
||||
<button
|
||||
data-testid="mobile-notification-card"
|
||||
key={item.id}
|
||||
className="mobile-list-card w-full text-left"
|
||||
type="button"
|
||||
onClick={() => void openNotificationTarget(item, targetLink)}
|
||||
>
|
||||
<div className="mobile-list-card__header">
|
||||
<div className="min-w-0">
|
||||
<div className="text-xs font-medium text-primary">{notificationTypeLabel(item.type)}</div>
|
||||
<div className="mobile-list-card__title mt-0.5">{item.title}</div>
|
||||
{item.body ? <div className="mt-1 line-clamp-2 text-xs leading-5 text-zinc-500">{item.body}</div> : null}
|
||||
</div>
|
||||
<span className={item.readAt ? "badge-neutral mobile-status-slot" : "badge-warning mobile-status-slot"}>
|
||||
{item.readAt ? "已读" : "未读"}
|
||||
</span>
|
||||
</div>
|
||||
<span className={item.readAt ? "badge-neutral shrink-0" : "badge-warning shrink-0"}>
|
||||
{item.readAt ? "已读" : "未读"}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="mt-3 text-xs text-zinc-500">{formatTime(item.createdAt)}</div>
|
||||
<div className="mt-3 text-xs text-primary">{targetLink ? "直达详情" : "暂无直达详情"}</div>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
<div className="mobile-field-list mt-3">
|
||||
<div className="mobile-field-row">
|
||||
<div className="mobile-field-label">时间</div>
|
||||
<div className="mobile-field-value">{formatTime(item.createdAt)}</div>
|
||||
</div>
|
||||
<div className="mobile-field-row">
|
||||
<div className="mobile-field-label">去向</div>
|
||||
<div className="mobile-field-value text-primary">{targetLink ? "直达详情" : "暂无直达详情"}</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
<Pagination
|
||||
page={page}
|
||||
|
||||
在新工单中引用
屏蔽一个用户