-
Notifications
You must be signed in to change notification settings - Fork 2
Feature/home layout #9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f696354
a0878d3
9c67fe2
f562c97
8998f9e
810af89
0614fc2
b0070e1
a3eddd5
4752b98
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,19 @@ | ||
| import DesignSystemDemo from '@/pages/DesignSystem' | ||
| import { lazy, Suspense } from 'react' | ||
| import HomePage from '@/pages/Home' | ||
|
|
||
| const DesignSystemDemo = lazy(() => import('@/pages/DesignSystem')) | ||
|
|
||
| export default function App() { | ||
| return <DesignSystemDemo /> | ||
| const path = | ||
| typeof window !== 'undefined' ? window.location.pathname : '/' | ||
|
|
||
| if (path.startsWith('/design-system')) { | ||
| return ( | ||
| <Suspense fallback={null}> | ||
| <DesignSystemDemo /> | ||
| </Suspense> | ||
| ) | ||
| } | ||
|
|
||
| return <HomePage /> | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export { default } from './ui/HomePage' |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| // PR 2 (feature/home-layout) ๋จ๊ณ์ HomePage.tsx | ||
| import { SiteNav } from '@/widgets/site-nav' | ||
| import { SiteFooter } from '@/widgets/site-footer' | ||
| // ์์ง PR 3์์ ๋ง๋ค ์์ ์ด๋ฏ๋ก ์ฃผ์ ์ฒ๋ฆฌ! | ||
| // import { HomeHero } from '@/widgets/home-hero' | ||
|
|
||
| export default function HomePage() { | ||
| return ( | ||
| <div className="min-h-svh bg-bg text-fg"> | ||
| {/* ๊ธ๋ก๋ฒ ๋ ์ด์์์ ์ถํ ๋ถ๋ฆฌ ์์ */} | ||
| <SiteNav /> | ||
| <main> | ||
| {/* TODO: ๋ค์ PR์์ ์์ ฏ๋ค ์ถ๊ฐ ์์ */} | ||
| </main> | ||
| <SiteFooter /> | ||
| </div> | ||
| ) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export { SiteFooter } from './ui/SiteFooter' |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,113 @@ | ||
| // ๋จ์ ๋ทฐ ์น์ widgets ์์ ๊ตณ์ด ๋๋์ง ์๋๊ฒ ์ข๋ค๊ณ ํ๋จํ์ต๋๋ค. | ||
| // ์์, ๋ฉ์ธ์ง ๋ฑ ๋ง์ฐฌ๊ฐ์ง | ||
| const columns = [ | ||
| { | ||
| title: 'Company', | ||
| links: [ | ||
| { label: 'Home', href: '#top' }, | ||
| { label: 'About', href: '#quote' }, | ||
| { label: 'FAQ', href: '#faq' }, | ||
| { label: 'Team', href: '#quote' }, | ||
| ], | ||
| }, | ||
| { | ||
| title: 'Services', | ||
| links: [ | ||
| { label: 'Frontend Interview', href: '#services' }, | ||
| { label: 'Backend Interview', href: '#services' }, | ||
| { label: 'CS / Full Stack', href: '#services' }, | ||
| { label: 'Reports', href: '#services' }, | ||
| ], | ||
| }, | ||
| { | ||
| title: 'Other', | ||
| links: [ | ||
| { label: 'Design System', href: '/design-system' }, | ||
| { label: 'GitHub', href: '#' }, | ||
| { label: 'Privacy', href: '#' }, | ||
| { label: 'Get Started', href: '#cta' }, | ||
| ], | ||
| }, | ||
| ] | ||
|
|
||
| export function SiteFooter() { | ||
| return ( | ||
| <footer | ||
| id="footer" | ||
| className="relative text-white" | ||
| style={{ background: 'var(--color-sage-800)' }} | ||
| > | ||
| <div className="mx-auto max-w-content px-6 lg:px-12 pt-20 lg:pt-28 pb-12"> | ||
| <div className="flex flex-col lg:flex-row lg:items-end gap-8 lg:gap-12"> | ||
| <h2 | ||
| className="font-heading font-extrabold uppercase text-white leading-[0.95] tracking-tight flex-1" | ||
| style={{ fontSize: 'clamp(40px, 6vw, 88px)' }} | ||
| > | ||
| One smart step | ||
| </h2> | ||
| <a | ||
| href="#cta" | ||
| className="inline-flex self-start lg:self-end items-center gap-2 pl-5 pr-2 py-2.5 rounded-pill bg-[#e6dfd4] text-sage-900 text-button hover:bg-white transition-colors duration-fast" | ||
| > | ||
| Get Started | ||
| <span | ||
| aria-hidden | ||
| className="inline-flex items-center justify-center w-6 h-6 rounded-pill bg-sage-900 text-white text-[11px]" | ||
| > | ||
| โ | ||
| </span> | ||
| </a> | ||
| </div> | ||
|
|
||
| <div className="mt-12 h-px bg-sage-600/70" /> | ||
|
|
||
| <div className="mt-12 grid gap-12 lg:grid-cols-12"> | ||
| <div className="lg:col-span-5"> | ||
| <div className="font-heading font-extrabold uppercase tracking-[0.06em] text-white text-[22px]"> | ||
| Stack Up | ||
| </div> | ||
| <p className="mt-4 text-sage-200 max-w-sm leading-relaxed"> | ||
| IT ์ง๊ตฐ ๋ฉํฐ๋ชจ๋ฌ AI ๋ฉด์ ์๋ฎฌ๋ ์ดํฐ. GitHub ๋ ํฌ์ ์ด๋ ฅ์๋ฅผ ๋ถ์ํด | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ์ด๋ฐ ํ
์คํธ ํ๋์ฝ๋ฉ์ ์ง๊ธ์ฒ๋ผ ์ฒ๋ฆฌํ๋๊ฒ ์ข์๊น์?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ์ด๋๊ฐ์ ์ฃผ์์ ๋ฌ์๋๊ธฐ๋ ํ๋๋ฐ์, widgets์ ๋จ์ ๋ทฐ ์ปดํฌ๋ํธ์ ๊ฒฝ์ฐ์ ์ธ๊ทธ๋จผํธ๋ฅผ ๋ถ๋ฆฌํ๊ธฐ ๋ณด๋จ ํ๋์ ์ปดํฌ๋ํธ ํ์ผ์ ๋๋๊ฒ์ด ๊ฐ๋
์ฑ๋ ์ข๊ณ ๊ด๋ฆฌ๋ ํธํ๋ค๊ณ ์๊ฐํ์ต๋๋ค. |
||
| ๊ฐ์ธ ๋ง์ถค ๋ฉด์ ๊ณผ ์์ฑยท๋น์ธ์ด์ ํผ๋๋ฐฑ์ ์ ๊ณตํฉ๋๋ค. | ||
| </p> | ||
| </div> | ||
|
|
||
| <nav | ||
| aria-label="Footer" | ||
| className="lg:col-span-7 grid grid-cols-2 sm:grid-cols-3 gap-8" | ||
| > | ||
| {columns.map((col) => ( | ||
| <div key={col.title}> | ||
| <div className="text-caption font-mono uppercase tracking-[0.22em] text-sage-300"> | ||
| {col.title} | ||
| </div> | ||
| <ul className="mt-4 space-y-3"> | ||
| {col.links.map((l) => ( | ||
| <li key={l.label}> | ||
| <a | ||
| href={l.href} | ||
| className="text-white/90 hover:text-white transition-colors duration-fast" | ||
| > | ||
| {l.label} | ||
| </a> | ||
| </li> | ||
| ))} | ||
| </ul> | ||
| </div> | ||
| ))} | ||
| </nav> | ||
| </div> | ||
|
|
||
| <div className="mt-16 pt-8 border-t border-sage-600/60 flex flex-col sm:flex-row gap-3 sm:items-center sm:justify-between"> | ||
| <div className="text-caption font-mono text-sage-300"> | ||
| ยฉ 2026 StackUp ยท CNU ์ข ํฉ์ค๊ณ. All rights reserved. | ||
| </div> | ||
| <ul className="flex gap-6 text-caption text-sage-300"> | ||
| <li><a href="#" className="hover:text-white transition-colors duration-fast">Privacy</a></li> | ||
| <li><a href="#" className="hover:text-white transition-colors duration-fast">Terms</a></li> | ||
| </ul> | ||
| </div> | ||
| </div> | ||
| </footer> | ||
| ) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export { SiteNav } from './ui/SiteNav' |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| import { useEffect, useState } from 'react' | ||
|
|
||
| const items = [ | ||
| { href: '#services', label: 'Services' }, | ||
| { href: '#quote', label: 'About' }, | ||
| { href: '#faq', label: 'FAQ' }, | ||
| ] | ||
|
|
||
| export function SiteNav() { | ||
| const [scrolled, setScrolled] = useState(false) | ||
|
|
||
| useEffect(() => { | ||
| const onScroll = () => setScrolled(window.scrollY > 8) | ||
| onScroll() | ||
| window.addEventListener('scroll', onScroll, { passive: true }) | ||
| return () => window.removeEventListener('scroll', onScroll) | ||
| }, []) | ||
|
|
||
| return ( | ||
| <header | ||
| className={[ | ||
| 'sticky top-0 w-full transition-colors duration-normal ease-standard', | ||
| scrolled | ||
| ? 'bg-bg/85 backdrop-blur-md border-b border-border' | ||
| : 'bg-transparent border-b border-transparent', | ||
| ].join(' ')} | ||
| style={{ zIndex: 'var(--z-sticky)' }} | ||
| > | ||
| <div className="mx-auto max-w-content px-6 lg:px-12 h-16 flex items-center justify-between"> | ||
| <a | ||
| href="#top" | ||
| className="font-heading font-extrabold tracking-[0.04em] text-sage-900 text-[15px] uppercase" | ||
| > | ||
| Stack Up | ||
| </a> | ||
|
|
||
| <nav aria-label="Primary" className="hidden md:flex items-center gap-1"> | ||
| {items.map((it) => ( | ||
| <a | ||
| key={it.href} | ||
| href={it.href} | ||
| className="px-3 py-2 text-button text-fg-strong/80 hover:text-fg-strong transition-colors duration-fast" | ||
| > | ||
| {it.label} | ||
| </a> | ||
| ))} | ||
| </nav> | ||
|
|
||
| <div className="flex items-center"> | ||
| <a | ||
| href="#cta" | ||
| className="inline-flex items-center gap-2 pl-5 pr-2 py-2 rounded-pill bg-[#e6dfd4] text-sage-900 text-button hover:bg-[#dcd4c6] transition-colors duration-fast" | ||
| > | ||
| Get Started | ||
| <span | ||
| aria-hidden | ||
| className="inline-flex items-center justify-center w-6 h-6 rounded-pill bg-sage-900 text-white text-[11px]" | ||
| > | ||
| โ | ||
| </span> | ||
| </a> | ||
| </div> | ||
| </div> | ||
| </header> | ||
| ) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[๋จ์ ์ง๋ฌธ] ๋๋ ํ ๋ฆฌ๋ช ์ด ์ฌ๊ธฐ์๋ AsyncBoundary ๋ค์.
๋ค๋ฅธ ๊ณณ์์๋ site-footer ์ฒ๋ผ kebab-case ์ธ๋ฐ, ์ฌ๊ธฐ์๋ PascalCase๋ก ์ค์ ํ ์ด์ ๊ฐ ๊ถ๊ธํฉ๋๋ค.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
์ค ํ์ธํ์ง ๋ชปํ๋๋ฐ, ๊ฐ์ฌํฉ๋๋ค. ํ๋๋ก ํต์ผํ๋ ๋ฐฉํฅ์ผ๋ก ์์ ํ ๊ฒ์.