diff --git a/apps/web/app/page.tsx b/apps/web/app/page.tsx
index 01beb43..5f7f6a4 100644
--- a/apps/web/app/page.tsx
+++ b/apps/web/app/page.tsx
@@ -1,15 +1,32 @@
-"use client";
-import "@tldraw/tldraw/tldraw.css";
-import { Toaster } from "@ui/components";
+import { auth } from "@clerk/nextjs";
+import { SkeletonPlaceholder, Toaster } from "@ui/components";
+import { prisma } from "database";
+import { Suspense } from "react";
import Header from "~/components/header";
+import ProjectsTable from "~/components/projects-table";
+
+export default async function IndexPage() {
+ const { userId } = auth();
+
+ const projects = await prisma.project.findMany({
+ where: {
+ userId: userId,
+ },
+ include: {
+ repository: true,
+ },
+ });
-export default function IndexPage() {
return (
-
+
);
diff --git a/apps/web/package.json b/apps/web/package.json
index 702cd30..7bc3ed8 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -14,7 +14,9 @@
"@tldraw/tldraw": "2.0.0-canary.699502d8c479",
"axios": "^1.5.1",
"clsx": "^2.0.0",
+ "database": "workspace:*",
"lucide-react": "^0.293.0",
+ "luxon": "^3.4.4",
"million": "^2.6.4",
"next": "^14.0.3",
"react": "^18.2.0",
@@ -24,6 +26,7 @@
"zod": "^3.22.4"
},
"devDependencies": {
+ "@types/luxon": "^3.3.7",
"@types/node": "^17.0.12",
"@types/react": "^18.0.22",
"@types/react-dom": "^18.0.7",
diff --git a/apps/web/src/components/header.tsx b/apps/web/src/components/header.tsx
index 205e670..b219183 100644
--- a/apps/web/src/components/header.tsx
+++ b/apps/web/src/components/header.tsx
@@ -10,7 +10,7 @@ import {
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
- DropdownMenuTrigger
+ DropdownMenuTrigger,
} from "@ui/components";
import { User } from "lucide-react";
import HomeIcon from "./home-icon";
@@ -49,7 +49,9 @@ export default function Header({ children }: Props) {
{user?.fullName ?? "My Profile"}
- {user?.primaryEmailAddress.emailAddress ?? ""}
+
+ {user?.primaryEmailAddress.emailAddress ?? ""}
+
diff --git a/apps/web/src/components/projects-table.tsx b/apps/web/src/components/projects-table.tsx
new file mode 100644
index 0000000..cca2bf1
--- /dev/null
+++ b/apps/web/src/components/projects-table.tsx
@@ -0,0 +1,48 @@
+import {
+ Table,
+ TableBody,
+ TableCell,
+ TableHead,
+ TableHeader,
+ TableRow,
+} from "@ui/components";
+import { Project, Repository } from "database";
+import { DateTime } from "luxon";
+
+type ProjectWithRepository = Project & {
+ repository: Repository;
+};
+
+interface Props {
+ projects: ProjectWithRepository[];
+}
+
+/**
+ * Table for displaying the current user's projects
+ */
+export default function ProjectsTable({ projects }: Props) {
+ return (
+
+
+
+ Name
+ GitHub
+ Branch
+ Created
+
+
+
+ {projects.map((project) => {
+ return (
+
+ {project.name}
+ {project.repository.fullName}
+ {project.branch}
+ {DateTime.fromJSDate(project.createdAt).toFormat("dd MMM yyyy")}
+
+ );
+ })}
+
+
+ );
+}
diff --git a/packages/database/package.json b/packages/database/package.json
index 41a67a6..73e1b3f 100644
--- a/packages/database/package.json
+++ b/packages/database/package.json
@@ -25,7 +25,7 @@
},
"dependencies": {
"@paralleldrive/cuid2": "^2.2.2",
- "@prisma/client": "^5.5.2",
+ "@prisma/client": "^5.6.0",
"@t3-oss/env-core": "^0.7.1",
"core": "link:@t3-oss/env/core",
"zod": "^3.22.4"
@@ -34,7 +34,7 @@
"@types/node": "^17.0.12",
"config": "workspace:*",
"eslint": "^8.12.0",
- "prisma": "^5.5.2",
+ "prisma": "^5.6.0",
"rimraf": "^3.0.2",
"tsconfig": "workspace:*",
"tsup": "^5.11.13",
diff --git a/packages/database/prisma/schema.prisma b/packages/database/prisma/schema.prisma
index 8af24ef..2d391b5 100644
--- a/packages/database/prisma/schema.prisma
+++ b/packages/database/prisma/schema.prisma
@@ -1,6 +1,5 @@
generator client {
provider = "prisma-client-js"
- binaryTargets = ["native", "debian-openssl-1.1.x", "linux-musl-openssl-3.0.x"]
}
datasource db {
@@ -46,6 +45,8 @@ model Project {
id String @id @map("_id")
userId String
+ name String
+
repositoryId String @unique
repository Repository @relation(fields: [repositoryId], references: [id])
branch String
diff --git a/packages/ui/src/components/ui/index.tsx b/packages/ui/src/components/ui/index.tsx
index 6ddf99f..5c8b276 100644
--- a/packages/ui/src/components/ui/index.tsx
+++ b/packages/ui/src/components/ui/index.tsx
@@ -6,6 +6,7 @@ export * from "./dialog";
export * from "./dropdown-menu";
export * from "./popover";
export * from "./skeleton";
+export * from "./table";
export * from "./tabs";
export * from "./toast";
export * from "./toaster";
diff --git a/packages/ui/src/components/ui/table.tsx b/packages/ui/src/components/ui/table.tsx
new file mode 100644
index 0000000..0e554b6
--- /dev/null
+++ b/packages/ui/src/components/ui/table.tsx
@@ -0,0 +1,117 @@
+import * as React from "react"
+
+import { cn } from "@ui/lib/utils"
+
+const Table = React.forwardRef<
+ HTMLTableElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+))
+Table.displayName = "Table"
+
+const TableHeader = React.forwardRef<
+ HTMLTableSectionElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+))
+TableHeader.displayName = "TableHeader"
+
+const TableBody = React.forwardRef<
+ HTMLTableSectionElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+))
+TableBody.displayName = "TableBody"
+
+const TableFooter = React.forwardRef<
+ HTMLTableSectionElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+ tr]:last:border-b-0",
+ className
+ )}
+ {...props}
+ />
+))
+TableFooter.displayName = "TableFooter"
+
+const TableRow = React.forwardRef<
+ HTMLTableRowElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+))
+TableRow.displayName = "TableRow"
+
+const TableHead = React.forwardRef<
+ HTMLTableCellElement,
+ React.ThHTMLAttributes
+>(({ className, ...props }, ref) => (
+ |
+))
+TableHead.displayName = "TableHead"
+
+const TableCell = React.forwardRef<
+ HTMLTableCellElement,
+ React.TdHTMLAttributes
+>(({ className, ...props }, ref) => (
+ |
+))
+TableCell.displayName = "TableCell"
+
+const TableCaption = React.forwardRef<
+ HTMLTableCaptionElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+))
+TableCaption.displayName = "TableCaption"
+
+export {
+ Table,
+ TableHeader,
+ TableBody,
+ TableFooter,
+ TableHead,
+ TableRow,
+ TableCell,
+ TableCaption,
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index f623643..880934b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -141,9 +141,15 @@ importers:
clsx:
specifier: ^2.0.0
version: 2.0.0
+ database:
+ specifier: workspace:*
+ version: link:../../packages/database
lucide-react:
specifier: ^0.293.0
version: 0.293.0(react@18.2.0)
+ luxon:
+ specifier: ^3.4.4
+ version: 3.4.4
million:
specifier: ^2.6.4
version: 2.6.4
@@ -166,6 +172,9 @@ importers:
specifier: ^3.22.4
version: 3.22.4
devDependencies:
+ '@types/luxon':
+ specifier: ^3.3.7
+ version: 3.3.7
'@types/node':
specifier: ^17.0.12
version: 17.0.45
@@ -181,9 +190,6 @@ importers:
config:
specifier: workspace:*
version: link:../../packages/config
- database:
- specifier: workspace:*
- version: link:../../packages/database
eslint:
specifier: ^7.32.0
version: 7.32.0
@@ -225,8 +231,8 @@ importers:
specifier: ^2.2.2
version: 2.2.2
'@prisma/client':
- specifier: ^5.5.2
- version: 5.5.2(prisma@5.5.2)
+ specifier: ^5.6.0
+ version: 5.6.0(prisma@5.6.0)
'@t3-oss/env-core':
specifier: ^0.7.1
version: 0.7.1(typescript@4.9.5)(zod@3.22.4)
@@ -247,8 +253,8 @@ importers:
specifier: ^8.12.0
version: 8.52.0
prisma:
- specifier: ^5.5.2
- version: 5.5.2
+ specifier: ^5.6.0
+ version: 5.6.0
rimraf:
specifier: ^3.0.2
version: 3.0.2
@@ -2238,8 +2244,8 @@ packages:
webcrypto-core: 1.7.7
dev: false
- /@prisma/client@5.5.2(prisma@5.5.2):
- resolution: {integrity: sha512-54XkqR8M+fxbzYqe+bIXimYnkkcGqgOh0dn0yWtIk6CQT4IUCAvNFNcQZwk2KqaLU+/1PHTSWrcHtx4XjluR5w==}
+ /@prisma/client@5.6.0(prisma@5.6.0):
+ resolution: {integrity: sha512-mUDefQFa1wWqk4+JhKPYq8BdVoFk9NFMBXUI8jAkBfQTtgx8WPx02U2HB/XbAz3GSUJpeJOKJQtNvaAIDs6sug==}
engines: {node: '>=16.13'}
requiresBuild: true
peerDependencies:
@@ -2248,16 +2254,16 @@ packages:
prisma:
optional: true
dependencies:
- '@prisma/engines-version': 5.5.1-1.aebc046ce8b88ebbcb45efe31cbe7d06fd6abc0a
- prisma: 5.5.2
+ '@prisma/engines-version': 5.6.0-32.e95e739751f42d8ca026f6b910f5a2dc5adeaeee
+ prisma: 5.6.0
dev: false
- /@prisma/engines-version@5.5.1-1.aebc046ce8b88ebbcb45efe31cbe7d06fd6abc0a:
- resolution: {integrity: sha512-O+qHFnZvAyOFk1tUco2/VdiqS0ym42a3+6CYLScllmnpbyiTplgyLt2rK/B9BTjYkSHjrgMhkG47S0oqzdIckA==}
+ /@prisma/engines-version@5.6.0-32.e95e739751f42d8ca026f6b910f5a2dc5adeaeee:
+ resolution: {integrity: sha512-UoFgbV1awGL/3wXuUK3GDaX2SolqczeeJ5b4FVec9tzeGbSWJboPSbT0psSrmgYAKiKnkOPFSLlH6+b+IyOwAw==}
dev: false
- /@prisma/engines@5.5.2:
- resolution: {integrity: sha512-Be5hoNF8k+lkB3uEMiCHbhbfF6aj1GnrTBnn5iYFT7GEr3TsOEp1soviEcBR0tYCgHbxjcIxJMhdbvxALJhAqg==}
+ /@prisma/engines@5.6.0:
+ resolution: {integrity: sha512-Mt2q+GNJpU2vFn6kif24oRSBQv1KOkYaterQsi0k2/lA+dLvhRX6Lm26gon6PYHwUM8/h8KRgXIUMU0PCLB6bw==}
requiresBuild: true
/@protobufjs/aspromise@1.1.2:
@@ -4126,6 +4132,10 @@ packages:
'@types/koa': 2.13.10
dev: true
+ /@types/luxon@3.3.7:
+ resolution: {integrity: sha512-gKc9P2d4g5uYwmy4s/MO/yOVPmvHyvzka1YH6i5dM03UrFofHSmgc0D0ymbDRStFWHusk6cwwF6nhLm/ckBbbQ==}
+ dev: true
+
/@types/mime@1.3.4:
resolution: {integrity: sha512-1Gjee59G25MrQGk8bsNvC6fxNiRgUlGn2wlhGf95a59DrprnnHk80FIMMFG9XHMdrfsuA119ht06QPDXA1Z7tw==}
@@ -7700,6 +7710,11 @@ packages:
react: 18.2.0
dev: false
+ /luxon@3.4.4:
+ resolution: {integrity: sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==}
+ engines: {node: '>=12'}
+ dev: false
+
/lz-string@1.5.0:
resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==}
hasBin: true
@@ -8439,13 +8454,13 @@ packages:
hasBin: true
dev: true
- /prisma@5.5.2:
- resolution: {integrity: sha512-WQtG6fevOL053yoPl6dbHV+IWgKo25IRN4/pwAGqcWmg7CrtoCzvbDbN9fXUc7QS2KK0LimHIqLsaCOX/vHl8w==}
+ /prisma@5.6.0:
+ resolution: {integrity: sha512-EEaccku4ZGshdr2cthYHhf7iyvCcXqwJDvnoQRAJg5ge2Tzpv0e2BaMCp+CbbDUwoVTzwgOap9Zp+d4jFa2O9A==}
engines: {node: '>=16.13'}
hasBin: true
requiresBuild: true
dependencies:
- '@prisma/engines': 5.5.2
+ '@prisma/engines': 5.6.0
/prismjs@1.27.0:
resolution: {integrity: sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==}