Skip to content

Commit

Permalink
Add manager data to admin frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
koredefashokun committed Feb 9, 2025
1 parent 30abb79 commit 1cddd76
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 6 deletions.
27 changes: 26 additions & 1 deletion api/src/controllers/stores.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,31 @@ export default class StoreController {
return res.json({ payouts });
}

// GET /stores/current/managers
public async getCurrentStoreManagers(req: Request, res: Response) {
const store = await this.loadCurrentStore(req);
const managers = await prismaClient.storeManager.findMany({
where: { storeId: store.id }
});
return res.json({ managers });
}

// GET /stores/:id/payouts
public async getStorePayouts(req: Request, res: Response) {
if (!req.params.id) {
return res.status(400).json({ error: 'Store ID is required' });
}

const query = hydrateQuery(req.query);

const payouts = await prismaClient.payout.findMany({
where: { storeId: req.params.id },
...query
});

return res.json({ payouts });
}

// GET /stores/:id
public async getStoreById(req: Request, res: Response) {
if (!req.params.id) {
Expand Down Expand Up @@ -126,7 +151,7 @@ export default class StoreController {

const managers = await prismaClient.store
.findUnique({ where: { id: req.params.id } })
.managers();
.managers({ include: { manager: true } });

return res.json({ managers });
}
Expand Down
2 changes: 2 additions & 0 deletions api/src/routes/stores.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ router.post('/:id/products', authenticate, storeController.createStoreProduct);
router.get('/current', authenticate, storeController.getCurrentStore);
router.get('/:id', optionalAuth, storeController.getStoreById);
router.get('/:id/products', optionalAuth, storeController.getStoreProducts);
router.get('/:id/managers', isAdmin, storeController.getStoreManagers);
router.get('/:id/payouts', isAdmin, storeController.getStorePayouts);
router.get('/:id/orders', optionalAuth, storeController.getStoreOrders);

export default router;
71 changes: 70 additions & 1 deletion apps/admin/src/app/(dashboard)/stores/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,32 @@ import {
TableHeader,
TableRow
} from '@/components/ui/table';
import { useStoreProductsQuery, useStoreQuery } from '@/data/queries/stores';
import {
useStoreProductsQuery,
useStoreQuery,
useStorePayoutsQuery,
useStoreManagersQuery
} from '@/data/queries/stores';
import { formatNaira } from '@/utils/format';

const StoreDetailPage = ({ params }: { params: Promise<{ id: string }> }) => {
const { id } = React.use(params);
const { data: storeData, isLoading: isLoadingStore } = useStoreQuery(id);
const { data: productsData, isLoading: isLoadingProducts } =
useStoreProductsQuery(id);
const { data: payoutsData, isLoading: isLoadingPayouts } =
useStorePayoutsQuery(id);
const { data: managersData, isLoading: isLoadingManagers } =
useStoreManagersQuery(id);

if (isLoadingStore || isLoadingProducts) {
return <div>Loading...</div>;
}

const store = storeData?.store;
const products = productsData?.products || [];
const managers = managersData?.managers || [];
const payouts = payoutsData?.payouts || [];

return (
<div className='space-y-6'>
Expand Down Expand Up @@ -112,6 +123,64 @@ const StoreDetailPage = ({ params }: { params: Promise<{ id: string }> }) => {
</CardContent>
</Card>
</div>

<div className='grid grid-cols-1 md:grid-cols-2 gap-6'>
<Card>
<CardHeader>
<CardTitle>Managers</CardTitle>
</CardHeader>
<CardContent>
<div className='rounded-md border'>
<Table>
<TableHeader>
<TableRow>
<TableHead>Name</TableHead>
<TableHead>Email</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{managers.map(({ manager }) => (
<TableRow key={manager.id}>
<TableCell>{manager.name}</TableCell>
<TableCell>{manager.email}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
</CardContent>
</Card>

<Card>
<CardHeader>
<CardTitle>Payouts</CardTitle>
</CardHeader>
<CardContent>
<div className='rounded-md border'>
<Table>
<TableHeader>
<TableRow>
<TableHead>Amount</TableHead>
<TableHead>Status</TableHead>
<TableHead>Date</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{payoutsData?.payouts.map(payout => (
<TableRow key={payout.id}>
<TableCell>{formatNaira(payout.amount)}</TableCell>
<TableCell>{payout.status}</TableCell>
<TableCell>
{new Date(payout.createdAt).toLocaleDateString()}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
</CardContent>
</Card>
</div>
</div>
);
};
Expand Down
5 changes: 2 additions & 3 deletions apps/admin/src/app/(dashboard)/stores/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,13 @@ const columns: ColumnDef<Store>[] = [
<DropdownMenuContent align='end'>
<DropdownMenuLabel>Actions</DropdownMenuLabel>
<DropdownMenuItem
onClick={() => navigator.clipboard.writeText(row.original.id)}
onClick={() => navigator.clipboard.writeText(store.id)}
>
Copy store ID
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem
onClick={() => router.push(`/stores/${row.original.id}`)}
onClick={() => router.push(`/stores/${store.id}`)}
>
View store
</DropdownMenuItem>
Expand All @@ -81,7 +81,6 @@ const columns: ColumnDef<Store>[] = [

export default function StoresPage() {
const { data, isLoading } = useStoresQuery();
const router = useRouter();

return (
<div className='space-y-6'>
Expand Down
16 changes: 16 additions & 0 deletions apps/admin/src/data/queries/stores.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,19 @@ export const useStoreOrdersQuery = (id: string, params?: StoreFilters) => {
enabled: !!id
});
};

export const useStorePayoutsQuery = (id: string, params?: StoreFilters) => {
return useQuery({
queryKey: ['stores', id, 'payouts', params],
queryFn: () => dataService.stores.getStorePayouts(id, params),
enabled: !!id
});
};

export const useStoreManagersQuery = (id: string, params?: StoreFilters) => {
return useQuery({
queryKey: ['stores', id, 'managers', params],
queryFn: () => dataService.stores.getStoreManagers(id, params),
enabled: !!id
});
};
43 changes: 42 additions & 1 deletion apps/admin/src/data/services/stores.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { APIService } from './api';
import { Order } from './orders';
import { Product } from './products';

export interface Store {
Expand All @@ -13,6 +14,14 @@ export interface Store {
updatedAt: string;
}

export interface Payout {
id: string;
amount: number;
status: string;
createdAt: string;
updatedAt: string;
}

export interface GetStoresResponse {
stores: Store[];
}
Expand All @@ -35,6 +44,24 @@ export interface GetStoreResponse {
store: Store;
}

export interface GetStoreManagersResponse {
managers: {
manager: {
id: string;
name: string;
email: string;
};
}[];
}

export interface GetStorePayoutsResponse {
payouts: Payout[];
}

export interface GetStoreOrdersResponse {
orders: Order[];
}

export class StoreService {
constructor(private readonly api: APIService) {}

Expand Down Expand Up @@ -62,6 +89,20 @@ export class StoreService {
}

async getStoreOrders(id: string, params?: StoreFilters) {
return this.api.get(`/stores/${id}/orders`, params);
return this.api.get<GetStoreOrdersResponse>(`/stores/${id}/orders`, params);
}

async getStorePayouts(id: string, params?: StoreFilters) {
return this.api.get<GetStorePayoutsResponse>(
`/stores/${id}/payouts`,
params
);
}

async getStoreManagers(id: string, params?: StoreFilters) {
return this.api.get<GetStoreManagersResponse>(
`/stores/${id}/managers`,
params
);
}
}

0 comments on commit 1cddd76

Please sign in to comment.