From 359748841f4581bedfe6543c77c4b0a9aed6abe9 Mon Sep 17 00:00:00 2001 From: Joao Ramos Date: Fri, 22 Dec 2023 23:22:25 +0000 Subject: [PATCH 1/8] Added payment and date filter --- src/pages/payment-record.tsx | 96 ++++++++++++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 4 deletions(-) diff --git a/src/pages/payment-record.tsx b/src/pages/payment-record.tsx index e123779f..558c89b5 100644 --- a/src/pages/payment-record.tsx +++ b/src/pages/payment-record.tsx @@ -12,7 +12,7 @@ import {createColumnHelper, flexRender, getCoreRowModel, useReactTable} from "@t import {CURRENCIES} from "@/resources/paypal"; import {BsTrash} from "react-icons/bs"; import axios from "axios"; -import {useEffect, useState} from "react"; +import {useEffect, useState, useMemo} from "react"; import {AgentUser, CorporateUser, User} from "@/interfaces/user"; import UserCard from "@/components/UserCard"; import Modal from "@/components/Modal"; @@ -235,6 +235,18 @@ const PaymentCreator = ({onClose, reload, showComission = false}: {onClose: () = ); }; +const IS_PAID_OPTIONS = [ +{ + value: null, + label: 'All', +}, { + value: false, + label: 'Unpaid', +}, { + value: true, + label: 'Paid', +}, +]; export default function PaymentRecord() { const [selectedUser, setSelectedUser] = useState(); const [isCreatingPayment, setIsCreatingPayment] = useState(false); @@ -246,18 +258,31 @@ export default function PaymentRecord() { const {user} = useUser({redirectTo: "/login"}); const {users, reload: reloadUsers} = useUsers(); - const {payments, reload: reloadPayment} = usePayments(); - + 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) + .reduce((d, f) => { + // unlike other filters, date period is not optional + debugger; + return d.filter(f); + }, payments) .sort((a, b) => moment(b.date).diff(moment(a.date))), ); }, [payments, filters]); @@ -284,6 +309,13 @@ export default function PaymentRecord() { ]); }, [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}) @@ -613,6 +645,62 @@ export default function PaymentRecord() { }} /> +
+ +
void; onViewTeachers?: () => void; onViewCorporate?: () => void; + disabled?: boolean; } -const UserCard = ({user, loggedInUser, onClose, onViewStudents, onViewTeachers, onViewCorporate}: Props) => { +const USER_STATUS_OPTIONS = [ + { + value: 'active', + label: 'Active', + }, { + value: 'disabled', + label: 'Disabled', + }, { + value: 'paymentDue', + label: 'Payment Due', + } +]; + +const USER_TYPE_OPTIONS = Object.keys(USER_TYPE_LABELS).map((type) => ({ + value: type, + label: USER_TYPE_LABELS[type as keyof typeof USER_TYPE_LABELS] +})); + +const CURRENCIES_OPTIONS = CURRENCIES.map(({ label, currency}) => ({ value: currency, label })); + +const UserCard = ({user, loggedInUser, onClose, onViewStudents, onViewTeachers, onViewCorporate, disabled = false}: Props) => { const [expiryDate, setExpiryDate] = useState(user.subscriptionExpirationDate); const [type, setType] = useState(user.type); const [status, setStatus] = useState(user.status); @@ -154,6 +175,7 @@ const UserCard = ({user, loggedInUser, onClose, onViewStudents, onViewTeachers, placeholder="Enter corporate name" defaultValue={companyName} required + disabled={disabled} />
@@ -178,6 +201,7 @@ const UserCard = ({user, loggedInUser, onClose, onViewStudents, onViewTeachers, onChange={setCompanyName} placeholder="Enter corporate name" defaultValue={companyName} + disabled={disabled} /> setUserAmount(e ? parseInt(e) : undefined)} placeholder="Enter number of users" defaultValue={userAmount} + disabled={disabled} /> setMonthlyDuration(e ? parseInt(e) : undefined)} placeholder="Enter monthly duration" defaultValue={monthlyDuration} + disabled={disabled} />
@@ -204,17 +230,31 @@ const UserCard = ({user, loggedInUser, onClose, onViewStudents, onViewTeachers, type="number" defaultValue={paymentValue || 0} className="col-span-3" + disabled={disabled} + /> + setPaymentCurrency(e.target.value)} - className="p-6 col-span-2 w-full min-h-[70px] flex justify-center text-sm font-normal rounded-full border focus:outline-none cursor-pointer bg-white"> - {CURRENCIES.map(({label, currency}) => ( - - ))} -
@@ -249,6 +289,7 @@ const UserCard = ({user, loggedInUser, onClose, onViewStudents, onViewTeachers, color: state.isFocused ? "black" : styles.color, }), }} + isDisabled={disabled} /> )} @@ -262,6 +303,7 @@ const UserCard = ({user, loggedInUser, onClose, onViewStudents, onViewTeachers, type="number" defaultValue={commissionValue || 0} className="col-span-3" + disabled={disabled} /> ) : ( @@ -316,7 +358,8 @@ const UserCard = ({user, loggedInUser, onClose, onViewStudents, onViewTeachers, + className="grid grid-cols-2 items-center gap-4 place-items-center" + disabled={disabled}> {EMPLOYMENT_STATUS.map(({status, label}) => ( {({checked}) => ( @@ -351,7 +394,11 @@ const UserCard = ({user, loggedInUser, onClose, onViewStudents, onViewTeachers,
- + {({checked}) => ( Expiry Date setExpiryDate(checked ? user.subscriptionExpirationDate || new Date() : null)}> + onChange={(checked) => setExpiryDate(checked ? user.subscriptionExpirationDate || new Date() : null)} + disabled={disabled} + > Enabled
@@ -434,6 +483,7 @@ const UserCard = ({user, loggedInUser, onClose, onViewStudents, onViewTeachers, dateFormat="dd/MM/yyyy" selected={moment(expiryDate).toDate()} onChange={(date) => setExpiryDate(date)} + disabled={disabled} /> )}
@@ -445,27 +495,55 @@ const UserCard = ({user, loggedInUser, onClose, onViewStudents, onViewTeachers,
- + setType(e.target.value as typeof user.type)} - className="p-6 w-full min-h-[70px] flex justify-center text-sm font-normal rounded-full border focus:outline-none cursor-pointer bg-white"> - {Object.keys(USER_TYPE_LABELS).map((type) => ( - - ))} - + + (profilePictureInput.current as any)?.click()} + className="cursor-pointer text-mti-purple-light text-sm"> + Change picture + +
{USER_TYPE_LABELS[user.type]}
- - (profilePictureInput.current as any)?.click()} - className="cursor-pointer text-mti-purple-light text-sm"> - Change picture - -
{USER_TYPE_LABELS[user.type]}
+ {user.type === 'agent' && ( +
+ {user.demographicInformation?.country.toLowerCase() +
+ )}
From 938a5e9c7cb65c671c90c91dfc383551904af499 Mon Sep 17 00:00:00 2001 From: Joao Ramos Date: Sat, 23 Dec 2023 14:52:56 +0000 Subject: [PATCH 5/8] Removed debugger --- src/pages/profile.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/profile.tsx b/src/pages/profile.tsx index b632ee46..3d142ed4 100644 --- a/src/pages/profile.tsx +++ b/src/pages/profile.tsx @@ -159,7 +159,6 @@ export default function Home() { setIsLoading(false); }; - debugger; return ( <> From 1c645fcba2fa6be4fd24c55ac63d3a8d9599e877 Mon Sep 17 00:00:00 2001 From: Tiago Ribeiro Date: Sat, 23 Dec 2023 20:44:04 +0000 Subject: [PATCH 6/8] Added an ID to every payment record column --- src/pages/payment-record.tsx | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/pages/payment-record.tsx b/src/pages/payment-record.tsx index ed4be520..ef72c476 100644 --- a/src/pages/payment-record.tsx +++ b/src/pages/payment-record.tsx @@ -26,7 +26,7 @@ import ReactDatePicker from "react-datepicker"; import moment from "moment"; import PaymentAssetManager from "@/components/PaymentAssetManager"; import {toFixedNumber} from "@/utils/number"; -import { CSVLink } from "react-csv"; +import {CSVLink} from "react-csv"; export const getServerSideProps = withIronSessionSsr(({req, res}) => { const user = req.session.user; @@ -322,6 +322,7 @@ export default function PaymentRecord() { return [ columnHelper.accessor("corporateTransfer", { header: "Corporate transfer", + id: "corporateTransfer", 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 ( @@ -437,10 +445,12 @@ export default function PaymentRecord() { }), 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} @@ -449,6 +459,7 @@ export default function PaymentRecord() { }), columnHelper.accessor("agent", { header: "Country Manager", + id: "agent", 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} @@ -471,6 +484,7 @@ export default function PaymentRecord() { }), columnHelper.accessor("isPaid", { header: "Paid", + id: "isPaid", cell: (info) => ( e.header).map((e) => ({ - label: e.header, - key: e.accessorKey, - }))} - filename="payment-records.csv" - > + headers={defaultColumns + .filter((e) => e.header) + .map((e) => ({ + label: e.header?.toString() || "", + key: e.id || "", + }))} + filename="payment-records.csv"> Download CSV From 0c2200f49f59b8f402d291eca97e81566448d632 Mon Sep 17 00:00:00 2001 From: Joao Ramos Date: Wed, 27 Dec 2023 14:48:55 +0000 Subject: [PATCH 7/8] Removed debugger --- src/pages/payment-record.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/pages/payment-record.tsx b/src/pages/payment-record.tsx index 70da3f76..fda6160a 100644 --- a/src/pages/payment-record.tsx +++ b/src/pages/payment-record.tsx @@ -279,11 +279,7 @@ export default function PaymentRecord() { setDisplayPayments( filters .map((f) => f.filter) - .reduce((d, f) => { - // unlike other filters, date period is not optional - debugger; - return d.filter(f); - }, payments) + .reduce((d, f) => d.filter(f), payments) .sort((a, b) => moment(b.date).diff(moment(a.date))), ); }, [payments, filters]); From fe5833b061eb098c9e47e8394bc8b669e977e072 Mon Sep 17 00:00:00 2001 From: Joao Ramos Date: Wed, 27 Dec 2023 14:50:10 +0000 Subject: [PATCH 8/8] Fixed Date range picker label --- src/pages/payment-record.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/payment-record.tsx b/src/pages/payment-record.tsx index fda6160a..32c92aff 100644 --- a/src/pages/payment-record.tsx +++ b/src/pages/payment-record.tsx @@ -705,7 +705,7 @@ export default function PaymentRecord() { />
- +