From 6e6c23b6ad090e577a4b7ddba184af0c2020df19 Mon Sep 17 00:00:00 2001 From: Felix Zett Date: Sat, 30 Aug 2025 21:14:23 +0200 Subject: [PATCH] feat: / shows current/next trip. --- backend/routes/trips.py | 15 ++++- frontend/src/App.tsx | 136 +++++++++++++++++++++++++--------------- frontend/src/api.ts | 6 ++ frontend/src/main.tsx | 5 +- 4 files changed, 108 insertions(+), 54 deletions(-) diff --git a/backend/routes/trips.py b/backend/routes/trips.py index 6b581cb..851b2ae 100644 --- a/backend/routes/trips.py +++ b/backend/routes/trips.py @@ -1,4 +1,4 @@ - +from datetime import date from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session, joinedload from uuid import UUID @@ -129,3 +129,16 @@ def reconfigure_trip(trip_id: UUID, payload: TripUpdate, db: Session = Depends(g "deleted_checked_trip_item_ids": deleted_checked, "created_trip_item_ids": created_ids, } + +@router.get("/next-id", response_model=UUID) +def get_next_trip_id(db: Session = Depends(get_db)): + today = date.today() + trip = ( + db.query(models.Trip) + .filter(models.Trip.start_date >= today) + .order_by(models.Trip.start_date.asc()) + .first() + ) + if not trip: + raise HTTPException(status_code=404, detail="No upcoming trip found") + return trip.id diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index c6b7787..99662a4 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,11 +1,27 @@ import React, { useState, useEffect } from "react"; -import { BrowserRouter as Router, Routes, Route, Link, Navigate, useParams } from "react-router-dom"; -import { getSeed, getTrips, getTripItems, toggleTripItem } from "./api"; +import { BrowserRouter as Router, Routes, Route, Link, Navigate, useNavigate } from "react-router-dom"; +import { getSeed, getTrips, getNextTripId } from "./api"; import ItemsPage from "./pages/ItemsPage"; import TripChecklist from "./pages/TripChecklist"; +function NextTripRedirect({ trips }: { trips: any[] }) { + const [nextTripId, setNextTripId] = React.useState(null); + const [error, setError] = React.useState(null); + + React.useEffect(() => { + getNextTripId() + .then(setNextTripId) + .catch(() => setError("Kein anstehender Trip gefunden")); + }, []); + + if (error) return
{error}
; + if (!nextTripId) return
Lade...
; + return ; +} + export default function App() { const [trips, setTrips] = useState([]); + const navigate = useNavigate(); async function loadTrips() { const data = await getTrips(); @@ -16,59 +32,75 @@ export default function App() { loadTrips(); }, []); + async function goToCurrentTrip() { + try { + const id = await getNextTripId(); + navigate(`/trips/${id}`); + } catch { + alert("Kein anstehender Trip gefunden"); + } + } + return ( - -
-

Packlist

+
+

Packlist

-
- - - - - - - + + -
- - - - {trips.map((trip) => ( -
  • - - {trip.name} ({trip.start_date} – {trip.end_date}) - -
  • - ))} - - } - /> - } - /> - } /> - } /> -
    + + + + +
    - + + + + {trips.map((trip) => ( +
  • + + {trip.name} ({trip.start_date} – {trip.end_date}) + +
  • + ))} + + } + /> + } + /> + } /> + } /> +
    +
    ); } + +// Wichtig: Der -Inhalt muss innerhalb von verwendet werden! +// In main.tsx ist das bereits der Fall. diff --git a/frontend/src/api.ts b/frontend/src/api.ts index 6c423c0..6f744b6 100644 --- a/frontend/src/api.ts +++ b/frontend/src/api.ts @@ -82,3 +82,9 @@ export async function createItem(name: string, tags: string[]): Promise { if (!res.ok) throw new Error("Failed to create item"); return res.json(); } + +export async function getNextTripId(): Promise { + const res = await fetch(`${API_BASE}/trips/next-id`); + if (!res.ok) throw new Error("No upcoming trip found"); + return res.json(); +} diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx index c62d990..58169c8 100644 --- a/frontend/src/main.tsx +++ b/frontend/src/main.tsx @@ -3,13 +3,16 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App'; import './index.css'; +import { BrowserRouter } from "react-router-dom"; const queryClient = new QueryClient(); ReactDOM.createRoot(document.getElementById('root')!).render( - + + + ); \ No newline at end of file