Skip to content

Commit f9e73ab

Browse files
committed
feat: show imports in accordian
1 parent 457e305 commit f9e73ab

6 files changed

Lines changed: 184 additions & 12 deletions

File tree

collection/app/(app)/CSVImport.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { Dropzone } from "@mantine/dropzone";
2121
import "@mantine/dropzone/styles.css";
2222
import { useForm } from "@mantine/form";
2323
import { useDisclosure } from "@mantine/hooks";
24-
import { AcademicYear, RootItem } from "@prisma/client";
24+
import { RootItem } from "@prisma/client";
2525
import React, { useState, useTransition } from "react";
2626
import {
2727
FaCircleCheck,
@@ -33,6 +33,8 @@ import {
3333
} from "react-icons/fa6";
3434
import useSWR from "swr";
3535

36+
import { fetcher } from "../../lib/fetcher";
37+
3638
interface CSVImportFormProp {
3739
productsByAcademicYear: Record<string, RootItem[]>;
3840
/** Current academic year */
@@ -223,11 +225,6 @@ const CSVImportForm: React.FC<CSVImportFormProp> = ({
223225
);
224226
};
225227

226-
const fetcher = async (...args: Parameters<typeof fetch>) => {
227-
const res = await fetch(...args);
228-
return res.json();
229-
};
230-
231228
export const CSVImport = ({
232229
academicYears,
233230
currentAcademicYear,

collection/app/(app)/ImportsList.tsx

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
"use client";
22

3-
import { Accordion, Paper, Stack, Title } from "@mantine/core";
4-
import { OrderItemImport } from "@prisma/client";
3+
import { ImportTable } from "@/components/tables/ImportTable";
4+
import { ImportList } from "@/lib/crud/importCsv";
5+
import { Accordion, Badge, Button, Group, Paper, Stack, Text, Title } from "@mantine/core";
56
import React from "react";
7+
import { FaUndo } from "react-icons/fa";
68

79
interface ImportsListProps {
8-
imports: OrderItemImport[];
10+
imports: ImportList;
911
}
1012

1113
export const ImportsList: React.FC<ImportsListProps> = ({ imports }) => {
@@ -16,9 +18,30 @@ export const ImportsList: React.FC<ImportsListProps> = ({ imports }) => {
1618
<Accordion>
1719
{imports.map((importItem, index) => (
1820
<Accordion.Item key={index} value={importItem.id}>
19-
<Accordion.Control>{importItem.name}</Accordion.Control>
20-
<Accordion.Panel>
21-
<div>{importItem.name}</div>
21+
<Accordion.Control>
22+
<Group justify="space-between" mr="md">
23+
<Text>{importItem.name}</Text>
24+
<Badge color="blue">{importItem._count.OrderItem}</Badge>
25+
</Group>
26+
</Accordion.Control>
27+
<Accordion.Panel pl="md" pr="md">
28+
<Stack gap="xl">
29+
<Paper p="md" withBorder>
30+
<Group justify="space-between">
31+
<Title order={5}>Actions</Title>
32+
<Group>
33+
<Button
34+
color="red"
35+
variant="outline"
36+
leftSection={<FaUndo />}
37+
>
38+
Rollback Import
39+
</Button>
40+
</Group>
41+
</Group>
42+
</Paper>
43+
<ImportTable importId={importItem.id} />
44+
</Stack>
2245
</Accordion.Panel>
2346
</Accordion.Item>
2447
))}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { getItemsInImport } from "@/lib/crud/importCsv";
2+
import { NextRequest, NextResponse } from "next/server";
3+
4+
export async function GET(request: NextRequest, { params }: { params: { importId: string } }) {
5+
return NextResponse.json(await getItemsInImport(params.importId));
6+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { ImportItemList } from "@/lib/crud/importCsv";
2+
import { fetcher } from "@/lib/fetcher";
3+
import { Stack, Center, Loader } from "@mantine/core";
4+
import { createColumnHelper } from "@tanstack/react-table";
5+
import React from "react";
6+
import useSWR from "swr";
7+
8+
import TanstackTable from "./TanStackTable";
9+
10+
const columnHelper = createColumnHelper<ImportItemList["OrderItem"][number]>();
11+
12+
const columns = [
13+
columnHelper.accessor("Order.orderNo", {
14+
cell: (info) => info.getValue(),
15+
header: "Order No",
16+
id: "orderNo",
17+
sortingFn: "alphanumeric",
18+
}),
19+
// Shortcode
20+
columnHelper.accessor("Order.ImperialStudent.shortcode", {
21+
cell: (info) => info.getValue(),
22+
header: "Shortcode",
23+
id: "shortcode",
24+
sortingFn: "alphanumeric",
25+
}),
26+
// Item name
27+
columnHelper.accessor("Variant.RootItem.name", {
28+
cell: (info) => info.getValue(),
29+
header: "Item Name",
30+
id: "itemName",
31+
sortingFn: "alphanumeric",
32+
}),
33+
// Variant name
34+
columnHelper.accessor("Variant.variantName", {
35+
cell: (info) => info.getValue(),
36+
header: "Variant",
37+
id: "variant",
38+
sortingFn: "alphanumeric",
39+
}),
40+
// Quantity
41+
columnHelper.accessor("quantity", {
42+
cell: (info) => info.getValue(),
43+
header: "Quantity",
44+
id: "quantity",
45+
sortingFn: "alphanumeric",
46+
}),
47+
];
48+
49+
export const ImportTable = ({ importId }: { importId: string }) => {
50+
const { data } = useSWR(`/api/imports/${importId}`, fetcher) satisfies { data: ImportItemList };
51+
52+
if (!data)
53+
return (
54+
<Stack gap="md">
55+
<Center>
56+
<Loader size={24} />
57+
</Center>
58+
</Stack>
59+
);
60+
return (
61+
<TanstackTable
62+
columns={columns}
63+
data={data.OrderItem}
64+
enableSearch={false}
65+
initialSort={[
66+
{
67+
id: "orderNo",
68+
desc: false,
69+
},
70+
]}
71+
/>
72+
);
73+
};

collection/lib/crud/importCsv.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import { AcademicYear } from "@docsoc/eactivities";
44
import { createLogger } from "@docsoc/util";
5+
import { OrderItemImport } from "@prisma/client";
56
import { parse } from "csv-parse";
67
import { revalidatePath, revalidateTag } from "next/cache";
78

@@ -183,5 +184,72 @@ export async function getImportList() {
183184
orderBy: {
184185
date: "asc",
185186
},
187+
select: {
188+
id: true,
189+
name: true,
190+
date: true,
191+
_count: {
192+
select: {
193+
OrderItem: true,
194+
},
195+
},
196+
},
197+
});
198+
}
199+
200+
export type ImportList = Awaited<ReturnType<typeof getImportList>>;
201+
202+
export async function getItemsInImport(importId: string) {
203+
return prisma.orderItemImport.findUnique({
204+
where: {
205+
id: importId,
206+
},
207+
include: {
208+
OrderItem: {
209+
select: {
210+
quantity: true,
211+
Variant: {
212+
select: {
213+
variantName: true,
214+
RootItem: {
215+
select: {
216+
name: true,
217+
},
218+
},
219+
},
220+
},
221+
Order: {
222+
select: {
223+
orderNo: true,
224+
orderDate: true,
225+
ImperialStudent: {
226+
select: {
227+
shortcode: true,
228+
},
229+
},
230+
},
231+
},
232+
},
233+
},
234+
},
186235
});
187236
}
237+
238+
export interface ImportItemList extends OrderItemImport {
239+
OrderItem: {
240+
quantity: number;
241+
Variant: {
242+
variantName: string;
243+
RootItem: {
244+
name: string;
245+
};
246+
};
247+
Order: {
248+
orderNo: number;
249+
orderDate: Date;
250+
ImperialStudent: {
251+
shortcode: string;
252+
};
253+
};
254+
}[];
255+
}

collection/lib/fetcher.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
"use client";
2+
export const fetcher = async (...args: Parameters<typeof fetch>) => {
3+
const res = await fetch(...args);
4+
return res.json();
5+
};

0 commit comments

Comments
 (0)