diff --git a/apps/web/src/app/(dashboard)/dashboard/dashboard-chart.tsx b/apps/web/src/app/(dashboard)/dashboard/dashboard-chart.tsx index 28ec89b..f2a5892 100644 --- a/apps/web/src/app/(dashboard)/dashboard/dashboard-chart.tsx +++ b/apps/web/src/app/(dashboard)/dashboard/dashboard-chart.tsx @@ -1,85 +1,223 @@ -import { AreaChart, Area, XAxis, YAxis, Tooltip } from "recharts"; - -const data = [ - { - name: "Page A", - uv: 4000, - pv: 2400, - amt: 2400, - }, - { - name: "Page B", - uv: 3000, - pv: 1398, - amt: 2210, - }, - { - name: "Page C", - uv: 2000, - pv: 9800, - amt: 2290, - }, - { - name: "Page D", - uv: 2780, - pv: 3908, - amt: 2000, - }, - { - name: "Page E", - uv: 1890, - pv: 4800, - amt: 2181, - }, - { - name: "Page F", - uv: 2390, - pv: 3800, - amt: 2500, - }, - { - name: "Page G", - uv: 3490, - pv: 4300, - amt: 2100, - }, -]; +import React from "react"; +import { + BarChart, + Bar, + XAxis, + YAxis, + Tooltip, + ResponsiveContainer, +} from "recharts"; +import { EmailStatusIcon } from "../emails/email-status-badge"; +import { EmailStatus } from "@prisma/client"; +import { api } from "~/trpc/react"; +import Spinner from "@unsend/ui/src/spinner"; +import { Tabs, TabsList, TabsTrigger } from "@unsend/ui/src/tabs"; +import { useUrlState } from "~/hooks/useUrlState"; export default function DashboardChart() { + const [days, setDays] = useUrlState("days", "7"); + const statusQuery = api.email.dashboard.useQuery({ days: Number(days) }); + return ( - - - - - - - - - - - - - - - - - +
+
+

Dashboard

+ setDays(value)} + className="" + > + + 7 Days + 30 Days + + +
+ +
+
+ {!statusQuery.isLoading && statusQuery.data ? ( + <> + + + + + + + + ) : ( + <> +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ + )} +
+ {!statusQuery.isLoading && statusQuery.data ? ( +
+ + + {/* */} + + + { + const data = payload?.[0]?.payload as Record< + EmailStatus, + number + > & { name: string }; + + if ( + !data || + (!data.BOUNCED && + !data.COMPLAINED && + !data.DELIVERED && + !data.OPENED && + !data.CLICKED) + ) + return null; + + return ( +
+

+ {data.name} +

+ {data.DELIVERED ? ( +
+

Delivered

+

{data.DELIVERED} emails

+
+ ) : null} + {data.BOUNCED ? ( +
+

Bounced

+

{data.BOUNCED} emails

+
+ ) : null} + {data.COMPLAINED ? ( +
+

Complained

+

{data.COMPLAINED} emails

+
+ ) : null} + {data.OPENED ? ( +
+

Opened

+

{data.OPENED} emails

+
+ ) : null} + {data.CLICKED ? ( +
+

Clicked

+

{data.CLICKED} emails

+
+ ) : null} +
+ ); + }} + cursor={false} + /> + {/* */} + + + + + +
+
+
+ ) : null} +
+
); } + +type DashboardItemCardProps = { + status: EmailStatus | "total"; + count: number; + percentage: number; +}; + +const DashboardItemCard: React.FC = ({ + status, + count, + percentage, +}) => { + return ( +
+
+ {status !== "total" ? : null} +
{status.toLowerCase()}
+
+
+
+ {count} +
+ {status !== "total" ? ( +
{percentage}%
+ ) : null} +
+
+ ); +}; diff --git a/apps/web/src/app/(dashboard)/dashboard/page.tsx b/apps/web/src/app/(dashboard)/dashboard/page.tsx index 30c4290..01e78b8 100644 --- a/apps/web/src/app/(dashboard)/dashboard/page.tsx +++ b/apps/web/src/app/(dashboard)/dashboard/page.tsx @@ -5,8 +5,7 @@ import DashboardChart from "./dashboard-chart"; export default function Dashboard() { return (
- Dashboard -
+
diff --git a/apps/web/src/app/(dashboard)/layout.tsx b/apps/web/src/app/(dashboard)/layout.tsx index f98916f..618cb24 100644 --- a/apps/web/src/app/(dashboard)/layout.tsx +++ b/apps/web/src/app/(dashboard)/layout.tsx @@ -69,10 +69,13 @@ export default async function AuthenticatedDashboardLayout({
-
+
Unsend + + Early access +