diff --git a/package.json b/package.json index cb90b33..86bdda5 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "next-themes": "^0.4.4", "react": "19.0.0-rc-66855b96-20241106", "react-dom": "19.0.0-rc-66855b96-20241106", + "react-icons": "^5.4.0", "zustand": "^5.0.2" }, "devDependencies": { diff --git a/src/app/admin/layout.tsx b/src/app/admin/layout.tsx new file mode 100644 index 0000000..cec59fb --- /dev/null +++ b/src/app/admin/layout.tsx @@ -0,0 +1,10 @@ +import { Sidebar } from "@/app/components/Sidebar"; + +export default function Layout({ children }: { children: React.ReactNode }) { + return ( +
+ +
{children}
+
+ ); +} diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx index 285fd02..84ca1fc 100644 --- a/src/app/admin/page.tsx +++ b/src/app/admin/page.tsx @@ -1,10 +1,10 @@ import { Metadata } from "next"; -import { AdminHeader } from "../components/Header/admin"; +import { Sidebar } from "../components/Sidebar"; export const metadata: Metadata = { title: "Toogether Admin", }; export default async function AdminPage() { - return ; + return ; } diff --git a/src/app/components/Header/admin.tsx b/src/app/components/Header/admin.tsx deleted file mode 100644 index 33c3278..0000000 --- a/src/app/components/Header/admin.tsx +++ /dev/null @@ -1,32 +0,0 @@ -"use client"; - -export const AdminHeader = () => { - return ( - <> - - - - ); -}; diff --git a/src/app/components/Room/Table.tsx b/src/app/components/Room/Table.tsx index e24db89..518384a 100644 --- a/src/app/components/Room/Table.tsx +++ b/src/app/components/Room/Table.tsx @@ -1,61 +1,28 @@ "use client"; -import { axiosInstance } from "@/app/lib/axios"; -import moment from "moment"; -import { useEffect, useState } from "react"; +import { useRoomStore } from "@/app/stores/roomStore"; +import { useEffect } from "react"; import { RoomList } from "./List"; -import { Room } from "./Room"; export const RoomTable = () => { - const [rooms, setRooms] = useState<{ - future: Room[]; - actual: Room[]; - past: Room[]; - }>({ - future: [], - actual: [], - past: [], - }); + const { fetchRooms, actual, future, past } = useRoomStore(); useEffect(() => { - axiosInstance - .get< - { id: string; name: string; createdAt: string }[] - >("/@me/class") - .then((classResponse) => { - if (classResponse.data.length) - axiosInstance - .get< - Room[] - >(`/@me/class/${classResponse.data[0].id}/rooms`) - .then((classes) => { - // Filter rooms by date, get future, actual and past rooms - const future = classes.data.filter((room) => - moment(room.date).isAfter(moment(), "day"), - ); - const actual = classes.data.filter((room) => - moment(room.date).isSame(moment(), "day"), - ); - const past = classes.data.filter((room) => - moment(room.date).isBefore(moment(), "day"), - ); - setRooms({ future, actual, past }); - }); - }); + fetchRooms(); }, []); return (

Upcoming

- +

Today

- +

Past

- +
); diff --git a/src/app/components/Sidebar/index.tsx b/src/app/components/Sidebar/index.tsx new file mode 100644 index 0000000..90e2a4d --- /dev/null +++ b/src/app/components/Sidebar/index.tsx @@ -0,0 +1,42 @@ +"use client"; + +import { FaRegUser } from "react-icons/fa"; +import { ThemeSwitcher } from "../ThemeSwitcher/ThemeSwitcher"; +import { SidebarItem } from "./item"; +import { Link } from "@nextui-org/react"; +import { useRouter } from "next/navigation"; + +export const Sidebar = () => { + const router = useRouter(); + + return ( + + ); +}; diff --git a/src/app/components/Sidebar/item.tsx b/src/app/components/Sidebar/item.tsx new file mode 100644 index 0000000..fc681ec --- /dev/null +++ b/src/app/components/Sidebar/item.tsx @@ -0,0 +1,24 @@ +"use client"; +import { Link } from "@nextui-org/react"; +import { useRouter } from "next/navigation"; + +export const SidebarItem = ({ + title, + icon, + href, +}: { + title: string; + icon: React.ReactNode; + href: string; +}) => { + return ( + useRouter().push(href)} + color="foreground" + className="w-full px-2 py-1 gap-2" + > + {icon} + {title} + + ); +}; diff --git a/src/app/components/ThemeSwitcher/ThemeSwitcher.tsx b/src/app/components/ThemeSwitcher/ThemeSwitcher.tsx index ebf15dc..4d8e134 100644 --- a/src/app/components/ThemeSwitcher/ThemeSwitcher.tsx +++ b/src/app/components/ThemeSwitcher/ThemeSwitcher.tsx @@ -12,17 +12,15 @@ export const ThemeSwitcher = () => { }, []); return ( -
- -
+ ); }; diff --git a/src/app/dashboard/layout.tsx b/src/app/dashboard/layout.tsx new file mode 100644 index 0000000..a574612 --- /dev/null +++ b/src/app/dashboard/layout.tsx @@ -0,0 +1,19 @@ +import { authOptions } from "@/authOptions"; +import { getServerSession } from "next-auth"; +import { Header } from "../components/Header"; + +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + const session = await getServerSession(authOptions); + + return ( +
+
+ +
{children}
+
+ ); +} diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx new file mode 100644 index 0000000..4b59714 --- /dev/null +++ b/src/app/dashboard/page.tsx @@ -0,0 +1,16 @@ +import { Metadata } from "next"; +import { RoomTable } from "../components/Room/Table"; + +export const metadata: Metadata = { + title: "Toogether | Home", + description: + "Toogether is a platform that allows you to create and join rooms to study together.", +}; + +export default async function HomePage() { + return ( +
+ +
+ ); +} diff --git a/src/app/stores/roomStore.tsx b/src/app/stores/roomStore.tsx new file mode 100644 index 0000000..735e370 --- /dev/null +++ b/src/app/stores/roomStore.tsx @@ -0,0 +1,55 @@ +import moment from "moment"; +import { create } from "zustand"; +import { Room } from "../components/Room/Room"; +import { axiosInstance } from "../lib/axios"; + +type RoomStoreState = { + future: Room[]; + actual: Room[]; + past: Room[]; +}; + +type RoomStoreActions = { + _setRooms: (rooms: Room[]) => void; + fetchRooms: () => void; +}; + +type RoomStore = RoomStoreState & RoomStoreActions; + +const defaultState: RoomStoreState = { + future: [], + actual: [], + past: [], +}; + +export const useRoomStore = create()((set) => ({ + ...defaultState, + _setRooms: (rooms) => { + const future = rooms.filter((room) => + moment(room.date).isAfter(moment(), "day"), + ); + const actual = rooms.filter((room) => + moment(room.date).isSame(moment(), "day"), + ); + const past = rooms.filter((room) => + moment(room.date).isBefore(moment(), "day"), + ); + set({ future, actual, past }); + }, + fetchRooms: () => { + axiosInstance + .get< + { id: string; name: string; createdAt: string }[] + >("/@me/class") + .then((classResponse) => { + if (classResponse.data.length) + axiosInstance + .get< + Room[] + >(`/@me/class/${classResponse.data[0].id}/rooms`) + .then((classes) => { + useRoomStore.getState()._setRooms(classes.data); + }); + }); + }, +})); diff --git a/yarn.lock b/yarn.lock index ea5d381..dba219f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4491,6 +4491,11 @@ react-dom@19.0.0-rc-66855b96-20241106: dependencies: scheduler "0.25.0-rc-66855b96-20241106" +react-icons@^5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-5.4.0.tgz#443000f6e5123ee1b21ea8c0a716f6e7797f7416" + integrity sha512-7eltJxgVt7X64oHh6wSWNwwbKTCtMfK35hcjvJS0yxEAhPM8oUKdS3+kqaW1vicIltw+kR2unHaa12S9pPALoQ== + react-is@^16.13.1: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"