diff --git a/src/components/MapComponent.tsx b/src/components/MapComponent.tsx new file mode 100644 index 0000000..aa0fbe9 --- /dev/null +++ b/src/components/MapComponent.tsx @@ -0,0 +1,15 @@ +import { useContext, useEffect } from "preact/hooks"; +import { LeafletContext } from "#src/providers/LeafletProvider.tsx"; + +export function MapComponent() { + const leaf = useContext(LeafletContext); + if (!leaf) return
Component placeholder
; + useEffect(() => { + const map = leaf.map("map").setView(leaf.latLng(0, 0), 2); + leaf.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", { + attribution: + '© OpenStreetMap contributors', + }).addTo(map); + }); + return
; +} diff --git a/src/dev.ts b/src/dev.ts index ae73946..2ab5a89 100755 --- a/src/dev.ts +++ b/src/dev.ts @@ -1,7 +1,7 @@ #!/usr/bin/env -S deno run -A --watch=static/,routes/ import dev from "$fresh/dev.ts"; -import config from "./fresh.config.ts"; +import config from "#src/fresh.config.ts"; import "$std/dotenv/load.ts"; diff --git a/src/fresh.gen.ts b/src/fresh.gen.ts index cc09e45..15a0ba2 100644 --- a/src/fresh.gen.ts +++ b/src/fresh.gen.ts @@ -19,6 +19,7 @@ import * as $countdown from "./routes/countdown.tsx"; import * as $greet_name_ from "./routes/greet/[name].tsx"; import * as $greet_middleware from "./routes/greet/_middleware.ts"; import * as $index from "./routes/index.tsx"; +import * as $map from "./routes/map.tsx"; import * as $partials_about_id_ from "./routes/partials/about/[id].tsx"; import * as $projects_id_ from "./routes/projects/[id].tsx"; import * as $reportHandler from "./routes/reportHandler.ts"; @@ -27,6 +28,7 @@ import * as $subscribe from "./routes/subscribe.tsx"; import * as $Chart from "./islands/Chart.tsx"; import * as $Countdown from "./islands/Countdown.tsx"; import * as $Counter from "./islands/Counter.tsx"; +import * as $MapIsland from "./islands/MapIsland.tsx"; import * as $NextContentButton from "./islands/NextContentButton.tsx"; import { type Manifest } from "$fresh/server.ts"; @@ -49,6 +51,7 @@ const manifest = { "./routes/greet/[name].tsx": $greet_name_, "./routes/greet/_middleware.ts": $greet_middleware, "./routes/index.tsx": $index, + "./routes/map.tsx": $map, "./routes/partials/about/[id].tsx": $partials_about_id_, "./routes/projects/[id].tsx": $projects_id_, "./routes/reportHandler.ts": $reportHandler, @@ -59,6 +62,7 @@ const manifest = { "./islands/Chart.tsx": $Chart, "./islands/Countdown.tsx": $Countdown, "./islands/Counter.tsx": $Counter, + "./islands/MapIsland.tsx": $MapIsland, "./islands/NextContentButton.tsx": $NextContentButton, }, baseUrl: import.meta.url, diff --git a/src/islands/Counter.tsx b/src/islands/Counter.tsx index 2b8df82..8f01e78 100644 --- a/src/islands/Counter.tsx +++ b/src/islands/Counter.tsx @@ -1,7 +1,7 @@ import { Signal } from "@preact/signals"; import { ComponentChildren } from "preact"; -import { Button } from "../components/Button.tsx"; -import { Card } from "../components/Card.tsx"; +import { Button } from "#src/components/Button.tsx"; +import { Card } from "#src/components/Card.tsx"; interface Props { count: Signal; diff --git a/src/islands/MapIsland.tsx b/src/islands/MapIsland.tsx new file mode 100644 index 0000000..6086c0b --- /dev/null +++ b/src/islands/MapIsland.tsx @@ -0,0 +1,10 @@ +import { MapComponent } from "#src/components/MapComponent.tsx"; +import { LeafletProvider } from "#src/providers/LeafletProvider.tsx"; + +export function MapIsland() { + return ( + + + + ); +} diff --git a/src/providers/LeafletProvider.tsx b/src/providers/LeafletProvider.tsx new file mode 100644 index 0000000..10b4836 --- /dev/null +++ b/src/providers/LeafletProvider.tsx @@ -0,0 +1,34 @@ +import * as Leaflet from "https://esm.sh/v135/@types/leaflet@1.9.4/index.d.ts"; +import { IS_BROWSER } from "$fresh/runtime.ts"; +import { useState } from "preact/hooks"; +import { ComponentChildren, createContext } from "preact"; + +// Create a context to hold Leaflet data/functions +export const LeafletContext = createContext(null); + +// LeafletProvider component manages Leaflet loading and context +export function LeafletProvider(props: { children: ComponentChildren }) { + if (!IS_BROWSER) { + return

Leaflet must be loaded on the client. No children will render

; + } + const [value, setValue] = useState(null); + return ( + <> + +