diff --git a/prisma/migrations/20260426093000_add_project_submissions/migration.sql b/prisma/migrations/20260426093000_add_project_submissions/migration.sql new file mode 100644 index 0000000..c24dde8 --- /dev/null +++ b/prisma/migrations/20260426093000_add_project_submissions/migration.sql @@ -0,0 +1,21 @@ +CREATE TYPE "ProjectSubmissionStatus" AS ENUM ('PENDING', 'APPROVED', 'REJECTED', 'IMPORTED'); + +CREATE TABLE "project_submissions" ( + "id" TEXT NOT NULL, + "url" TEXT NOT NULL, + "normalizedUrl" TEXT NOT NULL, + "projectName" TEXT, + "description" TEXT, + "submitterName" TEXT, + "submitterEmail" TEXT, + "locale" TEXT NOT NULL DEFAULT 'zh', + "status" "ProjectSubmissionStatus" NOT NULL DEFAULT 'PENDING', + "reviewNotes" TEXT, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + CONSTRAINT "project_submissions_pkey" PRIMARY KEY ("id") +); + +CREATE UNIQUE INDEX "project_submissions_normalizedUrl_key" ON "project_submissions"("normalizedUrl"); +CREATE INDEX "idx_project_submission_status_createdAt" ON "project_submissions"("status", "createdAt"); +CREATE INDEX "idx_project_submission_locale" ON "project_submissions"("locale"); diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 08af3df..eba2e02 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -130,6 +130,25 @@ model Signal { @@map("signals") } +model ProjectSubmission { + id String @id @default(cuid()) + url String + normalizedUrl String @unique + projectName String? + description String? + submitterName String? + submitterEmail String? + locale String @default("zh") + status ProjectSubmissionStatus @default(PENDING) + reviewNotes String? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + @@index([status, createdAt], map: "idx_project_submission_status_createdAt") + @@index([locale], map: "idx_project_submission_locale") + @@map("project_submissions") +} + enum LinkType { WEBSITE GITHUB @@ -149,6 +168,13 @@ enum TaskStatus { FAILED } +enum ProjectSubmissionStatus { + PENDING + APPROVED + REJECTED + IMPORTED +} + enum TagCategory { FIXED_PROJECT_TYPE TECH_STACK diff --git a/src/app/[locale]/about/page.tsx b/src/app/[locale]/about/page.tsx index 8365898..9ec58ff 100644 --- a/src/app/[locale]/about/page.tsx +++ b/src/app/[locale]/about/page.tsx @@ -88,7 +88,7 @@ export default async function AboutPage({ params }: AboutPageProps) {

- hub + {t('heroEyebrow')}

@@ -109,7 +109,7 @@ export default async function AboutPage({ params }: AboutPageProps) { {t('ctaProjects')} {t('ctaSubmit')} @@ -135,7 +135,7 @@ export default async function AboutPage({ params }: AboutPageProps) {
{capabilityCards.map((card) => (
- {card.icon} +

{card.title}

{card.description}

@@ -151,7 +151,7 @@ export default async function AboutPage({ params }: AboutPageProps) { {workflowSteps.map((step, index) => (
0{index + 1}
- {step.icon} +

{step.title}

{step.description}

@@ -165,7 +165,7 @@ export default async function AboutPage({ params }: AboutPageProps) {
{principles.map((principle) => (
- {principle.icon} +

{principle.title}

{principle.description}

@@ -177,7 +177,7 @@ export default async function AboutPage({ params }: AboutPageProps) {

{t('closingTitle')}

{t('closingDescription')}

- + {t('closingCta')}
diff --git a/src/app/[locale]/docs/page.tsx b/src/app/[locale]/docs/page.tsx new file mode 100644 index 0000000..8c4ecc3 --- /dev/null +++ b/src/app/[locale]/docs/page.tsx @@ -0,0 +1,28 @@ +import type { Metadata } from "next"; +import { getTranslations } from "next-intl/server"; +import { StaticInfoPage } from "@/components/static/StaticInfoPage"; + +interface PageProps { + params: Promise<{ locale: string }>; +} + +export async function generateMetadata({ params }: PageProps): Promise { + const { locale } = await params; + const t = await getTranslations({ locale, namespace: "staticPages.docs" }); + return { title: t("title"), description: t("description") }; +} + +export default async function DocsPage({ params }: PageProps) { + const { locale } = await params; + const t = await getTranslations({ locale, namespace: "staticPages.docs" }); + const sections = t.raw("sections") as Array<{ title: string; body: string }>; + + return ( + + ); +} diff --git a/src/app/[locale]/layout.tsx b/src/app/[locale]/layout.tsx index a3ed7db..2eb303c 100644 --- a/src/app/[locale]/layout.tsx +++ b/src/app/[locale]/layout.tsx @@ -2,8 +2,9 @@ import { notFound } from "next/navigation" import { NextIntlClientProvider } from 'next-intl' import { setRequestLocale, getMessages, getTranslations } from 'next-intl/server' import Link from "next/link" -import { LocaleSwitcher } from "@/components/locale/LocaleSwitcher" import { AnnouncementBar } from "@/components/layout/AnnouncementBar" +import { NewsletterSignup } from "@/components/layout/NewsletterSignup" +import { SiteHeader } from "@/components/layout/SiteHeader" import type { Metadata } from "next" const locales = ['zh', 'en'] @@ -54,69 +55,18 @@ export default async function LocaleLayout({ closeLabel={t('closeAnnouncement')} /> - {/* Navigation */} -
-
-
- {/* Logo */} -
- smart_toy - - Agent Park - -
- - {/* Desktop Nav */} - - - {/* Right side */} -
- - - {tNav('submitProject')} - -
- - {/* Mobile menu button */} -
- -
-
-
-
+
{children}
@@ -128,36 +78,21 @@ export default async function LocaleLayout({

{t('stayUpdatedDesc')}

-
- -
- - -
- -
+
- rocket_launch +
@@ -167,10 +102,10 @@ export default async function LocaleLayout({ {/* Footer */}