mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-29 00:20:04 +01:00
web: show success on checkout completion
This commit is contained in:
committed by
Abdullah Atta
parent
6d3e985c9d
commit
dd368a4170
@@ -55,6 +55,8 @@ export function BuyDialog(props: BuyDialogProps) {
|
||||
const theme = useTheme() as Theme;
|
||||
|
||||
const onApplyCoupon = useCheckoutStore((store) => store.applyCoupon);
|
||||
const isCheckoutCompleted = useCheckoutStore((store) => store.isCompleted);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
useCheckoutStore.getState().reset();
|
||||
@@ -118,7 +120,7 @@ export function BuyDialog(props: BuyDialogProps) {
|
||||
boxShadow: "4px 5px 18px 2px #00000038",
|
||||
borderRadius: "dialog",
|
||||
flexDirection: ["column", "column", "row"],
|
||||
width: ["95%", "80%", "60%"],
|
||||
width: ["95%", "80%", isCheckoutCompleted ? "400px" : "60%"],
|
||||
maxHeight: ["95%", "80%", "80%"],
|
||||
alignSelf: "center",
|
||||
overflowY: ["scroll", "scroll", "hidden"]
|
||||
@@ -139,7 +141,7 @@ export function BuyDialog(props: BuyDialogProps) {
|
||||
flexShrink: 0,
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
width: ["100%", "100%", 350]
|
||||
width: ["100%", "100%", isCheckoutCompleted ? "100%" : 350]
|
||||
}}
|
||||
p={4}
|
||||
py={50}
|
||||
@@ -165,6 +167,9 @@ function SideBar(props: SideBarProps) {
|
||||
const user = useUserStore((store) => store.user);
|
||||
const couponCode = useCheckoutStore((store) => store.couponCode);
|
||||
const onApplyCoupon = useCheckoutStore((store) => store.applyCoupon);
|
||||
const isCheckoutCompleted = useCheckoutStore((store) => store.isCompleted);
|
||||
|
||||
if (isCheckoutCompleted) return <CheckoutCompleted onClose={onClose} />;
|
||||
|
||||
if (user && selectedPlan)
|
||||
return (
|
||||
@@ -230,12 +235,16 @@ function Details() {
|
||||
const user = useUserStore((store) => store.user);
|
||||
const selectedPlan = useCheckoutStore((state) => state.selectedPlan);
|
||||
const onPriceUpdated = useCheckoutStore((state) => state.updatePrice);
|
||||
const completeCheckout = useCheckoutStore((state) => state.completeCheckout);
|
||||
const isCheckoutCompleted = useCheckoutStore((store) => store.isCompleted);
|
||||
const couponCode = useCheckoutStore((store) => store.couponCode);
|
||||
const setIsApplyingCoupon = useCheckoutStore(
|
||||
(store) => store.setIsApplyingCoupon
|
||||
);
|
||||
const theme = useThemeStore((store) => store.theme);
|
||||
|
||||
if (isCheckoutCompleted) return null;
|
||||
|
||||
if (selectedPlan && user)
|
||||
return (
|
||||
<PaddleCheckout
|
||||
@@ -243,6 +252,7 @@ function Details() {
|
||||
theme={theme}
|
||||
user={user}
|
||||
coupon={couponCode}
|
||||
onCompleted={completeCheckout}
|
||||
onCouponApplied={() => setIsApplyingCoupon(true)}
|
||||
onPriceUpdated={(pricingInfo) => {
|
||||
onPriceUpdated(pricingInfo);
|
||||
@@ -396,6 +406,31 @@ function AlreadyPremium(props: AlreadyPremiumProps) {
|
||||
);
|
||||
}
|
||||
|
||||
function CheckoutCompleted(props: { onClose: () => void }) {
|
||||
const { onClose } = props;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Rocket width={200} />
|
||||
<Text variant="heading" mt={4} sx={{ textAlign: "center" }}>
|
||||
Thank you!
|
||||
</Text>
|
||||
<Text variant="body" mt={1} sx={{ textAlign: "center" }}>
|
||||
You have successfully subscribed to Notesnook Pro.
|
||||
</Text>
|
||||
<Button
|
||||
variant="primary"
|
||||
mt={2}
|
||||
sx={{ borderRadius: 100, px: 6 }}
|
||||
onClick={onClose}
|
||||
data-test-id="see-all-plans"
|
||||
>
|
||||
Continue
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
type SelectedPlanProps = {
|
||||
plan: Plan;
|
||||
pricingInfo: PricingInfo | undefined;
|
||||
|
||||
@@ -39,7 +39,8 @@ const SUBSCRIBED_EVENTS: PaddleEvents[] = [
|
||||
PaddleEvents["Checkout.Loaded"],
|
||||
PaddleEvents["Checkout.Coupon.Applied"],
|
||||
PaddleEvents["Checkout.Coupon.Remove"],
|
||||
PaddleEvents["Checkout.Location.Submit"]
|
||||
PaddleEvents["Checkout.Location.Submit"],
|
||||
PaddleEvents["Checkout.Complete"]
|
||||
];
|
||||
|
||||
type PaddleCheckoutProps = {
|
||||
@@ -48,10 +49,11 @@ type PaddleCheckoutProps = {
|
||||
plan: Plan;
|
||||
onPriceUpdated?: (pricingInfo: PricingInfo) => void;
|
||||
onCouponApplied?: () => void;
|
||||
onCompleted?: () => void;
|
||||
coupon?: string;
|
||||
};
|
||||
export function PaddleCheckout(props: PaddleCheckoutProps) {
|
||||
const { plan, onPriceUpdated, coupon, onCouponApplied } = props;
|
||||
const { plan, onPriceUpdated, coupon, onCouponApplied, onCompleted } = props;
|
||||
const [sourceUrl, setSourceUrl] = useState<string>();
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [checkoutId, setCheckoutId] = useState<string>();
|
||||
@@ -96,6 +98,10 @@ export function PaddleCheckout(props: PaddleCheckoutProps) {
|
||||
)
|
||||
return;
|
||||
|
||||
if (event_name === PaddleEvents["Checkout.Complete"]) {
|
||||
onCompleted && onCompleted();
|
||||
return;
|
||||
}
|
||||
if (event_name === PaddleEvents["Checkout.Loaded"]) setIsLoading(false);
|
||||
|
||||
const pricingInfo = await updatePrice(checkout.id);
|
||||
@@ -108,7 +114,7 @@ export function PaddleCheckout(props: PaddleCheckoutProps) {
|
||||
return () => {
|
||||
window.removeEventListener("message", onMessage);
|
||||
};
|
||||
}, [onPriceUpdated, updatePrice, plan]);
|
||||
}, [onPriceUpdated, updatePrice, plan, onCompleted]);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
|
||||
@@ -22,6 +22,8 @@ import create from "zustand";
|
||||
import produce from "immer";
|
||||
|
||||
interface ICheckoutStore {
|
||||
isCompleted: boolean;
|
||||
completeCheckout: () => void;
|
||||
selectedPlan?: Plan;
|
||||
selectPlan: (plan?: Plan) => void;
|
||||
pricingInfo?: PricingInfo;
|
||||
@@ -33,10 +35,17 @@ interface ICheckoutStore {
|
||||
reset: () => void;
|
||||
}
|
||||
export const useCheckoutStore = create<ICheckoutStore>((set) => ({
|
||||
isCompleted: false,
|
||||
selectedPlan: undefined,
|
||||
pricingInfo: undefined,
|
||||
couponCode: undefined,
|
||||
isApplyingCoupon: false,
|
||||
completeCheckout: () =>
|
||||
set(
|
||||
produce((state: ICheckoutStore) => {
|
||||
state.isCompleted = true;
|
||||
})
|
||||
),
|
||||
selectPlan: (plan) =>
|
||||
set(
|
||||
produce((state: ICheckoutStore) => {
|
||||
|
||||
Reference in New Issue
Block a user