add key of product

This commit is contained in:
gofnnp 2024-04-05 18:42:11 +04:00
parent c2c1f5a31c
commit e2a230af88
8 changed files with 138 additions and 55 deletions

View File

@ -7,6 +7,11 @@ interface Payload {
export type PayloadGet = Payload; export type PayloadGet = Payload;
export interface IPaymentInfo {
productId: string;
key: string;
}
export interface PayloadPost extends Payload { export interface PayloadPost extends Payload {
data: { data: {
user: { user: {
@ -21,9 +26,7 @@ export interface PayloadPost extends Payload {
sign: string | null; sign: string | null;
age: number | null; age: number | null;
}; };
paymentInfo: { paymentInfo: IPaymentInfo;
productId: string;
};
return_url: string; return_url: string;
}; };
} }

View File

@ -48,9 +48,14 @@ function AddConsultationPage() {
const handleClick = async () => { const handleClick = async () => {
if (!userFromStore || !currentProduct) return; if (!userFromStore || !currentProduct) return;
setIsLoading(true); setIsLoading(true);
const { productId, key } = currentProduct;
const paymentInfo = {
productId,
key,
};
const paymentIntent = await createSinglePayment( const paymentIntent = await createSinglePayment(
userFromStore, userFromStore,
currentProduct.productId, paymentInfo,
tokenFromStore, tokenFromStore,
userFromStore.email, userFromStore.email,
userFromStore.profile.full_name, userFromStore.profile.full_name,

View File

@ -53,9 +53,14 @@ function AddReportPage() {
const currentProduct = getCurrentProduct(activeOffer?.productKey); const currentProduct = getCurrentProduct(activeOffer?.productKey);
if (!currentProduct) return; if (!currentProduct) return;
setIsLoading(true); setIsLoading(true);
const { productId, key } = currentProduct;
const paymentInfo = {
productId,
key,
};
const paymentIntent = await createSinglePayment( const paymentIntent = await createSinglePayment(
userFromStore, userFromStore,
currentProduct.productId, paymentInfo,
tokenFromStore, tokenFromStore,
userFromStore.email, userFromStore.email,
userFromStore.profile.full_name, userFromStore.profile.full_name,

View File

@ -63,9 +63,14 @@ function UnlimitedReadingsPage() {
const handleClick = async () => { const handleClick = async () => {
if (!userFromStore || !currentProduct) return; if (!userFromStore || !currentProduct) return;
setIsLoading(true); setIsLoading(true);
const { productId, key } = currentProduct;
const paymentInfo = {
productId,
key,
};
const paymentIntent = await createSinglePayment( const paymentIntent = await createSinglePayment(
userFromStore, userFromStore,
currentProduct.productId, paymentInfo,
tokenFromStore, tokenFromStore,
userFromStore.email, userFromStore.email,
userFromStore.profile.full_name, userFromStore.profile.full_name,

View File

@ -138,10 +138,14 @@ function PaymentWithEmailPage() {
} }
setCurrentProduct(currentProduct); setCurrentProduct(currentProduct);
const { productId } = currentProduct; const { productId, key } = currentProduct;
const paymentInfo = {
productId,
key,
};
const paymentIntent = await createSinglePayment( const paymentIntent = await createSinglePayment(
user, user,
productId, paymentInfo,
token, token,
email, email,
name, name,
@ -171,10 +175,14 @@ function PaymentWithEmailPage() {
} }
setCurrentProduct(currentProduct); setCurrentProduct(currentProduct);
const { productId } = currentProduct; const { productId, key } = currentProduct;
const paymentInfo = {
productId,
key,
};
const paymentIntent = await createSinglePayment( const paymentIntent = await createSinglePayment(
userFromStore, userFromStore,
productId, paymentInfo,
tokenFromStore, tokenFromStore,
userFromStore.email, userFromStore.email,
userFromStore.profile.full_name, userFromStore.profile.full_name,

View File

@ -1,17 +1,18 @@
import React from "react"; import React from "react";
import { useNavigate } from 'react-router-dom'; import { useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { Elements } from "@stripe/react-stripe-js"; import { Elements } from "@stripe/react-stripe-js";
import { Stripe, loadStripe } from "@stripe/stripe-js"; import { Stripe, loadStripe } from "@stripe/stripe-js";
import './discount-screen.css'; import "./discount-screen.css";
import routes from '@/routes'; import routes from "@/routes";
import { useApi } from "@/api"; import { useApi } from "@/api";
import { useAuth } from "@/auth"; import { useAuth } from "@/auth";
import HeaderLogo from '@/components/palmistry/header-logo/header-logo'; import HeaderLogo from "@/components/palmistry/header-logo/header-logo";
import CheckoutForm from "@/components/PaymentPage/methods/Stripe/CheckoutForm"; import CheckoutForm from "@/components/PaymentPage/methods/Stripe/CheckoutForm";
import { ResponseGet } from "@/api/resources/SinglePayment";
const currentProductKey = "skip.trial.subscription.aura"; const currentProductKey = "skip.trial.subscription.aura";
const returnUrl = `${window.location.host}/palmistry/premium-bundle`; const returnUrl = `${window.location.host}/palmistry/premium-bundle`;
@ -23,10 +24,11 @@ export default function DiscountScreen() {
const { i18n } = useTranslation(); const { i18n } = useTranslation();
const locale = i18n.language; const locale = i18n.language;
const [price, setPrice] = React.useState(''); const [price, setPrice] = React.useState("");
const [isSuccess] = React.useState(false); const [isSuccess] = React.useState(false);
const [stripePromise, setStripePromise] = React.useState<Promise<Stripe | null> | null>(null); const [stripePromise, setStripePromise] =
const [productId, setProductId] = React.useState(''); React.useState<Promise<Stripe | null> | null>(null);
const [product, setProduct] = React.useState<ResponseGet>();
const [clientSecret, setClientSecret] = React.useState<string | null>(null); const [clientSecret, setClientSecret] = React.useState<string | null>(null);
const [stripePublicKey, setStripePublicKey] = React.useState<string>(""); const [stripePublicKey, setStripePublicKey] = React.useState<string>("");
@ -43,18 +45,22 @@ export default function DiscountScreen() {
setPrice((plan?.price_cents / 100).toFixed(2)); setPrice((plan?.price_cents / 100).toFixed(2));
})(); })();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []); }, []);
React.useEffect(() => { React.useEffect(() => {
(async () => { (async () => {
const products = await api.getSinglePaymentProducts({ token }); const products = await api.getSinglePaymentProducts({ token });
const product = products.find((product) => product.key === currentProductKey); const product = products.find(
(product) => product.key === currentProductKey
);
if (product) { if (product) {
setProductId(product.productId); setProduct(product);
} }
})(); })();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []); }, []);
React.useEffect(() => { React.useEffect(() => {
@ -64,7 +70,13 @@ export default function DiscountScreen() {
}, [stripePublicKey]); }, [stripePublicKey]);
const buy = async () => { const buy = async () => {
if (!user?.id) return; if (!user?.id || !product) return;
const { productId, key } = product;
const paymentInfo = {
productId,
key,
};
const response = await api.createSinglePayment({ const response = await api.createSinglePayment({
token: token, token: token,
@ -80,16 +92,18 @@ export default function DiscountScreen() {
sign: "", sign: "",
age: 0, age: 0,
}, },
paymentInfo: { paymentInfo,
productId,
},
return_url: returnUrl, return_url: returnUrl,
}, },
}); });
if ('paymentIntent' in response && response.paymentIntent.status === "paid" || 'payment' in response && response.payment.status === "paid") { if (
("paymentIntent" in response &&
response.paymentIntent.status === "paid") ||
("payment" in response && response.payment.status === "paid")
) {
goPremiumBundle(); goPremiumBundle();
} else if ('paymentIntent' in response) { } else if ("paymentIntent" in response) {
setClientSecret(response.paymentIntent.data.client_secret); setClientSecret(response.paymentIntent.data.client_secret);
setStripePublicKey(response.paymentIntent.data.public_key); setStripePublicKey(response.paymentIntent.data.public_key);
} }
@ -108,10 +122,14 @@ export default function DiscountScreen() {
<div className="discount-screen__blocks"> <div className="discount-screen__blocks">
<section className="discount-screen__block"> <section className="discount-screen__block">
<span className="discount-screen__price-block">19 for <br /> 1-week plan</span> <span className="discount-screen__price-block">
19 for <br /> 1-week plan
</span>
<div className="discount-screen__details"> <div className="discount-screen__details">
<span className="discount-screen__details-name">Total savings</span> <span className="discount-screen__details-name">
Total savings
</span>
<span className="discount-screen__details-value">0</span> <span className="discount-screen__details-value">0</span>
</div> </div>
@ -120,7 +138,11 @@ export default function DiscountScreen() {
<span className="discount-screen__details-value">yes</span> <span className="discount-screen__details-value">yes</span>
</div> </div>
<button className="discount-screen__button" style={{ minHeight: '38px' }} onClick={goPremiumBundle}> <button
className="discount-screen__button"
style={{ minHeight: "38px" }}
onClick={goPremiumBundle}
>
Start trial Start trial
</button> </button>
</section> </section>
@ -128,10 +150,14 @@ export default function DiscountScreen() {
<section className="discount-screen__block"> <section className="discount-screen__block">
<div className="discount-screen__header-block">save 33%</div> <div className="discount-screen__header-block">save 33%</div>
<span className="discount-screen__price-block">{price} for <br /> 1-week plan</span> <span className="discount-screen__price-block">
{price} for <br /> 1-week plan
</span>
<div className="discount-screen__details"> <div className="discount-screen__details">
<span className="discount-screen__details-name">Total savings</span> <span className="discount-screen__details-name">
Total savings
</span>
<span className="discount-screen__details-value">6.27</span> <span className="discount-screen__details-value">6.27</span>
</div> </div>
@ -148,7 +174,11 @@ export default function DiscountScreen() {
</div> </div>
{stripePromise && clientSecret && ( {stripePromise && clientSecret && (
<div className={`discount-screen__widget${isSuccess ? " discount-screen__widget_success" : ""}`}> <div
className={`discount-screen__widget${
isSuccess ? " discount-screen__widget_success" : ""
}`}
>
<Elements stripe={stripePromise} options={{ clientSecret }}> <Elements stripe={stripePromise} options={{ clientSecret }}>
<CheckoutForm returnUrl={returnUrl} /> <CheckoutForm returnUrl={returnUrl} />
</Elements> </Elements>
@ -168,7 +198,9 @@ export default function DiscountScreen() {
/> />
</svg> </svg>
<div className="discount-screen__success-text">Payment success</div> <div className="discount-screen__success-text">
Payment success
</div>
</div> </div>
)} )}
</div> </div>

View File

@ -1,16 +1,17 @@
import React from "react"; import React from "react";
import { useNavigate } from 'react-router-dom'; import { useNavigate } from "react-router-dom";
import { Elements } from "@stripe/react-stripe-js"; import { Elements } from "@stripe/react-stripe-js";
import { Stripe, loadStripe } from "@stripe/stripe-js"; import { Stripe, loadStripe } from "@stripe/stripe-js";
import './premium-bundle-screen.css'; import "./premium-bundle-screen.css";
import routes from '@/routes'; import routes from "@/routes";
import HeaderLogo from '@/components/palmistry/header-logo/header-logo'; import HeaderLogo from "@/components/palmistry/header-logo/header-logo";
import { useApi } from '@/api'; import { useApi } from "@/api";
import { useAuth } from "@/auth"; import { useAuth } from "@/auth";
import CheckoutForm from "@/components/PaymentPage/methods/Stripe/CheckoutForm"; import CheckoutForm from "@/components/PaymentPage/methods/Stripe/CheckoutForm";
import { ResponseGet } from "@/api/resources/SinglePayment";
const currentProductKey = "premium.bundle.aura"; const currentProductKey = "premium.bundle.aura";
const returnUrl = window.location.host; const returnUrl = window.location.host;
@ -20,8 +21,9 @@ export default function PremiumBundleScreen() {
const { token, user } = useAuth(); const { token, user } = useAuth();
const api = useApi(); const api = useApi();
const [stripePromise, setStripePromise] = React.useState<Promise<Stripe | null> | null>(null); const [stripePromise, setStripePromise] =
const [productId, setProductId] = React.useState(''); React.useState<Promise<Stripe | null> | null>(null);
const [product, setProduct] = React.useState<ResponseGet>();
const [isSuccess] = React.useState(false); const [isSuccess] = React.useState(false);
const [clientSecret, setClientSecret] = React.useState<string | null>(null); const [clientSecret, setClientSecret] = React.useState<string | null>(null);
const [stripePublicKey, setStripePublicKey] = React.useState<string>(""); const [stripePublicKey, setStripePublicKey] = React.useState<string>("");
@ -30,12 +32,15 @@ export default function PremiumBundleScreen() {
(async () => { (async () => {
const products = await api.getSinglePaymentProducts({ token }); const products = await api.getSinglePaymentProducts({ token });
const product = products.find((product) => product.key === currentProductKey); const product = products.find(
(product) => product.key === currentProductKey
);
if (product) { if (product) {
setProductId(product.productId); setProduct(product);
} }
})(); })();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []); }, []);
React.useEffect(() => { React.useEffect(() => {
@ -45,7 +50,9 @@ export default function PremiumBundleScreen() {
}, [stripePublicKey]); }, [stripePublicKey]);
const buy = async () => { const buy = async () => {
if (!user?.id) return; if (!user?.id || !product) return;
const { productId, key } = product;
const response = await api.createSinglePayment({ const response = await api.createSinglePayment({
token: token, token: token,
@ -63,14 +70,19 @@ export default function PremiumBundleScreen() {
}, },
paymentInfo: { paymentInfo: {
productId, productId,
key,
}, },
return_url: returnUrl, return_url: returnUrl,
}, },
}); });
if ('paymentIntent' in response && response.paymentIntent.status === "paid" || 'payment' in response && response.payment.status === "paid") { if (
("paymentIntent" in response &&
response.paymentIntent.status === "paid") ||
("payment" in response && response.payment.status === "paid")
) {
goHome(); goHome();
} else if ('paymentIntent' in response) { } else if ("paymentIntent" in response) {
setClientSecret(response.paymentIntent.data.client_secret); setClientSecret(response.paymentIntent.data.client_secret);
setStripePublicKey(response.paymentIntent.data.public_key); setStripePublicKey(response.paymentIntent.data.public_key);
} }
@ -87,9 +99,13 @@ export default function PremiumBundleScreen() {
</div> </div>
<div className="premium-bundle-screen__content"> <div className="premium-bundle-screen__content">
<button className="premium-bundle-screen__button-skip" onClick={goHome}>Skip &gt;</button> <button className="premium-bundle-screen__button-skip" onClick={goHome}>
Skip &gt;
</button>
<span className="premium-bundle-screen__title">Get extra insights with our Premium Bundle</span> <span className="premium-bundle-screen__title">
Get extra insights with our Premium Bundle
</span>
<span className="premium-bundle-screen__subtitle"> <span className="premium-bundle-screen__subtitle">
Exclusive offer: recommended for get more insights about what future Exclusive offer: recommended for get more insights about what future
@ -97,7 +113,9 @@ export default function PremiumBundleScreen() {
</span> </span>
<div className="premium-bundle-screen__block-description"> <div className="premium-bundle-screen__block-description">
<span className="premium-bundle-screen__list-title">What your Premium Bundle will include:</span> <span className="premium-bundle-screen__list-title">
What your Premium Bundle will include:
</span>
<div className="premium-bundle-screen__item"> <div className="premium-bundle-screen__item">
<div className="premium-bundle-screen__icon"> <div className="premium-bundle-screen__icon">
@ -180,7 +198,9 @@ export default function PremiumBundleScreen() {
</div> </div>
<div className="premium-bundle-screen__subsection"> <div className="premium-bundle-screen__subsection">
<span className="premium-bundle-screen__one-time-price">One-time price of 19!</span> <span className="premium-bundle-screen__one-time-price">
One-time price of 19!
</span>
<p>Original price is 45. Save 58%!</p> <p>Original price is 45. Save 58%!</p>
</div> </div>
@ -202,7 +222,7 @@ export default function PremiumBundleScreen() {
viewBox="0 0 13 16" viewBox="0 0 13 16"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
> >
<path d="M11.5556 6.24219H1.44444C0.6467 6.24219 0 6.97481 0 7.87855V13.6058C0 14.5096 0.6467 15.2422 1.44444 15.2422H11.5556C12.3533 15.2422 13 14.5096 13 13.6058V7.87855C13 6.97481 12.3533 6.24219 11.5556 6.24219Z"/> <path d="M11.5556 6.24219H1.44444C0.6467 6.24219 0 6.97481 0 7.87855V13.6058C0 14.5096 0.6467 15.2422 1.44444 15.2422H11.5556C12.3533 15.2422 13 14.5096 13 13.6058V7.87855C13 6.97481 12.3533 6.24219 11.5556 6.24219Z" />
<path <path
fillRule="evenodd" fillRule="evenodd"
clipRule="evenodd" clipRule="evenodd"
@ -214,7 +234,11 @@ export default function PremiumBundleScreen() {
</div> </div>
{stripePromise && clientSecret && ( {stripePromise && clientSecret && (
<div className={`discount-screen__widget${isSuccess ? " discount-screen__widget_success" : ""}`}> <div
className={`discount-screen__widget${
isSuccess ? " discount-screen__widget_success" : ""
}`}
>
<Elements stripe={stripePromise} options={{ clientSecret }}> <Elements stripe={stripePromise} options={{ clientSecret }}>
<CheckoutForm returnUrl={returnUrl} /> <CheckoutForm returnUrl={returnUrl} />
</Elements> </Elements>
@ -234,7 +258,9 @@ export default function PremiumBundleScreen() {
/> />
</svg> </svg>
<div className="discount-screen__success-text">Payment success</div> <div className="discount-screen__success-text">
Payment success
</div>
</div> </div>
)} )}
</div> </div>

View File

@ -1,10 +1,11 @@
import { User } from "@/api/resources/User"; import { User } from "@/api/resources/User";
import { getZodiacSignByDate } from "../zodiac-sign"; import { getZodiacSignByDate } from "../zodiac-sign";
import { ApiContextValue } from "@/api"; import { ApiContextValue } from "@/api";
import { IPaymentInfo } from "@/api/resources/SinglePayment";
export const createSinglePayment = async ( export const createSinglePayment = async (
user: User, user: User,
productId: string, paymentInfo: IPaymentInfo,
token: string, token: string,
email: string, email: string,
name: string | null, name: string | null,
@ -28,9 +29,7 @@ export const createSinglePayment = async (
sign: "partner_cancer", sign: "partner_cancer",
age: 26, age: 26,
}, },
paymentInfo: { paymentInfo,
productId,
},
return_url: returnUrl, return_url: returnUrl,
}, },
}); });