diff --git a/frontend/src/@types/index.ts b/frontend/src/@types/index.ts index 1cc50be2..10a48031 100644 --- a/frontend/src/@types/index.ts +++ b/frontend/src/@types/index.ts @@ -46,3 +46,16 @@ export interface DatasetExport { fileNames: string[]; dataSets: Array; } + +export interface IQuest { + title: string; + description: string; + config: string; + guid: string; + userGuid: string; + createdAt: string; + updatedAt: string; + joinCode: string; + organizerName?: string; + participants?: string[]; // userNpubs +} diff --git a/frontend/src/components/stripe-button.tsx b/frontend/src/components/stripe-button.tsx new file mode 100644 index 00000000..60535c0a --- /dev/null +++ b/frontend/src/components/stripe-button.tsx @@ -0,0 +1,29 @@ +import React, { useEffect } from "react"; + +const StripeButton: React.FC = () => { + useEffect(() => { + const script = document.createElement("script"); + script.src = "https://js.stripe.com/v3/buy-button.js"; + script.async = true; + document.body.appendChild(script); + + return () => { + document.body.removeChild(script); + }; + }, []); + + return ( +
+ `, + }} + >
+ ); +}; + +export default StripeButton; diff --git a/frontend/src/pages/profile.tsx b/frontend/src/pages/profile.tsx index c437a90b..55fa4ba7 100644 --- a/frontend/src/pages/profile.tsx +++ b/frontend/src/pages/profile.tsx @@ -4,9 +4,11 @@ import { getServerSession } from "next-auth"; import { useSession, signOut } from "next-auth/react"; import { authOptions } from "./api/auth/[...nextauth]"; -import { DashboardLayout } from "~/components/layouts"; +import { DashboardLayout, Meta } from "~/components/layouts"; import { Button, Dialog, DialogContent, DialogDescription, DialogTitle } from "~/components/ui"; import { deletePrivateKey } from "~/utils/auth"; +import Link from "next/link"; +import StripeButton from "~/components/stripe-button"; const AccountPage: NextPage = () => { const { data: session } = useSession(); @@ -19,6 +21,12 @@ const AccountPage: NextPage = () => { return ( +

Profile

You have been assigned an anonymous account

@@ -38,7 +46,8 @@ const AccountPage: NextPage = () => {
-

You're on the Fusion Free Plan.

+

Fusion is open source. Fund our development!

+
); diff --git a/frontend/src/pages/quest/[guid].tsx b/frontend/src/pages/quest/[guid].tsx new file mode 100644 index 00000000..ee21f077 --- /dev/null +++ b/frontend/src/pages/quest/[guid].tsx @@ -0,0 +1,118 @@ +// this is what will contain the dashboard + +import { GetServerSideProps, NextPage } from "next"; +import { getServerSession } from "next-auth"; +import { DashboardLayout, Meta } from "~/components/layouts"; +import { authOptions } from "../api/auth/[...nextauth]"; +import { Button } from "~/components/ui"; +import React from "react"; +import { api } from "~/config"; +import { useSession } from "next-auth/react"; +import { IQuest } from "~/@types"; +import { usePathname } from "next/navigation"; + +const QuestDetailPage: NextPage = () => { + const [quest, setQuest] = React.useState(null); + const pathname = usePathname(); + + // get the last part of the pathname + const questId = pathname.split("/").pop(); + + const session = useSession(); + // fetch the quest info + React.useEffect(() => { + // maker request to backend to get quest info + (async () => { + const res = await api.get("/quest/detail", { + params: { + questId, + }, + headers: { + Authorization: `Bearer ${session.data?.user?.authToken}`, + }, + }); + + if (res.status === 200) { + const data = res.data; + setQuest(data.quest); + + const questSubscribers = await getQuestSubscribers(questId!); + if (questSubscribers) { + setQuestSubscribers(questSubscribers); + } + } + })(); + }, []); + + // TODO: move to quest.service.ts + const [questSubscribers, setQuestSubscribers] = React.useState([]); + const getQuestSubscribers = async (questId: string) => { + try { + const res = await api.get( + "/quest/subscribers", + + { + params: { + questId, + }, + headers: { + Authorization: `Bearer ${session.data?.user?.authToken}`, + }, + } + ); + + if (res.status === 200) { + console.log("Quest Subscribers fetched successfully"); + console.log(res.data); + return res.data.userQuests; + } else { + console.error("Failed to fetch quest subscribers"); + } + } catch (error) { + console.error("Failed to fetch quest subscribers", error); + } + }; + + return ( + + +

Quest

+ + {/* display overall quest details */} +
+

{quest?.title}

+

{quest?.description}

+ +

Active Participants: {questSubscribers.length}

+
+ + +
+ ); +}; + +export default QuestDetailPage; + +export const getServerSideProps: GetServerSideProps = async ({ req, res }) => { + const session = await getServerSession(req, res, authOptions); + + if (!session) { + return { + redirect: { + destination: "/auth/login", + permanent: false, + }, + }; + } + + return { + props: { session }, + }; +}; diff --git a/frontend/src/pages/quests.tsx b/frontend/src/pages/quests.tsx index adac5de1..68d45982 100644 --- a/frontend/src/pages/quests.tsx +++ b/frontend/src/pages/quests.tsx @@ -7,6 +7,7 @@ import { DashboardLayout, Meta } from "~/components/layouts"; import { Button, Dialog, DialogContent, DialogDescription, DialogTitle, Input } from "~/components/ui"; import { api } from "~/config"; import { useSession } from "next-auth/react"; +import Link from "next/link"; interface IQuest { title: string; @@ -175,6 +176,8 @@ const QuestsPage: NextPage = () => { {" "}

Quests

@@ -273,7 +276,9 @@ const QuestsPage: NextPage = () => { {savedQuests.map((quest) => ( - {quest.title} + + {quest.title} + {quest.description}