Skip to content

Commit

Permalink
Merge branch 'release/2.0.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
publdaze committed Nov 2, 2023
2 parents bb80ed2 + 94a8460 commit 2d583ea
Show file tree
Hide file tree
Showing 16 changed files with 160 additions and 62 deletions.
44 changes: 44 additions & 0 deletions .github/ISSUE_TEMPLATE/🐞-버그-제보-🐞.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
name: "\U0001F41E 버그 제보 \U0001F41E"
about: 홈페이지 사용 시 발생한 버그를 제보해주세요.
title: ''
labels: "\U0001F41E Bug"
assignees: ''

---

### 버그 설명 (필수)
- 어떤 문제가 있었는지 명확하고 간결하게 알려주세요.


### 버그 재현 방법 (필수)
- 어떤 순서로 접근했을때 버그가 발생했나요?

> 예시
> 1. '...'으로 이동하고
> 2. '....'을 클릭하고
> 3. '....'을 스크롤하면
> 4. 에러 발생

### 의도한 동작
- 원래 어떻게 동작되어야 하는 지 간략하게 적어주세요.


### 스크린샷
- 버그가 발생한 화면을 이미지로 남겨주면 버그 파악에 용이합니다.


### 데스크탑에서 발생한 경우 (아래 정보를 기입해주세요):
- OS: [예시: Windows - 버전까지 적어주면 더 좋습니다!]
- Browser: [예시: chrome, safari]


### 모바일에서 발생한 경우 (아래 정보를 기입해주세요):
- Device: [예시: iPhone6]
- OS: [예시: iOS8.1]
- Browser: [예시: chrome, safari]


### 추가 정보
- 버그를 설명하는데 추가적인 정보가 있다면 기입해주세요.
23 changes: 23 additions & 0 deletions .github/ISSUE_TEMPLATE/🚀-불편사항-제보-🚀.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
name: "\U0001F680 불편사항 제보 \U0001F680"
about: 홈페이지 사용 시 불편사항이 있다면 제보해주세요.
title: ''
labels: "\U0001F680 enhancement"
assignees: ''

---

### 불편사항 설명 (필수)
- 어떤 불편사항이 있었는지 명확하고 간결하게 알려주세요.


### 원하는 개선 방향
- 이떤 형태로 개선되면 좋을 지 알려주세요.


### 스크린샷
- 이해에 도움이 되는 이미지가 있다면 첨부해주세요.


### 추가 정보
- 불편 사항을 설명하는데 더 자세한 내용이 필요하다면 여기에 기입해주세요.
2 changes: 1 addition & 1 deletion src/api/SearchAccountApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const useSearchIdMutation = () => {

const useRequestAuthCodeMutation = () => {
const fetcher = ({ loginId, email }: { loginId: string; email: string }) =>
axios.post('/sign-in/send-password-change-auth-code', { loginId, email });
axios.post('/sign-in/send-password-change-auth-code', { loginId, email }).then(({ data }) => data);

return useMutation(fetcher);
};
Expand Down
1 change: 0 additions & 1 deletion src/components/Input/SearchInput.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable react/jsx-props-no-spreading */
import React, { KeyboardEvent } from 'react';
import { IconButton, StandardTextFieldProps } from '@mui/material';
import { MdOutlineSearch } from 'react-icons/md';
Expand Down
9 changes: 8 additions & 1 deletion src/components/Layout/Sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import { Drawer, Toolbar, useMediaQuery, useTheme } from '@mui/material';
import { Button, Drawer, Toolbar, useMediaQuery, useTheme } from '@mui/material';
import { VscBug } from 'react-icons/vsc';
import { Role } from '@api/dto';
import CATEGORIES from '@constants/category';
import { KEEPER_COLOR, SIDEBAR_WIDTH } from '@constants/keeperTheme';
Expand Down Expand Up @@ -35,6 +36,12 @@ const Sidebar = ({ mobileSidebarOpen, setMobileSidebarOpen }: SidebarProps) => {
}
return <CategoryNav key={category.id} category={category} />;
})}
<div className="my-4 flex h-full items-end justify-center">
<Button target="_blank" href="https://github.com/KEEPER31337/Homepage-Front-R2/issues/new/choose">
<VscBug className="mr-2" />
버그 및 불편 사항 제보
</Button>
</div>
</Drawer>
);
};
Expand Down
1 change: 0 additions & 1 deletion src/components/Selector/Selector.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable react/jsx-props-no-spreading */
import React from 'react';
import { FormControl, InputLabel, MenuItem, Select, SelectChangeEvent, SelectProps } from '@mui/material';

Expand Down
6 changes: 3 additions & 3 deletions src/pages/Game/Game.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@ const Game = () => {
title: '게임 방법',
contents: [
'각 칸에는 서로 다른 한자리 숫자가 입력됩니다',
'한 이닝 당 30초의 시간이 주어지고,',
'한 턴당 30초의 시간이 주어지고,',
'시간 내에 입력하지 않으면 ❌ 표시와 함께 다음 이닝으로 넘어갑니다',
'하루에 1번의 기회가 주어집니다',
],
},
{
title: '정답 처리',
contents: [
'🟢 숫자는 맞지만, 위치는 틀린 경우 - ball',
'🟡 숫자, 위치 모두 맞춘 경우 - strike',
'🟢 숫자, 위치 모두 맞춘 경우 - strike',
'🟡 숫자는 맞지만, 위치는 틀린 경우 - ball',
'⚫️ 숫자, 위치 모두 틀린 경우',
],
},
Expand Down
2 changes: 1 addition & 1 deletion src/pages/Profile/Tab/BoardTab/Table/MemberBoardTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ interface MemberBoardTableProps {

const MemberBoardTable = ({ memberId }: MemberBoardTableProps) => {
const navigate = useNavigate();
const { page, getRowNumber } = usePagination('myBoardPage');
const { page, getRowNumber } = usePagination(`memberBoardPage_${memberId}`);

const { data: memberBoard } = useGetMemberPostsQuery({ page, size: rowCnt, memberId });

Expand Down
20 changes: 13 additions & 7 deletions src/pages/admin/SeminarManage/SeminarManage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useEffect, useState } from 'react';
import { Typography } from '@mui/material';
import { DateTime } from 'luxon';
import { AttendSeminarInfo, MemberSeminarAttendance, AttendanceStatus } from '@api/dto';
import { useGetAttendSeminarListMutation, useGetSeminarListQuery } from '@api/seminarApi';
Expand Down Expand Up @@ -63,13 +64,18 @@ const SeminarManage = () => {
return (
<div>
<PageTitle>세미나 관리 {`(${currentTerm.year}${currentTerm.season})`}</PageTitle>
<div className="mb-5 flex justify-end space-x-2">
<ActionButton mode="add" onClick={() => setOpenAddSeminarModal(true)}>
추가
</ActionButton>
<ActionButton mode="delete" onClick={() => setOpenDeleteSeminarModal(true)}>
삭제
</ActionButton>
<div className="mb-5 flex items-end justify-between">
<Typography variant="small" className="text-subOrange">
*시간 만료로 인한 결석은 23시 50분에 일괄 결석으로 처리됩니다.
</Typography>
<div className="flex space-x-2">
<ActionButton mode="add" onClick={() => setOpenAddSeminarModal(true)}>
추가
</ActionButton>
<ActionButton mode="delete" onClick={() => setOpenDeleteSeminarModal(true)}>
삭제
</ActionButton>
</div>
</div>
<StandardTable<AttendSeminarInfo>
columns={[...seminarManageColumn.slice(0, 2), ...dynamicColumn, ...seminarManageColumn.slice(2)]}
Expand Down
2 changes: 1 addition & 1 deletion src/pages/board/BoardView/Card/CommentCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const CommentCard = ({ commentInfo, replyComments }: CommentCardProps) => {
<Card className="!bg-mainBlack !bg-none">
<CommentCardHeader commentInfo={commentInfo} />
{(!commentInfo.isDeleted || replyComments.length > 0) && (
<CardContent className="mb-5 whitespace-pre sm:!px-16">
<CardContent className="mb-5 whitespace-pre-line break-all sm:!px-16">
{!commentInfo.isDeleted && <Typography marginBottom={5}>{commentInfo.content}</Typography>}
<div className="space-y-3">
{replyComments.map((replyComment) => (
Expand Down
8 changes: 3 additions & 5 deletions src/pages/board/BoardView/Section/PostSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,9 @@ const PostSection = ({ postId, post, password }: PostSectionProps) => {
</Button>
{fileOpen && (
<div className="mb-10 mt-2 space-y-2 text-pointBlue">
{post.categoryName === '시험게시판' && (
<Typography variant="small" className="block text-subOrange">
*시험 게시판 파일 다운로드를 위해서는 댓글 작성이 필요합니다.
</Typography>
)}
<Typography variant="small" className="block text-subOrange">
*파일 다운로드를 위해서는 댓글 작성이 필요합니다.
</Typography>
{files && <FileViewer files={files} onRowClick={handleDownloadFileClick} />}
</div>
)}
Expand Down
9 changes: 4 additions & 5 deletions src/pages/login/Search/SearchPWFirstStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import TimerInput from '@components/Input/TimerInput';
import MailAuthenticationModal from '@components/Modal/MailAuthenticationModal';
import WarningModal from '@components/Modal/WarningModal';

const TIMER_DURATION_SECOND = 300;
interface searchPWFormProps {
id: string;
email: string;
Expand Down Expand Up @@ -82,9 +81,9 @@ const SearchPWFirstStep = ({ setCurrentStep, form, setForm }: SearchPWFirstStepP
requestAuthcode(
{ loginId: form.id, email: form.email },
{
onSuccess: () => {
onSuccess: ({ expiredSeconds }) => {
setIsAuthCodeRequireClick(true);
setExpirationTime(DateTime.now().plus({ seconds: TIMER_DURATION_SECOND }));
setExpirationTime(DateTime.now().plus({ seconds: expiredSeconds }));
setMatchInfoModalOpen(false);
},
onError: () => {
Expand Down Expand Up @@ -125,8 +124,8 @@ const SearchPWFirstStep = ({ setCurrentStep, form, setForm }: SearchPWFirstStepP
requestAuthcode(
{ loginId: form.id, email: form.email },
{
onSuccess: () => {
setExpirationTime(DateTime.now().plus({ seconds: TIMER_DURATION_SECOND }));
onSuccess: ({ expiredSeconds }) => {
setExpirationTime(DateTime.now().plus({ seconds: expiredSeconds }));
},
},
);
Expand Down
70 changes: 41 additions & 29 deletions src/pages/senimarAttend/Card/MemberCardContent.tsx
Original file line number Diff line number Diff line change
@@ -1,86 +1,97 @@
import React, { useState, useEffect } from 'react';
import { Typography } from '@mui/material';
import { AxiosError } from 'axios';
import { DateTime } from 'luxon';
import { useRecoilState } from 'recoil';
import { SeminarStatus } from '@api/dto';
import { useAttendSeminarMutation, useGetAvailableSeminarInfoQuery, useGetSeminarInfoQuery } from '@api/seminarApi';
import FilledButton from '@components/Button/FilledButton';
import ConfirmModal from '@components/Modal/ConfirmModal';
import Countdown from '../Countdown/Countdown';
import SeminarInput from '../Input/SeminarInput';
import SeminarAttendStatus from '../Status/SeminarAttendStatus';
import attendCountState from '../seminarAttend.recoil';

interface ErrorResponse {
message: string;
}

const MAX_ATTEND_COUNT = 5;

const MemberCardContent = ({ seminarId }: { seminarId: number }) => {
const { data: seminarData } = useGetSeminarInfoQuery(seminarId);
const {
mutate: attend,
isSuccess: isAttendSuccess,
error: attendError,
data: attendData,
} = useAttendSeminarMutation(seminarId);
const validCode = seminarData?.attendanceCode;
const { mutate: attend, isSuccess: isAttendSuccess, data: attendData } = useAttendSeminarMutation(seminarId);

const [incorrectCodeMsg, setIncorrectCodeMsg] = useState('ㅤ');
const [inputCode, setInputCode] = useState('');
const [attendStatus, setAttendStatus] = useState<undefined | SeminarStatus>(undefined);
const [excessModalOpen, setExcessModalOpen] = useState(false);
const [isTransitionTime, setIsTransitionTime] = useState(false);

const [attendCount, setAttendCount] = useRecoilState(attendCountState);

const { data: availableSeminarData } = useGetAvailableSeminarInfoQuery();
const isValidActivityStatus = (value: SeminarStatus) => {
return value === 'ATTENDANCE' || value === 'LATENESS' || value === 'ABSENCE' || value === 'BEFORE_ATTENDANCE';
};
const unableSeminar = !availableSeminarData?.id || availableSeminarData?.id !== seminarData?.id;
const unableSeminar =
!availableSeminarData?.id || availableSeminarData?.id !== seminarData?.id || attendCount >= MAX_ATTEND_COUNT;

useEffect(() => {
setAttendStatus(seminarData?.statusType);
}, [seminarData]);

const handleAttendButtonClick = () => {
attend(inputCode);
if (parseInt(localStorage.getItem('출석시도횟수') ?? '0', 10) > 5) setExcessModalOpen(true);
attend(inputCode, {
onError: (error) => {
const axiosError = error as AxiosError<ErrorResponse>;
if (axiosError.response?.status === 400) {
const remainAttendCount = MAX_ATTEND_COUNT - attendCount - 1;
setAttendCount((prev) => prev + 1);

if (remainAttendCount <= 0) {
setExcessModalOpen(true);
setIncorrectCodeMsg('남은 제출 횟수가 없습니다.');
return;
}
setIncorrectCodeMsg(`출석코드가 틀렸습니다. (남은 제출횟수 ${remainAttendCount}회)`);
return;
}
const errorMessage = axiosError?.response?.data?.message;
setIncorrectCodeMsg(errorMessage?.slice((errorMessage?.indexOf(':') || 0) + 1) ?? 'ㅤ');
},
});
};

useEffect(() => {
if (isAttendSuccess && isValidActivityStatus(attendData.data.statusType)) {
setAttendStatus(attendData.data.statusType);
setIncorrectCodeMsg('ㅤ');
localStorage.removeItem('출석시도횟수');
}
}, [isAttendSuccess]);

useEffect(() => {
if (inputCode !== validCode) {
const attemptNum = parseInt(localStorage.getItem('출석시도횟수') ?? '0', 10) + 1;
if (attemptNum <= 5) {
localStorage.setItem('출석시도횟수', String(attemptNum));
setIncorrectCodeMsg(`출석코드가 틀렸습니다.(남은 제출횟수 ${attemptNum}회)`);
}
} else {
const axiosError = attendError as AxiosError<ErrorResponse>;
const errorMessage = axiosError?.response?.data?.message;
setIncorrectCodeMsg(errorMessage?.slice((errorMessage?.indexOf(':') || 0) + 1) ?? 'ㅤ');
}
}, [attendError]);

useEffect(() => {
setIncorrectCodeMsg('ㅤ');
}, []);

useEffect(() => {
if (seminarData?.latenessCloseTime && DateTime.now() > seminarData.latenessCloseTime) {
setAttendCount(0);
}
}, [unableSeminar]);

return (
<div className={`${unableSeminar && 'opacity-50'}`}>
<ConfirmModal
open={excessModalOpen}
modalWidth="sm"
modalWidth="xs"
onClose={() => setExcessModalOpen(false)}
title="출석 제한 횟수 초과"
>
<Typography>가능한 출석 횟수를 초과했습니다.</Typography>
<Typography>출석 처리에 문제가 있는 경우 회장님에게 문의해주세요</Typography>
</ConfirmModal>
<Typography className="!mt-[16px] !text-h3 !font-bold ">{seminarData?.name} 세미나</Typography>
<Typography className="!mt-[16px] !text-h3 !font-bold">{seminarData?.name} 세미나</Typography>
<p className="mb-[14px] mt-[26px]">출석 코드</p>
<div className="mb-[15px]">
<SeminarInput
Expand All @@ -90,7 +101,6 @@ const MemberCardContent = ({ seminarId }: { seminarId: number }) => {
inputCode={unableSeminar ? '' : inputCode}
/>
</div>

<div className="mx-auto mt-[20px] flex h-[60px] w-[146px] justify-between">
<div className="grid content-between">
<div>출석</div>
Expand Down Expand Up @@ -119,7 +129,9 @@ const MemberCardContent = ({ seminarId }: { seminarId: number }) => {
{attendStatus === 'ATTENDANCE' || attendStatus === 'LATENESS' || attendStatus === 'ABSENCE' ? (
<SeminarAttendStatus status={attendStatus} />
) : (
<FilledButton onClick={handleAttendButtonClick}>출석</FilledButton>
<FilledButton onClick={handleAttendButtonClick} disabled={unableSeminar}>
출석
</FilledButton>
)}
</div>
</div>
Expand Down
9 changes: 6 additions & 3 deletions src/pages/senimarAttend/Input/SeminarInput.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import ReactCodesInput from 'react-codes-input';
import { KEEPER_COLOR } from '@constants/keeperTheme';

interface SeminarInputProps {
disabled?: boolean;
Expand All @@ -17,12 +18,14 @@ const SeminarInput = ({ disabled, helperText, setInputCode, inputCode }: Seminar
type="number"
onChange={setInputCode}
codeLength={4}
classNameCodeWrapperFocus="!border-0"
initialFocus
focusColor={KEEPER_COLOR.pointBlue}
classNameEnteredValue="h-[51px] py-2"
classNameWrapper="flex h-[52px] w-[192px] justify-between"
classNameCodeWrapper="w-[42px] border-b-2 border-pointBlue text-white bg-subBlack text-3xl text-center pt-2"
classNameCodeWrapper="w-[42px] border-b border-pointBlue text-white bg-subBlack text-3xl text-center"
/>

<div className="my-[4px] flex items-center justify-center text-small text-red-500">{helperText}</div>
<div className="mt-2 flex items-center justify-center text-small text-red-500">{helperText}</div>
</div>
);
};
Expand Down
Loading

0 comments on commit 2d583ea

Please sign in to comment.