made sorting logic typesafe

This commit is contained in:
Daniel 2023-06-14 06:14:50 +03:30
parent d375f8f914
commit 8d094f320a
6 changed files with 65 additions and 52 deletions

View File

@ -1,10 +1,11 @@
import React, { ChangeEvent } from "react"; import React, { ChangeEvent } from "react";
import ClickAwayHandler from "./ClickAwayHandler"; import ClickAwayHandler from "./ClickAwayHandler";
import RadioButton from "./RadioButton"; import RadioButton from "./RadioButton";
import { Sort } from "@/types/global";
type Props = { type Props = {
handleSortChange: (e: ChangeEvent<HTMLInputElement>) => void; handleSortChange: (e: Sort) => void;
sortBy: string; sortBy: Sort;
toggleSortDropdown: Function; toggleSortDropdown: Function;
}; };
@ -25,38 +26,38 @@ export default function SortLinkDropdown({
<div className="flex flex-col gap-2"> <div className="flex flex-col gap-2">
<RadioButton <RadioButton
label="Name (A-Z)" label="Name (A-Z)"
state={sortBy === "Name (A-Z)"} state={sortBy === Sort.NameAZ}
onClick={handleSortChange} onClick={() => handleSortChange(Sort.NameAZ)}
/> />
<RadioButton <RadioButton
label="Name (Z-A)" label="Name (Z-A)"
state={sortBy === "Name (Z-A)"} state={sortBy === Sort.NameZA}
onClick={handleSortChange} onClick={() => handleSortChange(Sort.NameZA)}
/> />
<RadioButton <RadioButton
label="Title (A-Z)" label="Title (A-Z)"
state={sortBy === "Title (A-Z)"} state={sortBy === Sort.TitleAZ}
onClick={handleSortChange} onClick={() => handleSortChange(Sort.TitleAZ)}
/> />
<RadioButton <RadioButton
label="Title (Z-A)" label="Title (Z-A)"
state={sortBy === "Title (Z-A)"} state={sortBy === Sort.TitleZA}
onClick={handleSortChange} onClick={() => handleSortChange(Sort.TitleZA)}
/> />
<RadioButton <RadioButton
label="Date (Newest First)" label="Date (Newest First)"
state={sortBy === "Date (Newest First)"} state={sortBy === Sort.DateNewestFirst}
onClick={handleSortChange} onClick={() => handleSortChange(Sort.DateNewestFirst)}
/> />
<RadioButton <RadioButton
label="Date (Oldest First)" label="Date (Oldest First)"
state={sortBy === "Date (Oldest First)"} state={sortBy === Sort.DateOldestFirst}
onClick={handleSortChange} onClick={() => handleSortChange(Sort.DateOldestFirst)}
/> />
</div> </div>
</ClickAwayHandler> </ClickAwayHandler>

View File

@ -2,7 +2,7 @@ import Dropdown from "@/components/Dropdown";
import LinkCard from "@/components/LinkCard"; import LinkCard from "@/components/LinkCard";
import useCollectionStore from "@/store/collections"; import useCollectionStore from "@/store/collections";
import useLinkStore from "@/store/links"; import useLinkStore from "@/store/links";
import { CollectionIncludingMembers } from "@/types/global"; import { CollectionIncludingMembers, Sort } from "@/types/global";
import { import {
faEllipsis, faEllipsis,
faFolder, faFolder,
@ -10,7 +10,7 @@ import {
} from "@fortawesome/free-solid-svg-icons"; } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { ChangeEvent, useEffect, useState } from "react"; import { useEffect, useState } from "react";
import MainLayout from "@/layouts/MainLayout"; import MainLayout from "@/layouts/MainLayout";
import { useSession } from "next-auth/react"; import { useSession } from "next-auth/react";
import ProfilePhoto from "@/components/ProfilePhoto"; import ProfilePhoto from "@/components/ProfilePhoto";
@ -29,15 +29,15 @@ export default function Index() {
const [expandDropdown, setExpandDropdown] = useState(false); const [expandDropdown, setExpandDropdown] = useState(false);
const [sortDropdown, setSortDropdown] = useState(false); const [sortDropdown, setSortDropdown] = useState(false);
const [sortBy, setSortBy] = useState("Name (A-Z)"); const [sortBy, setSortBy] = useState<Sort>(Sort.NameAZ);
const [activeCollection, setActiveCollection] = const [activeCollection, setActiveCollection] =
useState<CollectionIncludingMembers>(); useState<CollectionIncludingMembers>();
const [sortedLinks, setSortedLinks] = useState(links); const [sortedLinks, setSortedLinks] = useState(links);
const handleSortChange = (event: ChangeEvent<HTMLInputElement>) => { const handleSortChange = (e: Sort) => {
setSortBy(event.target.value); setSortBy(e);
}; };
useEffect(() => { useEffect(() => {
@ -51,15 +51,15 @@ export default function Index() {
...links.filter((e) => e.collection.id === Number(router.query.id)), ...links.filter((e) => e.collection.id === Number(router.query.id)),
]; ];
if (sortBy === "Name (A-Z)") if (sortBy === Sort.NameAZ)
setSortedLinks(linksArray.sort((a, b) => a.name.localeCompare(b.name))); setSortedLinks(linksArray.sort((a, b) => a.name.localeCompare(b.name)));
else if (sortBy === "Title (A-Z)") else if (sortBy === Sort.TitleAZ)
setSortedLinks(linksArray.sort((a, b) => a.title.localeCompare(b.title))); setSortedLinks(linksArray.sort((a, b) => a.title.localeCompare(b.title)));
else if (sortBy === "Name (Z-A)") else if (sortBy === Sort.NameZA)
setSortedLinks(linksArray.sort((a, b) => b.name.localeCompare(a.name))); setSortedLinks(linksArray.sort((a, b) => b.name.localeCompare(a.name)));
else if (sortBy === "Title (Z-A)") else if (sortBy === Sort.TitleZA)
setSortedLinks(linksArray.sort((a, b) => b.title.localeCompare(a.title))); setSortedLinks(linksArray.sort((a, b) => b.title.localeCompare(a.title)));
else if (sortBy === "Date (Newest First)") else if (sortBy === Sort.DateNewestFirst)
setSortedLinks( setSortedLinks(
linksArray.sort( linksArray.sort(
(a, b) => (a, b) =>
@ -67,7 +67,7 @@ export default function Index() {
new Date(a.createdAt as string).getTime() new Date(a.createdAt as string).getTime()
) )
); );
else if (sortBy === "Date (Oldest First)") else if (sortBy === Sort.DateOldestFirst)
setSortedLinks( setSortedLinks(
linksArray.sort( linksArray.sort(
(a, b) => (a, b) =>

View File

@ -2,6 +2,7 @@ import LinkCard from "@/components/LinkCard";
import SortLinkDropdown from "@/components/SortLinkDropdown"; import SortLinkDropdown from "@/components/SortLinkDropdown";
import MainLayout from "@/layouts/MainLayout"; import MainLayout from "@/layouts/MainLayout";
import useLinkStore from "@/store/links"; import useLinkStore from "@/store/links";
import { Sort } from "@/types/global";
import { faLink, faSort } from "@fortawesome/free-solid-svg-icons"; import { faLink, faSort } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { ChangeEvent, useEffect, useState } from "react"; import { ChangeEvent, useEffect, useState } from "react";
@ -10,25 +11,25 @@ export default function Links() {
const { links } = useLinkStore(); const { links } = useLinkStore();
const [sortDropdown, setSortDropdown] = useState(false); const [sortDropdown, setSortDropdown] = useState(false);
const [sortBy, setSortBy] = useState("Name (A-Z)"); const [sortBy, setSortBy] = useState<Sort>(Sort.NameAZ);
const [sortedLinks, setSortedLinks] = useState(links); const [sortedLinks, setSortedLinks] = useState(links);
const handleSortChange = (event: ChangeEvent<HTMLInputElement>) => { const handleSortChange = (e: Sort) => {
setSortBy(event.target.value); setSortBy(e);
}; };
useEffect(() => { useEffect(() => {
const linksArray = [...links]; const linksArray = [...links];
if (sortBy === "Name (A-Z)") if (sortBy === Sort.NameAZ)
setSortedLinks(linksArray.sort((a, b) => a.name.localeCompare(b.name))); setSortedLinks(linksArray.sort((a, b) => a.name.localeCompare(b.name)));
else if (sortBy === "Title (A-Z)") else if (sortBy === Sort.TitleAZ)
setSortedLinks(linksArray.sort((a, b) => a.title.localeCompare(b.title))); setSortedLinks(linksArray.sort((a, b) => a.title.localeCompare(b.title)));
else if (sortBy === "Name (Z-A)") else if (sortBy === Sort.NameZA)
setSortedLinks(linksArray.sort((a, b) => b.name.localeCompare(a.name))); setSortedLinks(linksArray.sort((a, b) => b.name.localeCompare(a.name)));
else if (sortBy === "Title (Z-A)") else if (sortBy === Sort.TitleZA)
setSortedLinks(linksArray.sort((a, b) => b.title.localeCompare(a.title))); setSortedLinks(linksArray.sort((a, b) => b.title.localeCompare(a.title)));
else if (sortBy === "Date (Newest First)") else if (sortBy === Sort.DateNewestFirst)
setSortedLinks( setSortedLinks(
linksArray.sort( linksArray.sort(
(a, b) => (a, b) =>
@ -36,7 +37,7 @@ export default function Links() {
new Date(a.createdAt as string).getTime() new Date(a.createdAt as string).getTime()
) )
); );
else if (sortBy === "Date (Oldest First)") else if (sortBy === Sort.DateOldestFirst)
setSortedLinks( setSortedLinks(
linksArray.sort( linksArray.sort(
(a, b) => (a, b) =>

View File

@ -3,6 +3,7 @@ import LinkCard from "@/components/LinkCard";
import SortLinkDropdown from "@/components/SortLinkDropdown"; import SortLinkDropdown from "@/components/SortLinkDropdown";
import MainLayout from "@/layouts/MainLayout"; import MainLayout from "@/layouts/MainLayout";
import useLinkStore from "@/store/links"; import useLinkStore from "@/store/links";
import { Sort } from "@/types/global";
import { faFilter, faSearch, faSort } from "@fortawesome/free-solid-svg-icons"; import { faFilter, faSearch, faSort } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
@ -35,11 +36,11 @@ export default function Links() {
const [filterDropdown, setFilterDropdown] = useState(false); const [filterDropdown, setFilterDropdown] = useState(false);
const [sortDropdown, setSortDropdown] = useState(false); const [sortDropdown, setSortDropdown] = useState(false);
const [sortBy, setSortBy] = useState("Name (A-Z)"); const [sortBy, setSortBy] = useState<Sort>(Sort.NameAZ);
const [sortedLinks, setSortedLinks] = useState(links); const [sortedLinks, setSortedLinks] = useState(links);
const handleSortChange = (event: ChangeEvent<HTMLInputElement>) => { const handleSortChange = (e: Sort) => {
setSortBy(event.target.value); setSortBy(e);
}; };
useEffect(() => { useEffect(() => {
@ -61,15 +62,15 @@ export default function Links() {
}), }),
]; ];
if (sortBy === "Name (A-Z)") if (sortBy === Sort.NameAZ)
setSortedLinks(linksArray.sort((a, b) => a.name.localeCompare(b.name))); setSortedLinks(linksArray.sort((a, b) => a.name.localeCompare(b.name)));
else if (sortBy === "Title (A-Z)") else if (sortBy === Sort.TitleAZ)
setSortedLinks(linksArray.sort((a, b) => a.title.localeCompare(b.title))); setSortedLinks(linksArray.sort((a, b) => a.title.localeCompare(b.title)));
else if (sortBy === "Name (Z-A)") else if (sortBy === Sort.NameZA)
setSortedLinks(linksArray.sort((a, b) => b.name.localeCompare(a.name))); setSortedLinks(linksArray.sort((a, b) => b.name.localeCompare(a.name)));
else if (sortBy === "Title (Z-A)") else if (sortBy === Sort.TitleZA)
setSortedLinks(linksArray.sort((a, b) => b.title.localeCompare(a.title))); setSortedLinks(linksArray.sort((a, b) => b.title.localeCompare(a.title)));
else if (sortBy === "Date (Newest First)") else if (sortBy === Sort.DateNewestFirst)
setSortedLinks( setSortedLinks(
linksArray.sort( linksArray.sort(
(a, b) => (a, b) =>
@ -77,7 +78,7 @@ export default function Links() {
new Date(a.createdAt as string).getTime() new Date(a.createdAt as string).getTime()
) )
); );
else if (sortBy === "Date (Oldest First)") else if (sortBy === Sort.DateOldestFirst)
setSortedLinks( setSortedLinks(
linksArray.sort( linksArray.sort(
(a, b) => (a, b) =>

View File

@ -8,6 +8,7 @@ import MainLayout from "@/layouts/MainLayout";
import { Tag } from "@prisma/client"; import { Tag } from "@prisma/client";
import useTagStore from "@/store/tags"; import useTagStore from "@/store/tags";
import SortLinkDropdown from "@/components/SortLinkDropdown"; import SortLinkDropdown from "@/components/SortLinkDropdown";
import { Sort } from "@/types/global";
export default function Index() { export default function Index() {
const router = useRouter(); const router = useRouter();
@ -16,14 +17,14 @@ export default function Index() {
const { tags } = useTagStore(); const { tags } = useTagStore();
const [sortDropdown, setSortDropdown] = useState(false); const [sortDropdown, setSortDropdown] = useState(false);
const [sortBy, setSortBy] = useState("Name (A-Z)"); const [sortBy, setSortBy] = useState<Sort>(Sort.NameAZ);
const [activeTag, setActiveTag] = useState<Tag>(); const [activeTag, setActiveTag] = useState<Tag>();
const [sortedLinks, setSortedLinks] = useState(links); const [sortedLinks, setSortedLinks] = useState(links);
const handleSortChange = (event: ChangeEvent<HTMLInputElement>) => { const handleSortChange = (e: Sort) => {
setSortBy(event.target.value); setSortBy(e);
}; };
useEffect(() => { useEffect(() => {
@ -37,15 +38,15 @@ export default function Index() {
), ),
]; ];
if (sortBy === "Name (A-Z)") if (sortBy === Sort.NameAZ)
setSortedLinks(linksArray.sort((a, b) => a.name.localeCompare(b.name))); setSortedLinks(linksArray.sort((a, b) => a.name.localeCompare(b.name)));
else if (sortBy === "Title (A-Z)") else if (sortBy === Sort.TitleAZ)
setSortedLinks(linksArray.sort((a, b) => a.title.localeCompare(b.title))); setSortedLinks(linksArray.sort((a, b) => a.title.localeCompare(b.title)));
else if (sortBy === "Name (Z-A)") else if (sortBy === Sort.NameZA)
setSortedLinks(linksArray.sort((a, b) => b.name.localeCompare(a.name))); setSortedLinks(linksArray.sort((a, b) => b.name.localeCompare(a.name)));
else if (sortBy === "Title (Z-A)") else if (sortBy === Sort.TitleZA)
setSortedLinks(linksArray.sort((a, b) => b.title.localeCompare(a.title))); setSortedLinks(linksArray.sort((a, b) => b.title.localeCompare(a.title)));
else if (sortBy === "Date (Newest First)") else if (sortBy === Sort.DateNewestFirst)
setSortedLinks( setSortedLinks(
linksArray.sort( linksArray.sort(
(a, b) => (a, b) =>
@ -53,7 +54,7 @@ export default function Index() {
new Date(a.createdAt as string).getTime() new Date(a.createdAt as string).getTime()
) )
); );
else if (sortBy === "Date (Oldest First)") else if (sortBy === Sort.DateOldestFirst)
setSortedLinks( setSortedLinks(
linksArray.sort( linksArray.sort(
(a, b) => (a, b) =>

View File

@ -42,3 +42,12 @@ export interface PublicCollectionIncludingLinks
ownerName?: string; ownerName?: string;
links: Link[]; links: Link[];
} }
export enum Sort {
NameAZ,
NameZA,
TitleAZ,
TitleZA,
DateNewestFirst,
DateOldestFirst,
}