Skip to content

Commit

Permalink
feat(app): allowing subjects to be choosen
Browse files Browse the repository at this point in the history
  • Loading branch information
akshat-OwO committed Mar 14, 2024
1 parent 7e25ed0 commit 4436693
Show file tree
Hide file tree
Showing 2 changed files with 174 additions and 13 deletions.
127 changes: 114 additions & 13 deletions src/components/SubjectList.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
"use client";

import { Courses } from "@/config";
import { useSubjectList } from "@/hooks/use-subject-list";
import {
useActiveSubjectsStore,
useSubjectList,
} from "@/hooks/use-subject-list";
import { getSubjectList } from "@/lib/server";
import { cn } from "@/lib/utils";
import { QueryKey, useQuery } from "@tanstack/react-query";
import _ from "lodash";
import { Expand, Maximize2, Minimize2 } from "lucide-react";
import { Check, Expand, ListChecks, Maximize2, Minimize2 } from "lucide-react";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useCallback, useState } from "react";
import { useCallback, useMemo, useRef, useState } from "react";
import { Button } from "./ui/button";
import {
Card,
Expand All @@ -17,6 +20,8 @@ import {
CardHeader,
CardTitle,
} from "./ui/card";
import { Command, CommandGroup, CommandInput, CommandItem } from "./ui/command";
import { Popover, PopoverContent, PopoverTrigger } from "./ui/popover";
import { ScrollArea } from "./ui/scroll-area";
import { Skeleton } from "./ui/skeleton";

Expand All @@ -29,6 +34,8 @@ const SubjectList = ({ course }: SubjectListProps) => {

const searchParams = useSearchParams()!;

const { activeSubjects } = useActiveSubjectsStore();

const semester = searchParams.get("semester");
const branch = searchParams.get("branch");

Expand All @@ -49,6 +56,18 @@ const SubjectList = ({ course }: SubjectListProps) => {
queryFn: async () => await getSubjectList({ course, branch, semester }),
});

const generateSubjectList = useMemo(() => {
const subjects = activeSubjects.find(
(active) => active.branch === branch && active.semester === semester
);

if (subjects && subjects.subjects.length > 0) {
return subjects.subjects;
} else {
if (list) return list.slice(0, 9);
}
}, [list, semester, branch, activeSubjects]);

if (isLoading) {
return <SubjectList.Skeleton />;
}
Expand All @@ -69,19 +88,24 @@ const SubjectList = ({ course }: SubjectListProps) => {
Spoiler alert: courage required
</CardDescription>
</div>
<Button
onClick={() =>
subjectListModal.onOpen(list as string[])
}
size={"icon"}
variant={"ghost"}
>
<Expand className="h-4 w-4" />
</Button>
<div className="flex items-center gap-2">
{list.length > 9 && (
<SubjectList.ActiveSubjects list={list} />
)}
<Button
onClick={() =>
subjectListModal.onOpen(generateSubjectList)
}
size={"icon"}
variant={"ghost"}
>
<Expand className="h-4 w-4" />
</Button>
</div>
</CardHeader>
<CardContent>
<ScrollArea type="always" className="h-28 pr-5">
<SubjectList.Data list={list as string[]} />
<SubjectList.Data list={generateSubjectList} />
</ScrollArea>
</CardContent>
</Card>
Expand Down Expand Up @@ -185,4 +209,81 @@ SubjectList.Data = function SubjectListData({ list }: { list: string[] }) {
);
};

SubjectList.ActiveSubjects = function SubjectListActiveSubjects({
list,
}: {
list: string[];
}) {
const inputRef = useRef<HTMLInputElement>(null);
const [open, setOpen] = useState<boolean>(false);

const searchParams = useSearchParams()!;

const semester = searchParams.get("semester");
const branch = searchParams.get("branch");

const { activeSubjects, toggleSubject } = useActiveSubjectsStore();

const onOpenChange = (value: boolean) => {
inputRef.current?.blur();
setOpen(value);
};

const toggle = (subject: string) => {
if (semester && branch) {
toggleSubject(semester, branch, subject);
}
};

return (
<Popover open={open} onOpenChange={onOpenChange}>
<PopoverTrigger asChild>
<Button
variant="outline"
size="icon"
aria-expanded={open}
role="combobox"
>
<ListChecks className="size-4" />
</Button>
</PopoverTrigger>
<PopoverContent>
<Command loop>
<CommandInput
ref={inputRef}
placeholder="Search Subjects..."
/>
<CommandGroup>
{list.map((subject) => {
const isActive = activeSubjects.some(
(active) =>
active.branch === branch &&
active.semester === semester &&
active.subjects.includes(subject)
);
return (
<CommandItem
key={subject}
value={subject}
onSelect={() => toggle(subject)}
>
<Check
className={cn(
"mr-2 h-4 w-4",
isActive
? "opacity-100"
: "opacity-0"
)}
/>
<div className="flex-1">{subject}</div>
</CommandItem>
);
})}
</CommandGroup>
</Command>
</PopoverContent>
</Popover>
);
};

export default SubjectList;
60 changes: 60 additions & 0 deletions src/hooks/use-subject-list.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { create } from "zustand";
import { persist } from "zustand/middleware";

type SubjectListStore = {
isOpen: boolean;
Expand All @@ -13,3 +14,62 @@ export const useSubjectList = create<SubjectListStore>((set, get) => ({
onClose: () => set({ isOpen: false, subjectList: [] }),
subjectList: [],
}));

type ActiveSubjectList = {
semester: string;
branch: string;
subjects: string[];
};

type ActiveSubjectsState = {
activeSubjects: ActiveSubjectList[];
toggleSubject: (semester: string, branch: string, subject: string) => void;
};

export const useActiveSubjectsStore = create<ActiveSubjectsState>()(
persist(
(set, get) => ({
activeSubjects: [],
toggleSubject: (semester, branch, subject) => {
const activeSubjects = [...get().activeSubjects];
const existingSubjectIndex = activeSubjects.findIndex(
(active) =>
active.branch === branch && active.semester === semester
);

if (existingSubjectIndex !== -1) {
const existingSubject =
activeSubjects[existingSubjectIndex];
const updatedSubjects = existingSubject.subjects.includes(
subject
)
? existingSubject.subjects.filter((s) => s !== subject)
: [...existingSubject.subjects, subject];
const updatedActiveSubjects = [
...activeSubjects.slice(0, existingSubjectIndex),
{ ...existingSubject, subjects: updatedSubjects },
...activeSubjects.slice(existingSubjectIndex + 1),
];
set({ activeSubjects: updatedActiveSubjects });
} else {
const newActiveSubject = {
semester,
branch,
subjects: [subject],
};
const updatedActiveSubjects = [
...activeSubjects,
newActiveSubject,
];
set({ activeSubjects: updatedActiveSubjects });
}
},
}),
{
name: "active-subjects",
partialize: (state) => ({
activeSubjects: state.activeSubjects,
}),
}
)
);

0 comments on commit 4436693

Please sign in to comment.