Merge pull request #253 from trails-cool/feat/route-empty-state-cta
Show empty-state CTA on Route detail when no waypoints
This commit is contained in:
commit
29cbcef844
3 changed files with 49 additions and 1 deletions
|
|
@ -99,6 +99,11 @@ export default function RouteDetailPage({ loaderData }: Route.ComponentProps) {
|
|||
const [editLoading, setEditLoading] = useState(false);
|
||||
const [highlightedDay, setHighlightedDay] = useState<number | null>(null);
|
||||
|
||||
// A route is "empty" when it has no geometry and no computed distance —
|
||||
// i.e. nobody has planned any waypoints yet. Surfaced as a dedicated
|
||||
// empty-state below so the page isn't a dead end.
|
||||
const isEmpty = !route.geojson && route.distance == null;
|
||||
|
||||
const handleEditInPlanner = useCallback(async () => {
|
||||
setEditLoading(true);
|
||||
try {
|
||||
|
|
@ -121,7 +126,7 @@ export default function RouteDetailPage({ loaderData }: Route.ComponentProps) {
|
|||
<p className="mt-2 text-gray-600">{route.description}</p>
|
||||
)}
|
||||
</div>
|
||||
{isOwner && (
|
||||
{isOwner && !isEmpty && (
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<button
|
||||
onClick={handleEditInPlanner}
|
||||
|
|
@ -222,6 +227,35 @@ export default function RouteDetailPage({ loaderData }: Route.ComponentProps) {
|
|||
</div>
|
||||
)}
|
||||
|
||||
{isEmpty && (
|
||||
<div className="mt-6 flex flex-col items-center rounded-lg border border-dashed border-gray-300 bg-gray-50 px-6 py-12 text-center">
|
||||
<div className="text-4xl" aria-hidden="true">🗺️</div>
|
||||
<h2 className="mt-4 text-lg font-semibold text-gray-900">
|
||||
{t("routes.empty.heading")}
|
||||
</h2>
|
||||
<p className="mt-2 max-w-md text-sm text-gray-600">
|
||||
{isOwner ? t("routes.empty.bodyOwner") : t("routes.empty.bodyViewer")}
|
||||
</p>
|
||||
{isOwner && (
|
||||
<div className="mt-6 flex flex-wrap items-center justify-center gap-3">
|
||||
<button
|
||||
onClick={handleEditInPlanner}
|
||||
disabled={editLoading}
|
||||
className="rounded-md bg-blue-600 px-4 py-2 text-sm font-medium text-white hover:bg-blue-700 disabled:opacity-50"
|
||||
>
|
||||
{editLoading ? t("routes.opening") : t("routes.empty.openInPlanner")}
|
||||
</button>
|
||||
<a
|
||||
href={`/routes/${route.id}/edit`}
|
||||
className="text-sm text-gray-600 underline hover:text-gray-900"
|
||||
>
|
||||
{t("routes.empty.uploadGpx")}
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{versions.length > 0 && (
|
||||
<div className="mt-8">
|
||||
<h2 className="text-lg font-semibold text-gray-900">Version History</h2>
|
||||
|
|
|
|||
|
|
@ -179,6 +179,13 @@ export default {
|
|||
noRoutesYet: "Noch keine Routen. Erstelle deine erste Route!",
|
||||
noMapPreview: "Keine Kartenvorschau",
|
||||
saveChanges: "Änderungen speichern",
|
||||
empty: {
|
||||
heading: "Diese Route ist leer",
|
||||
bodyOwner: "Du hast noch keine Wegpunkte geplant. Öffne sie im Planer, um eine Strecke zu skizzieren, oder lade eine GPX-Datei hoch.",
|
||||
bodyViewer: "Diese Route enthält noch keine Wegpunkte.",
|
||||
openInPlanner: "Im Planer öffnen",
|
||||
uploadGpx: "oder eine GPX-Datei hochladen",
|
||||
},
|
||||
},
|
||||
activities: {
|
||||
title: "Aktivitäten",
|
||||
|
|
|
|||
|
|
@ -179,6 +179,13 @@ export default {
|
|||
noRoutesYet: "No routes yet. Create your first route!",
|
||||
noMapPreview: "No map preview",
|
||||
saveChanges: "Save Changes",
|
||||
empty: {
|
||||
heading: "This route is empty",
|
||||
bodyOwner: "You haven't planned any waypoints yet. Open it in the Planner to sketch a path, or upload a GPX file.",
|
||||
bodyViewer: "This route doesn't have any waypoints yet.",
|
||||
openInPlanner: "Open in Planner",
|
||||
uploadGpx: "or upload a GPX file",
|
||||
},
|
||||
},
|
||||
activities: {
|
||||
title: "Activities",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue