"use client"; import { useCallback, useState } from "react"; import { tripsAPI, Trip } from "@/lib/api/trips"; import { useInfiniteResource } from "@/hooks/useInfiniteResource"; import { useDeleteResource } from "@/hooks/useDeleteResource"; import { CARD_TITLE_ACTION, CARD_TITLE_ROW, Card, CardContent, CardHeader, CardTitle, } from "@/components/ui/card"; import { Button, ButtonLink } from "@/components/ui/button"; import { EmptyState } from "@/components/ui/empty-state"; import { useQuickCreate } from "@/components/layout/quick-create"; import { DeleteWithReassignDialog } from "@/components/dives/delete-with-reassign-dialog"; import { TripCard } from "@/components/trips/trip-card"; import { BackdropCardList } from "@/components/ui/backdrop-card"; import { TripDialog } from "@/components/trips/trip-dialog"; import { Luggage, Plus } from "lucide-react"; const RECENT_TRIPS_COUNT = 5; // The plain-delete toast, and the first half of the one a move gets - "moved to // Cebu 2026" is an addition to what happened, not a replacement for it. const DELETED_MESSAGE = "Trip deleted successfully."; // Shows the user's most recent trips by trip date (up to 5), each editable and // deletable where it stands. Used on the Home page so divers can quickly jump // back into a trip they're logging dives for. export function RecentTripsCard() { const openCreate = useQuickCreate(); const [editingTrip, setEditingTrip] = useState(null); // The trips list endpoint already sorts by each trip's earliest part start, // descending, so the first page is exactly the most recent trips - no // client-side sorting (which would disagree with /trips). const fetchTrips = useCallback( (page: number, perPage: number) => tripsAPI.getTrips(page, perPage), [], ); const { items: recentTrips, isLoading: isLoadingTrips, reload, applySaved, } = useInfiniteResource(fetchTrips, { keyOf: (trip) => trip.uuid, itemsPerPage: RECENT_TRIPS_COUNT, errorMessage: "Failed to load trips. Please try again.", }); const { deletingId, pendingId, requestDelete, cancelDelete, confirmDelete } = useDeleteResource(tripsAPI.deleteTrip, { successMessage: DELETED_MESSAGE, errorMessage: "Failed to delete trip. Please try again.", // Read again rather than dropping the row: the card shows the latest // five, so a delete owes it the sixth, and one that moved its dives // changes another trip's counts. onDeleted: () => reload(), }); return (
Recent Trips View all trips
{isLoadingTrips ? ( ) : recentTrips.length === 0 ? ( openCreate("trip")}> Add your first trip } /> ) : ( {recentTrips.map((trip) => ( setEditingTrip(trip)} onDelete={() => requestDelete(trip.uuid)} isDeleting={deletingId === trip.uuid} /> ))} )} !open && setEditingTrip(null)} trip={editingTrip} onSaved={applySaved} /> confirmDelete( moveDivesTo, name ? `${DELETED_MESSAGE} Its dives moved to ${name}.` : undefined, ) } />
); }