feat: refactor class selection handling by introducing user store and updating related components
This commit is contained in:
parent
da74d1bf82
commit
1684ac2743
@ -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>
|
||||
|
@ -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">
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
});
|
||||
|
31
src/app/stores/userStore.ts
Normal file
31
src/app/stores/userStore.ts
Normal 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
5
src/app/types/class.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
interface Class {
|
||||
id: string;
|
||||
name: string;
|
||||
createdAt: string;
|
||||
}
|
Loading…
Reference in New Issue
Block a user