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;
|
autorenewable: boolean;
|
||||||
error: string;
|
error: string;
|
||||||
links?: IPayPalLink[];
|
links?: IPayPalLink[];
|
||||||
|
stripe_status?: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -232,7 +232,9 @@ function App(): JSX.Element {
|
|||||||
<Route
|
<Route
|
||||||
path={routes.client.paymentResult()}
|
path={routes.client.paymentResult()}
|
||||||
element={<PaymentResultPage />}
|
element={<PaymentResultPage />}
|
||||||
/>
|
>
|
||||||
|
<Route path=":id" element={<PaymentResultPage />} />
|
||||||
|
</Route>
|
||||||
<Route
|
<Route
|
||||||
path={routes.client.paymentSuccess()}
|
path={routes.client.paymentSuccess()}
|
||||||
element={<PaymentSuccessPage />}
|
element={<PaymentSuccessPage />}
|
||||||
|
|||||||
@ -13,9 +13,13 @@ import { useNavigate } from "react-router-dom";
|
|||||||
|
|
||||||
interface ICheckoutFormProps {
|
interface ICheckoutFormProps {
|
||||||
children?: JSX.Element | null;
|
children?: JSX.Element | null;
|
||||||
|
subscriptionReceiptId?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function CheckoutForm({ children }: ICheckoutFormProps) {
|
export default function CheckoutForm({
|
||||||
|
children,
|
||||||
|
subscriptionReceiptId,
|
||||||
|
}: ICheckoutFormProps) {
|
||||||
const stripe = useStripe();
|
const stripe = useStripe();
|
||||||
const elements = useElements();
|
const elements = useElements();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
@ -28,7 +32,6 @@ export default function CheckoutForm({ children }: ICheckoutFormProps) {
|
|||||||
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
|
|
||||||
if (!stripe || !elements) {
|
if (!stripe || !elements) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -39,7 +42,7 @@ export default function CheckoutForm({ children }: ICheckoutFormProps) {
|
|||||||
const { error } = await stripe.confirmPayment({
|
const { error } = await stripe.confirmPayment({
|
||||||
elements,
|
elements,
|
||||||
confirmParams: {
|
confirmParams: {
|
||||||
return_url: `https://${window.location.host}/payment/result`,
|
return_url: `https://${window.location.host}/payment/result/${subscriptionReceiptId}`,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (error) {
|
if (error) {
|
||||||
@ -48,14 +51,12 @@ export default function CheckoutForm({ children }: ICheckoutFormProps) {
|
|||||||
dispatch(actions.status.update("subscribed"));
|
dispatch(actions.status.update("subscribed"));
|
||||||
navigate(routes.client.paymentSuccess());
|
navigate(routes.client.paymentSuccess());
|
||||||
}
|
}
|
||||||
} catch(error) {
|
} catch (error) {
|
||||||
console.log('error -> ', error);
|
console.log("error -> ", error);
|
||||||
setMessage("Oops! Something went wrong.");
|
setMessage("Oops! Something went wrong.");
|
||||||
} finally {
|
} finally {
|
||||||
setIsProcessing(false);
|
setIsProcessing(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -66,12 +67,18 @@ export default function CheckoutForm({ children }: ICheckoutFormProps) {
|
|||||||
>
|
>
|
||||||
{children ? children : null}
|
{children ? children : null}
|
||||||
<PaymentElement onReady={() => setFormReady(true)} />
|
<PaymentElement onReady={() => setFormReady(true)} />
|
||||||
<MainButton color="blue" disabled={isProcessing || !formReady} id="submit">
|
<MainButton
|
||||||
|
color="blue"
|
||||||
|
disabled={isProcessing || !formReady}
|
||||||
|
id="submit"
|
||||||
|
>
|
||||||
<span id="button-text">
|
<span id="button-text">
|
||||||
{isProcessing ? "Processing..." : "Pay now"}
|
{isProcessing ? "Processing..." : "Pay now"}
|
||||||
</span>
|
</span>
|
||||||
</MainButton>
|
</MainButton>
|
||||||
<Title variant="h5" style={{color: 'red'}}>{message}</Title>
|
<Title variant="h5" style={{ color: "red" }}>
|
||||||
|
{message}
|
||||||
|
</Title>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +1,91 @@
|
|||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import routes from "@/routes";
|
import routes from "@/routes";
|
||||||
import { useEffect } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useSearchParams } from "react-router-dom";
|
import { useSearchParams } from "react-router-dom";
|
||||||
import { useDispatch } from "react-redux";
|
import { useDispatch } from "react-redux";
|
||||||
import { actions } from "@/store";
|
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 {
|
function PaymentResultPage(): JSX.Element {
|
||||||
|
// const api = useApi();
|
||||||
|
// const { token } = useAuth();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
const status = searchParams.get("redirect_status");
|
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(() => {
|
useEffect(() => {
|
||||||
if (status === "succeeded") {
|
if (status === "succeeded") {
|
||||||
@ -19,7 +95,7 @@ function PaymentResultPage(): JSX.Element {
|
|||||||
return navigate(routes.client.paymentFail());
|
return navigate(routes.client.paymentFail());
|
||||||
}, [navigate, status, dispatch]);
|
}, [navigate, status, dispatch]);
|
||||||
|
|
||||||
return <></>;
|
return <div className={styles.page}>{isLoading && <Loader />}</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default PaymentResultPage;
|
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 { PaymentRequest } from "@stripe/stripe-js";
|
||||||
import { ISubscriptionPlan } from "@/api/resources/SubscriptionPlans";
|
import { ISubscriptionPlan } from "@/api/resources/SubscriptionPlans";
|
||||||
import styles from "./styles.module.css";
|
import styles from "./styles.module.css";
|
||||||
|
import { useDispatch } from "react-redux";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import routes from "@/routes";
|
||||||
|
|
||||||
interface ApplePayButtonProps {
|
interface ApplePayButtonProps {
|
||||||
activeSubPlan: ISubscriptionPlan | null;
|
activeSubPlan: ISubscriptionPlan | null;
|
||||||
client_secret: string;
|
client_secret: string;
|
||||||
|
subscriptionReceiptId?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ApplePayButton({ activeSubPlan, client_secret }: ApplePayButtonProps) {
|
function ApplePayButton({
|
||||||
|
activeSubPlan,
|
||||||
|
client_secret,
|
||||||
|
subscriptionReceiptId,
|
||||||
|
}: ApplePayButtonProps) {
|
||||||
const stripe = useStripe();
|
const stripe = useStripe();
|
||||||
const elements = useElements();
|
const elements = useElements();
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const navigate = useNavigate();
|
||||||
const [paymentRequest, setPaymentRequest] = useState<PaymentRequest | null>(
|
const [paymentRequest, setPaymentRequest] = useState<PaymentRequest | null>(
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
@ -63,13 +73,22 @@ function ApplePayButton({ activeSubPlan, client_secret }: ApplePayButtonProps) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
navigate(`${routes.client.paymentResult()}/${subscriptionReceiptId}`);
|
||||||
// Show a success message to your customer
|
// Show a success message to your customer
|
||||||
// There's a risk of the customer closing the window before callback
|
// There's a risk of the customer closing the window before callback
|
||||||
// execution. Set up a webhook or plugin to listen for the
|
// execution. Set up a webhook or plugin to listen for the
|
||||||
// payment_intent.succeeded event that handles any business critical
|
// payment_intent.succeeded event that handles any business critical
|
||||||
// post-payment actions.
|
// post-payment actions.
|
||||||
});
|
});
|
||||||
}, [activeSubPlan, client_secret, elements, stripe]);
|
}, [
|
||||||
|
activeSubPlan,
|
||||||
|
client_secret,
|
||||||
|
dispatch,
|
||||||
|
elements,
|
||||||
|
navigate,
|
||||||
|
stripe,
|
||||||
|
subscriptionReceiptId,
|
||||||
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@ -28,21 +28,12 @@ export function StripePage(): JSX.Element {
|
|||||||
useState<Promise<Stripe | null> | null>(null);
|
useState<Promise<Stripe | null> | null>(null);
|
||||||
const [subPlans, setSubPlans] = useState<ISubscriptionPlan[] | null>(null);
|
const [subPlans, setSubPlans] = useState<ISubscriptionPlan[] | null>(null);
|
||||||
const [clientSecret, setClientSecret] = useState<string>("");
|
const [clientSecret, setClientSecret] = useState<string>("");
|
||||||
|
const [subscriptionReceiptId, setSubscriptionReceiptId] =
|
||||||
|
useState<string>("");
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
if (!activeSubPlan) {
|
if (!activeSubPlan) {
|
||||||
navigate(routes.client.priceList());
|
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(() => {
|
useEffect(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
@ -59,26 +50,6 @@ export function StripePage(): JSX.Element {
|
|||||||
})();
|
})();
|
||||||
}, [activeSubPlan, api, locale, navigate]);
|
}, [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(() => {
|
useEffect(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const { subscription_receipt } = await api.createSubscriptionReceipt({
|
const { subscription_receipt } = await api.createSubscriptionReceipt({
|
||||||
@ -88,7 +59,9 @@ export function StripePage(): JSX.Element {
|
|||||||
sub_plan_id: activeSubPlan?.id || "stripe.7",
|
sub_plan_id: activeSubPlan?.id || "stripe.7",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const { id } = subscription_receipt;
|
||||||
const { client_secret } = subscription_receipt.data;
|
const { client_secret } = subscription_receipt.data;
|
||||||
|
setSubscriptionReceiptId(id);
|
||||||
setClientSecret(client_secret);
|
setClientSecret(client_secret);
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
})();
|
})();
|
||||||
@ -109,16 +82,17 @@ export function StripePage(): JSX.Element {
|
|||||||
<p className={styles.email}>{email}</p>
|
<p className={styles.email}>{email}</p>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{stripePromise && clientSecret && (
|
{stripePromise && clientSecret && subscriptionReceiptId && (
|
||||||
<Elements stripe={stripePromise} options={{ clientSecret }}>
|
<Elements stripe={stripePromise} options={{ clientSecret }}>
|
||||||
<ApplePayButton
|
<ApplePayButton
|
||||||
activeSubPlan={activeSubPlan}
|
activeSubPlan={activeSubPlan}
|
||||||
client_secret={clientSecret}
|
client_secret={clientSecret}
|
||||||
|
subscriptionReceiptId={subscriptionReceiptId}
|
||||||
/>
|
/>
|
||||||
{activeSubPlan && (
|
{activeSubPlan && (
|
||||||
<SubPlanInformation subPlan={activeSubPlan} subPlans={subPlans} />
|
<SubPlanInformation subPlan={activeSubPlan} subPlans={subPlans} />
|
||||||
)}
|
)}
|
||||||
<CheckoutForm></CheckoutForm>
|
<CheckoutForm subscriptionReceiptId={subscriptionReceiptId} />
|
||||||
</Elements>
|
</Elements>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
import Title from "@/components/Title";
|
// import Title from "@/components/Title";
|
||||||
import styles from "./styles.module.css";
|
import styles from "./styles.module.css";
|
||||||
import MainButton from "@/components/MainButton";
|
import MainButton from "@/components/MainButton";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import routes from "@/routes";
|
import routes from "@/routes";
|
||||||
import { useSelector } from "react-redux";
|
// import { useSelector } from "react-redux";
|
||||||
import { selectors } from "@/store";
|
// import { selectors } from "@/store";
|
||||||
|
|
||||||
function WorksForUsPage() {
|
function WorksForUsPage() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { relationshipProblem } = useSelector(selectors.selectQuestionnaire);
|
// const { relationshipProblem } = useSelector(selectors.selectQuestionnaire);
|
||||||
|
|
||||||
const handleBack = () => {
|
const handleBack = () => {
|
||||||
navigate(-1);
|
navigate(-1);
|
||||||
@ -22,7 +22,7 @@ function WorksForUsPage() {
|
|||||||
<section className={`${styles.page} page`}>
|
<section className={`${styles.page} page`}>
|
||||||
<img src="/starry_key.svg" alt="The starry key" />
|
<img src="/starry_key.svg" alt="The starry key" />
|
||||||
<div>
|
<div>
|
||||||
{relationshipProblem === "very_unhappy" && (
|
{/* {relationshipProblem === "very_unhappy" && (
|
||||||
<Title variant="h1" className={styles.title}>
|
<Title variant="h1" className={styles.title}>
|
||||||
We’ve got you covered! We’ll start with small, personalized insights
|
We’ve got you covered! We’ll start with small, personalized insights
|
||||||
into you and your partner’s personality traits.
|
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
|
<br /> Let's find out what's working (and what isn’t) and go from
|
||||||
there.
|
there.
|
||||||
</Title>
|
</Title>
|
||||||
)}
|
)} */}
|
||||||
<p className={styles.text}>
|
<p className={styles.text}>
|
||||||
Now, we need some information about{" "}
|
Now, we need some information about{" "}
|
||||||
<span className={styles.blue}>Your Partner’s Profile</span> to create
|
<span className={styles.blue}>Your Partner’s Profile</span> to create
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user