From 4cbd045502feede9bd9674860e881d122c60e627 Mon Sep 17 00:00:00 2001 From: Joao Ramos Date: Tue, 12 Dec 2023 22:44:33 +0000 Subject: [PATCH] Added comission to user card and updated user update to insert a new payment entry --- src/components/UserCard.tsx | 87 ++++++++++++++++++++--------------- src/interfaces/user.ts | 1 + src/pages/api/users/update.ts | 56 +++++++++++++++++++++- 3 files changed, 106 insertions(+), 38 deletions(-) diff --git a/src/components/UserCard.tsx b/src/components/UserCard.tsx index 98db4a77..c703d99c 100644 --- a/src/components/UserCard.tsx +++ b/src/components/UserCard.tsx @@ -60,7 +60,7 @@ const UserCard = ({user, loggedInUser, onClose, onViewStudents, onViewTeachers, const [paymentValue, setPaymentValue] = useState(user.type === "corporate" ? user.corporateInformation?.payment?.value : undefined); const [paymentCurrency, setPaymentCurrency] = useState(user.type === "corporate" ? user.corporateInformation?.payment?.currency : "EUR"); const [monthlyDuration, setMonthlyDuration] = useState(user.type === "corporate" ? user.corporateInformation?.monthlyDuration : undefined); - + const [commissionValue, setCommission] = useState(user.type === "corporate" ? user.corporateInformation?.payment?.commission : undefined); const {stats} = useStats(user.id); const {users} = useUsers(); @@ -106,6 +106,7 @@ const UserCard = ({user, loggedInUser, onClose, onViewStudents, onViewTeachers, payment: { value: paymentValue, currency: paymentCurrency, + ...referralAgent === '' ? {} : { commission: commissionValue } }, } : undefined, @@ -194,41 +195,6 @@ const UserCard = ({user, loggedInUser, onClose, onViewStudents, onViewTeachers, placeholder="Enter monthly duration" defaultValue={monthlyDuration} /> - -
- - {referralAgentLabel && ( - u.type === "agent").map((x) => ({value: x.id, label: `${x.name} - ${x.email}`})), + ]} + defaultValue={{ + value: referralAgent, + label: referralAgentLabel, + }} + onChange={(value) => setReferralAgent(value?.value)} + 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, + }), + }} + /> + )} +
+
+ {referralAgent !== '' ? ( + <> + + setCommission(e ? parseInt(e) : undefined)} + type="number" + defaultValue={commissionValue || 0} + className="col-span-3" + /> + + ) :
} +
+
)} diff --git a/src/interfaces/user.ts b/src/interfaces/user.ts index 5594f273..cd337ac5 100644 --- a/src/interfaces/user.ts +++ b/src/interfaces/user.ts @@ -57,6 +57,7 @@ export interface CorporateInformation { payment?: { value: number; currency: string; + commission: number; }; referralAgent?: string; } diff --git a/src/pages/api/users/update.ts b/src/pages/api/users/update.ts index 65bf3aa9..2f4a3723 100644 --- a/src/pages/api/users/update.ts +++ b/src/pages/api/users/update.ts @@ -1,13 +1,16 @@ // Next.js API route support: https://nextjs.org/docs/api-routes/introduction import type {NextApiRequest, NextApiResponse} from "next"; import {app} from "@/firebase"; -import {getFirestore, collection, getDocs, getDoc, doc, setDoc} from "firebase/firestore"; +import {getFirestore, collection, getDocs, getDoc, doc, setDoc, query, where} from "firebase/firestore"; import {withIronSessionApiRoute} from "iron-session/next"; import {sessionOptions} from "@/lib/session"; import {User} from "@/interfaces/user"; import {getDownloadURL, getStorage, ref, uploadBytes} from "firebase/storage"; import {getAuth, signInWithEmailAndPassword, updateEmail, updatePassword} from "firebase/auth"; import {errorMessages} from "@/constants/errors"; +import moment from "moment"; +import ShortUniqueId from "short-unique-id"; +import {Payment} from "@/interfaces/paypal"; const db = getFirestore(app); const storage = getStorage(app); @@ -15,6 +18,52 @@ const auth = getAuth(app); export default withIronSessionApiRoute(handler, sessionOptions); +const addPaymentRecord = async (data: Payment) => { + const shortUID = new ShortUniqueId(); + await setDoc(doc(db, "payments", shortUID.randomUUID(8)), data); +} +const managePaymentRecords = async (user: User, userId: string | undefined): Promise => { + try { + if(user.type === 'corporate' && userId) { + const data = { + corporate: userId, + agent: user.corporateInformation.referralAgent, + agentCommission: user.corporateInformation.payment!.commission, + agentValue: (user.corporateInformation.payment!.commission / 100) * user.corporateInformation.payment!.value, + currency: user.corporateInformation.payment!.currency, + value: user.corporateInformation.payment!.value, + isPaid: false, + date: new Date(), + } as Payment; + + const corporatePayments = await getDocs(query(collection(db, "payments"), where("corporate", "==", userId))); + if(corporatePayments.docs.length === 0) { + await addPaymentRecord(data); + return true; + } + + const hasPaymentPaidAndExpiring = corporatePayments.docs.filter((doc) => { + const data = doc.data(); + return data.isPaid + && moment().isAfter(moment(user.subscriptionExpirationDate).subtract(30, "days")) + && moment().isBefore(moment(user.subscriptionExpirationDate)); + }); + + if(hasPaymentPaidAndExpiring.length > 0) { + await addPaymentRecord(data); + return true; + } + } + + return false; + } catch(e) { + // if this process fails it should not stop the rest of the process + console.log(e); + return false; + } + +} + async function handler(req: NextApiRequest, res: NextApiResponse) { if (!req.session.user) { res.status(401).json({ok: false}); @@ -25,7 +74,8 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { const updatedUser = req.body as User & {password?: string; newPassword?: string}; if (!!req.query.id) { - await setDoc(userRef, updatedUser, {merge: true}); + const user = await setDoc(userRef, updatedUser, {merge: true}); + await managePaymentRecords(updatedUser, updatedUser.id); res.status(200).json({ok: true}); return; } @@ -74,6 +124,8 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { await req.session.save(); } + await managePaymentRecords(user, req.query.id); + res.status(200).json({user}); }