From 29777da43057ac894afb6497a44ccd3451d2a9c0 Mon Sep 17 00:00:00 2001 From: Milo Schwartz Date: Sun, 6 Oct 2024 12:39:05 -0400 Subject: [PATCH] added axios client --- server/environment.ts | 13 ++++++- server/index.ts | 3 ++ server/middlewares/notFound.ts | 7 ++-- src/api/index.ts | 11 ++++++ src/app/auth/login/page.tsx | 18 ++++++++-- src/app/globals.css | 64 +++++++++++++++++----------------- src/app/layout.tsx | 6 ++-- 7 files changed, 81 insertions(+), 41 deletions(-) create mode 100644 src/api/index.ts diff --git a/server/environment.ts b/server/environment.ts index ed99f4e5..b8353b10 100644 --- a/server/environment.ts +++ b/server/environment.ts @@ -43,7 +43,17 @@ const environmentSchema = z.object({ .pipe(z.number().optional()), EMAIL_SMTP_USER: z.string().optional(), EMAIL_SMTP_PASS: z.string().optional(), - EMAIL_NOREPLY: z.string().optional(), + EMAIL_NOREPLY: z.string().email().optional(), + SITE_DOMAIN: z + .string() + .optional() + .transform((val) => { + if (!val) { + return `http://localhost:${environment.EXTERNAL_PORT}`; + } + return val; + }) + .pipe(z.string().url()), }); const environment = { @@ -63,6 +73,7 @@ const environment = { EMAIL_SMTP_USER: process.env.EMAIL_SMTP_USER as string, EMAIL_SMTP_PASS: process.env.EMAIL_SMTP_PASS as string, EMAIL_NOREPLY: process.env.EMAIL_NOREPLY as string, + SITE_DOMAIN: process.env.NEXT_PUBLIC_SITE_DOMAIN as string, }; const parsedConfig = environmentSchema.safeParse(environment); diff --git a/server/index.ts b/server/index.ts index ff432824..120e1400 100644 --- a/server/index.ts +++ b/server/index.ts @@ -7,6 +7,7 @@ import helmet from "helmet"; import cors from "cors"; import { errorHandlerMiddleware, + notFoundMiddleware, rateLimitMiddleware, } from "@server/middlewares"; import internal from "@server/routers/internal"; @@ -42,6 +43,8 @@ app.prepare().then(() => { externalServer.use(prefix, unauthenticated); externalServer.use(prefix, authenticated); + externalServer.use(notFoundMiddleware) + // We are using NEXT from here on externalServer.all("*", (req: Request, res: Response) => { const parsedUrl = parse(req.url!, true); diff --git a/server/middlewares/notFound.ts b/server/middlewares/notFound.ts index 2d20b27c..706796c9 100644 --- a/server/middlewares/notFound.ts +++ b/server/middlewares/notFound.ts @@ -7,8 +7,11 @@ export function notFoundMiddleware( res: Response, next: NextFunction, ) { - const message = `The requests url is not found - ${req.originalUrl}`; - return next(createHttpError(HttpCode.NOT_FOUND, message)); + if (req.path.startsWith("/api")) { + const message = `The requests url is not found - ${req.originalUrl}`; + return next(createHttpError(HttpCode.NOT_FOUND, message)); + } + return next(); } export default notFoundMiddleware; diff --git a/src/api/index.ts b/src/api/index.ts new file mode 100644 index 00000000..dac704e5 --- /dev/null +++ b/src/api/index.ts @@ -0,0 +1,11 @@ +import axios from "axios"; + +export const api = axios.create({ + baseURL: `http://${process.env.NEXT_PUBLIC_SITE_DOMAIN || "localhost:3000"}/api/v1`, + timeout: 10000, + headers: { + "Content-Type": "application/json", + }, +}); + +export default api; diff --git a/src/app/auth/login/page.tsx b/src/app/auth/login/page.tsx index 9c4d53a5..964d02be 100644 --- a/src/app/auth/login/page.tsx +++ b/src/app/auth/login/page.tsx @@ -24,6 +24,8 @@ import { } from "@/components/ui/card"; import { Alert, AlertDescription } from "@/components/ui/alert"; import { ExclamationTriangleIcon } from "@radix-ui/react-icons"; +import api from "@app/api"; +import { LoginBody, LoginResponse } from "@server/routers/auth"; const formSchema = z.object({ email: z.string().email({ message: "Invalid email address" }), @@ -43,9 +45,19 @@ export default function LoginForm() { }, }); - function onSubmit(values: z.infer) { - console.log(values); - setError("Invalid email or password. Please try again."); + async function onSubmit(values: z.infer) { + const { email, password } = values; + const res = await api + .post("/auth/login", { + email, + password, + }) + .catch((e) => { + setError( + e.response?.data?.message || + "An error occurred while logging in", + ); + }); } return ( diff --git a/src/app/globals.css b/src/app/globals.css index 5965ac69..b3a6afb2 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -3,47 +3,47 @@ @tailwind utilities; @layer base { :root { - --background: 28.4 100% 100%; - --foreground: 28.4 5% 10%; - --card: 28.4 50% 100%; - --card-foreground: 28.4 5% 15%; - --popover: 28.4 100% 100%; - --popover-foreground: 28.4 100% 10%; - --primary: 28.4 72.5% 25.7%; + --background: 31 100% 100%; + --foreground: 31 5% 10%; + --card: 31 50% 100%; + --card-foreground: 31 5% 15%; + --popover: 31 100% 100%; + --popover-foreground: 31 100% 10%; + --primary: 31 11% 28%; --primary-foreground: 0 0% 100%; - --secondary: 28.4 30% 90%; + --secondary: 31 30% 90%; --secondary-foreground: 0 0% 0%; - --muted: -9.600000000000001 30% 95%; - --muted-foreground: 28.4 5% 40%; - --accent: -9.600000000000001 30% 90%; - --accent-foreground: 28.4 5% 15%; + --muted: -7 30% 95%; + --muted-foreground: 31 5% 40%; + --accent: -7 30% 90%; + --accent-foreground: 31 5% 15%; --destructive: 0 100% 50%; - --destructive-foreground: 28.4 5% 100%; - --border: 28.4 30% 82%; - --input: 28.4 30% 50%; - --ring: 28.4 72.5% 25.7%; + --destructive-foreground: 31 5% 100%; + --border: 31 30% 82%; + --input: 31 30% 50%; + --ring: 31 11% 28%; --radius: 0rem; } .dark { - --background: 28.4 50% 10%; - --foreground: 28.4 5% 100%; - --card: 28.4 50% 10%; - --card-foreground: 28.4 5% 100%; - --popover: 28.4 50% 5%; - --popover-foreground: 28.4 5% 100%; - --primary: 28.4 72.5% 25.7%; + --background: 31 50% 10%; + --foreground: 31 5% 100%; + --card: 31 50% 10%; + --card-foreground: 31 5% 100%; + --popover: 31 50% 5%; + --popover-foreground: 31 5% 100%; + --primary: 31 11% 28%; --primary-foreground: 0 0% 100%; - --secondary: 28.4 30% 20%; + --secondary: 31 30% 20%; --secondary-foreground: 0 0% 100%; - --muted: -9.600000000000001 30% 25%; - --muted-foreground: 28.4 5% 65%; - --accent: -9.600000000000001 30% 25%; - --accent-foreground: 28.4 5% 95%; + --muted: -7 30% 25%; + --muted-foreground: 31 5% 65%; + --accent: -7 30% 25%; + --accent-foreground: 31 5% 95%; --destructive: 0 100% 50%; - --destructive-foreground: 28.4 5% 100%; - --border: 28.4 30% 50%; - --input: 28.4 30% 50%; - --ring: 28.4 72.5% 25.7%; + --destructive-foreground: 31 5% 100%; + --border: 31 30% 50%; + --input: 31 30% 50%; + --ring: 31 11% 28%; --radius: 0rem; } } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 8ca3ad2b..e8aa54f8 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,13 +1,13 @@ import type { Metadata } from "next"; import "./globals.css"; -import { Noto_Sans } from "next/font/google"; +import { Roboto } from "next/font/google"; export const metadata: Metadata = { title: "Pangolin", description: "", }; -const inter = Noto_Sans({ subsets: ["latin"] }); +const font = Roboto({ subsets: ["latin"], style: "normal", weight: "400" }); export default function RootLayout({ children, @@ -16,7 +16,7 @@ export default function RootLayout({ }>) { return ( - +
{children}