feat: add class selection functionality to header and room table components
This commit is contained in:
parent
434414d99d
commit
ff82486134
@ -1,6 +1,8 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import { User } from "@/app/types/next-auth";
|
import { User } from "@/app/types/next-auth";
|
||||||
import {
|
import {
|
||||||
|
Autocomplete,
|
||||||
|
AutocompleteItem,
|
||||||
Avatar,
|
Avatar,
|
||||||
Button,
|
Button,
|
||||||
Dropdown,
|
Dropdown,
|
||||||
@ -14,6 +16,8 @@ import {
|
|||||||
} from "@nextui-org/react";
|
} from "@nextui-org/react";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { ThemeSwitcher } from "../ThemeSwitcher/ThemeSwitcher";
|
import { ThemeSwitcher } from "../ThemeSwitcher/ThemeSwitcher";
|
||||||
|
import { useClassStore } from "@/app/stores/classStore";
|
||||||
|
import { useEffect, useRef } from "react";
|
||||||
|
|
||||||
const getInitials = (name: string) => {
|
const getInitials = (name: string) => {
|
||||||
if (!name) return "";
|
if (!name) return "";
|
||||||
@ -31,15 +35,46 @@ const getInitials = (name: string) => {
|
|||||||
|
|
||||||
export const Header = ({ user }: { user?: User }) => {
|
export const Header = ({ user }: { user?: User }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const { classes, selectedClass, setSelectedClass, fetchClass } =
|
||||||
|
useClassStore();
|
||||||
|
const listClassesRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
const initials = user?.name ? getInitials(user.name) : "";
|
const initials = user?.name ? getInitials(user.name) : "";
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchClass().then(() => {
|
||||||
|
if (selectedClass) setSelectedClass(classes[0]);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Navbar className="mb-2">
|
<Navbar className="mb-2">
|
||||||
<NavbarBrand>
|
<NavbarBrand>
|
||||||
<p className="font-bold text-inherit">Toogether</p>
|
<p className="font-bold text-inherit">Toogether</p>
|
||||||
</NavbarBrand>
|
</NavbarBrand>
|
||||||
|
|
||||||
|
<NavbarContent as="div" justify="center">
|
||||||
|
<Autocomplete
|
||||||
|
ref={listClassesRef}
|
||||||
|
size="sm"
|
||||||
|
label="Select an class"
|
||||||
|
value={selectedClass?.name}
|
||||||
|
onSelectionChange={(selectedId) => {
|
||||||
|
console.log(selectedId);
|
||||||
|
const inputSelectedClass = classes.find(
|
||||||
|
(Class) => Class.id === selectedId,
|
||||||
|
);
|
||||||
|
setSelectedClass(inputSelectedClass);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{classes.map((Class) => (
|
||||||
|
<AutocompleteItem key={Class.id} isSelected>
|
||||||
|
{Class.name}
|
||||||
|
</AutocompleteItem>
|
||||||
|
))}
|
||||||
|
</Autocomplete>
|
||||||
|
</NavbarContent>
|
||||||
|
|
||||||
<NavbarContent as="div" justify="end">
|
<NavbarContent as="div" justify="end">
|
||||||
{user?.roles.includes("admin") ? (
|
{user?.roles.includes("admin") ? (
|
||||||
<NavbarItem>
|
<NavbarItem>
|
||||||
@ -53,7 +88,7 @@ export const Header = ({ user }: { user?: User }) => {
|
|||||||
</Button>
|
</Button>
|
||||||
</NavbarItem>
|
</NavbarItem>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<NavbarItem>
|
<NavbarItem>
|
||||||
<ThemeSwitcher />
|
<ThemeSwitcher />
|
||||||
</NavbarItem>
|
</NavbarItem>
|
||||||
|
@ -2,13 +2,15 @@
|
|||||||
import { useRoomStore } from "@/app/stores/roomStore";
|
import { useRoomStore } from "@/app/stores/roomStore";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { RoomList } from "./List";
|
import { RoomList } from "./List";
|
||||||
|
import { useClassStore } from "@/app/stores/classStore";
|
||||||
|
|
||||||
export const RoomTable = () => {
|
export const RoomTable = () => {
|
||||||
const { fetchRooms, actual, future, past } = useRoomStore();
|
const { fetchRooms, actual, future, past } = useRoomStore();
|
||||||
|
const { selectedClass } = useClassStore();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchRooms();
|
fetchRooms();
|
||||||
}, []);
|
}, [selectedClass]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-4">
|
<div className="flex flex-col gap-4">
|
||||||
|
40
src/app/stores/classStore.tsx
Normal file
40
src/app/stores/classStore.tsx
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { create } from "zustand";
|
||||||
|
import { axiosInstance } from "../lib/axios";
|
||||||
|
|
||||||
|
type Class = { id: string; name: string; createdAt: string };
|
||||||
|
|
||||||
|
type ClassStoreState = {
|
||||||
|
classes: Class[];
|
||||||
|
selectedClass: Class | undefined | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
type ClassStoreActions = {
|
||||||
|
_setClass: (classes: Class[]) => void;
|
||||||
|
fetchClass: () => Promise<void>;
|
||||||
|
setSelectedClass: (selectedClass: Class | undefined | null) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
type ClassStore = ClassStoreState & ClassStoreActions;
|
||||||
|
|
||||||
|
const defaultState: ClassStoreState = {
|
||||||
|
classes: [],
|
||||||
|
selectedClass: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useClassStore = create<ClassStore>()((set) => ({
|
||||||
|
...defaultState,
|
||||||
|
_setClass: (classes: Class[]) => {
|
||||||
|
set(() => ({
|
||||||
|
classes: classes,
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
setSelectedClass: (selectedClass: Class | undefined | null) => {
|
||||||
|
set(() => ({
|
||||||
|
selectedClass: selectedClass,
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
fetchClass: async () => {
|
||||||
|
const classResponse = await axiosInstance.get<Class[]>("/@me/class");
|
||||||
|
useClassStore.getState()._setClass(classResponse.data);
|
||||||
|
},
|
||||||
|
}));
|
@ -2,6 +2,7 @@ import moment from "moment";
|
|||||||
import { create } from "zustand";
|
import { create } from "zustand";
|
||||||
import { Room } from "../components/Room/Room";
|
import { Room } from "../components/Room/Room";
|
||||||
import { axiosInstance } from "../lib/axios";
|
import { axiosInstance } from "../lib/axios";
|
||||||
|
import { useClassStore } from "./classStore";
|
||||||
|
|
||||||
type RoomStoreState = {
|
type RoomStoreState = {
|
||||||
future: Room[];
|
future: Room[];
|
||||||
@ -37,19 +38,13 @@ export const useRoomStore = create<RoomStore>()((set) => ({
|
|||||||
set({ future, actual, past });
|
set({ future, actual, past });
|
||||||
},
|
},
|
||||||
fetchRooms: () => {
|
fetchRooms: () => {
|
||||||
|
const classSelected = useClassStore.getState().selectedClass;
|
||||||
|
if (!classSelected) return;
|
||||||
|
|
||||||
axiosInstance
|
axiosInstance
|
||||||
.get<
|
.get<Room[]>(`/@me/class/${classSelected.id}/rooms`)
|
||||||
{ id: string; name: string; createdAt: string }[]
|
.then((classes) => {
|
||||||
>("/@me/class")
|
useRoomStore.getState()._setRooms(classes.data);
|
||||||
.then((classResponse) => {
|
|
||||||
if (classResponse.data.length)
|
|
||||||
axiosInstance
|
|
||||||
.get<
|
|
||||||
Room[]
|
|
||||||
>(`/@me/class/${classResponse.data[0].id}/rooms`)
|
|
||||||
.then((classes) => {
|
|
||||||
useRoomStore.getState()._setRooms(classes.data);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
Loading…
Reference in New Issue
Block a user