Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
a62c80b
feat: figam-mcp를 통해 홈페이지 퍼블리싱 및 환경 세팅
Wonchang0314 Apr 8, 2026
156247f
feat: add blog, project, and recruit pages with navigation and footer…
ravex-museong Apr 13, 2026
643bb3f
refactor: standardize string quotes and improve layout styles across …
ravex-museong Apr 13, 2026
10bcf81
refactor: encapsulate section content in Inner components for improve…
ravex-museong Apr 13, 2026
6a1bd72
feat: enhance recruitment sections with dynamic button labels and imp…
ravex-museong Apr 20, 2026
52e3496
feat: replace image assets with SVGs for buttons across multiple sect…
ravex-museong Apr 20, 2026
63ee51f
feat: implement PreAlertModal for recruitment sections; update button…
ravex-museong Apr 26, 2026
f26b929
feat: add recruitment application page and section component; impleme…
ravex-museong Apr 26, 2026
67b66ec
feat: integrate recruitment status context and enhance data fetching;…
ravex-museong Apr 27, 2026
e9e2f86
feat: update styled components across various sections for responsive…
ravex-museong Apr 30, 2026
3d9fb08
feat: enhance responsive typography across navigation and section com…
ravex-museong May 1, 2026
ab65c9e
feat: refine layout and typography in ArticleListPageSection, Project…
ravex-museong May 1, 2026
16a9479
refactor: remove unused articleBanner constant and update background …
ravex-museong May 1, 2026
69dfebb
feat: add success icon and enhance layout in RecruitApplySection; upd…
ravex-museong May 4, 2026
1a6d772
feat: add Instagram icon to footer and enhance responsive typography …
ravex-museong May 4, 2026
3b2e497
feat: implement dynamic metadata generation and enhance recruitment s…
ravex-museong May 4, 2026
d7b68a7
feat: enhance responsive typography and layout in recruitment section…
ravex-museong May 4, 2026
bff1b26
feat: enhance recruitment navigation and sections with dynamic links;…
ravex-museong May 8, 2026
dd6ae1d
feat: enhance responsive typography and layout across multiple sectio…
ravex-museong May 8, 2026
fca89b1
feat: improve responsive typography in HeroSection; update font sizes…
ravex-museong May 8, 2026
8329112
feat: update .gitignore and enhance project and article sections; rem…
ravex-museong May 13, 2026
d3a1d7e
feat: enhance ProjectDetailSection with conditional PDF rendering; ad…
ravex-museong May 13, 2026
e88d436
Merge remote-tracking branch 'origin/main' into dev/web-figma
Wonchang0314 May 15, 2026
f6765cf
refactor(api,web): legacy webApi 폐기 + apps/web 도메인별 API 레이어 재배치
Wonchang0314 May 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions apps/web/app/blog/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
import type { Metadata } from "next";
import { Navigation } from "@/components/layout/Navigation";
import { Footer } from "@/components/layout/Footer";
import { ArticleListPageSection } from "@/components/sections/ArticleListPageSection";
import { fetchPublicArticlesPage } from "@/lib/api/blog";

export const metadata: Metadata = {
title: "DDD 블로그 - 사이드 프로젝트 인사이트",
description: "DDD 멤버들의 사이드 프로젝트 경험과 개발, 협업 인사이트를 공유합니다.",
};

export default function BlogPage() {
return <></>;
export default async function BlogPage() {
const { items, nextCursor } = await fetchPublicArticlesPage({ limit: 4 });

return (
<>
<Navigation />
<main>
<ArticleListPageSection initialItems={items} initialNextCursor={nextCursor} />
</main>
<Footer />
</>
);
}
7 changes: 7 additions & 0 deletions apps/web/app/globals.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
@import url('https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.css');

* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
background-color: #0c0e0f;
font-family: 'Pretendard', sans-serif;
}
38 changes: 16 additions & 22 deletions apps/web/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,27 @@
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";

const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});

const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});
import type { Metadata } from 'next';
import { PreAlertModal } from '@/components/modals/PreAlertModal';
import { RecruitStatusProvider } from "@/components/providers/RecruitStatusProvider";
import { fetchRecruitStatus } from "@/lib/api/cohort";
import './globals.css';

export const metadata: Metadata = {
title: {
default: "DDD - 사이드 프로젝트로 성장하는 개발자 커뮤니티",
template: "%s | DDD",
default: 'DDD - 사이드 프로젝트로 성장하는 개발자 커뮤니티',
template: '%s | DDD',
},
description: "개발자, 디자이너, 기획자가 함께 사이드 프로젝트를 만들고 성장하는 커뮤니티 DDD. 실전 협업 경험을 쌓아보세요.",
description:
'개발자, 디자이너, 기획자가 함께 사이드 프로젝트를 만들고 성장하는 커뮤니티 DDD. 실전 협업 경험을 쌓아보세요.',
};

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
export default async function RootLayout({ children }: { children: React.ReactNode }) {
const recruitStatus = await fetchRecruitStatus();

return (
<html lang="ko">
<body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>{children}</body>
<body>
<RecruitStatusProvider recruitStatus={recruitStatus}>{children}</RecruitStatusProvider>
<PreAlertModal />
</body>
</html>
);
}
32 changes: 30 additions & 2 deletions apps/web/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,31 @@
export default function Home() {
return <></>;
import { Navigation } from '@/components/layout/Navigation';
import { Footer } from '@/components/layout/Footer';
import { HeroSection } from '@/components/sections/HeroSection';
import { AboutSection } from '@/components/sections/AboutSection';
import { ProjectsSection } from '@/components/sections/ProjectsSection';
import { BlogSection } from '@/components/sections/BlogSection';
import { FaqSection } from '@/components/sections/FaqSection';
import { SponsorSection } from '@/components/sections/SponsorSection';
import { CtaSection } from '@/components/sections/CtaSection';
import { fetchPublicArticles } from '@/lib/api/blog';
import { fetchPublicProjects } from '@/lib/api/project';

export default async function HomePage() {
const [projects, articles] = await Promise.all([fetchPublicProjects(), fetchPublicArticles()]);

return (
<>
<Navigation />
<main>
<HeroSection />
<AboutSection />
<ProjectsSection items={projects.slice(0, 6)} />
<BlogSection items={articles.slice(0, 5)} />
<FaqSection />
<SponsorSection />
<CtaSection />
</main>
<Footer />
</>
);
}
29 changes: 24 additions & 5 deletions apps/web/app/project/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,40 @@
import type { Metadata } from "next";
import { notFound } from "next/navigation";
import { Navigation } from "@/components/layout/Navigation";
import { Footer } from "@/components/layout/Footer";
import { ProjectDetailSection } from "@/components/sections/ProjectDetailSection";
import { fetchPublicProjectById } from "@/lib/api/project";

type Props = {
params: Promise<{ id: string }>;
};

export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { id } = await params;

// TODO: fetch project name by id
const projectName = id;
const project = await fetchPublicProjectById(id);
const projectName = project?.title ?? id;

return {
title: projectName,
description: `DDD에서 진행된 사이드 프로젝트 ${projectName} 직접 확인해보세요.`,
};
}

export default function ProjectDetailPage() {
return <></>;
export default async function ProjectDetailPage({ params }: Props) {
const { id } = await params;
const project = await fetchPublicProjectById(id);

if (!project) {
notFound();
}

return (
<>
<Navigation />
<main>
<ProjectDetailSection project={project} />
</main>
<Footer />
</>
);
}
18 changes: 16 additions & 2 deletions apps/web/app/project/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
import type { Metadata } from "next";
import { Navigation } from "@/components/layout/Navigation";
import { Footer } from "@/components/layout/Footer";
import { ProjectListPageSection } from "@/components/sections/ProjectListPageSection";
import { fetchPublicProjectsPage } from "@/lib/api/project";

export const metadata: Metadata = {
title: "DDD 프로젝트 - 사이드 프로젝트 결과물 모음",
description: "DDD에서 진행된 다양한 사이드 프로젝트 결과물을 확인해보세요.",
};

export default function ProjectPage() {
return <></>;
export default async function ProjectPage() {
const { items, nextCursor } = await fetchPublicProjectsPage({ limit: 9 });

return (
<>
<Navigation />
<main>
<ProjectListPageSection initialItems={items} initialNextCursor={nextCursor} />
</main>
<Footer />
</>
);
}
21 changes: 21 additions & 0 deletions apps/web/app/recruit/apply/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { Metadata } from "next";
import { Navigation } from "@/components/layout/Navigation";
import { Footer } from "@/components/layout/Footer";
import { RecruitApplySection } from "@/components/sections/RecruitApplySection";

export const metadata: Metadata = {
title: "DDD 지원서 | DDD",
description: "DDD 13기 지원서 페이지입니다.",
};

export default function RecruitApplyPage() {
return (
<>
<Navigation />
<main>
<RecruitApplySection />
</main>
<Footer />
</>
);
}
32 changes: 27 additions & 5 deletions apps/web/app/recruit/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,32 @@
import type { Metadata } from "next";
import { Navigation } from "@/components/layout/Navigation";
import { Footer } from "@/components/layout/Footer";
import { RecruitHeroSection } from "@/components/sections/RecruitHeroSection";
import { RecruitRolesSection } from "@/components/sections/RecruitRolesSection";
import { RecruitScheduleSection } from "@/components/sections/RecruitScheduleSection";
import { RecruitCurriculumSection } from "@/components/sections/RecruitCurriculumSection";
import { recruitPageMetaDescriptionByStatus } from "@/constants/recruit";
import { fetchRecruitStatus } from "@/lib/api/cohort";

export const metadata: Metadata = {
title: "DDD 모집 - 사이드 프로젝트 멤버 지원",
description: "DDD에서 함께할 개발자, 디자이너, 기획자를 모집합니다.",
};
export async function generateMetadata(): Promise<Metadata> {
const recruitStatus = await fetchRecruitStatus();
return {
title: "DDD 모집 - 사이드 프로젝트 멤버 지원",
description: recruitPageMetaDescriptionByStatus[recruitStatus],
};
}

export default function RecruitPage() {
return <></>;
return (
<>
<Navigation />
<main>
<RecruitHeroSection />
<RecruitRolesSection />
<RecruitScheduleSection />
<RecruitCurriculumSection />
</main>
<Footer />
</>
);
}
Loading