From 8cef14fd80ee95728eeeabdfc48cc01ff8fa679f Mon Sep 17 00:00:00 2001 From: Ingrihka Date: Tue, 20 Oct 2026 10:31:45 +0200 Subject: [PATCH] feat: vising for handlet liste(#59) --- .../pages/shoppingLists/CompletedListView.css | 106 +++++++++ .../pages/shoppingLists/CompletedListView.tsx | 202 ++++++++++++++++++ .../shoppingLists/ShoppingListDetailPage.tsx | 5 + .../shoppingLists/shoppingListMockData.ts | 125 +++++++++++ .../pages/shoppingLists/shoppingListTypes.ts | 2 + 5 files changed, 440 insertions(+) create mode 100644 frontend/src/pages/shoppingLists/CompletedListView.css create mode 100644 frontend/src/pages/shoppingLists/CompletedListView.tsx diff --git a/frontend/src/pages/shoppingLists/CompletedListView.css b/frontend/src/pages/shoppingLists/CompletedListView.css new file mode 100644 index 0000000..b9374c4 --- /dev/null +++ b/frontend/src/pages/shoppingLists/CompletedListView.css @@ -0,0 +1,106 @@ +/* Visning for en handlet liste – fra Figma (Previous list). + Notatblokken, oppsummeringen og oppsettet kommer fra ShoppingListDetailPage.css. */ + +.completed-list__paper { + display: flex; + flex-direction: column; + gap: 18px; + padding-bottom: 34px; +} + +.completed-list__header { + display: flex; + justify-content: space-between; + align-items: flex-start; + gap: 16px; +} + +/* Skjevt «HANDLET»-stempel */ +.completed-list__stamp { + margin: 8px 24px 0 0; + padding: 6px 14px; + border: 2px solid var(--annotation); + border-radius: 4px; + font: 500 16px var(--font-mono); + letter-spacing: 0.24em; + color: var(--annotation); + transform: rotate(-8deg); +} + +/* Varene i to kolonner */ +.completed-list__columns { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 36px; +} + +.completed-list__column { + margin: 0; + padding: 0; + list-style: none; +} + +.completed-row { + display: flex; + align-items: center; + gap: 10px; + padding: 8px 0; + border-bottom: 1px solid var(--note-rule); +} + +.completed-row__check { + flex-shrink: 0; + color: var(--text-accent); +} + +.completed-row__name { + flex: 1; + min-width: 0; + font: 400 22px/28px var(--font-note); + color: var(--note-ink); +} + +.completed-row__price { + white-space: nowrap; + font: 500 10px var(--font-mono); + letter-spacing: 0.06em; + color: var(--text-secondary); +} + +/* «Slett lista» ser ut som en lenke, men er en knapp */ +.completed-list__delete { + align-self: flex-start; + padding: 0; + border: none; + background: none; + font: 500 10px var(--font-mono); + letter-spacing: 0.06em; + color: var(--text-accent); + cursor: pointer; +} + +.completed-list__delete:hover { + text-decoration: underline; +} + +.completed-list__delete:focus-visible { + outline: 2px solid var(--text-accent); + outline-offset: 2px; +} + +/* Mobil: én kolonne, mindre stempel */ +@media (max-width: 600px) { + .completed-list__columns { + grid-template-columns: 1fr; + gap: 0; + } + + .completed-list__stamp { + margin-right: 0; + font-size: 12px; + } + + .completed-row__name { + font-size: 19px; + } +} diff --git a/frontend/src/pages/shoppingLists/CompletedListView.tsx b/frontend/src/pages/shoppingLists/CompletedListView.tsx new file mode 100644 index 0000000..ba294aa --- /dev/null +++ b/frontend/src/pages/shoppingLists/CompletedListView.tsx @@ -0,0 +1,202 @@ +import { Link } from "react-router"; +import type { ShoppingList } from "./shoppingListTypes"; +import "./CompletedListView.css"; +import "../../components/button/Button.css"; + +type CompletedListViewProps = { + list: ShoppingList; +}; + +// Gir f.eks. "47,80" +function formatPrice(value: number) { + return value.toFixed(2).replace(".", ","); +} + +// Gir f.eks. "18.09.2026" +function formatShortDate(isoDate: string) { + return new Date(isoDate).toLocaleDateString("nb-NO", { + day: "2-digit", + month: "2-digit", + year: "numeric", + }); +} + +// Gir f.eks. "FREDAG 18. SEPTEMBER 2026" +function formatLongDate(isoDate: string) { + return new Date(isoDate) + .toLocaleDateString("nb-NO", { + weekday: "long", + day: "numeric", + month: "long", + year: "numeric", + }) + .toUpperCase(); +} + +// Liten hake. Bruker currentColor, så fargen følger temaet. +function CheckIcon() { + return ( + + ); +} + +function CompletedListView({ list }: CompletedListViewProps) { + const completedAt = list.completedAt ?? list.createdAt; + const total = + list.estimatedTotal ?? + list.items.reduce( + (sum, item) => sum + (item.unitPrice ?? 0) * item.quantity, + 0, + ); + + // Deler varene i to kolonner: første halvdel til venstre, resten til høyre + const half = Math.ceil(list.items.length / 2); + const columns = [list.items.slice(0, half), list.items.slice(half)]; + + return ( +
+
+ {/* Oversikten over tidligere lister kobles av Alexis */} + + ← TIDLIGERE HANDLELISTER + +

FIG. 11 — HANDLET LISTE

+
+ +
+
+ + +
+

HANDLELAPPEN — IT2810 · GRUPPE 27

+

SIDE 11 / 11

+
+
+ ); +} + +export default CompletedListView; diff --git a/frontend/src/pages/shoppingLists/ShoppingListDetailPage.tsx b/frontend/src/pages/shoppingLists/ShoppingListDetailPage.tsx index ced4b41..4c69a37 100644 --- a/frontend/src/pages/shoppingLists/ShoppingListDetailPage.tsx +++ b/frontend/src/pages/shoppingLists/ShoppingListDetailPage.tsx @@ -8,6 +8,7 @@ import "../../components/shoppingListRow/ShoppingListRow.css"; import "../../components/checkbox/Checkbox.css"; import "../../components/quantityStepper/QuantityStepper.css"; import "../../components/button/Button.css"; +import CompletedListView from "./CompletedListView"; type SortOrder = "added" | "alphabetical"; @@ -97,6 +98,10 @@ function ShoppingListDetailPage() { ); } + // Handlede lister vises uten redigering + if (list.status === "COMPLETED") { + return ; + } return (
diff --git a/frontend/src/pages/shoppingLists/shoppingListMockData.ts b/frontend/src/pages/shoppingLists/shoppingListMockData.ts index 6be5388..244f6f4 100644 --- a/frontend/src/pages/shoppingLists/shoppingListMockData.ts +++ b/frontend/src/pages/shoppingLists/shoppingListMockData.ts @@ -191,4 +191,129 @@ export const mockLists: ShoppingList[] = [ }, ], }, + + { + id: "11", + name: "Ukeshandel", + status: "COMPLETED", + inUse: false, + createdAt: "2026-09-15", + completedAt: "2026-09-18", + store: "Kiwi Lerkendal", + estimatedTotal: 669.6, + items: [ + { + id: "19", + ean: "19", + name: "Lettmelk", + quantity: 2, + unitPrice: 23.9, + checked: true, + }, + { + id: "20", + ean: "20", + name: "Grovbrød", + quantity: 1, + unitPrice: 39.9, + checked: true, + }, + { + id: "21", + ean: "21", + name: "Norvegia 26 %", + quantity: 1, + unitPrice: 79.9, + checked: true, + }, + { + id: "22", + ean: "22", + name: "Egg, 12 stk", + quantity: 1, + unitPrice: 54.9, + checked: true, + }, + { + id: "23", + ean: "23", + name: "Bananer", + quantity: 1, + unitPrice: 29.9, + checked: true, + }, + { + id: "24", + ean: "24", + name: "Epler", + quantity: 6, + unitPrice: 5.9, + checked: true, + }, + { + id: "25", + ean: "25", + name: "Kyllingfilet", + quantity: 1, + unitPrice: 119, + checked: true, + }, + { + id: "26", + ean: "26", + name: "Ris", + quantity: 1, + unitPrice: 32.9, + checked: true, + }, + { + id: "27", + ean: "27", + name: "Tomater", + quantity: 4, + unitPrice: 6.9, + checked: true, + }, + { + id: "28", + ean: "28", + name: "Agurk", + quantity: 1, + unitPrice: 16.9, + checked: true, + }, + { + id: "29", + ean: "29", + name: "Kaffe", + quantity: 1, + unitPrice: 64.9, + checked: true, + }, + { + id: "30", + ean: "30", + name: "Havregryn", + quantity: 1, + unitPrice: 28.9, + checked: true, + }, + { + id: "31", + ean: "31", + name: "Yoghurt", + quantity: 3, + unitPrice: 12.9, + checked: true, + }, + { + id: "32", + ean: "32", + name: "Smør", + quantity: 1, + unitPrice: 52.9, + checked: true, + }, + ], + }, ]; diff --git a/frontend/src/pages/shoppingLists/shoppingListTypes.ts b/frontend/src/pages/shoppingLists/shoppingListTypes.ts index 93be9f5..8a7ed85 100644 --- a/frontend/src/pages/shoppingLists/shoppingListTypes.ts +++ b/frontend/src/pages/shoppingLists/shoppingListTypes.ts @@ -16,4 +16,6 @@ export interface ShoppingList { createdAt: string; items: ShoppingListItem[]; estimatedTotal: number | null; + completedAt?: string; // dato listen ble handlet, f.eks. "2026-09-18" + store?: string; // butikken det ble handlet i }