mirror of
https://github.com/ForFarmTeam/ForFarm.git
synced 2025-12-19 22:14:08 +01:00
feat: fetch user profile on sidebar
This commit is contained in:
parent
8f6488a70d
commit
0c16743230
@ -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
22
frontend/api/user.ts
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
BIN
frontend/public/avatars/avatar.webp
Normal file
BIN
frontend/public/avatars/avatar.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.0 KiB |
@ -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;
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user