diff --git a/frontend/src/components/Header.module.css b/frontend/src/components/Header.module.css index c4b6c16c..226dd2e0 100644 --- a/frontend/src/components/Header.module.css +++ b/frontend/src/components/Header.module.css @@ -12,6 +12,7 @@ padding: 0 30px; gap: 30px; } + .brand { display: flex; align-items: center; @@ -37,10 +38,12 @@ border: none; cursor: pointer; padding: 0; + flex-shrink: 0; } .menuButton span { display: block; + width: 100%; height: 2px; background: white; border-radius: 2px; diff --git a/frontend/src/components/stockgame/Betting.jsx b/frontend/src/components/stockgame/Betting.jsx index 25fc2ec2..7b535d3d 100644 --- a/frontend/src/components/stockgame/Betting.jsx +++ b/frontend/src/components/stockgame/Betting.jsx @@ -1,47 +1,122 @@ import styles from './Betting.module.css'; -// import icon1 from '../../assets/at_icon_1.png'; +import icon1 from '../../assets/at_icon_1.png'; import StockInfoItem from './StockInfoItem'; import { useState, useEffect } from 'react'; import { dailyBet, weeklyBet } from '../../utils/bettingInfo'; +import { + getDailyBetHistory, + getWeeklyBetHistory, +} from '../../utils/bettingHistory'; +import { api } from '../../utils/axios'; -const DailyBetting = ({ period }) => { +const Betting = ({ period }) => { const [isBetting, setIsBetting] = useState('none'); - // const data = period === 'daily' ? mockDailyBet : mockWeeklyBet; - // const data = period === 'daily' ? dailyBet() : weeklyBet(); const [data, setData] = useState(null); + const [userBets, setUserBets] = useState(null); useEffect(() => { async function fetchData() { if (period === 'daily') { const res = await dailyBet(); setData(res); + const history = await getDailyBetHistory(); + setUserBets(history && history.length > 0 ? history[0] : null); } else { const res = await weeklyBet(); setData(res); + const history = await getWeeklyBetHistory(); + setUserBets(history && history.length > 0 ? history[0] : null); } } fetchData(); }, [period]); - const onClickUpBet = () => { + // userBets 또는 data가 바뀔 때 베팅 여부 체크 + useEffect(() => { + if (!data || !userBets) { + setIsBetting('none'); + return; + } + + if (data.betRoundId === userBets.betRoundId) { + userBets.option === 'RISE' ? setIsBetting('up') : setIsBetting('down'); + } else { + setIsBetting('none'); + } + }, [data, userBets]); + + const update = async () => { + const updatedData = + period === 'daily' ? await dailyBet() : await weeklyBet(); + setData(updatedData); + const history = + period === 'daily' + ? await getDailyBetHistory() + : await getWeeklyBetHistory(); + setUserBets(history && history.length > 0 ? history[0] : null); + }; + + const onClickUpBet = async () => { if (isBetting !== 'none') { alert('이미 베팅하셨습니다.'); } else if (confirm('상승에 베팅하시겠습니까?')) { - setIsBetting('up'); + try { + const res = await api.post('/api/user-bets', { + roundId: data.betRoundId, + option: 'RISE', + stakePoints: 0, + isFree: true, + }); + await update(); + alert('베팅이 완료되었습니다.'); + return res; + } catch (error) { + // 409 처리 + if (error.status === 409) { + alert('베팅 가능 시간이 아닙니다.'); + return; + } + alert('오류가 발생했습니다. 다시 시도해주세요.'); + return null; + } } }; - const onClickDownBet = () => { + const onClickDownBet = async () => { if (isBetting !== 'none') { alert('이미 베팅하셨습니다.'); } else if (confirm('하락에 베팅하시겠습니까?')) { - setIsBetting('down'); + try { + const res = await api.post('/api/user-bets', { + roundId: data.betRoundId, + option: 'FALL', + stakePoints: 0, + isFree: true, + }); + await update(); + alert('베팅이 완료되었습니다.'); + return res; + } catch (error) { + // 409 처리 + if (error.status === 409) { + alert('베팅 가능 시간이 아닙니다.'); + return; + } + alert('오류가 발생했습니다. 다시 시도해주세요.'); + return null; + } } }; - const onClickCancelBet = () => { + const onClickCancelBet = async () => { if (confirm('베팅을 취소하시겠습니까?')) { - setIsBetting('none'); + try { + await api.delete(`/api/user-bets/${userBets.userBetId}`); + await update(); + alert('베팅이 취소되었습니다.'); + } catch (error) { + alert(error.message); + } } }; @@ -58,12 +133,12 @@ const DailyBetting = ({ period }) => {