+
+
+ Please verify your email
+
+
+
+
+ We've sent you an email with a link to verify your email address.
+
+
+
+
+
+
+ );
+};
+
+export default VerifyEmail;
diff --git a/src/components/pages/buyflow/ProBuyflow.tsx b/src/components/pages/buyflow/ProBuyflow.tsx
new file mode 100644
index 0000000..49e3c95
--- /dev/null
+++ b/src/components/pages/buyflow/ProBuyflow.tsx
@@ -0,0 +1,137 @@
+import useFirebase from "../../../hooks/useFirebase";
+import useUser from "../../../hooks/useUser";
+import { Message } from "../../common/Message";
+import { useMutation } from "@tanstack/react-query";
+import { Firestore, doc, setDoc } from "firebase/firestore";
+import { Navigate, useNavigate } from "react-router-dom";
+
+type SubscriptionPerios = "month" | "year";
+
+type Subscription = {
+ period: SubscriptionPerios;
+ price: string;
+};
+
+const subscribe = async ({
+ firestore,
+ userId,
+ subscription,
+}: {
+ firestore: Firestore;
+ userId: string;
+ subscription: Subscription;
+}) => {
+ // Create a new subscription document
+ await setDoc(doc(firestore, `/subscriptions/${userId}`), {
+ plan_id: "pro",
+ period: subscription.period,
+ price: subscription.price,
+ currency: "USD",
+ start_date: new Date(),
+ });
+};
+
+const ProBuyflow = () => {
+ const user = useUser();
+ const navigate = useNavigate();
+ const firebase = useFirebase();
+ const subscribeMutation = useMutation({
+ mutationFn: subscribe,
+ onSuccess: () => {
+ // Redirect to the thanks page
+ setTimeout(() => {
+ navigate("/buy/pro/thanks");
+ }, 500);
+ },
+ });
+
+ if (!user) {
+ return (
+
+
+
+ Get Tree of Science Pro
+
+
+
+
+
With Tree of Science Pro you get:
+
+ - Upload files up to 100MB
+ - Unlimited history
+
+
For just $10/month or $100/year
+
+
+
+
+
+
+
+
+ );
+};
+
+export default ProBuyflow;
diff --git a/src/components/pages/buyflow/Thanks.tsx b/src/components/pages/buyflow/Thanks.tsx
new file mode 100644
index 0000000..083d3a4
--- /dev/null
+++ b/src/components/pages/buyflow/Thanks.tsx
@@ -0,0 +1,51 @@
+import useUser from "../../../hooks/useUser";
+import { Navigate, useNavigate } from "react-router-dom";
+
+const Thanks = () => {
+ const user = useUser();
+ const navigate = useNavigate();
+
+ if (!user) {
+ return (
+
+
+
+ Thanks for purchasing Tree of Science Pro!
+
+
+
+
+ You now have access to all the pro features of Tree of Science.
+
+
+ As you probably noticed you were not charged, and you won't be charged
+ for the time being.
+
+
+ Once we start charging for Tree of Science Pro, you will be given the
+ option to renew or cancel your subscription.
+
+
+
+
+
+
+ );
+};
+
+export default Thanks;
diff --git a/src/components/pages/docs/FAQ.tsx b/src/components/pages/docs/Faq.tsx
similarity index 99%
rename from src/components/pages/docs/FAQ.tsx
rename to src/components/pages/docs/Faq.tsx
index d4a0f08..74a2621 100644
--- a/src/components/pages/docs/FAQ.tsx
+++ b/src/components/pages/docs/Faq.tsx
@@ -1,7 +1,7 @@
import Reference from "../../tree/Reference";
-import { useEffect } from "react";
+import { FC, useEffect } from "react";
-const FAQ = () => {
+const Faq: FC = () => {
useEffect(() => {
window.scrollTo(0, 0);
}, []);
@@ -218,4 +218,4 @@ const FAQ = () => {
);
};
-export default FAQ;
+export default Faq;
diff --git a/src/components/pages/docs/PressRelease.tsx b/src/components/pages/docs/PressRelease.tsx
index 528d1a7..c7edb07 100644
--- a/src/components/pages/docs/PressRelease.tsx
+++ b/src/components/pages/docs/PressRelease.tsx
@@ -2,7 +2,9 @@ import { useEffect } from "react";
const PresRelease = () => {
useEffect(() => {
- window && window.scrollTo(0, 0);
+ if (window) {
+ window.scrollTo(0, 0);
+ }
});
return (
diff --git a/src/components/pages/docs/Sap.tsx b/src/components/pages/docs/Sap.tsx
index 6b17c27..e3b3eab 100644
--- a/src/components/pages/docs/Sap.tsx
+++ b/src/components/pages/docs/Sap.tsx
@@ -1,10 +1,11 @@
-import TableOfContent from "../../common/TableOfContent";
-import { HeadingData } from "../../common/TableOfContent/constants";
+import TableOfContents from "../../common/TableOfContents";
import { useEffect } from "react";
const Sap = () => {
useEffect(() => {
- window && window.scrollTo(0, 0);
+ if (window) {
+ window.scrollTo(0, 0);
+ }
}, []);
return (
@@ -15,7 +16,7 @@ const Sap = () => {
works, and latest contributions for a state-of- the-art literature
summary.
-
Roots
diff --git a/src/components/tree/Tree.tsx b/src/components/tree/Tree.tsx
index 3b0223e..48c0494 100644
--- a/src/components/tree/Tree.tsx
+++ b/src/components/tree/Tree.tsx
@@ -71,7 +71,7 @@ const Tree: FC = ({
branch_3: [],
};
const sections: Section[] = Object.keys(keywords) as Section[];
- for (let section of sections) {
+ for (const section of sections) {
for (const article of treeSections[section] ?? []) {
if (!article.keywords) continue;
keywords[section] = keywords[section].concat(article.keywords);
@@ -101,7 +101,7 @@ const Tree: FC = ({
{
stars: {
...stars,
- [labelAsBase64]: !Boolean(stars[labelAsBase64]),
+ [labelAsBase64]: !stars[labelAsBase64],
},
},
{ merge: true },
diff --git a/src/components/tree/TreeVis.tsx b/src/components/tree/TreeVis.tsx
index bc92079..40bfeeb 100644
--- a/src/components/tree/TreeVis.tsx
+++ b/src/components/tree/TreeVis.tsx
@@ -118,15 +118,15 @@ export const TreeVis: FC = ({ treeResult: treeSections }) => {
.force("charge", forceManyBody().strength(5))
.force(
"y",
- forceY().y((d) => (d as any).centerY),
+ forceY().y((d) => (d as { centerY: number }).centerY),
)
.force(
"x",
- forceX().x((d) => (d as any).centerX),
+ forceX().x((d) => (d as { centerX: number }).centerX),
)
.force(
"collide",
- forceCollide().radius((d) => (d as any).radius + 2),
+ forceCollide().radius((d) => (d as { radius: number }).radius + 2),
)
.on("tick", () => {
svg
diff --git a/src/components/upload/TOS/createTree.ts b/src/components/upload/Tos/createTree.ts
similarity index 100%
rename from src/components/upload/TOS/createTree.ts
rename to src/components/upload/Tos/createTree.ts
diff --git a/src/components/upload/TOS/index.tsx b/src/components/upload/Tos/index.tsx
similarity index 86%
rename from src/components/upload/TOS/index.tsx
rename to src/components/upload/Tos/index.tsx
index 5dc3dd6..3382fe5 100644
--- a/src/components/upload/TOS/index.tsx
+++ b/src/components/upload/Tos/index.tsx
@@ -8,9 +8,9 @@ import { countFormat, round, weightFormat } from "../../../utils/math";
import AcceptsEmail from "../AcceptsEmail";
import EmailVerification from "../EmailVerification";
import { createTree } from "./createTree";
+import { useMutation } from "@tanstack/react-query";
import { logEvent } from "firebase/analytics";
import React, { FC, useContext } from "react";
-import { useMutation } from "react-query";
import { useNavigate } from "react-router-dom";
import { Link } from "react-router-dom";
@@ -28,7 +28,7 @@ const hasFinished = (
true,
);
-const TOS: FC = () => {
+const Tos: FC = () => {
const { progress } = useContext(FileContext);
const files = useFiles();
const hashes = files.map((file) => file.hash);
@@ -43,9 +43,10 @@ const TOS: FC = () => {
const {
mutate: create,
- isLoading,
+ isPending,
isError,
- } = useMutation(createTree, {
+ } = useMutation({
+ mutationFn: createTree,
onSuccess: (treePath: string) =>
navigate(`/${treePath}`, { replace: true }),
});
@@ -84,33 +85,36 @@ const TOS: FC = () => {
size [MB]