Skip to content

Commit 5be159d

Browse files
author
Osamah Ahmad
committed
subscription checking
1 parent 8cb2119 commit 5be159d

File tree

4 files changed

+78
-18
lines changed

4 files changed

+78
-18
lines changed

src/App.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { useEffect, useState } from 'react';
22
import { CssVarsProvider, extendTheme } from '@mui/joy';
33
import './App.css';
4-
import { Paths } from './resources/Paths.ts';
4+
import Paths from './resources/Paths.ts';
55
import Landing from './pages/Landing.tsx';
66
import QuestionBank from './pages/QuestionBank.tsx';
77
import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom';

src/pages/Landing.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import React from "react";
2-
import {Button, ButtonGroup, Typography, Card, Accordion, AccordionSummary, AccordionDetails, Grid, Dropdown, MenuButton, Menu, IconButton, MenuItem, Link, List } from '@mui/joy';
2+
import { Button, ButtonGroup, Typography, Card, Accordion, AccordionSummary, AccordionDetails, Grid, Dropdown, MenuButton, Menu, IconButton, MenuItem, Link, List } from '@mui/joy';
33
import './Landing.css';
44
import { MdMoreVert } from 'react-icons/md';
55
import { useNavigate } from "react-router-dom";
6-
import { Paths } from "../resources/Paths.ts";
6+
import Paths from "../resources/Paths.ts";
77
import { auth } from "../resources/Firebase.js";
88
import useDocumentTitle from "../hooks/useDocumentTitle.ts";
99
import Strings from "../resources/Strings.ts";
@@ -527,7 +527,7 @@ const Landing: React.FC<LandingProps> = () => {
527527
</Card>
528528
<Card className={sections[4]} variant='outlined'>
529529
<Typography level='h2' color='success'>{sectionTitles[sections[4]]}</Typography>
530-
<Button color='success' sx={{width: 'fit-content'}} onClick={() => navigate(Paths.QuestionBank)}>Access the Question Bank</Button>
530+
<Button color='success' sx={{ width: 'fit-content' }} onClick={() => navigate(Paths.QuestionBank)}>Access the Question Bank</Button>
531531
{auth && auth.currentUser && <Typography>You're currently signed in as {auth.currentUser.email}. <Link onClick={() => auth.signOut()}>Sign Out</Link>.</Typography>}
532532
</Card>
533533
<footer>

src/pages/QuestionBank.tsx

+67-11
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import useDocumentTitle from "../hooks/useDocumentTitle.ts";
66
import { Alert, Button, CircularProgress, Link, Typography } from "@mui/joy";
77
import { onAuthStateChanged, sendEmailVerification } from "firebase/auth";
88
import { auth } from "../resources/Firebase.js";
9+
import Paths from '../resources/Paths.ts';
910

1011
const str2xml = (str: string) => {
1112
if (str.charCodeAt(0) === 65279) {
@@ -78,11 +79,7 @@ const getParagraphs = async (file: File) => {
7879
return paragraphs;
7980
};
8081

81-
interface QuestionBankProps {
82-
83-
}
84-
85-
const QuestionBank: React.FC<QuestionBankProps> = ({ }) => {
82+
const QuestionBank: React.FC = ({ }) => {
8683
/* hooks */
8784
useDocumentTitle('My Answers');
8885

@@ -157,6 +154,31 @@ const QuestionBank: React.FC<QuestionBankProps> = ({ }) => {
157154
</>
158155
);
159156

157+
/* subscription */
158+
const [subscriptionChecked, setSubscriptionChecked] = useState<boolean>(false);
159+
const [subscriptionExpiryDate, setSubscriptionExpiryDate] = useState<Date>();
160+
161+
const checkSubscription = useCallback(async () => {
162+
try {
163+
const response = await fetch(Paths.Serverless + '?user-uid=' + auth.currentUser?.uid);
164+
if (response.status === 200) {
165+
const timestamp = await response.text();
166+
const timestampInt = parseInt(timestamp, 10);
167+
setSubscriptionChecked(true);
168+
setSubscriptionExpiryDate(new Date(timestampInt * 1000));
169+
}
170+
} catch (error) {
171+
setSubscriptionChecked(true);
172+
console.error(error);
173+
}
174+
}, [setSubscriptionChecked, setSubscriptionExpiryDate]);
175+
176+
useEffect(() => {
177+
checkSubscription();
178+
}, [checkSubscription]);
179+
180+
const hasSubscriptionExpired = subscriptionExpiryDate && (subscriptionExpiryDate < new Date(Date.now()));
181+
160182
/* parse data */
161183
const [paragraphs, setParagraphs] = useState<string[]>([]);
162184

@@ -178,8 +200,8 @@ const QuestionBank: React.FC<QuestionBankProps> = ({ }) => {
178200

179201
return (
180202
<div>
181-
{auth.currentUser && !emailVerified && (
182-
<Alert color="warning">
203+
{!emailVerified && (
204+
<Alert color='success'>
183205
<Typography
184206
level="body-sm"
185207
sx={{ color: "inherit", display: "flex", gap: ".25em", alignItems: "center" }}
@@ -189,10 +211,44 @@ const QuestionBank: React.FC<QuestionBankProps> = ({ }) => {
189211
</Typography>
190212
</Alert>
191213
)}
192-
<Button>Purchase</Button>
193-
{paragraphs.map((paragraph, index) => (
194-
<div key={index}>{paragraph}</div>
195-
))}
214+
{subscriptionExpiryDate && (
215+
<>
216+
<Alert color={hasSubscriptionExpired ? 'danger' : 'success'}>
217+
<Typography
218+
level="body-sm"
219+
sx={{ color: "inherit", display: "flex", gap: ".25em", alignItems: "center" }}
220+
>
221+
Your subscription {hasSubscriptionExpired ? 'expired' : 'will renew'} on {
222+
subscriptionExpiryDate && (
223+
subscriptionExpiryDate.toLocaleString('en-GB', {
224+
hour: '2-digit',
225+
minute: '2-digit',
226+
hour12: true
227+
}) +
228+
' on ' +
229+
subscriptionExpiryDate.toLocaleString('en-GB', {
230+
weekday: 'long',
231+
day: 'numeric',
232+
month: 'long',
233+
year: 'numeric'
234+
}))
235+
}.
236+
</Typography>
237+
</Alert>
238+
{paragraphs.map((paragraph, index) => (
239+
<div key={index}>{paragraph}</div>
240+
))}
241+
</>
242+
)}
243+
{subscriptionChecked
244+
? (!subscriptionExpiryDate || hasSubscriptionExpired) &&
245+
<Button onClick={() => {
246+
auth.currentUser && (window.location.href = Paths.Subscribe + auth.currentUser.uid)
247+
}}>
248+
Purchase
249+
</Button>
250+
: <CircularProgress />
251+
}
196252
</div>
197253
);
198254
};

src/resources/Paths.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
export enum Paths {
1+
enum Paths {
22
QuestionBank = '/question-bank',
33
SignUp = '/create-account',
44
SignIn = '/sign-in',
55
TermsOfService = 'terms-of-service',
66
PrivacyPolicy = 'privacy-policy',
7-
Verification = 'verification'
8-
}
7+
Verification = 'verification',
8+
Subscribe = 'https://buy.stripe.com/test_6oE6oo2vog1Tbn2fYY?client_reference_id=',
9+
Serverless = 'https://radiology-interview-prep-serverless.osamah-ahmad.workers.dev'
10+
}
11+
12+
export default Paths;

0 commit comments

Comments
 (0)