refactor: Extract SatsDisplay component and fix page IDs
- Extract SatsDisplay component to shared components directory - Fix page IDs: rename 'admin-appointments' to 'admin-trades' - Fix trades page using correct 'trades' page ID
This commit is contained in:
parent
ce8f5a1183
commit
4e6f38e4a1
5 changed files with 66 additions and 169 deletions
|
|
@ -6,6 +6,7 @@ import { useRouter } from "next/navigation";
|
|||
import { Permission } from "../auth-context";
|
||||
import { api } from "../api";
|
||||
import { Header } from "../components/Header";
|
||||
import { SatsDisplay } from "../components/SatsDisplay";
|
||||
import { useRequireAuth } from "../hooks/useRequireAuth";
|
||||
import { components } from "../generated/api";
|
||||
import { formatDate, formatTime, getDateRange } from "../utils/date";
|
||||
|
|
@ -30,65 +31,6 @@ function formatEur(cents: number): string {
|
|||
return `€${(cents / 100).toLocaleString("de-DE")}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format satoshi amount with styled components
|
||||
* Leading zeros are subtle, main digits are prominent
|
||||
* e.g., 1876088 -> "₿ 0.01" (subtle) + "876 088 sats" (prominent)
|
||||
*/
|
||||
function SatsDisplay({ sats }: { sats: number }) {
|
||||
const btc = sats / 100_000_000;
|
||||
const btcStr = btc.toFixed(8);
|
||||
const [whole, decimal] = btcStr.split(".");
|
||||
|
||||
// Group decimal into chunks: first 2, then two groups of 3
|
||||
const part1 = decimal.slice(0, 2);
|
||||
const part2 = decimal.slice(2, 5);
|
||||
const part3 = decimal.slice(5, 8);
|
||||
|
||||
// Find where meaningful digits start (first non-zero after decimal)
|
||||
const fullDecimal = part1 + part2 + part3;
|
||||
let firstNonZero = fullDecimal.length;
|
||||
for (let i = 0; i < fullDecimal.length; i++) {
|
||||
if (fullDecimal[i] !== "0") {
|
||||
firstNonZero = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Build the display with subtle leading zeros and prominent digits
|
||||
const subtleStyle: React.CSSProperties = {
|
||||
opacity: 0.45,
|
||||
fontWeight: 400,
|
||||
};
|
||||
|
||||
// Determine which parts are subtle vs prominent
|
||||
const renderPart = (part: string, startIdx: number) => {
|
||||
const chars = part.split("").map((char, i) => {
|
||||
const globalIdx = startIdx + i;
|
||||
const isSubtle = globalIdx < firstNonZero;
|
||||
return (
|
||||
<span key={globalIdx} style={isSubtle ? subtleStyle : undefined}>
|
||||
{char}
|
||||
</span>
|
||||
);
|
||||
});
|
||||
return chars;
|
||||
};
|
||||
|
||||
return (
|
||||
<span style={{ fontFamily: "'DM Mono', monospace" }}>
|
||||
<span style={subtleStyle}>₿</span>
|
||||
<span style={subtleStyle}> {whole}.</span>
|
||||
{renderPart(part1, 0)}
|
||||
<span> </span>
|
||||
{renderPart(part2, 2)}
|
||||
<span> </span>
|
||||
{renderPart(part3, 5)}
|
||||
<span> sats</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format price for display
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue