Skip to content

Commit

Permalink
add: ExamPage>終了時のmodal
Browse files Browse the repository at this point in the history
  • Loading branch information
watasuke102 committed Jan 7, 2024
1 parent cadff9e commit 1e528bb
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/app/exam/_components/ExamPage/ExamPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import ArrowLeftIcon from '@assets/arrow-left.svg';
import ArrowRightIcon from '@assets/arrow-right.svg';
import CircleIcon from '@assets/circle.svg';
import CheckIcon from '@assets/check.svg';
import {FinishModal} from '../FinishModal/FinishModal';

type Props = {
title: string;
Expand Down Expand Up @@ -106,6 +107,7 @@ export function ExamPage(props: Props): JSX.Element {
</div>
</section>
</div>
<FinishModal />
</ExamReducerContext.Provider>
);
}
12 changes: 11 additions & 1 deletion src/app/exam/_components/ExamReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
// Twitter: @Watasuke102
// This software is released under the MIT or MIT SUSHI-WARE License.
import React from 'react';
import AnswerState from '@mytypes/AnswerState';
import Exam from '@mytypes/Exam';
import ExamState from '@mytypes/ExamState';
import {Move, Shuffle, ToggleElement} from '@utils/ArrayUtil';
Expand All @@ -32,6 +31,10 @@ export type Action =
from: number;
to: number;
}
| {
type: 'is_modal_open/set';
data: boolean;
}
| {
type: 'handle_button/prev' | 'handle_button/next';
};
Expand All @@ -40,6 +43,7 @@ export type StateType = {
index: number;
exam: Exam[];
exam_state: ExamState[];
is_modal_open: boolean;
};

export function init_state(exam: Exam[]): StateType {
Expand Down Expand Up @@ -71,6 +75,7 @@ export function init_state(exam: Exam[]): StateType {
correct_count: 0,
};
}),
is_modal_open: false,
};
}

Expand Down Expand Up @@ -102,6 +107,9 @@ export const exam_reducer: ReducerType = (current, action) => {
current.index = action.index;
}
break;
case 'is_modal_open/set':
current.is_modal_open = action.data;
break;
case 'handle_button/prev':
if (current.index > 0) {
--current.index;
Expand All @@ -111,6 +119,8 @@ export const exam_reducer: ReducerType = (current, action) => {
if (current.exam_state[current.index].checked) {
if (current.index < current.exam.length - 1) {
++current.index;
} else {
current.is_modal_open = true;
}
} else {
current.exam_state[current.index] = check_answer(
Expand Down
24 changes: 24 additions & 0 deletions src/app/exam/_components/FinishModal/FinishModal.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// TAGether - Share self-made exam for classmates
// CopyRight (c) 2020-2023 watasuke
//
// Email : <[email protected]>
// Twitter: @Watasuke102
// This software is released under the MIT or MIT SUSHI-WARE License.
@import '../../../../components/common/variable';

.modal {
min-width: 400px;
padding: 24px 32px;
text-align: center;
}

.modal_mes {
display: inline-grid;
grid-template-columns: 32px auto;
gap: 8px;
font-size: 1.9em;
font-weight: bold;
svg {
color: $color-primary-3;
}
}
58 changes: 58 additions & 0 deletions src/app/exam/_components/FinishModal/FinishModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// TAGether - Share self-made exam for classmates
// CopyRight (c) 2020-2023 watasuke
//
// Email : <[email protected]>
// Twitter: @Watasuke102
// This software is released under the MIT or MIT SUSHI-WARE License.
import css from './FinishModal.module.scss';
import React from 'react';
import {useRouter, useSearchParams} from 'next/navigation';
import {ExamReducerContext} from '../ExamReducer';
import Modal from '@/common/Modal/Modal';
import TadaIcon from '@assets/tada.svg';
import ButtonContainer from '@/common/Button/ButtonContainer';
import Button from '@/common/Button/Button';
import EditIcon from '@assets/edit.svg';
import ArrowLeftIcon from '@assets/arrow-left.svg';

export function FinishModal(): JSX.Element {
const router = useRouter();
const params = useSearchParams();
const id = params.get('id');

const [state, dispatch] = React.useContext(ExamReducerContext);
const [correct_answers, total_questions] = state.exam_state.reduce(
(acc, cur) => [acc[0] + cur.correct_count, acc[1] + cur.total_question],
[0, 0],
);
const correct_rate = Math.round((correct_answers / total_questions) * 10000) / 100;

return (
<Modal isOpen={state.is_modal_open} close={() => dispatch({type: 'is_modal_open/set', data: false})}>
<div className={css.modal}>
<div className={css.modal_mes}>
<TadaIcon /> <span>問題終了</span>
</div>
<p className={css.correct_rate}>
正答率:{correct_rate}% ({total_questions}問中{correct_answers}問正解)
</p>
{/* TODO: jump to history */}
<ButtonContainer>
<></>
<Button
text={'編集する'}
icon={<EditIcon />}
type={'material'}
OnClick={() => id && router.push(`/edit?id=${id}`)}
/>
<Button
text={'カテゴリ一覧へ移動'}
icon={<ArrowLeftIcon />}
type={'filled'}
OnClick={() => router.push('/list')}
/>
</ButtonContainer>
</div>
</Modal>
);
}
1 change: 1 addition & 0 deletions src/assets/tada.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 1e528bb

Please sign in to comment.