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
Binary file added public/images/landing/landing_mobile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/landing/landing_tablet.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
410 changes: 283 additions & 127 deletions src/app/_components/common/Header.tsx

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/app/_components/common/LoginModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const LoginModal = ({ open, onClose }: LoginModalProps) => {
onClick={onClose}
aria-hidden="true"
/>
<div className="absolute inset-0 flex items-center justify-center">
<div className="absolute inset-0 flex items-start justify-center overflow-y-auto pt-[100px] pb-10 lg:items-center lg:pt-0">
<div className="relative w-full max-w-[480px] rounded-[20px] bg-white p-[42px] shadow-[0_0_20px_0_rgba(0,0,0,0.15)]">
<button
onClick={onClose}
Expand Down
181 changes: 181 additions & 0 deletions src/app/_components/common/MobileLoginScreen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
'use client';
import React, { useEffect, useState } from 'react';
import CloseIcon from '@/assets/icons/close.svg';
import MainLogo from '@/assets/icons/main_logo.svg';
import Check from '@/assets/icons/white_check.svg';
import Kakao from '@/assets/icons/kakao.svg';
import KakaoActive from '@/assets/icons/kakao_active.svg';
import Naver from '@/assets/icons/naver.svg';
import NaverActive from '@/assets/icons/naver_active.svg';

type MobileLoginScreenProps = {
open: boolean;
onClose: () => void;
};

const MobileLoginScreen = ({ open, onClose }: MobileLoginScreenProps) => {
const [agreeToTerms1, setAgreeToTerms1] = useState(false);
const [agreeToTerms2, setAgreeToTerms2] = useState(false);
const isAllAgreed = agreeToTerms1 && agreeToTerms2;

useEffect(() => {
if (!open) {
setAgreeToTerms1(false);
setAgreeToTerms2(false);
return;
}
document.body.style.overflow = 'hidden';
const onKeyDown = (e: KeyboardEvent) => {
if (e.key === 'Escape') onClose();
};
window.addEventListener('keydown', onKeyDown);
return () => {
document.body.style.overflow = '';
window.removeEventListener('keydown', onKeyDown);
};
}, [open, onClose]);

if (!open) return null;

const handleKakaoLogin = () => {
const backendUrl = process.env.NEXT_PUBLIC_BASE_URL;
const oauthUrl = `${backendUrl}/oauth2/authorization/kakao`;
window.location.href = oauthUrl;
};

const handleNaverLogin = () => {
const backendUrl = process.env.NEXT_PUBLIC_BASE_URL;
const oauthUrl = `${backendUrl}/oauth2/authorization/naver`;
window.location.href = oauthUrl;
};

return (
<div className="fixed inset-0 z-[200] bg-white md:[display:none]">
{/* Close Button */}
<button
onClick={onClose}
className="absolute top-4 right-4 cursor-pointer"
aria-label="닫기"
>
<CloseIcon />
</button>

{/* Content */}
<div className="flex flex-col items-center px-[42px] pt-[140px]">
<div className="flex flex-col items-center gap-9">
<MainLogo />

<div className="flex flex-col items-center gap-2">
<h2 className="text-[24px] font-bold leading-[1.5] tracking-[-0.48px] text-gray-900">
로그인/회원가입
</h2>
<p className="text-[16px] font-medium leading-[1.5] tracking-[-0.16px] text-gray-600">
로그인 후 스타라이트의 모든 기능을 이용하세요
</p>
</div>

<div className="flex w-full flex-col gap-3">
<div className="flex items-center justify-between">
<p className="text-[14px] font-medium leading-[1.5] text-gray-500">
서비스 이용약관에 동의합니다.{' '}
<a
href="https://marked-lift-a34.notion.site/29e6dc10381580dd8a1fff635ed3300f?source=copy_link"
target="_blank"
rel="noopener noreferrer"
className="underline underline-offset-2"
aria-label="서비스 이용약관 보기"
>
(약관 보기)
</a>
</p>
{agreeToTerms1 ? (
<div
className="bg-primary-500 flex h-6 w-6 flex-shrink-0 cursor-pointer items-center justify-center rounded-[5.3px]"
onClick={() => setAgreeToTerms1(false)}
>
<Check />
</div>
) : (
<div
className="h-6 w-6 flex-shrink-0 cursor-pointer rounded-[5.3px] border-[1.44px] border-gray-400"
onClick={() => setAgreeToTerms1(true)}
/>
)}
</div>
<div className="flex items-center justify-between">
<p className="text-[14px] font-medium leading-[1.5] text-gray-500">
개인정보 처리방침에 동의합니다.{' '}
<a
href="https://marked-lift-a34.notion.site/29e6dc103815807cbd1cc93cd14ef38e?source=copy_link"
target="_blank"
rel="noopener noreferrer"
className="underline underline-offset-2"
aria-label="개인정보 처리방침 약관 보기"
>
(약관 보기)
</a>
</p>
{agreeToTerms2 ? (
<div
className="bg-primary-500 flex h-6 w-6 flex-shrink-0 cursor-pointer items-center justify-center rounded-[5.3px]"
onClick={() => setAgreeToTerms2(false)}
>
<Check />
</div>
) : (
<div
className="h-6 w-6 flex-shrink-0 cursor-pointer rounded-[5.3px] border-[1.44px] border-gray-400"
onClick={() => setAgreeToTerms2(true)}
/>
)}
</div>
</div>

<div className="flex w-full flex-col gap-3">
<button
type="button"
onClick={handleKakaoLogin}
disabled={!isAllAgreed}
className={`flex h-[44px] w-full items-center justify-center gap-3 rounded-lg transition-colors ${
isAllAgreed
? 'cursor-pointer bg-[#FEE500] hover:bg-[#FDD835]'
: 'cursor-not-allowed bg-gray-200'
}`}
>
{isAllAgreed ? <KakaoActive /> : <Kakao />}
<span
className={`text-[16px] font-medium ${
isAllAgreed ? 'text-gray-900' : 'text-gray-500'
}`}
>
카카오 로그인
</span>
</button>

<button
type="button"
onClick={handleNaverLogin}
disabled={!isAllAgreed}
className={`flex h-[44px] w-full items-center justify-center gap-3 rounded-lg transition-colors ${
isAllAgreed
? 'cursor-pointer bg-[#03C75A] hover:bg-[#02B350]'
: 'cursor-not-allowed bg-gray-200'
}`}
>
{isAllAgreed ? <NaverActive /> : <Naver />}
<span
className={`text-[16px] font-medium ${
isAllAgreed ? 'text-white' : 'text-gray-500'
}`}
>
네이버 로그인
</span>
</button>
</div>
</div>
</div>
</div>
);
};

export default MobileLoginScreen;
45 changes: 45 additions & 0 deletions src/app/_components/common/MobileNavAlertModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
'use client';
import React from 'react';
import ErrorIcon from '@/assets/icons/error.svg';

type MobileNavAlertModalProps = {
open: boolean;
onClose: () => void;
};

const MobileNavAlertModal = ({ open, onClose }: MobileNavAlertModalProps) => {
if (!open) return null;

return (
<div className="fixed inset-0 z-[200] lg:[display:none]">
<div
className="absolute inset-0 bg-black/20"
onClick={onClose}
aria-hidden="true"
/>
<div className="absolute inset-0 flex items-center justify-center px-8">
<div className="flex w-[326px] flex-col items-center gap-6 rounded-[20px] bg-white px-6 pt-8 pb-6 md:w-[377px] md:rounded-xl md:px-6">
<ErrorIcon />
<div className="flex w-full flex-col gap-2">
<p className="text-center text-[18px] font-semibold leading-[1.5] tracking-[-0.36px] text-gray-900 md:text-[20px] md:tracking-[-0.4px]">
PC환경에서 서비스를 이용해주세요
</p>
<div className="flex flex-col items-center text-[14px] font-medium leading-[1.5] text-gray-600">
<p>모바일 환경에서는 지원되지 않습니다.</p>
<p>안정적인 경험을 위해 데스크탑 환경을 권장해요!</p>
</div>
</div>
<button
type="button"
onClick={onClose}
className="bg-primary-500 w-full cursor-pointer rounded-lg py-[10px] text-[16px] font-medium leading-[1.5] tracking-[-0.16px] text-white transition-colors hover:bg-primary-600"
>
닫기
</button>
</div>
</div>
</div>
);
};

export default MobileNavAlertModal;
22 changes: 12 additions & 10 deletions src/app/_components/landing/Landing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,19 @@ const Landing = () => {

return (
<>
<div className="relative flex flex-col items-center text-center font-semibold text-white">
<p className="text-5xl">막막한 사업계획서 작성,</p>
<p className="mt-6 text-5xl">스타라이트와 함께 하세요</p>
<div className="ds-title mt-[18px] font-semibold text-white">
<div className="relative flex flex-col items-center px-5 text-center font-semibold text-white md:px-8 lg:px-0">
<p className="text-[28px] leading-[150%] md:text-5xl lg:text-5xl">
막막한 사업계획서 작성,
<br />
스타라이트와 함께 하세요
</p>
<div className="ds-text mt-[18px] font-semibold text-white md:ds-title lg:ds-title lg:mt-[18px]">
AI와 전문가가 함께하는 사업계획서 플랫폼
</div>

<div ref={ctaRef} className="mt-8 flex gap-3">
<div ref={ctaRef} className="mt-6 hidden w-full flex-col gap-3 md:mt-8 md:flex md:w-auto md:flex-row">
<button
className="bg-primary-500 ds-text hover:bg-primary-600 active:bg-primary-700 h-[50px] w-[220px] cursor-pointer rounded-full px-8 font-medium text-white"
className="bg-primary-500 ds-subtext hover:bg-primary-600 active:bg-primary-700 h-[44px] w-full cursor-pointer rounded-full px-6 font-medium text-white md:ds-text md:h-[50px] md:w-[220px] md:px-8"
onClick={() => {
if (isAuthenticated) {
router.push('/business');
Expand All @@ -42,7 +45,7 @@ const Landing = () => {
사업계획서 작성하기
</button>
<button
className="ds-text h-[50px] cursor-pointer rounded-full bg-white px-8 font-semibold text-gray-900 hover:bg-gray-100 active:bg-gray-200"
className="ds-subtext h-[44px] w-full cursor-pointer rounded-full bg-white px-6 font-semibold text-gray-900 hover:bg-gray-100 active:bg-gray-200 md:ds-text md:h-[50px] md:w-auto md:px-8"
onClick={() => {
if (isAuthenticated) {
setIsModalOpen(true);
Expand All @@ -54,14 +57,13 @@ const Landing = () => {
PDF 업로드하고 채점받기
</button>
</div>

<div className="pointer-events-none absolute top-full left-1/2 mt-20 -translate-x-1/2">
<div className="pointer-events-none absolute top-full left-1/2 mt-12 w-[358px] -translate-x-1/2 md:mt-16 md:w-[640px] lg:mt-20 lg:w-[912px]">
<Image
src="/images/landing/homeimage.png"
alt="홈화면 이미지"
width={912}
height={560}
className="w-[90vw] max-w-[912px]"
className="h-auto w-full"
priority
unoptimized={true}
/>
Expand Down
Loading