diff --git a/src/pages/payment-record.tsx b/src/pages/payment-record.tsx index ec4cc59f..178640e1 100644 --- a/src/pages/payment-record.tsx +++ b/src/pages/payment-record.tsx @@ -37,7 +37,7 @@ import PaymentAssetManager from "@/components/PaymentAssetManager"; import { toFixedNumber } from "@/utils/number"; import { CSVLink } from "react-csv"; import { Tab } from "@headlessui/react"; - +import { useListSearch } from "@/hooks/useListSearch"; export const getServerSideProps = withIronSessionSsr(({ req, res }) => { const user = req.session.user; @@ -69,7 +69,7 @@ export const getServerSideProps = withIronSessionSsr(({ req, res }) => { }, sessionOptions); const columnHelper = createColumnHelper(); -const paypalColumnHelper = createColumnHelper(); +const paypalColumnHelper = createColumnHelper(); const PaymentCreator = ({ onClose, @@ -348,7 +348,7 @@ const IS_FILE_SUBMITTED_OPTIONS = [ }, ]; -const CSV_WHITELISTED_KEYS = [ +const CSV_PAYMENTS_WHITELISTED_KEYS = [ "corporateId", "corporate", "date", @@ -359,12 +359,28 @@ const CSV_WHITELISTED_KEYS = [ "isPaid", ]; +const CSV_PAYPAL_WHITELISTED_KEYS = [ + "orderId", + "status", + "name", + "email", + "value", + "createdAt", + "subscriptionExpirationDate", +]; + interface SimpleCSVColumn { key: string; label: string; index: number; } +interface PaypalPaymentWithUserData extends PaypalPayment { + name: string; + email: string; +} + +const paypalFilterRows = [["email"], ["name"]]; export default function PaymentRecord() { const [selectedCorporateUser, setSelectedCorporateUser] = useState(); const [selectedAgentUser, setSelectedAgentUser] = useState(); @@ -407,6 +423,8 @@ export default function PaymentRecord() { }); }, [originalPayments, startDate, endDate]); + const [selectedIndex, setSelectedIndex] = useState(0); + useEffect(() => { setDisplayPayments( filters @@ -839,6 +857,15 @@ export default function PaymentRecord() { getCoreRowModel: getCoreRowModel(), }); + const updatedPaypalPayments = useMemo( + () => + paypalPayments.map((p) => { + const user = users.find((x) => x.id === p.userId) as User; + return { ...p, name: user?.name, email: user?.email }; + }), + [paypalPayments, users] + ); + const paypalColumns = [ paypalColumnHelper.accessor("orderId", { header: "Order ID", @@ -856,24 +883,20 @@ export default function PaymentRecord() { return {value}; }, }), - paypalColumnHelper.accessor("userId", { + paypalColumnHelper.accessor("name", { header: "User Name", id: "name", cell: (info) => { - const { value } = columHelperValue("userId", info); - - const user = users.find((x) => x.id === value) as User; - return {user?.name}; + const { value } = columHelperValue(info.column.id, info); + return {value}; }, }), - paypalColumnHelper.accessor("userId", { + paypalColumnHelper.accessor("email", { header: "Email", id: "email", cell: (info) => { - const { value } = columHelperValue("userId", info); - - const user = users.find((x) => x.id === value) as User; - return {user?.email}; + const { value } = columHelperValue(info.column.id, info); + return {value}; }, }), paypalColumnHelper.accessor("value", { @@ -906,8 +929,13 @@ export default function PaymentRecord() { }), ]; + const { rows: filteredRows, renderSearch } = useListSearch( + paypalFilterRows, + updatedPaypalPayments + ); + const paypalTable = useReactTable({ - data: paypalPayments, + data: filteredRows, columns: paypalColumns, getCoreRowModel: getCoreRowModel(), }); @@ -967,11 +995,18 @@ export default function PaymentRecord() { }; const getCSVData = () => { - const columns = table + const tables = [table, paypalTable]; + const whitelists = [ + CSV_PAYMENTS_WHITELISTED_KEYS, + CSV_PAYPAL_WHITELISTED_KEYS, + ]; + const currentTable = tables[selectedIndex]; + const whitelist = whitelists[selectedIndex]; + const columns = currentTable .getHeaderGroups() .reduce((accm: SimpleCSVColumn[], group: HeaderGroup) => { const whitelistedColumns = group.headers.filter((header) => - CSV_WHITELISTED_KEYS.includes(header.id) + whitelist.includes(header.id) ); const data = whitelistedColumns.map((data) => ({ @@ -982,7 +1017,7 @@ export default function PaymentRecord() { return [...accm, ...data]; }, []); - const { rows } = table.getRowModel(); + const { rows } = currentTable.getRowModel(); const finalColumns = [ ...columns, @@ -1045,6 +1080,7 @@ export default function PaymentRecord() { ); + return ( <> @@ -1099,283 +1135,7 @@ export default function PaymentRecord() { )} -
-
- - 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) - } - menuPortalTarget={document?.body} - styles={{ - menuPortal: (base) => ({ ...base, zIndex: 9999 }), - 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, - }), - }} - /> -
- )} -
- - e.value === commissionTransfer - )} - onChange={(value) => { - if (value) return setCommissionTransfer(value.value); - setCommissionTransfer(null); - }} - menuPortalTarget={document?.body} - styles={{ - menuPortal: (base) => ({ ...base, zIndex: 9999 }), - 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, - }), - }} - /> -
- )} -
- - u.type === "corporate" + ) as CorporateUser[] + ).map((user) => ({ + value: user.id, + meta: user, + label: `${ + user.corporateInformation?.companyInformation?.name || + user.name + } - ${user.email}`, + }))} + defaultValue={ + user.type === "corporate" + ? { + value: user.id, + meta: user, + label: `${ + user.corporateInformation?.companyInformation + ?.name || user.name + } - ${user.email}`, + } + : undefined + } + isDisabled={user.type === "corporate"} + onChange={(value) => + setCorporate((value as any)?.meta ?? undefined) + } + menuPortalTarget={document?.body} + styles={{ + menuPortal: (base) => ({ ...base, zIndex: 9999 }), + 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, + }), + }} + /> +
+ {user.type !== "corporate" && ( +
+ + e.value === paid)} + onChange={(value) => { + if (value) return setPaid(value.value); + setPaid(null); + }} + menuPortalTarget={document?.body} + styles={{ + menuPortal: (base) => ({ ...base, zIndex: 9999 }), + 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, + }), + }} + /> +
+
+ + + moment(date).isSameOrBefore(moment(new Date())) + } + onChange={([initialDate, finalDate]: [Date, Date]) => { + setStartDate( + initialDate ?? moment("01/01/2023").toDate() + ); + if (finalDate) { + // basicly selecting a final day works as if I'm selecting the first + // minute of that day. this way it covers the whole day + setEndDate(moment(finalDate).endOf("day").toDate()); + return; + } + setEndDate(null); + }} + /> +
+ {user.type !== "corporate" && ( +
+ + e.value === corporateTransfer + )} + onChange={(value) => { + if (value) return setCorporateTransfer(value.value); + setCorporateTransfer(null); + }} + menuPortalTarget={document?.body} + styles={{ + menuPortal: (base) => ({ ...base, zIndex: 9999 }), + 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, + }), + }} + /> +
+
{renderTable(table as Table)} - - {renderTable(paypalTable as Table)} + + {renderSearch()} + {renderTable(paypalTable as Table)}