Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions frontend/frontend/app/marketplace/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"use client";

import * as React from 'react';
import Link from 'next/link';
import FeatureLauncherGrid from '@/components/marketplace/feature-launcher-grid';
Expand Down Expand Up @@ -625,6 +627,7 @@ export default function MarketplacePage() {
<FeatureOrchestratorPopup
isOpen={featureOrchestrator.isPopupOpen}
activeFeatureId={featureOrchestrator.activeFeatureId}
featureMeta={featureOrchestrator.activeFeatureMeta}
popupMode={featureOrchestrator.activeFeature?.popup_mode}
title={featureOrchestrator.activeFeature?.title || 'AI 엑셀 시트'}
featureSummary={featureOrchestrator.activeFeature?.summary || '시트 schema preview 와 최종 workbook 패키지를 생성하는 실행형 backend'}
Expand Down
18 changes: 8 additions & 10 deletions frontend/frontend/components/marketplace/feature-launcher-grid.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client';

import * as React from 'react';
import type { FeatureCatalogItem } from '@/hooks/use-feature-orchestrator';
import { getFeatureExperienceMeta, type FeatureCatalogItem } from '@/hooks/use-feature-orchestrator';

interface FeatureLauncherGridProps {
catalog: FeatureCatalogItem[];
Expand All @@ -24,10 +24,7 @@ export default function FeatureLauncherGrid({ catalog, catalogLoading, catalogEr
<div className="grid gap-4 md:grid-cols-2 xl:grid-cols-5" data-testid="marketplace-feature-launcher-grid">
{catalog.map((feature) => {
const enabled = feature.status === 'enabled';
const isSpreadsheetFeature = feature.feature_id === 'ai-sheet';
const featureSummary = isSpreadsheetFeature
? '시트 schema preview 를 먼저 확인하고, final phase 에서 xlsx/csv workbook 패키지를 즉시 다운로드합니다.'
: feature.summary;
const meta = getFeatureExperienceMeta(feature.feature_id);
return (
<article key={feature.feature_id} data-testid={`marketplace-feature-card-${feature.feature_id}`} className={`rounded-[20px] border p-4 shadow-[0_0_0_1px_rgba(255,255,255,0.03)] ${enabled ? 'border-[#30363d] bg-[#0d1117]' : 'border-[#2b3240] bg-[#121826]'}`}>
<div className="flex items-start justify-between gap-3">
Expand All @@ -36,20 +33,21 @@ export default function FeatureLauncherGrid({ catalog, catalogLoading, catalogEr
<p className="mt-2 text-xs uppercase tracking-[0.18em] text-[#8b949e]">{feature.popup_mode}</p>
</div>
<span className={`rounded-full border px-3 py-1.5 text-xs font-bold ${enabled ? 'border-[#31c45d] text-[#31c45d]' : 'border-[#7d8590] text-[#7d8590]'}`}>
{enabled ? (isSpreadsheetFeature ? '엑셀 즉시 생성' : 'Popup 실행') : '준비 중'}
{enabled ? meta.launcherBadge : '준비 중'}
</span>
</div>
<p className="mt-4 min-h-[96px] text-sm leading-7 text-[#98a3b3]">{featureSummary}</p>
<p className="mt-4 min-h-[96px] text-sm leading-7 text-[#98a3b3]">{meta.launcherSummary}</p>
<div className="mt-4 flex flex-wrap gap-2 text-[11px] text-[#d2d9e3]">
{isSpreadsheetFeature && <span className="rounded-full border border-[#2a7cff] bg-[#10264a] px-3 py-1.5 text-[#9ecbff]">schema preview</span>}
{isSpreadsheetFeature && <span className="rounded-full border border-[#2a7cff] bg-[#10264a] px-3 py-1.5 text-[#9ecbff]">xlsx/csv 다운로드</span>}
{meta.launcherHighlights.map((highlight) => (
<span key={`${feature.feature_id}-${highlight}`} className="rounded-full border border-[#2a7cff] bg-[#10264a] px-3 py-1.5 text-[#9ecbff]">{highlight}</span>
))}
{feature.supports_photo_upload && <span className="rounded-full border border-[#30363d] bg-[#151b23] px-3 py-1.5">사진 업로드</span>}
{feature.supports_final_phase && <span className="rounded-full border border-[#30363d] bg-[#151b23] px-3 py-1.5">final phase</span>}
{feature.feature_id === activeFeatureId && <span className="rounded-full border border-[#2a7cff] bg-[#10264a] px-3 py-1.5 text-[#9ecbff]">선택됨</span>}
</div>
<div className="mt-6">
<button type="button" data-testid={`marketplace-feature-launch-${feature.feature_id}`} onClick={() => enabled && onLaunch(feature.feature_id)} disabled={!enabled} className={`w-full rounded-2xl px-4 py-2.5 text-sm font-bold ${enabled ? 'bg-[#2a7cff] text-white' : 'cursor-not-allowed bg-[#202938] text-[#7d8590]'}`}>
{enabled ? (isSpreadsheetFeature ? '엑셀 시트 생성 시작' : '팝업 오케스트레이터 열기') : '후속 구현 예정'}
{enabled ? meta.launcherCta : '후속 구현 예정'}
</button>
</div>
</article>
Expand Down
Loading