This commit is contained in:
eric
2026-03-12 02:23:10 -05:00
parent f653dccd6d
commit 421f979e10
21 changed files with 709 additions and 264 deletions

View File

@@ -1,5 +1,6 @@
"use client";
import { useState } from "react";
import { Link, useTranslation } from "@/i18n/navigation";
const days = [
@@ -14,6 +15,7 @@ const days = [
export default function Roadmap() {
const { t } = useTranslation("roadmap");
const [courseToast, setCourseToast] = useState(false);
return (
<section id="roadmap" className="bg-slate-50 py-20 sm:py-28 dark:bg-slate-900">
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
@@ -26,70 +28,99 @@ export default function Roadmap() {
</p>
</div>
<div className="mt-14 grid gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
{days.map((d) => (
<Link
key={d.day}
href={`/day/${d.day}`}
className="card-hover group flex flex-col rounded-2xl border border-slate-100 bg-white p-5 shadow-sm transition-all hover:border-sky-200 hover:shadow-md dark:border-slate-800 dark:bg-slate-800 dark:hover:border-sky-700"
>
<div className="flex items-center gap-3">
<div
className={`flex h-10 w-10 shrink-0 items-center justify-center rounded-lg text-xs font-bold text-white ${d.color}`}
>
DAY {d.day}
{/* 7天入门文档 - 独立区块 */}
<div className="mt-14">
<h3 className="mb-4 text-center text-sm font-semibold uppercase tracking-wider text-slate-500 dark:text-slate-400">
{t("daysSection")}
</h3>
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
{days.map((d) => (
<Link
key={d.day}
href={`/day/${d.day}`}
className="card-hover group flex flex-col rounded-2xl border border-slate-200 bg-white p-5 shadow-sm transition-all hover:border-sky-200 hover:shadow-md dark:border-slate-700 dark:bg-slate-800 dark:hover:border-sky-600"
>
<div className="flex items-center gap-3">
<div
className={`flex h-10 w-10 shrink-0 items-center justify-center rounded-lg text-xs font-bold text-white ${d.color}`}
>
DAY {d.day}
</div>
<span className="text-xl">{d.icon}</span>
<h3 className="text-base font-bold text-slate-900 group-hover:text-sky-600 dark:text-slate-100 dark:group-hover:text-sky-400">
{t(`days.${d.day}.title`)}
</h3>
</div>
<span className="text-xl">{d.icon}</span>
<h3 className="text-base font-bold text-slate-900 group-hover:text-sky-600 dark:text-slate-100 dark:group-hover:text-sky-400">
{t(`days.${d.day}.title`)}
</h3>
</div>
<p className="mt-3 flex-1 text-sm leading-relaxed text-slate-600 dark:text-slate-400">
{t(`days.${d.day}.desc`)}
</p>
<span className="mt-3 inline-flex items-center text-sm font-medium text-sky-600 dark:text-sky-400">
{t("viewDetails")}
</span>
</Link>
))}
<Link
href="/ebook"
className="card-hover group flex flex-col rounded-2xl border border-slate-100 bg-white p-5 shadow-sm transition-all hover:border-sky-200 hover:shadow-md dark:border-slate-800 dark:bg-slate-800 dark:hover:border-sky-700"
>
<div className="flex items-center gap-3">
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-gradient-to-r from-sky-500 to-cyan-500 text-xs font-bold text-white">
📖
</div>
<h3 className="text-base font-bold text-slate-900 group-hover:text-sky-600">
{t("ebook.title")}
</h3>
</div>
<p className="mt-3 flex-1 text-sm leading-relaxed text-slate-600">
{t("ebook.desc")}
</p>
<span className="mt-3 inline-flex items-center text-sm font-medium text-sky-600">
{t("ebook.cta")}
</span>
</Link>
<p className="mt-3 flex-1 text-sm leading-relaxed text-slate-600 dark:text-slate-400">
{t(`days.${d.day}.desc`)}
</p>
<span className="mt-3 inline-flex items-center text-sm font-medium text-sky-600 dark:text-sky-400">
{t("viewDetails")}
</span>
</Link>
))}
</div>
</div>
<div className="mt-16 overflow-hidden rounded-2xl border border-amber-200 bg-gradient-to-r from-amber-50 to-orange-50 p-8 text-center dark:border-amber-800 dark:from-amber-900/30 dark:to-orange-900/30 sm:p-10">
<div className="mb-2 text-sm font-semibold text-amber-600 dark:text-amber-400">
{t("course.tag")}
</div>
<h3 className="text-2xl font-bold text-slate-900">
{t("course.title")}
{/* 电子书 + 实战课 - 平级展示 */}
<div className="mt-16">
<h3 className="mb-6 text-center text-sm font-semibold uppercase tracking-wider text-slate-500 dark:text-slate-400">
{t("productsSection")}
</h3>
<p className="mx-auto mt-3 max-w-xl text-slate-600 dark:text-slate-400">
{t("course.desc")}
</p>
<Link
href="/course"
className="mt-6 inline-flex items-center gap-2 rounded-full bg-amber-500 px-8 py-3 font-semibold text-white transition-colors hover:bg-amber-600 dark:bg-amber-600 dark:hover:bg-amber-500"
>
{t("course.cta")}
</Link>
<div className="grid gap-6 sm:grid-cols-2">
<Link
href="/ebook"
className="group flex flex-col overflow-hidden rounded-2xl border-2 border-slate-200 bg-gradient-to-br from-sky-50 to-cyan-50/50 p-8 shadow-md transition-all hover:border-sky-300 hover:shadow-lg dark:border-slate-700 dark:from-sky-900/20 dark:to-cyan-900/10 dark:hover:border-sky-600"
>
<div className="mb-4 flex h-14 w-14 items-center justify-center rounded-2xl bg-gradient-to-r from-sky-500 to-cyan-500 text-3xl shadow-lg shadow-sky-200/50 dark:shadow-sky-900/30">
📖
</div>
<h3 className="text-xl font-bold text-slate-900 dark:text-slate-100">
{t("ebook.title")}
</h3>
<p className="mt-2 flex-1 text-slate-600 dark:text-slate-400">
{t("ebook.desc")}
</p>
<span className="mt-6 inline-flex items-center gap-2 text-sm font-semibold text-sky-600 dark:text-sky-400">
{t("ebook.cta")}
</span>
</Link>
<div className="flex flex-col overflow-hidden rounded-2xl border-2 border-amber-200 bg-gradient-to-br from-amber-50 to-orange-50/50 p-8 shadow-md transition-all dark:border-amber-800 dark:from-amber-900/20 dark:to-orange-900/10">
<div className="mb-4 flex h-14 w-14 items-center justify-center rounded-2xl bg-gradient-to-r from-amber-500 to-orange-500 text-3xl shadow-lg shadow-amber-200/50 dark:shadow-amber-900/30">
🎓
</div>
<span className="mb-2 inline-block text-xs font-semibold uppercase tracking-wider text-amber-600 dark:text-amber-400">
{t("course.tag")}
</span>
<h3 className="text-xl font-bold text-slate-900 dark:text-slate-100">
{t("course.title")}
</h3>
<p className="mt-2 flex-1 text-slate-600 dark:text-slate-400">
{t("course.desc")}
</p>
<button
type="button"
onClick={() => {
setCourseToast(true);
setTimeout(() => setCourseToast(false), 2000);
}}
className="mt-6 inline-flex cursor-not-allowed items-center gap-2 self-start rounded-full bg-amber-500 px-6 py-3 font-semibold text-white opacity-90 transition hover:opacity-100 dark:bg-amber-600"
>
{t("course.cta")}
</button>
</div>
</div>
</div>
{courseToast && (
<div
className="fixed bottom-8 left-1/2 z-50 -translate-x-1/2 rounded-lg bg-slate-800 px-6 py-3 text-sm font-medium text-white shadow-lg dark:bg-slate-700"
role="alert"
>
{t("course.updating")}
</div>
)}
</div>
</section>
);