diff --git a/components/IconButton.tsx b/components/IconButton.tsx index 2eab7f0..f10a57a 100644 --- a/components/IconButton.tsx +++ b/components/IconButton.tsx @@ -1,9 +1,10 @@ import { JSX } from 'preact/jsx-runtime' +import { Icons } from './icons.tsx' interface IconButtonProps { active?: boolean text?: string - icon?: JSX.Element + icon?: keyof (typeof Icons) } export function IconButton( @@ -11,13 +12,22 @@ export function IconButton( & IconButtonProps & JSX.HTMLAttributes, ) { + const Icon = typeof icon === 'string' + ? Icons[icon as keyof typeof Icons] + : (() => <>) return ( ) diff --git a/components/IconLink.tsx b/components/IconLink.tsx new file mode 100644 index 0000000..fbab3d2 --- /dev/null +++ b/components/IconLink.tsx @@ -0,0 +1,34 @@ +import { JSX } from 'preact/jsx-runtime' +import { Icons } from './icons.tsx' + +interface IconLinkProps { + active?: boolean + text?: string + icon?: keyof (typeof Icons) +} + +export function IconLink( + { icon, children, active, ...props }: + & IconLinkProps + & JSX.HTMLAttributes, +) { + const Icon = typeof icon === 'string' + ? Icons[icon as keyof typeof Icons] + : (() => <>) + return ( + + {icon !== undefined + ? ( + + + + ) + : ''} +
{children}
+
+ ) +} diff --git a/components/icons.tsx b/components/icons.tsx new file mode 100644 index 0000000..6f19696 --- /dev/null +++ b/components/icons.tsx @@ -0,0 +1,22 @@ +export const Icons = { + 'SomeIcon': SomeIcon, +} + +function SomeIcon() { + return ( + + + + ) +} diff --git a/deno.json b/deno.json index 3107d16..058543c 100644 --- a/deno.json +++ b/deno.json @@ -25,6 +25,7 @@ "preact": "https://esm.sh/preact@10.19.6", "preact/": "https://esm.sh/preact@10.19.6/", "@preact/signals": "https://esm.sh/*@preact/signals@1.2.2", + "preact/hooks": "https://esm.sh/preact@10.19.6/hooks", "@preact/signals-core": "https://esm.sh/*@preact/signals-core@1.5.1", "tailwindcss": "npm:tailwindcss@3.4.1", "tailwindcss/": "npm:/tailwindcss@3.4.1/", diff --git a/fresh.gen.ts b/fresh.gen.ts index 205300a..98ac17a 100644 --- a/fresh.gen.ts +++ b/fresh.gen.ts @@ -5,11 +5,13 @@ import * as $_404 from './routes/_404.tsx' import * as $_app from './routes/_app.tsx' import * as $api_joke from './routes/api/joke.ts' +import * as $bank_subpage_index from './routes/bank/[[subpage]]/index.tsx' import * as $greet_name_ from './routes/greet/[name].tsx' import * as $index from './routes/index.tsx' import * as $BudgetCard from './islands/BudgetCard.tsx' import * as $Counter from './islands/Counter.tsx' import * as $Dashboard from './islands/Dashboard.tsx' +import * as $Nav from './islands/Nav.tsx' import { type Manifest } from '$fresh/server.ts' const manifest = { @@ -17,6 +19,7 @@ const manifest = { './routes/_404.tsx': $_404, './routes/_app.tsx': $_app, './routes/api/joke.ts': $api_joke, + './routes/bank/[[subpage]]/index.tsx': $bank_subpage_index, './routes/greet/[name].tsx': $greet_name_, './routes/index.tsx': $index, }, @@ -24,6 +27,7 @@ const manifest = { './islands/BudgetCard.tsx': $BudgetCard, './islands/Counter.tsx': $Counter, './islands/Dashboard.tsx': $Dashboard, + './islands/Nav.tsx': $Nav, }, baseUrl: import.meta.url, } satisfies Manifest diff --git a/islands/BudgetCard.tsx b/islands/BudgetCard.tsx index a89e377..cd03c03 100644 --- a/islands/BudgetCard.tsx +++ b/islands/BudgetCard.tsx @@ -119,7 +119,6 @@ export function ProgressBarCard( & ProgressBarCardProps & JSX.HTMLAttributes, ) { - console.log({ fillRatio }) return (
- - - ), - }, - { - text: 'Some Text', - icon: ( - - - - ), - }, - { - text: 'Some Text', - icon: ( - - - - ), - }, - ] +const budgets: Budget[] = [ + { + name: 'Groceries', + target: 1000, + spent: 367.97, + }, + { + name: + 'A very long budget name that should definitely be shortened to something reasonable', + target: 100000000, + spent: 26893085.56, + }, + { + name: 'Fast Food', + target: 300, + spent: 420.69, + }, + { + name: 'Insurance', + target: 220.44, + spent: 0, + }, + { + name: 'Mortgage', + target: 1310.47, + spent: 1310.47, + }, +] + +export function BudgetsOverview() { + let sig = useSignal(IS_BROWSER ? globalThis.location.hash : '') + + addEventListener('popstate', (ev) => { + console.log('popstate', ev) + sig.value = globalThis.location.hash + ev.preventDefault() + return false + }) + + useEffect(() => { + setTimeout(() => { + console.log('Timeout!') + }, 2000) + addEventListener('popstate', (ev) => { + console.log('popstate', ev) + sig.value = globalThis.location.hash + }) + }, [sig]) const uncategorizedSpend = 851.22 @@ -100,9 +61,10 @@ export default function Dashboard() {

FlanBank

+ {sig.value}
-
+
{/*

Budgets Overview

*/}
{uncategorizedSpend <= 0 ? '' : ( @@ -123,21 +85,7 @@ export default function Dashboard() { {budgets.map((budget, _i) => )}
- - +
) diff --git a/islands/Nav.tsx b/islands/Nav.tsx new file mode 100644 index 0000000..0ce824a --- /dev/null +++ b/islands/Nav.tsx @@ -0,0 +1,47 @@ +import { JSX } from 'preact/jsx-runtime' +import { IconLink } from '../components/IconLink.tsx' +import { Icons } from '../components/icons.tsx' +import { IS_BROWSER } from '$fresh/runtime.ts' + +interface NavItem { + text: string + href: string + icon?: keyof typeof Icons +} + +const navItems: NavItem[] = [ + { + text: 'Budgets', + href: '/bank/budgets', + icon: 'SomeIcon', + }, + { + text: 'Transactions', + href: '/bank/transactions', + }, + { + text: 'Something', + href: '/bank/something', + }, +] + +export function Nav(_props: JSX.HTMLAttributes) { + // TODO: on nav, the `active` field is not updated + globalThis.addEventListener('popstate', (ev) => { + console.log('popstate', ev) + }) + return ( + + ) +} diff --git a/routes/_app.tsx b/routes/_app.tsx index 161dac7..1428948 100644 --- a/routes/_app.tsx +++ b/routes/_app.tsx @@ -1,4 +1,5 @@ import { type PageProps } from '$fresh/server.ts' +import { Partial } from '$fresh/runtime.ts' export default function App({ Component }: PageProps) { return ( @@ -8,8 +9,13 @@ export default function App({ Component }: PageProps) { Bank - - + + + + ) diff --git a/routes/bank/[[subpage]]/index.tsx b/routes/bank/[[subpage]]/index.tsx new file mode 100644 index 0000000..a4e0dc7 --- /dev/null +++ b/routes/bank/[[subpage]]/index.tsx @@ -0,0 +1,21 @@ +import { PageProps } from '$fresh/server.ts' +import { BudgetsOverview } from '../../../islands/Dashboard.tsx' + +export default function Bank(props: PageProps) { + const { subpage } = props.params + let Component = () => ; + switch (subpage) { + case 'transactions': + Component = () => <>Transactions + break + + } + + return ( +
+
+

FlanBank

+ {sig.value} +
+
+
} diff --git a/routes/index.tsx b/routes/index.tsx index 3f225bd..936c36d 100644 --- a/routes/index.tsx +++ b/routes/index.tsx @@ -1,5 +1,6 @@ -import Dashboard from '../islands/Dashboard.tsx' - -export default function Home() { - return +export function handler(_req: Request): Response { + return new Response('', { + status: 307, + headers: { Location: '/bank' }, + }) }