"use client"; import { useEffect, useReducer, useTransition } from "react"; import { makeInitialState, reducer, type Screen, type Tab, } from "@/lib/app-state"; import { AppDataProvider, type AppData } from "@/lib/app-context"; import type { Place } from "@/lib/types"; import { deleteCollection, deletePlace } from "@/lib/db/actions"; import { TabBar } from "@/components/ui-primitives"; import { Icons } from "@/components/icons"; import { PlacesListScreen } from "@/screens/places-list-screen"; import { PlaceDetailScreen } from "@/screens/place-detail-screen"; import { CollectionsListScreen } from "@/screens/collections-list-screen"; import { CollectionDetailScreen } from "@/screens/collection-detail-screen"; import { ProfileScreen } from "@/screens/profile-screen"; import { AddPlaceSheet } from "@/sheets/add-place-sheet"; import { EditPlaceSheet } from "@/sheets/edit-place-sheet"; import { SaveToCollectionSheet } from "@/sheets/save-to-collection-sheet"; import { CollectionFormSheet } from "@/sheets/collection-form-sheet"; import { InviteDialog } from "@/sheets/invite-dialog"; import { MembersSheet, ConfirmDialog } from "@/sheets/members-sheet"; export function PlacesApp({ initialPlaces, data, }: { initialPlaces: Place[]; data: AppData; }) { const [state, dispatch] = useReducer(reducer, initialPlaces, makeInitialState); const [, startTransition] = useTransition(); useEffect(() => { if (!state.toast) return; const key = state.toastKey; const id = setTimeout( () => dispatch({ type: "CLEAR_TOAST", key }), 2200, ); return () => clearTimeout(id); }, [state.toast, state.toastKey]); useEffect(() => { const sync = () => dispatch({ type: "SET_OFFLINE", value: !navigator.onLine }); sync(); window.addEventListener("online", sync); window.addEventListener("offline", sync); return () => { window.removeEventListener("online", sync); window.removeEventListener("offline", sync); }; }, []); const top = state.stack[state.stack.length - 1]; const activeTab: Tab = top.screen === "place" || top.screen === "collection" ? state.tab : (top.screen as Tab); const onTab = (id: string) => { if (id === "profile" || id === "collections" || id === "places") { dispatch({ type: "TAB", tab: id }); } }; const renderScreen = (screen: Screen) => { if (screen === "places") return ; if (screen === "collections") return ; if (screen === "profile") return ; if (screen === "place") return ( ); if (screen === "collection") return ( ); return null; }; const m = state.modal; const placeForDelete = m?.type === "confirmDeletePlace" ? state.places.find((p) => p.id === m.placeId) : null; const collectionForDelete = m?.type === "confirmDeleteCollection" ? data.collections.find((c) => c.id === m.collectionId) : null; return (
{renderScreen(top.screen)} dispatch({ type: "OPEN_ADD" })} showFab={top.screen !== "profile"} /> {m?.type === "add" && ( dispatch({ type: "CLOSE_MODAL" })} dispatch={dispatch} /> )} {m?.type === "editPlace" && (() => { const p = state.places.find((x) => x.id === m.placeId); return p ? ( dispatch({ type: "CLOSE_MODAL" })} dispatch={dispatch} /> ) : null; })()} {m?.type === "saveToCollection" && ( dispatch({ type: "CLOSE_MODAL" })} dispatch={dispatch} /> )} {m?.type === "createCollection" && ( dispatch({ type: "CLOSE_MODAL" })} dispatch={dispatch} /> )} {m?.type === "editCollection" && (() => { const c = data.collections.find((x) => x.id === m.collectionId); return c ? ( dispatch({ type: "CLOSE_MODAL" })} dispatch={dispatch} /> ) : null; })()} {m?.type === "invite" && ( dispatch({ type: "CLOSE_MODAL" })} dispatch={dispatch} /> )} {m?.type === "members" && ( dispatch({ type: "CLOSE_MODAL" })} dispatch={dispatch} /> )} {m?.type === "confirmDeletePlace" && placeForDelete && ( { const id = m.placeId; dispatch({ type: "DELETE_PLACE", placeId: id }); startTransition(() => { deletePlace(id).catch(() => dispatch({ type: "TOAST", value: "Xóa thất bại" }), ); }); }} onClose={() => dispatch({ type: "CLOSE_MODAL" })} /> )} {m?.type === "confirmDeleteCollection" && collectionForDelete && ( { const id = m.collectionId; dispatch({ type: "CLOSE_MODAL" }); dispatch({ type: "BACK" }); startTransition(() => { deleteCollection(id) .then(() => dispatch({ type: "TOAST", value: "Đã xóa" })) .catch(() => dispatch({ type: "TOAST", value: "Xóa thất bại" })); }); }} onClose={() => dispatch({ type: "CLOSE_MODAL" })} /> )} {state.toast && (
{state.toast}
)}
); }