's'
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import Footer from "../../components/Footer";
|
||||
import Footer from "@/app/components/Footer";
|
||||
|
||||
export const metadata = {
|
||||
title: "关于我们 | 游牧中国",
|
||||
|
||||
272
app/[locale]/city/[slug]/page.tsx
Normal file
272
app/[locale]/city/[slug]/page.tsx
Normal file
@@ -0,0 +1,272 @@
|
||||
"use client";
|
||||
|
||||
import { use } from "react";
|
||||
import { useTranslation, Link } from "@/i18n/navigation";
|
||||
import Footer from "@/app/components/Footer";
|
||||
|
||||
interface CityGuide {
|
||||
slug: string;
|
||||
nameZh: string;
|
||||
nameEn: string;
|
||||
emoji: string;
|
||||
descriptionZh: string;
|
||||
descriptionEn: string;
|
||||
costOfLiving: {
|
||||
item: string;
|
||||
priceZh: string;
|
||||
priceEn: string;
|
||||
}[];
|
||||
coworking: {
|
||||
name: string;
|
||||
address: string;
|
||||
price: string;
|
||||
rating: number;
|
||||
}[];
|
||||
neighborhoods: {
|
||||
name: string;
|
||||
pros: string;
|
||||
cons: string;
|
||||
}[];
|
||||
tips: string[];
|
||||
}
|
||||
|
||||
const CITY_GUIDES: CityGuide[] = [
|
||||
{
|
||||
slug: "dali",
|
||||
nameZh: "大理",
|
||||
nameEn: "Dali",
|
||||
emoji: "🏯",
|
||||
descriptionZh: "大理是中国最受欢迎的的数字游民目的地之一,以其悠闲的生活方式、美丽的自然风光和实惠的生活成本著称。",
|
||||
descriptionEn: "Dali is one of China's most popular digital nomad destinations, known for its laid-back lifestyle, beautiful scenery, and affordable cost of living.",
|
||||
costOfLiving: [
|
||||
{ item: "租房 (单间)", priceZh: "¥800-1500/月", priceEn: "¥800-1500/month" },
|
||||
{ item: "共享办公", priceZh: "¥300-500/月", priceEn: "¥300-500/month" },
|
||||
{ item: "餐饮", priceZh: "¥30-50/天", priceEn: "¥30-50/day" },
|
||||
{ item: "咖啡", priceZh: "¥15-30/杯", priceEn: "¥15-30/cup" },
|
||||
],
|
||||
coworking: [
|
||||
{ name: "空岛空间", address: "大理古城人民路", price: "¥400/月", rating: 4.8 },
|
||||
{ name: "Dreamland", address: "大理古城博爱路", price: "¥350/月", rating: 4.6 },
|
||||
{ name: "柴米多", address: "大理古城叶榆路", price: "¥500/月", rating: 4.7 },
|
||||
],
|
||||
neighborhoods: [
|
||||
{ name: "大理古城", pros: "配套设施齐全,咖啡馆多", cons: "游客较多" },
|
||||
{ name: "海东", pros: "安静,海景房", cons: "交通不便" },
|
||||
{ name: "下关市区", pros: "生活便利,性价比高", cons: "缺乏氛围" },
|
||||
],
|
||||
tips: [
|
||||
"推荐10月-次年4月前往,天气最佳",
|
||||
"古城内租房建议提前实地看房",
|
||||
"办理民宿短租备案更合规",
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: "chengdu",
|
||||
nameZh: "成都",
|
||||
nameEn: "Chengdu",
|
||||
emoji: "🐼",
|
||||
descriptionZh: "成都被誉为天府之国,是中国西部的科技中心,也是一座充满生活气息的城市,非常适合数字游民。",
|
||||
descriptionEn: "Chengdu, known as the 'Land of Abundance', is the tech hub of western China and a city full of life, perfect for digital nomads.",
|
||||
costOfLiving: [
|
||||
{ item: "租房 (单间)", priceZh: "¥1200-2500/月", priceEn: "¥1200-2500/month" },
|
||||
{ item: "共享办公", priceZh: "¥400-800/月", priceEn: "¥400-800/month" },
|
||||
{ item: "餐饮", priceZh: "¥40-60/天", priceEn: "¥40-60/day" },
|
||||
{ item: "咖啡", priceZh: "¥20-35/杯", priceEn: "¥20-35/cup" },
|
||||
],
|
||||
coworking: [
|
||||
{ name: "Workfrom成都", address: "高新区天府大道", price: "¥600/月", rating: 4.7 },
|
||||
{ name: "Feng Coffee", address: "锦江区春熙路", price: "¥500/月", rating: 4.5 },
|
||||
{ name: "方糖小镇", address: "武侯区科华北路", price: "¥450/月", rating: 4.6 },
|
||||
],
|
||||
neighborhoods: [
|
||||
{ name: "高新区", pros: "科技公司多,年轻人多", cons: "房价较高" },
|
||||
{ name: "锦江区", pros: "美食众多,生活便利", cons: "较拥挤" },
|
||||
{ name: "玉林路", pros: "文艺氛围,咖啡馆多", cons: "老小区" },
|
||||
],
|
||||
tips: [
|
||||
"推荐3-5月或9-11月前往",
|
||||
"高新区互联网公司聚集,便于社交",
|
||||
"美食之都,餐饮选择丰富",
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: "shenzhen",
|
||||
nameZh: "深圳",
|
||||
nameEn: "Shenzhen",
|
||||
emoji: "🌃",
|
||||
descriptionZh: "深圳是中国最具活力的科技创新城市,毗邻香港,是年轻创业者的天堂。",
|
||||
descriptionEn: "Shenzhen is China's most dynamic tech innovation city, adjacent to Hong Kong, a paradise for young entrepreneurs.",
|
||||
costOfLiving: [
|
||||
{ item: "租房 (单间)", priceZh: "¥1500-3500/月", priceEn: "¥1500-3500/month" },
|
||||
{ item: "共享办公", priceZh: "¥600-1200/月", priceEn: "¥600-1200/month" },
|
||||
{ item: "餐饮", priceZh: "¥50-80/天", priceEn: "¥50-80/day" },
|
||||
{ item: "咖啡", priceZh: "¥25-40/杯", priceEn: "¥25-40/cup" },
|
||||
],
|
||||
coworking: [
|
||||
{ name: "WeWork", address: "南山区科技园", price: "¥1000/月", rating: 4.8 },
|
||||
{ name: "思微SimplyWork", address: "南山区科兴科学园", price: "¥800/月", rating: 4.6 },
|
||||
{ name: "柴火创客空间", address: "南山区高新南七道", price: "¥700/月", rating: 4.7 },
|
||||
],
|
||||
neighborhoods: [
|
||||
{ name: "南山区", pros: "科技公司集中,氛围好", cons: "房价最高" },
|
||||
{ name: "福田区", pros: "市中心,交通便利", cons: "缺乏创业氛围" },
|
||||
{ name: "龙华区", pros: "性价比高", cons: "较偏远" },
|
||||
],
|
||||
tips: [
|
||||
"全年气候宜人,随时适合前往",
|
||||
"创业氛围浓厚,便于资源对接",
|
||||
"离香港近,可一日往返",
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: "hangzhou",
|
||||
nameZh: "杭州",
|
||||
nameEn: "Hangzhou",
|
||||
emoji: "⛲",
|
||||
descriptionZh: "杭州是中国最美的城市之一,阿里巴巴总部所在地,数字经济发达。",
|
||||
descriptionEn: "Hangzhou is one of China's most beautiful cities, home to Alibaba, with a developed digital economy.",
|
||||
costOfLiving: [
|
||||
{ item: "租房 (单间)", priceZh: "¥1400-2800/月", priceEn: "¥1400-2800/month" },
|
||||
{ item: "共享办公", priceZh: "¥500-900/月", priceEn: "¥500-900/month" },
|
||||
{ item: "餐饮", priceZh: "¥45-70/天", priceEn: "¥45-70/day" },
|
||||
{ item: "咖啡", priceZh: "¥22-38/杯", priceEn: "¥22-38/cup" },
|
||||
],
|
||||
coworking: [
|
||||
{ name: "Binggo咖啡", address: "西湖区文二路", price: "¥600/月", rating: 4.6 },
|
||||
{ name: "创业邦", address: "滨江区江南大道", price: "¥700/月", rating: 4.5 },
|
||||
{ name: "福云咖啡", address: "西湖区教工路", price: "¥550/月", rating: 4.4 },
|
||||
],
|
||||
neighborhoods: [
|
||||
{ name: "滨江区", pros: "阿里附近,创业氛围浓", cons: "房价较高" },
|
||||
{ name: "西湖区", pros: "环境优美,生活便利", cons: "游客较多" },
|
||||
{ name: "余杭区", pros: "性价比高,阿里新总部", cons: "配套不全" },
|
||||
],
|
||||
tips: [
|
||||
"推荐4-5月前往,西湖景色最美",
|
||||
"阿里巴巴带动数字经济发展",
|
||||
"生活节奏适中,工作生活平衡好",
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default function CityGuidePage({ params }: { params: Promise<{ slug: string }> }) {
|
||||
const { slug } = use(params);
|
||||
const { t } = useTranslation("cityGuide");
|
||||
|
||||
const city = CITY_GUIDES.find((c) => c.slug === slug);
|
||||
|
||||
if (!city) {
|
||||
return (
|
||||
<div className="min-h-screen bg-[#fafafa] dark:bg-gray-950">
|
||||
<main className="max-w-[1200px] mx-auto px-4 py-16 text-center">
|
||||
<h1 className="text-2xl font-bold text-gray-900 dark:text-gray-100">城市指南不存在</h1>
|
||||
<Link href="/" className="text-[#ff4d4f] mt-4 inline-block">返回首页</Link>
|
||||
</main>
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-[#fafafa] dark:bg-gray-950">
|
||||
<main className="max-w-[1200px] mx-auto px-4 sm:px-6 py-6 sm:py-8">
|
||||
<Link href="/" className="inline-flex items-center gap-1 text-sm text-gray-500 dark:text-gray-400 hover:text-[#ff4d4f] mb-4">
|
||||
← 返回首页
|
||||
</Link>
|
||||
|
||||
<div className="bg-white dark:bg-gray-900 rounded-2xl overflow-hidden shadow-lg border border-gray-100 dark:border-gray-800">
|
||||
<div className="h-32 sm:h-48 bg-gradient-to-r from-purple-500 to-pink-500 flex items-end p-6 sm:p-8">
|
||||
<span className="text-5xl sm:text-7xl mb-2">{city.emoji}</span>
|
||||
<h1 className="text-3xl sm:text-4xl font-bold text-white ml-4">{city.nameZh}</h1>
|
||||
</div>
|
||||
|
||||
<div className="p-6 sm:p-8">
|
||||
<p className="text-gray-600 dark:text-gray-400 text-base sm:text-lg mb-8">
|
||||
{city.descriptionZh}
|
||||
</p>
|
||||
|
||||
<section className="mb-8">
|
||||
<h2 className="text-xl font-bold text-gray-900 dark:text-gray-100 mb-4 flex items-center gap-2">
|
||||
💰 生活成本
|
||||
</h2>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
|
||||
{city.costOfLiving.map((item, i) => (
|
||||
<div key={i} className="flex justify-between items-center p-3 bg-gray-50 dark:bg-gray-800 rounded-lg">
|
||||
<span className="text-gray-600 dark:text-gray-400">{item.item}</span>
|
||||
<span className="font-semibold text-gray-900 dark:text-gray-100">{item.priceZh}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="mb-8">
|
||||
<h2 className="text-xl font-bold text-gray-900 dark:text-gray-100 mb-4 flex items-center gap-2">
|
||||
💻 共享办公推荐
|
||||
</h2>
|
||||
<div className="space-y-3">
|
||||
{city.coworking.map((cw, i) => (
|
||||
<div key={i} className="flex flex-col sm:flex-row sm:items-center justify-between p-4 bg-gray-50 dark:bg-gray-800 rounded-lg gap-2">
|
||||
<div>
|
||||
<div className="font-semibold text-gray-900 dark:text-gray-100">{cw.name}</div>
|
||||
<div className="text-sm text-gray-500 dark:text-gray-400">{cw.address}</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="text-[#ff4d4f] font-medium">{cw.price}</span>
|
||||
<span className="text-amber-500">⭐ {cw.rating}</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="mb-8">
|
||||
<h2 className="text-xl font-bold text-gray-900 dark:text-gray-100 mb-4 flex items-center gap-2">
|
||||
🏠 社区推荐
|
||||
</h2>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
|
||||
{city.neighborhoods.map((n, i) => (
|
||||
<div key={i} className="p-4 bg-gray-50 dark:bg-gray-800 rounded-lg">
|
||||
<div className="font-semibold text-gray-900 dark:text-gray-100 mb-2">{n.name}</div>
|
||||
<div className="text-sm text-green-600 dark:text-green-400 mb-1">✓ {n.pros}</div>
|
||||
<div className="text-sm text-red-500 dark:text-red-400">✗ {n.cons}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="mb-8">
|
||||
<h2 className="text-xl font-bold text-gray-900 dark:text-gray-100 mb-4 flex items-center gap-2">
|
||||
💡 实用Tips
|
||||
</h2>
|
||||
<ul className="space-y-2">
|
||||
{city.tips.map((tip, i) => (
|
||||
<li key={i} className="flex items-start gap-2 text-gray-600 dark:text-gray-400">
|
||||
<span className="text-[#ff4d4f]">•</span>
|
||||
{tip}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<div className="flex flex-col sm:flex-row gap-3">
|
||||
<Link
|
||||
href="/join"
|
||||
className="flex-1 text-center bg-[#ff4d4f] text-white py-3 px-6 rounded-full font-medium hover:bg-[#ff7a45] transition-colors"
|
||||
>
|
||||
加入当地社群
|
||||
</Link>
|
||||
<Link
|
||||
href="/meetups"
|
||||
className="flex-1 text-center bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 py-3 px-6 rounded-full font-medium hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors"
|
||||
>
|
||||
查看线下活动
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
236
app/[locale]/discuss/page.tsx
Normal file
236
app/[locale]/discuss/page.tsx
Normal file
@@ -0,0 +1,236 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useTranslation, Link } from "@/i18n/navigation";
|
||||
import Footer from "@/app/components/Footer";
|
||||
|
||||
interface Topic {
|
||||
id: string;
|
||||
title: string;
|
||||
author: string;
|
||||
avatar: string;
|
||||
views: number;
|
||||
replies: number;
|
||||
likes: number;
|
||||
category: string;
|
||||
lastActive: string;
|
||||
pinned: boolean;
|
||||
}
|
||||
|
||||
const MOCK_TOPICS: Topic[] = [
|
||||
{
|
||||
id: "1",
|
||||
title: "大理最佳共享办公空间推荐 Top 10",
|
||||
author: "林晓",
|
||||
avatar: "https://i.pravatar.cc/150?img=5",
|
||||
views: 2340,
|
||||
replies: 56,
|
||||
likes: 128,
|
||||
category: "资源共享",
|
||||
lastActive: "2小时前",
|
||||
pinned: true,
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
title: "2026年数字游民友好城市排名",
|
||||
author: "张浩",
|
||||
avatar: "https://i.pravatar.cc/150?img=3",
|
||||
views: 1890,
|
||||
replies: 42,
|
||||
likes: 95,
|
||||
category: "城市测评",
|
||||
lastActive: "5小时前",
|
||||
pinned: true,
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
title: "远程工作者的税务规划指南",
|
||||
author: "陈悦",
|
||||
avatar: "https://i.pravatar.cc/150?img=9",
|
||||
views: 1560,
|
||||
replies: 38,
|
||||
likes: 87,
|
||||
category: "税务签证",
|
||||
lastActive: "1天前",
|
||||
pinned: false,
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
title: "成都 vs 大理:哪个更适合游民?",
|
||||
author: "周杰",
|
||||
avatar: "https://i.pravatar.cc/150?img=7",
|
||||
views: 1230,
|
||||
replies: 67,
|
||||
likes: 54,
|
||||
category: "城市对比",
|
||||
lastActive: "3小时前",
|
||||
pinned: false,
|
||||
},
|
||||
{
|
||||
id: "5",
|
||||
title: "新手游民必备工具与装备清单",
|
||||
author: "吴婷",
|
||||
avatar: "https://i.pravatar.cc/150?img=1",
|
||||
views: 980,
|
||||
replies: 29,
|
||||
likes: 76,
|
||||
category: "经验分享",
|
||||
lastActive: "1天前",
|
||||
pinned: false,
|
||||
},
|
||||
{
|
||||
id: "6",
|
||||
title: "如何在泰国办理长期签证?",
|
||||
author: "杨帅",
|
||||
avatar: "https://i.pravatar.cc/150?img=12",
|
||||
views: 2150,
|
||||
replies: 89,
|
||||
likes: 156,
|
||||
category: "税务签证",
|
||||
lastActive: "30分钟前",
|
||||
pinned: false,
|
||||
},
|
||||
{
|
||||
id: "7",
|
||||
title: "数字游民保险选择指南",
|
||||
author: "赵琪",
|
||||
avatar: "https://i.pravatar.cc/150?img=16",
|
||||
views: 1780,
|
||||
replies: 45,
|
||||
likes: 112,
|
||||
category: "安全保障",
|
||||
lastActive: "6小时前",
|
||||
pinned: false,
|
||||
},
|
||||
{
|
||||
id: "8",
|
||||
title: "东南亚最佳数字游民目的地",
|
||||
author: "黄磊",
|
||||
avatar: "https://i.pravatar.cc/150?img=11",
|
||||
views: 3210,
|
||||
replies: 78,
|
||||
likes: 234,
|
||||
category: "目的地",
|
||||
lastActive: "1小时前",
|
||||
pinned: false,
|
||||
},
|
||||
];
|
||||
|
||||
const CATEGORIES = [
|
||||
{ key: "all", zh: "全部", en: "All" },
|
||||
{ key: "城市测评", zh: "城市测评", en: "City Review" },
|
||||
{ key: "城市对比", zh: "城市对比", en: "City Comparison" },
|
||||
{ key: "税务签证", zh: "税务签证", en: "Tax & Visa" },
|
||||
{ key: "资源共享", zh: "资源共享", en: "Resource Sharing" },
|
||||
{ key: "经验分享", zh: "经验分享", en: "Experience" },
|
||||
{ key: "安全保障", zh: "安全保障", en: "Safety & Insurance" },
|
||||
{ key: "目的地", zh: "目的地", en: "Destinations" },
|
||||
];
|
||||
|
||||
export default function DiscussPage() {
|
||||
const { t } = useTranslation("discuss");
|
||||
const [activeCategory, setActiveCategory] = useState("all");
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
|
||||
const filteredTopics = MOCK_TOPICS.filter((topic) => {
|
||||
const matchesCategory = activeCategory === "all" || topic.category === activeCategory;
|
||||
const matchesSearch = topic.title.toLowerCase().includes(searchQuery.toLowerCase());
|
||||
return matchesCategory && matchesSearch;
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-[#fafafa] dark:bg-gray-950">
|
||||
<main className="max-w-[1200px] mx-auto px-4 sm:px-6 py-6 sm:py-8">
|
||||
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4 mb-6">
|
||||
<div>
|
||||
<h1 className="text-2xl sm:text-3xl font-bold text-gray-900 dark:text-gray-100">
|
||||
{t("title")}
|
||||
</h1>
|
||||
<p className="text-gray-500 dark:text-gray-400 mt-1 text-sm sm:text-base">
|
||||
{t("subtitle")}
|
||||
</p>
|
||||
</div>
|
||||
<button className="bg-[#ff4d4f] text-white px-4 sm:px-6 py-2 sm:py-2.5 rounded-full font-medium text-sm hover:bg-[#ff7a45] transition-colors">
|
||||
{t("newPost")}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="mb-6">
|
||||
<input
|
||||
type="text"
|
||||
placeholder={t("searchPlaceholder")}
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
className="w-full px-4 py-3 rounded-xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-[#ff4d4f]/20 focus:border-[#ff4d4f]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-wrap gap-2 mb-6">
|
||||
{CATEGORIES.map((cat) => (
|
||||
<button
|
||||
key={cat.key}
|
||||
onClick={() => setActiveCategory(cat.key)}
|
||||
className={`px-3 sm:px-4 py-1.5 sm:py-2 rounded-full text-xs sm:text-sm font-medium transition-colors ${
|
||||
activeCategory === cat.key
|
||||
? "bg-[#ff4d4f] text-white"
|
||||
: "bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700"
|
||||
}`}
|
||||
>
|
||||
{cat.zh}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="space-y-3 sm:space-y-4">
|
||||
{filteredTopics.map((topic) => (
|
||||
<div
|
||||
key={topic.id}
|
||||
className="bg-white dark:bg-gray-900 rounded-xl p-4 sm:p-5 shadow-sm border border-gray-100 dark:border-gray-800 hover:shadow-md transition-shadow cursor-pointer"
|
||||
>
|
||||
<div className="flex items-start gap-3 sm:gap-4">
|
||||
<img
|
||||
src={topic.avatar}
|
||||
alt={topic.author}
|
||||
className="w-10 h-10 sm:w-12 sm:h-12 rounded-full object-cover shrink-0"
|
||||
/>
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center gap-2 mb-1">
|
||||
{topic.pinned && (
|
||||
<span className="text-[#ff4d4f] text-xs font-medium">📌</span>
|
||||
)}
|
||||
<span className="text-xs text-[#ff4d4f] bg-red-50 dark:bg-red-900/20 px-2 py-0.5 rounded-full">
|
||||
{topic.category}
|
||||
</span>
|
||||
</div>
|
||||
<h3 className="font-semibold text-gray-900 dark:text-gray-100 text-sm sm:text-base mb-2 line-clamp-2">
|
||||
{topic.title}
|
||||
</h3>
|
||||
<div className="flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-gray-500 dark:text-gray-400">
|
||||
<span>{topic.author}</span>
|
||||
<span className="hidden sm:inline">·</span>
|
||||
<span>{topic.lastActive}</span>
|
||||
<span className="hidden sm:inline">·</span>
|
||||
<span>👁 {topic.views}</span>
|
||||
<span>💬 {topic.replies}</span>
|
||||
<span>❤️ {topic.likes}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{filteredTopics.length === 0 && (
|
||||
<div className="text-center py-12 sm:py-16">
|
||||
<span className="text-4xl sm:text-5xl mb-4 block">💬</span>
|
||||
<p className="text-gray-500 dark:text-gray-400 text-base sm:text-lg">
|
||||
{t("noResults")}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import Footer from "../../components/Footer";
|
||||
import Footer from "@/app/components/Footer";
|
||||
|
||||
export const metadata = {
|
||||
title: "招聘 | 游牧中国",
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useMemo } from "react";
|
||||
import { Link, useLocale } from "@/i18n/navigation";
|
||||
import { Link, useLocale, useRouter } from "@/i18n/navigation";
|
||||
import { useTranslation } from "@/i18n/navigation";
|
||||
import HeroSection from "../components/HeroSection";
|
||||
import FilterBar from "../components/FilterBar";
|
||||
import CityCard from "../components/CityCard";
|
||||
import CityModal from "../components/CityModal";
|
||||
import Footer from "../components/Footer";
|
||||
import Footer from "@/app/components/Footer";
|
||||
import { cities, type City } from "../data/cities";
|
||||
import { HOME_CONFIG } from "@/config";
|
||||
|
||||
@@ -23,6 +23,7 @@ export default function Home() {
|
||||
const [sortBy, setSortBy] = useState("score");
|
||||
const [cityModal, setCityModal] = useState<City | null>(null);
|
||||
const locale = useLocale();
|
||||
const router = useRouter();
|
||||
const { t } = useTranslation("home");
|
||||
const { t: tNav } = useTranslation("nav");
|
||||
|
||||
@@ -52,6 +53,13 @@ export default function Home() {
|
||||
return result;
|
||||
}, [activeFilter, sortBy]);
|
||||
|
||||
const cityTags = [
|
||||
{ key: "dali", emoji: "🏯", zh: "大理", en: "Dali" },
|
||||
{ key: "chengdu", emoji: "🐼", zh: "成都", en: "Chengdu" },
|
||||
{ key: "shenzhen", emoji: "🌃", zh: "深圳", en: "Shenzhen" },
|
||||
{ key: "hangzhou", emoji: "⛲", zh: "杭州", en: "Hangzhou" },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-[#fafafa] dark:bg-gray-950">
|
||||
<HeroSection />
|
||||
@@ -125,7 +133,7 @@ export default function Home() {
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
<Link href="/homeMeetups" className="right-item block">
|
||||
<Link href="/meetups" className="right-item block">
|
||||
<div className="right-item-header">{t("latestEvents")}</div>
|
||||
<div className="p-1.5 sm:p-4 flex flex-col gap-0.5 sm:gap-2.5 text-[10px] sm:text-sm text-gray-700 dark:text-gray-300 h-[calc(100%-38px)] sm:h-[calc(100%-42px)]">
|
||||
<div className="flex items-center gap-1 bg-[#f5f6f7] dark:bg-gray-800 rounded-lg px-1.5 py-1 sm:px-3 sm:py-2 font-medium text-gray-900 dark:text-gray-100">
|
||||
@@ -182,44 +190,47 @@ export default function Home() {
|
||||
</h2>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 sm:gap-5">
|
||||
{routes.map((route) => (
|
||||
<div
|
||||
key={route.title}
|
||||
className="community-card group cursor-pointer"
|
||||
<Link
|
||||
key={route.titleZh}
|
||||
href={`/dashboard?route=${encodeURIComponent(locale === "zh" ? route.titleZh : route.titleEn)}`}
|
||||
className="community-card group cursor-pointer block"
|
||||
>
|
||||
<div className={`h-2 bg-gradient-to-r ${route.gradient}`} />
|
||||
<div className="p-4 sm:p-5">
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<h3 className="font-bold text-gray-900 dark:text-gray-100 text-sm">
|
||||
{route.title}
|
||||
{locale === "zh" ? route.titleZh : route.titleEn}
|
||||
</h3>
|
||||
<span className="text-[11px] text-gray-400 dark:text-gray-500 bg-gray-50 dark:bg-gray-800 rounded-full px-2 py-0.5">
|
||||
{route.duration}
|
||||
{locale === "zh" ? route.durationZh : route.durationEn}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-1 mb-3">
|
||||
{route.cities.map((city, i) => (
|
||||
<span key={city} className="flex items-center gap-0.5 text-sm">
|
||||
<span>{route.emojis[i]}</span>
|
||||
<span className="font-medium text-gray-700 dark:text-gray-300">{city}</span>
|
||||
{i < route.cities.length - 1 && (
|
||||
{route.emojis.map((emoji, i) => (
|
||||
<span key={i} className="flex items-center gap-0.5 text-sm">
|
||||
<span>{emoji}</span>
|
||||
<span className="font-medium text-gray-700 dark:text-gray-300">
|
||||
{locale === "zh" ? route.citiesZh[i] : route.citiesEn[i]}
|
||||
</span>
|
||||
{i < route.emojis.length - 1 && (
|
||||
<span className="text-gray-300 dark:text-gray-600 mx-1">→</span>
|
||||
)}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
<p className="text-xs text-gray-500 dark:text-gray-400 mb-3 leading-relaxed">
|
||||
{route.desc}
|
||||
{locale === "zh" ? route.descZh : route.descEn}
|
||||
</p>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm font-semibold text-gray-900 dark:text-gray-100">
|
||||
{route.cost}
|
||||
{locale === "zh" ? route.costZh : route.costEn}
|
||||
</span>
|
||||
<span className="text-xs text-[#ff4d4f] font-medium group-hover:translate-x-1 transition-transform">
|
||||
查看详情 →
|
||||
{t("routeDetails")}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
@@ -231,7 +242,7 @@ export default function Home() {
|
||||
</h2>
|
||||
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 sm:gap-5">
|
||||
<div className="community-card">
|
||||
<Link href="/meetups" className="community-card block">
|
||||
<div className="p-4 sm:p-5">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<h3 className="font-bold text-gray-900 dark:text-gray-100 text-sm flex items-center gap-1.5">
|
||||
@@ -257,14 +268,11 @@ export default function Home() {
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<Link
|
||||
href="/homeMeetups"
|
||||
className="block w-full text-center text-xs font-medium text-[#ff4d4f] hover:text-[#ff7a45] mt-4 pt-3 border-t border-gray-100 dark:border-gray-700 transition-colors"
|
||||
>
|
||||
<div className="block w-full text-center text-xs font-medium text-[#ff4d4f] hover:text-[#ff7a45] mt-4 pt-3 border-t border-gray-100 dark:border-gray-700 transition-colors">
|
||||
{t("viewMore")}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
<div className="community-card">
|
||||
<div className="p-4 sm:p-5">
|
||||
@@ -290,35 +298,35 @@ export default function Home() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="community-card">
|
||||
<Link href="/discuss" className="community-card block">
|
||||
<div className="p-4 sm:p-5">
|
||||
<h3 className="font-bold text-gray-900 dark:text-gray-100 text-sm flex items-center gap-1.5 mb-4">
|
||||
🔥 {t("hotDiscussions")}
|
||||
</h3>
|
||||
<div className="space-y-3">
|
||||
{hotTopics.map((t_item, i) => (
|
||||
<a key={t_item.title} href="#" className="flex items-start gap-2.5 group">
|
||||
<div key={t_item.titleZh} className="flex items-start gap-2.5 group">
|
||||
<span className={`text-xs font-bold mt-0.5 w-4 shrink-0 ${i < 3 ? "text-[#ff4d4f]" : "text-gray-300 dark:text-gray-600"}`}>
|
||||
{i + 1}
|
||||
</span>
|
||||
<div className="flex-1">
|
||||
<p min-w-0 className="text-sm text-gray-700 dark:text-gray-300 group-hover:text-gray-900 dark:group-hover:text-gray-100 transition-colors line-clamp-1 leading-snug">
|
||||
{t_item.title}
|
||||
<p className="min-w-0 text-sm text-gray-700 dark:text-gray-300 group-hover:text-gray-900 dark:group-hover:text-gray-100 transition-colors line-clamp-1 leading-snug">
|
||||
{locale === "zh" ? t_item.titleZh : t_item.titleEn}
|
||||
</p>
|
||||
<p className="text-[11px] text-gray-400 dark:text-gray-500 mt-0.5">
|
||||
{t_item.views.toLocaleString()} {t("views")}
|
||||
</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<button className="w-full text-center text-xs font-medium text-[#ff4d4f] hover:text-[#ff7a45] mt-4 pt-3 border-t border-gray-100 dark:border-gray-700 transition-colors">
|
||||
{t("viewMore")}
|
||||
</button>
|
||||
<div className="block w-full text-center text-xs font-medium text-[#ff4d4f] hover:text-[#ff7a45] mt-4 pt-3 border-t border-gray-100 dark:border-gray-700 transition-colors">
|
||||
{t("viewAllTopics")}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
<div className="community-card bg-gradient-to-br from-emerald-50 to-teal-50 dark:from-emerald-950/30 dark:to-teal-950/30">
|
||||
<Link href="/services" className="community-card bg-gradient-to-br from-emerald-50 to-teal-50 dark:from-emerald-950/30 dark:to-teal-950/30 block">
|
||||
<div className="p-4 sm:p-5">
|
||||
<div className="flex items-start gap-3 mb-3">
|
||||
<span className="text-2xl">🛡️</span>
|
||||
@@ -330,13 +338,13 @@ export default function Home() {
|
||||
<p className="text-xs text-emerald-700 dark:text-emerald-400 bg-emerald-100/50 dark:bg-emerald-900/30 rounded-lg px-3 py-2 mb-3">
|
||||
{t("insuranceCoverage")}
|
||||
</p>
|
||||
<button className="w-full text-center text-sm font-semibold text-emerald-700 dark:text-emerald-400 hover:text-emerald-800 dark:hover:text-emerald-300 bg-white/80 dark:bg-gray-800/80 hover:bg-white dark:hover:bg-gray-800 border border-emerald-200 dark:border-emerald-800 rounded-full py-2 transition-colors">
|
||||
<div className="w-full text-center text-sm font-semibold text-emerald-700 dark:text-emerald-400 hover:text-emerald-800 dark:hover:text-emerald-300 bg-white/80 dark:bg-gray-800/80 hover:bg-white dark:hover:bg-gray-800 border border-emerald-200 dark:border-emerald-800 rounded-full py-2 transition-colors">
|
||||
{t("learnMore")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
<div className="community-card bg-gradient-to-br from-violet-50 to-purple-50 dark:from-violet-950/30 dark:to-purple-950/30">
|
||||
<Link href="/join" className="community-card bg-gradient-to-br from-violet-50 to-purple-50 dark:from-violet-950/30 dark:to-purple-950/30 block">
|
||||
<div className="p-4 sm:p-5">
|
||||
<div className="flex items-start gap-3 mb-3">
|
||||
<span className="text-2xl">💬</span>
|
||||
@@ -358,13 +366,13 @@ export default function Home() {
|
||||
</div>
|
||||
<span className="text-xs text-gray-400 dark:text-gray-500">{t("onlineNow")}</span>
|
||||
</div>
|
||||
<button className="w-full text-center text-sm font-semibold text-violet-700 dark:text-violet-400 hover:text-violet-800 dark:hover:text-violet-300 bg-white/80 dark:bg-gray-800/80 hover:bg-white dark:hover:bg-gray-800 border border-violet-200 dark:border-violet-800 rounded-full py-2 transition-colors">
|
||||
<div className="w-full text-center text-sm font-semibold text-violet-700 dark:text-violet-400 hover:text-violet-800 dark:hover:text-violet-300 bg-white/80 dark:bg-gray-800/80 hover:bg-white dark:hover:bg-gray-800 border border-violet-200 dark:border-violet-800 rounded-full py-2 transition-colors">
|
||||
{t("joinChat")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
<div className="community-card bg-gradient-to-br from-amber-50 to-orange-50 dark:from-amber-950/30 dark:to-orange-950/30">
|
||||
<Link href="/tools" className="community-card bg-gradient-to-br from-amber-50 to-orange-50 dark:from-amber-950/30 dark:to-orange-950/30 block">
|
||||
<div className="p-4 sm:p-5">
|
||||
<div className="flex items-start gap-3 mb-3">
|
||||
<span className="text-2xl">🏛️</span>
|
||||
@@ -376,20 +384,21 @@ export default function Home() {
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-1.5 mb-3">
|
||||
{["🏯 大理", "🐼 成都", "🌃 深圳", "⛲ 杭州"].map((tag) => (
|
||||
<span
|
||||
key={tag}
|
||||
className="text-[11px] bg-amber-100/60 dark:bg-amber-900/30 text-amber-700 dark:text-amber-400 rounded-full px-2 py-0.5"
|
||||
{cityTags.map((tag) => (
|
||||
<button
|
||||
key={tag.key}
|
||||
onClick={() => router.push(`/city/${tag.key}`)}
|
||||
className="text-[11px] bg-amber-100/60 dark:bg-amber-900/30 text-amber-700 dark:text-amber-400 rounded-full px-2 py-0.5 cursor-pointer hover:bg-amber-200 dark:hover:bg-amber-800 transition-colors"
|
||||
>
|
||||
{tag}
|
||||
</span>
|
||||
{tag.emoji} {locale === "zh" ? tag.zh : tag.en}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<button className="w-full text-center text-sm font-semibold text-amber-700 dark:text-amber-400 hover:text-amber-800 dark:hover:text-amber-300 bg-white/80 dark:bg-gray-800/80 hover:bg-white dark:hover:bg-gray-800 border border-amber-200 dark:border-amber-800 rounded-full py-2 transition-colors">
|
||||
<div className="w-full text-center text-sm font-semibold text-amber-700 dark:text-amber-400 hover:text-amber-800 dark:hover:text-amber-300 bg-white/80 dark:bg-gray-800/80 hover:bg-white dark:hover:bg-gray-800 border border-amber-200 dark:border-amber-800 rounded-full py-2 transition-colors">
|
||||
{t("viewGuides")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
224
app/[locale]/services/page.tsx
Normal file
224
app/[locale]/services/page.tsx
Normal file
@@ -0,0 +1,224 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useTranslation, Link } from "@/i18n/navigation";
|
||||
import Footer from "@/app/components/Footer";
|
||||
|
||||
interface Service {
|
||||
id: string;
|
||||
icon: string;
|
||||
titleZh: string;
|
||||
titleEn: string;
|
||||
descZh: string;
|
||||
descEn: string;
|
||||
features: { zh: string; en: string }[];
|
||||
priceZh: string;
|
||||
priceEn: string;
|
||||
color: string;
|
||||
gradientFrom: string;
|
||||
gradientTo: string;
|
||||
}
|
||||
|
||||
const SERVICES: Service[] = [
|
||||
{
|
||||
id: "insurance",
|
||||
icon: "🛡️",
|
||||
titleZh: "旅行保险",
|
||||
titleEn: "Travel Insurance",
|
||||
descZh: "数字游民定制方案,覆盖全球",
|
||||
descEn: "Global coverage for digital nomads",
|
||||
features: [
|
||||
{ zh: "覆盖中国 + 境外", en: "Coverage in China + overseas" },
|
||||
{ zh: "远程工作专属条款", en: "Remote work specific terms" },
|
||||
{ zh: "医疗直付服务", en: "Direct medical payment" },
|
||||
{ zh: "24/7 中文客服", en: "24/7 Chinese support" },
|
||||
],
|
||||
priceZh: "¥15/天起",
|
||||
priceEn: "From ¥15/day",
|
||||
color: "emerald",
|
||||
gradientFrom: "from-emerald-500",
|
||||
gradientTo: "to-teal-500",
|
||||
},
|
||||
{
|
||||
id: "chat",
|
||||
icon: "💬",
|
||||
titleZh: "社区聊天",
|
||||
titleEn: "Community Chat",
|
||||
descZh: "与全球数字游民实时交流",
|
||||
descEn: "Connect with nomads worldwide in real-time",
|
||||
features: [
|
||||
{ zh: "3,200+ 在线成员", en: "3,200+ members online" },
|
||||
{ zh: "城市群/兴趣群", en: "City & interest groups" },
|
||||
{ zh: "即时信息对接", en: "Instant networking" },
|
||||
{ zh: "经验分享互助", en: "Experience sharing" },
|
||||
],
|
||||
priceZh: "免费",
|
||||
priceEn: "Free",
|
||||
color: "violet",
|
||||
gradientFrom: "from-violet-500",
|
||||
gradientTo: "to-purple-500",
|
||||
},
|
||||
{
|
||||
id: "tools",
|
||||
icon: "🧰",
|
||||
titleZh: "工具箱",
|
||||
titleEn: "Tools",
|
||||
descZh: "汇率、税务、签证一站式",
|
||||
descEn: "Exchange, tax & visa in one place",
|
||||
features: [
|
||||
{ zh: "实时汇率计算", en: "Real-time exchange rates" },
|
||||
{ zh: "税务估算器", en: "Tax calculator" },
|
||||
{ zh: "签证倒计时", en: "Visa countdown" },
|
||||
{ zh: "FIRE 计算器", en: "FIRE calculator" },
|
||||
],
|
||||
priceZh: "免费",
|
||||
priceEn: "Free",
|
||||
color: "blue",
|
||||
gradientFrom: "from-blue-500",
|
||||
gradientTo: "to-cyan-500",
|
||||
},
|
||||
{
|
||||
id: "coworking",
|
||||
icon: "🏢",
|
||||
titleZh: "共享办公",
|
||||
titleEn: "Coworking",
|
||||
descZh: "全球优质办公空间推荐",
|
||||
descEn: "Premium workspace recommendations",
|
||||
features: [
|
||||
{ zh: "全球 10,000+ 空间", en: "10,000+ spaces worldwide" },
|
||||
{ zh: "会员专属折扣", en: "Member discounts" },
|
||||
{ zh: "实地考察报告", en: "On-site reviews" },
|
||||
{ zh: "预订直通车", en: "Direct booking" },
|
||||
],
|
||||
priceZh: "¥99/月起",
|
||||
priceEn: "From ¥99/month",
|
||||
color: "orange",
|
||||
gradientFrom: "from-orange-500",
|
||||
gradientTo: "to-amber-500",
|
||||
},
|
||||
{
|
||||
id: "visa",
|
||||
icon: "📋",
|
||||
titleZh: "签证服务",
|
||||
titleEn: "Visa Services",
|
||||
descZh: "专业签证顾问全程护航",
|
||||
descEn: "Professional visa consultants",
|
||||
features: [
|
||||
{ zh: "全球签证办理", en: "Global visa processing" },
|
||||
{ zh: "材料翻译公证", en: "Translation & notarization" },
|
||||
{ zh: "加急服务", en: "Expedited service" },
|
||||
{ zh: "拒签退款保障", en: "Refund guarantee" },
|
||||
],
|
||||
priceZh: "咨询报价",
|
||||
priceEn: "Contact for quote",
|
||||
color: "rose",
|
||||
gradientFrom: "from-rose-500",
|
||||
gradientTo: "to-pink-500",
|
||||
},
|
||||
{
|
||||
id: "mentor",
|
||||
icon: "🎓",
|
||||
titleZh: "导师计划",
|
||||
titleEn: "Mentor Program",
|
||||
descZh: "资深游民一对一指导",
|
||||
descEn: "1-on-1 guidance from experienced nomads",
|
||||
features: [
|
||||
{ zh: "职业规划建议", en: "Career planning" },
|
||||
{ zh: "创业经验分享", en: "Startup experience" },
|
||||
{ zh: "远程工作技巧", en: "Remote work tips" },
|
||||
{ zh: "人脉资源对接", en: "Network access" },
|
||||
],
|
||||
priceZh: "¥299/次",
|
||||
priceEn: "¥299/session",
|
||||
color: "indigo",
|
||||
gradientFrom: "from-indigo-500",
|
||||
gradientTo: "to-violet-500",
|
||||
},
|
||||
];
|
||||
|
||||
export default function ServicesPage() {
|
||||
const { t } = useTranslation("services");
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-[#fafafa] dark:bg-gray-950">
|
||||
<main className="max-w-[1200px] mx-auto px-4 sm:px-6 py-6 sm:py-8">
|
||||
<div className="text-center mb-10 sm:mb-12">
|
||||
<h1 className="text-2xl sm:text-3xl md:text-4xl font-bold text-gray-900 dark:text-gray-100 mb-3">
|
||||
{t("title")}
|
||||
</h1>
|
||||
<p className="text-gray-500 dark:text-gray-400 text-sm sm:text-base">
|
||||
{t("subtitle")}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5 sm:gap-6">
|
||||
{SERVICES.map((service) => (
|
||||
<div
|
||||
key={service.id}
|
||||
className="bg-white dark:bg-gray-900 rounded-2xl overflow-hidden shadow-sm border border-gray-100 dark:border-gray-800 hover:shadow-lg transition-shadow"
|
||||
>
|
||||
<div className={`h-2 bg-gradient-to-r ${service.gradientFrom} ${service.gradientTo}`} />
|
||||
<div className="p-5 sm:p-6">
|
||||
<div className="flex items-start justify-between mb-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="text-3xl">{service.icon}</span>
|
||||
<div>
|
||||
<h3 className="font-bold text-gray-900 dark:text-gray-100 text-lg">
|
||||
{service.titleZh}
|
||||
</h3>
|
||||
<p className="text-xs text-gray-500 dark:text-gray-400">
|
||||
{service.titleEn}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p className="text-sm text-gray-600 dark:text-gray-400 mb-4">
|
||||
{service.descZh}
|
||||
</p>
|
||||
|
||||
<ul className="space-y-2 mb-5">
|
||||
{service.features.map((feature, i) => (
|
||||
<li key={i} className="flex items-center gap-2 text-xs sm:text-sm text-gray-500 dark:text-gray-400">
|
||||
<span className="text-[#ff4d4f]">✓</span>
|
||||
{feature.zh}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<div className="flex items-center justify-between pt-4 border-t border-gray-100 dark:border-gray-800">
|
||||
<span className="font-bold text-gray-900 dark:text-gray-100">
|
||||
{service.priceZh}
|
||||
</span>
|
||||
<Link
|
||||
href="/join"
|
||||
className="text-sm font-medium text-[#ff4d4f] hover:text-[#ff7a45] transition-colors"
|
||||
>
|
||||
{t("learnMore")} →
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="mt-12 sm:mt-16 bg-gradient-to-r from-[#ff4d4f] to-[#ff7a45] rounded-2xl p-6 sm:p-10 text-center">
|
||||
<h2 className="text-xl sm:text-2xl font-bold text-white mb-3">
|
||||
还没有找到需要的服务?
|
||||
</h2>
|
||||
<p className="text-white/80 mb-5 text-sm sm:text-base">
|
||||
联系我们的客服,获取定制化解决方案
|
||||
</p>
|
||||
<Link
|
||||
href="/contact"
|
||||
className="inline-block bg-white text-[#ff4d4f] px-6 py-2.5 rounded-full font-medium hover:bg-gray-100 transition-colors"
|
||||
>
|
||||
联系客服
|
||||
</Link>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -21,17 +21,23 @@ export interface Meetup {
|
||||
}
|
||||
|
||||
export interface HotTopic {
|
||||
title: string;
|
||||
titleZh: string;
|
||||
titleEn: string;
|
||||
views: number;
|
||||
}
|
||||
|
||||
export interface Route {
|
||||
title: string;
|
||||
cities: string[];
|
||||
titleZh: string;
|
||||
titleEn: string;
|
||||
citiesZh: string[];
|
||||
citiesEn: string[];
|
||||
emojis: string[];
|
||||
duration: string;
|
||||
cost: string;
|
||||
desc: string;
|
||||
durationZh: string;
|
||||
durationEn: string;
|
||||
costZh: string;
|
||||
costEn: string;
|
||||
descZh: string;
|
||||
descEn: string;
|
||||
gradient: string;
|
||||
}
|
||||
|
||||
@@ -83,39 +89,54 @@ export const MEETUPS: Meetup[] = [
|
||||
];
|
||||
|
||||
export const HOT_TOPICS: HotTopic[] = [
|
||||
{ title: "大理最佳共享办公空间推荐 Top 10", views: 2340 },
|
||||
{ title: "2026年数字游民友好城市排名", views: 1890 },
|
||||
{ title: "远程工作者的税务规划指南", views: 1560 },
|
||||
{ title: "成都 vs 大理:哪个更适合游民?", views: 1230 },
|
||||
{ title: "新手游民必备工具与装备清单", views: 980 },
|
||||
{ titleZh: "大理最佳共享办公空间推荐 Top 10", titleEn: "Top 10 Coworking Spaces in Dali", views: 2340 },
|
||||
{ titleZh: "2026年数字游民友好城市排名", titleEn: "2026 Digital Nomad Friendly Cities Ranking", views: 1890 },
|
||||
{ titleZh: "远程工作者的税务规划指南", titleEn: "Tax Planning Guide for Remote Workers", views: 1560 },
|
||||
{ titleZh: "成都 vs 大理:哪个更适合游民?", titleEn: "Chengdu vs Dali: Which is Better for Nomads?", views: 1230 },
|
||||
{ titleZh: "新手游民必备工具与装备清单", titleEn: "Essential Tools & Equipment for New Nomads", views: 980 },
|
||||
];
|
||||
|
||||
export const ROUTES: Route[] = [
|
||||
{
|
||||
title: "云南慢生活线",
|
||||
cities: ["昆明", "大理", "丽江"],
|
||||
titleZh: "云南慢生活线",
|
||||
titleEn: "Yunnan Slow Life Route",
|
||||
citiesZh: ["昆明", "大理", "丽江"],
|
||||
citiesEn: ["Kunming", "Dali", "Lijiang"],
|
||||
emojis: ["🌸", "🏯", "🏔️"],
|
||||
duration: "3-6个月",
|
||||
cost: "¥3,200/月起",
|
||||
desc: "从春城昆明出发,沿着滇西北一路感受最纯粹的慢生活",
|
||||
durationZh: "3-6个月",
|
||||
durationEn: "3-6 months",
|
||||
costZh: "¥3,200/月起",
|
||||
costEn: "From ¥3,200/month",
|
||||
descZh: "从春城昆明出发,沿着滇西北一路感受最纯粹的慢生活",
|
||||
descEn: "From spring city Kunming, experience the purest slow life along northwest Yunnan",
|
||||
gradient: "from-purple-500 to-pink-500",
|
||||
},
|
||||
{
|
||||
title: "科技创业线",
|
||||
cities: ["深圳", "杭州", "上海"],
|
||||
titleZh: "科技创业线",
|
||||
titleEn: "Tech Startup Route",
|
||||
citiesZh: ["深圳", "杭州", "上海"],
|
||||
citiesEn: ["Shenzhen", "Hangzhou", "Shanghai"],
|
||||
emojis: ["🌃", "⛲", "🏙️"],
|
||||
duration: "2-4个月",
|
||||
cost: "¥7,000/月起",
|
||||
desc: "穿越中国三大科技中心,连接最前沿的创业生态",
|
||||
durationZh: "2-4个月",
|
||||
durationEn: "2-4 months",
|
||||
costZh: "¥7,000/月起",
|
||||
costEn: "From ¥7,000/month",
|
||||
descZh: "穿越中国三大科技中心,连接最前沿的创业生态",
|
||||
descEn: "Cross China's three tech hubs, connect with cutting-edge startup ecosystem",
|
||||
gradient: "from-blue-500 to-cyan-500",
|
||||
},
|
||||
{
|
||||
title: "美食文化线",
|
||||
cities: ["成都", "重庆", "长沙"],
|
||||
titleZh: "美食文化线",
|
||||
titleEn: "Food Culture Route",
|
||||
citiesZh: ["成都", "重庆", "长沙"],
|
||||
citiesEn: ["Chengdu", "Changsha", "Chongqing"],
|
||||
emojis: ["🐼", "🌶️", "🎪"],
|
||||
duration: "2-3个月",
|
||||
cost: "¥4,000/月起",
|
||||
desc: "巴蜀到湘楚,用味蕾丈量中国最火辣的城市",
|
||||
durationZh: "2-3个月",
|
||||
durationEn: "2-3 months",
|
||||
costZh: "¥4,000/月起",
|
||||
costEn: "From ¥4,000/month",
|
||||
descZh: "巴蜀到湘楚,用味蕾丈量中国最火辣的城市",
|
||||
descEn: "From Sichuan to Hunan, explore China's spiciest cities with your taste buds",
|
||||
gradient: "from-orange-500 to-red-500",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -97,7 +97,9 @@
|
||||
"perMonth": "/month",
|
||||
"travelingNow": "Traveling Now",
|
||||
"hotDiscussions": "Hot Discussions",
|
||||
"viewAllTopics": "View all topics →",
|
||||
"views": "views",
|
||||
"routeDetails": "View route details →",
|
||||
"viewMore": "View more →",
|
||||
"travelInsurance": "Travel Insurance",
|
||||
"travelInsuranceDesc": "Nomad-customized plans",
|
||||
@@ -356,5 +358,30 @@
|
||||
"regenerate": "Regenerate",
|
||||
"subtitle": "Countries visited? Avg monthly cost?",
|
||||
"generate": "Generate report"
|
||||
},
|
||||
"discuss": {
|
||||
"title": "Discussions",
|
||||
"subtitle": "Share experiences and connect",
|
||||
"newPost": "New Post",
|
||||
"searchPlaceholder": "Search discussions...",
|
||||
"noResults": "No discussions yet, start the first one!",
|
||||
"replies": "replies",
|
||||
"views": "views"
|
||||
},
|
||||
"cityGuide": {
|
||||
"costOfLiving": "Cost of Living",
|
||||
"coworking": "Coworking",
|
||||
"neighborhoods": "Neighborhoods",
|
||||
"tips": "Tips",
|
||||
"joinCommunity": "Join Local Community",
|
||||
"viewEvents": "View Events",
|
||||
"notFound": "City guide not found",
|
||||
"backToHome": "Back to Home"
|
||||
},
|
||||
"services": {
|
||||
"title": "Services",
|
||||
"subtitle": "Premium services for digital nomads",
|
||||
"learnMore": "Learn More",
|
||||
"comingSoon": "Coming Soon"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +97,9 @@
|
||||
"perMonth": "场/月",
|
||||
"travelingNow": "正在旅行",
|
||||
"hotDiscussions": "热门讨论",
|
||||
"viewAllTopics": "查看全部话题 →",
|
||||
"views": "次浏览",
|
||||
"routeDetails": "查看路线详情 →",
|
||||
"viewMore": "查看更多 →",
|
||||
"travelInsurance": "旅行保险",
|
||||
"travelInsuranceDesc": "数字游民定制方案",
|
||||
@@ -356,5 +358,31 @@
|
||||
"regenerate": "重新生成",
|
||||
"subtitle": "今年飞了多少国家?平均月生活成本?",
|
||||
"generate": "生成年报"
|
||||
},
|
||||
"discuss": {
|
||||
"title": "热门讨论",
|
||||
"subtitle": "分享经验、交流心得",
|
||||
"newPost": "发布新帖",
|
||||
"searchPlaceholder": "搜索讨论话题...",
|
||||
"noResults": "暂无讨论,来发起第一个话题吧",
|
||||
"replies": "回复",
|
||||
"views": "浏览"
|
||||
},
|
||||
"cityGuide": {
|
||||
"costOfLiving": "生活成本",
|
||||
"coworking": "共享办公",
|
||||
"neighborhoods": "社区推荐",
|
||||
"tips": "实用Tips",
|
||||
"joinCommunity": "加入当地社群",
|
||||
"viewEvents": "查看线下活动",
|
||||
"notFound": "城市指南不存在",
|
||||
"backToHome": "返回首页"
|
||||
},
|
||||
"services": {
|
||||
"title": "增值服务",
|
||||
"subtitle": "数字游民专属增值服务",
|
||||
"learnMore": "了解更多",
|
||||
"comingSoon": "即将上线",
|
||||
"contactSupport": "联系客服"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user