diff --git a/frontend/src/pages/TripsPage.tsx b/frontend/src/pages/TripsPage.tsx index 85a7af5..64c2694 100644 --- a/frontend/src/pages/TripsPage.tsx +++ b/frontend/src/pages/TripsPage.tsx @@ -1,17 +1,26 @@ import React, { useState, useEffect } from "react"; import { Link } from "react-router-dom"; -import { getSeed, getTrips, deleteTrip, createTrip } from "../api"; +import { getSeed, getTrips, deleteTrip, createTrip, getTags } from "../api"; export default function TripsPage() { const [trips, setTrips] = useState([]); + const [allTags, setAllTags] = useState([]); const [newTrip, setNewTrip] = useState({ name: "", start_date: "", end_date: "" }); + const [selectedTags, setSelectedTags] = useState([]); + const [markedTags, setMarkedTags] = useState([]); const [creating, setCreating] = useState(false); + const [showForm, setShowForm] = useState(false); async function loadTrips() { const data = await getTrips(); setTrips(data); } + useEffect(() => { + loadTrips(); + getTags().then(setAllTags); + }, []); + async function handleDeleteTrip(tripId: string) { if (window.confirm("Diesen Trip wirklich löschen?")) { await deleteTrip(tripId); @@ -27,20 +36,19 @@ export default function TripsPage() { name: newTrip.name, start_date: newTrip.start_date, end_date: newTrip.end_date, - selected_tag_ids: [], - marked_tag_ids: [], + selected_tag_ids: selectedTags, + marked_tag_ids: markedTags, }); setNewTrip({ name: "", start_date: "", end_date: "" }); + setSelectedTags([]); + setMarkedTags([]); + setShowForm(false); await loadTrips(); } finally { setCreating(false); } } - useEffect(() => { - loadTrips(); - }, []); - // Markiere nächsten anstehenden Trip const today = new Date().toISOString().slice(0, 10); const nextTripIdx = trips.findIndex( @@ -48,40 +56,104 @@ export default function TripsPage() { ); const nextTripId = nextTripIdx !== -1 ? trips[nextTripIdx].id : null; + function toggleTag(tagId: string) { + setSelectedTags((prev) => + prev.includes(tagId) ? prev.filter((id) => id !== tagId) : [...prev, tagId] + ); + // Wenn ein Tag abgewählt wird, auch aus markedTags entfernen + setMarkedTags((prev) => prev.filter((id) => id !== tagId)); + } + + function toggleMarkTag(tagId: string) { + if (!selectedTags.includes(tagId)) return; + setMarkedTags((prev) => + prev.includes(tagId) ? prev.filter((id) => id !== tagId) : [...prev, tagId] + ); + } + return (

Packlist

-
- setNewTrip(t => ({ ...t, name: e.target.value }))} - className="border rounded px-2 py-1" - required - /> - setNewTrip(t => ({ ...t, start_date: e.target.value }))} - className="border rounded px-2 py-1" - required - /> - setNewTrip(t => ({ ...t, end_date: e.target.value }))} - className="border rounded px-2 py-1" - required - /> - -
+ + {showForm && ( +
+ setNewTrip(t => ({ ...t, name: e.target.value }))} + className="border rounded px-2 py-1" + required + /> +
+ setNewTrip(t => ({ ...t, start_date: e.target.value }))} + className="border rounded px-2 py-1" + required + /> + setNewTrip(t => ({ ...t, end_date: e.target.value }))} + className="border rounded px-2 py-1" + required + /> +
+
+
Tags auswählen:
+
+ {allTags.map((tag: any) => { + const isSelected = selectedTags.includes(tag.id); + const isMarked = markedTags.includes(tag.id); + return ( + toggleTag(tag.id)} + onDoubleClick={() => toggleMarkTag(tag.id)} + title={ + isSelected + ? isMarked + ? "Doppelklick: Markierung entfernen" + : "Doppelklick: Tag markieren" + : "Klick: Tag auswählen" + } + > + #{tag.name} + {isMarked && isSelected && ( + + )} + + ); + })} +
+
+ Klick: auswählen/abwählen, Doppelklick: markieren +
+
+ +
+ )} {trips.map(trip => { const isPast = trip.start_date < today;