Extracted the PayPalScriptProvider

This commit is contained in:
Tiago Ribeiro
2024-02-03 23:40:31 +00:00
parent 00c171b161
commit 5dcab23fdb
2 changed files with 206 additions and 256 deletions

View File

@@ -11,11 +11,12 @@ interface Props {
price: number;
duration: number;
duration_unit: DurationUnit;
loadScript?: boolean;
setIsLoading: (isLoading: boolean) => void;
onSuccess: (duration: number, duration_unit: DurationUnit) => void;
}
export default function PayPalPayment({clientID, price, currency, duration, duration_unit, setIsLoading, onSuccess}: Props) {
export default function PayPalPayment({clientID, price, currency, duration, duration_unit, loadScript, setIsLoading, onSuccess}: Props) {
const createOrder = async (data: CreateOrderData, actions: CreateOrderActions): Promise<string> => {
setIsLoading(true);
@@ -45,7 +46,7 @@ export default function PayPalPayment({clientID, price, currency, duration, dura
setIsLoading(false);
};
return (
return loadScript ? (
<PayPalScriptProvider
options={{
clientId: clientID,
@@ -60,7 +61,17 @@ export default function PayPalPayment({clientID, price, currency, duration, dura
createOrder={createOrder}
onApprove={onApprove}
onCancel={onCancel}
onError={onError}></PayPalButtons>
onError={onError}
/>
</PayPalScriptProvider>
) : (
<PayPalButtons
className="w-full"
style={{layout: "vertical"}}
createOrder={createOrder}
onApprove={onApprove}
onCancel={onCancel}
onError={onError}
/>
);
}

View File

@@ -4,15 +4,16 @@ import PayPalPayment from "@/components/PayPalPayment";
import useGroups from "@/hooks/useGroups";
import usePackages from "@/hooks/usePackages";
import useUsers from "@/hooks/useUsers";
import { User } from "@/interfaces/user";
import {User} from "@/interfaces/user";
import clsx from "clsx";
import { capitalize } from "lodash";
import { useState } from "react";
import {capitalize} from "lodash";
import {useState} from "react";
import getSymbolFromCurrency from "currency-symbol-map";
import useInvites from "@/hooks/useInvites";
import { BsArrowRepeat } from "react-icons/bs";
import {BsArrowRepeat} from "react-icons/bs";
import InviteCard from "@/components/Medium/InviteCard";
import { useRouter } from "next/router";
import {useRouter} from "next/router";
import {PayPalScriptProvider} from "@paypal/react-paypal-js";
interface Props {
user: User;
@@ -21,24 +22,15 @@ interface Props {
reload: () => void;
}
export default function PaymentDue({
user,
hasExpired = false,
clientID,
reload,
}: Props) {
export default function PaymentDue({user, hasExpired = false, clientID, reload}: Props) {
const [isLoading, setIsLoading] = useState(false);
const router = useRouter();
const { packages } = usePackages();
const { users } = useUsers();
const { groups } = useGroups();
const {
invites,
isLoading: isInvitesLoading,
reload: reloadInvites,
} = useInvites({ to: user?.id });
const {packages} = usePackages();
const {users} = useUsers();
const {groups} = useGroups();
const {invites, isLoading: isInvitesLoading, reload: reloadInvites} = useInvites({to: user?.id});
const isIndividual = () => {
if (user?.type === "developer") return true;
@@ -47,9 +39,7 @@ export default function PaymentDue({
if (userGroups.length === 0) return true;
const userGroupsAdminTypes = userGroups
.map((g) => users?.find((u) => u.id === g.admin)?.type)
.filter((t) => !!t);
const userGroupsAdminTypes = userGroups.map((g) => users?.find((u) => u.id === g.admin)?.type).filter((t) => !!t);
return userGroupsAdminTypes.every((t) => t !== "corporate");
};
@@ -59,9 +49,7 @@ export default function PaymentDue({
<div className="absolute left-0 top-0 z-[999] h-screen w-screen overflow-hidden bg-black/60">
<div className="absolute left-1/2 top-1/2 flex h-fit w-fit -translate-x-1/2 -translate-y-1/2 animate-pulse flex-col items-center gap-8 text-white">
<span className={clsx("loading loading-infinity w-48")} />
<span className={clsx("text-2xl font-bold")}>
Completing your payment...
</span>
<span className={clsx("text-2xl font-bold")}>Completing your payment...</span>
</div>
</div>
)}
@@ -72,17 +60,9 @@ export default function PaymentDue({
<div className="flex items-center gap-4">
<div
onClick={reloadInvites}
className="text-mti-purple-light hover:text-mti-purple-dark flex cursor-pointer items-center gap-2 transition duration-300 ease-in-out"
>
<span className="text-mti-black text-lg font-bold">
Invites
</span>
<BsArrowRepeat
className={clsx(
"text-xl",
isInvitesLoading && "animate-spin",
)}
/>
className="text-mti-purple-light hover:text-mti-purple-dark flex cursor-pointer items-center gap-2 transition duration-300 ease-in-out">
<span className="text-mti-black text-lg font-bold">Invites</span>
<BsArrowRepeat className={clsx("text-xl", isInvitesLoading && "animate-spin")} />
</div>
</div>
<span className="text-mti-gray-taupe scrollbar-hide flex gap-8 overflow-x-scroll">
@@ -102,40 +82,29 @@ export default function PaymentDue({
)}
<div className="flex w-full flex-col items-center justify-center gap-4 text-center">
{hasExpired && (
<span className="text-lg font-bold">
You do not have time credits for your account type!
</span>
)}
{hasExpired && <span className="text-lg font-bold">You do not have time credits for your account type!</span>}
{isIndividual() && (
<div className="scrollbar-hide flex w-full flex-col items-center gap-12 overflow-x-scroll">
<span className="max-w-lg">
To add to your use of EnCoach, please purchase one of the time
packages available below:
To add to your use of EnCoach, please purchase one of the time packages available below:
</span>
<div className="flex w-full flex-wrap justify-center gap-8">
<PayPalScriptProvider
options={{
clientId: clientID,
currency: "USD",
intent: "capture",
commit: true,
vault: true,
}}>
{packages.map((p) => (
<div
key={p.id}
className={clsx(
"flex flex-col items-start gap-6 rounded-xl bg-white p-4",
)}
>
<div key={p.id} className={clsx("flex flex-col items-start gap-6 rounded-xl bg-white p-4")}>
<div className="mb-2 flex flex-col items-start">
<img
src="/logo_title.png"
alt="EnCoach's Logo"
className="w-32"
/>
<img src="/logo_title.png" alt="EnCoach's Logo" className="w-32" />
<span className="text-xl font-semibold">
EnCoach - {p.duration}{" "}
{capitalize(
p.duration === 1
? p.duration_unit.slice(
0,
p.duration_unit.length - 1,
)
: p.duration_unit,
p.duration === 1 ? p.duration_unit.slice(0, p.duration_unit.length - 1) : p.duration_unit,
)}
</span>
</div>
@@ -158,49 +127,30 @@ export default function PaymentDue({
<span>This includes:</span>
<ul className="flex flex-col items-start text-sm">
<li>- Train your abilities for the IELTS exam</li>
<li>
- Gain insights into your weaknesses and strengths
</li>
<li>
- Allow yourself to correctly prepare for the exam
</li>
<li>- Gain insights into your weaknesses and strengths</li>
<li>- Allow yourself to correctly prepare for the exam</li>
</ul>
</div>
</div>
))}
</PayPalScriptProvider>
</div>
</div>
)}
{!isIndividual() &&
user.type === "corporate" &&
user?.corporateInformation.payment && (
{!isIndividual() && user.type === "corporate" && user?.corporateInformation.payment && (
<div className="flex flex-col items-center">
<span className="max-w-lg">
To add to your use of EnCoach and that of your students and
teachers, please pay your designated package below:
To add to your use of EnCoach and that of your students and teachers, please pay your designated package below:
</span>
<div
className={clsx(
"flex flex-col items-start gap-6 rounded-xl bg-white p-4",
)}
>
<div className={clsx("flex flex-col items-start gap-6 rounded-xl bg-white p-4")}>
<div className="mb-2 flex flex-col items-start">
<img
src="/logo_title.png"
alt="EnCoach's Logo"
className="w-32"
/>
<span className="text-xl font-semibold">
EnCoach - {user.corporateInformation?.monthlyDuration}{" "}
Months
</span>
<img src="/logo_title.png" alt="EnCoach's Logo" className="w-32" />
<span className="text-xl font-semibold">EnCoach - {user.corporateInformation?.monthlyDuration} Months</span>
</div>
<div className="flex w-full flex-col items-start gap-2">
<span className="text-2xl">
{user.corporateInformation.payment.value}
{getSymbolFromCurrency(
user.corporateInformation.payment.currency,
)}
{getSymbolFromCurrency(user.corporateInformation.payment.currency)}
</span>
<PayPalPayment
key={clientID}
@@ -214,24 +164,18 @@ export default function PaymentDue({
setIsLoading(false);
setTimeout(reload, 500);
}}
loadScript
/>
</div>
<div className="flex flex-col items-start gap-1">
<span>This includes:</span>
<ul className="flex flex-col items-start text-sm">
<li>
- Allow a total of{" "}
{
user.corporateInformation.companyInformation
.userAmount
}{" "}
students and teachers to use EnCoach
- Allow a total of {user.corporateInformation.companyInformation.userAmount} students and teachers to
use EnCoach
</li>
<li>- Train their abilities for the IELTS exam</li>
<li>
- Gain insights into your students&apos; weaknesses
and strengths
</li>
<li>- Gain insights into your students&apos; weaknesses and strengths</li>
<li>- Allow them to correctly prepare for the exam</li>
</ul>
</div>
@@ -241,27 +185,22 @@ export default function PaymentDue({
{!isIndividual() && user.type !== "corporate" && (
<div className="flex flex-col items-center">
<span className="max-w-lg">
You are not the person in charge of your time credits, please
contact your administrator about this situation.
You are not the person in charge of your time credits, please contact your administrator about this situation.
</span>
<span className="max-w-lg">
If you believe this to be a mistake, please contact the
platform&apos;s administration, thank you for your patience.
If you believe this to be a mistake, please contact the platform&apos;s administration, thank you for your
patience.
</span>
</div>
)}
{!isIndividual() &&
user.type === "corporate" &&
!user.corporateInformation.payment && (
{!isIndividual() && user.type === "corporate" && !user.corporateInformation.payment && (
<div className="flex flex-col items-center">
<span className="max-w-lg">
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.
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.
</span>
<span className="max-w-lg">
Please try again later or contact your agent or an admin,
thank you for your patience.
Please try again later or contact your agent or an admin, thank you for your patience.
</span>
</div>
)}