From 27584564bc0939dfb4f7edc26c5f3d73c70b9c96 Mon Sep 17 00:00:00 2001 From: Tara Aqeel Date: Tue, 20 Oct 2026 18:41:52 +0200 Subject: [PATCH 1/2] feat: legg til sortering av aktive handlelister (#77) --- .../pages/shoppingLists/ShoppingListsPage.css | 27 ++++++- .../pages/shoppingLists/ShoppingListsPage.tsx | 74 ++++++++++++++++++- 2 files changed, 97 insertions(+), 4 deletions(-) diff --git a/frontend/src/pages/shoppingLists/ShoppingListsPage.css b/frontend/src/pages/shoppingLists/ShoppingListsPage.css index 0eddd0f..fd9ef6a 100644 --- a/frontend/src/pages/shoppingLists/ShoppingListsPage.css +++ b/frontend/src/pages/shoppingLists/ShoppingListsPage.css @@ -224,7 +224,7 @@ .shopping-lists-page__actions { display: flex; - align-items: center; + align-items: flex-end; gap: 12px; flex-wrap: wrap; } @@ -327,4 +327,29 @@ /* Kortene retter seg opp ved hover */ .shopping-list-card:hover { transform: translateY(-4px) rotate(0deg); +} + +.shopping-lists-page__sort { + display: flex; + flex-direction: column; + gap: 6px; + font-family: var(--font-mono); + font-size: 11px; + color: var(--text-muted); +} + +.shopping-lists-page__sort select { + padding: 10px 14px; + font-family: var(--font-ui); + font-size: 13px; + color: var(--text-primary); + background: var(--bg-surface); + border: 1px solid var(--border-hairline); + border-radius: 6px; + cursor: pointer; +} + +.shopping-lists-page__sort select:focus-visible { + outline: 2px solid var(--text-accent); + outline-offset: 3px; } \ No newline at end of file diff --git a/frontend/src/pages/shoppingLists/ShoppingListsPage.tsx b/frontend/src/pages/shoppingLists/ShoppingListsPage.tsx index 3d04e2f..96ef276 100644 --- a/frontend/src/pages/shoppingLists/ShoppingListsPage.tsx +++ b/frontend/src/pages/shoppingLists/ShoppingListsPage.tsx @@ -1,3 +1,4 @@ +import { useEffect, useState } from "react"; import { useNavigate } from "react-router"; import ShoppingListCard from "./ShoppingListCard"; import type { ShoppingList } from "./shoppingListTypes"; @@ -62,12 +63,64 @@ const mockLists: ShoppingList[] = [ ]; +type SortOrder = "newest" | "oldest" | "name-asc" | "name-desc"; + +const SORT_STORAGE_KEY = "active-lists-sort-order"; + +function loadSortOrder(): SortOrder { + try { + const saved = localStorage.getItem(SORT_STORAGE_KEY); + + if ( + saved === "newest" || + saved === "oldest" || + saved === "name-asc" || + saved === "name-desc" + ) { + return saved; + } + } catch { + // Bruk standardverdien hvis localStorage ikke er tilgjengelig. + } + + return "newest"; +} + export default function ShoppingListsPage() { const navigate = useNavigate(); - const activeLists = mockLists.filter( - (list) => list.status === "ACTIVE" - ); +const [sortOrder, setSortOrder] = useState(loadSortOrder); + +useEffect(() => { + try { + localStorage.setItem(SORT_STORAGE_KEY, sortOrder); + } catch { + // Sorteringen fungerer selv om lagring ikke er tilgjengelig. + } +}, [sortOrder]); + +const activeLists = mockLists + .filter((list) => list.status === "ACTIVE") + .sort((a, b) => { + // Listen som er i bruk skal alltid ligge først. + if (a.inUse !== b.inUse) { + return a.inUse ? -1 : 1; + } + + switch (sortOrder) { + case "oldest": + return a.createdAt.localeCompare(b.createdAt); + + case "name-asc": + return a.name.localeCompare(b.name, "nb-NO"); + + case "name-desc": + return b.name.localeCompare(a.name, "nb-NO"); + + default: + return b.createdAt.localeCompare(a.createdAt); + } + }); function handleOpenList(id: string) { navigate(`/lists/${id}`); @@ -91,6 +144,21 @@ export default function ShoppingListsPage() {
+