From fa544bf4e84194f193dd76f3d6e0bbc3eb452271 Mon Sep 17 00:00:00 2001 From: Tiago Ribeiro Date: Sun, 26 Nov 2023 11:01:27 +0000 Subject: [PATCH] Enabled payment for Corporate along with increasing every single one of their students/teachers expiry date as well --- src/components/PayPalPayment.tsx | 11 +- src/pages/(status)/PaymentDue.tsx | 172 +++++++++++++++++------------- src/pages/api/paypal/approve.ts | 28 ++++- 3 files changed, 127 insertions(+), 84 deletions(-) diff --git a/src/components/PayPalPayment.tsx b/src/components/PayPalPayment.tsx index 4240b900..32c75756 100644 --- a/src/components/PayPalPayment.tsx +++ b/src/components/PayPalPayment.tsx @@ -10,10 +10,11 @@ interface Props { price: number; duration: number; duration_unit: DurationUnit; + setIsLoading: (isLoading: boolean) => void; onSuccess: (duration: number, duration_unit: DurationUnit) => void; } -export default function PayPalPayment({price, currency, duration, duration_unit, onSuccess}: Props) { +export default function PayPalPayment({price, currency, duration, duration_unit, setIsLoading, onSuccess}: Props) { const [{options}, dispatch] = usePayPalScriptReducer(); useEffect(() => { @@ -28,7 +29,7 @@ export default function PayPalPayment({price, currency, duration, duration_unit, }, [currency]); const createOrder = async (data: CreateOrderData, actions: CreateOrderActions): Promise => { - console.log(data, actions); + setIsLoading(true); return axios .post("/api/paypal", {currencyCode: currency, price}) @@ -49,13 +50,11 @@ export default function PayPalPayment({price, currency, duration, duration_unit, }; const onError = async (data: Record) => { - console.log(data); - toast.error("ERROR!"); + setIsLoading(false); }; const onCancel = async (data: Record, actions: OnCancelledActions) => { - console.log(data, actions); - toast.error("CANCEL!"); + setIsLoading(false); }; return ( diff --git a/src/pages/(status)/PaymentDue.tsx b/src/pages/(status)/PaymentDue.tsx index e5093943..685a81ae 100644 --- a/src/pages/(status)/PaymentDue.tsx +++ b/src/pages/(status)/PaymentDue.tsx @@ -20,10 +20,9 @@ import Input from "@/components/Low/Input"; import Button from "@/components/Low/Button"; export default function PaymentDue({user, reload}: {user: User; reload: () => void}) { - const [selectedPackage, setPackage] = useState(); - const [code, setCode] = useState(); + const [isLoading, setIsLoading] = useState(false); - const {packages, isLoading} = usePackages(); + const {packages} = usePackages(); const {users} = useUsers(); const {groups} = useGroups(); @@ -38,31 +37,86 @@ export default function PaymentDue({user, reload}: {user: User; reload: () => vo return userGroupsAdminTypes.every((t) => t !== "admin"); }; - return user ? ( - -
- You do not have time credits for your account type! - {isIndividual() && ( -
- To add to your use of EnCoach, please purchase one of the time packages available below: -
- {packages.map((p) => ( -
+ return ( + <> + {isLoading && ( +
+
+ + Completing your payment... +
+
+ )} + {user ? ( + +
+ You do not have time credits for your account type! + {isIndividual() && ( +
+ + To add to your use of EnCoach, please purchase one of the time packages available below: + +
+ {packages.map((p) => ( +
+
+ EnCoach's Logo + + EnCoach - {p.duration}{" "} + {capitalize( + p.duration === 1 ? p.duration_unit.slice(0, p.duration_unit.length - 1) : p.duration_unit, + )} + +
+
+ + {p.price} + {getSymbolFromCurrency(p.currency)} + + { + setTimeout(reload, 500); + }} + /> +
+
+ This includes: +
    +
  • - Train your abilities for the IELTS exam
  • +
  • - Gain insights into your weaknesses and strengths
  • +
  • - Allow yourself to correctly prepare for the exam
  • +
+
+
+ ))} +
+
+ )} + {!isIndividual() && user?.corporateInformation && user?.corporateInformation.payment && ( +
+ + To add to your use of EnCoach and that of your students and teachers, please pay your designated package below: + +
EnCoach's Logo - - EnCoach - {p.duration}{" "} - {capitalize(p.duration === 1 ? p.duration_unit.slice(0, p.duration_unit.length - 1) : p.duration_unit)} - + EnCoach - {user.corporateInformation?.monthlyDuration} Months
- {p.price} - {getSymbolFromCurrency(p.currency)} + {user.corporateInformation.payment.value} + {getSymbolFromCurrency(user.corporateInformation.payment.currency)} { + setIsLoading(false); setTimeout(reload, 500); }} /> @@ -70,68 +124,34 @@ export default function PaymentDue({user, reload}: {user: User; reload: () => vo
This includes:
    -
  • - Train your abilities for the IELTS exam
  • -
  • - Gain insights into your weaknesses and strengths
  • -
  • - Allow yourself to correctly prepare for the exam
  • +
  • + - Allow a total of {user.corporateInformation.companyInformation.userAmount} students and teachers to + use EnCoach +
  • +
  • - Train their abilities for the IELTS exam
  • +
  • - Gain insights into your students' weaknesses and strengths
  • +
  • - Allow them to correctly prepare for the exam
- ))} -
-
- )} - {!isIndividual() && user?.corporateInformation && user?.corporateInformation.payment && ( -
- - To add to your use of EnCoach and that of your students and teachers, please pay your designated package below: - -
-
- EnCoach's Logo - EnCoach - {user.corporateInformation?.monthlyDuration} Month(s)
-
- - {user.corporateInformation.payment.value} - {getSymbolFromCurrency(user.corporateInformation.payment.currency)} + )} + {!isIndividual() && (!user?.corporateInformation || !user?.corporateInformation?.payment) && ( +
+ + An admin nor your agent have yet set the price intended to your requirements in terms of the amount of users you + desire and your expected monthly duration. + + + Please try again again later or contact your agent or an admin, thank you for your patience. - { - setTimeout(reload, 500); - }} - />
-
- This includes: -
    -
  • - - Allow a total of {user.corporateInformation.companyInformation.userAmount} students and teachers to use - EnCoach -
  • -
  • - Train their abilities for the IELTS exam
  • -
  • - Gain insights into your students' weaknesses and strengths
  • -
  • - Allow them to correctly prepare for the exam
  • -
-
-
+ )}
- )} - {!isIndividual() && (!user?.corporateInformation || !user?.corporateInformation?.payment) && ( -
- - An admin nor your agent have yet set the price intended to your requirements in terms of the amount of users you desire - and your expected monthly duration. - - Please try again again later or contact your agent or an admin, thank you for your patience. -
- )} -
- - ) : ( -
+ + ) : ( +
+ )} + ); } diff --git a/src/pages/api/paypal/approve.ts b/src/pages/api/paypal/approve.ts index d9dbbc16..0ca4226d 100644 --- a/src/pages/api/paypal/approve.ts +++ b/src/pages/api/paypal/approve.ts @@ -11,6 +11,7 @@ import {v4} from "uuid"; import {OrderResponseBody} from "@paypal/paypal-js"; import {getAccessToken} from "@/utils/paypal"; import moment from "moment"; +import {Group} from "@/interfaces/user"; const db = getFirestore(app); @@ -36,6 +37,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { ); if (request.data.status === "COMPLETED") { + const user = req.session.user; const subscriptionExpirationDate = req.session.user.subscriptionExpirationDate; const today = moment(new Date()); const dateToBeAddedTo = !subscriptionExpirationDate @@ -51,8 +53,30 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { {merge: true}, ); - res.status(200).json({ok: true}); - return; + if (user.type === "corporate") { + const snapshot = await getDocs(collection(db, "groups")); + const groups: Group[] = ( + snapshot.docs.map((doc) => ({ + id: doc.id, + ...doc.data(), + })) as Group[] + ).filter((x) => x.admin === user.id); + + await Promise.all( + groups + .flatMap((x) => x.participants) + .map( + async (x) => + await setDoc( + doc(db, "users", x), + {subscriptionExpirationDate: updatedExpirationDate.toISOString(), status: "active"}, + {merge: true}, + ), + ), + ); + } + + return res.status(200).json({ok: true}); } res.status(404).json({ok: false, reason: "Order ID not found or purchase was not approved!"});