Skip to content

Commit

Permalink
feat: coupons import csv with hardcoded offer_id
Browse files Browse the repository at this point in the history
  • Loading branch information
ClementNumericite committed Jan 24, 2024
1 parent a0c9ab3 commit a2492f1
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 0 deletions.
23 changes: 23 additions & 0 deletions imports/coupons.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
code,validityTo
H1D1,01/06/24
H1D2,02/06/24
H1D3,03/06/24
H1D4,04/06/24
H1D5,05/06/24
H1D6,06/06/24
H1D7,07/06/24
H1D8,08/06/24
H1D9,09/06/24
H1D10,10/06/24
H1D11,11/06/24
H1D12,12/06/24
H1D13,13/06/24
H1D14,14/06/24
H1D15,15/06/24
H1D16,16/06/24
H1D17,17/06/24
H1D18,18/06/24
H1D19,19/06/24
H1D20,20/06/24
H1D21,21/06/24
H1D22,22/06/24
14 changes: 14 additions & 0 deletions webapp/src/payload/collections/Coupon.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
import dynamic from "next/dynamic";
import type { Props } from "payload/components/views/List";
import { type CollectionConfig } from "payload/types";

const ImportCoupons = dynamic<Props>(
() => import("../components/ImportCoupons"),
{
ssr: false,
}
);

export const Coupons: CollectionConfig = {
slug: "coupons",
labels: {
Expand Down Expand Up @@ -47,4 +56,9 @@ export const Coupons: CollectionConfig = {
required: true,
},
],
admin: {
components: {
BeforeListTable: [ImportCoupons],
},
},
};
72 changes: 72 additions & 0 deletions webapp/src/payload/components/ImportCoupons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { Box, Button } from "@chakra-ui/react";
import Papa from "papaparse";
import type { Props } from "payload/components/views/List";
import React, { useCallback } from "react";
import { api } from "~/utils/api";
import { convertFrenchDateToEnglish } from "~/utils/tools";

export type ImportCouponsProps = {};

const ImportCoupons = ({ hasCreatePermission, resetParams }: Props) => {
if (!hasCreatePermission) return;

const { mutate: createCoupons } = api.coupon.create.useMutation({
onSuccess() {
resetParams();
},
});

const handleFileChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];

if (file) {
Papa.parse(file, {
complete: (result) => {
createCoupons(
result.data
.filter(
(row: any) =>
row.code &&
row.validityTo &&
convertFrenchDateToEnglish(row.validityTo)
)
.map((row: any) => {
const englishDate = convertFrenchDateToEnglish(
row.validityTo
);

return {
code: row.code,
validityTo: new Date(englishDate as string).toISOString(),
status: "available",
offer: 1,
};
})
);
},
header: true, // Si votre CSV a une ligne d'en-tête
dynamicTyping: true, // Convertit automatiquement les valeurs en types appropriés
});
}
},
[]
);

return (
<Box>
<input
id="csvInput"
type="file"
accept=".csv"
onChange={handleFileChange}
style={{ display: "none" }}
/>
<Button as="label" htmlFor="csvInput" cursor="pointer">
Importer un CSV
</Button>
</Box>
);
};

export default ImportCoupons;
23 changes: 23 additions & 0 deletions webapp/src/server/api/routers/coupon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,27 @@ export const couponRouter = createTRPCRouter({

return { data: coupons.docs[0] as CouponIncluded };
}),
create: protectedProcedure
.input(
z.array(
z.object({
code: z.string(),
validityTo: z.string(),
status: z.enum(["available", "archived"]),
offer: z.number(),
})
)
)
.mutation(async ({ ctx, input }) => {
const promises = input.map((data) => {
return ctx.payload.create({
collection: "coupons",
data,
});
});

const coupons = await Promise.all(promises);

return { data: coupons };
}),
});
20 changes: 20 additions & 0 deletions webapp/src/utils/tools.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export const convertFrenchDateToEnglish = (
frenchDate: string
): string | null => {
const match = frenchDate.match(/^(\d{2})\/(\d{2})\/(\d{2})$/);

if (match) {
const [, day, month, year] = match.map(Number);

if (year !== undefined && month !== undefined && day !== undefined) {
// Creating a Date object with a four-digit year
const englishFormattedDate = new Date(2000 + year, month - 1, day);

// Using toISOString to get the date in ISO format (YYYY-MM-DD)
return englishFormattedDate.toISOString().split("T")[0] || null;
}
}

// Return null if the input format is incorrect
return null;
};

0 comments on commit a2492f1

Please sign in to comment.