Files
2026-03-09 03:45:10 -05:00

237 lines
7.6 KiB
TypeScript
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"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>
);
}