Skip to content

Commit

Permalink
Update Users and transaction pages
Browse files Browse the repository at this point in the history
  • Loading branch information
czystyl committed Sep 22, 2023
1 parent 57f7438 commit 9d19aa6
Show file tree
Hide file tree
Showing 17 changed files with 10,592 additions and 824 deletions.
3 changes: 3 additions & 0 deletions apps/web/next.config.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
/** @type {import("next").NextConfig} */
const config = {
reactStrictMode: true,
images: {
domains: ["img.clerk.com"],
},
compiler: {
styledComponents: true,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Link from "next/link";
import dayjs from "dayjs";

import { serverAPIClient } from "~/utils/serverAPIClient";
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
import {
Table,
Expand All @@ -11,6 +11,7 @@ import {
TableHeader,
TableRow,
} from "~/components/ui/table";
import { serverAPIClient } from "~/utils/serverAPIClient";

export default async function TransactionsTab() {
const transactions = await serverAPIClient().admin.recentTransactions({
Expand Down Expand Up @@ -39,24 +40,30 @@ export default async function TransactionsTab() {
</TableHeader>
<TableBody>
{transactions.map(({ transaction, sender, recipient }) => (
<TableRow key={transaction.uuid}>
<TableCell className="font-medium">
{transaction.uuid}
</TableCell>
<TableCell>{transaction.title}</TableCell>
<TableCell>
{sender?.firstName} {sender?.lastName}
</TableCell>
<TableCell>
{recipient?.firstName} {recipient?.lastName}
</TableCell>
<TableCell>
{dayjs(transaction.createdAt).format("DD-MM-YYYY")}
</TableCell>
<TableCell className="text-right">
{transaction.value}$
</TableCell>
</TableRow>
<Link
key={transaction.id}
href={`/dashboard/transactions/${transaction.id}`}
legacyBehavior
>
<TableRow key={transaction.uuid}>
<TableCell className="font-medium">
{transaction.uuid}
</TableCell>
<TableCell>{transaction.title}</TableCell>
<TableCell>
{sender?.firstName} {sender?.lastName}
</TableCell>
<TableCell>
{recipient?.firstName} {recipient?.lastName}
</TableCell>
<TableCell>
{dayjs(transaction.createdAt).format("DD-MM-YYYY")}
</TableCell>
<TableCell className="text-right">
{transaction.value}$
</TableCell>
</TableRow>
</Link>
))}
</TableBody>
</Table>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Link from "next/link";
import dayjs from "dayjs";

import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
Expand Down Expand Up @@ -35,15 +36,21 @@ export default async function UserTab() {
</TableHeader>
<TableBody>
{users.map((user) => (
<TableRow key={user.clerkId}>
<TableCell className="font-medium">{user.id}</TableCell>
<TableCell>{user.clerkId}</TableCell>
<TableCell>{user.firstName}</TableCell>
<TableCell>{user.lastName}</TableCell>
<TableCell className="text-right">
{dayjs(user.createdAt).format("YYYY-MM-DD")}
</TableCell>
</TableRow>
<Link
key={user.clerkId}
href={`/dashboard/users/${user.clerkId}`}
legacyBehavior
>
<TableRow>
<TableCell className="font-medium">{user.id}</TableCell>
<TableCell>{user.clerkId}</TableCell>
<TableCell>{user.firstName}</TableCell>
<TableCell>{user.lastName}</TableCell>
<TableCell className="text-right">
{dayjs(user.createdAt).format("YYYY-MM-DD")}
</TableCell>
</TableRow>
</Link>
))}
</TableBody>
</Table>
Expand Down
16 changes: 16 additions & 0 deletions apps/web/src/app/dashboard/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { Metadata } from "next";

import Header from "~/components/Header";

export default function DashboardLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<div className="flex flex-col">
<Header />
{children}
</div>
);
}
60 changes: 23 additions & 37 deletions apps/web/src/app/dashboard/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import type { Metadata } from "next";
import { UserButton } from "@clerk/nextjs";

import { ModeToggle } from "~/components/ModeToggle";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "~/components/ui/tabs";
import TransactionsTab from "../transactions/TransactionsTab";
import UserTab from "../users/UserTab";
import TransactionsTab from "../TransactionsTab";
import UserTab from "../UserTab";
import OverviewTab from "./OverviewTab";

export const metadata: Metadata = {
Expand All @@ -14,41 +12,29 @@ export const metadata: Metadata = {

export default function DashboardPage() {
return (
<div className="flex flex-col">
<div className="border-b">
<div className="flex h-16 items-center px-4">
<h1 className="bg-gradient-to-r from-green-400 to-blue-600 bg-clip-text text-3xl font-extrabold text-transparent">
The Bank
</h1>
<div className="flex-1 space-y-4 p-8 pt-6">
<Tabs defaultValue="overview" className="space-y-4">
<TabsList>
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="users">Users</TabsTrigger>
<TabsTrigger value="transactions">Transactions</TabsTrigger>
<TabsTrigger value="reports" disabled about="elo">
Reports
</TabsTrigger>
</TabsList>

<div className="ml-auto flex items-center space-x-4">
<UserButton />
<ModeToggle />
</div>
</div>
</div>
<TabsContent value="transactions" className="space-y-4">
<TransactionsTab />
</TabsContent>

<div className="flex-1 space-y-4 p-8 pt-6">
<Tabs defaultValue="overview" className="space-y-4">
<TabsList>
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="users">Users</TabsTrigger>
<TabsTrigger value="transactions">Transactions</TabsTrigger>
<TabsTrigger value="reports" disabled about="elo">
Reports
</TabsTrigger>
</TabsList>
<TabsContent value="transactions" className="space-y-4">
<TransactionsTab />
</TabsContent>
<TabsContent value="users" className="space-y-4">
<UserTab />
</TabsContent>
<TabsContent value="overview" className="space-y-4">
<OverviewTab />
</TabsContent>
</Tabs>
</div>
<TabsContent value="users" className="space-y-4">
<UserTab />
</TabsContent>

<TabsContent value="overview" className="space-y-4">
<OverviewTab />
</TabsContent>
</Tabs>
</div>
);
}
53 changes: 53 additions & 0 deletions apps/web/src/app/dashboard/transactions/[id]/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import Link from "next/link";
import { ArrowLeft, ArrowRight } from "lucide-react";

import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "~/components/ui/card";
import { Skeleton } from "~/components/ui/skeleton";

export default async function TransactionsPage() {
return (
<div className="mx-auto w-1/4">
<Link href="/dashboard">
<div className="flex items-center">
<ArrowLeft className="my-4 h-10 w-10" />
Back
</div>
</Link>

<Card className="text-center">
<CardHeader>
<CardTitle>
<Skeleton className="mx-auto mt-3 h-[14px] w-full rounded-full" />
</CardTitle>
<CardDescription>
<Skeleton className="mx-auto h-[10px] w-1/2 rounded-full" />
</CardDescription>
</CardHeader>
<CardContent>
<div className="my-4 flex items-center justify-between">
<Skeleton className=" mx-auto h-[150px] w-[150px] rounded-full" />
<ArrowRight />
<Skeleton className=" mx-auto h-[150px] w-[150px] rounded-full" />
</div>

<div className="grid gap-2">
<Skeleton className="mx-auto h-[20px] w-1/4 rounded-full" />
<Skeleton className="mx-auto h-[20px] w-1/2 rounded-full" />
<Skeleton className="mx-auto h-[20px] w-1/4 rounded-full" />
<Skeleton className="mx-auto h-[20px] w-1/3 rounded-full" />{" "}
</div>
</CardContent>
<CardFooter>
<Skeleton className="h-[20px] w-1/2 rounded-full" />
</CardFooter>
</Card>
</div>
);
}
100 changes: 100 additions & 0 deletions apps/web/src/app/dashboard/transactions/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import type { Metadata } from "next";
import Link from "next/link";
import { formatTransactionValue, formatValue } from "@the-bank/core";
import dayjs from "dayjs";
import { ArrowLeft, ArrowRight } from "lucide-react";

import { Avatar, AvatarFallback, AvatarImage } from "~/components/ui/avatar";
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "~/components/ui/card";
import { serverAPIClient } from "~/utils/serverAPIClient";

export const metadata: Metadata = {
title: "Transactions",
description: "Example transactions app built using the components.",
};

type TransactionsPageProps = {
params: {
id: string;
};
};

export default async function TransactionsPage({
params,
}: TransactionsPageProps) {
const transaction = await serverAPIClient().admin.getTransaction({
id: Number(params.id),
});

if (!transaction) {
return (
<div className="mx-auto mt-10 w-1/4">
<p>Transaction not found</p>
</div>
);
}

return (
<div className="mx-auto w-1/4">
<Link href="/dashboard">
<div className="flex items-center">
<ArrowLeft className="my-4 h-10 w-10" />
Back
</div>
</Link>

<Card className="text-center">
<CardHeader>
<CardTitle>{transaction.transaction.title}</CardTitle>
<CardDescription>{transaction.transaction.uuid}</CardDescription>
</CardHeader>
<CardContent>
<div className="my-4 flex items-center justify-between">
<div>
<Avatar className="mx-auto h-[150px] w-[150px]">
<AvatarImage src={transaction.sender?.imageUrl} alt="Avatar" />
<AvatarFallback>
{transaction.sender?.firstName?.at(0)}
</AvatarFallback>
</Avatar>
</div>
<ArrowRight />
<div>
<Avatar className="mx-auto h-[150px] w-[150px]">
<AvatarImage src={transaction.sender?.imageUrl} alt="Avatar" />
<AvatarFallback>
{transaction.sender?.firstName?.at(0)}
</AvatarFallback>
</Avatar>
</div>
</div>
<p>TYPE: {transaction.transaction.type}</p>
<p>
BALANCE: {formatValue({ value: transaction.transaction.balance })}
</p>
<p>
Value:{" "}
{formatTransactionValue(
transaction.transaction.value,
transaction.transaction.type,
)}
</p>
<p>TITLE: {transaction.transaction.title}</p>
</CardContent>
<CardFooter>
<p>
Created at{" "}
{dayjs(transaction.transaction?.createdAt).format("DD-MM-YYYY")}
</p>
</CardFooter>
</Card>
</div>
);
}
Loading

0 comments on commit 9d19aa6

Please sign in to comment.