diff --git a/apps/frontend/src/app/dashboard/login/page.tsx b/apps/frontend/src/app/dashboard/login/page.tsx
new file mode 100644
index 00000000..1d2fd80f
--- /dev/null
+++ b/apps/frontend/src/app/dashboard/login/page.tsx
@@ -0,0 +1,5 @@
+import { LoginForm } from "src/components/login/LoginForm";
+
+export default async function Page() {
+ return ;
+}
diff --git a/apps/frontend/src/app/page.tsx b/apps/frontend/src/app/page.tsx
index ac9edc63..aa2ab86f 100644
--- a/apps/frontend/src/app/page.tsx
+++ b/apps/frontend/src/app/page.tsx
@@ -2,5 +2,5 @@ import { redirect } from "next/navigation";
import { toPage } from "src/utils/next/toPage";
export default async function Page() {
- redirect(toPage("dashboard"));
+ redirect(toPage("accounts"));
}
diff --git a/apps/frontend/src/components/login/LoginForm.tsx b/apps/frontend/src/components/login/LoginForm.tsx
index fc3b2e5b..6e8272d5 100644
--- a/apps/frontend/src/components/login/LoginForm.tsx
+++ b/apps/frontend/src/components/login/LoginForm.tsx
@@ -1,12 +1,25 @@
+"use client";
+
import Sheet from "@mui/joy/Sheet";
import Typography from "@mui/joy/Typography";
import FormControl from "@mui/joy/FormControl";
import FormLabel from "@mui/joy/FormLabel";
import Input from "@mui/joy/Input";
import Button from "@mui/joy/Button";
-import Link from "@mui/joy/Link";
+import { useRouter } from "next/navigation";
+import { useState } from "react";
+import { toPage } from "src/utils/next/toPage";
export function LoginForm() {
+ const [email, setEmail] = useState("opentrader");
+ const [password, setPassword] = useState("");
+ const router = useRouter();
+
+ const handleLogin = () => {
+ window.localStorage.setItem("ADMIN_PASSWORD", password);
+ router.replace(toPage("grid-bot"));
+ };
+
return (
- Welcome!
+ Welcome Trader!
Sign in to continue.
- Email
+ Username
-
+ setEmail(e.target.value)}
+ placeholder="username"
+ type="text"
+ value={email}
+ />
Password
-
+ setPassword(e.target.value)}
+ />
-
-
-
-
-
-
-
- Sign up}
- fontSize="sm"
- sx={{
- alignSelf: "center",
- }}
- >
- Don't have an account?
-
);
}
diff --git a/apps/frontend/src/providers/TrpcProvider.tsx b/apps/frontend/src/providers/TrpcProvider.tsx
index 25e85375..fb9127a3 100644
--- a/apps/frontend/src/providers/TrpcProvider.tsx
+++ b/apps/frontend/src/providers/TrpcProvider.tsx
@@ -14,6 +14,9 @@ import { isTRPCError } from "src/ui/errors/utils";
import { useTRPCErrorModal } from "src/ui/errors/api";
import { tClient } from "src/lib/trpc/client";
import { getBaseUrl } from "src/lib/trpc/getBaseUrl";
+import { isUnauthorizedError } from "src/ui/errors/utils/isUnauthorizedError";
+import { isLoginPage } from "src/utils/auth/isLoginPage";
+import { toPage } from "src/utils/next/toPage";
export const TrpcProvider: React.FC<{ children: React.ReactNode }> = ({
children,
@@ -26,6 +29,11 @@ export const TrpcProvider: React.FC<{ children: React.ReactNode }> = ({
queryCache: new QueryCache({
onError: (error) => {
if (isTRPCError(error)) {
+ if (isUnauthorizedError(error) && !isLoginPage()) {
+ window.location.href = toPage("login");
+ return;
+ }
+
showErrorModal(error);
}
},
diff --git a/apps/frontend/src/ui/errors/utils/isUnauthorizedError.ts b/apps/frontend/src/ui/errors/utils/isUnauthorizedError.ts
new file mode 100644
index 00000000..f9b3567a
--- /dev/null
+++ b/apps/frontend/src/ui/errors/utils/isUnauthorizedError.ts
@@ -0,0 +1,10 @@
+import { TRPC_ERROR_CODES_BY_KEY } from "@trpc/server/rpc";
+import type { TRPCApiError } from "src/ui/errors/types";
+
+export function isUnauthorizedError(error: TRPCApiError) {
+ return (
+ "code" in error.shape &&
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- shape is any
+ error.shape.code === TRPC_ERROR_CODES_BY_KEY.UNAUTHORIZED
+ );
+}
diff --git a/apps/frontend/src/utils/auth/isLoginPage.ts b/apps/frontend/src/utils/auth/isLoginPage.ts
new file mode 100644
index 00000000..6a232032
--- /dev/null
+++ b/apps/frontend/src/utils/auth/isLoginPage.ts
@@ -0,0 +1,5 @@
+import { toPage } from "src/utils/next/toPage";
+
+export function isLoginPage() {
+ return window.location.pathname === toPage("login");
+}
diff --git a/apps/frontend/src/utils/next/toPage.ts b/apps/frontend/src/utils/next/toPage.ts
index d5c7218b..57a754b7 100644
--- a/apps/frontend/src/utils/next/toPage.ts
+++ b/apps/frontend/src/utils/next/toPage.ts
@@ -1,4 +1,5 @@
const routes = {
+ login: "/dashboard/login",
dashboard: "/dashboard",
accounts: "/dashboard/accounts",
"bot/:id": (botId: number) => {