fix(ui): design-system consistency — typography, borders, admin IA, search removal

- typography: font-semibold/font-medium → font-bold throughout (card, dialog, empty-state, notification-bell, quiz-experience, questions-panel, profile-manage)
- borders: border → border-2 for content containers (leaderboard error, notifications page, quiz pass screen, quiz option tiles, learning-panel error)
- admin IA: remove Card-in-SectionPanel nesting from announce-panel, challenges-panel, physical-orders-panel; SectionPanel gains optional actions slot
- announce-panel: flat composer + live preview; history as flat list; cancel-edit button
- lockout: raw textarea → Textarea design-system component
- global-search: delete component and all references (feature removed)
- progress.tsx: dir="ltr" for correct RTL fill direction; remove rtl:me-auto
This commit is contained in:
ahp
2026-10-20 17:51:23 +03:30
parent 7716c1677c
commit 96b10c9148
15 changed files with 299 additions and 373 deletions
@@ -6,7 +6,6 @@ import { Loader2 } from "lucide-react";
import { http, toUserError } from "@/lib/api";
import type { CertificatePhysicalOrder, PhysicalCertSettings, PhysicalOrderStatus } from "@/lib/types";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Input } from "@/components/ui/input";
import { toast } from "@/components/providers";
@@ -75,16 +74,16 @@ export function PhysicalOrdersPanel() {
};
return (
<Card>
<CardHeader className="flex flex-row flex-wrap items-center justify-between gap-3 space-y-0">
<CardTitle className="text-base">فهرست سفارش‌ها</CardTitle>
<div className="space-y-4">
<div className="flex flex-wrap items-center justify-between gap-3">
<p className="text-xs text-muted-foreground">پیگیری درخواست و ارسال گواهینامه فیزیکی.</p>
<div className="flex flex-wrap items-center gap-2">
<select
className="h-10 rounded-lg border border-input bg-card px-3 text-sm outline-none focus-visible:ring-2 focus-visible:ring-ring"
value={statusFilter}
onChange={(e) => setStatusFilter(e.target.value)}
>
<option value="">همه</option>
<option value="">همه وضعیت‌ها</option>
<option value="requested">درخواست‌شده</option>
<option value="paid">پرداخت‌شده</option>
<option value="shipped">ارسال‌شده</option>
@@ -97,15 +96,15 @@ export function PhysicalOrdersPanel() {
</span>
)}
</div>
</CardHeader>
<CardContent className="space-y-2">
</div>
<div className="space-y-2">
{isLoading && (
<div className="flex justify-center py-8">
<Loader2 className="h-5 w-5 animate-spin text-muted-foreground" />
</div>
)}
{(data?.orders ?? []).map((o) => (
<div key={o.id} className="space-y-2 rounded-md border border-border px-3 py-3">
<div key={o.id} className="space-y-2 rounded-xl border border-border px-3 py-3">
<div className="flex flex-wrap items-center justify-between gap-2">
<div>
<p className="text-sm font-medium">{o.userName ?? `کاربر ${o.userId}`}</p>
@@ -167,7 +166,9 @@ export function PhysicalOrdersPanel() {
</div>
))}
{!isLoading && (data?.orders ?? []).length === 0 && (
<p className="py-8 text-center text-sm text-muted-foreground">سفارشی نیست.</p>
<p className="rounded-2xl border border-dashed border-border px-4 py-6 text-center text-sm text-muted-foreground">
سفارشی نیست.
</p>
)}
<ListPagination
page={page}
@@ -175,7 +176,7 @@ export function PhysicalOrdersPanel() {
total={data?.total ?? 0}
onPageChange={setPage}
/>
</CardContent>
</Card>
</div>
</div>
);
}