Skip to content

Commit

Permalink
Adjust admin
Browse files Browse the repository at this point in the history
  • Loading branch information
koredefashokun committed Jan 6, 2025
1 parent 5142559 commit 838377f
Show file tree
Hide file tree
Showing 33 changed files with 1,968 additions and 253 deletions.
22 changes: 17 additions & 5 deletions apps/admin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,33 @@
"lint": "next lint"
},
"dependencies": {
"@mantine/core": "^7.15.2",
"@mantine/dates": "^7.15.2",
"@mantine/form": "^7.15.2",
"@mantine/hooks": "^7.15.2",
"@emotion/react": "^11.14.0",
"@radix-ui/react-checkbox": "^1.1.3",
"@radix-ui/react-dialog": "^1.1.1",
"@radix-ui/react-dropdown-menu": "^2.1.4",
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-popover": "^1.1.4",
"@radix-ui/react-select": "^2.1.4",
"@radix-ui/react-separator": "^1.1.1",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-tabs": "^1.1.2",
"@radix-ui/react-toast": "^1.2.4",
"@tabler/icons-react": "^3.26.0",
"@tanstack/react-query": "^5.62.11",
"@tanstack/react-query-devtools": "^5.62.15",
"axios": "^1.7.9",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"dayjs": "^1.11.13",
"lucide-react": "^0.469.0",
"next": "15.1.3",
"react": "^19.0.0",
"react-dom": "^19.0.0"
"react-dom": "^19.0.0",
"tailwind-merge": "^2.5.2"
},
"devDependencies": {
"@eslint/eslintrc": "^3",
"@shadcn/ui": "^0.0.4",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
Expand Down
49 changes: 49 additions & 0 deletions apps/admin/src/app/dashboard/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Store, ShoppingCart, Users } from 'lucide-react';
import Link from 'next/link';

export default function DashboardLayout({
children
}: {
children: React.ReactNode;
}) {
return (
<div className='min-h-screen flex'>
{/* Sidebar */}
<aside className='w-64 bg-gray-900 text-white'>
<div className='p-4'>
<h1 className='text-2xl font-bold'>Admin Panel</h1>
</div>
<nav className='mt-8'>
<div className='px-4 space-y-2'>
<Link
href='/dashboard/stores'
className='flex items-center space-x-2 p-2 rounded-lg hover:bg-gray-800'
>
<Store className='h-5 w-5' />
<span>Stores</span>
</Link>
<Link
href='/dashboard/orders'
className='flex items-center space-x-2 p-2 rounded-lg hover:bg-gray-800'
>
<ShoppingCart className='h-5 w-5' />
<span>Orders</span>
</Link>
<Link
href='/dashboard/users'
className='flex items-center space-x-2 p-2 rounded-lg hover:bg-gray-800'
>
<Users className='h-5 w-5' />
<span>Users</span>
</Link>
</div>
</nav>
</aside>

{/* Main Content */}
<main className='flex-1 p-8 bg-gray-100 dark:bg-gray-800'>
{children}
</main>
</div>
);
}
89 changes: 89 additions & 0 deletions apps/admin/src/app/dashboard/orders/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
'use client';

import { Eye } from 'lucide-react';

import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow
} from '@/components/ui/table';
import { useOrdersQuery } from '@/data/queries/orders';

const statusVariants = {
Pending: 'secondary',
Processing: 'default',
Completed: 'success',
Cancelled: 'destructive',
Delivered: 'success'
} as const;

export default function OrdersPage() {
const { data: orders, isLoading } = useOrdersQuery();
return (
<div className='space-y-6'>
<div className='flex justify-between items-center'>
<h1 className='text-3xl font-bold'>Orders</h1>
</div>

<div className='bg-white dark:bg-gray-900 shadow rounded-lg'>
<Table>
<TableHeader>
<TableRow>
<TableHead>Order ID</TableHead>
<TableHead>Customer</TableHead>
<TableHead>Store</TableHead>
<TableHead>Status</TableHead>
<TableHead>Total</TableHead>
<TableHead>Date</TableHead>
<TableHead>Actions</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{isLoading ? (
<TableRow>
<TableCell colSpan={7} className='text-center'>
Loading...
</TableCell>
</TableRow>
) : (
orders?.map(order => (
<TableRow key={order.id}>
<TableCell>{order.id}</TableCell>
<TableCell>{order.user.name}</TableCell>
<TableCell>{order.store.name}</TableCell>
<TableCell>
<Badge
variant={
statusVariants[
order.status as keyof typeof statusVariants
]
}
>
{order.status}
</Badge>
</TableCell>
<TableCell>${order.total.toFixed(2)}</TableCell>
<TableCell>
{new Date(order.createdAt).toLocaleDateString()}
</TableCell>
<TableCell>
<div className='flex gap-2'>
<Button variant='ghost' size='sm' className='h-8 w-8 p-0'>
<Eye className='h-4 w-4' />
</Button>
</div>
</TableCell>
</TableRow>
))
)}
</TableBody>
</Table>
</div>
</div>
);
}
66 changes: 66 additions & 0 deletions apps/admin/src/app/dashboard/stores/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
'use client';

import { Edit, Trash } from 'lucide-react';

import { Button } from '@/components/ui/button';
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow
} from '@/components/ui/table';
import { useStoresQuery } from '@/data/queries/stores';

export default function StoresPage() {
const { data: stores, isLoading } = useStoresQuery();

return (
<div className='space-y-6'>
<div className='flex justify-between items-center'>
<h1 className='text-3xl font-bold'>Stores</h1>
</div>

<div className='bg-white dark:bg-gray-900 shadow rounded-lg'>
<Table>
<TableHeader>
<TableRow>
<TableHead>Store Name</TableHead>
<TableHead>Actions</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{isLoading ? (
<TableRow>
<TableCell colSpan={5} className='text-center'>
Loading...
</TableCell>
</TableRow>
) : (
stores?.map(store => (
<TableRow key={store.id}>
<TableCell>{store.name}</TableCell>
<TableCell>
<div className='flex gap-2'>
<Button variant='ghost' size='sm' className='h-8 w-8 p-0'>
<Edit className='h-4 w-4' />
</Button>
<Button
variant='ghost'
size='sm'
className='h-8 w-8 p-0 text-destructive hover:text-destructive'
>
<Trash className='h-4 w-4' />
</Button>
</div>
</TableCell>
</TableRow>
))
)}
</TableBody>
</Table>
</div>
</div>
);
}
72 changes: 72 additions & 0 deletions apps/admin/src/app/dashboard/users/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
'use client';

import { Edit, Trash } from 'lucide-react';

import { Button } from '@/components/ui/button';
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow
} from '@/components/ui/table';
import { useUsersQuery } from '@/data/queries/users';

export default function UsersPage() {
const { data: users, isLoading } = useUsersQuery();

return (
<div className='space-y-6'>
<div className='flex justify-between items-center'>
<h1 className='text-3xl font-bold'>Users</h1>
</div>

<div className='bg-white dark:bg-gray-900 shadow rounded-lg'>
<Table>
<TableHeader>
<TableRow>
<TableHead>Name</TableHead>
<TableHead>Email</TableHead>
<TableHead>Joined</TableHead>
<TableHead>Actions</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{isLoading ? (
<TableRow>
<TableCell colSpan={6} className='text-center'>
Loading...
</TableCell>
</TableRow>
) : (
users?.map(user => (
<TableRow key={user.id}>
<TableCell>{user.name}</TableCell>
<TableCell>{user.email}</TableCell>
<TableCell>
{new Date(user.createdAt).toLocaleDateString()}
</TableCell>
<TableCell>
<div className='flex gap-2'>
<Button variant='ghost' size='sm' className='h-8 w-8 p-0'>
<Edit className='h-4 w-4' />
</Button>
<Button
variant='ghost'
size='sm'
className='h-8 w-8 p-0 text-destructive hover:text-destructive'
>
<Trash className='h-4 w-4' />
</Button>
</div>
</TableCell>
</TableRow>
))
)}
</TableBody>
</Table>
</div>
</div>
);
}
28 changes: 10 additions & 18 deletions apps/admin/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,25 @@
import type { Metadata } from 'next';
import { Geist, Geist_Mono } from 'next/font/google';
import './globals.css';
import { Inter } from 'next/font/google';

const geistSans = Geist({
variable: '--font-geist-sans',
subsets: ['latin']
});
import './globals.css';
import { Providers } from './providers';

const geistMono = Geist_Mono({
variable: '--font-geist-mono',
subsets: ['latin']
});
const inter = Inter({ subsets: ['latin'] });

export const metadata: Metadata = {
title: 'Create Next App',
description: 'Generated by create next app'
title: 'Admin Dashboard',
description: 'Admin dashboard for managing the marketplace'
};

export default function RootLayout({
children
}: Readonly<{
}: {
children: React.ReactNode;
}>) {
}) {
return (
<html lang='en'>
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
{children}
<body className={inter.className}>
<Providers>{children}</Providers>
</body>
</html>
);
Expand Down
Loading

0 comments on commit 838377f

Please sign in to comment.