Skip to content

Commit 3fbf78c

Browse files
authored
스크립트 연습 구현 (#52)
* 스크립트 연습 라우터 연결 * 영어 입력 활성화 * 영어 오타 분석 추출 기능 구현 * 스크립트 연습 결과창 연동 구현 * 스크립트 연습 진행 정보창 업데이트 * 스크립트 연습 결과 최종 정보 출력 구현 * 스크립트 연습 구현 완료 * 전체적인 ui 개선
1 parent e5dc7b6 commit 3fbf78c

23 files changed

+470
-46
lines changed

front/src/App.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import ParagraphPractice from "./features/practices/paragraphs";
88
import WordPractice from "./features/practices/words";
99
import KeyPractice from "./features/practices/keys";
1010
import PracticeSentence from "./features/practices/sentences/PracticeSentence"
11+
import PracticeScript from "./features/practices/scripts/PracticeScript"
12+
import PracticeResult from "./components/PracticeResult"
1113

1214
function App() {
1315
return (
@@ -21,7 +23,10 @@ function App() {
2123
<Route exact path="/" component={ParagraphPractice} />
2224
<Route exact path="/practice-key" component={KeyPractice} />
2325
<Route exact path="/practice-word" component={WordPractice} />
24-
<Route path="/practice-sentence" component={PracticeSentence} />
26+
<Route exact path="/practice-sentence" component={PracticeSentence} />
27+
<Route exact path="/practice-script/list" component={ShowScript} />
28+
<Route path="/practice-script" component={PracticeScript} />
29+
<Route exact path="/practice-result" component={PracticeResult} />
2530
</Switch>
2631
</main>
2732
</Router>

front/src/app/store.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ import keyboardsReducer from '../features/keyboards/KeyboardsSlice';
33
import wordsReducer from '../features/practices/words/wordsSlice';
44
import keysReducer from '../features/practices/keys/keysSlice';
55
import sentenceReducer from '../features/practices/sentences/sentenceSlice';
6+
import scriptReducer from '../features/practices/scripts/scriptSlice';
67

78
export default configureStore({
89
reducer: {
910
keyboards: keyboardsReducer,
1011
words: wordsReducer,
1112
keys: keysReducer,
1213
sentence: sentenceReducer,
14+
script: scriptReducer,
1315
}
1416
});

front/src/components/DetailMenu.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ function DetailMenu({onChoose}) {
2525
href: '/practice-word' },
2626
{ title: '문장연습',
2727
href: '/practice-sentence' },
28-
{ title: '스크팁트 연습',
29-
href: '/practice-script' }];
28+
{ title: '스크립트 연습',
29+
href: '/practice-script/list' }];
3030
const PracticeList = PracticeModes.map((menu,index) =>
3131
<Link id = 'detail' to = {menu.href} key = {index}>
3232
<li id='list'>{menu.title}</li>

front/src/components/PracticeBox.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ import '../sass/main.css'
33
import PropTypes from 'prop-types';
44
import ProgressBox from '../components/ProgressBox';
55
import PracticeSentenceTask from '../features/practices/sentences/PracticeSentenceTask';
6+
import PracticeScriptTask from '../features/practices/scripts/PracticeScriptTask';
67

7-
function PracticeBox({information}) {
8+
function PracticeBox({type, information}) {
89
const boxes = information.map((item, index) => (
910
<ProgressBox
1011
key={index}
@@ -16,12 +17,14 @@ function PracticeBox({information}) {
1617
return (
1718
<div className="practice-box">
1819
<div className="practice-info">{boxes}</div>
19-
<PracticeSentenceTask />
20+
{type == "sentence" && <PracticeSentenceTask />}
21+
{type == "script" && <PracticeScriptTask />}
2022
</div>
2123
);
2224
}
2325

2426
PracticeBox.propTypes = {
27+
type: PropTypes.string,
2528
information: PropTypes.array,
2629
};
2730

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import React from "react";
2+
import "../sass/main.css";
3+
import { useLocation } from "react-router-dom";
4+
5+
function PracticeResult() {
6+
const location = useLocation();
7+
return (
8+
<div className="ScriptList">
9+
최종 타수 : {location.state.typeSpeed}
10+
<ul className="ScriptListItem">
11+
{location.state.scriptList.map((item, idx) => {
12+
return <li key={idx}>{item.name}</li>;
13+
})}
14+
</ul>
15+
</div>
16+
);
17+
}
18+
19+
export default PracticeResult;

front/src/components/ProgressBox.js

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,35 @@ import ProgressBar from "@ramonak/react-progress-bar";
55

66
function ProgressBox ({title, figure, id}) {
77
var progressPercent = String(figure).replace("%", '');
8-
return (
9-
<div className='progress-box' id = {id}>
10-
<div className='left-content'>
11-
<div className='title'>{title}</div>
12-
<div className='progress-border'>
13-
<ProgressBar
14-
completed={progressPercent}
15-
bgColor='#7BC5C5'
16-
baseBgColor='#FFFFFF'
17-
borderRadius='2px'
18-
isLabelVisible={false}/>
8+
if (title == "스크립트명")
9+
return (
10+
<div className="progress-box" id={id}>
11+
<div className="left-content">
12+
<div className="title">{title}</div>
13+
<div className="text-box">
14+
<div className="name">{figure}</div>
15+
</div>
1916
</div>
2017
</div>
21-
<div className='figure'>{figure}</div>
22-
</div>
23-
);
18+
);
19+
else
20+
return (
21+
<div className="progress-box" id={id}>
22+
<div className="left-content">
23+
<div className="title">{title}</div>
24+
<div className="progress-border">
25+
<ProgressBar
26+
completed={progressPercent}
27+
bgColor="#7BC5C5"
28+
baseBgColor="#FFFFFF"
29+
borderRadius="2px"
30+
isLabelVisible={false}
31+
/>
32+
</div>
33+
</div>
34+
<div className="figure">{figure}</div>
35+
</div>
36+
);
2437
}
2538

2639
ProgressBox.propTypes = {

front/src/components/Title.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ function Title({title}) {
1414
}
1515

1616
const TitleStyle = {
17-
width: '100%',
17+
width: '94%',
1818
color: '#828282',
1919
fontWeight: '400',
2020
fontSize: '27.5px',

front/src/features/practices/keys/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import ProgressBar from "@ramonak/react-progress-bar";
2525
import useSound from 'use-sound';
2626
import keySoundAsset from '../../../mechanicalKeyboard.mp3';
2727
import style from '../words/index.module.scss';
28+
import '../../../sass/main.css';
2829

2930
function Header() {
3031
const dispatch = useDispatch();
@@ -137,7 +138,7 @@ function KeysPractice() {
137138
));
138139

139140
return (
140-
<div className="noselect">
141+
<div className="content2">
141142
<Header />
142143
<div className={style.BodyContainer}>
143144
<div className={style.Body}>
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import React, {useState, useEffect} from 'react';
2+
import useInterval from '@use-it/interval'
3+
import '../../../sass/main.css'
4+
import Title from '../../../components/Title';
5+
import PracticeBox from '../../../components/PracticeBox';
6+
import { useSelector, useDispatch } from 'react-redux';
7+
import { initState, selectProgressPercent, selectTypeCount, updateTypeSpeed, selectTitle} from "./scriptSlice";
8+
9+
function PracticeScript() {
10+
const dispatch = useDispatch();
11+
const progressPecent = useSelector(selectProgressPercent);
12+
const typeCount = useSelector(selectTypeCount);
13+
const [tick, setTick] = useState(0); // 시작 후 흐른 시간
14+
const [typeSpeed, setTypeSpeed] = useState(0);
15+
const [maxTypeSpeed, setMaxTypeSpeed] = useState(0);
16+
const [praticeInformation, setPractiveInformation] = useState([]);
17+
const title = useSelector(selectTitle);
18+
19+
useEffect(() => {
20+
dispatch(initState());
21+
}, []);
22+
23+
useEffect(() => {
24+
setPractiveInformation([
25+
{ title: "진행도", figure: progressPecent, id: "noBorder" },
26+
{ title: "현재 타수", figure: typeSpeed },
27+
{ title: "최대 타수", figure: maxTypeSpeed },
28+
{ title: "스크립트명", figure: title },
29+
]);
30+
}, [tick]);
31+
32+
useInterval(() => {
33+
setTypeSpeed(parseInt(typeCount / tick * 60) | 0);
34+
setMaxTypeSpeed(Math.max(typeSpeed, maxTypeSpeed));
35+
setTick(tick + 0.1);
36+
dispatch(updateTypeSpeed(typeSpeed));
37+
}, 100);
38+
39+
return (
40+
<div className="content">
41+
<Title title="스크립트 연습" />
42+
<PracticeBox type = "script" information = {praticeInformation}/>
43+
</div>
44+
);
45+
}
46+
47+
export default PracticeScript;

0 commit comments

Comments
 (0)