feat:分组汇总置顶可选

This commit is contained in:
hzm
2026-02-10 08:41:42 +08:00
parent 9cf05c1c1c
commit 3abee08b2f
3 changed files with 53 additions and 5 deletions

View File

@@ -8,6 +8,26 @@ export function PlusIcon(props) {
); );
} }
export function PinIcon(props) {
return (
<svg {...props} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<line x1="12" y1="17" x2="12" y2="22"></line>
<path d="M5 17h14v-1.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V6h1a2 2 0 0 0 0-4H8a2 2 0 0 0 0 4h1v4.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24Z"></path>
</svg>
);
}
export function PinOffIcon(props) {
return (
<svg {...props} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<line x1="2" y1="2" x2="22" y2="22"></line>
<line x1="12" y1="17" x2="12" y2="22"></line>
<path d="M9 9v1.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V17h14v-1.76a2 2 0 0 0-.5-.9"></path>
<path d="M15 5.24V6h1a2 2 0 0 0 0-4H8a2 2 0 0 0-1.33.5"></path>
</svg>
);
}
export function UpdateIcon(props) { export function UpdateIcon(props) {
return ( return (
<svg {...props} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"> <svg {...props} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">

View File

@@ -420,6 +420,16 @@ input[type="number"] {
transform: translateY(0); transform: translateY(0);
} }
.sticky-toggle-btn {
display: none !important;
}
@media (max-width: 640px) {
.sticky-toggle-btn {
display: inline-flex !important;
}
}
.icon-button.danger { .icon-button.danger {
background: linear-gradient(180deg, #ef4444, #f87171); background: linear-gradient(180deg, #ef4444, #f87171);
color: #2b0b0b; color: #2b0b0b;

View File

@@ -9,7 +9,7 @@ import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone'; import timezone from 'dayjs/plugin/timezone';
import Announcement from "./components/Announcement"; import Announcement from "./components/Announcement";
import { DatePicker, DonateTabs, NumericInput, Stat } from "./components/Common"; import { DatePicker, DonateTabs, NumericInput, Stat } from "./components/Common";
import { ChevronIcon, CloseIcon, CloudIcon, DragIcon, ExitIcon, EyeIcon, EyeOffIcon, GridIcon, ListIcon, LoginIcon, LogoutIcon, MailIcon, PlusIcon, RefreshIcon, SettingsIcon, SortIcon, StarIcon, TrashIcon, UpdateIcon, UserIcon } from "./components/Icons"; import { ChevronIcon, CloseIcon, CloudIcon, DragIcon, ExitIcon, EyeIcon, EyeOffIcon, GridIcon, ListIcon, LoginIcon, LogoutIcon, MailIcon, PinIcon, PinOffIcon, PlusIcon, RefreshIcon, SettingsIcon, SortIcon, StarIcon, TrashIcon, UpdateIcon, UserIcon } from "./components/Icons";
import githubImg from "./assets/github.svg"; import githubImg from "./assets/github.svg";
import weChatGroupImg from "./assets/weChatGroup.png"; import weChatGroupImg from "./assets/weChatGroup.png";
import { supabase, isSupabaseConfigured } from './lib/supabase'; import { supabase, isSupabaseConfigured } from './lib/supabase';
@@ -1729,6 +1729,7 @@ function CountUp({ value, prefix = '', suffix = '', decimals = 2, className = ''
function GroupSummary({ funds, holdings, groupName, getProfit }) { function GroupSummary({ funds, holdings, groupName, getProfit }) {
const [showPercent, setShowPercent] = useState(true); const [showPercent, setShowPercent] = useState(true);
const [isMasked, setIsMasked] = useState(false); const [isMasked, setIsMasked] = useState(false);
const [isSticky, setIsSticky] = useState(false);
const rowRef = useRef(null); const rowRef = useRef(null);
const [assetSize, setAssetSize] = useState(24); const [assetSize, setAssetSize] = useState(24);
const [metricSize, setMetricSize] = useState(18); const [metricSize, setMetricSize] = useState(18);
@@ -1790,7 +1791,25 @@ function GroupSummary({ funds, holdings, groupName, getProfit }) {
if (!summary.hasHolding) return null; if (!summary.hasHolding) return null;
return ( return (
<div className="glass card group-summary-card" style={{ marginBottom: 8, padding: '16px 20px', background: 'rgba(255, 255, 255, 0.03)' }}> <div className={isSticky ? "group-summary-sticky" : ""}>
<div className="glass card group-summary-card" style={{ marginBottom: 8, padding: '16px 20px', background: 'rgba(255, 255, 255, 0.03)', position: 'relative' }}>
<span
className="sticky-toggle-btn"
onClick={() => setIsSticky(!isSticky)}
style={{
position: 'absolute',
top: 4,
right: 4,
width: 24,
height: 24,
padding: 4,
opacity: 0.6,
zIndex: 10,
color: 'var(--muted)'
}}
>
{isSticky ? <PinIcon width="14" height="14" /> : <PinOffIcon width="14" height="14" />}
</span>
<div ref={rowRef} className="row" style={{ alignItems: 'flex-end', justifyContent: 'space-between' }}> <div ref={rowRef} className="row" style={{ alignItems: 'flex-end', justifyContent: 'space-between' }}>
<div> <div>
<div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 4 }}> <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 4 }}>
@@ -1855,6 +1874,7 @@ function GroupSummary({ funds, holdings, groupName, getProfit }) {
</div> </div>
</div> </div>
</div> </div>
</div>
); );
} }
@@ -4107,14 +4127,12 @@ export default function HomePage() {
</div> </div>
) : ( ) : (
<> <>
<div className={'group-summary-sticky'}>
<GroupSummary <GroupSummary
funds={displayFunds} funds={displayFunds}
holdings={holdings} holdings={holdings}
groupName={getGroupName()} groupName={getGroupName()}
getProfit={getHoldingProfit} getProfit={getHoldingProfit}
/> />
</div>
{currentTab !== 'all' && currentTab !== 'fav' && ( {currentTab !== 'all' && currentTab !== 'fav' && (
<motion.button <motion.button