feat: 企业级设计系统 v3 — 高级侧边栏/排版/阴影/动效
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { NavLink } from 'react-router-dom';
|
import { NavLink } from 'react-router-dom';
|
||||||
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
||||||
import { CalendarDays, Rows3, ChartColumn, GraduationCap, Shapes, SlidersHorizontal, LogIn, ShieldCheck, Cloud } from 'lucide-react';
|
import { CalendarDays, Rows3, ChartColumn, GraduationCap, Shapes, SlidersHorizontal, LogIn, LogOut, ShieldCheck, Cloud } from 'lucide-react';
|
||||||
import { serverMe, clearToken, getToken } from '@/lib/api';
|
import { serverMe, clearToken, getToken } from '@/lib/api';
|
||||||
import { LoginDialog } from '@/components/auth/LoginDialog';
|
import { LoginDialog } from '@/components/auth/LoginDialog';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
@@ -13,25 +13,26 @@ const NAV = [
|
|||||||
{ to: '/timeline', label: '时间线', icon: CalendarDays },
|
{ to: '/timeline', label: '时间线', icon: CalendarDays },
|
||||||
{ to: '/records', label: '记录', icon: Rows3 },
|
{ to: '/records', label: '记录', icon: Rows3 },
|
||||||
{ to: '/grades', label: '成绩', icon: GraduationCap },
|
{ to: '/grades', label: '成绩', icon: GraduationCap },
|
||||||
{ to: '/dashboard', label: '统计', icon: ChartColumn }
|
{ to: '/dashboard', label: '统计', icon: ChartColumn },
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
section: '配置',
|
section: '配置',
|
||||||
items: [
|
items: [
|
||||||
{ to: '/admin', label: '管理', icon: ShieldCheck },
|
{ to: '/admin', label: '管理', icon: ShieldCheck },
|
||||||
{ to: '/types', label: '记录类型', icon: Shapes },
|
{ to: '/types', label: '记录类型', icon: Shapes },
|
||||||
{ to: '/taxonomy', label: '字典与维度', icon: SlidersHorizontal }
|
{ to: '/taxonomy', label: '字典与维度', icon: SlidersHorizontal },
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
function LogoMark() {
|
function LogoMark() {
|
||||||
return (
|
return (
|
||||||
<svg width="26" height="26" viewBox="0 0 26 26" fill="none" aria-hidden>
|
<svg width='28' height='28' viewBox='0 0 26 26' fill='none' aria-hidden>
|
||||||
<rect x="1" y="1" width="24" height="24" rx="6" fill="var(--brand)" />
|
<defs><linearGradient id='lg' x1='0' y1='0' x2='0' y2='26'><stop stopColor='#4359e8'/><stop offset='1' stopColor='#2a3ab8'/></linearGradient></defs>
|
||||||
<ellipse cx="11" cy="10" rx="4.2" ry="5.2" fill="#fff" opacity="0.95" transform="rotate(-18 11 10)" />
|
<rect x='1' y='1' width='24' height='24' rx='7' fill='url(#lg)'/>
|
||||||
<circle cx="17.5" cy="17.5" r="3.1" fill="#fff" opacity="0.7" />
|
<ellipse cx='11' cy='10' rx='4.2' ry='5.2' fill='#fff' opacity='.95' transform='rotate(-18 11 10)'/>
|
||||||
|
<circle cx='17.5' cy='17.5' r='3.1' fill='#fff' opacity='.7'/>
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -42,47 +43,51 @@ export function Sidebar({ open, onClose }: { open: boolean; onClose: () => void
|
|||||||
queryKey: ['me'],
|
queryKey: ['me'],
|
||||||
queryFn: () => serverMe(),
|
queryFn: () => serverMe(),
|
||||||
enabled: !!getToken(),
|
enabled: !!getToken(),
|
||||||
retry: 0
|
retry: 0,
|
||||||
});
|
});
|
||||||
const [loginOpen, setLoginOpen] = useState(false);
|
|
||||||
const me = meQ.data ?? null;
|
const me = meQ.data ?? null;
|
||||||
|
const [loginOpen, setLoginOpen] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<aside
|
<aside
|
||||||
className={
|
className={cn(
|
||||||
'flex w-[224px] shrink-0 flex-col border-r border-line bg-surface' +
|
'flex w-[236px] shrink-0 flex-col border-r border-line bg-surface',
|
||||||
' max-lg:fixed max-lg:inset-y-0 max-lg:left-0 max-lg:z-40 max-lg:transition-transform' +
|
'max-lg:fixed max-lg:inset-y-0 max-lg:left-0 max-lg:z-40 max-lg:transition-transform',
|
||||||
(open ? ' max-lg:translate-x-0' : ' max-lg:-translate-x-full')
|
open ? 'max-lg:translate-x-0' : 'max-lg:-translate-x-full',
|
||||||
}
|
)}
|
||||||
>
|
>
|
||||||
<div className="flex h-14 items-center gap-2.5 border-b border-line px-4">
|
<LoginDialog open={loginOpen} onClose={() => setLoginOpen(false)} defaultUrl='https://footpr.linyux.cn' />
|
||||||
|
|
||||||
|
{/* Logo */}
|
||||||
|
<div className="flex h-[60px] items-center gap-3 border-b border-line px-5">
|
||||||
<LogoMark />
|
<LogoMark />
|
||||||
<div className="leading-tight">
|
<div className="leading-tight">
|
||||||
<div className="text-[14px] font-semibold text-ink-1">足迹</div>
|
<div className="text-[15px] font-bold tracking-tight text-ink-1">足迹</div>
|
||||||
<div className="text-[10px] font-medium tracking-[0.18em] text-ink-3">FOOTPRINTS</div>
|
<div className="text-[9px] font-medium tracking-[0.24em] text-ink-3">FOOTPRINTS</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<LoginDialog open={loginOpen} onClose={() => setLoginOpen(false)} defaultUrl={'https://footpr.linyux.cn'} />
|
|
||||||
<nav className="flex-1 overflow-y-auto px-2 py-3">
|
{/* 导航 */}
|
||||||
{NAV.map(group => (
|
<nav className="flex-1 overflow-y-auto px-2.5 py-4">
|
||||||
<div key={group.section} className="mb-4">
|
{NAV.map((group) => (
|
||||||
<div className="px-2 pb-1.5 text-[11px] font-medium text-ink-3">{group.section}</div>
|
<div key={group.section} className="mb-5">
|
||||||
|
<div className="px-2.5 pb-1.5 text-[10px] font-semibold uppercase tracking-[0.08em] text-ink-3">{group.section}</div>
|
||||||
<div className="flex flex-col gap-0.5">
|
<div className="flex flex-col gap-0.5">
|
||||||
{group.items.map(item => (
|
{group.items.map((item) => (
|
||||||
<NavLink
|
<NavLink
|
||||||
key={item.to}
|
key={item.to}
|
||||||
to={item.to}
|
to={item.to}
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
className={({ isActive }) =>
|
className={({ isActive }) =>
|
||||||
cn(
|
cn(
|
||||||
'flex h-8 items-center gap-2.5 rounded-md px-2 text-[13px] transition-colors',
|
'relative flex h-[34px] items-center gap-3 rounded-lg px-3 text-[13px] font-medium transition-all duration-150',
|
||||||
isActive
|
isActive
|
||||||
? 'bg-brand-subtle font-medium text-brand-text'
|
? 'bg-brand-subtle text-brand-text nav-active'
|
||||||
: 'text-ink-2 hover:bg-surface-3 hover:text-ink-1'
|
: 'text-ink-2 hover:bg-surface-3 hover:text-ink-1',
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<item.icon size={15} strokeWidth={2} />
|
<item.icon size={16} strokeWidth={1.8} />
|
||||||
{item.label}
|
{item.label}
|
||||||
</NavLink>
|
</NavLink>
|
||||||
))}
|
))}
|
||||||
@@ -91,41 +96,41 @@ export function Sidebar({ open, onClose }: { open: boolean; onClose: () => void
|
|||||||
))}
|
))}
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div className="border-t border-line px-4 py-3">
|
{/* 左下角:账号区 */}
|
||||||
{/* 左下角:账号区(云端模式) */}
|
<div className="border-t border-line px-3 py-3">
|
||||||
{getToken() && me ? (
|
{getToken() && me ? (
|
||||||
<div className="flex flex-col gap-1">
|
<div className="rounded-lg bg-surface-2 px-3 py-2.5">
|
||||||
<div className="flex items-center justify-between gap-2">
|
<div className="flex items-center justify-between gap-2">
|
||||||
<div className="flex items-center gap-1.5 min-w-0">
|
<div className="flex items-center gap-2 min-w-0">
|
||||||
<Cloud size={13} className="shrink-0 text-success" />
|
<div className="flex size-6 shrink-0 items-center justify-center rounded-full bg-brand text-[10px] font-bold text-white">
|
||||||
<div className="min-w-0 truncate text-[12px] font-medium text-ink-1" title={me.username}>
|
{me.username.charAt(0).toUpperCase()}
|
||||||
{me.is_admin && <span className="mr-0.5 text-brand-text">管理员</span>}
|
</div>
|
||||||
{me.username}
|
<div className="min-w-0">
|
||||||
|
<div className="truncate text-[12px] font-semibold text-ink-1" title={me.username}>{me.username}</div>
|
||||||
|
{me.is_admin && <div className='text-[10px] text-brand-text'>管理员</div>}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
className="shrink-0 text-[11px] text-ink-3 underline transition-colors hover:text-danger"
|
className="shrink-0 rounded p-1 text-ink-3 transition-colors hover:bg-surface-3 hover:text-danger"
|
||||||
|
title="退出登录"
|
||||||
onClick={() => { clearToken(); qc.clear(); window.location.reload(); }}
|
onClick={() => { clearToken(); qc.clear(); window.location.reload(); }}
|
||||||
>
|
>
|
||||||
退出
|
<LogOut size={13} />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-1 text-[10px] text-success">
|
<div className="mt-1.5 flex items-center gap-1 text-[10px] text-success">
|
||||||
<Cloud size={10} />
|
<Cloud size={10} />
|
||||||
云端同步已开启
|
云端同步已开启
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex flex-col gap-1.5">
|
|
||||||
<button
|
<button
|
||||||
className="flex w-full items-center gap-1.5 rounded-md bg-brand-subtle px-2 py-1.5 text-[12.5px] font-medium text-brand-text transition-colors hover:brightness-[0.97]"
|
className="flex w-full items-center justify-center gap-2 rounded-lg border border-brand/30 bg-brand-subtle px-3 py-2 text-[13px] font-medium text-brand-text transition-all hover:shadow-brand"
|
||||||
onClick={() => setLoginOpen(true)}
|
onClick={() => setLoginOpen(true)}
|
||||||
>
|
>
|
||||||
<LogIn size={13} />
|
<LogIn size={14} />
|
||||||
登录账号
|
登录我的档案
|
||||||
</button>
|
</button>
|
||||||
<div className="text-[10px] text-ink-3">登录后数据云端互通</div>
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
|
|||||||
+77
-77
@@ -1,10 +1,5 @@
|
|||||||
@import 'tailwindcss';
|
@import 'tailwindcss';
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
Footprints 设计系统 v2 —— 企业级视觉规范
|
|
||||||
栅格 4px · 控件高 28px · 正文 14px · 圆角 6/8
|
|
||||||
============================================ */
|
|
||||||
|
|
||||||
@theme inline {
|
@theme inline {
|
||||||
--color-bg: var(--bg);
|
--color-bg: var(--bg);
|
||||||
--color-surface: var(--surface);
|
--color-surface: var(--surface);
|
||||||
@@ -26,58 +21,61 @@
|
|||||||
--color-danger: var(--danger);
|
--color-danger: var(--danger);
|
||||||
--color-danger-subtle: var(--danger-subtle);
|
--color-danger-subtle: var(--danger-subtle);
|
||||||
|
|
||||||
--radius-sm: 4px;
|
--radius-sm: 5px;
|
||||||
--radius-md: 6px;
|
--radius-md: 8px;
|
||||||
--radius-lg: 8px;
|
--radius-lg: 12px;
|
||||||
|
|
||||||
--shadow-card: 0 1px 2px rgba(16, 24, 40, 0.04), 0 1px 3px rgba(16, 24, 40, 0.05);
|
--shadow-card: 0 1px 2px rgba(0,0,0,.03), 0 2px 8px rgba(0,0,0,.04);
|
||||||
--shadow-pop: 0 12px 32px rgba(16, 24, 40, 0.16), 0 2px 8px rgba(16, 24, 40, 0.08);
|
--shadow-pop: 0 4px 12px rgba(0,0,0,.08), 0 16px 48px rgba(0,0,0,.12);
|
||||||
|
--shadow-brand: 0 2px 8px rgba(48,86,211,.28);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------- 亮色 ---------- */
|
/* ── 亮色 ── */
|
||||||
:root {
|
:root {
|
||||||
--bg: #f4f5f7;
|
--bg: #f3f4f6;
|
||||||
--surface: #ffffff;
|
--surface: #ffffff;
|
||||||
--surface-2: #f9fafb;
|
--surface-2: #f8f9fa;
|
||||||
--surface-3: #eff1f4;
|
--surface-3: #eceef1;
|
||||||
--border: #e5e8ec;
|
--border: #e3e6ea;
|
||||||
--border-strong: #ccd3dc;
|
--border-strong: #c8cdd6;
|
||||||
--text-1: #15181d;
|
--text-1: #111318;
|
||||||
--text-2: #454e5c;
|
--text-2: #3d434f;
|
||||||
--text-3: #7e8798;
|
--text-3: #747c8a;
|
||||||
--brand: #3056d3;
|
--brand: #3346d3;
|
||||||
--brand-hover: #2748b8;
|
--brand-hover: #2a3ab8;
|
||||||
--brand-subtle: #eef2ff;
|
--brand-subtle: #eef1ff;
|
||||||
--brand-text: #2748b8;
|
--brand-text: #2a3ab8;
|
||||||
--success: #15803d;
|
--success: #177245;
|
||||||
--success-subtle: #ecfdf3;
|
--success-subtle: #ebfaf1;
|
||||||
--warning: #b45309;
|
--warning: #a86509;
|
||||||
--warning-subtle: #fffaeb;
|
--warning-subtle: #fef8eb;
|
||||||
--danger: #dc2626;
|
--danger: #d5304f;
|
||||||
--danger-subtle: #fef3f2;
|
--danger-subtle: #fef0f2;
|
||||||
|
color-scheme: light;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------- 暗色 ---------- */
|
/* ── 暗色 ── */
|
||||||
.dark {
|
.dark {
|
||||||
--bg: #0e1013;
|
--bg: #0c0d10;
|
||||||
--surface: #15181e;
|
--surface: #141519;
|
||||||
--surface-2: #1a1e25;
|
--surface-2: #1a1c22;
|
||||||
--surface-3: #22272f;
|
--surface-3: #23262e;
|
||||||
--border: #262c35;
|
--border: #262932;
|
||||||
--border-strong: #3a424f;
|
--border-strong: #363b47;
|
||||||
--text-1: #e8ebf1;
|
--text-1: #e9ebf0;
|
||||||
--text-2: #a2abb9;
|
--text-2: #a0a8b8;
|
||||||
--text-3: #6d7684;
|
--text-3: #68707e;
|
||||||
--brand: #7c93f5;
|
--brand: #6d8bfa;
|
||||||
--brand-hover: #94a8f8;
|
--brand-hover: #8aa2fb;
|
||||||
--brand-subtle: #1c2340;
|
--brand-subtle: #1a2144;
|
||||||
--brand-text: #a3b4f8;
|
--brand-text: #96adfa;
|
||||||
--success: #4ade80;
|
--success: #34d399;
|
||||||
--success-subtle: #12251a;
|
--success-subtle: #0d2921;
|
||||||
--warning: #fbbf24;
|
--warning: #fbbf24;
|
||||||
--warning-subtle: #2a2213;
|
--warning-subtle: #2b2109;
|
||||||
--danger: #f87171;
|
--danger: #f87171;
|
||||||
--danger-subtle: #2c1618;
|
--danger-subtle: #2d1317;
|
||||||
|
color-scheme: dark;
|
||||||
}
|
}
|
||||||
|
|
||||||
html, body, #root { height: 100%; }
|
html, body, #root { height: 100%; }
|
||||||
@@ -85,51 +83,53 @@ html, body, #root { height: 100%; }
|
|||||||
body {
|
body {
|
||||||
background: var(--bg);
|
background: var(--bg);
|
||||||
color: var(--text-1);
|
color: var(--text-1);
|
||||||
font-family: system-ui, 'Segoe UI Variable Text', 'Segoe UI', 'Microsoft YaHei UI', 'Microsoft YaHei', 'PingFang SC', sans-serif;
|
font-family: 'Inter Variable', 'Inter', system-ui, -apple-system, 'Segoe UI Variable Text', 'Segoe UI', 'Microsoft YaHei UI', 'Microsoft YaHei', 'PingFang SC', sans-serif;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 1.55;
|
line-height: 1.55;
|
||||||
letter-spacing: 0.005em;
|
letter-spacing: 0.003em;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
text-rendering: optimizeLegibility;
|
text-rendering: optimizeLegibility;
|
||||||
|
font-feature-settings: 'cv02', 'cv03', 'cv04', 'cv11';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 标题排版:紧凑字距 */
|
h1, h2, h3 { letter-spacing: -0.022em; text-wrap: balance; }
|
||||||
h1, h2, h3 {
|
|
||||||
letter-spacing: -0.01em;
|
|
||||||
text-wrap: balance;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 数字统一等宽,对齐敏感场景(表格/指标卡) */
|
.num { font-variant-numeric: tabular-nums lining-nums; font-feature-settings: 'tnum' 1, 'lnum' 1; }
|
||||||
.num {
|
|
||||||
font-variant-numeric: tabular-nums;
|
|
||||||
font-feature-settings: 'tnum' 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
::selection { background: color-mix(in srgb, var(--brand) 22%, transparent); }
|
::selection { background: color-mix(in srgb, var(--brand) 18%, transparent); }
|
||||||
|
|
||||||
/* 滚动条:更纤细,悬停加深 */
|
* { scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--text-3) 30%, transparent) transparent; }
|
||||||
* { scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }
|
*::-webkit-scrollbar { width: 5px; height: 5px; }
|
||||||
*::-webkit-scrollbar { width: 6px; height: 6px; }
|
*::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--text-3) 25%, transparent); border-radius: 3px; }
|
||||||
*::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 3px; }
|
*::-webkit-scrollbar-thumb:hover { background: color-mix(in srgb, var(--text-3) 45%, transparent); }
|
||||||
*::-webkit-scrollbar-thumb:hover { background: var(--text-3); }
|
|
||||||
*::-webkit-scrollbar-track { background: transparent; }
|
*::-webkit-scrollbar-track { background: transparent; }
|
||||||
|
|
||||||
:focus-visible {
|
:focus-visible {
|
||||||
outline: 2px solid color-mix(in srgb, var(--brand) 55%, transparent);
|
outline: 2px solid color-mix(in srgb, var(--brand) 50%, transparent);
|
||||||
outline-offset: 1px;
|
outline-offset: 2px;
|
||||||
|
border-radius: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
.animate-in { animation: fp-fade-slide-in 0.18s ease-out; }
|
/* 微动效 */
|
||||||
|
.animate-in { animation: fp-in .22s cubic-bezier(.16,1,.3,1); }
|
||||||
|
@keyframes fp-in { from { opacity: 0; transform: translateY(6px) scale(.98); } to { opacity: 1; transform: none; } }
|
||||||
|
|
||||||
@keyframes fp-fade-slide-in {
|
.animate-fade { animation: fp-fade .3s ease-out; }
|
||||||
from { opacity: 0; transform: translateY(4px); }
|
@keyframes fp-fade { from { opacity: 0; } to { opacity: 1; } }
|
||||||
to { opacity: 1; transform: none; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 数字输入框去掉浏览器步进按钮的视觉噪音 */
|
/* 数字输入去噪 */
|
||||||
input[type='number']::-webkit-outer-spin-button,
|
input[type='number']::-webkit-outer-spin-button,
|
||||||
input[type='number']::-webkit-inner-spin-button {
|
input[type='number']::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
|
||||||
-webkit-appearance: none;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
input[type='number'] { -moz-appearance: textfield; appearance: textfield; }
|
input[type='number'] { -moz-appearance: textfield; appearance: textfield; }
|
||||||
|
|
||||||
|
/* 卡片悬停微抬 */
|
||||||
|
.hover-lift { transition: transform .2s cubic-bezier(.16,1,.3,1), box-shadow .2s ease; }
|
||||||
|
.hover-lift:hover { transform: translateY(-1px); box-shadow: 0 4px 16px rgba(0,0,0,.08), 0 1px 4px rgba(0,0,0,.04); }
|
||||||
|
|
||||||
|
/* 侧边栏激活指示条 */
|
||||||
|
.nav-active::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute; left: 0; top: 6px; bottom: 6px; width: 3px;
|
||||||
|
border-radius: 0 3px 3px 0; background: var(--brand);
|
||||||
|
}
|
||||||
|
|||||||
+3
-3
@@ -1,5 +1,5 @@
|
|||||||
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-BPypTgG9.js","assets/index-D8_RHt64.css"])))=>i.map(i=>d[i]);
|
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-DfnNvRlO.js","assets/index-CY5BkXpe.css"])))=>i.map(i=>d[i]);
|
||||||
import{c as Q,u as M,r as w,e as d,Y as r,f as N,j as e,E as c,B as t,P as B,A as l,i as F,T as K,Z as P,_ as R,$ as S,a0 as L,a1 as U,a2 as A}from"./index-BPypTgG9.js";import{C,a as q,b as z}from"./card-DtBTl1yb.js";/**
|
import{c as Q,u as M,r as w,e as d,Y as r,f as N,j as e,E as c,B as t,P as B,A as l,i as F,T as K,Z as P,_ as R,$ as S,a0 as L,a1 as U,a2 as A}from"./index-DfnNvRlO.js";import{C,a as q,b as z}from"./card-D7onCjYF.js";/**
|
||||||
* @license lucide-react v0.475.0 - ISC
|
* @license lucide-react v0.475.0 - ISC
|
||||||
*
|
*
|
||||||
* This source code is licensed under the ISC license.
|
* This source code is licensed under the ISC license.
|
||||||
@@ -9,4 +9,4 @@ import{c as Q,u as M,r as w,e as d,Y as r,f as N,j as e,E as c,B as t,P as B,A a
|
|||||||
*
|
*
|
||||||
* This source code is licensed under the ISC license.
|
* This source code is licensed under the ISC license.
|
||||||
* See the LICENSE file in the root directory of this source tree.
|
* See the LICENSE file in the root directory of this source tree.
|
||||||
*/const V=[["path",{d:"M18 21a8 8 0 0 0-16 0",key:"3ypg7q"}],["circle",{cx:"10",cy:"8",r:"5",key:"o932ke"}],["path",{d:"M22 20c0-3.37-2-6.5-4-8a5 5 0 0 0-.45-8.3",key:"10s06x"}]],W=Q("UsersRound",V);function a(){return localStorage.getItem("fp-server-url")||""}function O(){var p,y,j,k,f,g,_,b;const i=M(),[o,n]=w.useState(!1),m=d({queryKey:["me"],queryFn:()=>L(()=>import("./index-BPypTgG9.js").then(s=>s.a3),__vite__mapDeps([0,1])).then(s=>s.serverMe(a())),enabled:!!r()}),x=d({queryKey:["admin-users"],queryFn:()=>U(a()),enabled:!!r()}),u=d({queryKey:["admin-invites"],queryFn:()=>A(a()),enabled:!!r()}),T=N({mutationFn:s=>R(s,a()),onSuccess:()=>{i.invalidateQueries({queryKey:["admin-invites"]}),n(!1)},onError:()=>n(!1)}),E=N({mutationFn:s=>S(s,a()),onSuccess:()=>void i.invalidateQueries({queryKey:["admin-invites"]})});if(m.data&&!m.data.is_admin)return e.jsx(c,{title:"需要管理员账号",description:"当前登录账号不是管理员。"});const v=((y=(p=u.data)==null?void 0:p.data)==null?void 0:y.invites)??[],h=((k=(j=x.data)==null?void 0:j.data)==null?void 0:k.users)??[],I=((g=(f=u.data)==null?void 0:f.data)==null?void 0:g.total)??0;return e.jsxs("div",{className:"mx-auto max-w-[1080px] px-6 py-5",children:[e.jsxs("div",{className:"mb-4 flex items-center justify-between",children:[e.jsx("h2",{className:"text-[15px] font-semibold text-ink-1",children:"管理"}),e.jsx(t,{variant:"secondary",onClick:()=>{i.invalidateQueries()},children:"刷新"})]}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-4",children:[e.jsxs(C,{children:[e.jsx(q,{title:"邀请码("+I+")",extra:e.jsxs(t,{size:"sm",variant:"primary",disabled:o,onClick:()=>{n(!0),T.mutate(5)},children:[e.jsx(B,{size:13})," 批量生成 5 个"]})}),e.jsx(z,{className:"p-0",children:v.length?e.jsx("div",{className:"divide-y divide-line max-h-[420px] overflow-y-auto",children:v.map(s=>e.jsxs("div",{className:"flex items-center gap-2 px-4 py-2 text-[12.5px]",children:[e.jsx("code",{className:"num rounded-sm px-1.5 py-0.5 "+(s.valid?"bg-success-subtle text-success":"bg-surface-3 text-ink-3"),children:s.code}),s.valid?e.jsx(l,{color:"var(--success)",children:"可用"}):e.jsx(l,{color:"var(--text-3)",children:"已使用"}),s.used_by_name&&e.jsxs("span",{className:"text-ink-3 truncate",children:["被 ",s.used_by_name," 使用于 ",F(s.used_at)]}),!s.used_by&&e.jsxs("span",{className:"ml-auto flex gap-1",children:[e.jsx(t,{size:"sm",variant:"secondary",onClick:()=>{navigator.clipboard.writeText(s.code)},children:"复制"}),!s.valid&&e.jsx(t,{size:"icon-sm",variant:"ghost","aria-label":"作废",className:"text-ink-3",onClick:()=>E.mutate(s.id),children:e.jsx(K,{size:13})})]})]},s.id))}):e.jsx(c,{icon:e.jsx(H,{size:32,strokeWidth:1.5}),title:"暂无邀请码",description:"生成后发给需要注册的用户。"})})]}),e.jsxs(C,{children:[e.jsx(q,{title:"用户("+(((b=(_=x.data)==null?void 0:_.data)==null?void 0:b.total)??0)+")"}),e.jsx(z,{className:"p-0",children:h.length?e.jsx("div",{className:"divide-y divide-line max-h-[420px] overflow-y-auto",children:h.map(s=>e.jsxs("div",{className:"flex items-center gap-2 px-4 py-2 text-[12.5px]",children:[e.jsx("span",{className:"font-medium text-ink-1",children:s.username}),s.is_admin&&e.jsx(l,{color:"var(--brand-text)",children:"管理员"}),e.jsxs("span",{className:"num ml-auto text-ink-3",children:[s.devices," 设备 · ",s.records," 记录 · ",P(s.attachment_bytes)]})]},s.id))}):e.jsx(c,{icon:e.jsx(W,{size:32,strokeWidth:1.5}),title:"暂无用户"})})]})]}),o&&e.jsx("div",{className:"mt-3 text-[12px] text-ink-3",children:"生成中…"})]})}export{O as AdminPage};
|
*/const V=[["path",{d:"M18 21a8 8 0 0 0-16 0",key:"3ypg7q"}],["circle",{cx:"10",cy:"8",r:"5",key:"o932ke"}],["path",{d:"M22 20c0-3.37-2-6.5-4-8a5 5 0 0 0-.45-8.3",key:"10s06x"}]],W=Q("UsersRound",V);function a(){return localStorage.getItem("fp-server-url")||""}function O(){var p,y,j,k,f,g,_,b;const i=M(),[o,n]=w.useState(!1),m=d({queryKey:["me"],queryFn:()=>L(()=>import("./index-DfnNvRlO.js").then(s=>s.a3),__vite__mapDeps([0,1])).then(s=>s.serverMe(a())),enabled:!!r()}),x=d({queryKey:["admin-users"],queryFn:()=>U(a()),enabled:!!r()}),u=d({queryKey:["admin-invites"],queryFn:()=>A(a()),enabled:!!r()}),T=N({mutationFn:s=>R(s,a()),onSuccess:()=>{i.invalidateQueries({queryKey:["admin-invites"]}),n(!1)},onError:()=>n(!1)}),E=N({mutationFn:s=>S(s,a()),onSuccess:()=>void i.invalidateQueries({queryKey:["admin-invites"]})});if(m.data&&!m.data.is_admin)return e.jsx(c,{title:"需要管理员账号",description:"当前登录账号不是管理员。"});const v=((y=(p=u.data)==null?void 0:p.data)==null?void 0:y.invites)??[],h=((k=(j=x.data)==null?void 0:j.data)==null?void 0:k.users)??[],I=((g=(f=u.data)==null?void 0:f.data)==null?void 0:g.total)??0;return e.jsxs("div",{className:"mx-auto max-w-[1080px] px-6 py-5",children:[e.jsxs("div",{className:"mb-4 flex items-center justify-between",children:[e.jsx("h2",{className:"text-[15px] font-semibold text-ink-1",children:"管理"}),e.jsx(t,{variant:"secondary",onClick:()=>{i.invalidateQueries()},children:"刷新"})]}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-4",children:[e.jsxs(C,{children:[e.jsx(q,{title:"邀请码("+I+")",extra:e.jsxs(t,{size:"sm",variant:"primary",disabled:o,onClick:()=>{n(!0),T.mutate(5)},children:[e.jsx(B,{size:13})," 批量生成 5 个"]})}),e.jsx(z,{className:"p-0",children:v.length?e.jsx("div",{className:"divide-y divide-line max-h-[420px] overflow-y-auto",children:v.map(s=>e.jsxs("div",{className:"flex items-center gap-2 px-4 py-2 text-[12.5px]",children:[e.jsx("code",{className:"num rounded-sm px-1.5 py-0.5 "+(s.valid?"bg-success-subtle text-success":"bg-surface-3 text-ink-3"),children:s.code}),s.valid?e.jsx(l,{color:"var(--success)",children:"可用"}):e.jsx(l,{color:"var(--text-3)",children:"已使用"}),s.used_by_name&&e.jsxs("span",{className:"text-ink-3 truncate",children:["被 ",s.used_by_name," 使用于 ",F(s.used_at)]}),!s.used_by&&e.jsxs("span",{className:"ml-auto flex gap-1",children:[e.jsx(t,{size:"sm",variant:"secondary",onClick:()=>{navigator.clipboard.writeText(s.code)},children:"复制"}),!s.valid&&e.jsx(t,{size:"icon-sm",variant:"ghost","aria-label":"作废",className:"text-ink-3",onClick:()=>E.mutate(s.id),children:e.jsx(K,{size:13})})]})]},s.id))}):e.jsx(c,{icon:e.jsx(H,{size:32,strokeWidth:1.5}),title:"暂无邀请码",description:"生成后发给需要注册的用户。"})})]}),e.jsxs(C,{children:[e.jsx(q,{title:"用户("+(((b=(_=x.data)==null?void 0:_.data)==null?void 0:b.total)??0)+")"}),e.jsx(z,{className:"p-0",children:h.length?e.jsx("div",{className:"divide-y divide-line max-h-[420px] overflow-y-auto",children:h.map(s=>e.jsxs("div",{className:"flex items-center gap-2 px-4 py-2 text-[12.5px]",children:[e.jsx("span",{className:"font-medium text-ink-1",children:s.username}),s.is_admin&&e.jsx(l,{color:"var(--brand-text)",children:"管理员"}),e.jsxs("span",{className:"num ml-auto text-ink-3",children:[s.devices," 设备 · ",s.records," 记录 · ",P(s.attachment_bytes)]})]},s.id))}):e.jsx(c,{icon:e.jsx(W,{size:32,strokeWidth:1.5}),title:"暂无用户"})})]})]}),o&&e.jsx("div",{className:"mt-3 text-[12px] text-ink-3",children:"生成中…"})]})}export{O as AdminPage};
|
||||||
+1
-1
@@ -1 +1 @@
|
|||||||
import{r as g,e as v,j as t,S as j,s as S}from"./index-BPypTgG9.js";import{C as c,a as d,b as x}from"./card-DtBTl1yb.js";import{u as N,i as u,a as m}from"./useChart-ODBxrUQE.js";import{u as k,i as w,a as C,b as L,c as R,d as $,e as z,f as T}from"./echarts-BIWefrIc.js";k([w,C,L,R,$,z,T]);function q(){const[l,n]=g.useState(""),i=N(),e=v({queryKey:["stats",l||void 0],queryFn:()=>S(l?Number(l):void 0)}).data,p=u("2"),r=u("3"),h=m(()=>({grid:{left:34,right:12,top:14,bottom:24},tooltip:{trigger:"axis"},xAxis:{type:"category",data:(e==null?void 0:e.monthly.map(a=>a.ym.slice(2)))??[],axisLine:{lineStyle:{color:r}},axisTick:{show:!1},axisLabel:{color:r,fontSize:10}},yAxis:{type:"value",splitLine:{lineStyle:{color:"rgba(128,138,155,0.15)"}},axisLabel:{color:r,fontSize:10}},series:[{type:"bar",data:(e==null?void 0:e.monthly.map(a=>a.count))??[],barMaxWidth:18,itemStyle:{color:"#3056d3",borderRadius:[3,3,0,0]}}]}),[e,i]),b=m(()=>{const a=((e==null?void 0:e.by_type)??[]).filter(s=>s.count>0);return{tooltip:{trigger:"item"},legend:{orient:"vertical",right:4,top:"middle",textStyle:{color:p,fontSize:11},itemWidth:10,itemHeight:10},series:[{type:"pie",radius:["48%","72%"],center:["34%","50%"],label:{show:!1},data:a.map(s=>({name:s.label,value:s.count,itemStyle:{color:s.color||"#64748b"}}))}]}},[e,i]),y=m(()=>{const a=((e==null?void 0:e.by_level)??[]).filter(s=>s.count>0).slice().reverse();return{grid:{left:64,right:24,top:8,bottom:22},tooltip:{trigger:"axis"},xAxis:{type:"value",splitLine:{lineStyle:{color:"rgba(128,138,155,0.15)"}},axisLabel:{color:r,fontSize:10}},yAxis:{type:"category",data:a.map(s=>s.label),axisLine:{show:!1},axisTick:{show:!1},axisLabel:{color:p,fontSize:11}},series:[{type:"bar",data:a.map(s=>({value:s.count,itemStyle:{color:s.color||"#3056d3",borderRadius:[0,3,3,0]}})),barMaxWidth:14}]}},[e,i]),f=((e==null?void 0:e.metrics)??[]).slice(0,3);return t.jsxs("div",{className:"mx-auto max-w-[1080px] px-6 py-5",children:[t.jsxs("div",{className:"mb-4 flex flex-wrap items-center justify-between gap-3",children:[t.jsxs("div",{className:"flex flex-wrap gap-3",children:[t.jsx(o,{label:"总记录",value:(e==null?void 0:e.total)??0}),t.jsx(o,{label:l?l+" 年新增":"本年新增",value:(e==null?void 0:e.total_this_year)??0}),t.jsx(o,{label:"附件总数",value:(e==null?void 0:e.attachment_total)??0}),f.map(a=>t.jsx(o,{label:a.label,value:a.value,unit:a.unit??""},a.key))]}),t.jsx(j,{className:"w-[120px]",value:l,onChange:a=>n(a.target.value),options:[{value:"",label:"全部年份"},...((e==null?void 0:e.years)??[]).map(a=>({value:String(a),label:a+" 年"}))]})]}),!(e!=null&&e.metrics.length)&&t.jsx("div",{className:"mb-4 rounded-md border border-dashed border-line px-4 py-2 text-[12px] text-ink-3",children:"提示:在「统计」配置中注册指标(如志愿时长、读书本数),带单位的数值字段即可在此量化展示。"}),t.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-4",children:[t.jsxs(c,{children:[t.jsx(d,{title:"近 12 个月活跃度"}),t.jsx(x,{children:t.jsx("div",{ref:h,className:"h-[220px]"})})]}),t.jsxs(c,{children:[t.jsx(d,{title:"类型分布"}),t.jsx(x,{children:t.jsx("div",{ref:b,className:"h-[220px]"})})]}),t.jsxs(c,{className:"col-span-2",children:[t.jsx(d,{title:"级别分布"}),t.jsx(x,{children:t.jsx("div",{ref:y,className:"h-[200px]"})})]})]})]})}function o({label:l,value:n,unit:i}){return t.jsxs("div",{className:"min-w-[120px] rounded-lg border border-line bg-surface px-4 py-3 shadow-card",children:[t.jsx("div",{className:"text-[12px] text-ink-3",children:l}),t.jsxs("div",{className:"num mt-0.5 text-[22px] font-semibold leading-tight text-ink-1",children:[n,i&&t.jsx("span",{className:"ml-1 text-[12px] font-normal text-ink-3",children:i})]})]})}export{q as DashboardPage};
|
import{r as g,e as v,j as t,S as j,s as S}from"./index-DfnNvRlO.js";import{C as c,a as d,b as x}from"./card-D7onCjYF.js";import{u as N,i as u,a as m}from"./useChart-Dn2X0nrY.js";import{u as k,i as w,a as C,b as L,c as R,d as $,e as z,f as T}from"./echarts-BIWefrIc.js";k([w,C,L,R,$,z,T]);function q(){const[l,n]=g.useState(""),i=N(),e=v({queryKey:["stats",l||void 0],queryFn:()=>S(l?Number(l):void 0)}).data,p=u("2"),r=u("3"),h=m(()=>({grid:{left:34,right:12,top:14,bottom:24},tooltip:{trigger:"axis"},xAxis:{type:"category",data:(e==null?void 0:e.monthly.map(a=>a.ym.slice(2)))??[],axisLine:{lineStyle:{color:r}},axisTick:{show:!1},axisLabel:{color:r,fontSize:10}},yAxis:{type:"value",splitLine:{lineStyle:{color:"rgba(128,138,155,0.15)"}},axisLabel:{color:r,fontSize:10}},series:[{type:"bar",data:(e==null?void 0:e.monthly.map(a=>a.count))??[],barMaxWidth:18,itemStyle:{color:"#3056d3",borderRadius:[3,3,0,0]}}]}),[e,i]),b=m(()=>{const a=((e==null?void 0:e.by_type)??[]).filter(s=>s.count>0);return{tooltip:{trigger:"item"},legend:{orient:"vertical",right:4,top:"middle",textStyle:{color:p,fontSize:11},itemWidth:10,itemHeight:10},series:[{type:"pie",radius:["48%","72%"],center:["34%","50%"],label:{show:!1},data:a.map(s=>({name:s.label,value:s.count,itemStyle:{color:s.color||"#64748b"}}))}]}},[e,i]),y=m(()=>{const a=((e==null?void 0:e.by_level)??[]).filter(s=>s.count>0).slice().reverse();return{grid:{left:64,right:24,top:8,bottom:22},tooltip:{trigger:"axis"},xAxis:{type:"value",splitLine:{lineStyle:{color:"rgba(128,138,155,0.15)"}},axisLabel:{color:r,fontSize:10}},yAxis:{type:"category",data:a.map(s=>s.label),axisLine:{show:!1},axisTick:{show:!1},axisLabel:{color:p,fontSize:11}},series:[{type:"bar",data:a.map(s=>({value:s.count,itemStyle:{color:s.color||"#3056d3",borderRadius:[0,3,3,0]}})),barMaxWidth:14}]}},[e,i]),f=((e==null?void 0:e.metrics)??[]).slice(0,3);return t.jsxs("div",{className:"mx-auto max-w-[1080px] px-6 py-5",children:[t.jsxs("div",{className:"mb-4 flex flex-wrap items-center justify-between gap-3",children:[t.jsxs("div",{className:"flex flex-wrap gap-3",children:[t.jsx(o,{label:"总记录",value:(e==null?void 0:e.total)??0}),t.jsx(o,{label:l?l+" 年新增":"本年新增",value:(e==null?void 0:e.total_this_year)??0}),t.jsx(o,{label:"附件总数",value:(e==null?void 0:e.attachment_total)??0}),f.map(a=>t.jsx(o,{label:a.label,value:a.value,unit:a.unit??""},a.key))]}),t.jsx(j,{className:"w-[120px]",value:l,onChange:a=>n(a.target.value),options:[{value:"",label:"全部年份"},...((e==null?void 0:e.years)??[]).map(a=>({value:String(a),label:a+" 年"}))]})]}),!(e!=null&&e.metrics.length)&&t.jsx("div",{className:"mb-4 rounded-md border border-dashed border-line px-4 py-2 text-[12px] text-ink-3",children:"提示:在「统计」配置中注册指标(如志愿时长、读书本数),带单位的数值字段即可在此量化展示。"}),t.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-4",children:[t.jsxs(c,{children:[t.jsx(d,{title:"近 12 个月活跃度"}),t.jsx(x,{children:t.jsx("div",{ref:h,className:"h-[220px]"})})]}),t.jsxs(c,{children:[t.jsx(d,{title:"类型分布"}),t.jsx(x,{children:t.jsx("div",{ref:b,className:"h-[220px]"})})]}),t.jsxs(c,{className:"col-span-2",children:[t.jsx(d,{title:"级别分布"}),t.jsx(x,{children:t.jsx("div",{ref:y,className:"h-[200px]"})})]})]})]})}function o({label:l,value:n,unit:i}){return t.jsxs("div",{className:"min-w-[120px] rounded-lg border border-line bg-surface px-4 py-3 shadow-card",children:[t.jsx("div",{className:"text-[12px] text-ink-3",children:l}),t.jsxs("div",{className:"num mt-0.5 text-[22px] font-semibold leading-tight text-ink-1",children:[n,i&&t.jsx("span",{className:"ml-1 text-[12px] font-normal text-ink-3",children:i})]})]})}export{q as DashboardPage};
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import{c as K,e as I,j as e,E as O,t as $,u as k,b as S,r as u,f as y,v as H,w as W,B as g,P as q,C as Q,x as J,y as T,z as U,A as N,k as G,T as E,I as j,D as Y,F as C,H as B,J as V}from"./index-BPypTgG9.js";import{C as f,a as z,b as _}from"./card-DtBTl1yb.js";import{u as X,i as M,a as L}from"./useChart-ODBxrUQE.js";import{u as Z,i as ee,b as se,a as te,c as ae,d as re,e as ne,f as le}from"./echarts-BIWefrIc.js";/**
|
import{c as K,e as I,j as e,E as O,t as $,u as k,b as S,r as u,f as y,v as H,w as W,B as g,P as q,C as Q,x as J,y as T,z as U,A as N,k as G,T as E,I as j,D as Y,F as C,H as B,J as V}from"./index-DfnNvRlO.js";import{C as f,a as z,b as _}from"./card-D7onCjYF.js";import{u as X,i as M,a as L}from"./useChart-Dn2X0nrY.js";import{u as Z,i as ee,b as se,a as te,c as ae,d as re,e as ne,f as le}from"./echarts-BIWefrIc.js";/**
|
||||||
* @license lucide-react v0.475.0 - ISC
|
* @license lucide-react v0.475.0 - ISC
|
||||||
*
|
*
|
||||||
* This source code is licensed under the ISC license.
|
* This source code is licensed under the ISC license.
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import{c as re,j as e,a as u,r as t,u as oe,b as ce,d as de,e as C,f as ue,I as xe,S as m,B as b,P as Y,g as pe,L as me,G as ve,R as he,h as je,i as ge,k as fe,T as ye,E as be,l as Ne,m as ke,C as Se,n as we,o as Ce,p as Ee,s as qe,q as _e}from"./index-BPypTgG9.js";/**
|
import{c as re,j as e,a as u,r as t,u as oe,b as ce,d as de,e as C,f as ue,I as xe,S as m,B as b,P as Y,g as pe,L as me,G as ve,R as he,h as je,i as ge,k as fe,T as ye,E as be,l as Ne,m as ke,C as Se,n as we,o as Ce,p as Ee,s as qe,q as _e}from"./index-DfnNvRlO.js";/**
|
||||||
* @license lucide-react v0.475.0 - ISC
|
* @license lucide-react v0.475.0 - ISC
|
||||||
*
|
*
|
||||||
* This source code is licensed under the ISC license.
|
* This source code is licensed under the ISC license.
|
||||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import{c as P,u as Q,b as z,e as B,r as i,f as T,j as e,B as p,P as F,K as q,A as E,k as D,T as I,C as K,M as L,D as G,F as r,I as j,N as H,S as R,O as W,o as J}from"./index-BPypTgG9.js";import{C as U}from"./card-DtBTl1yb.js";/**
|
import{c as P,u as Q,b as z,e as B,r as i,f as T,j as e,B as p,P as F,K as q,A as E,k as D,T as I,C as K,M as L,D as G,F as r,I as j,N as H,S as R,O as W,o as J}from"./index-DfnNvRlO.js";import{C as U}from"./card-D7onCjYF.js";/**
|
||||||
* @license lucide-react v0.475.0 - ISC
|
* @license lucide-react v0.475.0 - ISC
|
||||||
*
|
*
|
||||||
* This source code is licensed under the ISC license.
|
* This source code is licensed under the ISC license.
|
||||||
@@ -1 +1 @@
|
|||||||
import{j as s,a}from"./index-BPypTgG9.js";function i({className:r,...e}){return s.jsx("div",{className:a("rounded-lg border border-line bg-surface shadow-card",r),...e})}function t({title:r,extra:e,className:n}){return s.jsxs("div",{className:a("flex min-h-11 flex-wrap items-center justify-between gap-2 border-b border-line px-4 py-1.5",n),children:[s.jsx("h3",{className:"text-[13px] font-semibold text-ink-1",children:r}),e&&s.jsx("div",{className:"flex flex-wrap items-center gap-2",children:e})]})}function c({className:r,...e}){return s.jsx("div",{className:a("p-4",r),...e})}export{i as C,t as a,c as b};
|
import{j as s,a}from"./index-DfnNvRlO.js";function i({className:r,...e}){return s.jsx("div",{className:a("rounded-lg border border-line bg-surface shadow-card",r),...e})}function t({title:r,extra:e,className:n}){return s.jsxs("div",{className:a("flex min-h-11 flex-wrap items-center justify-between gap-2 border-b border-line px-4 py-1.5",n),children:[s.jsx("h3",{className:"text-[13px] font-semibold text-ink-1",children:r}),e&&s.jsx("div",{className:"flex flex-wrap items-center gap-2",children:e})]})}function c({className:r,...e}){return s.jsx("div",{className:a("p-4",r),...e})}export{i as C,t as a,c as b};
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+56
-51
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
|||||||
import{r}from"./index-BPypTgG9.js";import{g as f}from"./echarts-BIWefrIc.js";function p(){const[n,o]=r.useState(0);return r.useEffect(()=>{const s=()=>o(t=>t+1);return window.addEventListener("fp-theme-change",s),()=>window.removeEventListener("fp-theme-change",s)},[]),n}function d(n){return getComputedStyle(document.documentElement).getPropertyValue("--text-"+n).trim()||"#454e5c"}function h(n,o){const s=r.useRef(null),[t,i]=r.useState(null),u=r.useRef(n);return u.current=n,r.useEffect(()=>{if(!t)return;const e=f(t);s.current=e,e.setOption(u.current(),{notMerge:!0});const c=new ResizeObserver(()=>e.resize());return c.observe(t),()=>{c.disconnect(),e.dispose(),s.current=null}},[t]),r.useEffect(()=>{var e;(e=s.current)==null||e.setOption(u.current(),{notMerge:!0})},[t,...o]),e=>i(e)}export{h as a,d as i,p as u};
|
import{r}from"./index-DfnNvRlO.js";import{g as f}from"./echarts-BIWefrIc.js";function p(){const[n,o]=r.useState(0);return r.useEffect(()=>{const s=()=>o(t=>t+1);return window.addEventListener("fp-theme-change",s),()=>window.removeEventListener("fp-theme-change",s)},[]),n}function d(n){return getComputedStyle(document.documentElement).getPropertyValue("--text-"+n).trim()||"#454e5c"}function h(n,o){const s=r.useRef(null),[t,i]=r.useState(null),u=r.useRef(n);return u.current=n,r.useEffect(()=>{if(!t)return;const e=f(t);s.current=e,e.setOption(u.current(),{notMerge:!0});const c=new ResizeObserver(()=>e.resize());return c.observe(t),()=>{c.disconnect(),e.dispose(),s.current=null}},[t]),r.useEffect(()=>{var e;(e=s.current)==null||e.setOption(u.current(),{notMerge:!0})},[t,...o]),e=>i(e)}export{h as a,d as i,p as u};
|
||||||
@@ -8,8 +8,8 @@
|
|||||||
<link rel="icon" href="/icons/pwa-192.png" />
|
<link rel="icon" href="/icons/pwa-192.png" />
|
||||||
<link rel="apple-touch-icon" href="/icons/pwa-192.png" />
|
<link rel="apple-touch-icon" href="/icons/pwa-192.png" />
|
||||||
<title>足迹 Footprints</title>
|
<title>足迹 Footprints</title>
|
||||||
<script type="module" crossorigin src="/assets/index-BPypTgG9.js"></script>
|
<script type="module" crossorigin src="/assets/index-DfnNvRlO.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-D8_RHt64.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-CY5BkXpe.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
|||||||
Reference in New Issue
Block a user