138 lines
5.4 KiB
TypeScript
138 lines
5.4 KiB
TypeScript
"use client";
|
|
|
|
import { Link, useTranslation } from "@/app/digital/i18n/navigation";
|
|
import type { ResourceData } from "@/app/digital/lib/theme-data";
|
|
import { useCrossSiteUrls } from "@/app/digital/lib/useCrossSiteUrls";
|
|
import DigitalThemeIcon, { type IconName } from "./DigitalThemeIcon";
|
|
import ResourceNavigation from "./ResourceNavigation";
|
|
|
|
const mainModuleKeys = ["destinations", "vipEntry", "appDownload"] as const;
|
|
const topicKeys = ["indieDev", "aiAgent", "cloudPhone", "unmannedLive"] as const;
|
|
|
|
const linkIcons: Record<string, string> = {
|
|
destinations: "🗺️",
|
|
vipEntry: "👑",
|
|
appDownload: "📱",
|
|
indieDev: "🛠️",
|
|
aiAgent: "🤖",
|
|
cloudPhone: "☁️",
|
|
unmannedLive: "📺",
|
|
};
|
|
|
|
const linkIconNames: Record<string, IconName> = {
|
|
destinations: "map",
|
|
vipEntry: "spark",
|
|
appDownload: "phone",
|
|
indieDev: "tool",
|
|
aiAgent: "spark",
|
|
cloudPhone: "cloud",
|
|
unmannedLive: "video",
|
|
};
|
|
|
|
const topicHrefs: Record<(typeof topicKeys)[number], string> = {
|
|
indieDev: "/ebook",
|
|
aiAgent: "/#tools",
|
|
cloudPhone: "/ebook",
|
|
unmannedLive: "/ebook",
|
|
};
|
|
|
|
type CommunityProps = {
|
|
resourceData?: ResourceData;
|
|
};
|
|
|
|
export default function Community({ resourceData }: CommunityProps) {
|
|
const { t } = useTranslation("community");
|
|
const { meetupUrl, vipUrl } = useCrossSiteUrls();
|
|
const linkHrefs: Record<string, { href: string; newTab?: boolean }> = {
|
|
destinations: { href: meetupUrl, newTab: true },
|
|
vipEntry: { href: vipUrl, newTab: true },
|
|
appDownload: { href: "/app" },
|
|
};
|
|
|
|
const renderCardContent = (key: string) => (
|
|
<>
|
|
<span className="dn-icon-box flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-slate-50 text-xl dark:bg-slate-800">
|
|
<DigitalThemeIcon
|
|
name={linkIconNames[key] ?? "compass"}
|
|
emoji={linkIcons[key]}
|
|
className="h-5 w-5"
|
|
/>
|
|
</span>
|
|
<div className="min-w-0 flex-1">
|
|
<h4 className="font-bold text-slate-900 dark:text-slate-100">{t(`links.${key}.title`)}</h4>
|
|
<p className="mt-1 text-sm text-slate-500 dark:text-slate-400">{t(`links.${key}.desc`)}</p>
|
|
<span className="dn-text-link mt-2 inline-block text-sm font-medium text-sky-600">{t(`links.${key}.label`)}</span>
|
|
</div>
|
|
</>
|
|
);
|
|
|
|
return (
|
|
<section id="community" className="dn-section dn-community py-20 sm:py-28 dark:bg-slate-950">
|
|
<div className="dn-container mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
|
<div id="resources" className="text-center">
|
|
<h2 className="dn-section-title text-3xl font-bold tracking-tight text-slate-900 dark:text-slate-100 sm:text-4xl">
|
|
<span className="gradient-text">{t("resourcesTitle")}</span>
|
|
</h2>
|
|
<p className="dn-section-copy mx-auto mt-4 max-w-2xl text-lg text-slate-600 dark:text-slate-400">
|
|
{t("contributeSubtitle")}
|
|
<br />
|
|
{t("contributeSubtitle2")}
|
|
</p>
|
|
</div>
|
|
|
|
{/* 图书 / 商业数码 / 网盘 */}
|
|
{resourceData && <ResourceNavigation data={resourceData} />}
|
|
|
|
{/* 目的地数据库 + 私域VIP入口 + App 下载 - 主模块 */}
|
|
<div className="mt-12 grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
|
{mainModuleKeys.map((key) => {
|
|
const { href, newTab } = linkHrefs[key];
|
|
return (
|
|
<Link
|
|
key={key}
|
|
href={href}
|
|
target={newTab ? "_blank" : undefined}
|
|
rel={newTab ? "noopener noreferrer" : undefined}
|
|
className="dn-card card-hover flex items-start gap-5 rounded-2xl border-2 border-slate-200 bg-white p-6 shadow-md transition-all hover:border-sky-300 hover:shadow-lg dark:border-slate-700 dark:bg-slate-900 dark:hover:border-sky-600"
|
|
>
|
|
{renderCardContent(key)}
|
|
</Link>
|
|
);
|
|
})}
|
|
</div>
|
|
|
|
{/* 4 个专题 */}
|
|
<div className="mt-8">
|
|
<h3 className="mb-4 text-center text-sm font-semibold uppercase tracking-wider text-slate-500 dark:text-slate-400">
|
|
{t("topicTag")}
|
|
</h3>
|
|
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
|
|
{topicKeys.map((key) => (
|
|
<Link
|
|
key={key}
|
|
href={topicHrefs[key]}
|
|
className="dn-card dn-muted-card flex items-start gap-4 rounded-xl border border-slate-200 bg-slate-50/80 p-4 opacity-90 transition-all hover:opacity-100 dark:border-slate-700 dark:bg-slate-800/60"
|
|
>
|
|
<span className="dn-icon-box flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-slate-200 text-lg dark:bg-slate-700">
|
|
<DigitalThemeIcon
|
|
name={linkIconNames[key] ?? "compass"}
|
|
emoji={linkIcons[key]}
|
|
className="h-5 w-5"
|
|
/>
|
|
</span>
|
|
<div className="min-w-0 flex-1 text-left">
|
|
<h4 className="font-bold text-slate-700 dark:text-slate-300">{t(`links.${key}.title`)}</h4>
|
|
<p className="mt-0.5 text-xs text-slate-500 dark:text-slate-400">{t(`links.${key}.desc`)}</p>
|
|
<span className="dn-text-link mt-1.5 inline-block text-xs font-medium text-sky-600">
|
|
{t(`links.${key}.label`)}
|
|
</span>
|
|
</div>
|
|
</Link>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|