Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(client): 랜딩페이지 퍼블리싱 #24

Merged
merged 18 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from 16 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
13 changes: 1 addition & 12 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,5 @@
"source.organizeImports": "explicit"
},
"editor.formatOnSave": true,
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
26 changes: 14 additions & 12 deletions apps/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,23 @@
},
"dependencies": {
"@jjoing/ui": "workspace:*",
"next": "^14.0.0",
"react": "18.3.1",
"react-dom": "18.3.1"
"next": "^14.0.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^5.3.0"
},
"devDependencies": {
"@jjoing/eslint-config": "workspace:*",
"@jjoing/typescript-config": "workspace:*",
"@types/node": "^20",
"@types/react": "^18.3.3",
"@types/react-dom": "^18",
"autoprefixer": "^10.4.20",
"eslint": "^8",
"eslint-config-next": "14.2.5",
"postcss": "^8.4.41",
"tailwindcss": "^3.4.9",
"typescript": "^5.5.4"
"@types/node": "^20.8.0",
"@types/react": "^18.2.23",
"@types/react-dom": "^18.2.7",
"autoprefixer": "^10.4.14",
"eslint": "^8.50.0",
"eslint-config-next": "^14.0.5",
"framer-motion": "^11.3.30",
"postcss": "^8.4.27",
"tailwindcss": "^3.3.3",
"typescript": "^5.2.2"
}
}
Empty file added apps/client/src/apis/.gitkeep
Empty file.
Binary file modified apps/client/src/app/favicon.ico
Binary file not shown.
23 changes: 23 additions & 0 deletions apps/client/src/app/fonts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import localFont from 'next/font/local';

export const pretendard = localFont({
src: [
{
path: '../assets/fonts/Pretendard/Pretendard-Regular.woff2',
weight: '400',
},
{
path: '../assets/fonts/Pretendard/Pretendard-Medium.woff2',
weight: '500',
},
{
path: '../assets/fonts/Pretendard/Pretendard-SemiBold.woff2',
weight: '600',
},
{
path: '../assets/fonts/Pretendard/Pretendard-Bold.woff2',
weight: '700',
},
],
variable: '--font-pretendard',
});
13 changes: 12 additions & 1 deletion apps/client/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
import { Footer, Header } from '@/components/layouts';
import Providers from '@/providers/Providers';
import '@/styles/globals.css';
import { PropsWithChildren } from 'react';
import { pretendard } from './fonts';

export const metadata = { title: '쪼잉' };

const RootLayout = ({ children }: PropsWithChildren) => {
return (
<html lang="kr">
<body>{children}</body>
<body className={`${pretendard.variable}`}>
<Providers>
<Header />
<div className="font-pretendard pt-[64px]">{children}</div>
<Footer />
</Providers>
</body>
</html>
);
};
Expand Down
4 changes: 3 additions & 1 deletion apps/client/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import LandingPage from '@/components/landing/landing';

export default function HomePage() {
return <></>;
return <LandingPage />;
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
3 changes: 3 additions & 0 deletions apps/client/src/assets/images/alarm-icon.svg
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 apps/client/src/assets/images/cooperation.webp
Binary file not shown.
3 changes: 3 additions & 0 deletions apps/client/src/assets/images/github-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions apps/client/src/assets/images/imagine-icon.svg
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 apps/client/src/assets/images/improveSkill.webp
Binary file not shown.
12 changes: 12 additions & 0 deletions apps/client/src/assets/images/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export { default as AlarmIcon } from './alarm-icon.svg';
export { default as Cooperation } from './cooperation.webp';
export { default as GithubIcon } from './github-icon.svg';
export { default as ImagineIcon } from './imagine-icon.svg';
export { default as ImproveSkillIcon } from './improveSkill.webp';
export { default as Interviewer1 } from './interviewer01.svg';
export { default as Interviewer2 } from './interviewer02.svg';
export { default as Interviewer3 } from './interviewer03.svg';
export { default as MainLogo } from './logo.svg';
export { default as MakeProjectIcon } from './makeProject.webp';
export { default as MouseIcon } from './mouse-icon.svg';
export { default as NetworkIcon } from './network.webp';
lsj0202 marked this conversation as resolved.
Show resolved Hide resolved
9 changes: 9 additions & 0 deletions apps/client/src/assets/images/interviewer01.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions apps/client/src/assets/images/interviewer02.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions apps/client/src/assets/images/interviewer03.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions apps/client/src/assets/images/logo.svg
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 apps/client/src/assets/images/makeProject.webp
Binary file not shown.
3 changes: 3 additions & 0 deletions apps/client/src/assets/images/mouse-icon.svg
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 apps/client/src/assets/images/network.webp
Binary file not shown.
3 changes: 3 additions & 0 deletions apps/client/src/components/landing/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { default as InterviewCard } from './interviewCard';
export { default as InterviewJJoing } from './interviewJJoing';
lsj0202 marked this conversation as resolved.
Show resolved Hide resolved
export { default as IntroduceJJoing } from './introduceJJoing';
63 changes: 63 additions & 0 deletions apps/client/src/components/landing/interviewCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
'use client';

import { Text } from '@jjoing/ui';
import { m } from 'framer-motion';
import Image from 'next/image';

type InterviewCardProps = {
id: number;
name: string;
developmentField: string;
inconvenience: string;
needs: string[];
icon: string;
};

const InterviewCard = ({
id,
name,
developmentField,
inconvenience,
needs,
icon,
}: InterviewCardProps) => {
return (
<m.div
className="border-2 border-lightPrimary w-[349px] h-[327px] rounded-3xl p-5 bg-white"
initial={{ opacity: 0, y: 50 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, ease: 'easeInOut', delay: id * 0.1 }}
>
<div className="flex border-b pb-3 border-gray-300 h-[185px]">
<div className="w-3/5 flex flex-col justify-evenly gap-5 mb-4">
<div className="flex flex-col gap-[2px]">
<Text size="md" weight="semibold">
{name}
</Text>
<Text size="sm" weight="medium">
{developmentField}
</Text>
</div>
<Text weight="medium" size="lg" className="leading-6 whitespace-pre-line">
"{inconvenience}"
</Text>
</div>
<Image src={icon} width={94} height={140} alt="icon" />
</div>
<div className="h-[100px] pt-3 flex flex-col">
<Text size="md" className="mb-3">
NEEDS
</Text>
<ul className="md:list-disc">
{needs.map((need, index) => (
<li className="ml-6 mt-1" key={index}>
{need}
</li>
))}
</ul>
</div>
</m.div>
);
};

export default InterviewCard;
38 changes: 38 additions & 0 deletions apps/client/src/components/landing/interviewJJoing.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { InterviewMeta } from '@/constants';
import { Text } from '@jjoing/ui';
import { RefObject } from 'react';
import { Container, Wrapper } from '../layouts';
import InterviewCard from './interviewCard';

type InterviewJJoingProps = {
mouseRef: RefObject<HTMLDivElement>;
};

const InterviewJJoing = ({ mouseRef }: InterviewJJoingProps) => {
return (
<Container className="h-[100vh] bg-white">
<Wrapper
className="h-full flex flex-col items-center justify-center gap-8"
ref={mouseRef}
>
<Text size="md" color="gray">
Interview
</Text>
<Text size="lg" className="text-center">
프로젝트를 함께 할 팀원, 찾기 어렵고 먼저 연락하기 망설여진 적이 있나요? <br />
<Text weight="medium" color="primary">
팀원을 구할 때 느꼈던 불편한 점
</Text>
에 대해 물어보았습니다.
</Text>
<div className="h-[380px] mt-10 w-[1082px] grid grid-cols-3 gap-[20px] items-center">
{InterviewMeta.map((interview) => (
<InterviewCard key={interview.id} {...interview} />
))}
</div>
</Wrapper>
</Container>
);
};

export default InterviewJJoing;
72 changes: 72 additions & 0 deletions apps/client/src/components/landing/introduceJJoing.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
'use client';

import { ImagineIcon, MouseIcon } from '@/assets/images';
import { Button, Text } from '@jjoing/ui';
import dynamic from 'next/dynamic';
import Image from 'next/image';
import { useRef } from 'react';
import { Container, Sticker, Wrapper } from '../layouts';

const InterviewJJoing = dynamic(() => import('./interviewJJoing'), {
ssr: false,
});

const IntroduceJJoing = () => {
const mouseRef = useRef<HTMLDivElement>(null);

const handleScroll = () => {
lsj0202 marked this conversation as resolved.
Show resolved Hide resolved
if (mouseRef.current) mouseRef.current.scrollIntoView({ behavior: 'smooth' });
};

return (
<>
<Container className="content-container bg-main-gradient">
<Wrapper className="flex h-full justify-between">
<div className="w-[416px] flex items-center">
<div className="w-full h-[450px] flex flex-col gap-10">
<Text color="gray800" size="xl" weight="semibold">
내가 원하는 <br />
최고의 팀원과 <br />
지금 바로
<Text size="xxl" weight="bold" color="primary" className="ml-3">
쪼잉
</Text>
<br />
</Text>
<Text size="lg" color="gray">
당신의 아이디어를 현실로 만들 팀원을 구해보세요! <br />
쪼잉은 더 나은 프로젝트 경험을 위해 시작되었습니다.
</Text>
<Button outline={true} round="3xl" size="md" className="text-gray-800">
시작하기 {'>'}
</Button>
</div>
</div>
<div className="flex items-end mb-8">
<div className="flex flex-col items-center gap-3" onClick={handleScroll}>
<div className="flex items-center justify-center rounded-[50%] size-12 bg-gray-100 cursor-pointer bounce">
<Image
src={MouseIcon}
layout="intrinsic"
width={20}
height={20}
alt="mouse-icon"
priority
/>
</div>
<Text size="xs" color="gray400">
스크롤을 내려주세요.
</Text>
</div>
</div>
<div className="w-[400px] flex items-end justify-end">
<Sticker stickerUrl={ImagineIcon} width={380} height={384} />
</div>
</Wrapper>
</Container>
<InterviewJJoing mouseRef={mouseRef} />
</>
);
};

export default IntroduceJJoing;
Loading
Loading