Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[todo] 멘토링 취소 모달 개발 #235

Merged
merged 9 commits into from
Oct 4, 2023
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;
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);
obvoso marked this conversation as resolved.
Show resolved Hide resolved
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 : "Success");
JuneParkCode marked this conversation as resolved.
Show resolved Hide resolved
dispatch(closeCancelModal());
} catch (e: BaseQueryError<any>) {
alert(errorMsg ? errorMsg : "Error");
}
};

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={1000}
style={{ height: 80, marginBottom: 24 }}
onChange={(e) => setCancelMsg(e.target.value)}
JuneParkCode marked this conversation as resolved.
Show resolved Hide resolved
placeholder="최대 1000글자"
JuneParkCode marked this conversation as resolved.
Show resolved Hide resolved
className="w-full max-w-[500px] mt-3"
/>}
</div>
<div className="connect-btn-wrapper">
<Button
buttonType={ButtonType.CANCLE}
obvoso marked this conversation as resolved.
Show resolved Hide resolved
onClick={() => handleClose()}
>
닫기
</Button>
<Button
buttonType={ButtonType.ACCEPT}
onClick={() => handleCancel()}
>
취소하기
</Button>
</div>
</div>
</section>
</div>
);
};

export default CancelModal;
24 changes: 2 additions & 22 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 @@ -141,10 +124,7 @@ export default function Reservation({ children }: props) {
<Button
buttonType={ButtonType.CANCLE}
onClick={() => {
handleCancelReservation(
"취소 완료되었습니다.",
"취소에 실패하였습니다.",
);
dispatch(ReservationSlice.actions.openCancelModal());
}}
>
{myRole === ReservationUserRole.mentor &&
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
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