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

[FE] 브랜치 병합 #44

Merged
merged 24 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
e4b6655
✨ feat: 상위 5개 리스트 컴포넌트 구현 #5
dannysir Nov 5, 2024
80b2f08
✨ feat: 상위 항목 네비게이션바 생성 #5
dannysir Nov 5, 2024
3fcc476
✨ feat: 네비게이션바 애니메이션 추가 #5
dannysir Nov 5, 2024
0f45de7
✨ feat: 헤더 레이아웃 생성 #5
dannysir Nov 5, 2024
df8a435
💄 design: 헤더 위치를 위해 패딩 추가 #5
dannysir Nov 5, 2024
853b6d2
🎨 style: prettier 설정 & 적용 / 코드 스타일 변경. #5
dannysir Nov 5, 2024
220aa9f
Merge pull request #24 from boostcampwm-2024/feature/layout/topfive-#5
dongree Nov 5, 2024
f1f543a
✨ feat: 로그인 레이아웃 구성 #1
dongree Nov 5, 2024
edfe779
✨ feat: 로그인 레이아웃 toggle 기능 구현 #1
dongree Nov 5, 2024
7741678
Merge pull request #25 from boostcampwm-2024/feature/layout/login-#1
dannysir Nov 6, 2024
8311987
✨ feat: 차트 그리기 #3
dannysir Nov 6, 2024
1ae2e02
Merge pull request #31 from boostcampwm-2024/feature/layout/chart-#3
dongree Nov 6, 2024
569a538
💄 design: chart design 개선 #3
dongree Nov 6, 2024
d3dcdd9
🎨 style: 파일, 폴더 분리 및 코드 구조 단순화 #3
dongree Nov 6, 2024
25af9c1
💄 design: 상승, 하락에 따른 차트 색상 변경 #3
dongree Nov 6, 2024
0f27228
Merge pull request #34 from boostcampwm-2024/feature/layout/chart2-#3
dannysir Nov 6, 2024
4665800
✨ feat: login API 연동 #4
dongree Nov 7, 2024
90e876f
✨ feat: accssToken 전역으로 상태 관리 #4
dongree Nov 7, 2024
a031b4d
✨ feat: 상위/하위 목록 API 연동 & 스타일 변경 #11
dannysir Nov 7, 2024
3c120a0
💄 design: 회원가입 ui 제거, overlay 투명도 높이기
dongree Nov 7, 2024
3388d71
⚙️ chore: console.log 제거 및 사용하지 않는 id 제거
dongree Nov 7, 2024
bffb800
💄design: 카드 컴포넌트 스타일 수정 #11
dannysir Nov 7, 2024
bea670e
Merge pull request #40 from boostcampwm-2024/feature/connect/login-#4
dannysir Nov 7, 2024
6a593bf
Merge pull request #39 from boostcampwm-2024/feature/connect/topfive-#11
dongree Nov 7, 2024
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
1 change: 1 addition & 0 deletions FE/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"semi": true,"singleQuote": true,"trailingComma": "all","printWidth": 80,"tabWidth": 2,"bracketSpacing": true,"jsxSingleQuote": true,"jsxBracketSameLine": false,"arrowParens": "always","plugins": ["prettier-plugin-tailwindcss"]}
25 changes: 13 additions & 12 deletions FE/eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
import js from "@eslint/js";
import globals from "globals";
import reactHooks from "eslint-plugin-react-hooks";
import reactRefresh from "eslint-plugin-react-refresh";
import tseslint from "typescript-eslint";

export default tseslint.config(
{ ignores: ['dist'] },
{ ignores: ["dist"] },
{
extends: [js.configs.recommended, ...tseslint.configs.recommended],
files: ['**/*.{ts,tsx}'],
files: ["**/*.{ts,tsx}"],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
plugins: {
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
"react-hooks": reactHooks,
"react-refresh": reactRefresh,
},
rules: {
...reactHooks.configs.recommended.rules,
'react-refresh/only-export-components': [
'warn',
"react-refresh/only-export-components": [
"warn",
{ allowConstantExport: true },
],
quotes: ["error", "single"],
},
},
)
);
104 changes: 104 additions & 0 deletions FE/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions FE/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"preview": "vite preview"
},
"dependencies": {
"@heroicons/react": "^2.1.5",
"@tanstack/react-query": "^4.36.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
Expand All @@ -28,6 +29,8 @@
"eslint-plugin-react-refresh": "^0.4.14",
"globals": "^15.11.0",
"postcss": "^8.4.47",
"prettier": "^3.3.3",
"prettier-plugin-tailwindcss": "^0.6.8",
"tailwindcss": "^3.4.14",
"typescript": "~5.6.2",
"typescript-eslint": "^8.11.0",
Expand Down
Binary file added FE/public/Logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion FE/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ function App() {
return (
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path='/' element={<Home />} />
</Routes>
</Router>
);
Expand Down
54 changes: 53 additions & 1 deletion FE/src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,55 @@
import useAuthStore from 'store/authStore';
import useLoginModalStore from 'store/useLoginModalStore';

export default function Header() {
return <div>header</div>;
const { toggleModal } = useLoginModalStore();
const { isLogin, resetToken } = useAuthStore();

return (
<header className='fixed left-0 top-0 h-[60px] w-full'>
<div className='mx-auto flex h-full max-w-[1280px] items-center justify-between px-[88px]'>
<div className='flex items-center gap-2'>
<img src={'../public/Logo.png'} className={'h-[32px]'} />
<h1 className='text-xl font-bold text-juga-grayscale-black'>JuGa</h1>
</div>

<div className='flex items-center gap-8'>
<nav className='flex items-center gap-6 text-sm font-bold text-juga-grayscale-500'>
<button className='px-0.5 py-2'>홈</button>
<button className='px-0.5 py-2'>랭킹</button>
<button className='px-0.5 py-2'>마이페이지</button>
</nav>
<div className='relative'>
<input
type='text'
placeholder='Search...'
className='h-[36px] w-[280px] rounded-lg bg-juga-grayscale-50 px-4 py-2'
/>
</div>
</div>
<div className='flex items-center gap-4'>
{isLogin ? (
<button
className='px-4 py-2 text-sm text-juga-grayscale-500'
onClick={resetToken}
>
로그아웃
</button>
) : (
<>
<button
className='px-4 py-2 text-sm text-juga-grayscale-500'
onClick={toggleModal}
>
로그인
</button>
{/* <button className='px-4 py-2 text-sm text-white rounded-lg bg-juga-grayscale-black'>
회원가입
</button> */}
</>
)}
</div>
</div>
</header>
);
}
12 changes: 12 additions & 0 deletions FE/src/components/Login/Input.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { ComponentProps } from 'react';

type LoginInputProps = ComponentProps<'input'>;

export default function Input({ ...props }: LoginInputProps) {
return (
<input
className='px-4 py-2 text-sm border-2 rounded-lg outline-none'
{...props}
/>
);
}
72 changes: 72 additions & 0 deletions FE/src/components/Login/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import useLoginModalStore from 'store/useLoginModalStore';
import Input from './Input';
import { ChatBubbleOvalLeftIcon } from '@heroicons/react/16/solid';
import { FormEvent, useEffect, useState } from 'react';
import { login } from 'service/auth';
import useAuthStore from 'store/authStore';

export default function Login() {
const { isOpen, toggleModal } = useLoginModalStore();
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const { setAccessToken } = useAuthStore();

useEffect(() => {
setEmail('');
setPassword('');
}, [isOpen]);

if (!isOpen) return;

const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
const res = await login(email, password);

if ('error' in res) {
return;
}

setAccessToken(res.accessToken);
toggleModal();
};

return (
<>
<Overay onClick={() => toggleModal()} />
<section className='fixed left-1/2 top-1/2 flex w-[500px] -translate-x-1/2 -translate-y-1/2 flex-col rounded-2xl bg-white p-20 shadow-lg'>
<h2 className='text-3xl font-bold'>JuGa</h2>
<form className='flex flex-col mb-2' onSubmit={handleSubmit}>
<div className='flex flex-col gap-2 my-10'>
<Input
type='text'
placeholder='아이디'
value={email}
onChange={(e) => setEmail(e.target.value)}
autoComplete='username'
/>
<Input
type='password'
placeholder='비밀번호'
value={password}
onChange={(e) => setPassword(e.target.value)}
autoComplete='current-password'
/>
</div>
<button className='py-2 text-white transition rounded-3xl bg-juga-blue-40 hover:bg-juga-blue-50'>
로그인
</button>
</form>
<button className='flex items-center justify-center gap-2 rounded-3xl bg-yellow-300 px-3.5 py-2 transition hover:bg-yellow-400'>
<ChatBubbleOvalLeftIcon className='size-5' />
<p>카카오 계정으로 로그인</p>
</button>
</section>
</>
);
}

function Overay({ onClick }: { onClick: () => void }) {
return (
<div className='fixed inset-0 bg-black opacity-30' onClick={onClick}></div>
);
}
49 changes: 49 additions & 0 deletions FE/src/components/StockIndex/Chart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { useEffect, useRef, useState } from 'react';
import { drawChart } from 'utils/chart';

const X_LENGTH = 79;

type StockIndexChartProps = {
name: string;
};

export function Chart({ name }: StockIndexChartProps) {
const [prices, setPrices] = useState<number[]>([50, 54]);
const canvasRef = useRef<HTMLCanvasElement>(null);

useEffect(() => {
const interval = setInterval(() => {
if (prices.length === X_LENGTH) {
clearInterval(interval);
return;
}
setPrices((prev) => [...prev, Math.floor(Math.random() * 50) + 25]);
}, 500);

return () => clearInterval(interval);
}, [prices.length]);

useEffect(() => {
const canvas = canvasRef.current;
const ctx = canvas?.getContext('2d');
if (!ctx) return;

drawChart(ctx, prices);
}, [prices]);

return (
<div className='flex h-[200px] w-[500px] items-center rounded-lg bg-juga-grayscale-50 p-5'>
<div className='flex flex-col items-start justify-center flex-1 h-full gap-1 text-sm'>
<p className='text-lg font-semibold'>{name}</p>
<p className='text-2xl font-bold'>2562.4</p>
<p className='font-semibold text-juga-blue-40'>-31.55(-1.2%)</p>
</div>
<canvas
ref={canvasRef}
width={600}
height={300}
className='flex-1 h-full'
/>
</div>
);
}
Loading