Skip to content

Commit

Permalink
Merge pull request #20 from Jr-YongFill/feature/stack/#17
Browse files Browse the repository at this point in the history
Feature/stack/#17
  • Loading branch information
github-actions[bot] authored Jul 28, 2024
2 parents c0634e7 + eb45a05 commit 9fb482b
Show file tree
Hide file tree
Showing 7 changed files with 291 additions and 17 deletions.
37 changes: 37 additions & 0 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"http-proxy-middleware": "^3.0.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-modal": "^3.16.1",
"react-router-dom": "^6.25.1",
"react-scripts": "5.0.1",
"styled-components": "^6.1.12",
Expand Down
Binary file added src/assets/default.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
160 changes: 155 additions & 5 deletions src/components/Store.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,165 @@
import React from 'react';
import React, { useEffect, useRef, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import Header from './Header';
import styled from 'styled-components';
import { baseAPI } from '../config';
import palette from '../styles/pallete';
import Modal from 'react-modal';

const Title = styled.div`
display: flex;
flex-direction: row;
justify-content: space-between;
// background-color: gold;
margin: 30px 50px;
`;

const Main = styled.div`
display: flex;
// background-color: gold;
margin: 0px 50px;
flex-direction: column;
align-items: center;
`;

const Content = styled.div`
display: grid;
margin: 20px 20px;
grid-template-columns: 1fr 1fr 1fr;
`;

const MyBtn = styled.button`
background-color: ${(props) => props.color};
border:none;
width: 300px;
height: 100px;
border-radius: 20px;
font-size: 30px;
font-weight: bold;
color: white;
margin: 30px;
`;

const ModalContent = styled.div`
display: flex;
flex-direction: column;
align-items: center;
`;

const ModalTextBox = styled.div`
margin-top: 30px;
font-size: 25px;
font-weight: bold;
`;

const Store = () => {
const memberId = 1;
const [credit, setCredit] = useState(0);
const [stacks, setStacks] = useState(null);
const [modalSwitch, setModalSwitch] = useState(false);
const [modalStack, setModalStack] = useState(null);
const myModalTextBoxRef = useRef(null);
const myModalBtnRef = useRef(null);
const navigate = useNavigate(); // useNavigate를 호출

const fetchMemberCredit = async () => {
const response = await baseAPI.get(`/api/members/${memberId}/credits`);
}

const fetchPurchasStack = async (stackId) => {
try {
await baseAPI.post(`/api/stacks/${stackId}`);
window.location.reload();
} catch (err) {
myModalTextBoxRef.current.style.color = 'red';
myModalTextBoxRef.current.innerText = '크레딧이 부족합니다.';
myModalBtnRef.current.innerText = '닫기';
myModalBtnRef.current.addEventListener('click', () => { setModalSwitch(false); });
}
}

const fetchMemberStack = async () => {
const response = await baseAPI.get(`/api/members/${memberId}/stacks`);
setStacks(response.data);
}

useEffect(() => {
fetchMemberStack();
}, []);

return (
<div>
<>
<Header />
<h2>상점</h2>
<button onClick={() => navigate('/interview/main')}>면접 메인</button>
</div>
<Title>
<h1>Stack 상점</h1>
<h1>내 크레딧: {credit}</h1>
</Title>
<Main>
<Content>
{stacks && stacks.map((stack, idx) => {
return <MyBtn
key={idx}
color={stack.isPurchase ? palette.skyblue : palette.gray}
onClick={() => {
setModalSwitch(true);
setModalStack(stacks.at(idx));
}}
>{stack.stackName}</MyBtn>
})}
</Content>
<MyBtn color={palette.skyblue} onClick={() => navigate('/interview/main')}>면접 보러가기</MyBtn>
<Modal
isOpen={modalSwitch}
onRequestClose={() => setModalSwitch(false)}
style={{
content: {
top: '200px',
left: '500px',
right: '500px',
bottom: '200px',
borderRadius: '30px',
border: 'none',
background: `${palette.pink}`,
}
}}>
{modalStack &&
<ModalContent>
{
modalStack.isPurchase ?
<>
<ModalTextBox style={{ 'margin-bottom': '125px' }}>
이미 구매한 질문입니다.
</ModalTextBox>
<MyBtn
color={palette.skyblue}
onClick={() => setModalSwitch(false)}>
닫기
</MyBtn>
</>
:
<>
<ModalTextBox ref={myModalTextBoxRef}>
해당 질문 카테고리를 구매하시겠습니까?
</ModalTextBox>
<ModalTextBox>
{modalStack.stackName} : {modalStack.description}
</ModalTextBox>
<ModalTextBox>
포인트 : {modalStack.price}
</ModalTextBox>
<MyBtn
ref={myModalBtnRef}
color={palette.skyblue}
onClick={() => {
fetchPurchasStack(modalStack.id);
}}>
구매
</MyBtn>
</>}
</ModalContent>}
</Modal>
</Main >
</>
);
};

Expand Down
96 changes: 91 additions & 5 deletions src/components/interview/InterviewMain.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,103 @@
import React from 'react';
import { useNavigate } from 'react-router-dom';
import Header from '../Header';
import palette from '../../styles/pallete';
import styled from 'styled-components';
import img from '../../assets/default.png';

const Title = styled.div`
display: flex;
flex-direction: row;
justify-content: space-between;
// background-color: gold;
margin: 50px 150px;
`;

const TitleTextGroup = styled.div`
`;

const BtnGroup = styled.div`
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
`;

const BtnBox = styled.div`
display: flex;
flex-direction: column;
margin-left: 50px;
margin-right: 50px;
`;

const MyBtn = styled.button`
background-color: ${(props) => props.color};
border:none;
width: 300px;
height: 100px;
border-radius: 20px;
font-size: 30px;
font-weight: bold;
color: white;
`;

const InterviewMain = () => {
const navigate = useNavigate(); // useNavigate를 호출
return (
<div>
<>
<Header />
<h2>면접 메인 페이지</h2>
<button onClick={() => navigate('/interview/practice-choice-stack')}>연습 선택 스택</button>
<button onClick={() => navigate('/interview/choice-stack')}>면접 선택 스택</button>
</div>
<Title>
<TitleTextGroup>
<div style={{
'font-size': '60px',
'font-weight': 'bold',
}}>
면접 시뮬레이션
</div>
<div style={{
'margin-top': '40px',
'font-size': '30px',
'font-weight': 'bold',
}}>
CS 면접, 잘 준비 되셨나요?<br />
아는 만큼 대답해주세요!<br /><br />
GPT가 면접 답변을 평가해줘요!
</div>
<div style={{
'margin-top': '10px',
'font-size': '20px',
'color': '#A4A4A4'
}}>
기능 사용을 위해서는 Open AI API키가 필요합니다.<br /><br />
API키 생성 방법
</div>
</TitleTextGroup>
<img src={img} width={'20%'} alt={'기본 이미지'}></img>
</Title>
<BtnGroup>
<BtnBox>
<MyBtn color={palette.skyblue} onClick={() => navigate('/interview/practice-choice-stack')}>연습 선택 스택</MyBtn>
<div style={{
'margin-top': '10px',
'font-size': '20px',
'color': '#A4A4A4'
}}>
# 무한모드 #1문제씩_정답_확인가능
</div>
</BtnBox>
<BtnBox>
<MyBtn color={palette.skyblue} onClick={() => navigate('/interview/choice-stack')}>면접 선택 스택</MyBtn>
<div style={{
'margin-top': '10px',
'font-size': '20px',
'color': '#A4A4A4'
}}>
# 10개씩 #한번에_정답_확인가능
</div>
</BtnBox>
</BtnGroup>
</>
);
};

Expand Down
4 changes: 1 addition & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
<App />
);

// If you want to start measuring performance in your app, pass a function
Expand Down
10 changes: 6 additions & 4 deletions src/styles/pallete.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const palette = {
skyblue: '#B6CCED',
blue:'#1C61C9',
};
export default palette;
skyblue: '#B6CCED',
gray: '#C0C5CD',
blue: '#1C61C9',
pink: '#FFF7F7',
};
export default palette;

0 comments on commit 9fb482b

Please sign in to comment.