diff --git a/package.json b/package.json index 1abe152..f41c915 100644 --- a/package.json +++ b/package.json @@ -3,9 +3,9 @@ "version": "0.1.0", "private": true, "scripts": { - "dev": "next dev --turbopack", + "dev": "next dev --turbopack -p 4000", "build": "next build", - "start": "next start", + "start": "next start -p 4000", "lint": "next lint" }, "dependencies": { @@ -20,6 +20,7 @@ "moment": "^2.30.1", "next": "15.0.3", "next-auth": "^4.24.10", + "next-themes": "^0.4.4", "react": "19.0.0-rc-66855b96-20241106", "react-dom": "19.0.0-rc-66855b96-20241106", "zustand": "^5.0.2" diff --git a/src/app/components/AppWrapper.tsx b/src/app/components/AppWrapper.tsx index 6952afb..97b7d2c 100644 --- a/src/app/components/AppWrapper.tsx +++ b/src/app/components/AppWrapper.tsx @@ -2,6 +2,7 @@ import { NextUIProvider } from "@nextui-org/react"; import { SessionProvider } from "next-auth/react"; +import { ThemeProvider as NextThemesProvider } from "next-themes"; export default function AppWrapper({ children, @@ -10,7 +11,11 @@ export default function AppWrapper({ }) { return ( - {children} + + + {children} + + ); } diff --git a/src/app/components/Conference/Card.tsx b/src/app/components/Conference/Card.tsx index 0ad34c0..0387559 100644 --- a/src/app/components/Conference/Card.tsx +++ b/src/app/components/Conference/Card.tsx @@ -3,6 +3,7 @@ import { parseDate, Time } from "@internationalized/date"; import { + Button, Card, CardBody, CardHeader, @@ -10,49 +11,64 @@ import { Divider, TimeInput, } from "@nextui-org/react"; -import { Conference } from "./Conference"; +import { Room } from "./Conference"; +import moment from "moment"; +import { useRouter } from "next/navigation"; export const ConferenceCard = ({ id, - title, - author, + name, date, - hours, -}: Conference) => { + Times, + Presentator +}: Room) => { + const router = useRouter(); + return ( - +
-

{title}

-

{author}

+

{name}

+

{Presentator.username}

- - - {hours.map((hour, hourIndex) => ( -
- - - - + + {Times.map((time) => ( +
+ +
+ + - + +
))}
+
+ +
); }; diff --git a/src/app/components/Conference/Conference.d.ts b/src/app/components/Conference/Conference.d.ts index 8898c01..e60551f 100644 --- a/src/app/components/Conference/Conference.d.ts +++ b/src/app/components/Conference/Conference.d.ts @@ -1,16 +1,17 @@ -export interface Conference { +export interface Room { id: string; - title: string; - author: string; + name: string; date: string; - hours: { - start: { - hours: number; - minutes: number; - }; - end: { - hours: number; - minutes: number; - }; + Times: { + id: number; + startTime: string; + endTime: string; + roomId: string; }[]; -} + Presentator: { + id: string; + username: string; + role: string; + createdAt: string; + } +} \ No newline at end of file diff --git a/src/app/components/Conference/List.tsx b/src/app/components/Conference/List.tsx index 31b6bd0..c7dca2d 100644 --- a/src/app/components/Conference/List.tsx +++ b/src/app/components/Conference/List.tsx @@ -1,21 +1,22 @@ +"use client" import { ConferenceCard } from "./Card"; -import { Conference } from "./Conference"; +import { Room } from "./Conference"; export const ConferenceList = ({ - conferences, + rooms, }: { - conferences: Conference[]; + rooms: Room[]; }) => { return (
- {conferences.map((conference) => ( + {rooms.map((room) => ( ))}
diff --git a/src/app/components/Header/index.tsx b/src/app/components/Header/index.tsx index 527ae4a..4891d0d 100644 --- a/src/app/components/Header/index.tsx +++ b/src/app/components/Header/index.tsx @@ -10,6 +10,7 @@ import { NavbarContent, } from "@nextui-org/react"; import { useSession } from "next-auth/react"; +import { ThemeSwitcher } from "../ThemeSwitcher/ThemeSwitcher"; export const Header = () => { const { data: session } = useSession(); @@ -18,6 +19,7 @@ export const Header = () => {

Toogether

+
diff --git a/src/app/components/ThemeSwitcher/ThemeSwitcher.tsx b/src/app/components/ThemeSwitcher/ThemeSwitcher.tsx new file mode 100644 index 0000000..21ea773 --- /dev/null +++ b/src/app/components/ThemeSwitcher/ThemeSwitcher.tsx @@ -0,0 +1,23 @@ +"use client"; +import { useTheme } from "next-themes"; +import { useEffect, useState } from "react"; + +export const ThemeSwitcher = () => { + const [mounted, setMounted] = useState(false); + const { theme, setTheme } = useTheme(); + + useEffect(() => { + setMounted(true); + }, []); + + if (!mounted) return null; + + return ( +
+ {theme === "light" ? ( + ) : ( + + )} +
+ ); +}; diff --git a/src/app/layout.tsx b/src/app/layout.tsx index af08642..35157e7 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -7,7 +7,7 @@ export default function RootLayout({ children: React.ReactNode; }) { return ( - + {children} diff --git a/src/app/page.tsx b/src/app/page.tsx index a2e62d4..fe48a3f 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,54 +1,115 @@ +"use client"; +import { Card, Divider, Skeleton } from "@nextui-org/react"; +import moment from "moment"; +import { useEffect, useState } from "react"; +import { Room } from "./components/Conference/Conference"; import { ConferenceList } from "./components/Conference/List"; import { Header } from "./components/Header"; +import { axiosInstance } from "./lib/axios"; -const RandomConferenceData = [ - { - id: "1", - title: "Conference sur les conférences", - author: "Rémi Formentel", - date: "2021-09-01", - hours: [ - { - start: { hours: 9, minutes: 0 }, - end: { hours: 12, minutes: 0 }, - }, - { - start: { hours: 13, minutes: 0 }, - end: { hours: 15, minutes: 0 }, - }, - ], - }, - { - id: "2", - title: "Apprendre a dev pour les nuls", - author: "Fabien Taupin", - date: "2021-09-01", - hours: [ - { - start: { hours: 18, minutes: 0 }, - end: { hours: 23, minutes: 0 }, - }, - ], - }, -]; +const SkeletonCard = () => { + return +
+ +
+ + +
+ +
+ + +
+ +
+ +
+ + - + +
+ +
+ +} const HomePage = () => { + const [roomsLoading, setRoomsLoading] = useState(true); + const [rooms, setRooms] = useState<{ + future: Room[]; + actual: Room[]; + past: Room[]; + }>({ + future: [], + actual: [], + past: [] + }); + + useEffect(() => { + axiosInstance.get<{ id: string, name: string, createdAt: string }[]>("/@me/class") + .then((classResponse) => { + classResponse.data.length > 0 && + axiosInstance.get(`/@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())); + + setRooms({ future, actual, past }); + setRoomsLoading(false); + }); + }) + + }, []); + return ( <>
-
-

Cours a venir

- -
-
-

Cours passés

- -
-
-

Autres cours

- -
+ {roomsLoading + ? <> +
+

Cours a venir

+
+ + + +
+
+
+

Cours actuels

+
+ + + +
+
+
+

Cours passés

+
+ + + +
+
+ + : <> +
+

Cours a venir

+ +
+
+

Cours actuels

+ +
+
+

Cours passés

+ +
+ + + }
); diff --git a/tailwind.config.ts b/tailwind.config.ts index e93a934..af8c0d3 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -14,16 +14,6 @@ export default { background: "var(--background)", foreground: "var(--foreground)", }, - animation: { - "gradient-x": "gradient-x 5s ease infinite", - }, - keyframes: { - "gradient-x": { - "0%": { "background-position": "0% 50%" }, - "50%": { "background-position": "100% 50%" }, - "100%": { "background-position": "0% 50%" }, - }, - }, }, }, darkMode: "class", diff --git a/yarn.lock b/yarn.lock index 44b18ff..71816a6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4148,6 +4148,11 @@ next-auth@^4.24.10: preact-render-to-string "^5.1.19" uuid "^8.3.2" +next-themes@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/next-themes/-/next-themes-0.4.4.tgz#ce6f68a4af543821bbc4755b59c0d3ced55c2d13" + integrity sha512-LDQ2qIOJF0VnuVrrMSMLrWGjRMkq+0mpgl6e0juCLqdJ+oo8Q84JRWT6Wh11VDQKkMMe+dVzDKLWs5n87T+PkQ== + next@15.0.3: version "15.0.3" resolved "https://registry.yarnpkg.com/next/-/next-15.0.3.tgz#804f5b772e7570ef1f088542a59860914d3288e9" @@ -4730,8 +4735,16 @@ streamsearch@^1.1.0: resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0: - name string-width-cjs +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.1.0: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -4812,7 +4825,14 @@ string.prototype.trimstart@^1.0.8: define-properties "^1.2.1" es-object-atoms "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==