feat: implement TripChecklist component and update trips route for detailed view
This commit is contained in:
parent
e79d3a2b87
commit
3186a9d549
2 changed files with 59 additions and 44 deletions
|
|
@ -1,22 +1,17 @@
|
|||
import React, { useState, useEffect } from "react";
|
||||
import { BrowserRouter as Router, Routes, Route, Link, Navigate } from "react-router-dom";
|
||||
import { BrowserRouter as Router, Routes, Route, Link, Navigate, useParams } from "react-router-dom";
|
||||
import { getSeed, getTrips, getTripItems, toggleTripItem } from "./api";
|
||||
import ItemsPage from "./pages/ItemsPage";
|
||||
import TripChecklist from "./pages/TripChecklist";
|
||||
|
||||
export default function App() {
|
||||
const [trips, setTrips] = useState<any[]>([]);
|
||||
const [items, setItems] = useState<Record<string, any[]>>({});
|
||||
|
||||
async function loadTrips() {
|
||||
const data = await getTrips();
|
||||
setTrips(data);
|
||||
}
|
||||
|
||||
async function loadItems(tripId: string) {
|
||||
const data = await getTripItems(tripId);
|
||||
setItems((prev) => ({ ...prev, [tripId]: data }));
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
loadTrips();
|
||||
}, []);
|
||||
|
|
@ -52,47 +47,25 @@ export default function App() {
|
|||
<Route
|
||||
path="/trips"
|
||||
element={
|
||||
<>
|
||||
<ul>
|
||||
{trips.map((trip) => (
|
||||
<div key={trip.id} className="border rounded p-2 mb-4">
|
||||
<div className="flex justify-between items-center">
|
||||
<div>
|
||||
<h2 className="font-bold">{trip.name}</h2>
|
||||
<p>
|
||||
{trip.start_date} – {trip.end_date}
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
className="text-sm text-blue-500 underline"
|
||||
onClick={() => loadItems(trip.id)}
|
||||
>
|
||||
Packliste anzeigen
|
||||
</button>
|
||||
</div>
|
||||
{items[trip.id] && (
|
||||
<ul className="mt-2">
|
||||
{items[trip.id].map((item) => (
|
||||
<li key={item.id} className="flex items-center gap-2">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={item.checked}
|
||||
onChange={async () => {
|
||||
await toggleTripItem(item.id);
|
||||
await loadItems(trip.id);
|
||||
}}
|
||||
/>
|
||||
<span>{item.name_calculated}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
<li key={trip.id} className="mb-2">
|
||||
<Link
|
||||
to={`/trips/${trip.id}`}
|
||||
className="text-blue-600 underline"
|
||||
>
|
||||
{trip.name} <span className="text-gray-500">({trip.start_date} – {trip.end_date})</span>
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</>
|
||||
</ul>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/trips/:id"
|
||||
element={<TripChecklist trips={trips} />}
|
||||
/>
|
||||
<Route path="/items" element={<ItemsPage />} />
|
||||
{/* Optional: Redirect / to /trips */}
|
||||
<Route path="/" element={<Navigate to="/trips" />} />
|
||||
</Routes>
|
||||
</div>
|
||||
|
|
|
|||
42
frontend/src/pages/TripChecklist.tsx
Normal file
42
frontend/src/pages/TripChecklist.tsx
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
// filepath: frontend/src/pages/TripChecklist.tsx
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { getTripItems, toggleTripItem } from "../api";
|
||||
|
||||
export default function TripChecklist({ trips }: { trips: any[] }) {
|
||||
const { id } = useParams();
|
||||
const [items, setItems] = useState<any[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (id) {
|
||||
getTripItems(id).then(setItems);
|
||||
}
|
||||
}, [id]);
|
||||
|
||||
const trip = trips.find((t) => t.id === id);
|
||||
|
||||
if (!trip) return <div>Trip not found</div>;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2 className="font-bold text-xl mb-2">{trip.name}</h2>
|
||||
<p className="mb-4">{trip.start_date} – {trip.end_date}</p>
|
||||
<ul>
|
||||
{items.map((item) => (
|
||||
<li key={item.id} className="flex items-center gap-2">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={item.checked}
|
||||
onChange={async () => {
|
||||
await toggleTripItem(item.id);
|
||||
const updated = await getTripItems(id!);
|
||||
setItems(updated);
|
||||
}}
|
||||
/>
|
||||
<span>{item.name_calculated}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Loading…
Reference in a new issue