polish(ui): design language uplift - press feedback, brand gradient, header glass, route icon chips, empty states

- button: unified press scale (active:scale-[0.97]), primary gets vertical
  brand gradient + tighter shadow, secondary gains subtle hover shadow
- input/select/textarea: consistent focus border + 1.5px brand ring
- empty states: icon in circular tinted badge with soft ring, larger rhythm
- header: translucent frosted-glass surface (color-mix + backdrop blur),
  per-route lucide icon chip beside page title (desktop), subtitle hidden
  on phones to declutter
- sidebar: active nav icon tinted brand via .nav-active > svg; user card
  avatar gets brand gradient + ring
- dark theme: text-3 contrast raised (#68707e -> #747c8a)
- verified live (headless): h1/chips/glass render on dashboard/timeline/
  assessment/resume; tsc + vite build green; temp instrumentation reverted
This commit is contained in:
root
2026-10-17 22:33:39 +08:00
parent 8cdf8b44fa
commit a5e976fee6
24 changed files with 138 additions and 103 deletions
+25 -3
View File
@@ -1,6 +1,7 @@
import { useState } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import { Search, Sun, Moon, Plus, Menu } from 'lucide-react';
import { Search, Sun, Moon, Plus, Menu, CalendarDays, Rows3, GraduationCap, ChartColumn, Shapes, SlidersHorizontal, User, ScrollText, ClipboardCheck, ShieldCheck } from 'lucide-react';
import type { LucideIcon } from 'lucide-react';
import { Button, Input } from '@/components/ui';
const TITLES: Record<string, { title: string; sub?: string }> = {
@@ -24,6 +25,20 @@ export function Header({ onMenu }: { onMenu?: () => void }) {
const meta = TITLES[pathname] ?? { title: '' };
const ROUTE_ICONS: Record<string, LucideIcon> = {
'/timeline': CalendarDays,
'/records': Rows3,
'/grades': GraduationCap,
'/dashboard': ChartColumn,
'/types': Shapes,
'/taxonomy': SlidersHorizontal,
'/profile': User,
'/resume': ScrollText,
'/assessment': ClipboardCheck,
'/admin': ShieldCheck,
};
const RouteIcon = ROUTE_ICONS[pathname];
const toggleTheme = () => {
const next = !dark;
setDark(next);
@@ -33,14 +48,21 @@ export function Header({ onMenu }: { onMenu?: () => void }) {
};
return (
<header className="no-print flex h-14 shrink-0 items-center gap-2 border-b border-line bg-surface px-3 sm:gap-4 sm:px-5">
<header className="no-print header-glass sticky top-0 z-20 flex h-14 shrink-0 items-center gap-2.5 border-b border-line px-3 sm:gap-4 sm:px-5">
<Button variant="ghost" size="icon" className="lg:hidden" onClick={onMenu} aria-label="打开导航">
<Menu size={17} />
</Button>
<div className="flex min-w-0 items-center gap-2.5">
{RouteIcon && (
<span className="hidden size-8 shrink-0 items-center justify-center rounded-lg bg-brand-subtle text-brand-text sm:flex" aria-hidden>
<RouteIcon size={16} strokeWidth={2} />
</span>
)}
<div className="min-w-0">
<h1 className="truncate text-[15px] font-semibold leading-tight text-ink-1">{meta.title}</h1>
{meta.sub && <p className="truncate text-[11px] leading-tight text-ink-3">{meta.sub}</p>}
{meta.sub && <p className="hidden truncate text-[11px] leading-tight text-ink-3 sm:block sm:mt-[1px]">{meta.sub}</p>}
</div>
</div>
<div className="relative ml-auto hidden w-[240px] md:block lg:w-[280px]">
+2 -2
View File
@@ -109,10 +109,10 @@ export function Sidebar({ open, onClose }: { open: boolean; onClose: () => void
{/* 左下角:账号区 */}
<div className="border-t border-line px-3 py-3">
{getToken() && me ? (
<div className="rounded-lg bg-surface-2 px-3 py-2.5">
<div className="rounded-lg border border-line bg-surface-2 px-3 py-2.5 shadow-card">
<div className="flex items-center justify-between gap-2">
<div className="flex items-center gap-2 min-w-0">
<div className="flex size-6 shrink-0 items-center justify-center rounded-full bg-brand text-[10px] font-bold text-white">
<div className="flex size-6 shrink-0 items-center justify-center rounded-full bg-gradient-to-b from-[#4359e8] to-[#2a3ab8] text-[10px] font-bold text-white shadow-card">
{me.username.charAt(0).toUpperCase()}
</div>
<div className="min-w-0">
+3 -3
View File
@@ -3,12 +3,12 @@ import { cva, type VariantProps } from 'class-variance-authority';
import { cn } from '@/lib/utils';
const buttonVariants = cva(
'inline-flex items-center justify-center gap-1.5 whitespace-nowrap rounded-md font-medium transition-colors select-none disabled:pointer-events-none disabled:opacity-45',
'inline-flex items-center justify-center gap-1.5 whitespace-nowrap rounded-md font-medium select-none transition-all duration-150 active:scale-[0.97] disabled:pointer-events-none disabled:opacity-45',
{
variants: {
variant: {
primary: 'bg-brand text-white hover:bg-brand-hover shadow-card',
secondary: 'bg-surface text-ink-1 border border-line hover:bg-surface-3 hover:border-line-strong',
primary: 'bg-gradient-to-b from-[#3d51e0] to-brand text-white shadow-[0_1px_2px_rgba(48,86,211,.25)] hover:brightness-110 active:brightness-95',
secondary: 'bg-surface text-ink-1 border border-line shadow-card hover:bg-surface-3 hover:border-line-strong hover:shadow-[0_2px_6px_rgba(0,0,0,.06)]',
ghost: 'text-ink-2 hover:bg-surface-3 hover:text-ink-1',
subtle: 'bg-brand-subtle text-brand-text hover:brightness-[0.97]',
danger: 'bg-danger text-white hover:brightness-110',
+6 -3
View File
@@ -8,9 +8,12 @@ export function Empty({ icon, title, description, action }: {
action?: ReactNode;
}) {
return (
<div className="flex flex-col items-center justify-center gap-2 py-16 text-center">
<div className="text-ink-3">{icon ?? <Inbox size={36} strokeWidth={1.5} />}</div>
<div className="text-[13px] font-medium text-ink-2">{title}</div>
<div className="flex flex-col items-center justify-center gap-3 py-16 text-center">
<div className="relative flex size-14 items-center justify-center rounded-full border border-line bg-surface-2 text-ink-3 shadow-card">
<div className="absolute inset-0 rounded-full ring-1 ring-brand/5" aria-hidden />
{icon ?? <Inbox size={26} strokeWidth={1.5} />}
</div>
<div className="mt-1 text-[13px] font-medium text-ink-2">{title}</div>
{description && <div className="max-w-[360px] text-[12px] text-ink-3">{description}</div>}
{action && <div className="mt-2">{action}</div>}
</div>
+1 -1
View File
@@ -1,7 +1,7 @@
import { forwardRef, type InputHTMLAttributes, type TextareaHTMLAttributes } from 'react';
import { cn } from '@/lib/utils';
const base = 'w-full rounded-md border border-line bg-surface px-2.5 text-[13px] text-ink-1 placeholder:text-ink-3 transition-colors hover:border-line-strong focus:border-brand focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed';
const base = 'w-full rounded-md border border-line bg-surface px-2.5 text-[13px] text-ink-1 placeholder:text-ink-3 transition-colors hover:border-line-strong focus:border-brand focus:ring-[1.5px] focus:ring-brand/15 focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed';
export const Input = forwardRef<HTMLInputElement, InputHTMLAttributes<HTMLInputElement>>(function Input(
{ className, ...props }, ref
+1 -1
View File
@@ -12,7 +12,7 @@ export const Select = forwardRef<HTMLSelectElement, SelectHTMLAttributes<HTMLSel
ref={ref}
className={cn(
'w-full h-8 appearance-none rounded-md border border-line bg-surface pl-2.5 pr-7 text-[13px] text-ink-1',
'transition-colors hover:border-line-strong focus:border-brand focus:outline-none disabled:opacity-50',
'transition-colors hover:border-line-strong focus:border-brand focus:ring-[1.5px] focus:ring-brand/15 focus:outline-none disabled:opacity-50',
className
)}
{...props}
+11 -1
View File
@@ -64,7 +64,7 @@
--border-strong: #363b47;
--text-1: #e9ebf0;
--text-2: #a0a8b8;
--text-3: #68707e;
--text-3: #747c8a;
--brand: #6d8bfa;
--brand-hover: #8aa2fb;
--brand-subtle: #1a2144;
@@ -145,10 +145,20 @@ input[type='number']::-webkit-outer-spin-button,
input[type='number']::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
input[type='number'] { -moz-appearance: textfield; appearance: textfield; }
/* 页头毛玻璃(滚动透出内容时更轻盈) */
.header-glass {
background: color-mix(in srgb, var(--surface) 86%, transparent);
backdrop-filter: blur(10px) saturate(1.4);
-webkit-backdrop-filter: blur(10px) saturate(1.4);
}
/* 卡片悬停微抬 */
.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 由 NavLink isActive 挂载) */
.nav-active > svg { color: var(--brand-text); }
/* 侧边栏激活指示条 */
.nav-active::before {
content: '';
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
import{c as ve,d as Ce,f as pe,r as S,ai as ke,aj as Se,j as e,S as _e,B as A,ak as xe,ah as ze,m as me,H as fe,af as Oe,ag as Ie,v as Me,M as Re}from"./index-DuP8O2p4.js";import{R as he,P as Fe,C as Ke}from"./rotate-ccw-xltE5Sb1.js";/**
import{c as ve,d as Ce,f as pe,r as S,ai as ke,aj as Se,j as e,S as _e,B as A,ak as xe,ah as ze,m as me,H as fe,af as Oe,ag as Ie,v as Me,M as Re}from"./index-DH5SEuAI.js";import{R as he,P as Fe,C as Ke}from"./rotate-ccw-Cm9sTuWZ.js";/**
* @license lucide-react v0.475.0 - ISC
*
* This source code is licensed under the ISC license.
@@ -1 +1 @@
import{r as g,f as v,j as t,S as j,t as S}from"./index-DuP8O2p4.js";import{C as c,a as d,b as x}from"./card-DR9dPxFa.js";import{u as N,i as u,a as m}from"./useChart-DtLH1jYK.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-3 py-4 sm:px-6 sm: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:"lg: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,f as v,j as t,S as j,t as S}from"./index-DH5SEuAI.js";import{C as c,a as d,b as x}from"./card-BI024Nvz.js";import{u as N,i as u,a as m}from"./useChart-ZF2N_RV4.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-3 py-4 sm:px-6 sm: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:"lg: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,4 +1,4 @@
import{c as $,f as O,j as e,E as H,w as U,u as k,d as C,r as u,g as y,x as W,y as J,B as j,P as E,I as g,z as Y,C as A,A as V,D as B,F as X,m as S,l as Q,T as q,H as Z,J as z,K as M,S as T,M as D}from"./index-DuP8O2p4.js";import{C as w,a as G,b as F}from"./card-DR9dPxFa.js";import{u as ee,i as K,a as P}from"./useChart-DtLH1jYK.js";import{u as se,i as te,b as ae,a as re,c as ne,d as le,e as ie,f as oe}from"./echarts-BIWefrIc.js";/**
import{c as $,f as O,j as e,E as H,w as U,u as k,d as C,r as u,g as y,x as W,y as J,B as j,P as E,I as g,z as Y,C as A,A as V,D as B,F as X,m as S,l as Q,T as q,H as Z,J as z,K as M,S as T,M as D}from"./index-DH5SEuAI.js";import{C as w,a as G,b as F}from"./card-BI024Nvz.js";import{u as ee,i as K,a as P}from"./useChart-ZF2N_RV4.js";import{u as se,i as te,b as ae,a as re,c as ne,d as le,e as ie,f as oe}from"./echarts-BIWefrIc.js";/**
* @license lucide-react v0.475.0 - ISC
*
* This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
import{c as E,u as P,d as S,r as p,f as q,g as F,j as e,B as f,l as B,ac as L,H as z,J as k,S as M,I as Q,ad as _,ae as K,af as v,ag as T}from"./index-DuP8O2p4.js";/**
import{c as E,u as P,d as S,r as p,f as q,g as F,j as e,B as f,l as B,ac as L,H as z,J as k,S as M,I as Q,ad as _,ae as K,af as v,ag as T}from"./index-DH5SEuAI.js";/**
* @license lucide-react v0.475.0 - ISC
*
* This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
import{c as fe,j as e,a as N,r as s,b as he,u as ve,d as ge,e as je,f as L,g as ye,I as be,S as k,B as w,P as Q,h as te,L as se,G as ae,R as Ne,i as ne,k as ke,l as we,T as Ce,E as le,m as Ee,n as Se,o as _e,C as ze,p as qe,q as Le,s as Re,t as De,v as Ie}from"./index-DuP8O2p4.js";/**
import{c as fe,j as e,a as N,r as s,b as he,u as ve,d as ge,e as je,f as L,g as ye,I as be,S as k,B as w,P as Q,h as te,L as se,G as ae,R as Ne,i as ne,k as ke,l as we,T as Ce,E as le,m as Ee,n as Se,o as _e,C as ze,p as qe,q as Le,s as Re,t as De,v as Ie}from"./index-DH5SEuAI.js";/**
* @license lucide-react v0.475.0 - ISC
*
* This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
import{c as B,d as ve,f as te,r as E,j as e,B as R,ah as Ne,af as L,J as U,S as se,ad as ce,P as q,H as we,a9 as Ce,T as ne,I as W,ag as Se,v as _e}from"./index-DuP8O2p4.js";import{C as ie,a as ae,b as re}from"./card-DR9dPxFa.js";import{R as le,P as ze,C as Re}from"./rotate-ccw-xltE5Sb1.js";/**
import{c as B,d as ve,f as te,r as E,j as e,B as R,ah as Ne,af as L,J as U,S as se,ad as ce,P as q,H as we,a9 as Ce,T as ne,I as W,ag as Se,v as _e}from"./index-DH5SEuAI.js";import{C as ie,a as ae,b as re}from"./card-BI024Nvz.js";import{R as le,P as ze,C as Re}from"./rotate-ccw-Cm9sTuWZ.js";/**
* @license lucide-react v0.475.0 - ISC
*
* This source code is licensed under the ISC license.
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
import{c as D,u as K,d as I,f as L,r,g as q,j as e,B as p,P as F,N as O,m as _,l as H,T as P,C as R,O as G,H as J,J as i,I as j,Q as U,S as z,U as V,V as W,q as X}from"./index-DuP8O2p4.js";import{C as Y}from"./card-DR9dPxFa.js";/**
import{c as D,u as K,d as I,f as L,r,g as q,j as e,B as p,P as F,N as O,m as _,l as H,T as P,C as R,O as G,H as J,J as i,I as j,Q as U,S as z,U as V,V as W,q as X}from"./index-DH5SEuAI.js";import{C as Y}from"./card-BI024Nvz.js";/**
* @license lucide-react v0.475.0 - ISC
*
* This source code is licensed under the ISC license.
@@ -1 +1 @@
import{j as s,a}from"./index-DuP8O2p4.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-DH5SEuAI.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
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
import{c as t}from"./index-DuP8O2p4.js";/**
import{c as t}from"./index-DH5SEuAI.js";/**
* @license lucide-react v0.475.0 - ISC
*
* This source code is licensed under the ISC license.
@@ -1 +1 @@
import{r}from"./index-DuP8O2p4.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-DH5SEuAI.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};
+2 -2
View File
@@ -9,8 +9,8 @@
<link rel="icon" href="/icons/pwa-192.png" />
<link rel="apple-touch-icon" href="/icons/pwa-192.png" />
<title>足迹 Footprints</title>
<script type="module" crossorigin src="/assets/index-DuP8O2p4.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-D9E2kUSE.css">
<script type="module" crossorigin src="/assets/index-DH5SEuAI.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-TvH70H3i.css">
</head>
<body>
<div id="root"></div>