Skip to content

Commit 9134b01

Browse files
anees-asgharnalves599
authored andcommitted
Implement sidebar
1 parent 9305b34 commit 9134b01

File tree

6 files changed

+127
-38
lines changed

6 files changed

+127
-38
lines changed

src/app/(authenticated)/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export default async function AuthenticatedLayout({
1313
if (!session) redirect("/login");
1414

1515
return (
16-
<div className="h-screen text-white flex flex-col">
16+
<div className="h-screen text-white flex flex-col relative">
1717
<Toolbar />
1818
<div className="flex-1 overflow-y-scroll bg-gray-100 text-black mb-navbar">
1919
{children}

src/app/(authenticated)/schedule/ScheduleTable.tsx

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,19 @@ import { getEventFullDate } from "@/utils/utils";
88
import { usePathname, useRouter, useSearchParams } from "next/navigation";
99
import { useEffect, useMemo, useState } from "react";
1010

11+
function getPageHeading(kind: string | null) {
12+
switch (kind) {
13+
case "keynote":
14+
return "Keynotes";
15+
case "presentation":
16+
return "Presentations";
17+
case "workshop":
18+
return "Workshops";
19+
default:
20+
return "Schedule";
21+
}
22+
}
23+
1124
interface ScheduleTableProps {
1225
sessions: SINFOSession[];
1326
}
@@ -23,10 +36,15 @@ export default function ScheduleTable({ sessions }: ScheduleTableProps) {
2336
const placeParam = searchParams.get("place");
2437

2538
const sessionsByDay = useMemo(() => {
26-
const sortedSessions = sessions.sort((a, b) =>
27-
a.date.localeCompare(b.date)
28-
);
29-
return sortedSessions.reduce(
39+
const sessionsCleaned = sessions
40+
.filter(
41+
(s) =>
42+
(!kindParam || s.kind.toLowerCase() === kindParam) &&
43+
(!placeParam || s.place.toLowerCase() === placeParam)
44+
)
45+
.sort((a, b) => a.date.localeCompare(b.date));
46+
47+
return sessionsCleaned.reduce(
3048
(acc, s) => {
3149
const day = s.date.split("T")[0];
3250
const daySessions = [...(acc[day] || []), s];
@@ -50,8 +68,6 @@ export default function ScheduleTable({ sessions }: ScheduleTableProps) {
5068

5169
const updateSearchParam = (newDay: string) => {
5270
const params = new URLSearchParams(searchParams.toString());
53-
params.delete("kind");
54-
params.delete("place");
5571

5672
if (newDay === dayParam) {
5773
params.delete("day");
@@ -69,6 +85,12 @@ export default function ScheduleTable({ sessions }: ScheduleTableProps) {
6985

7086
return (
7187
<>
88+
<div className="flex flex-col items-start gap-y-2 p-4 text-start text-sm">
89+
<h1 className="text-2xl font-bold">{getPageHeading(kindParam)}</h1>
90+
<p className="text-sm text-gray-600">
91+
Checkout all the available sessions.
92+
</p>
93+
</div>
7294
<GridList>
7395
{sortedDays.map((d) => (
7496
<EventDayButton
@@ -83,15 +105,9 @@ export default function ScheduleTable({ sessions }: ScheduleTableProps) {
83105
.filter((d) => !showingDay || d === showingDay)
84106
.map((d) => (
85107
<List key={d} title={getEventFullDate(d)}>
86-
{sessionsByDay[d]
87-
.filter(
88-
(s) =>
89-
(!kindParam || s.kind === kindParam) &&
90-
(!placeParam || s.place === placeParam)
91-
)
92-
.map((s) => (
93-
<SessionTile key={s.id} session={s} onlyShowHours={true} />
94-
))}
108+
{sessionsByDay[d].map((s) => (
109+
<SessionTile key={s.id} session={s} onlyShowHours={true} />
110+
))}
95111
</List>
96112
))}
97113
</>

src/app/(authenticated)/schedule/page.tsx

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,6 @@ export default async function Schedule() {
1010

1111
return (
1212
<div className="container m-auto h-full">
13-
<div className="flex flex-col items-start gap-y-2 p-4 text-start text-sm">
14-
<h1 className="text-2xl font-bold">Schedule</h1>
15-
<p className="text-sm text-gray-600">
16-
Checkout all the available sessions.
17-
</p>
18-
</div>
1913
<ScheduleTable sessions={sessions} />
2014
</div>
2115
);

src/components/BottomNavbar/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export default async function BottomNavbar() {
2222
if (!user) return <></>;
2323

2424
return (
25-
<div className="fixed z-100 bottom-0 left-0 right-0 bg-sinfo-primary">
25+
<div className="fixed z-10 bottom-0 left-0 right-0 bg-sinfo-primary">
2626
<div className="relative container m-auto flex h-navbar flex-row">
2727
{navbarItemKeysByRole[convertToAppRole(user.role)].map((k) => (
2828
<NavbarItem key={k} name={k} />

src/components/Toolbar/Sidebar.tsx

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { X } from "lucide-react";
2+
import { signOut } from "next-auth/react";
3+
import Link from "next/link";
4+
5+
interface SidebarProps {
6+
show: boolean;
7+
onClose: () => void;
8+
}
9+
10+
export default function Sidebar({ show, onClose }: SidebarProps) {
11+
async function handleLogout() {
12+
await signOut();
13+
}
14+
15+
return (
16+
<div
17+
className={`z-20 fixed top-0 left-0 h-full w-full bg-sinfo-primary p-10 flex flex-col gap-6 transition-transform duration-300 ${
18+
show ? "translate-x-0" : "-translate-x-full"
19+
}`}
20+
>
21+
<div className="flex justify-end">
22+
<button onClick={onClose}>
23+
<X size={40} />
24+
</button>
25+
</div>
26+
27+
{/* Primary Options (grouped) */}
28+
<div className="flex flex-col gap-10 text-3xl">
29+
<div className="flex flex-col gap-2">
30+
<Link href="/profile" onClick={onClose}>
31+
Profile
32+
</Link>
33+
</div>
34+
<div className="flex flex-col gap-2">
35+
<Link href="/schedule?kind=keynote" onClick={onClose}>
36+
Keynotes
37+
</Link>
38+
<Link href="/schedule?kind=presentation" onClick={onClose}>
39+
Presentations
40+
</Link>
41+
<Link href="/schedule?kind=workshop" onClick={onClose}>
42+
Workshops
43+
</Link>
44+
</div>
45+
<div className="flex flex-col gap-2">
46+
<Link href="/speakers" onClick={onClose}>
47+
Speakers
48+
</Link>
49+
<Link href="/companies" onClick={onClose}>
50+
Companies
51+
</Link>
52+
</div>
53+
<div></div>
54+
</div>
55+
<div className="flex-1" />
56+
57+
{/* Secondary Options */}
58+
<div className="flex flex-col gap-2 text-xl">
59+
<Link href="https://sinfo.org/">Website</Link>
60+
<Link href="https://github.com/sinfo/nextjs-sinfo-webapp/issues/new">
61+
Report a Bug
62+
</Link>
63+
{/* todo: the pages below dont exist */}
64+
<Link href="#" onClick={onClose}>
65+
Privacy Policy
66+
</Link>
67+
<Link href="#" onClick={onClose}>
68+
Code of Conduct
69+
</Link>
70+
<button className="text-start" onClick={handleLogout}>
71+
Logout
72+
</button>
73+
</div>
74+
</div>
75+
);
76+
}

src/components/Toolbar.tsx renamed to src/components/Toolbar/index.tsx

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,33 @@
22

33
import { Image } from "next/dist/client/image-component";
44
import { sinfoLogo } from "@/assets/images";
5-
import { signOut, useSession } from "next-auth/react";
5+
import { useSession } from "next-auth/react";
66
import { usePathname, useRouter } from "next/navigation";
7-
import { ArrowLeft, LogOut, Menu, RefreshCcw } from "lucide-react";
7+
import { ArrowLeft, Menu, RefreshCcw } from "lucide-react";
8+
import { useState } from "react";
9+
import Sidebar from "./Sidebar";
810

911
export default function Toolbar() {
1012
const { data: session } = useSession();
1113
const router = useRouter();
1214
const currPath = usePathname();
1315

14-
const showMenu: boolean = currPath === "/home" || currPath === "/profile";
16+
const [isExpanded, setIsExpanded] = useState(false);
1517

16-
async function handleExit() {
17-
await signOut();
18-
}
18+
const showMenu: boolean = currPath === "/home" || currPath === "/profile";
1919

2020
return (
21-
<div className="bg-sinfo-primary">
22-
<div className="container m-auto p-4">
21+
<>
22+
<Sidebar show={isExpanded} onClose={() => setIsExpanded(false)} />
23+
<div className="bg-sinfo-primary container m-auto p-4 pb-2 flex flex-col gap-4">
2324
<nav className="flex flex-row items-center">
2425
<div className="w-1/6 flex justify-start items-center">
2526
{showMenu ? (
26-
<Menu size={32} />
27+
<Menu
28+
size={32}
29+
className="cursor-pointer"
30+
onClick={() => setIsExpanded(true)}
31+
/>
2732
) : (
2833
<ArrowLeft
2934
size={32}
@@ -42,18 +47,16 @@ export default function Toolbar() {
4247
quality={100}
4348
/>
4449
</div>
45-
<div className="w-1/6 flex justify-end items-center gap-x-2">
46-
{/* potentially temporary until we have an alternative way to logout */}
47-
<RefreshCcw size={32} onClick={() => window.location.reload()} />
48-
<LogOut size={32} onClick={handleExit} />
50+
<div className="w-1/6 flex justify-end items-center">
51+
<RefreshCcw size={28} onClick={() => window.location.reload()} />
4952
</div>
5053
</nav>
5154
{currPath === "/home" && session?.user?.name && (
52-
<div className="mt-4 text-lg">
55+
<div className="text-lg">
5356
Welcome, <span className="font-semibold">{session.user.name}!</span>
5457
</div>
5558
)}
5659
</div>
57-
</div>
60+
</>
5861
);
5962
}

0 commit comments

Comments
 (0)