Skip to content

Commit

Permalink
Plan page + Beta Wallet integration (#25)
Browse files Browse the repository at this point in the history
* Plan page + Beta Wallet integration
  • Loading branch information
kubk authored Mar 23, 2024
1 parent 36f6487 commit 8f08e58
Show file tree
Hide file tree
Showing 20 changed files with 403 additions and 110 deletions.
17 changes: 17 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"@twa-dev/sdk": "^7.0.0",
"@xelene/tgui": "^2.0.4",
"autosize": "^6.0.1",
"canvas-confetti": "^1.9.2",
"colord": "^2.9.3",
"dompurify": "^3.0.9",
"framer-motion": "^10.16.4",
Expand Down Expand Up @@ -60,6 +61,7 @@
"@cloudflare/workers-types": "^4.20231002.0",
"@peculiar/webcrypto": "^1.4.3",
"@types/autosize": "^4.0.3",
"@types/canvas-confetti": "^1.6.4",
"@types/dompurify": "^3.0.5",
"@types/luxon": "^3.4.0",
"@types/node": "^20.8.0",
Expand Down
13 changes: 13 additions & 0 deletions public/privacy-policy.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
TOS
</body>
</html>
13 changes: 13 additions & 0 deletions public/terms-of-service.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
TOS
</body>
</html>
6 changes: 3 additions & 3 deletions src/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ import {
CreateOrderRequest,
CreateOrderResponse,
} from "../../functions/order-plan.ts";
import { MyPlansResponse } from "../../functions/my-plans.ts";
import { DuplicateFolderResponse } from "../../functions/duplicate-folder.ts";
import { MyStatisticsResponse } from "../../functions/my-statistics.ts";
import { AllPlansResponse } from "../../functions/plans.ts";

export const healthRequest = () => {
return request<HealthResponse>("/health");
Expand Down Expand Up @@ -165,8 +165,8 @@ export const createOrderRequest = (planId: number) => {
);
};

export const myPlansRequest = () => {
return request<MyPlansResponse>("/my-plans");
export const allPlansRequest = () => {
return request<AllPlansResponse>("/plans");
};

export const myStatisticsRequest = () => {
Expand Down
4 changes: 3 additions & 1 deletion src/screens/deck-list/main-screen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import React, { Fragment } from "react";
import { observer } from "mobx-react-lite";
import { css, cx } from "@emotion/css";
import { PublicDeck } from "./public-deck.tsx";
import { DeckRowWithCardsToReview } from "../shared/deck-row-with-cards-to-review/deck-row-with-cards-to-review.tsx";
import {
DeckRowWithCardsToReview
} from "../shared/deck-row-with-cards-to-review/deck-row-with-cards-to-review.tsx";
import { deckListStore } from "../../store/deck-list-store.ts";
import { useMount } from "../../lib/react/use-mount.ts";
import { Hint } from "../../ui/hint.tsx";
Expand Down
70 changes: 70 additions & 0 deletions src/screens/plans/plan-item.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { css, cx } from "@emotion/css";
import { theme } from "../../ui/theme.tsx";
import { Flex } from "../../ui/flex.tsx";
import React from "react";
import { HorizontalDivider } from "../../ui/horizontal-divider.tsx";

type Props = {
title: string;
description?: string[];
onClick?: () => void;
isSelected?: boolean;
paidUntil?: string;
};

export const PlanItem = (props: Props) => {
const { title, description, onClick, isSelected, paidUntil } = props;

return (
<div
onClick={onClick}
className={cx(
css({
padding: 16,
boxSizing: "border-box",
display: "flex",
flexDirection: "column",
alignSelf: "center",
width: "100%",
gap: 4,
color: theme.buttonColor,
boxShadow: theme.boxShadow,
backgroundColor: theme.buttonColorLighter,
borderRadius: theme.borderRadius,
cursor: "pointer",
}),
isSelected &&
css({
border: "4px solid " + theme.buttonColor,
borderRadius: theme.borderRadius,
}),
)}
>
<Flex alignItems={"center"} gap={8} justifyContent={"center"}>
<h3 className={css({ color: "inherit" })}>{title}</h3>
</Flex>
{description && (
<ul className={cx(css({ fontSize: 14, paddingLeft: 26 }))}>
{description.map((item, i) => (
<li key={i}>{item}</li>
))}
</ul>
)}
{paidUntil && (
<>
<HorizontalDivider color={theme.buttonColor} />
<div
className={css({
fontSize: 16,
fontWeight: 600,
color: theme.buttonColor,
textAlign: "center",
})}
>
Paid until: {paidUntil}
</div>
</>
)}
</div>
);
};
102 changes: 72 additions & 30 deletions src/screens/plans/plans-screen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,93 @@ import { observer } from "mobx-react-lite";
import { Screen } from "../shared/screen.tsx";
import { useBackButton } from "../../lib/telegram/use-back-button.tsx";
import { screenStore } from "../../store/screen-store.ts";
import { t } from "../../translations/t.ts";
import { Flex } from "../../ui/flex.tsx";
import React from "react";
import { Choice } from "../../ui/choice.tsx";
import { SelectedPlan } from "./selected-plan.tsx";
import React, { useState } from "react";
import { PlanItem } from "./plan-item.tsx";
import { useMainButton } from "../../lib/telegram/use-main-button.tsx";
import { Hint } from "../../ui/hint.tsx";
import { useMount } from "../../lib/react/use-mount.ts";
import { FullScreenLoader } from "../../ui/full-screen-loader.tsx";
import { getPlanDescription, getPlanFullTile } from "./translations.ts";
import { PlansScreenStore } from "./store/plans-screen-store.ts";
import { useTelegramProgress } from "../../lib/telegram/use-telegram-progress.tsx";
import { userStore } from "../../store/user-store.ts";
import { DateTime } from "luxon";
import { ExternalLink } from "../../ui/external-link.tsx";

export const PlansScreen = observer(() => {
const [store] = useState(() => new PlansScreenStore());
useBackButton(() => {
screenStore.back();
});

useMount(() => {
store.load();
});

useMainButton(
() => store.buyText,
() => {
store.createOrder();
},
() => store.isBuyButtonVisible,
);

useTelegramProgress(() => store.isCreatingOrder);

if (store.plansRequest?.state === "pending") {
return <FullScreenLoader />;
}

return (
<Screen title={"Plans"}>
<Flex
direction={"column"}
alignItems={"center"}
justifyContent={"center"}
mt={50}
gap={12}
gap={16}
mt={4}
mb={16}
fullWidth
>
<Flex direction={"column"} gap={8}>
<SelectedPlan>
<Choice
icon={"mdi mdi-cards-outline mdi-36px"}
title={"Free"}
outline
/>
</SelectedPlan>
<Choice
icon={"mdi mdi-cards-outline mdi-36px"}
title={"Plus"}
description={t("deck_description")}
onClick={() => {
screenStore.go({ type: "deckForm" });
}}
/>
<Choice
icon={"mdi mdi-folder-open-outline mdi-36px"}
title={"Pro"}
description={t("folder_description")}
onClick={() => {
screenStore.go({ type: "folderForm" });
}}
/>
<Flex direction={"column"} gap={16} fullWidth>
{store.plans.map((plan) => {
const paidPlan = userStore.plans?.find(
(p) => p.plan_id === plan.id,
);
const paidUntil = paidPlan?.until_date
? DateTime.fromISO(paidPlan.until_date).toLocaleString(
DateTime.DATE_FULL,
)
: undefined;

return (
<PlanItem
key={plan.id}
title={getPlanFullTile(plan)}
isSelected={store.selectedPlanId === plan.id}
paidUntil={paidUntil}
description={getPlanDescription(plan)}
onClick={() => {
if (!paidUntil) {
store.selectPlan(plan.id);
}
}}
/>
);
})}
</Flex>
<Hint>
By purchasing MemoCard you agree to the{" "}
<ExternalLink href={"/terms-of-service.html"}>
Terms of Service
</ExternalLink>{" "}
and{" "}
<ExternalLink href={"/privacy-policy.html"}>
Privacy Policy
</ExternalLink>
.
</Hint>
</Flex>
</Screen>
);
Expand Down
30 changes: 0 additions & 30 deletions src/screens/plans/selected-plan.tsx

This file was deleted.

Loading

0 comments on commit 8f08e58

Please sign in to comment.