-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add admin auth * initial routes to fetch data * frontend wip * slight changes to frontend + add route * fetching data implemented * front end styling * fixed one eslint error * loading page * route to not found page * cleanup pagination component * merge * trying to fix types * fix types * fix tsc * make fonts bigger --------- Co-authored-by: owen <owensimpson1127@gmail.com>
- Loading branch information
1 parent
b715df0
commit 3b35c1b
Showing
19 changed files
with
562 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import AdminDashboard from "@good-dog/components/admin/AdminDashboard"; | ||
import { HydrateClient, trpc } from "@good-dog/trpc/server"; | ||
|
||
export const dynamic = "force-dynamic"; | ||
|
||
export default async function AdminPage() { | ||
void trpc.adminData.prefetch(); | ||
|
||
return ( | ||
<HydrateClient> | ||
<AdminDashboard /> | ||
</HydrateClient> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
"use client"; | ||
|
||
import { useState } from "react"; | ||
|
||
import { trpc } from "@good-dog/trpc/client"; | ||
import { | ||
Card, | ||
CardContent, | ||
CardDescription, | ||
CardHeader, | ||
CardTitle, | ||
} from "@good-dog/ui/card"; | ||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@good-dog/ui/tabs"; | ||
|
||
import { DataTable } from "./DataTable"; | ||
|
||
export default function AdminDashboard() { | ||
const [activeTab, setActiveTab] = useState("users"); | ||
const [data] = trpc.adminData.useSuspenseQuery(); | ||
|
||
const userData = data.users; | ||
const groupData = data.groups; | ||
const groupInvitesData = data.groupInvites; | ||
|
||
return ( | ||
<div className="bg-good-dog-violet pb-10"> | ||
<div className="mx-10"> | ||
<h1 className="mb-6 text-7xl font-bold text-white">Admin Dashboard</h1> | ||
<Tabs value={activeTab} onValueChange={setActiveTab} className="w-full"> | ||
<TabsList> | ||
<TabsTrigger className="text-xl" value="users"> | ||
Users | ||
</TabsTrigger> | ||
<TabsTrigger className="text-xl" value="groups"> | ||
Groups | ||
</TabsTrigger> | ||
<TabsTrigger className="text-xl" value="invites"> | ||
Invites | ||
</TabsTrigger> | ||
</TabsList> | ||
<div className="pt-2"> | ||
<TabsContent className="text-3xl" value="users"> | ||
<Card> | ||
<CardHeader> | ||
<CardTitle>Users</CardTitle> | ||
<CardDescription className="text-xl"> | ||
Manage user accounts in the system. | ||
</CardDescription> | ||
</CardHeader> | ||
<CardContent> | ||
<DataTable table="users" data={userData} /> | ||
</CardContent> | ||
</Card> | ||
</TabsContent> | ||
<TabsContent className="text-3xl" value="groups"> | ||
<Card> | ||
<CardHeader> | ||
<CardTitle>Groups</CardTitle> | ||
<CardDescription className="text-xl"> | ||
Manage user groups and permissions. | ||
</CardDescription> | ||
</CardHeader> | ||
<CardContent> | ||
<DataTable table="groups" data={groupData} /> | ||
</CardContent> | ||
</Card> | ||
</TabsContent> | ||
<TabsContent className="text-3xl" value="invites"> | ||
<Card> | ||
<CardHeader> | ||
<CardTitle>Invites</CardTitle> | ||
<CardDescription className="text-xl"> | ||
Manage pending invitations. | ||
</CardDescription> | ||
</CardHeader> | ||
<CardContent> | ||
<DataTable table="groupInvites" data={groupInvitesData} /> | ||
</CardContent> | ||
</Card> | ||
</TabsContent> | ||
</div> | ||
</Tabs> | ||
</div> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
"use client"; | ||
|
||
import React from "react"; | ||
|
||
import type { GetProcedureOutput } from "@good-dog/trpc/utils"; | ||
import { | ||
Table, | ||
TableBody, | ||
TableCell, | ||
TableHead, | ||
TableHeader, | ||
TableRow, | ||
} from "@good-dog/ui/table"; | ||
|
||
export type AdminDataTypes = { | ||
[T in keyof GetProcedureOutput<"adminData">]: GetProcedureOutput<"adminData">[T][number]; | ||
}; | ||
|
||
interface DataColumn<T extends keyof AdminDataTypes> { | ||
accessorKey: keyof AdminDataTypes[T] & string; | ||
header: string; | ||
cell?: ( | ||
value: AdminDataTypes[T][keyof AdminDataTypes[T] & string], | ||
) => React.ReactNode; | ||
} | ||
|
||
const columns: { [T in keyof AdminDataTypes]: DataColumn<T>[] } = { | ||
users: [ | ||
{ accessorKey: "firstName", header: "First Name" }, | ||
{ accessorKey: "lastName", header: "Last Name" }, | ||
{ accessorKey: "email", header: "Email" }, | ||
{ accessorKey: "role", header: "Role" }, | ||
{ accessorKey: "stageName", header: "Stage Name" }, | ||
{ accessorKey: "isSongWriter", header: "Songwriter?" }, | ||
{ accessorKey: "isAscapAffiliated", header: "ASCAP Affiliated?" }, | ||
{ accessorKey: "isBmiAffiliated", header: "BMI Affiliated?" }, | ||
{ accessorKey: "createdAt", header: "Date of Creation" }, | ||
{ accessorKey: "updatedAt", header: "Date Last Updated" }, | ||
], | ||
groups: [ | ||
{ accessorKey: "name", header: "Name" }, | ||
{ accessorKey: "createdAt", header: "Date of Creation" }, | ||
{ accessorKey: "updatedAt", header: "Date Last Updated" }, | ||
], | ||
groupInvites: [ | ||
{ accessorKey: "email", header: "Email" }, | ||
{ accessorKey: "firstName", header: "First Name" }, | ||
{ accessorKey: "lastName", header: "Last Name" }, | ||
{ accessorKey: "stageName", header: "Stage Name" }, | ||
{ accessorKey: "role", header: "Role" }, | ||
{ accessorKey: "isSongWriter", header: "Songwriter?" }, | ||
{ accessorKey: "isAscapAffiliated", header: "ASCAP Affiliated?" }, | ||
{ accessorKey: "isBmiAffiliated", header: "BMI Affiliated?" }, | ||
{ accessorKey: "createdAt", header: "Date of Creation" }, | ||
], | ||
}; | ||
|
||
interface DataTableProps<T extends keyof AdminDataTypes> { | ||
table: T; | ||
data: AdminDataTypes[T][]; | ||
} | ||
|
||
export function DataTable<T extends keyof AdminDataTypes>({ | ||
table, | ||
data, | ||
}: DataTableProps<T>) { | ||
return ( | ||
<Table> | ||
<TableHeader className="text-nowrap text-lg"> | ||
<TableRow> | ||
{columns[table].map((column) => ( | ||
<TableHead key={column.accessorKey}>{column.header}</TableHead> | ||
))} | ||
</TableRow> | ||
</TableHeader> | ||
<TableBody className="text-base"> | ||
{data.map((entry, idx) => ( | ||
<TableRow key={idx}> | ||
{columns[table].map((column) => ( | ||
<TableCell key={column.accessorKey}> | ||
{column.cell?.(entry[column.accessorKey]) ?? | ||
String(entry[column.accessorKey])} | ||
</TableCell> | ||
))} | ||
</TableRow> | ||
))} | ||
</TableBody> | ||
</Table> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { Spinner } from "./Spinner"; | ||
|
||
export default function LoadingPage() { | ||
return ( | ||
<div className="flex min-h-screen flex-col items-center justify-start bg-good-dog-violet pt-44 text-good-dog-pale-yellow"> | ||
<div className="space-y-6 text-center"> | ||
<h1 className="animate-fade-in text-7xl font-bold tracking-wider"> | ||
LOADING | ||
</h1> | ||
<div className="flex justify-center"> | ||
<Spinner className="text-good-dog-celadon" /> | ||
</div> | ||
<p className="animate-pulse text-lg text-good-dog-orange/70"> | ||
Please wait while we fetch your content. | ||
</p> | ||
</div> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
export function Spinner({ className = "" }: { className?: string }) { | ||
return ( | ||
<div | ||
className={`inline-block h-8 w-8 animate-spin rounded-full border-4 border-solid border-current border-r-transparent align-[-0.125em] ${className}`} | ||
role="status" | ||
> | ||
<span className="sr-only">Loading...</span> | ||
</div> | ||
); | ||
} |
16 changes: 16 additions & 0 deletions
16
packages/db/prisma/migrations/20241124210934_renamed_initiator_id/migration.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
/* | ||
Warnings: | ||
- You are about to drop the column `intitiatorId` on the `GroupInvite` table. All the data in the column will be lost. | ||
- Added the required column `initiatorId` to the `GroupInvite` table without a default value. This is not possible if the table is not empty. | ||
*/ | ||
-- DropForeignKey | ||
ALTER TABLE "GroupInvite" DROP CONSTRAINT "GroupInvite_intitiatorId_fkey"; | ||
|
||
-- AlterTable | ||
ALTER TABLE "GroupInvite" DROP COLUMN "intitiatorId", | ||
ADD COLUMN "initiatorId" TEXT NOT NULL; | ||
|
||
-- AddForeignKey | ||
ALTER TABLE "GroupInvite" ADD CONSTRAINT "GroupInvite_initiatorId_fkey" FOREIGN KEY ("initiatorId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { adminAuthenticatedProcedureBuilder } from "../internal/init"; | ||
|
||
export const getAdminViewProcedure = adminAuthenticatedProcedureBuilder.query( | ||
async ({ ctx }) => { | ||
const [users, groups, groupInvites] = await Promise.all([ | ||
ctx.prisma.user.findMany({ omit: { hashedPassword: true } }), | ||
ctx.prisma.group.findMany(), | ||
ctx.prisma.groupInvite.findMany(), | ||
]); | ||
return { users, groups, groupInvites }; | ||
}, | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import type { VariantProps } from "class-variance-authority"; | ||
import React from "react"; | ||
import { cva } from "class-variance-authority"; | ||
|
||
import { cn } from "@good-dog/ui"; | ||
|
||
const badgeVariants = cva( | ||
"inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", | ||
{ | ||
variants: { | ||
variant: { | ||
default: | ||
"border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80", | ||
secondary: | ||
"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", | ||
destructive: | ||
"border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80", | ||
outline: "text-foreground", | ||
}, | ||
}, | ||
defaultVariants: { | ||
variant: "default", | ||
}, | ||
}, | ||
); | ||
|
||
export interface BadgeProps | ||
extends React.HTMLAttributes<HTMLDivElement>, | ||
VariantProps<typeof badgeVariants> {} | ||
|
||
function Badge({ className, variant, ...props }: BadgeProps) { | ||
return ( | ||
<div className={cn(badgeVariants({ variant }), className)} {...props} /> | ||
); | ||
} | ||
|
||
export { Badge, badgeVariants }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.