File size: 3,014 Bytes
766d85d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import { currencyDecimals } from '../../utils/formatters'
import { SYMBOLS, SPLIT_COLORS } from './BudgetPanel.constants'

export function widgetTheme(dark: boolean) {
  if (dark) return {
    bg: 'linear-gradient(180deg, #17171d 0%, #0d0d12 100%)',
    border: 'rgba(255,255,255,0.07)',
    text: '#ffffff',
    sub: 'rgba(255,255,255,0.6)',
    faint: 'rgba(255,255,255,0.4)',
    track: 'rgba(255,255,255,0.04)',
    divider: 'rgba(255,255,255,0.07)',
    iconBg: 'rgba(255,255,255,0.08)',
    iconBorder: 'rgba(255,255,255,0.12)',
    iconColor: 'rgba(255,255,255,0.9)',
    centerBg: '#17171d',
    flowBg: 'rgba(255,255,255,0.05)',
    flowBorder: 'rgba(255,255,255,0.07)',
    flowHoverBg: 'rgba(255,255,255,0.08)',
    flowHoverBorder: 'rgba(255,255,255,0.12)',
    rowHover: 'rgba(255,255,255,0.03)',
    shadow: '0 20px 50px rgba(0,0,0,0.35), inset 0 1px 0 rgba(255,255,255,0.04)',
    donutShadow: 'drop-shadow(0 0 20px rgba(0,0,0,0.3))',
  }
  return {
    bg: 'linear-gradient(180deg, #ffffff 0%, #f9fafb 100%)',
    border: 'rgba(15,23,42,0.08)',
    text: '#111827',
    sub: 'rgba(17,24,39,0.6)',
    faint: 'rgba(17,24,39,0.4)',
    track: 'rgba(15,23,42,0.05)',
    divider: 'rgba(15,23,42,0.08)',
    iconBg: 'rgba(15,23,42,0.05)',
    iconBorder: 'rgba(15,23,42,0.1)',
    iconColor: 'rgba(17,24,39,0.75)',
    centerBg: '#ffffff',
    flowBg: 'rgba(15,23,42,0.03)',
    flowBorder: 'rgba(15,23,42,0.08)',
    flowHoverBg: 'rgba(15,23,42,0.06)',
    flowHoverBorder: 'rgba(15,23,42,0.14)',
    rowHover: 'rgba(15,23,42,0.04)',
    shadow: '0 12px 32px rgba(15,23,42,0.08), 0 2px 6px rgba(0,0,0,0.04)',
    donutShadow: 'drop-shadow(0 4px 18px rgba(15,23,42,0.12))',
  }
}

export function hexLighten(hex: string, amount: number): string {
  const m = hex.replace('#', '').match(/.{2}/g)
  if (!m || m.length !== 3) return hex
  const mix = (c: number) => Math.min(255, Math.round(c + (255 - c) * amount))
  const [r, g, b] = m.map(x => parseInt(x, 16))
  return `#${[mix(r), mix(g), mix(b)].map(v => v.toString(16).padStart(2, '0')).join('')}`
}

export const fmtNum = (v: number | null | undefined, locale: string, cur: string) => {
  if (v == null || isNaN(v)) return '-'
  const d = currencyDecimals(cur)
  return Number(v).toLocaleString(locale, { minimumFractionDigits: d, maximumFractionDigits: d }) + ' ' + (SYMBOLS[cur] || cur)
}

type NumOrNull = number | null | undefined

export const calcPP = (p: NumOrNull, n: NumOrNull) => (n! > 0 ? (p as number) / (n as number) : null)
export const calcPD = (p: NumOrNull, d: NumOrNull) => (d! > 0 ? (p as number) / (d as number) : null)
export const calcPPD = (p: NumOrNull, n: NumOrNull, d: NumOrNull) => (n! > 0 && d! > 0 ? (p as number) / ((n as number) * (d as number)) : null)

export function splitColorFor(userId: number, order: number) {
  return SPLIT_COLORS[order % SPLIT_COLORS.length]
}

export function colorForUserId(userId: number) {
  return SPLIT_COLORS[((userId | 0) - 1 + SPLIT_COLORS.length * 1000) % SPLIT_COLORS.length]
}