This commit is contained in:
root
2026-06-08 10:02:16 +08:00
parent 934b9a4a23
commit b65908e328
24 changed files with 1216 additions and 93 deletions

60
app/lib/city-slugs.ts Normal file
View File

@@ -0,0 +1,60 @@
import { cities, type City } from "@/app/data/cities";
const CITY_SLUG_BY_NAME: Record<string, string> = {
: "dali",
: "chengdu",
: "shenzhen",
: "shanghai",
: "hangzhou",
: "xiamen",
: "beijing",
广: "guangzhou",
: "chongqing",
: "kunming",
: "sanya",
: "lijiang",
西: "xian",
: "nanjing",
: "changsha",
: "qingdao",
: "suzhou",
: "zhuhai",
};
function normalizeSlug(value: string): string {
return value
.trim()
.toLowerCase()
.replace(/[']/g, "")
.replace(/[^a-z0-9]+/g, "-")
.replace(/^-+|-+$/g, "");
}
export function citySlug(city: Pick<City, "slug" | "name" | "nameEn" | "id">): string {
if (city.slug) return normalizeSlug(city.slug);
if (CITY_SLUG_BY_NAME[city.name]) return CITY_SLUG_BY_NAME[city.name];
if (city.nameEn) return normalizeSlug(city.nameEn);
return `city-${city.id}`;
}
export function cityVolunteerHref(city: Pick<City, "slug" | "name" | "nameEn" | "id">): string {
return `/city/${encodeURIComponent(citySlug(city))}/volunteer`;
}
export function findCityBySlug(slug: string): City | undefined {
const decoded = decodeURIComponent(slug).trim();
const normalized = normalizeSlug(decoded);
return cities.find((city) => {
const candidates = [
city.slug,
citySlug(city),
city.name,
city.nameEn,
CITY_SLUG_BY_NAME[city.name],
].filter(Boolean);
return candidates.some((candidate) => {
const text = String(candidate);
return text === decoded || normalizeSlug(text) === normalized;
});
});
}