fix(build): restore dashboard layout + api client compatibility
This commit is contained in:
parent
7912b44f8d
commit
e2c91fb413
2 changed files with 111 additions and 0 deletions
66
src/components/DashboardLayout.tsx
Normal file
66
src/components/DashboardLayout.tsx
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
import { type ParentProps, createMemo } from "solid-js";
|
||||||
|
import { useLocation, useNavigate } from "@solidjs/router";
|
||||||
|
import DashboardShell from "~/components/DashboardShell";
|
||||||
|
|
||||||
|
const SIDEBAR_ITEMS = [
|
||||||
|
"My Dashboard",
|
||||||
|
"Leads",
|
||||||
|
"My Requests",
|
||||||
|
"Credits",
|
||||||
|
"Settings",
|
||||||
|
"Logout",
|
||||||
|
];
|
||||||
|
|
||||||
|
const ROUTE_BY_LABEL: Record<string, string> = {
|
||||||
|
"my dashboard": "/dashboard",
|
||||||
|
leads: "/dashboard/leads",
|
||||||
|
"my requests": "/dashboard/requests",
|
||||||
|
credits: "/dashboard/credits",
|
||||||
|
settings: "/dashboard/settings",
|
||||||
|
logout: "/dashboard/logout",
|
||||||
|
};
|
||||||
|
|
||||||
|
function readUserName() {
|
||||||
|
if (typeof window === "undefined") return "User";
|
||||||
|
try {
|
||||||
|
const raw =
|
||||||
|
localStorage.getItem("nxtgauge_auth_user") ||
|
||||||
|
localStorage.getItem("nxtgauge_user");
|
||||||
|
if (!raw) return "User";
|
||||||
|
const parsed = JSON.parse(raw);
|
||||||
|
return parsed?.full_name || parsed?.name || parsed?.email || "User";
|
||||||
|
} catch {
|
||||||
|
return "User";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function DashboardLayout(props: ParentProps) {
|
||||||
|
const location = useLocation();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const activeSidebar = createMemo(() => {
|
||||||
|
const path = location.pathname || "";
|
||||||
|
if (path.startsWith("/dashboard/requests")) return "My Requests";
|
||||||
|
if (path.startsWith("/dashboard/leads")) return "Leads";
|
||||||
|
if (path.startsWith("/dashboard/credits")) return "Credits";
|
||||||
|
if (path.startsWith("/dashboard/settings")) return "Settings";
|
||||||
|
return "My Dashboard";
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleSidebarSelect = (item: string) => {
|
||||||
|
const target = ROUTE_BY_LABEL[item.toLowerCase()];
|
||||||
|
if (target) navigate(target);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DashboardShell
|
||||||
|
sidebarItems={SIDEBAR_ITEMS}
|
||||||
|
activeSidebar={activeSidebar()}
|
||||||
|
onSidebarSelect={handleSidebarSelect}
|
||||||
|
roleKey="PROFESSIONAL"
|
||||||
|
userName={readUserName()}
|
||||||
|
>
|
||||||
|
{props.children}
|
||||||
|
</DashboardShell>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -24,6 +24,51 @@ async function apiFetch(path: string, options?: RequestInit): Promise<any> {
|
||||||
return res.json();
|
return res.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ApiResponse<T = any> = {
|
||||||
|
data: T;
|
||||||
|
status: number;
|
||||||
|
headers: Headers;
|
||||||
|
};
|
||||||
|
|
||||||
|
async function request<T = any>(
|
||||||
|
path: string,
|
||||||
|
options?: { method?: string; body?: unknown; headers?: HeadersInit }
|
||||||
|
): Promise<ApiResponse<T>> {
|
||||||
|
const mergedHeaders: HeadersInit = {
|
||||||
|
...getAuthHeaders(),
|
||||||
|
...(options?.headers || {}),
|
||||||
|
};
|
||||||
|
const init: RequestInit = {
|
||||||
|
method: options?.method || "GET",
|
||||||
|
headers: mergedHeaders,
|
||||||
|
credentials: "include",
|
||||||
|
};
|
||||||
|
if (options?.body !== undefined) {
|
||||||
|
init.body = JSON.stringify(options.body);
|
||||||
|
}
|
||||||
|
const res = await fetch(`${API}${path}`, init);
|
||||||
|
const raw = await res.text();
|
||||||
|
const data = raw ? JSON.parse(raw) : null;
|
||||||
|
if (!res.ok) {
|
||||||
|
const message = (data && (data.message || data.error)) || `API error ${res.status}`;
|
||||||
|
throw new Error(message);
|
||||||
|
}
|
||||||
|
return { data: data as T, status: res.status, headers: res.headers };
|
||||||
|
}
|
||||||
|
|
||||||
|
export const api = {
|
||||||
|
get: <T = any>(path: string, headers?: HeadersInit) =>
|
||||||
|
request<T>(path, { method: "GET", headers }),
|
||||||
|
post: <T = any>(path: string, body?: unknown, headers?: HeadersInit) =>
|
||||||
|
request<T>(path, { method: "POST", body, headers }),
|
||||||
|
put: <T = any>(path: string, body?: unknown, headers?: HeadersInit) =>
|
||||||
|
request<T>(path, { method: "PUT", body, headers }),
|
||||||
|
patch: <T = any>(path: string, body?: unknown, headers?: HeadersInit) =>
|
||||||
|
request<T>(path, { method: "PATCH", body, headers }),
|
||||||
|
delete: <T = any>(path: string, headers?: HeadersInit) =>
|
||||||
|
request<T>(path, { method: "DELETE", headers }),
|
||||||
|
};
|
||||||
|
|
||||||
export async function fetchProfile(rolePrefix: string): Promise<any> {
|
export async function fetchProfile(rolePrefix: string): Promise<any> {
|
||||||
return apiFetch(`/api/${rolePrefix}/profile/me`);
|
return apiFetch(`/api/${rolePrefix}/profile/me`);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue