Fix the big number
This commit is contained in:
parent
896ad15321
commit
2ea5107106
2 changed files with 35 additions and 77 deletions
|
|
@ -11,49 +11,21 @@ interface LedDisplayProps {
|
||||||
export default function LedDisplay({
|
export default function LedDisplay({
|
||||||
value,
|
value,
|
||||||
className,
|
className,
|
||||||
animate = true,
|
|
||||||
onClick
|
onClick
|
||||||
}: LedDisplayProps) {
|
}: LedDisplayProps) {
|
||||||
const [displayValue, setDisplayValue] = useState(0);
|
const [displayValue, setDisplayValue] = useState(0);
|
||||||
|
|
||||||
// Animate number changes
|
// Animate number changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!animate) {
|
setDisplayValue(value);
|
||||||
setDisplayValue(value);
|
return;
|
||||||
return;
|
}, [value]);
|
||||||
}
|
|
||||||
|
|
||||||
const duration = 1000; // 1 second animation
|
// Format number with zero-padding for consistent width
|
||||||
const steps = 60; // 60fps
|
|
||||||
const stepValue = (value - displayValue) / steps;
|
|
||||||
|
|
||||||
if (Math.abs(stepValue) < 0.01) {
|
|
||||||
setDisplayValue(value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const timer = setInterval(() => {
|
|
||||||
setDisplayValue(prev => {
|
|
||||||
const next = prev + stepValue;
|
|
||||||
if (Math.abs(next - value) < Math.abs(stepValue)) {
|
|
||||||
clearInterval(timer);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
return next;
|
|
||||||
});
|
|
||||||
}, duration / steps);
|
|
||||||
|
|
||||||
return () => clearInterval(timer);
|
|
||||||
}, [value, displayValue, animate]);
|
|
||||||
|
|
||||||
// Format number appropriately for shares
|
|
||||||
const formatValue = (value: number) => {
|
const formatValue = (value: number) => {
|
||||||
// If it's a whole number, show it as integer
|
// Always pad to 5 digits for consistent display width
|
||||||
if (value % 1 === 0) {
|
const integerPart = Math.floor(value);
|
||||||
return value.toString();
|
return integerPart.toString().padStart(5, '0');
|
||||||
}
|
|
||||||
// Otherwise show up to 6 decimal places, removing trailing zeros
|
|
||||||
return value.toFixed(6).replace(/\.?0+$/, '');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const formattedValue = formatValue(displayValue);
|
const formattedValue = formatValue(displayValue);
|
||||||
|
|
@ -61,43 +33,27 @@ export default function LedDisplay({
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"font-mono text-center select-none cursor-pointer",
|
"w-full text-center select-none cursor-pointer",
|
||||||
"bg-black text-red-500",
|
"bg-black text-red-500",
|
||||||
"border-4 border-gray-800 rounded-lg",
|
"px-8 py-12 transition-all duration-300",
|
||||||
"shadow-2xl shadow-red-500/20",
|
|
||||||
"p-8 transition-all duration-300",
|
|
||||||
"hover:shadow-red-500/40 hover:border-red-600",
|
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
>
|
>
|
||||||
<div className="relative">
|
<div className="relative w-full flex items-center justify-center">
|
||||||
{/* Background glow effect */}
|
|
||||||
<div className="absolute inset-0 text-red-500/20 blur-sm font-digital text-6xl md:text-8xl lg:text-9xl tracking-widest">
|
|
||||||
{formattedValue}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Main LED text */}
|
|
||||||
<div className={cn(
|
<div className={cn(
|
||||||
"relative z-10",
|
"relative z-10",
|
||||||
"text-6xl md:text-8xl lg:text-9xl",
|
"text-[8rem] md:text-[12rem] lg:text-[16rem]",
|
||||||
"font-digital font-normal tracking-widest",
|
"font-digital font-normal",
|
||||||
"text-red-500",
|
"text-red-500",
|
||||||
"drop-shadow-[0_0_10px_rgba(239,68,68,0.8)]",
|
"drop-shadow-[0_0_10px_rgba(239,68,68,0.8)]",
|
||||||
"filter brightness-110"
|
"filter brightness-110",
|
||||||
)}>
|
"leading-none",
|
||||||
|
"transition-all duration-300"
|
||||||
|
)}
|
||||||
|
style={{ letterSpacing: '0.15em' }}>
|
||||||
{formattedValue}
|
{formattedValue}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Subtle scan line effect */}
|
|
||||||
<div className="absolute inset-0 pointer-events-none">
|
|
||||||
<div className="h-full w-full bg-gradient-to-b from-transparent via-red-500/5 to-transparent animate-pulse" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Label */}
|
|
||||||
<div className="mt-4 text-red-400/80 text-sm md:text-base font-mono-display tracking-wider">
|
|
||||||
total shares
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -128,16 +128,18 @@ export default function Dashboard() {
|
||||||
<Head title="VWCE Tracker" />
|
<Head title="VWCE Tracker" />
|
||||||
|
|
||||||
{/* Stacked Layout */}
|
{/* Stacked Layout */}
|
||||||
<div className="min-h-screen bg-black flex items-center justify-center">
|
<div className="min-h-screen bg-black">
|
||||||
<div className="w-full max-w-4xl mx-4 space-y-4">
|
<div className="w-full max-w-4xl mx-auto px-4">
|
||||||
{/* Box 1: LED Number Display */}
|
{/* Box 1: LED Number Display - Fixed position from top */}
|
||||||
<LedDisplay
|
<div className="pt-32">
|
||||||
value={purchaseData.total_shares}
|
<LedDisplay
|
||||||
onClick={handleLedClick}
|
value={purchaseData.total_shares}
|
||||||
/>
|
onClick={handleLedClick}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Box 2: Progress Bar (toggleable) */}
|
{/* Box 2: Progress Bar (toggleable) */}
|
||||||
<div style={{ display: showProgressBar ? 'block' : 'none' }}>
|
<div className="mt-4" style={{ display: showProgressBar ? 'block' : 'none' }}>
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
value={purchaseData.total_shares}
|
value={purchaseData.total_shares}
|
||||||
onClick={handleProgressClick}
|
onClick={handleProgressClick}
|
||||||
|
|
@ -145,7 +147,7 @@ export default function Dashboard() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Box 3: Stats Box (toggleable) */}
|
{/* Box 3: Stats Box (toggleable) */}
|
||||||
<div style={{ display: showStatsBox ? 'block' : 'none' }}>
|
<div className="mt-4" style={{ display: showStatsBox ? 'block' : 'none' }}>
|
||||||
<StatsBox
|
<StatsBox
|
||||||
stats={statsData}
|
stats={statsData}
|
||||||
onAddPurchase={() => setActiveForm('purchase')}
|
onAddPurchase={() => setActiveForm('purchase')}
|
||||||
|
|
@ -154,7 +156,7 @@ export default function Dashboard() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Box 4: Forms (only when active form is set) */}
|
{/* Box 4: Forms (only when active form is set) */}
|
||||||
<div style={{ display: activeForm ? 'block' : 'none' }}>
|
<div className="mt-4" style={{ display: activeForm ? 'block' : 'none' }}>
|
||||||
<InlineForm
|
<InlineForm
|
||||||
type={activeForm}
|
type={activeForm}
|
||||||
onClose={() => setActiveForm(null)}
|
onClose={() => setActiveForm(null)}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue