chore: tidy up project structure and normalize formatting
This commit is contained in:
@@ -220,7 +220,7 @@ function pageBreak(doc: jsPDF, y: number, threshold: number = 262): boolean {
|
||||
|
||||
|
||||
// ===========================================================================
|
||||
// 1. CLEAN — Swiss minimalism, single blue accent
|
||||
// 1. CLEAN - Swiss minimalism, single blue accent
|
||||
// ===========================================================================
|
||||
|
||||
function renderClean(
|
||||
@@ -316,7 +316,7 @@ function renderClean(
|
||||
|
||||
|
||||
// ===========================================================================
|
||||
// 2. PROFESSIONAL — Navy header band, corporate polish
|
||||
// 2. PROFESSIONAL - Navy header band, corporate polish
|
||||
// ===========================================================================
|
||||
|
||||
function renderProfessional(
|
||||
@@ -402,7 +402,7 @@ function renderProfessional(
|
||||
|
||||
|
||||
// ===========================================================================
|
||||
// 3. BOLD — Large indigo block with oversized typography
|
||||
// 3. BOLD - Large indigo block with oversized typography
|
||||
// ===========================================================================
|
||||
|
||||
function renderBold(
|
||||
@@ -475,7 +475,7 @@ function renderBold(
|
||||
drawHeaderText(doc, layout, y, rowH, c.tableHeaderText, padX)
|
||||
y += rowH
|
||||
|
||||
// Rows — no borders, no stripes, generous height
|
||||
// Rows - no borders, no stripes, generous height
|
||||
for (const item of items) {
|
||||
if (pageBreak(doc, y)) y = 20
|
||||
y = drawItemRow(doc, item, layout, y, rowH, c.bodyText, padX)
|
||||
@@ -494,7 +494,7 @@ function renderBold(
|
||||
|
||||
|
||||
// ===========================================================================
|
||||
// 4. MINIMAL — Pure monochrome, everything centered
|
||||
// 4. MINIMAL - Pure monochrome, everything centered
|
||||
// ===========================================================================
|
||||
|
||||
function renderMinimal(
|
||||
@@ -562,7 +562,7 @@ function renderMinimal(
|
||||
drawHeaderText(doc, layout, y, rowH, c.primary, padX)
|
||||
y += rowH
|
||||
|
||||
// Rows — whitespace separation only
|
||||
// Rows - whitespace separation only
|
||||
for (const item of items) {
|
||||
if (pageBreak(doc, y)) y = 20
|
||||
y = drawItemRow(doc, item, layout, y, rowH, c.bodyText, padX)
|
||||
@@ -601,7 +601,7 @@ function renderMinimal(
|
||||
|
||||
|
||||
// ===========================================================================
|
||||
// 5. CLASSIC — Traditional layout, burgundy accents, bordered grid
|
||||
// 5. CLASSIC - Traditional layout, burgundy accents, bordered grid
|
||||
// ===========================================================================
|
||||
|
||||
function renderClassic(
|
||||
@@ -712,7 +712,7 @@ function renderClassic(
|
||||
|
||||
|
||||
// ===========================================================================
|
||||
// 6. MODERN — Teal accents, borderless, teal header text
|
||||
// 6. MODERN - Teal accents, borderless, teal header text
|
||||
// ===========================================================================
|
||||
|
||||
function renderModern(
|
||||
@@ -837,7 +837,7 @@ function renderModern(
|
||||
|
||||
|
||||
// ===========================================================================
|
||||
// 7. ELEGANT — Gold double-rule accents, centered layout
|
||||
// 7. ELEGANT - Gold double-rule accents, centered layout
|
||||
// ===========================================================================
|
||||
|
||||
function renderElegant(
|
||||
@@ -960,7 +960,7 @@ function renderElegant(
|
||||
|
||||
|
||||
// ===========================================================================
|
||||
// 8. CREATIVE — Purple sidebar, card-style rows
|
||||
// 8. CREATIVE - Purple sidebar, card-style rows
|
||||
// ===========================================================================
|
||||
|
||||
function renderCreative(
|
||||
@@ -1058,7 +1058,7 @@ function renderCreative(
|
||||
|
||||
|
||||
// ===========================================================================
|
||||
// 9. COMPACT — Data-dense layout with tight spacing
|
||||
// 9. COMPACT - Data-dense layout with tight spacing
|
||||
// ===========================================================================
|
||||
|
||||
function renderCompact(
|
||||
@@ -1184,7 +1184,7 @@ function renderCompact(
|
||||
|
||||
|
||||
// ===========================================================================
|
||||
// 10. DARK — Full dark background with cyan highlights
|
||||
// 10. DARK - Full dark background with cyan highlights
|
||||
// ===========================================================================
|
||||
|
||||
function renderDark(
|
||||
@@ -1307,7 +1307,7 @@ function renderDark(
|
||||
|
||||
|
||||
// ===========================================================================
|
||||
// 11. VIBRANT — Coral header band, warm tones
|
||||
// 11. VIBRANT - Coral header band, warm tones
|
||||
// ===========================================================================
|
||||
|
||||
function renderVibrant(
|
||||
@@ -1390,7 +1390,7 @@ function renderVibrant(
|
||||
|
||||
|
||||
// ===========================================================================
|
||||
// 12. CORPORATE — Blue header with info bar below
|
||||
// 12. CORPORATE - Blue header with info bar below
|
||||
// ===========================================================================
|
||||
|
||||
function renderCorporate(
|
||||
@@ -1482,7 +1482,7 @@ function renderCorporate(
|
||||
|
||||
|
||||
// ===========================================================================
|
||||
// 13. FRESH — Oversized watermark invoice number
|
||||
// 13. FRESH - Oversized watermark invoice number
|
||||
// ===========================================================================
|
||||
|
||||
function renderFresh(
|
||||
@@ -1581,7 +1581,7 @@ function renderFresh(
|
||||
|
||||
|
||||
// ===========================================================================
|
||||
// 14. NATURAL — Warm beige full-page background, terracotta accents
|
||||
// 14. NATURAL - Warm beige full-page background, terracotta accents
|
||||
// ===========================================================================
|
||||
|
||||
function renderNatural(
|
||||
@@ -1684,7 +1684,7 @@ function renderNatural(
|
||||
|
||||
|
||||
// ===========================================================================
|
||||
// 15. STATEMENT — Total-forward design, hero amount top-right
|
||||
// 15. STATEMENT - Total-forward design, hero amount top-right
|
||||
// ===========================================================================
|
||||
|
||||
function renderStatement(
|
||||
|
||||
@@ -15,10 +15,10 @@ export interface CurrencyOption {
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// LOCALES — ~140 worldwide locale/region combinations
|
||||
// LOCALES - ~140 worldwide locale/region combinations
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export const LOCALES: LocaleOption[] = [
|
||||
const _LOCALES_RAW: LocaleOption[] = [
|
||||
// System default
|
||||
{ code: 'system', name: 'System Default' },
|
||||
|
||||
@@ -234,11 +234,16 @@ export const LOCALES: LocaleOption[] = [
|
||||
{ code: 'fj-FJ', name: 'Fijian (Fiji)' },
|
||||
]
|
||||
|
||||
export const LOCALES: LocaleOption[] = [
|
||||
{ code: 'system', name: 'System Default' },
|
||||
..._LOCALES_RAW.filter(l => l.code !== 'system').sort((a, b) => a.name.localeCompare(b.name)),
|
||||
]
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FALLBACK_CURRENCIES — ~120+ currencies with English names
|
||||
// FALLBACK_CURRENCIES - ~120+ currencies with English names
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export const FALLBACK_CURRENCIES: CurrencyOption[] = [
|
||||
const _FALLBACK_CURRENCIES_RAW: CurrencyOption[] = [
|
||||
{ code: 'USD', name: 'US Dollar' },
|
||||
{ code: 'EUR', name: 'Euro' },
|
||||
{ code: 'GBP', name: 'British Pound' },
|
||||
@@ -369,6 +374,9 @@ export const FALLBACK_CURRENCIES: CurrencyOption[] = [
|
||||
{ code: 'BND', name: 'Brunei Dollar' },
|
||||
]
|
||||
|
||||
export const FALLBACK_CURRENCIES: CurrencyOption[] =
|
||||
[..._FALLBACK_CURRENCIES_RAW].sort((a, b) => a.name.localeCompare(b.name))
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Currency builder (runtime Intl detection with fallback)
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -383,7 +391,7 @@ function buildCurrencies(): CurrencyOption[] {
|
||||
return codes.map((code) => ({
|
||||
code,
|
||||
name: displayNames.of(code) ?? code,
|
||||
}))
|
||||
})).sort((a, b) => a.name.localeCompare(b.name))
|
||||
} catch {
|
||||
return FALLBACK_CURRENCIES
|
||||
}
|
||||
@@ -423,7 +431,7 @@ export function getCurrencyCode(): string {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Short date — e.g. "Jan 5, 2025"
|
||||
* Short date - e.g. "Jan 5, 2025"
|
||||
* Parses the date-part manually to avoid timezone-shift issues.
|
||||
*/
|
||||
export function formatDate(dateString: string): string {
|
||||
@@ -437,7 +445,7 @@ export function formatDate(dateString: string): string {
|
||||
}
|
||||
|
||||
/**
|
||||
* Long date — e.g. "Monday, January 5, 2025"
|
||||
* Long date - e.g. "Monday, January 5, 2025"
|
||||
*/
|
||||
export function formatDateLong(dateString: string): string {
|
||||
const [year, month, day] = dateString.substring(0, 10).split('-').map(Number)
|
||||
@@ -451,7 +459,7 @@ export function formatDateLong(dateString: string): string {
|
||||
}
|
||||
|
||||
/**
|
||||
* Short date + time — e.g. "Jan 5, 2025, 3:42 PM"
|
||||
* Short date + time - e.g. "Jan 5, 2025, 3:42 PM"
|
||||
*/
|
||||
export function formatDateTime(dateString: string): string {
|
||||
const date = new Date(dateString)
|
||||
@@ -465,7 +473,7 @@ export function formatDateTime(dateString: string): string {
|
||||
}
|
||||
|
||||
/**
|
||||
* Full currency format — e.g. "$1,234.56"
|
||||
* Full currency format - e.g. "$1,234.56"
|
||||
*/
|
||||
export function formatCurrency(amount: number): string {
|
||||
return new Intl.NumberFormat(getLocaleCode(), {
|
||||
@@ -485,7 +493,7 @@ export function formatCurrencyCompact(amount: number): string {
|
||||
}
|
||||
|
||||
/**
|
||||
* Number with locale grouping — e.g. "1,234.56"
|
||||
* Number with locale grouping - e.g. "1,234.56"
|
||||
*/
|
||||
export function formatNumber(amount: number, decimals?: number): string {
|
||||
return new Intl.NumberFormat(getLocaleCode(), {
|
||||
@@ -495,7 +503,7 @@ export function formatNumber(amount: number, decimals?: number): string {
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract just the currency symbol — e.g. "$", "\u00a3", "\u20ac"
|
||||
* Extract just the currency symbol - e.g. "$", "\u00a3", "\u20ac"
|
||||
*/
|
||||
export function getCurrencySymbol(): string {
|
||||
const parts = new Intl.NumberFormat(getLocaleCode(), {
|
||||
|
||||
Reference in New Issue
Block a user