Skip to content

Commit

Permalink
[todo] 멘토링 취소 모달 개발 (#235)
Browse files Browse the repository at this point in the history
* [fix]: index.tsx 메인 페이지에 Cancel Modal 적용

* [fix]: Mentoring index.tsx에 Cancel Modal 적용

* [fix]: Reservation page에 Cancel Modal 적용

* [fix]: Home page에 Feedback Modal 적용 #157

* [fix]: CANCLE읋 CANCEL로 변환

* [fix]: Success, Fail 문자열 변경

* [fix]: TextArea 에서 최대 문자 길이 제한 변경

* [fix]: useState 초기값 수정
  • Loading branch information
falconlee236 authored Oct 4, 2023
1 parent 458433e commit 93ea4d8
Show file tree
Hide file tree
Showing 13 changed files with 158 additions and 27 deletions.
1 change: 1 addition & 0 deletions 42manito/src/RTK/Apis/Reservation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export const reservationApi = createApi({
return {
url: `/reservations/${args.id}/cancel`,
method: "PATCH",
data: {content: args.content},
};
},
invalidatesTags: [{ type: "Reservation", id: "LIST" }],
Expand Down
10 changes: 10 additions & 0 deletions 42manito/src/RTK/Slices/Reservation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import { ReservationStatus } from "@/Types/Reservations/ReservationStatus";
interface currMentorType {
isReservationModalOpen: boolean;
isFeedbackModalOpen: boolean;
isCancelModalOpen: boolean;
selectedReservation: ReservationDefaultDto;
}

const InitialState: currMentorType = {
isReservationModalOpen: false,
isFeedbackModalOpen: false,
isCancelModalOpen: false,
selectedReservation: {
id: 0,
mentorId: 0,
Expand Down Expand Up @@ -46,6 +48,12 @@ export const ReservationSlice = createSlice({
closeFeedbackModal(state) {
state.isFeedbackModalOpen = false;
},
openCancelModal(state ) {
state.isCancelModalOpen = true;
},
closeCancelModal(state) {
state.isCancelModalOpen = false;
},
setSelectedReservation(state, action) {
state.selectedReservation = action.payload;
},
Expand All @@ -57,5 +65,7 @@ export const {
closeReservationModal,
openFeedbackModal,
closeFeedbackModal,
openCancelModal,
closeCancelModal,
setSelectedReservation,
} = ReservationSlice.actions;
2 changes: 1 addition & 1 deletion 42manito/src/Types/General/ButtonType.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const enum ButtonType {
ACCEPT,
CANCLE,
CANCEL,
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export interface ReservationPatchCancelReqDto {
id: number;
content: string;
}
36 changes: 36 additions & 0 deletions 42manito/src/components/Cancel/CancelMessageSelect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Select } from "antd";
import React, {Dispatch, SetStateAction} from "react";
interface args{
setOpenTextArea: Dispatch<SetStateAction<boolean>>;
setCancelMsg: Dispatch<SetStateAction<string>>;
}

export default function CancelMessageSelect({setOpenTextArea, setCancelMsg} : args) {
const defaultMsg = [
{label: "시간이 맞지않아 취소합니다.", value: 1},
{label: "멘토/멘티로부터 연락이 없어서 취소합니다.", value: 2},
{label: "직접 입력", value: 3}
]

const handleChange = (value: number) => {
const msgObj = defaultMsg.find(({value: id}) => id === value);
if (msgObj === undefined)
setCancelMsg("");
else
setCancelMsg(msgObj.label);
if (value === 3)
setOpenTextArea(true);
else
setOpenTextArea(false);
};

return (
<Select
defaultValue={1}
onChange={handleChange}
style={{ width: "100%" }}
options={defaultMsg}
className="w-full max-w-[500px]"
/>
);
}
83 changes: 83 additions & 0 deletions 42manito/src/components/Cancel/CancelModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import React, { useState } from "react";
import {RootState, useAppDispatch} from "@/RTK/store";
import { Input } from "antd";
import { Button } from "@/common";
import { ButtonType } from "@/Types/General/ButtonType";
import {closeCancelModal, setSelectedReservation} from "@/RTK/Slices/Reservation";
import CancelMessageSelect from "@/components/Cancel/CancelMessageSelect";
import { BaseQueryError } from "@reduxjs/toolkit/src/query/baseQueryTypes";
import {usePatchReservationCancelMutation} from "@/RTK/Apis/Reservation";
import {useSelector} from "react-redux";


const CancelModal = () => {
const [openTextArea, setOpenTextArea] = useState(false);
const [cancelMsg, setCancelMsg] = useState("시간이 맞지않아 취소합니다.");
const dispatch = useAppDispatch();
const [patchCancelReservation] = usePatchReservationCancelMutation();
const reservation = useSelector(
(state: RootState) => state.rootReducers.reservation.selectedReservation,
);
const handleCancel = async (msg?: string, errorMsg?: string) => {
try {
const data = await patchCancelReservation({
id: reservation.id,
content: cancelMsg,
}).unwrap();
dispatch(setSelectedReservation(data));
alert(msg ? msg : "멘토링이 취소되었습니다.");
dispatch(closeCancelModal());
} catch (e: BaseQueryError<any>) {
alert(errorMsg ? errorMsg : "멘토링 취소가 실패했습니다.");
}
};

const handleClose = () => {
dispatch(closeCancelModal());
};

return (
<div
className="connect-wrapper"
id="wrapper"
onClick={(e) => e.stopPropagation()}
>
<section
className={`connect-modal-section`}
onClick={(e) => e.stopPropagation()}
>
<div className="connect-container">
<div className="connect-title mt-5"> 멘토링 취소</div>
<div className="connect-content-wrapper">
<div className="connect-header"> 취소하려는 이유를 선택해주세요 </div>
<CancelMessageSelect setOpenTextArea={setOpenTextArea} setCancelMsg={setCancelMsg}/>
{openTextArea && <Input.TextArea
showCount
maxLength={100}
style={{ height: 80, marginBottom: 24 }}
onChange={(e) => setCancelMsg(e.target.value)}
placeholder="최대 100글자"
className="w-full max-w-[500px] mt-3"
/>}
</div>
<div className="connect-btn-wrapper">
<Button
buttonType={ButtonType.CANCEL}
onClick={() => handleClose()}
>
닫기
</Button>
<Button
buttonType={ButtonType.ACCEPT}
onClick={() => handleCancel()}
>
취소하기
</Button>
</div>
</div>
</section>
</div>
);
};

export default CancelModal;
2 changes: 1 addition & 1 deletion 42manito/src/components/Connect/ConnectModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ const ConnectModal = ({ handleYes, children }: Props) => {
</div>
<div className="connect-btn-wrapper">
<Button
buttonType={ButtonType.CANCLE}
buttonType={ButtonType.CANCEL}
onClick={() => handleFocusOut()}
>
취소하기
Expand Down
26 changes: 3 additions & 23 deletions 42manito/src/components/Reservation/Reservation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,7 @@ import {
import { ReservationStatus } from "@/Types/Reservations/ReservationStatus";
import { Button } from "@/common";
import NextProgressButton from "@/components/Reservation/NextProgressButton";
import { usePatchReservationCancelMutation } from "@/RTK/Apis/Reservation";
import {
ReservationSlice,
setSelectedReservation,
} from "@/RTK/Slices/Reservation";
import { BaseQueryError } from "@reduxjs/toolkit/src/query/baseQueryTypes";
import { ReservationSlice } from "@/RTK/Slices/Reservation";
import { RootState } from "@/RTK/store";
import FeedbackCard from "@/components/Reservation/feedback/FeedbackCard";
import { ButtonType } from "@/Types/General/ButtonType";
Expand Down Expand Up @@ -51,20 +46,8 @@ export default function Reservation({ children }: props) {
targetUserRole === ReservationUserRole.mentor
? ReservationUserRole.mentee
: ReservationUserRole.mentor;
const [patchCancelReservation] = usePatchReservationCancelMutation();
const dispatch = useDispatch();
const router = useRouter();
const handleCancelReservation = async (msg?: string, errorMsg?: string) => {
try {
const data = await patchCancelReservation({
id: reservation.id,
}).unwrap();
dispatch(setSelectedReservation(data));
alert(msg ? msg : "Success");
} catch (e: BaseQueryError<any>) {
alert(errorMsg ? errorMsg : "Error");
}
};
const handleClick = (name: string) => {
router.push(`/Search/${name}`);
dispatch(ReservationSlice.actions.closeReservationModal());
Expand Down Expand Up @@ -139,12 +122,9 @@ export default function Reservation({ children }: props) {
(myRole === ReservationUserRole.mentor &&
status === ReservationStatus.ACCEPT)) && (
<Button
buttonType={ButtonType.CANCLE}
buttonType={ButtonType.CANCEL}
onClick={() => {
handleCancelReservation(
"취소 완료되었습니다.",
"취소에 실패하였습니다.",
);
dispatch(ReservationSlice.actions.openCancelModal());
}}
>
{myRole === ReservationUserRole.mentor &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ const FeedbackModal = () => {
</div>
<div className="connect-btn-wrapper">
<Button
buttonType={ButtonType.CANCLE}
buttonType={ButtonType.CANCEL}
onClick={() => handleClose()}
>
취소하기
Expand Down
5 changes: 5 additions & 0 deletions 42manito/src/pages/Mentorings/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { ReservationStatus } from "@/Types/Reservations/ReservationStatus";
import { useRouter } from "next/router";
import Loading from "@/components/Global/Loading";
import FeedbackModal from "@/components/Reservation/modal/FeedbackModal";
import CancelModal from "@/components/Cancel/CancelModal";

const Mentoring = () => {
const banner = [
Expand All @@ -34,6 +35,9 @@ const Mentoring = () => {
const isFeedbackModalOpen = useSelector(
(state: RootState) => state.rootReducers.reservation.isFeedbackModalOpen
);
const isCancelModalOpen = useSelector(
(state: RootState) => state.rootReducers.reservation.isCancelModalOpen
);
const handleRoleSelect = (id: string) => {
if (id === "mentor") {
setRole(ReservationRole.MENTOR);
Expand Down Expand Up @@ -142,6 +146,7 @@ const Mentoring = () => {
</div>
{isReservationModalOpen && <ReservationModal />}
{isFeedbackModalOpen && <FeedbackModal />}
{isCancelModalOpen && <CancelModal />}
</Layout>
</>
);
Expand Down
2 changes: 1 addition & 1 deletion 42manito/src/pages/ProfileUpdate/[userId].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ export default function ProfileUpdate() {
</div>
<div className="profile-update-btn-wrapper">
<Button
buttonType={ButtonType.CANCLE}
buttonType={ButtonType.CANCEL}
type="button"
onClick={() => cancelButtonHandler()}
>
Expand Down
10 changes: 10 additions & 0 deletions 42manito/src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import ReservationModal from "@/components/Reservation/modal/ReservationModal";
import { BannersData } from "@/components/Banners/Banners";
import { ReservationRole } from "@/Types/Reservations/ReservationRole";
import { ReservationStatus } from "@/Types/Reservations/ReservationStatus";
import CancelModal from "@/components/Cancel/CancelModal";
import FeedbackModal from "@/components/Reservation/modal/FeedbackModal";

const MentorModal = dynamic(() => import("@/components/Mentor/Modal"));

Expand All @@ -36,6 +38,12 @@ export default function Home() {
const isReservationModalOpen = useSelector(
(state: RootState) => state.rootReducers.reservation.isReservationModalOpen
);
const isFeedbackModalOpen = useSelector(
(state: RootState) => state.rootReducers.reservation.isFeedbackModalOpen
);
const isCancelModalOpen = useSelector(
(state: RootState) => state.rootReducers.reservation.isCancelModalOpen,
);
const requestQuery = {
take: 100,
page: 0,
Expand Down Expand Up @@ -147,6 +155,8 @@ export default function Home() {
<MentorModal />
)}
{isReservationModalOpen && <ReservationModal />}
{isFeedbackModalOpen && <FeedbackModal />}
{isCancelModalOpen && (<CancelModal />)}
<button
onClick={scrollToTop}
className="fixed bottom-5 right-5 rounded-full
Expand Down
5 changes: 5 additions & 0 deletions 42manito/src/pages/reservation/[reservationId].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import React, { useEffect } from "react";
import Layout from "@/components/Layout/Layout";
import FeedbackModal from "@/components/Reservation/modal/FeedbackModal";
import { RootState } from "@/RTK/store";
import CancelModal from "@/components/Cancel/CancelModal";

export default function ReservationPage() {
const route = useRouter();
Expand All @@ -21,6 +22,9 @@ export default function ReservationPage() {
const isFeedbackModalOpen = useSelector(
(state: RootState) => state.rootReducers.reservation.isFeedbackModalOpen,
);
const isCancelModalOpen = useSelector(
(state: RootState) => state.rootReducers.reservation.isCancelModalOpen,
);
const dispatch = useDispatch();

useEffect(() => {
Expand All @@ -35,6 +39,7 @@ export default function ReservationPage() {
<div className="py-10">{!isLoading && !error && <Reservation />}</div>
</div>
{isFeedbackModalOpen && <FeedbackModal />}
{isCancelModalOpen && <CancelModal />}
</Layout>
</>
);
Expand Down

0 comments on commit 93ea4d8

Please sign in to comment.