feat: fetch user profile on sidebar

This commit is contained in:
Sosokker 2025-02-14 08:06:27 +07:00
parent 8f6488a70d
commit 0c16743230
5 changed files with 65 additions and 8 deletions

View File

@ -1,4 +1,5 @@
import axios from "axios"; import axios from "axios";
import Cookies from "js-cookie";
const axiosInstance = axios.create({ const axiosInstance = axios.create({
baseURL: process.env.NEXT_PUBLIC_BACKEND_URL || "http://localhost:8000", baseURL: process.env.NEXT_PUBLIC_BACKEND_URL || "http://localhost:8000",
@ -9,7 +10,7 @@ const axiosInstance = axios.create({
axiosInstance.interceptors.request.use( axiosInstance.interceptors.request.use(
(config) => { (config) => {
const token = localStorage.getItem("token"); const token = Cookies.get("token");
if (token) { if (token) {
config.headers.Authorization = `Bearer ${token}`; config.headers.Authorization = `Bearer ${token}`;
} }
@ -20,9 +21,7 @@ axiosInstance.interceptors.request.use(
axiosInstance.interceptors.response.use( axiosInstance.interceptors.response.use(
(response) => response, (response) => response,
(error) => { (error) => Promise.reject(error)
return Promise.reject(error);
}
); );
export default axiosInstance; export default axiosInstance;

22
frontend/api/user.ts Normal file
View File

@ -0,0 +1,22 @@
import axios from "axios";
import axiosInstance from "./config";
import { User } from "@/types";
export interface UserDataOutput {
user: User;
}
/**
* Fetches the data for the authenticated user.
*/
export async function fetchUserMe(): Promise<UserDataOutput> {
try {
const response = await axiosInstance.get("/user/me");
return response.data;
} catch (error: any) {
if (axios.isAxiosError(error)) {
throw new Error(error.response?.data?.message || "Failed to fetch user data.");
}
throw error;
}
}

View File

@ -19,12 +19,14 @@ import { NavProjects } from "./nav-projects";
import { NavUser } from "./nav-user"; import { NavUser } from "./nav-user";
import { TeamSwitcher } from "./team-switcher"; import { TeamSwitcher } from "./team-switcher";
import { Sidebar, SidebarContent, SidebarFooter, SidebarHeader, SidebarRail } from "@/components/ui/sidebar"; import { Sidebar, SidebarContent, SidebarFooter, SidebarHeader, SidebarRail } from "@/components/ui/sidebar";
import { useEffect } from "react";
import { fetchUserMe } from "@/api/user";
const data = { const data = {
user: { user: {
name: "shadcn", name: "shadcn",
email: "m@example.com", email: "m@example.com",
avatar: "/avatars/shadcn.jpg", avatar: "/avatars/avatar.webp",
}, },
teams: [ teams: [
{ {
@ -134,6 +136,31 @@ const data = {
}; };
export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) { export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
const [user, setUser] = React.useState<{ name: string; email: string; avatar: string }>({
name: "",
email: "",
avatar: "/avatars/avatar.webp",
});
const [loading, setLoading] = React.useState(true);
const [error, setError] = React.useState("");
useEffect(() => {
async function getUser() {
try {
const data = await fetchUserMe();
let to_set = user;
to_set.name = data.user.UUID;
to_set.email = data.user.Email;
setUser(to_set);
} catch (err: any) {
setError(err.message);
} finally {
setLoading(false);
}
}
getUser();
}, []);
return ( return (
<Sidebar collapsible="icon" {...props}> <Sidebar collapsible="icon" {...props}>
<SidebarHeader> <SidebarHeader>
@ -143,9 +170,7 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
<NavMain items={data.navMain} /> <NavMain items={data.navMain} />
<NavProjects projects={data.projects} /> <NavProjects projects={data.projects} />
</SidebarContent> </SidebarContent>
<SidebarFooter> <SidebarFooter>{loading ? "Loading..." : error ? error : <NavUser user={user} />}</SidebarFooter>
<NavUser user={data.user} />
</SidebarFooter>
<SidebarRail /> <SidebarRail />
</Sidebar> </Sidebar>
); );

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@ -25,3 +25,14 @@ export interface Farm {
type: string; type: string;
createdAt: Date; createdAt: Date;
} }
export interface User {
ID: number;
UUID: string;
Username: string;
Password: string;
Email: string;
CreatedAt: string;
UpdatedAt: string;
IsActive: boolean;
}