feat: 랜딩페이지 완성 및 에디터 홈 버튼 기능 구현

주요 변경사항:
- 🎨 가격 섹션을 CTA 섹션과 동일한 그라디언트 스타일로 변경
- 🗑️ 중복된 CTA 섹션 제거 및 페이지 구성 최적화
- 🏠 에디터 상단 로고 클릭 시 홈 이동 기능 추가 (저장 경고 포함)
- 📱 인증 페이지 컴포넌트 추가 (SignIn/SignUp)
- 💰 가격 정보 섹션 및 FAQ 섹션 추가
- 🔧 TopBar 컴포넌트에 로고 클릭 핸들러 추가

UI/UX 개선:
- 가격 섹션: 파란색-보라색 그라디언트 배경 적용
- 카드 스타일: 반투명 배경 및 backdrop-blur 효과
- 텍스트 색상: 그라디언트 배경에 맞는 흰색/파란색 톤 적용
- 버튼 스타일: 인기 플랜 노란색 강조, 일반 플랜 반투명 스타일

기능 추가:
- 에디터에서 로고 클릭 시 작업 손실 경고 및 홈 이동
- 완전한 인증 플로우 UI 구성
- 반응형 가격 정보 표시
This commit is contained in:
sheetEasy AI Team
2025-06-30 15:30:21 +09:00
parent 3d0a5799ff
commit 535281f0fb
12 changed files with 1608 additions and 445 deletions

View File

@@ -914,175 +914,161 @@ const TestSheetViewer: React.FC = () => {
{/* 파일 업로드 오버레이 - 레이어 분리 */}
{showUploadOverlay && (
<>
{/* 1. Univer CE 영역만 흐리게 하는 반투명 레이어 */}
<div
style={{
position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 0,
zIndex: 40,
backgroundColor: "rgba(255, 255, 255, 0.01)",
backdropFilter: "blur(8px)",
WebkitBackdropFilter: "blur(8px)",
display: "flex",
alignItems: "center",
justifyContent: "center",
pointerEvents: "auto",
}}
onClick={() => setShowUploadOverlay(false)}
>
<div
style={{
position: "absolute",
top: "0px", // 헤더 높이만큼 아래로 (헤더는 약 80px)
left: 0,
right: 0,
bottom: 0,
zIndex: 40,
backgroundColor: "rgba(255, 255, 255, 0.01)",
backdropFilter: "blur(8px)",
WebkitBackdropFilter: "blur(8px)", // Safari 지원
pointerEvents: "auto",
}}
/>
{/* 2. Univer 영역 중앙의 업로드 UI */}
<div
style={{
position: "absolute",
top: "-100px", // 헤더 높이만큼 아래로
left: 0,
right: 0,
bottom: 0,
display: "flex",
alignItems: "center",
justifyContent: "center",
padding: "1rem",
zIndex: 50,
}}
className="max-w-2xl w-full"
style={{ transform: "scale(0.8)" }}
onClick={(e) => e.stopPropagation()}
>
<div
className="max-w-2xl w-full"
style={{ transform: "scale(0.8)" }}
className="bg-white rounded-lg shadow-xl border p-8 md:p-12"
style={{
backgroundColor: "#ffffff",
boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.25)",
}}
>
<div
className="bg-white rounded-lg shadow-xl border p-8 md:p-12"
style={{
backgroundColor: "#ffffff",
boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.25)",
}}
>
<div className="text-center">
{/* 아이콘 및 제목 */}
<div className="mb-8">
<div
className={cn(
"mx-auto h-20 w-20 md:h-24 md:w-24 rounded-full flex items-center justify-center mb-4",
isProcessing ? "bg-blue-100" : "bg-blue-50",
)}
>
{isProcessing ? (
<svg
className="h-10 w-10 md:h-12 md:w-12 text-blue-600 animate-spin"
fill="none"
viewBox="0 0 24 24"
>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
/>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
/>
</svg>
) : (
<svg
className="h-10 w-10 md:h-12 md:w-12 text-blue-600"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
/>
</svg>
)}
</div>
<h2 className="text-xl md:text-2xl font-semibold mb-2 text-gray-900">
{isProcessing
? "파일 처리 중..."
: "Excel 파일을 업로드하세요"}
</h2>
<p className="text-sm md:text-base text-gray-600 mb-6">
{isProcessing ? (
<span className="text-blue-600">
...
</span>
) : (
<>
<span className="font-medium text-gray-900">
.xlsx
</span>{" "}
</>
)}
</p>
</div>
{/* 드래그 앤 드롭 영역 */}
<div className="text-center">
{/* 아이콘 및 제목 */}
<div className="mb-8">
<div
className={cn(
"border-2 border-dashed rounded-lg p-8 md:p-12 transition-all duration-200 cursor-pointer",
"hover:border-blue-400 hover:bg-blue-50",
"focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2",
isDragOver
? "border-blue-500 bg-blue-100 scale-105"
: "border-gray-300",
isProcessing && "opacity-50 cursor-not-allowed",
"mx-auto h-20 w-20 md:h-24 md:w-24 rounded-full flex items-center justify-center mb-4",
isProcessing ? "bg-blue-100" : "bg-blue-50",
)}
onDragEnter={handleDragEnter}
onDragLeave={handleDragLeave}
onDragOver={handleDragOver}
onDrop={handleDrop}
onClick={handleFilePickerClick}
tabIndex={isProcessing ? -1 : 0}
role="button"
>
<div className="flex flex-col items-center justify-center space-y-4">
<div className="text-4xl md:text-6xl">
{isDragOver ? "📂" : "📄"}
</div>
<div className="text-center">
<p className="text-base md:text-lg font-medium mb-2 text-gray-900">
{isDragOver
? "파일을 여기에 놓으세요"
: "파일을 드래그하거나 클릭하세요"}
</p>
<p className="text-sm text-gray-600">
50MB까지
</p>
</div>
{isProcessing ? (
<svg
className="h-10 w-10 md:h-12 md:w-12 text-blue-600 animate-spin"
fill="none"
viewBox="0 0 24 24"
>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
/>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
/>
</svg>
) : (
<svg
className="h-10 w-10 md:h-12 md:w-12 text-blue-600"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
/>
</svg>
)}
</div>
<h2 className="text-xl md:text-2xl font-semibold mb-2 text-gray-900">
{isProcessing
? "파일 처리 중..."
: "Excel 파일을 업로드하세요"}
</h2>
<p className="text-sm md:text-base text-gray-600 mb-6">
{isProcessing ? (
<span className="text-blue-600">
...
</span>
) : (
<>
<span className="font-medium text-gray-900">
.xlsx
</span>{" "}
</>
)}
</p>
</div>
{/* 드래그 앤 드롭 영역 */}
<div
className={cn(
"border-2 border-dashed rounded-lg p-8 md:p-12 transition-all duration-200 cursor-pointer",
"hover:border-blue-400 hover:bg-blue-50",
"focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2",
isDragOver
? "border-blue-500 bg-blue-100 scale-105"
: "border-gray-300",
isProcessing && "opacity-50 cursor-not-allowed",
)}
onDragEnter={handleDragEnter}
onDragLeave={handleDragLeave}
onDragOver={handleDragOver}
onDrop={handleDrop}
onClick={handleFilePickerClick}
tabIndex={isProcessing ? -1 : 0}
role="button"
>
<div className="flex flex-col items-center justify-center space-y-4">
<div className="text-4xl md:text-6xl">
{isDragOver ? "📂" : "📄"}
</div>
<div className="text-center">
<p className="text-base md:text-lg font-medium mb-2 text-gray-900">
{isDragOver
? "파일을 여기에 놓으세요"
: "파일을 드래그하거나 클릭하세요"}
</p>
<p className="text-sm text-gray-600">
50MB까지
</p>
</div>
</div>
</div>
{/* 숨겨진 파일 입력 */}
<input
ref={fileInputRef}
type="file"
accept=".xlsx"
onChange={handleFileInputChange}
className="hidden"
disabled={isProcessing}
/>
{/* 숨겨진 파일 입력 */}
<input
ref={fileInputRef}
type="file"
accept=".xlsx"
onChange={handleFileInputChange}
className="hidden"
disabled={isProcessing}
/>
{/* 지원 형식 안내 */}
<div className="mt-6 text-xs text-gray-500">
<p> 형식: Excel (.xlsx)</p>
<p> 크기: 50MB</p>
<p className="mt-2 text-blue-600">
💡 window.__UNIVER_DEBUG__
</p>
</div>
{/* 지원 형식 안내 */}
<div className="mt-6 text-xs text-gray-500">
<p> 형식: Excel (.xlsx)</p>
<p> 크기: 50MB</p>
<p className="mt-2 text-blue-600">
💡 window.__UNIVER_DEBUG__
</p>
</div>
</div>
</div>
</div>
</>
</div>
)}
{/* 프롬프트 입력창 - Univer 위 오버레이 */}