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 Cookies from "js-cookie";
const axiosInstance = axios.create({
baseURL: process.env.NEXT_PUBLIC_BACKEND_URL || "http://localhost:8000",
@ -9,7 +10,7 @@ const axiosInstance = axios.create({
axiosInstance.interceptors.request.use(
(config) => {
const token = localStorage.getItem("token");
const token = Cookies.get("token");
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
@ -20,9 +21,7 @@ axiosInstance.interceptors.request.use(
axiosInstance.interceptors.response.use(
(response) => response,
(error) => {
return Promise.reject(error);
}
(error) => Promise.reject(error)
);
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 { TeamSwitcher } from "./team-switcher";
import { Sidebar, SidebarContent, SidebarFooter, SidebarHeader, SidebarRail } from "@/components/ui/sidebar";
import { useEffect } from "react";
import { fetchUserMe } from "@/api/user";
const data = {
user: {
name: "shadcn",
email: "m@example.com",
avatar: "/avatars/shadcn.jpg",
avatar: "/avatars/avatar.webp",
},
teams: [
{
@ -134,6 +136,31 @@ const data = {
};
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 (
<Sidebar collapsible="icon" {...props}>
<SidebarHeader>
@ -143,9 +170,7 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
<NavMain items={data.navMain} />
<NavProjects projects={data.projects} />
</SidebarContent>
<SidebarFooter>
<NavUser user={data.user} />
</SidebarFooter>
<SidebarFooter>{loading ? "Loading..." : error ? error : <NavUser user={user} />}</SidebarFooter>
<SidebarRail />
</Sidebar>
);

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

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