update: add scroll area using shadcn for left side bar

This commit is contained in:
abiyasa05 2024-11-18 15:37:58 +07:00
parent ca4ec0a538
commit 9bfad134cb
2 changed files with 189 additions and 181 deletions

View File

@ -626,108 +626,112 @@ export default function AssessmentPage() {
{isMobile && ( {isMobile && (
<LeftSheet open={isLeftSidebarOpen} onOpenChange={(open) => setIsLeftSidebarOpen(open)}> <LeftSheet open={isLeftSidebarOpen} onOpenChange={(open) => setIsLeftSidebarOpen(open)}>
<LeftSheetContent className="h-full w-75 overflow-auto"> <LeftSheetContent className="h-full w-75 overflow-auto">
<Label className="text-gray-800 p-5 text-sm font-normal">Aspek Menu</Label> <ScrollArea className="h-full w-75 rounded-md p-2">
<div className="w-64"> <Label className="text-gray-800 p-5 text-sm font-normal">Aspek Menu</Label>
<div className="space-y-2"> <div className="w-64">
{/* Aspek */} <div className="space-y-2">
{aspectsQuery.data?.data {/* Aspek */}
.filter((aspect) => {aspectsQuery.data?.data
aspect.subAspects.some((subAspect) => .filter((aspect) =>
data?.data.some((question) => question.subAspectId === subAspect.id) aspect.subAspects.some((subAspect) =>
data?.data.some((question) => question.subAspectId === subAspect.id)
)
) )
) .map((aspect) => (
.map((aspect) => ( <div key={aspect.id} className="p-2 mt-4">
<div key={aspect.id} className="p-2 mt-4"> <div
<div className="flex justify-between cursor-pointer"
className="flex justify-between cursor-pointer" onClick={() => toggleAspect(aspect.id)}
onClick={() => toggleAspect(aspect.id)} >
> <div className="text-sm font-bold px-3">{aspect.name}</div>
<div className="text-sm font-bold px-3">{aspect.name}</div> <div>
<div> {openAspects[aspect.id] ? (
{openAspects[aspect.id] ? ( <TbChevronDown size={25} />
<TbChevronDown size={25} /> ) : (
) : ( <TbChevronRight size={25} />
<TbChevronRight size={25} /> )}
)} </div>
</div> </div>
</div>
{/* Sub-Aspek */} {/* Sub-Aspek */}
{openAspects[aspect.id] && ( {openAspects[aspect.id] && (
<div className="mt-2 space-y-2"> <div className="mt-2 space-y-2">
{aspect.subAspects {aspect.subAspects
.filter((subAspect) => .filter((subAspect) =>
data?.data.some((question) => question.subAspectId === subAspect.id) data?.data.some((question) => question.subAspectId === subAspect.id)
) )
.map((subAspect) => ( .map((subAspect) => (
<div <div
key={subAspect.id} key={subAspect.id}
className={`cursor-pointer p-2 px-6 rounded-sm transition-colors duration-150 ${selectedSubAspectId === subAspect.id ? 'text-black font-medium bg-gray-200' : 'text-gray-500'}`} className={`cursor-pointer p-2 px-6 rounded-sm transition-colors duration-150 ${selectedSubAspectId === subAspect.id ? 'text-black font-medium bg-gray-200' : 'text-gray-500'}`}
onClick={() => setSelectedSubAspectId(subAspect.id)} onClick={() => setSelectedSubAspectId(subAspect.id)}
> >
<div className="text-xs">{subAspect.name}</div> <div className="text-xs">{subAspect.name}</div>
</div> </div>
))} ))}
</div> </div>
)} )}
</div> </div>
))} ))}
</div>
</div> </div>
</div> </ScrollArea>
</LeftSheetContent> </LeftSheetContent>
</LeftSheet> </LeftSheet>
)} )}
{/* Sidebar for Desktop (Always Visible) */} {/* Sidebar for Desktop (Always Visible) */}
<div className="hidden md:block fixed h-full w-66 overflow-auto border-x"> <div className="hidden md:block fixed h-full w-62 overflow-auto border-x">
<Label className="text-gray-800 p-5 text-sm font-normal">Aspek Menu</Label> <ScrollArea className="h-full w-62 rounded-md p-2">
<div className="w-64"> <Label className="text-gray-800 p-5 text-sm font-normal">Aspek Menu</Label>
<div className="space-y-2"> <div className="w-64">
{/* Aspek */} <div className="space-y-2">
{aspectsQuery.data?.data {/* Aspek */}
.filter((aspect) => {aspectsQuery.data?.data
aspect.subAspects.some((subAspect) => .filter((aspect) =>
data?.data.some((question) => question.subAspectId === subAspect.id) aspect.subAspects.some((subAspect) =>
data?.data.some((question) => question.subAspectId === subAspect.id)
)
) )
) .map((aspect) => (
.map((aspect) => ( <div key={aspect.id} className="p-2 ">
<div key={aspect.id} className="p-2 "> <div
<div className="flex justify-between cursor-pointer"
className="flex justify-between cursor-pointer" onClick={() => toggleAspect(aspect.id)}
onClick={() => toggleAspect(aspect.id)} >
> <div className="text-sm font-bold px-3">{aspect.name}</div>
<div className="text-sm font-bold px-3">{aspect.name}</div> <div>
<div> {openAspects[aspect.id] ? (
{openAspects[aspect.id] ? ( <TbChevronDown size={25} />
<TbChevronDown size={25} /> ) : (
) : ( <TbChevronRight size={25} />
<TbChevronRight size={25} /> )}
)} </div>
</div> </div>
</div>
{/* Sub-Aspek */} {/* Sub-Aspek */}
{openAspects[aspect.id] && ( {openAspects[aspect.id] && (
<div className="mt-2 space-y-2"> <div className="mt-2 space-y-2">
{aspect.subAspects {aspect.subAspects
.filter((subAspect) => .filter((subAspect) =>
data?.data.some((question) => question.subAspectId === subAspect.id) data?.data.some((question) => question.subAspectId === subAspect.id)
) )
.map((subAspect) => ( .map((subAspect) => (
<div <div
key={subAspect.id} key={subAspect.id}
className={`flex justify-between cursor-pointer p-2 px-6 rounded-sm transition-colors duration-150 ${selectedSubAspectId === subAspect.id ? 'text-black font-medium bg-gray-200' : 'text-gray-500'}`} className={`flex justify-between cursor-pointer p-2 px-6 rounded-sm transition-colors duration-150 ${selectedSubAspectId === subAspect.id ? 'text-black font-medium bg-gray-200' : 'text-gray-500'}`}
onClick={() => setSelectedSubAspectId(subAspect.id)} onClick={() => setSelectedSubAspectId(subAspect.id)}
> >
<div className="text-xs">{subAspect.name}</div> <div className="text-xs">{subAspect.name}</div>
</div> </div>
))} ))}
</div> </div>
)} )}
</div> </div>
))} ))}
</div>
</div> </div>
</div> </ScrollArea>
</div> </div>
{/* MIDDLE */} {/* MIDDLE */}
@ -755,10 +759,10 @@ export default function AssessmentPage() {
> >
<div className="grid grid-cols-[auto_1fr_auto] gap-2 w-full items-start"> <div className="grid grid-cols-[auto_1fr_auto] gap-2 w-full items-start">
{/* Question Number */} {/* Question Number */}
<Label className="font-bold p-2 text-sm">{startIndex + index + 1}.</Label> <Label className="font-bold pl-6 text-sm">{startIndex + index + 1}.</Label>
{/* Question Text */} {/* Question Text */}
<Label className="font-bold break-words text-sm p-2">{question.questionText}</Label> <Label className="font-bold break-words text-sm">{question.questionText}</Label>
{/* Action Button/Flag */} {/* Action Button/Flag */}
<button <button

View File

@ -590,108 +590,112 @@ export default function AssessmentPage() {
{isMobile && ( {isMobile && (
<LeftSheet open={isLeftSidebarOpen} onOpenChange={(open) => setIsLeftSidebarOpen(open)}> <LeftSheet open={isLeftSidebarOpen} onOpenChange={(open) => setIsLeftSidebarOpen(open)}>
<LeftSheetContent className="h-full w-75 overflow-auto"> <LeftSheetContent className="h-full w-75 overflow-auto">
<Label className="text-gray-800 p-5 text-sm font-normal">Aspek Menu</Label> <ScrollArea className="h-full w-75 rounded-md p-2">
<div className="w-64"> <Label className="text-gray-800 p-5 text-sm font-normal">Aspek Menu</Label>
<div className="space-y-2"> <div className="w-64">
{/* Aspek */} <div className="space-y-2">
{aspectsQuery.data?.data {/* Aspek */}
.filter((aspect) => {aspectsQuery.data?.data
aspect.subAspects.some((subAspect) => .filter((aspect) =>
data?.data.some((question) => question.subAspectId === subAspect.id) aspect.subAspects.some((subAspect) =>
data?.data.some((question) => question.subAspectId === subAspect.id)
)
) )
) .map((aspect) => (
.map((aspect) => ( <div key={aspect.id} className="p-2 mt-4">
<div key={aspect.id} className="p-2 mt-4"> <div
<div className="flex justify-between cursor-pointer"
className="flex justify-between cursor-pointer" onClick={() => toggleAspect(aspect.id)}
onClick={() => toggleAspect(aspect.id)} >
> <div className="text-sm font-bold px-3">{aspect.name}</div>
<div className="text-sm font-bold px-3">{aspect.name}</div> <div>
<div> {openAspects[aspect.id] ? (
{openAspects[aspect.id] ? ( <TbChevronDown size={25} />
<TbChevronDown size={25} /> ) : (
) : ( <TbChevronRight size={25} />
<TbChevronRight size={25} /> )}
)} </div>
</div> </div>
</div>
{/* Sub-Aspek */} {/* Sub-Aspek */}
{openAspects[aspect.id] && ( {openAspects[aspect.id] && (
<div className="mt-2 space-y-2"> <div className="mt-2 space-y-2">
{aspect.subAspects {aspect.subAspects
.filter((subAspect) => .filter((subAspect) =>
data?.data.some((question) => question.subAspectId === subAspect.id) data?.data.some((question) => question.subAspectId === subAspect.id)
) )
.map((subAspect) => ( .map((subAspect) => (
<div <div
key={subAspect.id} key={subAspect.id}
className={`cursor-pointer p-2 px-6 rounded-sm transition-colors duration-150 ${selectedSubAspectId === subAspect.id ? 'text-black font-medium bg-gray-200' : 'text-gray-500'}`} className={`cursor-pointer p-2 px-6 rounded-sm transition-colors duration-150 ${selectedSubAspectId === subAspect.id ? 'text-black font-medium bg-gray-200' : 'text-gray-500'}`}
onClick={() => setSelectedSubAspectId(subAspect.id)} onClick={() => setSelectedSubAspectId(subAspect.id)}
> >
<div className="text-xs">{subAspect.name}</div> <div className="text-xs">{subAspect.name}</div>
</div> </div>
))} ))}
</div> </div>
)} )}
</div> </div>
))} ))}
</div>
</div> </div>
</div> </ScrollArea>
</LeftSheetContent> </LeftSheetContent>
</LeftSheet> </LeftSheet>
)} )}
{/* Sidebar for Desktop (Always Visible) */} {/* Sidebar for Desktop (Always Visible) */}
<div className="hidden md:block fixed h-full w-66 overflow-auto border-x"> <div className="hidden md:block fixed h-full w-66 overflow-auto border-x">
<Label className="text-gray-800 p-5 text-sm font-normal">Aspek Menu</Label> <ScrollArea className="h-full w-62 rounded-md p-2">
<div className="w-64"> <Label className="text-gray-800 p-5 text-sm font-normal">Aspek Menu</Label>
<div className="space-y-2"> <div className="w-64">
{/* Aspek */} <div className="space-y-2">
{aspectsQuery.data?.data {/* Aspek */}
.filter((aspect) => {aspectsQuery.data?.data
aspect.subAspects.some((subAspect) => .filter((aspect) =>
data?.data.some((question) => question.subAspectId === subAspect.id) aspect.subAspects.some((subAspect) =>
data?.data.some((question) => question.subAspectId === subAspect.id)
)
) )
) .map((aspect) => (
.map((aspect) => ( <div key={aspect.id} className="p-2 ">
<div key={aspect.id} className="p-2 "> <div
<div className="flex justify-between cursor-pointer"
className="flex justify-between cursor-pointer" onClick={() => toggleAspect(aspect.id)}
onClick={() => toggleAspect(aspect.id)} >
> <div className="text-sm font-bold px-3">{aspect.name}</div>
<div className="text-sm font-bold px-3">{aspect.name}</div> <div>
<div> {openAspects[aspect.id] ? (
{openAspects[aspect.id] ? ( <TbChevronDown size={25} />
<TbChevronDown size={25} /> ) : (
) : ( <TbChevronRight size={25} />
<TbChevronRight size={25} /> )}
)} </div>
</div> </div>
</div>
{/* Sub-Aspek */} {/* Sub-Aspek */}
{openAspects[aspect.id] && ( {openAspects[aspect.id] && (
<div className="mt-2 space-y-2"> <div className="mt-2 space-y-2">
{aspect.subAspects {aspect.subAspects
.filter((subAspect) => .filter((subAspect) =>
data?.data.some((question) => question.subAspectId === subAspect.id) data?.data.some((question) => question.subAspectId === subAspect.id)
) )
.map((subAspect) => ( .map((subAspect) => (
<div <div
key={subAspect.id} key={subAspect.id}
className={`flex justify-between cursor-pointer p-2 px-6 rounded-sm transition-colors duration-150 ${selectedSubAspectId === subAspect.id ? 'text-black font-medium bg-gray-200' : 'text-gray-500'}`} className={`flex justify-between cursor-pointer p-2 px-6 rounded-sm transition-colors duration-150 ${selectedSubAspectId === subAspect.id ? 'text-black font-medium bg-gray-200' : 'text-gray-500'}`}
onClick={() => setSelectedSubAspectId(subAspect.id)} onClick={() => setSelectedSubAspectId(subAspect.id)}
> >
<div className="text-xs">{subAspect.name}</div> <div className="text-xs">{subAspect.name}</div>
</div> </div>
))} ))}
</div> </div>
)} )}
</div> </div>
))} ))}
</div>
</div> </div>
</div> </ScrollArea>
</div> </div>
{/* MIDDLE */} {/* MIDDLE */}
@ -719,10 +723,10 @@ export default function AssessmentPage() {
> >
<div className="grid grid-cols-[auto_1fr_auto] gap-2 w-full items-start"> <div className="grid grid-cols-[auto_1fr_auto] gap-2 w-full items-start">
{/* Question Number */} {/* Question Number */}
<Label className="font-bold p-2 text-sm">{startIndex + index + 1}.</Label> <Label className="font-bold pl-6 text-sm">{startIndex + index + 1}.</Label>
{/* Question Text */} {/* Question Text */}
<Label className="font-bold break-words text-sm p-2">{question.questionText}</Label> <Label className="font-bold break-words text-sm">{question.questionText}</Label>
</div> </div>
{/* Radio Button Options */} {/* Radio Button Options */}