Merge branch 'clone' into 'main'
feat: questionnaire See merge request witapp/aura-webapp!25
This commit is contained in:
commit
212b7cbccb
@ -66,6 +66,7 @@ export interface SubscriptionReceipt {
|
||||
autorenewable: boolean;
|
||||
error: string;
|
||||
links?: IPayPalLink[];
|
||||
stripe_status?: string;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -232,7 +232,9 @@ function App(): JSX.Element {
|
||||
<Route
|
||||
path={routes.client.paymentResult()}
|
||||
element={<PaymentResultPage />}
|
||||
/>
|
||||
>
|
||||
<Route path=":id" element={<PaymentResultPage />} />
|
||||
</Route>
|
||||
<Route
|
||||
path={routes.client.paymentSuccess()}
|
||||
element={<PaymentSuccessPage />}
|
||||
|
||||
@ -13,9 +13,13 @@ import { useNavigate } from "react-router-dom";
|
||||
|
||||
interface ICheckoutFormProps {
|
||||
children?: JSX.Element | null;
|
||||
subscriptionReceiptId?: string;
|
||||
}
|
||||
|
||||
export default function CheckoutForm({ children }: ICheckoutFormProps) {
|
||||
export default function CheckoutForm({
|
||||
children,
|
||||
subscriptionReceiptId,
|
||||
}: ICheckoutFormProps) {
|
||||
const stripe = useStripe();
|
||||
const elements = useElements();
|
||||
const dispatch = useDispatch();
|
||||
@ -28,7 +32,6 @@ export default function CheckoutForm({ children }: ICheckoutFormProps) {
|
||||
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
|
||||
|
||||
if (!stripe || !elements) {
|
||||
return;
|
||||
}
|
||||
@ -39,7 +42,7 @@ export default function CheckoutForm({ children }: ICheckoutFormProps) {
|
||||
const { error } = await stripe.confirmPayment({
|
||||
elements,
|
||||
confirmParams: {
|
||||
return_url: `https://${window.location.host}/payment/result`,
|
||||
return_url: `https://${window.location.host}/payment/result/${subscriptionReceiptId}`,
|
||||
},
|
||||
});
|
||||
if (error) {
|
||||
@ -48,14 +51,12 @@ export default function CheckoutForm({ children }: ICheckoutFormProps) {
|
||||
dispatch(actions.status.update("subscribed"));
|
||||
navigate(routes.client.paymentSuccess());
|
||||
}
|
||||
} catch(error) {
|
||||
console.log('error -> ', error);
|
||||
} catch (error) {
|
||||
console.log("error -> ", error);
|
||||
setMessage("Oops! Something went wrong.");
|
||||
} finally {
|
||||
} finally {
|
||||
setIsProcessing(false);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
@ -66,12 +67,18 @@ export default function CheckoutForm({ children }: ICheckoutFormProps) {
|
||||
>
|
||||
{children ? children : null}
|
||||
<PaymentElement onReady={() => setFormReady(true)} />
|
||||
<MainButton color="blue" disabled={isProcessing || !formReady} id="submit">
|
||||
<MainButton
|
||||
color="blue"
|
||||
disabled={isProcessing || !formReady}
|
||||
id="submit"
|
||||
>
|
||||
<span id="button-text">
|
||||
{isProcessing ? "Processing..." : "Pay now"}
|
||||
</span>
|
||||
</MainButton>
|
||||
<Title variant="h5" style={{color: 'red'}}>{message}</Title>
|
||||
<Title variant="h5" style={{ color: "red" }}>
|
||||
{message}
|
||||
</Title>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,15 +1,91 @@
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import routes from "@/routes";
|
||||
import { useEffect } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useSearchParams } from "react-router-dom";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { actions } from "@/store";
|
||||
// import { SubscriptionReceipts, useApi, useApiCall } from "@/api";
|
||||
// import { useAuth } from "@/auth";
|
||||
import styles from "./styles.module.css";
|
||||
import Loader from "@/components/Loader";
|
||||
|
||||
function PaymentResultPage(): JSX.Element {
|
||||
// const api = useApi();
|
||||
// const { token } = useAuth();
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
const [searchParams] = useSearchParams();
|
||||
const status = searchParams.get("redirect_status");
|
||||
status;
|
||||
// const { id } = useParams();
|
||||
// const requestTimeOutRef = useRef<NodeJS.Timeout>();
|
||||
const [isLoading] = useState(true);
|
||||
// const [subscriptionReceipt, setSubscriptionReceipt] =
|
||||
// useState<SubscriptionReceipts.SubscriptionReceipt>();
|
||||
|
||||
// const loadData = useCallback(async () => {
|
||||
// if (!id) {
|
||||
// return null;
|
||||
// }
|
||||
// const getSubscriptionReceiptStatus = async () => {
|
||||
// const { subscription_receipt } = await api.getSubscriptionReceipt({
|
||||
// token,
|
||||
// id,
|
||||
// });
|
||||
// const { stripe_status } = subscription_receipt.data;
|
||||
// if (stripe_status === "incomplete") {
|
||||
// requestTimeOutRef.current = setTimeout(
|
||||
// getSubscriptionReceiptStatus,
|
||||
// 3000
|
||||
// );
|
||||
// }
|
||||
// setSubscriptionReceipt(subscription_receipt);
|
||||
// return { subscription_receipt };
|
||||
// };
|
||||
// return getSubscriptionReceiptStatus();
|
||||
// }, [api, id, token]);
|
||||
|
||||
// useApiCall<SubscriptionReceipts.Response | null>(loadData);
|
||||
|
||||
// useEffect(() => {
|
||||
// if (!subscriptionReceipt) {
|
||||
// if (id?.length) return;
|
||||
// return () => {
|
||||
// if (requestTimeOutRef.current) {
|
||||
// clearTimeout(requestTimeOutRef.current);
|
||||
// }
|
||||
// navigate(routes.client.paymentFail());
|
||||
// };
|
||||
// }
|
||||
// const { stripe_status } = subscriptionReceipt.data;
|
||||
// if (stripe_status === "succeeded") {
|
||||
// dispatch(actions.status.update("subscribed"));
|
||||
// setIsLoading(false);
|
||||
// return () => {
|
||||
// if (requestTimeOutRef.current) {
|
||||
// clearTimeout(requestTimeOutRef.current);
|
||||
// }
|
||||
// navigate(routes.client.paymentSuccess());
|
||||
// };
|
||||
// } else if (stripe_status === "payment_failed") {
|
||||
// setIsLoading(false);
|
||||
|
||||
// return () => {
|
||||
// if (requestTimeOutRef.current) {
|
||||
// clearTimeout(requestTimeOutRef.current);
|
||||
// }
|
||||
// navigate(routes.client.paymentFail());
|
||||
// };
|
||||
// }
|
||||
// }, [dispatch, id, navigate, subscriptionReceipt]);
|
||||
|
||||
// useEffect(() => {
|
||||
// return () => {
|
||||
// if (requestTimeOutRef.current) {
|
||||
// clearTimeout(requestTimeOutRef.current);
|
||||
// }
|
||||
// };
|
||||
// }, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (status === "succeeded") {
|
||||
@ -19,7 +95,7 @@ function PaymentResultPage(): JSX.Element {
|
||||
return navigate(routes.client.paymentFail());
|
||||
}, [navigate, status, dispatch]);
|
||||
|
||||
return <></>;
|
||||
return <div className={styles.page}>{isLoading && <Loader />}</div>;
|
||||
}
|
||||
|
||||
export default PaymentResultPage;
|
||||
|
||||
15
src/components/PaymentPage/results/styles.module.css
Normal file
15
src/components/PaymentPage/results/styles.module.css
Normal file
@ -0,0 +1,15 @@
|
||||
.page {
|
||||
position: relative;
|
||||
height: fit-content;
|
||||
min-height: calc(100vh - 103px);
|
||||
flex: auto;
|
||||
/* max-height: -webkit-fill-available; */
|
||||
color: #fff;
|
||||
overflow-y: scroll;
|
||||
padding-bottom: 180px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
@ -7,15 +7,25 @@ import {
|
||||
import { PaymentRequest } from "@stripe/stripe-js";
|
||||
import { ISubscriptionPlan } from "@/api/resources/SubscriptionPlans";
|
||||
import styles from "./styles.module.css";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import routes from "@/routes";
|
||||
|
||||
interface ApplePayButtonProps {
|
||||
activeSubPlan: ISubscriptionPlan | null;
|
||||
client_secret: string;
|
||||
subscriptionReceiptId?: string;
|
||||
}
|
||||
|
||||
function ApplePayButton({ activeSubPlan, client_secret }: ApplePayButtonProps) {
|
||||
function ApplePayButton({
|
||||
activeSubPlan,
|
||||
client_secret,
|
||||
subscriptionReceiptId,
|
||||
}: ApplePayButtonProps) {
|
||||
const stripe = useStripe();
|
||||
const elements = useElements();
|
||||
const dispatch = useDispatch();
|
||||
const navigate = useNavigate();
|
||||
const [paymentRequest, setPaymentRequest] = useState<PaymentRequest | null>(
|
||||
null
|
||||
);
|
||||
@ -63,13 +73,22 @@ function ApplePayButton({ activeSubPlan, client_secret }: ApplePayButtonProps) {
|
||||
return;
|
||||
}
|
||||
|
||||
navigate(`${routes.client.paymentResult()}/${subscriptionReceiptId}`);
|
||||
// Show a success message to your customer
|
||||
// There's a risk of the customer closing the window before callback
|
||||
// execution. Set up a webhook or plugin to listen for the
|
||||
// payment_intent.succeeded event that handles any business critical
|
||||
// post-payment actions.
|
||||
});
|
||||
}, [activeSubPlan, client_secret, elements, stripe]);
|
||||
}, [
|
||||
activeSubPlan,
|
||||
client_secret,
|
||||
dispatch,
|
||||
elements,
|
||||
navigate,
|
||||
stripe,
|
||||
subscriptionReceiptId,
|
||||
]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@ -28,21 +28,12 @@ export function StripePage(): JSX.Element {
|
||||
useState<Promise<Stripe | null> | null>(null);
|
||||
const [subPlans, setSubPlans] = useState<ISubscriptionPlan[] | null>(null);
|
||||
const [clientSecret, setClientSecret] = useState<string>("");
|
||||
const [subscriptionReceiptId, setSubscriptionReceiptId] =
|
||||
useState<string>("");
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
if (!activeSubPlan) {
|
||||
navigate(routes.client.priceList());
|
||||
}
|
||||
// const timeoutRef = useRef<NodeJS.Timeout>();
|
||||
|
||||
// const appleReceipt = async () => {
|
||||
// const { subscription_receipt } = await api.createSubscriptionReceipt({
|
||||
// token,
|
||||
// receiptData: "",
|
||||
// autorenewable: true,
|
||||
// sandbox: true,
|
||||
// });
|
||||
// console.log(subscription_receipt);
|
||||
// };
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
@ -59,26 +50,6 @@ export function StripePage(): JSX.Element {
|
||||
})();
|
||||
}, [activeSubPlan, api, locale, navigate]);
|
||||
|
||||
// useEffect(() => {
|
||||
// timeoutRef.current = setTimeout(async () => {
|
||||
// const { subscription_receipt } = await api.createSubscriptionReceipt({
|
||||
// token,
|
||||
// way: "stripe",
|
||||
// subscription_receipt: {
|
||||
// sub_plan_id: activeSubPlan?.id || "stripe.7",
|
||||
// },
|
||||
// });
|
||||
// const { client_secret } = subscription_receipt.data;
|
||||
// setClientSecret(client_secret);
|
||||
// setIsLoading(false);
|
||||
// }, 4000);
|
||||
// return () => {
|
||||
// if (timeoutRef.current) {
|
||||
// clearTimeout(timeoutRef.current);
|
||||
// }
|
||||
// };
|
||||
// }, [api, token]);
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
const { subscription_receipt } = await api.createSubscriptionReceipt({
|
||||
@ -88,7 +59,9 @@ export function StripePage(): JSX.Element {
|
||||
sub_plan_id: activeSubPlan?.id || "stripe.7",
|
||||
},
|
||||
});
|
||||
const { id } = subscription_receipt;
|
||||
const { client_secret } = subscription_receipt.data;
|
||||
setSubscriptionReceiptId(id);
|
||||
setClientSecret(client_secret);
|
||||
setIsLoading(false);
|
||||
})();
|
||||
@ -109,16 +82,17 @@ export function StripePage(): JSX.Element {
|
||||
<p className={styles.email}>{email}</p>
|
||||
</>
|
||||
)}
|
||||
{stripePromise && clientSecret && (
|
||||
{stripePromise && clientSecret && subscriptionReceiptId && (
|
||||
<Elements stripe={stripePromise} options={{ clientSecret }}>
|
||||
<ApplePayButton
|
||||
activeSubPlan={activeSubPlan}
|
||||
client_secret={clientSecret}
|
||||
subscriptionReceiptId={subscriptionReceiptId}
|
||||
/>
|
||||
{activeSubPlan && (
|
||||
<SubPlanInformation subPlan={activeSubPlan} subPlans={subPlans} />
|
||||
)}
|
||||
<CheckoutForm></CheckoutForm>
|
||||
<CheckoutForm subscriptionReceiptId={subscriptionReceiptId} />
|
||||
</Elements>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
import Title from "@/components/Title";
|
||||
// import Title from "@/components/Title";
|
||||
import styles from "./styles.module.css";
|
||||
import MainButton from "@/components/MainButton";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import routes from "@/routes";
|
||||
import { useSelector } from "react-redux";
|
||||
import { selectors } from "@/store";
|
||||
// import { useSelector } from "react-redux";
|
||||
// import { selectors } from "@/store";
|
||||
|
||||
function WorksForUsPage() {
|
||||
const navigate = useNavigate();
|
||||
const { relationshipProblem } = useSelector(selectors.selectQuestionnaire);
|
||||
// const { relationshipProblem } = useSelector(selectors.selectQuestionnaire);
|
||||
|
||||
const handleBack = () => {
|
||||
navigate(-1);
|
||||
@ -22,7 +22,7 @@ function WorksForUsPage() {
|
||||
<section className={`${styles.page} page`}>
|
||||
<img src="/starry_key.svg" alt="The starry key" />
|
||||
<div>
|
||||
{relationshipProblem === "very_unhappy" && (
|
||||
{/* {relationshipProblem === "very_unhappy" && (
|
||||
<Title variant="h1" className={styles.title}>
|
||||
We’ve got you covered! We’ll start with small, personalized insights
|
||||
into you and your partner’s personality traits.
|
||||
@ -40,7 +40,7 @@ function WorksForUsPage() {
|
||||
<br /> Let's find out what's working (and what isn’t) and go from
|
||||
there.
|
||||
</Title>
|
||||
)}
|
||||
)} */}
|
||||
<p className={styles.text}>
|
||||
Now, we need some information about{" "}
|
||||
<span className={styles.blue}>Your Partner’s Profile</span> to create
|
||||
|
||||
Loading…
Reference in New Issue
Block a user