diff --git a/apps/web/src/common/theme.ts b/apps/web/src/common/theme.ts
index 487e0d155..4f4b43804 100644
--- a/apps/web/src/common/theme.ts
+++ b/apps/web/src/common/theme.ts
@@ -43,12 +43,12 @@ export const THEME_LIGHT: any = {
primary: {
accent: "#008836",
accentForeground: "#ffffff",
- paragraph: "#5b5b5b",
+ paragraph: "#666666",
background: "#ffffff",
border: "#E2E2E2",
heading: "#181818",
icon: "#181818",
- separator: "#F0F0F0",
+ separator: "#E5E5E5",
placeholder: "#858585",
hover: "#eee",
backdrop: "#0000001a",
@@ -57,7 +57,7 @@ export const THEME_LIGHT: any = {
secondary: {
accent: "#0D9E46",
accentForeground: "#ffffff",
- paragraph: "#858585",
+ paragraph: "#909090",
background: "#F7F7F7",
border: "#EFEFEF",
heading: "#4B4B4B",
diff --git a/apps/web/src/components/field/index.tsx b/apps/web/src/components/field/index.tsx
index a5f6b9ed0..b6f9101e1 100644
--- a/apps/web/src/components/field/index.tsx
+++ b/apps/web/src/components/field/index.tsx
@@ -31,6 +31,7 @@ type Action = {
icon?: Icon;
component?: JSX.Element;
hidden?: boolean;
+ sx?: ThemeUIStyleObject;
};
export type FieldProps = InputProps & {
label?: string;
@@ -182,7 +183,8 @@ function Field(props: FieldProps) {
margin: 0,
display: "flex",
alignItems: "center",
- justifyContent: "center"
+ justifyContent: "center",
+ ...action.sx
}}
disabled={action.disabled}
>
@@ -225,7 +227,8 @@ function Field(props: FieldProps) {
margin: 0,
display: "flex",
alignItems: "center",
- justifyContent: "center"
+ justifyContent: "center",
+ ...action.sx
}}
disabled={action.disabled}
>
diff --git a/apps/web/src/components/icons/index.tsx b/apps/web/src/components/icons/index.tsx
index df5429f41..15a6455d2 100644
--- a/apps/web/src/components/icons/index.tsx
+++ b/apps/web/src/components/icons/index.tsx
@@ -24,7 +24,6 @@ import {
mdiMinus,
mdiBookOutline,
mdiNotebookOutline,
- mdiArrowLeft,
mdiArrowRight,
mdiArrowDown,
mdiBookPlusMultipleOutline,
@@ -45,7 +44,6 @@ import {
mdiMagnify,
mdiMenu,
mdiLoginVariant,
- mdiEmailAlertOutline,
mdiAccountOutline,
mdiLogoutVariant,
mdiSunglasses,
@@ -59,8 +57,6 @@ import {
mdiExportVariant,
mdiArrowExpandDown,
mdiArrowTopRightThick,
- mdiChevronLeft,
- mdiChevronRight,
mdiPound,
mdiPinOutline,
mdiPin,
@@ -109,7 +105,6 @@ import {
mdiNoteOutline,
mdiSyncAlert,
mdiAlertOutline,
- mdiEyeOutline,
mdiEyeOffOutline,
mdiAttachment,
mdiPencilOutline,
@@ -176,7 +171,6 @@ import {
mdiCalendarClockOutline,
mdiPuzzleOutline,
mdiBellRingOutline,
- mdiClockTimeFiveOutline,
mdiBellOffOutline,
mdiVibrate,
mdiBellCancelOutline,
@@ -246,6 +240,16 @@ import ChevronLeftIcon from "@notesnook/icons/chevron-left.svg?react";
import ChevronRightIcon from "@notesnook/icons/chevron-right.svg?react";
import ClockIcon from "@notesnook/icons/clock.svg?react";
import WarningCircle from "@notesnook/icons/warning-circle.svg?react";
+import CloudSvg from "@notesnook/icons/cloud.svg?react";
+import ShieldCheckSvg from "@notesnook/icons/shield-check.svg?react";
+import DeviceMobileCameraSvg from "@notesnook/icons/device-mobile-camera.svg?react";
+import FileSvg from "@notesnook/icons/file.svg?react";
+import ImageSvg from "@notesnook/icons/image.svg?react";
+import ArrowRightSvg from "@notesnook/icons/arrow-right.svg?react";
+import CheckCircleSvg from "@notesnook/icons/check-circle.svg?react";
+import ArrowLeftSvg from "@notesnook/icons/arrow-left.svg?react";
+import CheckCircleSuccesSvg from "@notesnook/icons/check-circle-success.svg?react";
+import InfoSvg from "@notesnook/icons/info.svg?react";
type MDIIconWrapperProps = {
title?: string;
@@ -370,7 +374,6 @@ export const Minus = createIcon(mdiMinus);
export const Notebook = createIcon(mdiBookOutline);
export const Notebooks = createIcon(mdiBookMultipleOutline);
export const Notebook2 = createIcon(mdiNotebookOutline);
-export const ArrowLeft = createIcon(mdiArrowLeft);
export const ArrowRight = createIcon(mdiArrowRight);
export const ArrowDown = createIcon(mdiArrowDown);
export const ArrowTopRight = createIcon(mdiArrowTopRight);
@@ -423,7 +426,6 @@ export const LightMode = createIcon(mdiWeatherSunny);
export const ThemeIcon = createIcon(mdiThemeLightDark);
export const Checkmark = createIcon(mdiCheck);
export const DoubleCheckmark = createIcon(mdiCheckAll);
-export const CheckCircle = createIcon(mdiCheckCircle);
export const CheckIntermediate = createIcon(mdiMinusCircleOutline);
export const CheckRemove = createIcon(mdiCloseCircleOutline);
export const CheckCircleOutline = createIcon(mdiCheckCircleOutline);
@@ -438,7 +440,6 @@ export const Text = createIcon(mdiFormatTitle);
export const Success = createIcon(mdiCheckCircle);
export const Error = createIcon(mdiAlertCircle);
export const Warn = createIcon(mdiAlertOutline);
-export const Info = createIcon(mdiInformation);
export const ToggleUnchecked = createIcon(mdiToggleSwitchOffOutline);
export const ToggleChecked = createIcon(mdiToggleSwitchOutline);
export const Backup = createIcon(mdiBackupRestore);
@@ -630,3 +631,13 @@ export const ChevronLeft = createSvgIcon(ChevronLeftIcon);
export const ChevronRight = createSvgIcon(ChevronRightIcon);
export const Clock = createSvgIcon(ClockIcon);
export const Warning = createSvgIcon(WarningCircle);
+export const Cloud = createSvgIcon(CloudSvg);
+export const ShieldCheck = createSvgIcon(ShieldCheckSvg);
+export const DeviceMobileCamera = createSvgIcon(DeviceMobileCameraSvg);
+export const FileDoc = createSvgIcon(FileSvg);
+export const Picture = createSvgIcon(ImageSvg);
+export const ArrowRightSvgIcon = createSvgIcon(ArrowRightSvg);
+export const CheckCircle = createSvgIcon(CheckCircleSvg);
+export const ArrowLeft = createSvgIcon(ArrowLeftSvg);
+export const CheckCircleSuccess = createSvgIcon(CheckCircleSuccesSvg);
+export const Info = createSvgIcon(InfoSvg);
diff --git a/apps/web/src/views/checkout.tsx b/apps/web/src/views/checkout.tsx
index 826a960ed..a99c6cef8 100644
--- a/apps/web/src/views/checkout.tsx
+++ b/apps/web/src/views/checkout.tsx
@@ -18,27 +18,35 @@ along with this program. If not, see .
*/
import "../app.css";
-import { useEffect, useState } from "react";
+import { useEffect, useRef, useState } from "react";
import { Box, Button, Flex, Text } from "@theme-ui/components";
+import Field from "../components/field";
import { hardNavigate, useQueryParams } from "../navigation";
-import { Support } from "../components/icons";
-import { HeadlessAuth } from "./auth";
import {
- CheckoutCompleted,
- CheckoutDetails,
- CheckoutPricing
-} from "../dialogs/buy-dialog";
+ Coupon,
+ Loading,
+ CheckCircle,
+ ArrowLeft,
+ Cloud,
+ ShieldCheck,
+ DeviceMobileCamera,
+ Info,
+ CheckCircleSuccess
+} from "../components/icons";
+import { HeadlessAuth } from "./auth";
+import { CheckoutDetails } from "../dialogs/buy-dialog";
import { useCheckoutStore } from "../dialogs/buy-dialog/store";
import { useStore as useUserStore } from "../stores/user-store";
import { z } from "zod";
import {
FEATURE_HIGHLIGHTS,
- toPricingInfo
+ toPricingInfo,
+ formatPrice
} from "../dialogs/buy-dialog/helpers";
import { isUserSubscribed } from "../hooks/use-is-user-premium";
-import { PLAN_METADATA } from "../dialogs/buy-dialog/plans";
-import { planToAvailability } from "@notesnook/common";
-import { FeatureCaption } from "../dialogs/buy-dialog/feature-caption";
+import { PLAN_METADATA, PERIOD_METADATA } from "../dialogs/buy-dialog/plans";
+import { getFeature, planToAvailability } from "@notesnook/common";
+import dayjs from "dayjs";
import { EVENTS } from "@notesnook/core";
import { db } from "../common/db";
@@ -83,11 +91,21 @@ const PlanSchema = z.object({
.optional()
});
-const CHECKOUT_STEPS = ["Account", "Payment", "Complete"];
+const CHECKOUT_STEP = {
+ ACCOUNT: "Account",
+ PAYMENT: "Payment",
+ COMPLETE: "Complete"
+} as const;
+
+type CheckoutStep = (typeof CHECKOUT_STEP)[keyof typeof CHECKOUT_STEP];
+
function Checkout() {
const [{ plan }] = useQueryParams();
+ const selectedPlan = useCheckoutStore((state) => state.selectedPlan);
- const [currentStep, setCurrentStep] = useState(0);
+ const [currentStep, setCurrentStep] = useState(
+ CHECKOUT_STEP.ACCOUNT
+ );
const [error, setError] = useState();
const [customer, setCustomer] = useState<{ id: string; email: string }>();
@@ -114,12 +132,12 @@ function Checkout() {
useCheckoutStore.getState().applyCoupon(pricingInfo.data.discount?.code);
if (pricingInfo.data.customer) {
setCustomer(pricingInfo.data.customer);
- setCurrentStep(1);
+ setCurrentStep(CHECKOUT_STEP.PAYMENT);
}
}, [plan]);
useEffect(() => {
- if (currentStep === 2) {
+ if (currentStep === CHECKOUT_STEP.COMPLETE) {
const event = db.eventManager.subscribe(
EVENTS.userSubscriptionUpdated,
() => {
@@ -151,178 +169,225 @@ function Checkout() {
alignItems: "center",
justifyContent: "space-between",
borderBottom: "1px solid var(--border)",
- px: 2
+ px: "spacing13",
+ py: "spacing8"
}}
>
-
-
+
+ {currentStep === CHECKOUT_STEP.COMPLETE ? null : (
+
+ )}
+
-
+
Notesnook
-
-