This commit is contained in:
Daniel Flanagan 2024-08-24 22:35:03 -05:00
parent 23728881bd
commit 31a868b4d9
3 changed files with 74 additions and 4 deletions

View file

@ -2,8 +2,9 @@ import { JSX } from 'preact/jsx-runtime'
import { Budget } from '../models.ts' import { Budget } from '../models.ts'
import { Currency } from '../components/Currency.tsx' import { Currency } from '../components/Currency.tsx'
import { Percentage } from '../components/Percentage.tsx' import { Percentage } from '../components/Percentage.tsx'
import { Component } from 'https://esm.sh/stable/preact@10.19.6/denonext/preact.mjs'
export function BudgetCard( function BudgetCardLit(
{ budget, ...props }: { budget, ...props }:
& { budget: Budget } & { budget: Budget }
& JSX.HTMLAttributes<HTMLDivElement>, & JSX.HTMLAttributes<HTMLDivElement>,
@ -30,8 +31,6 @@ export function BudgetCard(
</h2> </h2>
<div class={`p-2 pl-0 flex-1 leading-none`}> <div class={`p-2 pl-0 flex-1 leading-none`}>
<span class={textColor}> <span class={textColor}>
<Currency amount={Math.abs(budget.target - budget.spent)} />
{remainingRatio >= 0 ? ` left ` : ` over `}
</span> </span>
<br /> <br />
<small> <small>
@ -64,3 +63,73 @@ export function BudgetCard(
</div> </div>
) )
} }
export function BudgetCard(
{ budget, ...props }:
& { budget: Budget }
& JSX.HTMLAttributes<HTMLDivElement>,
) {
const remainingRatio = 1.0 - (budget.spent / budget.target)
const bgClass = (remainingRatio < 0 ? 'bg-red' : 'bg-green') + ' opacity-10'
const accentTextClass = remainingRatio < 0 ? 'text-red' : 'text-green'
return (
<ProgressBarCard
heading={budget.name}
bgClass={bgClass}
accentTextClass={accentTextClass}
ratio={remainingRatio}
subheading={
<>
<Currency amount={Math.abs(budget.target - budget.spent)} />
{remainingRatio >= 0 ? ` left ` : ` over `}
</>
}
{...props}
>
<small>
<Currency amount={budget.spent} /> of{' '}
<Currency amount={budget.target} />
{' spent '}
(<Percentage ratio={remainingRatio} /> remaining)
</small>
</ProgressBarCard>
)
}
interface ProgressBarCardProps {
heading: string
subheading: JSX.Element
bgClass: string
accentTextClass: string
ratio: number
}
export function ProgressBarCard(
{ heading, subheading, bgClass, accentTextClass, ratio, children, ...props }:
& ProgressBarCardProps
& JSX.HTMLAttributes<HTMLDivElement>,
) {
return (
<div
class='bg-surface0 rounded shadow hover:bg-surface1 transition-colors flex justify-between relative z-0 cursor-pointer'
{...props}
>
<div
class={`rounded absolute top-0 bottom-0 left-0 ${bgClass} z-[-1]`}
style={`right: ${ratio * 100}%;`}
/>
<h2
class={`py-2 px-3 text-2xl flex flex-none max-w-xs items-center ${accentTextClass} truncate`}
>
{heading}
</h2>
<div class={`p-2 pl-0 flex-1 leading-none`}>
<span class={accentTextClass}>
{subheading}
</span>
<br />
{children}
</div>
</div>
)
}

View file

@ -98,7 +98,7 @@ export default function Dashboard() {
<header class='bg-mantle'> <header class='bg-mantle'>
<h1 class='text-2xl font-mono p-2 px-2'>FlanBank</h1> <h1 class='text-2xl font-mono p-2 px-2'>FlanBank</h1>
</header> </header>
<section class='grid grid-rows-[1fr_auto] sm:grid-cols-2 sm:grid-rows-1 sm:grid-cols-[1fr_auto] flex-1 max-w-full'> <section class='grid grid-rows-[1fr_auto] sm:grid-cols-2 sm:grid-rows-1 sm:grid-cols-[1fr_auto] flex-1 max-w-full max-w-2xl mx-auto'>
<main class='p-2 sm:pr-0 flex flex-col gap-2 max-w-full'> <main class='p-2 sm:pr-0 flex flex-col gap-2 max-w-full'>
{/*<h1>Budgets Overview</h1>*/} {/*<h1>Budgets Overview</h1>*/}
<section class='flex flex-col gap-2 max-w-full'> <section class='flex flex-col gap-2 max-w-full'>

View file

@ -3,6 +3,7 @@ export interface Budget {
target: number target: number
buffer?: number buffer?: number
spent: number spent: number
color?: string
} }
export interface Bucket { export interface Bucket {