2023-04-23 08:26:39 -05:00
// Copyright (C) 2022-present Daniel31x13 <daniel31x13@gmail.com>
// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3.
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
2023-03-22 18:11:54 -05:00
import useCollectionStore from "@/store/collections" ;
2023-04-25 07:39:46 -05:00
import {
faBox ,
faEllipsis ,
faPlus ,
2023-05-14 10:41:08 -05:00
faSort ,
2023-04-25 07:39:46 -05:00
} from "@fortawesome/free-solid-svg-icons" ;
2023-03-28 02:31:50 -05:00
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" ;
2023-02-24 11:32:28 -06:00
import CollectionCard from "@/components/CollectionCard" ;
2023-03-28 02:31:50 -05:00
import Dropdown from "@/components/Dropdown" ;
2023-05-15 15:45:06 -05:00
import { ChangeEvent , useEffect , useState } from "react" ;
2023-04-23 08:26:39 -05:00
import Modal from "@/components/Modal" ;
2023-05-14 10:41:08 -05:00
import MainLayout from "@/layouts/MainLayout" ;
import ClickAwayHandler from "@/components/ClickAwayHandler" ;
2023-05-15 14:18:33 -05:00
import RadioButton from "@/components/RadioButton" ;
2023-05-26 23:29:45 -05:00
import CollectionModal from "@/components/Modal/CollectionModal" ;
import { useSession } from "next-auth/react" ;
2023-02-24 11:32:28 -06:00
export default function ( ) {
2023-03-22 18:11:54 -05:00
const { collections } = useCollectionStore ( ) ;
2023-04-23 08:26:39 -05:00
const [ expandDropdown , setExpandDropdown ] = useState ( false ) ;
2023-05-14 10:41:08 -05:00
const [ sortDropdown , setSortDropdown ] = useState ( false ) ;
2023-05-15 15:45:06 -05:00
const [ sortBy , setSortBy ] = useState ( "Name (A-Z)" ) ;
const [ sortedCollections , setSortedCollections ] = useState ( collections ) ;
2023-04-23 08:26:39 -05:00
2023-05-14 10:41:08 -05:00
const [ collectionModal , setCollectionModal ] = useState ( false ) ;
2023-04-23 08:26:39 -05:00
2023-05-26 23:29:45 -05:00
const session = useSession ( ) ;
2023-04-25 07:39:46 -05:00
const toggleCollectionModal = ( ) = > {
2023-05-14 10:41:08 -05:00
setCollectionModal ( ! collectionModal ) ;
} ;
const handleSortChange = ( event : ChangeEvent < HTMLInputElement > ) = > {
setSortBy ( event . target . value ) ;
2023-04-23 08:26:39 -05:00
} ;
2023-02-24 11:32:28 -06:00
2023-05-15 15:45:06 -05:00
useEffect ( ( ) = > {
const collectionsArray = [ . . . collections ] ;
if ( sortBy === "Name (A-Z)" )
setSortedCollections (
collectionsArray . sort ( ( a , b ) = > a . name . localeCompare ( b . name ) )
) ;
else if ( sortBy === "Description (A-Z)" )
setSortedCollections (
collectionsArray . sort ( ( a , b ) = >
a . description . localeCompare ( b . description )
)
) ;
else if ( sortBy === "Name (Z-A)" )
setSortedCollections (
collectionsArray . sort ( ( a , b ) = > b . name . localeCompare ( a . name ) )
) ;
else if ( sortBy === "Description (Z-A)" )
setSortedCollections (
collectionsArray . sort ( ( a , b ) = >
b . description . localeCompare ( a . description )
)
) ;
else if ( sortBy === "Date (Newest First)" )
setSortedCollections (
collectionsArray . sort (
( a , b ) = >
2023-05-26 23:29:45 -05:00
new Date ( b . createdAt as string ) . getTime ( ) -
new Date ( a . createdAt as string ) . getTime ( )
2023-05-15 15:45:06 -05:00
)
) ;
else if ( sortBy === "Date (Oldest First)" )
setSortedCollections (
collectionsArray . sort (
( a , b ) = >
2023-05-26 23:29:45 -05:00
new Date ( a . createdAt as string ) . getTime ( ) -
new Date ( b . createdAt as string ) . getTime ( )
2023-05-15 15:45:06 -05:00
)
) ;
} , [ collections , sortBy ] ) ;
2023-02-24 11:32:28 -06:00
return (
// ml-80
2023-05-14 10:41:08 -05:00
< MainLayout >
2023-04-30 15:54:40 -05:00
< div className = "p-5" >
2023-05-14 10:41:08 -05:00
< div className = "flex gap-3 items-center justify-between mb-5" >
< div className = "flex gap-3 items-center" >
< div className = "flex gap-2 items-center" >
< FontAwesomeIcon icon = { faBox } className = "w-5 h-5 text-sky-300" / >
< p className = "text-lg text-sky-900" > All Collections < / p >
< / div >
< div className = "relative" >
< div
onClick = { ( ) = > setExpandDropdown ( ! expandDropdown ) }
2023-05-27 22:21:35 -05:00
id = "expand-dropdown"
2023-05-14 10:41:08 -05:00
className = "inline-flex rounded-md cursor-pointer hover:bg-white hover:border-sky-500 border-sky-100 border duration-100 p-1"
>
< FontAwesomeIcon
icon = { faEllipsis }
2023-05-27 22:21:35 -05:00
id = "expand-dropdown"
2023-05-14 10:41:08 -05:00
className = "w-5 h-5 text-gray-500"
/ >
< / div >
{ expandDropdown ? (
< Dropdown
items = { [
{
2023-05-27 22:21:35 -05:00
name : "New Collection" ,
2023-05-14 10:41:08 -05:00
onClick : ( ) = > {
toggleCollectionModal ( ) ;
setExpandDropdown ( false ) ;
} ,
} ,
] }
onClickOutside = { ( e : Event ) = > {
const target = e . target as HTMLInputElement ;
2023-05-27 22:21:35 -05:00
if ( target . id !== "expand-dropdown" )
setExpandDropdown ( false ) ;
2023-05-14 10:41:08 -05:00
} }
className = "absolute top-8 left-0 w-36"
/ >
) : null }
< / div >
2023-03-28 02:31:50 -05:00
< / div >
2023-05-14 10:41:08 -05:00
2023-04-30 15:54:40 -05:00
< div className = "relative" >
< div
2023-05-14 10:41:08 -05:00
onClick = { ( ) = > setSortDropdown ( ! sortDropdown ) }
id = "sort-dropdown"
2023-04-30 15:54:40 -05:00
className = "inline-flex rounded-md cursor-pointer hover:bg-white hover:border-sky-500 border-sky-100 border duration-100 p-1"
>
< FontAwesomeIcon
2023-05-14 10:41:08 -05:00
icon = { faSort }
id = "sort-dropdown"
2023-05-01 15:00:23 -05:00
className = "w-5 h-5 text-gray-500"
2023-04-30 15:54:40 -05:00
/ >
< / div >
2023-05-14 10:41:08 -05:00
{ sortDropdown ? (
< ClickAwayHandler
2023-04-30 15:54:40 -05:00
onClickOutside = { ( e : Event ) = > {
const target = e . target as HTMLInputElement ;
2023-05-14 10:41:08 -05:00
if ( target . id !== "sort-dropdown" ) setSortDropdown ( false ) ;
2023-04-30 15:54:40 -05:00
} }
2023-05-15 15:45:06 -05:00
className = "absolute top-8 right-0 shadow-md bg-gray-50 rounded-md p-2 z-10 border border-sky-100 w-48"
2023-05-14 10:41:08 -05:00
>
2023-05-15 14:18:33 -05:00
< p className = "mb-2 text-sky-900 text-center font-semibold" >
Sort by
< / p >
2023-05-14 10:41:08 -05:00
< div className = "flex flex-col gap-2" >
2023-05-15 14:18:33 -05:00
< RadioButton
2023-05-15 15:45:06 -05:00
label = "Name (A-Z)"
state = { sortBy === "Name (A-Z)" }
onClick = { handleSortChange }
/ >
< RadioButton
label = "Name (Z-A)"
state = { sortBy === "Name (Z-A)" }
onClick = { handleSortChange }
/ >
< RadioButton
label = "Description (A-Z)"
state = { sortBy === "Description (A-Z)" }
onClick = { handleSortChange }
/ >
< RadioButton
label = "Description (Z-A)"
state = { sortBy === "Description (Z-A)" }
2023-05-15 14:18:33 -05:00
onClick = { handleSortChange }
/ >
< RadioButton
2023-05-15 15:45:06 -05:00
label = "Date (Newest First)"
state = { sortBy === "Date (Newest First)" }
2023-05-15 14:18:33 -05:00
onClick = { handleSortChange }
/ >
< RadioButton
2023-05-15 15:45:06 -05:00
label = "Date (Oldest First)"
state = { sortBy === "Date (Oldest First)" }
2023-05-15 14:18:33 -05:00
onClick = { handleSortChange }
/ >
2023-05-14 10:41:08 -05:00
< / div >
< / ClickAwayHandler >
2023-04-30 15:54:40 -05:00
) : null }
< / div >
2023-03-28 02:31:50 -05:00
< / div >
2023-05-14 10:41:08 -05:00
2023-05-24 20:47:18 -05:00
< div className = "grid 2xl:grid-cols-4 xl:grid-cols-3 sm:grid-cols-2 gap-5" >
2023-05-15 15:45:06 -05:00
{ sortedCollections . map ( ( e , i ) = > {
2023-04-30 15:54:40 -05:00
return < CollectionCard key = { i } collection = { e } / > ;
} ) }
2023-04-23 08:26:39 -05:00
2023-04-30 15:54:40 -05:00
< div
2023-05-25 09:22:27 -05:00
className = "p-5 self-stretch bg-gradient-to-tr from-sky-100 from-10% via-gray-100 via-20% min-h-[12rem] rounded-md cursor-pointer shadow duration-100 hover:shadow-none flex flex-col gap-4 justify-center items-center group"
2023-04-30 15:54:40 -05:00
onClick = { toggleCollectionModal }
>
2023-05-25 09:17:20 -05:00
< p className = "text-sky-900 group-hover:opacity-0 duration-100" >
New Collection
< / p >
< FontAwesomeIcon
icon = { faPlus }
className = "w-8 h-8 text-sky-500 group-hover:w-12 group-hover:h-12 group-hover:-mt-10 duration-100"
/ >
2023-04-30 15:54:40 -05:00
< / div >
2023-04-25 07:39:46 -05:00
< / div >
2023-03-28 02:31:50 -05:00
< / div >
2023-05-14 10:41:08 -05:00
{ collectionModal ? (
< Modal toggleModal = { toggleCollectionModal } >
2023-05-26 23:29:45 -05:00
< CollectionModal
activeCollection = { {
name : "" ,
description : "" ,
ownerId : session.data?.user.id as number ,
members : [ ] ,
} }
toggleCollectionModal = { toggleCollectionModal }
method = "CREATE"
/ >
2023-05-14 10:41:08 -05:00
< / Modal >
) : null }
< / MainLayout >
2023-02-24 11:32:28 -06:00
) ;
}