ui: responsive proportions - implicit column overflow fixes, meta grid single-col on mobile, consistent page max-widths, admin rows wrap
This commit is contained in:
@@ -109,7 +109,7 @@ export function DynamicForm({ fields, value, onChange, taxonomies }: {
|
||||
return (
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-x-3 gap-y-3.5">
|
||||
{fields.map(f => (
|
||||
<div key={f.key} className={f.widget === 'textarea' ? 'col-span-2' : ''}>
|
||||
<div key={f.key} className={f.widget === 'textarea' ? 'sm:col-span-2' : ''}>
|
||||
{renderField(f)}
|
||||
</div>
|
||||
))}
|
||||
|
||||
@@ -147,7 +147,7 @@ export function RecordDetailDialog({ open, onClose, footprintId, onEdit }: {
|
||||
|
||||
{/* 事项要素:时间/组织方 + 类型专属字段(按模板定义顺序 = 重要性顺序) */}
|
||||
<Section title="事项要素">
|
||||
<div className="grid grid-cols-2 gap-x-4 gap-y-2 rounded-md border border-line bg-surface-2 px-3 py-2.5 text-[12.5px]">
|
||||
<div className="grid grid-cols-1 gap-x-4 gap-y-2 rounded-md border border-line bg-surface-2 px-3 py-2.5 text-[12.5px] sm:grid-cols-2">
|
||||
<MetaItem label="时间" value={fmtRange(d.start_date, d.end_date) || '—'} />
|
||||
<MetaItem label="组织方" value={d.organizer || '—'} />
|
||||
{fields.map(f => <MetaItem key={f.label} label={f.label} value={f.value} />)}
|
||||
|
||||
@@ -79,7 +79,7 @@ export function AdminPage() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="mx-auto max-w-[1080px] px-6 py-5">
|
||||
<div className="mx-auto max-w-[1080px] px-3 py-4 sm:px-6 sm:py-5">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<h2 className="text-[15px] font-semibold text-ink-1">管理</h2>
|
||||
<Button variant="secondary" onClick={() => { void qc.invalidateQueries(); }}>
|
||||
@@ -139,7 +139,7 @@ export function AdminPage() {
|
||||
{filtered.length ? (
|
||||
<div className="divide-y divide-line max-h-[430px] overflow-y-auto">
|
||||
{filtered.map((i) => (
|
||||
<div key={i.id} className="flex items-center gap-2 px-4 py-2.5 text-[12.5px]">
|
||||
<div key={i.id} className="flex flex-wrap items-center gap-2 px-4 py-2.5 text-[12.5px]">
|
||||
<button
|
||||
className="num shrink-0 cursor-pointer rounded-sm bg-surface-3 px-1.5 py-0.5 font-mono text-[12px] text-ink-1 transition-colors hover:bg-brand-subtle hover:text-brand-text"
|
||||
title="点击复制"
|
||||
@@ -218,7 +218,7 @@ export function AdminPage() {
|
||||
{users.length ? (
|
||||
<div className="divide-y divide-line max-h-[520px] overflow-y-auto">
|
||||
{users.map((u) => (
|
||||
<div key={u.id} className="flex items-center gap-2 px-4 py-2.5 text-[12.5px]">
|
||||
<div key={u.id} className="flex flex-wrap items-center gap-2 px-4 py-2.5 text-[12.5px]">
|
||||
<span className="font-medium text-ink-1">{u.username}</span>
|
||||
{u.is_admin && <Badge color="var(--brand-text)">管理员</Badge>}
|
||||
<span className="num ml-auto text-ink-3">{u.devices} 设备 · {u.records} 记录 · {fmtSize(u.attachment_bytes)}</span>
|
||||
|
||||
@@ -124,7 +124,7 @@ export function DashboardPage() {
|
||||
<CardHeader title="类型分布" />
|
||||
<CardBody><div ref={typeRef} className="h-[220px]" /></CardBody>
|
||||
</Card>
|
||||
<Card className="col-span-2">
|
||||
<Card className="lg:col-span-2">
|
||||
<CardHeader title="级别分布" />
|
||||
<CardBody><div ref={levelRef} className="h-[200px]" /></CardBody>
|
||||
</Card>
|
||||
|
||||
@@ -85,7 +85,7 @@ export function RecordsPage() {
|
||||
const openDetail = (id: number) => { setDetailId(id); setDetailOpen(true); };
|
||||
|
||||
return (
|
||||
<div className="px-3 py-4 sm:px-6 sm:py-5">
|
||||
<div className="mx-auto max-w-[1280px] px-3 py-4 sm:px-6 sm:py-5">
|
||||
<div className="mb-3 flex flex-wrap items-center gap-2">
|
||||
<Input
|
||||
className="w-[220px]"
|
||||
|
||||
@@ -168,7 +168,7 @@ function TypeEditor({ source, onClose, onSaved }: { source: FootprintType | null
|
||||
}
|
||||
>
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="grid grid-cols-[1fr_120px_100px] gap-3">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-[1fr_120px_100px] gap-3">
|
||||
|
||||
<Field label="名称" required>
|
||||
<Input value={name} onChange={e => setName(e.target.value)} placeholder="如:学科竞赛" />
|
||||
|
||||
Reference in New Issue
Block a user