Skip to content

Commit

Permalink
Merge pull request #46 from boostcampwm-2024/dev
Browse files Browse the repository at this point in the history
Week01 마무리 배포 (11.08)
  • Loading branch information
jinddings authored Nov 11, 2024
2 parents d5e7764 + 7e17156 commit 123b608
Show file tree
Hide file tree
Showing 24 changed files with 643 additions and 16 deletions.
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

0 comments on commit 123b608

Please sign in to comment.