import { useEffect, useMemo, useRef, useState } from "react";
import { useLocation, useNavigate } from "react-router-dom";
import { MapContainer, TileLayer, Marker, ZoomControl, useMapEvents } from "react-leaflet";
import "leaflet/dist/leaflet.css";
import "../utils/leafletIcons";
import Icon from "../components/Icon";
import {
CafeFeature,
City,
fetchCafeFeatures,
fetchCities,
fetchMyCafes,
registerCafe,
updateCafe,
} from "../services/campaignApi";
import { getCafeUuid, setCafeUuid } from "../utils/cafe";
import { fromE164, toE164 } from "../utils/phone";
const DEFAULT_CAFE_LOCATION = { lat: 35.6892, lng: 51.389 };
function findTehran(cities: City[]): City | undefined {
return cities.find(
(c) => c.city_name === "تهران" || c.city_name.toLowerCase() === "tehran",
);
}
function FormField({
label,
placeholder,
hint,
value,
onChange,
}: {
label: string;
placeholder: string;
hint?: string;
value: string;
onChange: (value: string) => void;
}) {
return (
onChange(e.target.value)}
placeholder={placeholder}
className="w-full rounded-2xl border border-gray-200 px-4 py-3 text-right h-14 placeholder:font-light placeholder:text-[#999999]"
/>
{hint && (
{hint}
)}
);
}
function LocationPicker({
onSelect,
}: {
onSelect: (lat: number, lng: number) => void;
}) {
const onSelectRef = useRef(onSelect);
useEffect(() => {
onSelectRef.current = onSelect;
}, [onSelect]);
const handlers = useMemo(
() => ({
click(e: { latlng: { lat: number; lng: number } }) {
onSelectRef.current(e.latlng.lat, e.latlng.lng);
},
}),
[],
);
useMapEvents(handlers);
return null;
}
function CafeLocationMap({
label,
location,
onChange,
}: {
label: string;
location: { lat: number; lng: number };
onChange: (lat: number, lng: number) => void;
}) {
return (
);
}
function UploadBox({
label,
buttonLabel,
}: {
label: string;
buttonLabel: string;
}) {
return (
);
}
function FeatureChip({
label,
checked,
onToggle,
}: {
label: string;
checked: boolean;
onToggle: () => void;
}) {
return (
);
}
export default function CafeOwnerRegister() {
const navigate = useNavigate();
const location = useLocation();
// panel's "اطلاعات کافه" link navigates here with state:{step:2} to signal edit mode
const isEditMode =
(location.state as { step?: number } | null)?.step === 2;
const [cafeName, setCafeName] = useState("");
const [address, setAddress] = useState("");
const [cafePhone, setCafePhone] = useState("");
const [cafeLocation, setCafeLocation] = useState(DEFAULT_CAFE_LOCATION);
const [selectedFeatures, setSelectedFeatures] = useState([]);
const [cities, setCities] = useState([]);
// explicitly selected in edit mode (pre-filled from existing cafe); empty = auto-select Tehran below
const [selectedCityUuid, setSelectedCityUuid] = useState("");
const [cafeFeatures, setCafeFeatures] = useState([]);
const [isSubmitting, setIsSubmitting] = useState(false);
const [error, setError] = useState("");
// redirect owners who already have a cafe away from fresh registration
useEffect(() => {
if (!isEditMode && getCafeUuid()) {
navigate("/owner/panel", { replace: true });
}
}, [isEditMode, navigate]);
useEffect(() => {
fetchCities()
.then(setCities)
.catch(() => {});
fetchCafeFeatures()
.then(setCafeFeatures)
.catch(() => {});
}, []);
// fall back to Tehran when no city has been explicitly selected yet
const effectiveCityUuid =
selectedCityUuid ||
findTehran(cities)?.uuid ||
cities[0]?.uuid ||
"";
useEffect(() => {
if (!isEditMode) return;
fetchMyCafes()
.then((cafes) => {
const cafe = cafes[0];
if (!cafe) return;
setCafeName(cafe.name);
setSelectedCityUuid(cafe.city.uuid);
setAddress(cafe.address);
setCafePhone(fromE164(cafe.phone_number));
setCafeLocation({
lat: cafe.location.coordinates[1],
lng: cafe.location.coordinates[0],
});
setSelectedFeatures(cafe.features.map((f) => f.uuid));
})
.catch(() => {});
}, [isEditMode]);
const toggleFeature = (uuid: string) => {
setSelectedFeatures((prev) =>
prev.includes(uuid) ? prev.filter((f) => f !== uuid) : [...prev, uuid],
);
};
const handleContinue = async () => {
setError("");
setIsSubmitting(true);
try {
const payload = {
city_uuid: effectiveCityUuid,
name: cafeName,
phone_number: cafePhone ? toE164(cafePhone) : "",
location: {
type: "Point" as const,
coordinates: [cafeLocation.lng, cafeLocation.lat] as [
number,
number,
],
},
address,
feature_uuids: selectedFeatures,
};
if (isEditMode) {
const cafeUuid = getCafeUuid() ?? "";
await updateCafe(cafeUuid, payload);
navigate("/owner/panel");
} else {
const cafe = await registerCafe({ owner_uuid: "", ...payload });
setCafeUuid(cafe.uuid);
navigate("/owner/register/success");
}
} catch {
if (!isEditMode) {
navigate("/owner/register/fail");
} else {
setError("ذخیره تغییرات با خطا مواجه شد. لطفاً دوباره تلاش کنید.");
}
} finally {
setIsSubmitting(false);
}
};
return (
setCafeLocation({ lat, lng })}
/>
{cafeFeatures.map((feature) => (
toggleFeature(feature.uuid)}
/>
))}
{error && (
{error}
)}
);
}