diff --git a/services/frontend/src/app/dashboard/layout.tsx b/services/frontend/src/app/dashboard/layout.tsx
index 16ae6a2..cfdeb1b 100644
--- a/services/frontend/src/app/dashboard/layout.tsx
+++ b/services/frontend/src/app/dashboard/layout.tsx
@@ -7,32 +7,8 @@ import { Header } from "@/components/layout/header";
import { MobileTabBar } from "@/components/layout/mobile-tab-bar";
import { Sidebar } from "@/components/layout/sidebar";
import { MascotChatbot } from "@/features/mascot/mascot-chatbot";
-import { AuthProvider, useAuth } from "@/lib/hooks/use-auth";
import { WsProvider } from "@/lib/ws/context";
-function DashboardGuard({ children }: { children: React.ReactNode }) {
- const { authenticated, loading } = useAuth();
- const router = useRouter();
-
- useEffect(() => {
- if (!loading && !authenticated) {
- router.push("/");
- }
- }, [authenticated, loading, router]);
-
- if (loading) {
- return (
-
- );
- }
-
- if (!authenticated) return null;
-
- return <>{children}>;
-}
-
function DashboardShell({ children }: { children: React.ReactNode }) {
const searchParams = useSearchParams();
const router = useRouter();
@@ -49,7 +25,7 @@ function DashboardShell({ children }: { children: React.ReactNode }) {
const tabParam = searchParams.get("tab");
if (tabParam) {
restored.current = true;
- return; // explicit tab in URL — don't override
+ return;
}
uiStateApi
.get()
@@ -89,21 +65,17 @@ export default function DashboardLayout({
children: React.ReactNode;
}) {
return (
-
-
-
-
-
-
- }
- >
- {children}
-
-
-
-
-
+
+
+
+
+ }
+ >
+ {children}
+
+
+
);
}
diff --git a/services/frontend/src/app/page.tsx b/services/frontend/src/app/page.tsx
index b7536ff..485bdc5 100644
--- a/services/frontend/src/app/page.tsx
+++ b/services/frontend/src/app/page.tsx
@@ -1,103 +1,5 @@
-"use client";
+import { redirect } from "next/navigation";
-import { Loader2, Shield } from "lucide-react";
-import { useRouter } from "next/navigation";
-import { useEffect, useState } from "react";
-import { login } from "@/lib/api";
-
-export default function LoginPage() {
- const [password, setPassword] = useState("");
- const [error, setError] = useState("");
- const [loading, setLoading] = useState(false);
- const [checking, setChecking] = useState(true);
- const router = useRouter();
-
- useEffect(() => {
- const stored = localStorage.getItem("admin-password");
- if (stored) {
- login(stored)
- .then((ok) => {
- if (ok) router.replace("/dashboard");
- else setChecking(false);
- })
- .catch(() => setChecking(false));
- } else {
- setChecking(false);
- }
- }, [router]);
-
- const handleSubmit = async (e: React.FormEvent) => {
- e.preventDefault();
- setError("");
- setLoading(true);
-
- try {
- const ok = await login(password);
- if (ok) {
- localStorage.setItem("admin-password", password);
- router.push("/dashboard");
- } else {
- setError("Invalid password");
- }
- } catch {
- setError("Connection failed. Is the backend running?");
- } finally {
- setLoading(false);
- }
- };
-
- if (checking) {
- return (
-
-
-
- );
- }
-
- return (
-
-
-
-
-
-
-
Bete
-
- Discord Moderation Dashboard
-
-
-
-
-
-
- );
+export default function RootPage() {
+ redirect("/dashboard?tab=messages");
}
diff --git a/services/frontend/src/components/layout/sidebar.tsx b/services/frontend/src/components/layout/sidebar.tsx
index caf4249..d47fcc6 100644
--- a/services/frontend/src/components/layout/sidebar.tsx
+++ b/services/frontend/src/components/layout/sidebar.tsx
@@ -1,8 +1,7 @@
"use client";
-import { LayoutDashboard, LogOut, MessageSquare, Radio } from "lucide-react";
+import { LayoutDashboard, MessageSquare, Radio } from "lucide-react";
import { useRouter } from "next/navigation";
-import { useAuth } from "@/lib/hooks/use-auth";
const tabs = [
{ id: "messages", label: "Messages", icon: MessageSquare },
@@ -13,7 +12,6 @@ const tabs = [
type TabId = (typeof tabs)[number]["id"];
export function Sidebar({ activeTab }: { activeTab: TabId }) {
- const { logout } = useAuth();
const router = useRouter();
const handleTabClick = (tabId: TabId) => {
@@ -43,17 +41,6 @@ export function Sidebar({ activeTab }: { activeTab: TabId }) {
))}
-
-
-
-
);
}
diff --git a/services/frontend/src/lib/api/auth.ts b/services/frontend/src/lib/api/auth.ts
deleted file mode 100644
index 835387e..0000000
--- a/services/frontend/src/lib/api/auth.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { ApiError, api } from "./client";
-
-export async function login(password: string): Promise {
- try {
- const resp = await api.post<{ ok: boolean }>("/api/auth/login", {
- password,
- });
- return resp.ok;
- } catch (err) {
- if (err instanceof ApiError) return false;
- throw err;
- }
-}
diff --git a/services/frontend/src/lib/api/client.ts b/services/frontend/src/lib/api/client.ts
index dc08dbd..0f3dfd2 100644
--- a/services/frontend/src/lib/api/client.ts
+++ b/services/frontend/src/lib/api/client.ts
@@ -12,27 +12,17 @@ function getBaseUrl(): string {
if (typeof window === "undefined") return "";
const protocol = window.location.protocol.replace(":", "");
const host = window.location.host;
- // In dev, Next.js proxy can be configured, but default to same-host assumption
return `${protocol}://${host}`;
}
-function getAuthHeader(): string | null {
- if (typeof window === "undefined") return null;
- return localStorage.getItem("admin-password");
-}
-
export async function apiRequest(
method: string,
path: string,
body?: unknown,
): Promise {
const url = `${getBaseUrl()}${path}`;
- const password = getAuthHeader();
const headers: Record = {};
- if (password) {
- headers["X-Admin-Password"] = password;
- }
if (body !== undefined) {
headers["Content-Type"] = "application/json";
}
diff --git a/services/frontend/src/lib/api/index.ts b/services/frontend/src/lib/api/index.ts
index 390d1a0..db424fd 100644
--- a/services/frontend/src/lib/api/index.ts
+++ b/services/frontend/src/lib/api/index.ts
@@ -1,4 +1,3 @@
-export { login } from "./auth";
export { ApiError, api, apiRequest } from "./client";
export { configApi } from "./config";
export { dashboardApi } from "./dashboard";
diff --git a/services/frontend/src/lib/hooks/use-auth.tsx b/services/frontend/src/lib/hooks/use-auth.tsx
deleted file mode 100644
index da25daa..0000000
--- a/services/frontend/src/lib/hooks/use-auth.tsx
+++ /dev/null
@@ -1,78 +0,0 @@
-"use client";
-
-import {
- createContext,
- type ReactNode,
- useCallback,
- useContext,
- useEffect,
- useState,
-} from "react";
-import { login } from "@/lib/api";
-
-interface AuthContextValue {
- authenticated: boolean;
- loading: boolean;
- login: (password: string) => Promise;
- logout: () => void;
-}
-
-const AuthContext = createContext(null);
-
-export function AuthProvider({ children }: { children: ReactNode }) {
- const [authenticated, setAuthenticated] = useState(false);
- const [loading, setLoading] = useState(true);
-
- useEffect(() => {
- const password = localStorage.getItem("admin-password");
- if (password) {
- // Verify stored password still works
- login(password)
- .then((ok) => {
- setAuthenticated(ok);
- setLoading(false);
- })
- .catch(() => {
- localStorage.removeItem("admin-password");
- setLoading(false);
- });
- } else {
- setLoading(false);
- }
- }, []);
-
- const handleLogin = useCallback(async (password: string) => {
- const ok = await login(password);
- if (ok) {
- localStorage.setItem("admin-password", password);
- setAuthenticated(true);
- }
- return ok;
- }, []);
-
- const handleLogout = useCallback(() => {
- localStorage.removeItem("admin-password");
- setAuthenticated(false);
- }, []);
-
- return (
-
- {children}
-
- );
-}
-
-export function useAuth(): AuthContextValue {
- const ctx = useContext(AuthContext);
- if (!ctx) {
- throw new Error("useAuth must be used within an AuthProvider");
- }
- return ctx;
-}