aboutsummaryrefslogtreecommitdiff
path: root/frontend/src/app
diff options
context:
space:
mode:
authorGravatar Anshul Gupta <ansg191@anshulg.com> 2024-08-11 13:18:04 -0700
committerGravatar Anshul Gupta <ansg191@anshulg.com> 2024-08-11 13:18:04 -0700
commita9ec4cdbdab6f8026128728c34afa3150663a18b (patch)
tree093a91e2b05dec5a27dc373b71a038ebde9ee433 /frontend/src/app
parent32c8b0b24e868505eb46b3dbe2f3e29d467df2e4 (diff)
downloadibd-trader-a9ec4cdbdab6f8026128728c34afa3150663a18b.tar.gz
ibd-trader-a9ec4cdbdab6f8026128728c34afa3150663a18b.tar.zst
ibd-trader-a9ec4cdbdab6f8026128728c34afa3150663a18b.zip
Add new-user screen
Diffstat (limited to 'frontend/src/app')
-rw-r--r--frontend/src/app/api/new-user/add-ibd-creds/route.ts29
-rw-r--r--frontend/src/app/api/new-user/add-ibd-creds/types.ts10
-rw-r--r--frontend/src/app/api/new-user/check-ibd-creds/route.ts22
-rw-r--r--frontend/src/app/api/new-user/verify-username/route.ts14
-rw-r--r--frontend/src/app/api/new-user/verify-username/types.ts11
-rw-r--r--frontend/src/app/dashboard/page.tsx31
-rw-r--r--frontend/src/app/layout.tsx14
-rw-r--r--frontend/src/app/new-user/page.tsx29
8 files changed, 149 insertions, 11 deletions
diff --git a/frontend/src/app/api/new-user/add-ibd-creds/route.ts b/frontend/src/app/api/new-user/add-ibd-creds/route.ts
new file mode 100644
index 0000000..3740b90
--- /dev/null
+++ b/frontend/src/app/api/new-user/add-ibd-creds/route.ts
@@ -0,0 +1,29 @@
+import { NextRequest, NextResponse } from "next/server";
+import { createUserServiceClient } from "@/client/client";
+import { RequestBody, ResponseBody } from "./types";
+import { getSession, withApiAuthRequired } from "@auth0/nextjs-auth0";
+
+export const PUT = withApiAuthRequired(async function(req: NextRequest) {
+ const res = new NextResponse();
+ const session = await getSession(req, res);
+ if (!session || !session.user["sub"]) {
+ return res;
+ }
+
+ const { username, password } = RequestBody.parse(await req.json());
+
+ const client = createUserServiceClient();
+ await client.updateUser({
+ user: {
+ subject: session.user.sub,
+ ibdUsername: username,
+ ibdPassword: password,
+ },
+ updateMask: {
+ paths: ["ibd_username", "ibd_password"],
+ },
+ });
+
+ const ret: ResponseBody = {};
+ return NextResponse.json(ret, { status: 200 });
+});
diff --git a/frontend/src/app/api/new-user/add-ibd-creds/types.ts b/frontend/src/app/api/new-user/add-ibd-creds/types.ts
new file mode 100644
index 0000000..19b25fc
--- /dev/null
+++ b/frontend/src/app/api/new-user/add-ibd-creds/types.ts
@@ -0,0 +1,10 @@
+import { z } from "zod";
+
+export const RequestBody = z.object({
+ username: z.string(),
+ password: z.string(),
+});
+export const ResponseBody = z.object({});
+
+export type RequestBody = z.infer<typeof RequestBody>;
+export type ResponseBody = z.infer<typeof ResponseBody>;
diff --git a/frontend/src/app/api/new-user/check-ibd-creds/route.ts b/frontend/src/app/api/new-user/check-ibd-creds/route.ts
new file mode 100644
index 0000000..837f13a
--- /dev/null
+++ b/frontend/src/app/api/new-user/check-ibd-creds/route.ts
@@ -0,0 +1,22 @@
+import { NextRequest, NextResponse } from "next/server";
+import { createUserServiceClient } from "@/client/client";
+import { getSession, withApiAuthRequired } from "@auth0/nextjs-auth0";
+
+export const PUT = withApiAuthRequired(async function(req: NextRequest) {
+ const res = new NextResponse();
+ const session = await getSession(req, res);
+ if (!session || !session.user["sub"]) {
+ return res;
+ }
+
+ const client = createUserServiceClient();
+ const { authenticated } = await client.authenticateUser({
+ subject: session.user["sub"],
+ });
+
+ if (authenticated) {
+ return new Response(null, { status: 200 });
+ } else {
+ return new Response(null, { status: 401 });
+ }
+});
diff --git a/frontend/src/app/api/new-user/verify-username/route.ts b/frontend/src/app/api/new-user/verify-username/route.ts
new file mode 100644
index 0000000..b60c76e
--- /dev/null
+++ b/frontend/src/app/api/new-user/verify-username/route.ts
@@ -0,0 +1,14 @@
+import { NextRequest, NextResponse } from "next/server";
+import { createUserServiceClient } from "@/client/client";
+import { RequestBody, ResponseBody } from "@/app/api/new-user/verify-username/types";
+import { withApiAuthRequired } from "@auth0/nextjs-auth0";
+
+export const POST = withApiAuthRequired(async function(request: NextRequest) {
+ const { username } = RequestBody.parse(await request.json());
+
+ const client = createUserServiceClient();
+ const { exists } = await client.checkIBDUsername({ ibdUsername: username });
+
+ const ret: ResponseBody = { exists };
+ return NextResponse.json(ret, { status: 200 });
+});
diff --git a/frontend/src/app/api/new-user/verify-username/types.ts b/frontend/src/app/api/new-user/verify-username/types.ts
new file mode 100644
index 0000000..5063da4
--- /dev/null
+++ b/frontend/src/app/api/new-user/verify-username/types.ts
@@ -0,0 +1,11 @@
+import { z } from "zod";
+
+export const RequestBody = z.object({
+ username: z.string(),
+});
+export const ResponseBody = z.object({
+ exists: z.boolean(),
+});
+
+export type RequestBody = z.infer<typeof RequestBody>;
+export type ResponseBody = z.infer<typeof ResponseBody>;
diff --git a/frontend/src/app/dashboard/page.tsx b/frontend/src/app/dashboard/page.tsx
index 8ca17c6..289dcab 100644
--- a/frontend/src/app/dashboard/page.tsx
+++ b/frontend/src/app/dashboard/page.tsx
@@ -1,15 +1,34 @@
import { Metadata } from "next";
-import Link from "next/link";
+import { createUserServiceClient } from "@/client/client";
+import { getSession, withPageAuthRequired } from "@auth0/nextjs-auth0";
+import Layout from "@/components/Layout/Layout";
+import { redirect, RedirectType } from "next/navigation";
+import { red } from "next/dist/lib/picocolors";
export const metadata: Metadata = {
title: "IBD Trader Dashboard",
};
-export default function Dashboard() {
+export default withPageAuthRequired(async function Dashboard() {
+ const client = createUserServiceClient();
+
+ const user = await getSession();
+ if (!user) {
+ redirect("/api/auth/login", RedirectType.replace);
+ }
+
+ const dbUser = await client.createUser({
+ subject: user.user["sub"],
+ });
+
+ // Check if user has IBD credentials
+ if (!dbUser.user || !dbUser.user.ibdUsername) {
+ redirect("/new-user", RedirectType.replace);
+ }
+
return (
- <div>
+ <Layout>
<h1>Dashboard</h1>
- <Link href="/api/auth/logout">Logout</Link>
- </div>
+ </Layout>
);
-}
+}, { returnTo: "/dashboard" });
diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx
index 7eae606..bb15d68 100644
--- a/frontend/src/app/layout.tsx
+++ b/frontend/src/app/layout.tsx
@@ -2,6 +2,10 @@ import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import { UserProvider } from "@auth0/nextjs-auth0/client";
+import { config } from "@fortawesome/fontawesome-svg-core";
+import "@fortawesome/fontawesome-svg-core/styles.css";
+
+config.autoAddCss = false;
const inter = Inter({ subsets: ["latin"] });
@@ -11,13 +15,13 @@ export const metadata: Metadata = {
};
export default function RootLayout({
- children,
-}: Readonly<{ children: React.ReactNode }>) {
+ children,
+ }: Readonly<{ children: React.ReactNode }>) {
return (
<html lang="en">
- <UserProvider>
- <body className={inter.className}>{children}</body>
- </UserProvider>
+ <UserProvider>
+ <body className={inter.className}>{children}</body>
+ </UserProvider>
</html>
);
}
diff --git a/frontend/src/app/new-user/page.tsx b/frontend/src/app/new-user/page.tsx
new file mode 100644
index 0000000..57fcf82
--- /dev/null
+++ b/frontend/src/app/new-user/page.tsx
@@ -0,0 +1,29 @@
+import { Metadata } from "next";
+import { getSession, withPageAuthRequired } from "@auth0/nextjs-auth0";
+import { redirect, RedirectType } from "next/navigation";
+import { createUserServiceClient } from "@/client/client";
+import NewUserForm from "@/components/NewUserForm/NewUserForm";
+
+export const metadata: Metadata = {
+ title: "New User",
+};
+
+export default withPageAuthRequired(async function NewUser() {
+ const session = await getSession();
+ if (!session) {
+ redirect("/api/auth/login", RedirectType.replace);
+ }
+
+ const client = createUserServiceClient();
+ const { user } = await client.getUser({ subject: session.user["sub"] });
+ if (!user) {
+ throw new Error("User not found");
+ }
+
+ if (user.ibdUsername) {
+ // User already has IBD credentials
+ redirect("/dashboard", RedirectType.replace);
+ }
+
+ return <NewUserForm />;
+});