-
+
+
+
◆ 03 · Numbers
-
- 숫자로 보는 startover
+
+ 숫자로 보는 startover
- {STATS.map((s, i) => (
-
+ {STATS.map((s) => (
+
{s.value}
- {s.unit}
+ {s.unit}
-
{s.label}
-
{s.sub}
+
{s.label}
+
{s.sub}
))}
@@ -394,40 +374,41 @@ export default function HomePage() {
{/* ==========================================================
* CATEGORIES
* ========================================================== */}
-
+
-
-
+
+
-
+
◆ 04 · Categories
-
- 지원 업종
+
+ 지원 업종
-
+
휴게음식점부터 기타업종까지 7개 대분류,
49개 소분류를 지원합니다.
전체 매장 보기
→
- {INDUSTRY_MAJORS.map((m, i) => (
+ {INDUSTRY_MAJORS.map((m) => (
-
+
{m.label}
-
+
{m.children.length} sub
@@ -439,12 +420,12 @@ export default function HomePage() {
{/* ==========================================================
* BENEFITS
* ========================================================== */}
-
-
-
+
+
+
◆ 05 · Benefits
-
+
각자에게 필요한
혜택
@@ -453,35 +434,18 @@ export default function HomePage() {
{BENEFITS.map((b) => (
-
-
- {b.english}
-
-
- {b.label}
-
-
- {b.title}
-
+
+
{b.english}
+
{b.label}
+
{b.title}
- {b.points.map((p, idx) => (
- -
+ {b.points.map((p) => (
+
-
{p}
@@ -493,76 +457,26 @@ export default function HomePage() {
- {/* ==========================================================
- * SERVICES
- * ========================================================== */}
-
-
-
-
- ◆ 06 · Services
-
-
- 더 나아간 지원
-
-
-
- {SERVICES.map((s) => (
-
-
- {s.icon}
-
-
-
- {s.tag}
-
-
- {s.title}
-
-
- {s.desc}
-
-
- {s.cta}
- →
-
-
-
- ))}
-
-
-
-
{/* ==========================================================
* BLOG
* ========================================================== */}
-
-
+
+
-
- ◆ 07 · Journal
+
+ ◆ 06 · Journal
-
- 실무 가이드
+
+ 실무 가이드
-
+
폐업 절차, 지원금 신청, 상권 분석 — 현장에서 자주 묻는
질문을 글로 정리합니다.
블로그 전체 보기
→
@@ -572,18 +486,19 @@ export default function HomePage() {
-
+
{post.category}
-
+
{post.title}
-
+
{post.description}
-
+
{post.publishedAt} · {post.readMinutes}min
@@ -594,17 +509,17 @@ export default function HomePage() {
{/* ==========================================================
* FAQ
* ========================================================== */}
-
+
-
-
-
- ◆ 08 · FAQ
+
+
+
+ ◆ 07 · FAQ
-
+
자주 묻는 질문
@@ -612,22 +527,21 @@ export default function HomePage() {
{FAQ_PREVIEW.map((f, i) => (
- {f.q}
-
- +
-
+ {f.q}
+ +
- {f.a}
+ {f.a}
))}
-
+
전체 FAQ 보기
→
@@ -639,26 +553,22 @@ export default function HomePage() {
* FINAL CTA
* ========================================================== */}
- {/* Massive gradient background */}
-
-
+
-
-
- Get started
-
-
- 지금,
+
+
Get started
+
+ 지금,
새로 시작하세요
-
+
한 번의 등록으로 인수자 · 철거 · 인테리어 · 지원금까지.
흩어진 절차를 한 흐름으로 정돈합니다.
diff --git a/apps/web/src/app/stores/[id]/page.tsx b/apps/web/src/app/stores/[id]/page.tsx
index a9adece..65001e5 100644
--- a/apps/web/src/app/stores/[id]/page.tsx
+++ b/apps/web/src/app/stores/[id]/page.tsx
@@ -62,6 +62,15 @@ function formatPaybackMonths(premium?: number | null, profit?: number | null): s
return `${months.toFixed(1)}개월`;
}
+const STATUS_META: Record = {
+ OPEN: { label: '거래 가능', bg: '#03C75A', fg: '#ffffff' },
+ MATCHING: { label: '매칭 중', bg: '#00C4A7', fg: '#ffffff' },
+ RESERVED: { label: '예약', bg: '#84E1A1', fg: '#0F1D17' },
+ CONTRACTED: { label: '계약 진행 중', bg: '#0AB070', fg: '#ffffff' },
+ CLOSED: { label: '거래 완료', bg: '#7B8581', fg: '#ffffff' },
+ CANCELLED: { label: '취소', bg: '#E4E8E6', fg: '#0F1D17' },
+};
+
export default async function StoreDetailPage({ params }: { params: Promise<{ id: string }> }) {
const { id } = await params;
const prisma = createPrismaClient();
@@ -86,21 +95,7 @@ export default async function StoreDetailPage({ params }: { params: Promise<{ id
notFound();
}
- const statusLabel =
- store.dealStatus === 'OPEN'
- ? '거래 가능'
- : store.dealStatus === 'MATCHING'
- ? '매칭 중'
- : store.dealStatus === 'CONTRACTED'
- ? '계약 진행 중'
- : store.dealStatus;
-
- const statusClass =
- store.dealStatus === 'OPEN'
- ? 'bg-sage-500/10 text-sage-600'
- : store.dealStatus === 'MATCHING'
- ? 'bg-warm-400/15 text-warm-700'
- : 'bg-ink/5 text-ink-muted';
+ const status = STATUS_META[store.dealStatus] ?? { label: store.dealStatus, bg: '#E4E8E6', fg: '#0F1D17' };
const industryLabel = [
store.industryLeaf?.parent?.nameKo,
@@ -114,281 +109,312 @@ export default async function StoreDetailPage({ params }: { params: Promise<{ id
const profit = store.sale?.monthlyProfitAmount ?? null;
const startup = store.sale?.startupCostAmount ?? null;
- return (
-
-
-
- ← 매장 목록으로
-
-
+ const heroPhoto = store.photos.find((p) => p.isRepresentative) ?? store.photos[0] ?? null;
+ const restPhotos = store.photos.filter((p) => p.id !== heroPhoto?.id).slice(0, 8);
-
-
-
-
{store.listingTitle}
-
매장 ID: {store.publicId}
-
-
- {statusLabel}
+ return (
+
+ {/* ========================================================== *
+ * PHOTO HERO (mobile first — 직방/다방 style)
+ * ========================================================== */}
+
+
+ {heroPhoto ? (
+ /* eslint-disable-next-line @next/next/no-img-element */
+

+ ) : (
+
+ 사진 준비 중
+
+ )}
+
+ {status.label}
+
+ ×
+
+ {store.photos.length > 0 && (
+
+ 📷 {store.photos.length}
+
+ )}
- {/* 기본 정보 */}
-
-
- {/* 매매 정보 */}
-
- 매매 정보
-
- {/* 핵심 지표 (첫번째 캡쳐) */}
-
-
-
-
-
-
-
-
-
- {/* 매물설명 + 매장사진 (두번째 캡쳐) */}
- {(store.sale?.listingDescription || store.photos.length > 0) && (
-
-
매물 설명
- {store.sale?.listingDescription ? (
-
- {store.sale.listingDescription}
-
- ) : (
-
설명이 등록되지 않았습니다
- )}
-
- {store.photos[0] && (
-
- {/* eslint-disable-next-line @next/next/no-img-element */}
-

-
- )}
-
- )}
-
- {/* 매출/월수익 */}
- {(sales != null || profit != null) && (
-
-
매출 / 월수익
-
-
-
-
-
-
+ {/* Thumbnail strip (photos 2..9) */}
+ {restPhotos.length > 0 && (
+
+ {restPhotos.map((photo) => (
+
+ {/* eslint-disable-next-line @next/next/no-img-element */}
+
-
+ ))}
+
+ )}
+
+
+ {/* ========================================================== *
+ * SUMMARY BAR (price, status, title)
+ * ========================================================== */}
+
+
+ {store.regionCluster?.nameKo ?? '-'}
+ {industryLabel ? ` · ${industryLabel}` : ''}
+
+
+ {store.listingTitle}
+
+
+
+
+
+
+
+
+
+
+ {/* ========================================================== *
+ * BODY
+ * ========================================================== */}
+
+
+ {/* 매물 설명 */}
+ {store.sale?.listingDescription && (
+
+
+ {store.sale.listingDescription}
+
+
)}
- {/* 입지특징 */}
+ {/* 입지 특징 */}
{store.sale?.locationHighlight && (
-
-
입지 특징
-
+
+
{store.sale.locationHighlight}
-
+
)}
- {/* 매매사유 */}
+ {/* 매매 사유 */}
{store.sale?.saleReason && (
-
-
매매 사유
-
+
+
{store.sale.saleReason}
-
+
)}
- {/* 현장사진 (대표 사진 제외한 나머지) */}
- {store.photos.length > 1 && (
-
-
현장 사진
-
- {store.photos.slice(1).map((photo) => (
-
- {/* eslint-disable-next-line @next/next/no-img-element */}
-

-
- ))}
+ {/* 시설 정보 */}
+
+
+
+
+
+ {store.facility?.kitchenEquipmentSummary && (
+
+
시설 설명
+
{store.facility.kitchenEquipmentSummary}
+
+ )}
+
+
+
+ {/* Sticky sidebar */}
+
+
);
}
-function InfoItem({ label, value }: { label: string; value: string }) {
+function KpiTile({ label, value, accent }: { label: string; value: string; accent?: boolean }) {
return (
-
- );
-}
-
-function BigInfoItem({ label, value, accent }: { label: string; value: string; accent?: boolean }) {
- return (
-
-
{label}
+
);
}
+
+function SectionCard({ title, children }: { title: string; children: React.ReactNode }) {
+ return (
+
+ );
+}
+
+function InfoItem({ label, value }: { label: string; value: string }) {
+ return (
+
+ );
+}
+
+function RowInfo({ label, value }: { label: string; value: string }) {
+ return (
+
+ {label}
+ {value}
+
+ );
+}
diff --git a/apps/web/src/app/stores/page.tsx b/apps/web/src/app/stores/page.tsx
index 51c6afb..91de1e0 100644
--- a/apps/web/src/app/stores/page.tsx
+++ b/apps/web/src/app/stores/page.tsx
@@ -19,6 +19,15 @@ function formatKRWShort(value: number | null | undefined): string {
return `${v.toLocaleString('ko-KR')}원`;
}
+const STATUS_META: Record
= {
+ OPEN: { label: '거래 가능', bg: '#03C75A', fg: '#ffffff' },
+ MATCHING: { label: '매칭 중', bg: '#00C4A7', fg: '#ffffff' },
+ RESERVED: { label: '예약', bg: '#84E1A1', fg: '#0F1D17' },
+ CONTRACTED: { label: '계약 진행 중', bg: '#0AB070', fg: '#ffffff' },
+ CLOSED: { label: '거래 완료', bg: '#7B8581', fg: '#ffffff' },
+ CANCELLED: { label: '취소', bg: '#E4E8E6', fg: '#0F1D17' },
+};
+
export default async function StoresPage({
searchParams,
}: {
@@ -68,18 +77,25 @@ export default async function StoresPage({
return (
-
+
-
매장 검색
+
+ ◆ Store · Marketplace
+
+
매장 검색
- 공개된 매장을 검색하고 매칭 요청을 보내보세요
+ 공개된 매물 {stores.length.toLocaleString('ko-KR')}건 · 운영팀 검수를 통과한 매장만 노출됩니다
- 매장 등록
+ 매장 등록 →
@@ -90,12 +106,13 @@ export default async function StoresPage({
{stores.length === 0 ? (
- 등록된 매장이 없습니다
+ 조건에 맞는 매장이 없습니다
) : (
stores.map((store) => {
const premium = store.sale?.premiumAmount ?? store.lease?.premiumAmount ?? null;
const profit = store.sale?.monthlyProfitAmount ?? null;
+ const sales = store.sale?.monthlySalesAmount ?? null;
const industryLabel = [
store.industryLeaf?.parent?.nameKo,
store.industryLeaf?.nameKo,
@@ -103,21 +120,23 @@ export default async function StoresPage({
.filter(Boolean)
.join('/');
const photoSrc = store.photos[0]?.storageKey ?? null;
+ const meta = STATUS_META[store.dealStatus] ?? { label: store.dealStatus, bg: '#E4E8E6', fg: '#0F1D17' };
+ const isClosed = store.dealStatus === 'CLOSED';
return (
- {/* 사진 영역 */}
-
+
{photoSrc ? (
- // eslint-disable-next-line @next/next/no-img-element
+ /* eslint-disable-next-line @next/next/no-img-element */

) : (
@@ -125,23 +144,13 @@ export default async function StoresPage({
)}
- {store.dealStatus === 'OPEN'
- ? '거래 가능'
- : store.dealStatus === 'MATCHING'
- ? '매칭 중'
- : store.dealStatus}
+ {meta.label}
- {/* 정보 영역 */}
{store.regionCluster?.nameKo ?? '-'}
@@ -150,10 +159,10 @@ export default async function StoresPage({
{store.listingTitle}
-
+
권리금
-
+
{formatKRWShort(premium != null ? Number(premium) : null)}
@@ -163,6 +172,12 @@ export default async function StoresPage({
{formatKRWShort(profit != null ? Number(profit) : null)}
+
+ 월매출
+
+ {formatKRWShort(sales != null ? Number(sales) : null)}
+
+
@@ -171,7 +186,7 @@ export default async function StoresPage({
)}
-
+
매출·수익 정보는 매도인이 제공한 자료이며 법적 근거로 사용될 수 없습니다
diff --git a/apps/web/src/app/stores/store-filters.tsx b/apps/web/src/app/stores/store-filters.tsx
index dd497d8..fc92829 100644
--- a/apps/web/src/app/stores/store-filters.tsx
+++ b/apps/web/src/app/stores/store-filters.tsx
@@ -15,6 +15,7 @@ const STATUS_OPTIONS = [
{ value: 'OPEN', label: '거래 가능' },
{ value: 'MATCHING', label: '매칭 중' },
{ value: 'CONTRACTED', label: '계약 진행 중' },
+ { value: 'CLOSED', label: '거래 완료' },
];
export function StoreFilters() {
@@ -46,15 +47,21 @@ export function StoreFilters() {
[router],
);
+ const selectCls =
+ 'rounded-xl border px-4 py-3 text-sm text-ink bg-white focus:outline-none focus:border-[#03C75A] focus:ring-2 focus:ring-[#03C75A]/20';
+ const borderStyle = { borderColor: '#E4E8E6' } as const;
+
return (