feat(phase1): /showcase 제작 사례 허브 + TopNav 제작 사례 + robots 죽은 경로 정리
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,7 @@ import type { User } from '@supabase/supabase-js';
|
||||
const LINKS = [
|
||||
{ href: '/outsourcing', label: '외주 개발' },
|
||||
{ href: '/products', label: '소프트웨어' },
|
||||
{ href: '/showcase', label: '제작 사례' },
|
||||
];
|
||||
|
||||
export default function TopNav() {
|
||||
|
||||
@@ -6,7 +6,7 @@ export default function robots(): MetadataRoute.Robots {
|
||||
{
|
||||
userAgent: '*',
|
||||
allow: '/',
|
||||
disallow: ['/admin/', '/api/', '/mypage/', '/payment/', '/freelance', '/services/website', '/portfolio/'],
|
||||
disallow: ['/admin/', '/api/', '/mypage/', '/portfolio/'],
|
||||
},
|
||||
],
|
||||
sitemap: 'https://jaengseung-made.com/sitemap.xml',
|
||||
|
||||
166
app/showcase/page.tsx
Normal file
166
app/showcase/page.tsx
Normal file
@@ -0,0 +1,166 @@
|
||||
import type { Metadata } from 'next';
|
||||
import Link from 'next/link';
|
||||
import { SHOWCASE_SAMPLES } from '@/lib/showcase-samples';
|
||||
|
||||
// 제작 사례 허브 — 웹사이트 데모 8종 + 실서비스 운영 사례. 홈·외주·제품과 동일한 라이트 카드 언어.
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: '제작 사례 | 쟁승메이드',
|
||||
description: '직접 설계·개발한 웹사이트 데모와 실서비스 운영 사례.',
|
||||
};
|
||||
|
||||
const KOR_TIGHT = { letterSpacing: '-0.02em' } as const;
|
||||
const KOR_BODY = { letterSpacing: '-0.01em' } as const;
|
||||
|
||||
// 실운영 서비스(개인 NAS 실서비스 — 외부 링크 없음, 실증 서술만)
|
||||
const LIVE_SERVICES = [
|
||||
{ title: '로또 분석 랩', desc: '회차 수집·통계 분석·리포트 자동 생성까지 무인 운영' },
|
||||
{ title: '주식 자동매매 대시보드', desc: '시세 수집·스크리너·자동 주문을 하나의 콘솔로 운영' },
|
||||
{ title: 'AI 미디어 파이프라인', desc: '음악·영상·이미지 생성 워커를 큐 기반으로 상시 가동' },
|
||||
{ title: '여행 사진 갤러리', desc: '수천 장 사진의 지역 분류·썸네일·지도 탐색 자동화' },
|
||||
];
|
||||
|
||||
function ArrowRight() {
|
||||
return (
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
|
||||
<path d="M5 12h14" />
|
||||
<path d="m13 5 7 7-7 7" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default function ShowcasePage() {
|
||||
return (
|
||||
<>
|
||||
{/* ─── Hero ─── */}
|
||||
<section style={{ background: 'var(--jsm-surface)' }}>
|
||||
<div className="mx-auto max-w-6xl px-6 pt-20 pb-16 lg:px-8 lg:pt-28 lg:pb-20">
|
||||
<div className="max-w-2xl">
|
||||
<span className="inline-flex items-center gap-2 font-mono text-[11px] uppercase tracking-[0.22em]" style={{ color: 'var(--jsm-accent)' }}>
|
||||
<span className="inline-block h-1 w-1 rounded-full" style={{ background: 'var(--jsm-accent)' }} />
|
||||
showcase
|
||||
</span>
|
||||
<h1
|
||||
className="mt-6 font-extrabold break-keep"
|
||||
style={{ color: 'var(--jsm-ink)', fontSize: 'clamp(2.3rem, 6vw, 3.6rem)', lineHeight: 1.1, letterSpacing: '-0.035em' }}
|
||||
>
|
||||
제작 사례
|
||||
<span style={{ color: 'var(--jsm-accent)' }}>.</span>
|
||||
</h1>
|
||||
<p className="mt-7 break-keep text-lg leading-relaxed" style={{ color: 'var(--jsm-ink-soft)', ...KOR_BODY }}>
|
||||
실서비스를 직접 만들고 운영하며 검증한 방식 그대로 만듭니다.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ─── 웹사이트 데모 ─── */}
|
||||
<section style={{ background: 'var(--jsm-surface-alt)' }}>
|
||||
<div className="mx-auto max-w-6xl px-6 py-16 lg:px-8 lg:py-24">
|
||||
<p className="mb-3 font-mono text-[11px] uppercase tracking-[0.22em]" style={{ color: 'var(--jsm-accent)' }}>
|
||||
website demo
|
||||
</p>
|
||||
<h2 className="break-keep text-3xl font-bold lg:text-[2.6rem] lg:leading-[1.12]" style={{ color: 'var(--jsm-ink)', letterSpacing: '-0.03em' }}>
|
||||
웹사이트 데모
|
||||
</h2>
|
||||
|
||||
<div className="mt-12 grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-4">
|
||||
{SHOWCASE_SAMPLES.map((s) => (
|
||||
<div
|
||||
key={s.slug}
|
||||
className="flex flex-col rounded-2xl border p-6 transition-[transform,box-shadow,border-color] duration-300 hover:-translate-y-1 hover:border-[var(--jsm-accent)] hover:shadow-[0_24px_60px_-32px_rgba(15,23,42,0.4)]"
|
||||
style={{ background: 'var(--jsm-surface)', borderColor: 'var(--jsm-line)' }}
|
||||
>
|
||||
<h3 className="break-keep text-lg font-bold" style={{ color: 'var(--jsm-ink)', ...KOR_TIGHT }}>
|
||||
{s.title}
|
||||
</h3>
|
||||
<p className="mt-2.5 break-keep text-sm leading-relaxed" style={{ color: 'var(--jsm-ink-soft)', ...KOR_BODY }}>
|
||||
{s.description}
|
||||
</p>
|
||||
|
||||
{s.tags.length > 0 && (
|
||||
<div className="mt-4 flex flex-wrap gap-1.5">
|
||||
{s.tags.map((tag) => (
|
||||
<span
|
||||
key={tag}
|
||||
className="rounded-full px-2.5 py-1 text-xs font-medium"
|
||||
style={{ background: 'var(--jsm-accent-soft)', color: 'var(--jsm-accent)', ...KOR_BODY }}
|
||||
>
|
||||
{tag}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="mt-6 flex items-center justify-between border-t pt-5" style={{ borderColor: 'var(--jsm-line)' }}>
|
||||
<Link
|
||||
href={`/work/website/samples/${s.slug}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="group inline-flex items-center gap-1.5 text-sm font-semibold transition-colors duration-150 hover:text-[var(--jsm-accent-hover)]"
|
||||
style={{ color: 'var(--jsm-accent)', ...KOR_BODY }}
|
||||
>
|
||||
데모 보기
|
||||
<ArrowRight />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ─── 실서비스 운영 ─── */}
|
||||
<section style={{ background: 'var(--jsm-surface)' }}>
|
||||
<div className="mx-auto max-w-6xl px-6 py-16 lg:px-8 lg:py-24">
|
||||
<p className="mb-3 font-mono text-[11px] uppercase tracking-[0.22em]" style={{ color: 'var(--jsm-accent)' }}>
|
||||
live services
|
||||
</p>
|
||||
<h2 className="break-keep text-3xl font-bold lg:text-[2.6rem] lg:leading-[1.12]" style={{ color: 'var(--jsm-ink)', letterSpacing: '-0.03em' }}>
|
||||
실서비스 운영
|
||||
</h2>
|
||||
|
||||
<div className="mt-12 grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4">
|
||||
{LIVE_SERVICES.map((svc) => (
|
||||
<div
|
||||
key={svc.title}
|
||||
className="rounded-2xl border p-6"
|
||||
style={{ background: 'var(--jsm-surface-alt)', borderColor: 'var(--jsm-line)' }}
|
||||
>
|
||||
<p className="break-keep font-bold" style={{ color: 'var(--jsm-ink)', ...KOR_TIGHT }}>
|
||||
{svc.title}
|
||||
</p>
|
||||
<p className="mt-2 break-keep text-sm leading-relaxed" style={{ color: 'var(--jsm-ink-soft)', ...KOR_BODY }}>
|
||||
{svc.desc}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<p className="mt-8 break-keep text-sm leading-relaxed" style={{ color: 'var(--jsm-ink-faint)', ...KOR_BODY }}>
|
||||
위 서비스들은 개인 인프라에서 상시 운영 중인 실제 서비스입니다.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ─── CTA ─── */}
|
||||
<section style={{ background: 'var(--jsm-surface-alt)' }}>
|
||||
<div className="mx-auto max-w-6xl px-6 py-16 lg:px-8 lg:py-20">
|
||||
<h2 className="break-keep text-2xl font-bold lg:text-3xl" style={{ color: 'var(--jsm-ink)', ...KOR_TIGHT }}>
|
||||
이런 걸 만들어 드립니다
|
||||
</h2>
|
||||
<div className="mt-8 flex flex-col gap-4 sm:flex-row">
|
||||
<Link
|
||||
href="/outsourcing#contact"
|
||||
className="inline-flex items-center justify-center gap-2 rounded-lg px-6 py-3.5 text-sm font-semibold text-white transition-colors hover:bg-[var(--jsm-accent-hover)]"
|
||||
style={{ background: 'var(--jsm-accent)', ...KOR_BODY }}
|
||||
>
|
||||
프로젝트 문의
|
||||
<ArrowRight />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user