diff --git a/frontend/src/components/profile/ProfileModal.jsx b/frontend/src/components/profile/ProfileModal.jsx index a0c7bb9..6415d54 100644 --- a/frontend/src/components/profile/ProfileModal.jsx +++ b/frontend/src/components/profile/ProfileModal.jsx @@ -3,7 +3,7 @@ import PropTypes from "prop-types"; import { saveProfile, deleteProfile } from "../../api/api"; import Modal from "../ui/Modal"; import Alert from "../ui/Alert"; -import { Loader } from "lucide-react"; +import { Loader, ArrowUp, ArrowDown } from "lucide-react"; function unsanitize(text) { return text.replace(/\\:/g, ":").replace(/\\n/g, "\n"); @@ -30,6 +30,10 @@ function ProfileModal({ const [isDeleting, setIsDeleting] = useState(false); const [loading, setLoading] = useState(true); const [modalTitle, setModalTitle] = useState(""); + const [formatSortKey, setFormatSortKey] = useState("score"); + const [formatSortDirection, setFormatSortDirection] = useState("desc"); + const [tagSortKey, setTagSortKey] = useState("name"); + const [tagSortDirection, setTagSortDirection] = useState("desc"); useEffect(() => { if (isOpen) { @@ -57,17 +61,17 @@ function ProfileModal({ name: format.name, score: existingFormat ? existingFormat.score : 0, tags: format.tags || [], + date_created: format.date_created, + date_modified: format.date_modified, }; }); setCustomFormats(safeCustomFormats); - // Extract all unique tags from custom formats const allTags = [ ...new Set(safeCustomFormats.flatMap((format) => format.tags)), ]; setFormatTags(allTags); - // Initialize tag scores const initialTagScores = {}; allTags.forEach((tag) => { initialTagScores[tag] = 0; @@ -170,6 +174,91 @@ function ProfileModal({ event.target.select(); }; + const sortedFormats = [...filteredFormats].sort((a, b) => { + if (formatSortKey === "name") { + return formatSortDirection === "asc" + ? a.name.localeCompare(b.name) + : b.name.localeCompare(a.name); + } else if (formatSortKey === "score") { + return formatSortDirection === "asc" + ? a.score - b.score + : b.score - a.score; + } else if (formatSortKey === "dateCreated") { + return formatSortDirection === "asc" + ? new Date(a.date_created) - new Date(b.date_created) + : new Date(b.date_created) - new Date(a.date_created); + } else if (formatSortKey === "dateModified") { + return formatSortDirection === "asc" + ? new Date(a.date_modified) - new Date(b.date_modified) + : new Date(b.date_modified) - new Date(a.date_modified); + } + return 0; + }); + + const sortedTags = [...filteredTags].sort((a, b) => { + if (tagSortKey === "name") { + return tagSortDirection === "asc" + ? a.localeCompare(b) + : b.localeCompare(a); + } else if (tagSortKey === "score") { + return tagSortDirection === "asc" + ? tagScores[a] - tagScores[b] + : tagScores[b] - tagScores[a]; + } else if (tagSortKey === "dateCreated") { + return tagSortDirection === "asc" + ? new Date(a.date_created) - new Date(b.date_created) + : new Date(b.date_created) - new Date(a.date_created); + } else if (tagSortKey === "dateModified") { + return tagSortDirection === "asc" + ? new Date(a.date_modified) - new Date(b.date_modified) + : new Date(b.date_modified) - new Date(a.date_modified); + } + return 0; + }); + + const SortDropdown = ({ options, currentKey, currentDirection, onSort }) => { + const [isOpen, setIsOpen] = useState(false); + + const handleSort = (key) => { + if (key === currentKey) { + onSort(key, currentDirection === "asc" ? "desc" : "asc"); + } else { + onSort(key, "desc"); + } + setIsOpen(false); + }; + + return ( +