import Button from "@/components/Low/Button"; import Checkbox from "@/components/Low/Checkbox"; import Input from "@/components/Low/Input"; import Select from "@/components/Low/Select"; import Modal from "@/components/Modal"; import useDiscounts from "@/hooks/useDiscounts"; import useUser from "@/hooks/useUser"; import useUsers from "@/hooks/useUsers"; import { Discount } from "@/interfaces/paypal"; import { Code, User } from "@/interfaces/user"; import { USER_TYPE_LABELS } from "@/resources/user"; import { createColumnHelper, flexRender, getCoreRowModel, useReactTable } from "@tanstack/react-table"; import axios from "axios"; import clsx from "clsx"; import moment from "moment"; import { useEffect, useState } from "react"; import ReactDatePicker from "react-datepicker"; import { BsPencil, BsTrash } from "react-icons/bs"; import { toast } from "react-toastify"; const columnHelper = createColumnHelper(); const DiscountCreator = ({ discount, onClose }: { discount?: Discount; onClose: () => void }) => { const [percentage, setPercentage] = useState(discount?.percentage); const [domain, setDomain] = useState(discount?.domain); const [validUntil, setValidUntil] = useState(discount?.validUntil); const submit = async () => { const body = { percentage, domain, validUntil: validUntil?.toISOString() || undefined }; if (discount) { return axios .patch(`/api/discounts/${discount.id}`, body) .then(() => { toast.success("Discount has been edited successfully!"); onClose(); }) .catch(() => { toast.error("Something went wrong, please try again later!"); }); } return axios .post(`/api/discounts`, body) .then(() => { toast.success("New discount has been created successfully!"); onClose(); }) .catch(() => { toast.error("Something went wrong, please try again later!"); }); }; return (
setDomain(e.replaceAll("@", ""))} />
setPercentage(parseFloat(e))} />
moment(date).isAfter(new Date())} dateFormat="dd/MM/yyyy" selected={validUntil} onChange={(date) => setValidUntil(date ? moment(date).endOf("day").toDate() : undefined)} />
); }; export default function DiscountList({ user }: { user: User }) { const [selectedDiscounts, setSelectedDiscounts] = useState([]); const [isCreating, setIsCreating] = useState(false); const [editingDiscount, setEditingDiscount] = useState(); const [filteredDiscounts, setFilteredDiscounts] = useState([]); const { users } = useUsers(); const { discounts, reload } = useDiscounts(); useEffect(() => { setFilteredDiscounts(discounts); }, [discounts]); const toggleDiscount = (id: string) => { setSelectedDiscounts((prev) => (prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id])); }; const toggleAllDiscounts = (checked: boolean) => { if (checked) return setSelectedDiscounts(filteredDiscounts.map((x) => x.id)); return setSelectedDiscounts([]); }; const deleteDiscounts = async (discounts: string[]) => { if (!confirm(`Are you sure you want to delete these ${discounts.length} discount(s)?`)) return; const params = new URLSearchParams(); discounts.forEach((code) => params.append("discount", code)); axios .delete(`/api/discounts?${params.toString()}`) .then(() => toast.success(`Deleted the discount(s)!`)) .catch((reason) => { if (reason.response.status === 404) { toast.error("Discount not found!"); return; } if (reason.response.status === 403) { toast.error("You do not have permission to delete this discount!"); return; } toast.error("Something went wrong, please try again later."); }) .finally(reload); }; const deleteDiscount = async (discount: Discount) => { if (!confirm(`Are you sure you want to delete this "${discount.id}" discount?`)) return; axios .delete(`/api/discounts/${discount.id}`) .then(() => toast.success(`Deleted the "${discount.id}" discount`)) .catch((reason) => { if (reason.response.status === 404) { toast.error("Code not found!"); return; } if (reason.response.status === 403) { toast.error("You do not have permission to delete this discount!"); return; } toast.error("Something went wrong, please try again later."); }) .finally(reload); }; const defaultColumns = [ columnHelper.accessor("id", { id: "id", header: () => ( 0} onChange={(checked) => toggleAllDiscounts(checked)}> {""} ), cell: (info) => ( toggleDiscount(info.getValue())}> {""} ), }), columnHelper.accessor("id", { header: "ID", cell: (info) => info.getValue(), }), columnHelper.accessor("domain", { header: "Domain", cell: (info) => `@${info.getValue()}`, }), columnHelper.accessor("percentage", { header: "Percentage", cell: (info) => `${info.getValue()}%`, }), columnHelper.accessor("validUntil", { header: "Valid Until", cell: (info) => (info.getValue() ? moment(info.getValue()).format("DD/MM/YYYY") : ""), }), { header: "", id: "actions", cell: ({ row }: { row: { original: Discount } }) => { return (
{ setEditingDiscount(row.original); }}>
deleteDiscount(row.original)}>
); }, }, ]; const table = useReactTable({ data: filteredDiscounts, columns: defaultColumns, getCoreRowModel: getCoreRowModel(), }); const closeModal = () => { setIsCreating(false); setEditingDiscount(undefined); reload(); }; return ( <>
{selectedDiscounts.length} code(s) selected
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( ))} ))} {table.getRowModel().rows.map((row) => ( {row.getVisibleCells().map((cell) => ( ))} ))}
{header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}
{flexRender(cell.column.columnDef.cell, cell.getContext())}
); }