feat: refactor class selection handling by introducing user store and updating related components

This commit is contained in:
Rémi 2025-01-06 00:31:25 +01:00
parent da74d1bf82
commit 1684ac2743
8 changed files with 65 additions and 32 deletions

View File

@ -1,5 +1,4 @@
"use client";
import { useClassStore } from "@/app/stores/classStore";
import { User } from "@/app/types/next-auth";
import { getInitials } from "@/app/utils/initial";
import {
@ -19,19 +18,28 @@ import {
import { useRouter } from "next/navigation";
import { useEffect } from "react";
import { ThemeSwitcher } from "../ThemeSwitcher/ThemeSwitcher";
import { useUserStore } from "@/app/stores/userStore";
import { useClassStore } from "@/app/stores/classStore";
export const HeaderContent = ({ user }: { user?: User }) => {
const router = useRouter();
const { classes, selectedClass, setSelectedClass, fetchClass } =
useClassStore();
const initials = user?.name ? getInitials(user.name) : "";
const { classes, fetchClass } = useClassStore();
const {
currentClassId: selectedClassId,
setCurrentClassId: setSelectedClassId,
} = useUserStore();
useEffect(() => {
fetchClass().then((classesFetched) => {
setSelectedClass(classesFetched[0]);
});
}, [fetchClass, setSelectedClass]);
fetchClass();
}, [fetchClass]);
const selectedClass = classes.find((Class) => Class.id === selectedClassId);
useEffect(() => {
if (!selectedClass && classes.length > 0)
setSelectedClassId(classes[0].id);
}, [selectedClass, classes, setSelectedClassId]);
return (
<Navbar className="mb-2">
@ -46,15 +54,15 @@ export const HeaderContent = ({ user }: { user?: User }) => {
value={selectedClass?.name}
selectedKey={selectedClass?.id}
onSelectionChange={(selectedId) => {
console.log(selectedId);
const inputSelectedClass = classes.find(
(Class) => Class.id === selectedId,
);
setSelectedClass(inputSelectedClass);
if (inputSelectedClass)
setSelectedClassId(inputSelectedClass.id);
}}
>
{classes.map((Class) => (
<AutocompleteItem key={Class.id} isSelected>
<AutocompleteItem key={Class.id}>
{Class.name}
</AutocompleteItem>
))}
@ -86,7 +94,7 @@ export const HeaderContent = ({ user }: { user?: User }) => {
as="button"
className="transition-transform"
color="secondary"
name={initials}
name={user?.name ? getInitials(user.name) : ""}
size="sm"
/>
</DropdownTrigger>

View File

@ -1,16 +1,16 @@
"use client";
import { useRoomStore } from "@/app/stores/roomStore";
import { useUserStore } from "@/app/stores/userStore";
import { useEffect } from "react";
import { RoomList } from "./List";
import { useClassStore } from "@/app/stores/classStore";
export const RoomTable = () => {
const { fetchRooms, actual, future, past } = useRoomStore();
const { selectedClass } = useClassStore();
const { currentClassId: selectedClassId } = useUserStore();
useEffect(() => {
fetchRooms();
}, [fetchRooms, selectedClass]);
if (selectedClassId) fetchRooms();
}, [fetchRooms, selectedClassId]);
return (
<div className="flex flex-col gap-4">

View File

@ -10,7 +10,7 @@ export const Sidebar = () => {
const router = useRouter();
return (
<aside className="fixed top-0 left-0 w-64 h-screen transition-transform -translate-x-full sm:translate-x-0">
<aside className="fixed top-0 left-0 w-64 h-screen">
<div className="flex flex-col gap-2 h-full px-3 py-4 overflow-y-auto bg-foreground-100">
<ul className="font-medium gap-2">
<li>

View File

@ -1,6 +1,5 @@
import { API_URLS } from "../constants/apiUrl.constant";
import { axiosInstance } from "../lib/axios";
import { Class } from "../stores/classStore";
const getAll = () => axiosInstance.get<Class[]>(API_URLS.class.all);

View File

@ -1,24 +1,19 @@
import { create } from "zustand";
import { classService } from "../services/class.service";
export type Class = { id: string; name: string; createdAt: string };
type ClassStoreState = {
classes: Class[];
selectedClass: Class | undefined | null;
};
type ClassStoreActions = {
_setClass: (classes: Class[]) => void;
fetchClass: () => Promise<Class[]>;
setSelectedClass: (selectedClass: Class | undefined | null) => void;
};
type ClassStore = ClassStoreState & ClassStoreActions;
const defaultState: ClassStoreState = {
classes: [],
selectedClass: null,
};
export const useClassStore = create<ClassStore>()((set) => ({
@ -28,11 +23,6 @@ export const useClassStore = create<ClassStore>()((set) => ({
classes: classes,
}));
},
setSelectedClass: (selectedClass: Class | undefined | null) => {
set(() => ({
selectedClass: selectedClass,
}));
},
fetchClass: async () => {
const classResponse = await classService.getAll();
useClassStore.getState()._setClass(classResponse.data);

View File

@ -2,7 +2,7 @@ import moment from "moment";
import { create } from "zustand";
import { Room } from "../components/Room/Room";
import { axiosInstance } from "../lib/axios";
import { useClassStore } from "./classStore";
import { useUserStore } from "./userStore";
type RoomStoreState = {
future: Room[] | null;
@ -38,11 +38,11 @@ export const useRoomStore = create<RoomStore>()((set) => ({
set({ future, actual, past });
},
fetchRooms: () => {
const classSelected = useClassStore.getState().selectedClass;
if (!classSelected) return;
const selectedClassId = useUserStore.getState().currentClassId;
if (!selectedClassId) return;
axiosInstance
.get<Room[]>(`/@me/class/${classSelected.id}/rooms`)
.get<Room[]>(`/@me/class/${selectedClassId}/rooms`)
.then((classes) => {
useRoomStore.getState()._setRooms(classes.data);
});

View File

@ -0,0 +1,31 @@
import { create } from "zustand";
import { persist, createJSONStorage } from "zustand/middleware";
type UserStoreState = {
currentClassId: string | null;
};
type UserStoreActions = {
setCurrentClassId: (classId: string) => void;
};
type UserStore = UserStoreState & UserStoreActions;
const defaultState: UserStoreState = {
currentClassId: null,
};
export const useUserStore = create<UserStore>()(
persist(
(set) => ({
...defaultState,
setCurrentClassId: (classId: string) => {
set({ currentClassId: classId });
},
}),
{
name: "userStore",
storage: createJSONStorage(() => localStorage),
},
),
);

5
src/app/types/class.d.ts vendored Normal file
View File

@ -0,0 +1,5 @@
interface Class {
id: string;
name: string;
createdAt: string;
}