diff options
author | 2024-08-11 13:18:04 -0700 | |
---|---|---|
committer | 2024-08-11 13:18:04 -0700 | |
commit | a9ec4cdbdab6f8026128728c34afa3150663a18b (patch) | |
tree | 093a91e2b05dec5a27dc373b71a038ebde9ee433 /frontend/src/app | |
parent | 32c8b0b24e868505eb46b3dbe2f3e29d467df2e4 (diff) | |
download | ibd-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.ts | 29 | ||||
-rw-r--r-- | frontend/src/app/api/new-user/add-ibd-creds/types.ts | 10 | ||||
-rw-r--r-- | frontend/src/app/api/new-user/check-ibd-creds/route.ts | 22 | ||||
-rw-r--r-- | frontend/src/app/api/new-user/verify-username/route.ts | 14 | ||||
-rw-r--r-- | frontend/src/app/api/new-user/verify-username/types.ts | 11 | ||||
-rw-r--r-- | frontend/src/app/dashboard/page.tsx | 31 | ||||
-rw-r--r-- | frontend/src/app/layout.tsx | 14 | ||||
-rw-r--r-- | frontend/src/app/new-user/page.tsx | 29 |
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 />; +}); |