feat: add information of subscription plan on stripe page, fix private bug

This commit is contained in:
gofnnp 2023-11-16 05:00:46 +04:00
parent 8db05c3fd4
commit f355ff391c
8 changed files with 129 additions and 43 deletions

View File

@ -124,6 +124,18 @@ function App(): JSX.Element {
return (
<Routes>
<Route element={<Layout setIsSpecialOfferOpen={setIsSpecialOfferOpen} />}>
<Route
path={routes.client.paymentResult()}
element={<PaymentResultPage />}
/>
<Route
path={routes.client.paymentSuccess()}
element={<PaymentSuccessPage />}
/>
<Route
path={routes.client.paymentFail()}
element={<PaymentFailPage />}
/>
<Route element={<AuthorizedUserOutlet />}>
<Route path={routes.client.root()} element={<MainPage />} />
<Route path={routes.client.birthday()} element={<BirthdayPage />} />
@ -162,32 +174,20 @@ function App(): JSX.Element {
<Route path={routes.client.static()} element={<StaticPage />} />
<Route path={routes.client.priceList()} element={<PriceListPage />} />
{/* <Route
path={routes.client.wallpaper()}
element={<ProtectWallpaperPage />}
/> */}
path={routes.client.wallpaper()}
element={<ProtectWallpaperPage />}
/> */}
</Route>
<Route element={<PrivateOutlet />}>
<Route element={<AuthorizedUserOutlet />}>
<Route
path={routes.client.subscription()}
element={<SubscriptionPage />}
/>
<Route element={<PrivateOutlet />}>
<Route element={<AuthorizedUserOutlet />}>
<Route
path={routes.client.paymentMethod()}
element={<PaymentPage />}
/>
<Route
path={routes.client.paymentResult()}
element={<PaymentResultPage />}
/>
<Route
path={routes.client.paymentSuccess()}
element={<PaymentSuccessPage />}
/>
<Route
path={routes.client.paymentFail()}
element={<PaymentFailPage />}
/>
<Route
path={routes.client.paymentStripe()}
element={<StripePage />}

View File

@ -14,10 +14,10 @@ import routes from "@/routes";
import "./styles.css";
import Header from "../Header";
import { StripeButton } from "./methods/Stripe";
import { PayPalButton } from "./methods/PayPal/Button";
import { useAuth } from "@/auth";
import { useApi } from "@/api";
import { PayPalReceiptPayload } from "@/api/resources/UserSubscriptionReceipts";
// import { PayPalButton } from "./methods/PayPal/Button";
// import { useAuth } from "@/auth";
// import { useApi } from "@/api";
// import { PayPalReceiptPayload } from "@/api/resources/UserSubscriptionReceipts";
import { ISubscriptionPlan } from "@/api/resources/SubscriptionPlans";
const getPrice = (activeSubPlan: ISubscriptionPlan | null) => {
@ -32,8 +32,8 @@ const getPrice = (activeSubPlan: ISubscriptionPlan | null) => {
function PaymentPage(): JSX.Element {
const { t } = useTranslation();
const { applePay } = usePayment();
const api = useApi();
const { token } = useAuth();
// const api = useApi();
// const { token } = useAuth();
const [openErrorModal, setOpenErrorModal] = useState(false);
const navigate = useNavigate();
const isLoading = applePay === null;
@ -46,23 +46,23 @@ function PaymentPage(): JSX.Element {
navigate(routes.client.paymentStripe());
};
const navigateToPayPal = async () => {
const { subscription_receipt } = await api.createSubscriptionReceipt({
token,
itemInterval: "year",
way: "paypal",
subscription_receipt: {
sub_plan_id: activeSubPlan?.id || "",
},
} as PayPalReceiptPayload);
const url = subscription_receipt.data.links?.find(
(link) => link.rel === "approve"
)?.href;
if (!url?.length) {
return setOpenErrorModal(true);
}
window.location.href = url;
};
// const navigateToPayPal = async () => {
// const { subscription_receipt } = await api.createSubscriptionReceipt({
// token,
// itemInterval: "year",
// way: "paypal",
// subscription_receipt: {
// sub_plan_id: activeSubPlan?.id || "",
// },
// } as PayPalReceiptPayload);
// const url = subscription_receipt.data.links?.find(
// (link) => link.rel === "approve"
// )?.href;
// if (!url?.length) {
// return setOpenErrorModal(true);
// }
// window.location.href = url;
// };
return (
<>
@ -84,7 +84,7 @@ function PaymentPage(): JSX.Element {
{t("choose_payment")}
</Title>
<div className="payment-buttons-container">
<PayPalButton onClick={navigateToPayPal} />
{/* <PayPalButton onClick={navigateToPayPal} /> */}
<StripeButton onClick={navigateToStripe} />
</div>
<p className="payment-warining">

View File

@ -9,7 +9,11 @@ import {
import { useState } from "react";
import { useDispatch } from "react-redux";
export default function CheckoutForm() {
interface ICheckoutFormProps {
children?: JSX.Element | null;
}
export default function CheckoutForm({ children }: ICheckoutFormProps) {
const stripe = useStripe();
const elements = useElements();
const dispatch = useDispatch();
@ -46,6 +50,7 @@ export default function CheckoutForm() {
id="payment-form"
onSubmit={handleSubmit}
>
{children ? children : null}
<PaymentElement />
<MainButton color="blue" disabled={isProcessing} id="submit">
<span id="button-text">

View File

@ -10,6 +10,7 @@ import { useSelector } from "react-redux";
import { selectors } from "@/store";
import { useNavigate } from "react-router-dom";
import routes from "@/routes";
import SubPlanInformation from "../SubPlanInformation";
export function StripePage(): JSX.Element {
const api = useApi();
@ -55,7 +56,9 @@ export function StripePage(): JSX.Element {
) : null}
{stripePromise && clientSecret && (
<Elements stripe={stripePromise} options={{ clientSecret }}>
<CheckoutForm />
<CheckoutForm>
{activeSubPlan && <SubPlanInformation subPlan={activeSubPlan} />}
</CheckoutForm>
</Elements>
)}
</div>

View File

@ -0,0 +1,17 @@
import styles from "./styles.module.css";
import Title from "@/components/Title";
interface ITotalTodayProps {
total: string;
}
function TotalToday({ total }: ITotalTodayProps): JSX.Element {
return (
<div className={styles.container}>
<Title className={styles.text} variant="h3">{"Total today:"}</Title>
<Title className={styles.text} variant="h3">{total}</Title>
</div>
);
}
export default TotalToday;

View File

@ -0,0 +1,17 @@
.container {
width: 100%;
padding: 16px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
background-color: #e7f5ee;
border-radius: 7px;
}
.text {
font-size: 16px;
font-weight: 700;
color: #000;
margin: 0;
}

View File

@ -0,0 +1,28 @@
import { useTranslation } from "react-i18next";
import styles from "./styles.module.css";
import { ISubscriptionPlan } from "@/api/resources/SubscriptionPlans";
import TotalToday from "./TotalToday";
interface ISubPlanInformationProps {
subPlan: ISubscriptionPlan;
}
const getPrice = (plan: ISubscriptionPlan): string => {
return `$${(plan.trial?.price_cents || 0) / 100}`;
};
function SubPlanInformation({
subPlan,
}: ISubPlanInformationProps): JSX.Element {
const { t } = useTranslation();
return (
<div className={styles.container}>
<TotalToday total={getPrice(subPlan)} />
<p className={styles.description}>
{t("auweb.pay.information").replaceAll("%@", getPrice(subPlan))}
</p>
</div>
);
}
export default SubPlanInformation;

View File

@ -0,0 +1,16 @@
.container {
width: 100%;
max-width: 300px;
display: flex;
flex-direction: column;
gap: 20px;
}
.description {
font-size: 13px;
color: #666666;
text-align: left;
font-weight: 400;
line-height: 16px;
padding-bottom: 16px;
}