/* eslint-disable @next/next/no-img-element */ import Head from "next/head"; import {withIronSessionSsr} from "iron-session/next"; import {sessionOptions} from "@/lib/session"; import useUser from "@/hooks/useUser"; import {toast, ToastContainer} from "react-toastify"; import Layout from "@/components/High/Layout"; import {shouldRedirectHome} from "@/utils/navigation.disabled"; import usePayments from "@/hooks/usePayments"; import {Payment} from "@/interfaces/paypal"; import {createColumnHelper, flexRender, getCoreRowModel, useReactTable} from "@tanstack/react-table"; import {CURRENCIES} from "@/resources/paypal"; import {BsTrash} from "react-icons/bs"; import axios from "axios"; import {useEffect, useState, useMemo} from "react"; import {AgentUser, CorporateUser, User} from "@/interfaces/user"; import UserCard from "@/components/UserCard"; import Modal from "@/components/Modal"; import clsx from "clsx"; import useUsers from "@/hooks/useUsers"; import Checkbox from "@/components/Low/Checkbox"; import Button from "@/components/Low/Button"; import Select from "react-select"; import Input from "@/components/Low/Input"; import ReactDatePicker from "react-datepicker"; import moment from "moment"; import PaymentAssetManager from "@/components/PaymentAssetManager"; import {toFixedNumber} from "@/utils/number"; import {CSVLink} from "react-csv"; export const getServerSideProps = withIronSessionSsr(({req, res}) => { const user = req.session.user; if (!user || !user.isVerified) { res.setHeader("location", "/login"); res.statusCode = 302; res.end(); return { props: { user: null, }, }; } if (shouldRedirectHome(user) || !["admin", "developer"].includes(user.type)) { res.setHeader("location", "/"); res.statusCode = 302; res.end(); return { props: { user: null, }, }; } return { props: {user: req.session.user}, }; }, sessionOptions); const columnHelper = createColumnHelper(); const PaymentCreator = ({onClose, reload, showComission = false}: {onClose: () => void; reload: () => void; showComission: boolean}) => { const [corporate, setCorporate] = useState(); const [price, setPrice] = useState(0); const [currency, setCurrency] = useState("EUR"); const [commission, setCommission] = useState(0); const [referralAgent, setReferralAgent] = useState(); const [date, setDate] = useState(new Date()); const {users} = useUsers(); useEffect(() => { if (!corporate) return setReferralAgent(undefined); if (!corporate.corporateInformation?.referralAgent) return setReferralAgent(undefined); const referralAgent = users.find((u) => u.id === corporate.corporateInformation.referralAgent); setReferralAgent(referralAgent as AgentUser | undefined); }, [corporate, users]); useEffect(() => { const payment = corporate?.corporateInformation?.payment; setPrice(payment?.value || 0); setCurrency(payment?.currency || "EUR"); }, [corporate]); const submit = () => { axios .post(`/api/payments`, { corporate: corporate?.id, agent: referralAgent?.id, agentCommission: commission, agentValue: toFixedNumber((commission / 100) * price, 2), currency, value: price, isPaid: false, date: date.toISOString(), }) .then(() => { toast.success("New payment has been created successfully!"); reload(); onClose(); }) .catch(() => { toast.error("Something went wrong, please try again later!"); }); }; return (

New Payment

setPrice(e ? parseInt(e) : 0)} type="number" value={price} className="col-span-3" /> setCommission(e ? parseInt(e) : 0)} type="number" defaultValue={0} />
c.currency === currency)?.label}`} onChange={() => null} type="text" defaultValue={0} disabled />
)}
setDate(date ?? new Date())} />
null} type="text" defaultValue={"No country manager"} disabled />
); }; const IS_PAID_OPTIONS = [ { value: null, label: 'All', }, { value: false, label: 'Unpaid', }, { value: true, label: 'Paid', }, ]; export default function PaymentRecord() { const [selectedCorporateUser, setSelectedCorporateUser] = useState(); const [selectedAgentUser, setSelectedAgentUser] = useState(); const [isCreatingPayment, setIsCreatingPayment] = useState(false); const [filters, setFilters] = useState<{filter: (p: Payment) => boolean; id: string}[]>([]); const [displayPayments, setDisplayPayments] = useState([]); const [corporate, setCorporate] = useState(); const [agent, setAgent] = useState(); const {user} = useUser({redirectTo: "/login"}); const {users, reload: reloadUsers} = useUsers(); const {payments: originalPayments, reload: reloadPayment} = usePayments(); const [startDate, setStartDate] = useState(moment("01/01/2023").toDate()); const [endDate, setEndDate] = useState(moment().endOf('day').toDate()); const [paid, setPaid] = useState(IS_PAID_OPTIONS[0].value); const reload = () => { reloadUsers(); reloadPayment(); }; const payments = useMemo(() => { return originalPayments.filter((p: Payment) => { const date = moment(p.date); return date.isAfter(startDate) && date.isBefore(endDate); }); }, [originalPayments, startDate, endDate]); useEffect(() => { setDisplayPayments( filters .map((f) => f.filter) .reduce((d, f) => d.filter(f), payments) .sort((a, b) => moment(b.date).diff(moment(a.date))), ); }, [payments, filters]); useEffect(() => { if (user && user.type === "agent") { setAgent(user); } }, [user]); useEffect(() => { setFilters((prev) => [ ...prev.filter((x) => x.id !== "agent-filter"), ...(!agent ? [] : [{id: "agent-filter", filter: (p: Payment) => p.agent === agent.id}]), ]); }, [agent]); useEffect(() => console.log(filters), [filters]); useEffect(() => { setFilters((prev) => [ ...prev.filter((x) => x.id !== "corporate-filter"), ...(!corporate ? [] : [{id: "corporate-filter", filter: (p: Payment) => p.corporate === corporate.id}]), ]); }, [corporate]); useEffect(() => { setFilters((prev) => [ ...prev.filter((x) => x.id !== "paid"), ...(typeof paid !== 'boolean' ? [] : [{id: "paid", filter: (p: Payment) => p.isPaid === paid}]), ]) }, [paid]); const updatePayment = (payment: Payment, key: string, value: any) => { axios .patch(`api/payments/${payment.id}`, {...payment, [key]: value}) .then(() => toast.success("Updated the payment")) .finally(reload); }; const deletePayment = (id: string) => { if (!confirm(`Are you sure you want to delete this payment?`)) return; axios .delete(`/api/payments/${id}`) .then(() => toast.success(`Deleted the "${id}" payment`)) .catch((reason) => { if (reason.response.status === 404) { toast.error("Exam not found!"); return; } if (reason.response.status === 403) { toast.error("You do not have permission to delete this exam!"); return; } toast.error("Something went wrong, please try again later."); }) .finally(reload); }; const getFileAssetsColumns = () => { if (user) { const containerClassName = "flex gap-2 text-mti-purple-light hover:text-mti-purple-dark ease-in-out duration-300 cursor-pointer"; switch (user.type) { case "corporate": return [ columnHelper.accessor("corporateTransfer", { header: "Corporate transfer", id: "corporateTransfer", cell: (info) => (
), }), ]; case "agent": return [ columnHelper.accessor("commissionTransfer", { header: "Commission transfer", id: "commissionTransfer", cell: (info) => (
), }), ]; case "admin": return [ columnHelper.accessor("corporateTransfer", { header: "Corporate transfer", id: "corporateTransfer", cell: (info) => (
), }), columnHelper.accessor("commissionTransfer", { header: "Commission transfer", id: "commissionTransfer", cell: (info) => (
), }), ]; case "developer": return [ columnHelper.accessor("corporateTransfer", { header: "Corporate transfer", id: "corporateTransfer", cell: (info) => (
), }), columnHelper.accessor("commissionTransfer", { header: "Commission transfer", id: "commissionTransfer", cell: (info) => (
), }), ]; default: return []; } } return []; }; const defaultColumns = [ columnHelper.accessor("id", { header: "ID", id: "id", cell: (info) => info.getValue(), }), columnHelper.accessor("corporate", { header: "Corporate", id: "corporate", cell: (info) => { const user = users.find((x) => x.id === info.row.original.corporate) as CorporateUser; return (
setSelectedCorporateUser(user)}> {user?.corporateInformation.companyInformation.name || user?.name}
); }, }), columnHelper.accessor("date", { header: "Date", id: "date", cell: (info) => {moment(info.getValue()).format("DD/MM/YYYY")}, }), columnHelper.accessor("value", { header: "Amount", id: "amount", cell: (info) => ( {toFixedNumber(info.getValue(), 2)} {CURRENCIES.find((x) => x.currency === info.row.original.currency)?.label} ), }), columnHelper.accessor("agent", { header: "Country Manager", id: "agent", cell: (info) => (
setSelectedAgentUser(users.find((x) => x.id === info.row.original.agent))}> {(users.find((x) => x.id === info.row.original.agent) as AgentUser)?.name}
), }), columnHelper.accessor("agentCommission", { header: "Commission", id: "agentCommission", cell: (info) => <>{info.getValue()}%, }), columnHelper.accessor("agentValue", { header: "Commission Value", id: "agentValue", cell: (info) => ( {toFixedNumber(info.getValue(), 2)} {CURRENCIES.find((x) => x.currency === info.row.original.currency)?.label} ), }), columnHelper.accessor("isPaid", { header: "Paid", id: "isPaid", cell: (info) => ( (user?.type !== "agent" ? updatePayment(info.row.original, "isPaid", e) : null)}> ), }), ...getFileAssetsColumns(), { header: "", id: "actions", cell: ({row}: {row: {original: Payment}}) => { return (
{user?.type !== "agent" && (
deletePayment(row.original.id)}>
)}
); }, }, ]; const table = useReactTable({ data: displayPayments, columns: defaultColumns, getCoreRowModel: getCoreRowModel(), }); const getUserModal = () => { if(user) { if(selectedCorporateUser) { return ( setSelectedCorporateUser(undefined)}> <> {selectedCorporateUser && (
{ setSelectedCorporateUser(undefined); if (shouldReload) reload(); }} user={selectedCorporateUser} disabled />
)}
); } if(selectedAgentUser) { return ( setSelectedAgentUser(undefined)}> <> {selectedAgentUser && (
{ setSelectedAgentUser(undefined); if (shouldReload) reload(); }} user={selectedAgentUser} />
)}
); } } return null; } return ( <> Payment Record | EnCoach {user && ( {getUserModal()} setIsCreatingPayment(false)}> setIsCreatingPayment(false)} reload={reload} showComission={user.type === "developer" || user.type === "admin"} />

Payment Record

{(user.type === "developer" || user.type === "admin") && (
)}
u.type === "agent") as AgentUser[]).map((user) => ({ value: user.id, meta: user, label: `${user.name} - ${user.email}`, }))} value={agent ? {value: agent?.id, label: `${agent.name} - ${agent.email}`} : undefined} onChange={(value) => setAgent(value !== null ? (value as any).meta : undefined)} styles={{ control: (styles) => ({ ...styles, paddingLeft: "4px", border: "none", outline: "none", ":focus": { outline: "none", }, }), option: (styles, state) => ({ ...styles, backgroundColor: state.isFocused ? "#D5D9F0" : state.isSelected ? "#7872BF" : "white", color: state.isFocused ? "black" : styles.color, }), }} />