@@ -5,11 +5,10 @@ import { DashboardLayout } from '../../src/components/layout';
55import { backendFetch } from '../../src/lib/backend' ;
66
77type Group = { id : string ; name : string ; currency : string } ;
8- type Balance = { id : string ; userId : string ; counterpartyUserId : string ; amountCents : string } ;
98
10- function formatMoney ( cents : bigint , currency : string | null ) : string {
11- if ( ! currency ) {
12- return '— ' ;
9+ function formatMoney ( cents : string | null , currency : string | null ) : string {
10+ if ( ! cents || ! currency ) {
11+ return '$0.00 ' ;
1312 }
1413
1514 const amount = Number ( cents ) / 100 ;
@@ -18,72 +17,55 @@ function formatMoney(cents: bigint, currency: string | null): string {
1817
1918export default async function DashboardPage ( ) {
2019 const [ me , groups ] = await Promise . all ( [
21- backendFetch < AuthUserDto > ( '/users/me' ) . catch ( ( ) => null ) ,
22- backendFetch < Group [ ] > ( '/groups' ) . catch ( ( ) => [ ] as Group [ ] ) ,
20+ backendFetch < AuthUserDto > ( '/users/me' ) ,
21+ backendFetch < Group [ ] > ( '/groups' ) ,
2322 ] ) ;
2423
25- const activeGroup = groups [ 0 ] ?? null ;
26- const activeGroupId = activeGroup ?. id ;
27- const activeCurrency = activeGroup ?. currency ?? null ;
28-
29- const [ balances , activity ] = await Promise . all ( [
30- activeGroupId
31- ? backendFetch < Balance [ ] > ( `/groups/${ activeGroupId } /balances` ) . catch ( ( ) => [ ] as Balance [ ] )
32- : Promise . resolve ( [ ] as Balance [ ] ) ,
33- activeGroupId
34- ? backendFetch < ActivityDto [ ] > ( `/groups/${ activeGroupId } /activity?cursor=0&limit=5` ) . catch ( ( ) => [ ] as ActivityDto [ ] )
35- : Promise . resolve ( [ ] as ActivityDto [ ] ) ,
24+ const [ recentActivityData , summary ] = await Promise . all ( [
25+ backendFetch < { items : ActivityDto [ ] } > ( '/activity' ) ,
26+ backendFetch < { totalBalanceCents : string } > ( '/groups/summary' ) ,
3627 ] ) ;
3728
38- let oweCents = 0n ;
39- let owedToMeCents = 0n ;
40- if ( me ) {
41- for ( const bal of balances ) {
42- if ( bal . userId !== me . id ) continue ;
43- const amt = BigInt ( bal . amountCents ) ;
44- if ( amt < 0n ) oweCents += - amt ;
45- else owedToMeCents += amt ;
46- }
47- }
29+ const recentActivity = recentActivityData . items || [ ] ;
30+ const totalBalanceCents = summary . totalBalanceCents ;
4831
4932 return (
50- < DashboardLayout >
51- < div className = "space-y-12" >
52- < section className = "space-y-4" >
53- < div className = "flex items-center justify-between" >
54- < h2 className = "text-lg font-bold text-[var(--fs-text-primary)]" > Balance summary</ h2 >
55- < span className = "text-[11px] font-semibold uppercase tracking-[0.12em] text-[var(--fs-text-muted)]" >
56- Updated on refresh
57- </ span >
58- </ div >
59- < div className = "grid gap-6 md:grid-cols-3" >
60- < SummaryCard title = "Active groups" value = { groups . length } hint = "Registered ensembles" />
61- < SummaryCard
62- title = "Liabilities"
63- value = { formatMoney ( oweCents , activeCurrency ) }
64- hint = { activeGroupId ? `${ activeGroup ?. name } · ${ activeCurrency } ` : 'No active group selected' }
65- />
66- < SummaryCard
67- title = "Assets"
68- value = { formatMoney ( owedToMeCents , activeCurrency ) }
69- hint = { activeGroupId ? `Shown in ${ activeCurrency } ` : 'Select a group to see currency-specific totals' }
70- />
71- </ div >
72- </ section >
33+ < DashboardLayout user = { me } >
34+ < div className = "space-y-6" >
35+ < div className = "grid grid-cols-1 md:grid-cols-3 gap-6" >
36+ < SummaryCard
37+ title = "Total Balance"
38+ amount = { formatMoney ( totalBalanceCents , 'USD' ) }
39+ trend = { Number ( totalBalanceCents ) >= 0 ? 'up' : 'down' }
40+ description = { Number ( totalBalanceCents ) >= 0 ? 'You are owed' : 'You owe' }
41+ />
42+ < SummaryCard
43+ title = "Active Groups"
44+ amount = { groups . length . toString ( ) }
45+ description = "Across all categories"
46+ />
47+ < QuickActions />
48+ </ div >
7349
74- < section className = "grid gap-12 lg:grid-cols-[1fr_350px]" >
75- { activeGroupId ? (
76- < ActivityList groupId = { activeGroupId } items = { activity } />
77- ) : (
78- < div className = "rounded-3xl border border-[var(--fs-border)] bg-[var(--fs-card)] p-10 text-center shadow-[var(--fs-shadow-soft)]" >
79- < p className = "text-xl font-bold text-[var(--fs-text-primary)] mb-2" > No active group detected</ p >
80- < p className = "text-sm font-medium text-[var(--fs-text-muted)]" >
81- Create or select a group to start tracking balances and activity.
82- </ p >
50+ < div className = "grid grid-cols-1 lg:grid-cols-3 gap-6" >
51+ < div className = "lg:col-span-2" >
52+ < ActivityList items = { recentActivity } groupId = "" />
53+ </ div >
54+ < div >
55+ < h2 className = "text-xl font-semibold mb-4" > Group Balances</ h2 >
56+ < div className = "bg-white rounded-xl shadow-sm p-6" >
57+ { groups . map ( ( group ) => (
58+ < div key = { group . id } className = "flex justify-between items-center py-3 border-b last:border-0" >
59+ < span className = "font-medium" > { group . name } </ span >
60+ < span className = "text-sm text-gray-500" > { group . currency } </ span >
61+ </ div >
62+ ) ) }
63+ { groups . length === 0 && (
64+ < p className = "text-sm text-gray-500 text-center py-4" > No active groups yet.</ p >
65+ ) }
8366 </ div >
84- ) }
85- < QuickActions groupId = { activeGroupId } />
86- </ section >
67+ </ div >
68+ </ div >
8769 </ div >
8870 </ DashboardLayout >
8971 ) ;
0 commit comments