Skip to content

Commit

Permalink
feat(proposal): Implement CashCard component for dashboard. Add title…
Browse files Browse the repository at this point in the history
… and tabs to dashboard page.
  • Loading branch information
oneanotheruser committed Nov 22, 2024
1 parent 2b602ef commit e735f2a
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 56 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
'use client';

import { useEffect, useState } from 'react';
import { useEffect, useState, SyntheticEvent } from 'react';

import Image from 'next/image';

import { Box, Stack } from '@mui/material';
import { Box, Stack, Tab, Tabs, Typography } from '@mui/material';

import { CashCard } from '@/components/CashCard';
import DashboardCard from '@/components/DashboardCard';
import EmptyState from '@/components/EmptyState';
import {
IconUniversity,
IconBolt,
IconReceipt,
IconPayable,
Expand Down Expand Up @@ -50,58 +50,61 @@ const DashboardMockup = () => {
};

const Dashboard = () => {
const [currentTab, setCurrentTab] = useState<number>(1);
const changeTab = (_event: SyntheticEvent, newTab: number) =>
setCurrentTab(newTab);

return (
<Stack direction="column" justifyContent="flex-start" alignItems="center">
<Image priority src={dashboardHeader} alt="" />
<Stack
direction="row"
spacing={3}
useFlexGap={true}
justifyContent="space-between"
sx={{ width: '100%' }}
<>
<Typography variant="h2">Dashboard</Typography>
<Tabs
value={currentTab}
onChange={changeTab}
sx={{ mt: 4 }}
textColor="secondary"
>
<Box sx={{ flex: 1 }}>
<CashCard />
</Box>
<Box sx={{ flex: 1 }}>
<RecomendedActionsCard />
</Box>
</Stack>
<Box sx={{ width: '100%', mt: 3 }}>
<CashFlowCard />
</Box>
<Tab label="Overview" value={1} />
<Tab label="Xue’s view" value={2} disabled />
</Tabs>
<Stack
direction="row"
spacing={3}
useFlexGap={true}
justifyContent="space-between"
sx={{ width: '100%', mt: 3 }}
direction="column"
justifyContent="flex-start"
alignItems="center"
sx={{ mt: 3 }}
>
<Box sx={{ flex: 1 }}>
<OutstandingInvoicesCard />
</Box>
<Box sx={{ flex: 1 }}>
<DuePayablesCard />
<Stack
direction="row"
spacing={3}
useFlexGap={true}
justifyContent="space-between"
sx={{ width: '100%' }}
>
<Box sx={{ flex: 1 }}>
<CashCard />
</Box>
<Box sx={{ flex: 1 }}>
<RecomendedActionsCard />
</Box>
</Stack>
<Box sx={{ width: '100%', mt: 3 }}>
<CashFlowCard />
</Box>
<Stack
direction="row"
spacing={3}
useFlexGap={true}
justifyContent="space-between"
sx={{ width: '100%', mt: 3 }}
>
<Box sx={{ flex: 1 }}>
<OutstandingInvoicesCard />
</Box>
<Box sx={{ flex: 1 }}>
<DuePayablesCard />
</Box>
</Stack>
</Stack>
</Stack>
);
};

const CashCard = () => {
const emptyState = (
<EmptyState renderIcon={(props) => <IconUniversity {...props} />}>
No bank accounts connected
</EmptyState>
);

return (
<DashboardCard
title="Cash on accounts"
renderIcon={(props) => <IconUniversity {...props} />}
>
{emptyState}
</DashboardCard>
</>
);
};

Expand Down
9 changes: 4 additions & 5 deletions examples/with-nextjs-and-clerk-auth/src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
--demo-padding-4: calc(var(--demo-padding) * 4);
--demo-padding-5: calc(var(--demo-padding) * 5);
--demo-padding-6: calc(var(--demo-padding) * 6);
--demo-button-blue: #3737FF;
--demo-button-blue: #3737ff;
--demo-light-gray: #f9f9f9;
--demo-divider: #DDDDDD;
--demo-divider: #dddddd;
--demo-form-header: 88px;
}

Expand All @@ -22,7 +22,8 @@ html {
height: inherit;

> .Monite-PageContainer {
padding: var(--demo-padding-4) var(--demo-padding-4) var(--demo-padding-4) var(--demo-padding-4);
padding: var(--demo-padding-4) var(--demo-padding-4) var(--demo-padding-4)
var(--demo-padding-4);
height: inherit;

display: flex;
Expand All @@ -33,12 +34,10 @@ html {
}
}


.Monite-Dashboard {
overflow-y: auto !important;
background-color: var(--demo-light-gray) !important;


img {
max-width: 100%;
height: auto;
Expand Down
111 changes: 111 additions & 0 deletions examples/with-nextjs-and-clerk-auth/src/components/CashCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import { useEffect, useState } from 'react';

import { useCurrencies } from '@monite/sdk-react';
import { List, ListItem, ListItemText, Stack, Typography } from '@mui/material';

import { IconUniversity } from '@/icons';

import DashboardCard from './DashboardCard';
import EmptyState from './EmptyState';

interface CashItem {
name: string;
details: string;
total: number;
}

const mockData = {
total: 12734780,
currency: 'USD',
items: [
{
name: 'American Express',
details: 'Business Card ( **** 8779)',
total: 9734780,
},
{
name: 'Mercury',
details: 'Checking account (**** 2190)',
total: 1000000,
},
{
name: 'JP Morgan Case',
details: 'Checking account (**** 5467)',
total: 2000000,
},
],
};

const mockApi = () => Promise.resolve(mockData);

export function CashCard() {
const [total, setTotal] = useState(0);
const [currency, setCurrency] = useState<string>();
const [items, setItems] = useState<CashItem[]>([]);

const { formatCurrencyToDisplay } = useCurrencies();

useEffect(() => {
const fetchData = async () => {
const data = await mockApi();

setTotal(data.total);
setCurrency(data.currency);
setItems(data.items);
};

fetchData();
}, []);

const title = (
<Stack direction="row" justifyContent="space-between" alignItems="center">
<Stack>
<Typography variant="subtitle1">Cash on accounts</Typography>
{Boolean(items.length) && (
<Typography>{items.length} account(s)</Typography>
)}
</Stack>
{Boolean(total) && (
<Typography variant="h3">
{formatCurrencyToDisplay(total, currency as string)}
</Typography>
)}
</Stack>
);

const emptyState = (
<EmptyState renderIcon={(props) => <IconUniversity {...props} />}>
No bank accounts connected
</EmptyState>
);

const itemsList = (
<List dense>
{items.map((item) => (
<ListItem key={item.name} disablePadding={true}>
<ListItemText
primary={item.name}
primaryTypographyProps={{ variant: 'body1' }}
secondary={item.details}
/>
<ListItemText
primary={formatCurrencyToDisplay(item.total, currency as string)}
primaryTypographyProps={{
variant: 'body1',
sx: { fontWeight: 700, textAlign: 'right' },
}}
/>
</ListItem>
))}
</List>
);

return (
<DashboardCard
title={title}
renderIcon={(props) => <IconUniversity {...props} />}
>
{items.length ? itemsList : emptyState}
</DashboardCard>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Card, CardHeader, CardContent, SvgIconProps } from '@mui/material';
type IconVariant = 'info' | 'success' | 'critical';

interface DashboardCardProps {
title: string;
title: ReactNode;
renderIcon: (props: SvgIconProps) => ReactNode;
iconVariant?: IconVariant;
children?: ReactNode;
Expand Down Expand Up @@ -66,7 +66,7 @@ export default function DashboardCard({
}}
avatar={<div style={wrapper}>{renderIcon({ style: iconStyles })}</div>}
/>
<CardContent>{children}</CardContent>
<CardContent sx={{ pt: 0 }}>{children}</CardContent>
</Card>
);
}

0 comments on commit e735f2a

Please sign in to comment.