// Villa Mesochori — local guide with real photos (Wikimedia Commons) and a map of the area.
const guideNS = window.VillaMesochoriDesignSystem_9e1a21;
const { Card: GCard, Tag: GTag, Badge: GBadge, LucideIcon: GIcon } = guideNS;
const commons = (file, w) =>
`https://commons.wikimedia.org/wiki/Special:FilePath/${encodeURIComponent(file)}?width=${w || 800}`;
// Places now come from the content store — fully editable in the owners' area.
const HOUSE = { lat: 36.5359, lng: 23.0799 };
// Guide-card image with a graceful branded fallback if the photo can't load
function GImg({ src, alt }) {
const [failed, setFailed] = React.useState(false);
if (failed || !src) {
return (
{alt}
);
}
return
setFailed(true)} style={{ width: "100%", height: "100%", objectFit: "cover", display: "block", background: "var(--surface-sunken)" }} />;
}
const guideCommonsBase = commons; // alias
function GuideMap({ places, onPick }) {
const ref = React.useRef(null);
const mapRef = React.useRef(null);
const layerRef = React.useRef(null);
React.useEffect(() => {
if (!window.L || !ref.current || mapRef.current) return;
const map = L.map(ref.current, { scrollWheelZoom: false });
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution: '© OpenStreetMap contributors',
}).addTo(map);
mapRef.current = map;
layerRef.current = L.layerGroup().addTo(map);
return () => { map.remove(); mapRef.current = null; };
}, []);
React.useEffect(() => {
const map = mapRef.current, layer = layerRef.current;
if (!map || !layer) return;
layer.clearLayers();
const house = L.circleMarker([HOUSE.lat, HOUSE.lng], {
radius: 10, color: "#FAF6EF", weight: 2, fillColor: "#C05E37", fillOpacity: 1,
}).addTo(layer).bindPopup("Villa Mesochori
The house — Mesochori village");
const pts = [house.getLatLng()];
places.forEach((p) => {
if (!p.lat || !p.lng) return;
const m = L.circleMarker([p.lat, p.lng], {
radius: 7, color: "#FAF6EF", weight: 2, fillColor: "#4E7A5A", fillOpacity: 1,
}).addTo(layer).bindPopup(`${p.name}
${p.dist} from the house`);
m.on("click", () => onPick && onPick(p.id));
pts.push(m.getLatLng());
});
map.fitBounds(L.latLngBounds(pts).pad(0.18));
}, [places]);
return ;
}
function Guide() {
const [cat, setCat] = React.useState("All");
const c = window.VMContent.get();
const guidePlaces = (c.places || []).map((p, i) => Object.assign({ id: `p${i}` }, p));
const guideCats = ["All"].concat([...new Set(guidePlaces.map((p) => p.cat).filter(Boolean))]);
const shown = guidePlaces.filter((p) => cat === "All" || p.cat === cat);
return (
Places to go
{c.guideTitle}
{c.guideIntro}
{guideCats.map((t) => setCat(t)}>{t})}
{shown.map((p) => (
}
eyebrow={p.cat}
title={p.name}
footer={
{p.dist} from the house
}
>
"{p.tip}"
))}
The map
Everything within an hour of the house
The terracotta dot is the house. Photos: Wikimedia Commons (CC) — we'll swap in our own as we take them.
More places in the printed guide at the house
);
}
window.VMGuide = Guide;