Skip to content

Commit

Permalink
Merge pull request #332 from BCSDLab/fix/#330/image-qa-issue
Browse files Browse the repository at this point in the history
[비즈니스] 이벤트, 메뉴 관련 이슈 수정
  • Loading branch information
kimeodml authored May 10, 2024
2 parents a247cb5 + 866036e commit 22a88b9
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 67 deletions.
33 changes: 19 additions & 14 deletions src/page/AddMenu/components/AddMenuImgModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,40 @@ import { createPortal } from 'react-dom';
import { ReactComponent as CancelIcon } from 'assets/svg/addmenu/mobile-cancle-icon.svg';
import useAddMenuStore from 'store/addMenu';
import ErrorMessage from 'page/Auth/Signup/component/ErrorMessage';
import { ERRORMESSAGE } from 'page/ShopRegistration/constant/errorMessage'; import useImagesUpload from 'utils/hooks/useImagesUpload';
import { ERRORMESSAGE } from 'page/ShopRegistration/constant/errorMessage';
import { UploadError } from 'utils/hooks/useImagesUpload';
import styles from './AddMenuImgModal.module.scss';

interface AddMenuImgModalProps {
isOpen: boolean;
closeModal: (event?: React.MouseEvent | React.KeyboardEvent) => void;
imageObject: {
imageFile: string[];
imgRef: React.RefObject<HTMLInputElement>;
saveImgFile: () => Promise<void>;
uploadError: UploadError;
setImageFile: React.Dispatch<React.SetStateAction<string[]>>;
}
}

export default function AddMenuImgModal({ isOpen, closeModal }: AddMenuImgModalProps) {
export default function AddMenuImgModal({ isOpen, closeModal, imageObject }: AddMenuImgModalProps) {
const { setImageUrls } = useAddMenuStore();

const {
imageFile, imgRef, saveImgFile, uploadError,
} = useImagesUpload();

const triggerFileInput = () => {
imgRef.current?.click();
imageObject.imgRef.current?.click();
};
const handleImageChange = async () => {
await saveImgFile();
await imageObject.saveImgFile();
};
const triggerCameraInput = () => {
imgRef.current?.click();
imageObject.imgRef.current?.click();
};
useEffect(() => {
if (imageFile && !uploadError) {
setImageUrls(imageFile);
if (imageObject.imageFile && !imageObject.uploadError) {
setImageUrls(imageObject.imageFile);
closeModal();
}
}, [imageFile, uploadError, setImageUrls, closeModal]);
}, [imageObject.imageFile, imageObject.uploadError, setImageUrls, closeModal]);

if (!isOpen) return null;

Expand All @@ -45,12 +49,13 @@ export default function AddMenuImgModal({ isOpen, closeModal }: AddMenuImgModalP
<span className={styles['content__main-text']}>이미지 추가</span>
<span className={styles['content__sub-text']}>메뉴 사진을 추가할 수 있습니다.</span>
<div className={styles['content__button-container']}>
<input type="file" accept="image/*" style={{ display: 'none' }} onChange={handleImageChange} ref={imgRef} multiple />
<input type="file" accept="image/*" style={{ display: 'none' }} onChange={handleImageChange} ref={imageObject.imgRef} multiple />
<button type="button" className={styles['content__album-button']} onClick={triggerFileInput}>사진 앨범</button>
<button type="button" className={styles['content__camera-button']} onClick={triggerCameraInput}>카메라 촬영</button>
</div>
<div className={styles['content__image-error-message']}>
{uploadError && <ErrorMessage message={ERRORMESSAGE[uploadError]} />}
{imageObject.uploadError
&& <ErrorMessage message={ERRORMESSAGE[imageObject.uploadError]} />}
</div>
</div>
</div>,
Expand Down
25 changes: 16 additions & 9 deletions src/page/AddMenu/components/MenuImage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,23 @@ export default function MenuImage({ isComplete }: MenuImageProps) {
} = useBooleanState(false);

const {
imageFile, imgRef, saveImgFile, uploadError,
imageFile, imgRef, saveImgFile, uploadError, setImageFile,
} = useImagesUpload();
const imageObject = {
imageFile, imgRef, saveImgFile, uploadError, setImageFile,
}; // AddMenuImgModal에 넘길 props
const handleAddImage = () => {
imgRef.current?.click();
};
const handleDeleteImage = (image: string) => {
removeImageUrl(image);
setImageFile(imageFile.filter((img) => img !== image)); // pc 버전 이미지 동기화
};

const handleImageChange = async () => {
await saveImgFile();
};

useEffect(() => {
if (imageFile) {
setImageUrls(imageFile);
Expand All @@ -50,14 +56,14 @@ export default function MenuImage({ isComplete }: MenuImageProps) {
</div>
<div className={styles['mobile__new-image__container']}>
{!isComplete && (
<button
type="button"
className={styles['mobile__new-image__add-btn']}
onClick={openAddMenuImgModal}
>
<ImgPlusIcon className={styles['mobile__new-image__plusIcon']} />
<div className={styles['mobile__new-image__add-caption']}>이미지 추가</div>
</button>
<button
type="button"
className={styles['mobile__new-image__add-btn']}
onClick={openAddMenuImgModal}
>
<ImgPlusIcon className={styles['mobile__new-image__plusIcon']} />
<div className={styles['mobile__new-image__add-caption']}>이미지 추가</div>
</button>
)}
{imageUrl.map((image, index) => (
<div key={image} className={styles['mobile__new-image__item']}>
Expand All @@ -78,6 +84,7 @@ export default function MenuImage({ isComplete }: MenuImageProps) {
<AddMenuImgModal
isOpen={isAddMenuImgModal}
closeModal={closeAddMenuImgModal}
imageObject={imageObject}
/>
</div>
) : (
Expand Down
44 changes: 28 additions & 16 deletions src/page/ManageEvent/AddingEvent/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { useState } from 'react';
import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css';
import { useAddEvent } from 'query/event';
import { useNavigate, useParams } from 'react-router-dom';
Expand Down Expand Up @@ -97,17 +96,25 @@ export const initialError = {
export default function AddingEvent() {
const [eventInfo, setEventInfo] = useState<EventInfo>(initialState);
const [error, setError] = useState(initialError);
const [editor, setEditor] = useState('');
const [isAlertModalOpen, setIsAlertModalOpen] = useState(false);
const param = useParams();

const { mutate: addEvent, isPending } = useAddEvent(param.id!);
const navigate = useNavigate();

const changeInput = (e: React.ChangeEvent<HTMLInputElement>, type: 'title' | 'start' | 'end', change?: Change) => {
const changeInput = (
e: React.ChangeEvent<HTMLInputElement> | React.ChangeEvent<HTMLTextAreaElement>,
type: 'title' | 'start' | 'end' | 'content',
change?: Change,
) => {
const value = e.target.value.replaceAll(/[\D]/gi, '');
if (type === 'title' && e.target.value.length <= 25) {
setEventInfo({ ...eventInfo, title: e.target.value });
setError({ ...error, title: false });
}
if (type === 'content' && e.target.value.length <= 500) {
setEventInfo({ ...eventInfo, content: e.target.value });
setError({ ...error, content: false });
}
if (type === 'start') {
if (change === 'year' && e.target.value.length <= 4) {
Expand All @@ -116,6 +123,7 @@ export default function AddingEvent() {
if (change !== 'year' && e.target.value.length <= 2) {
setEventInfo({ ...eventInfo, start_date: { ...eventInfo.start_date, [change!]: value } });
}
setError({ ...error, date: false });
}
if (type === 'end') {
if (change === 'year' && e.target.value.length <= 4) {
Expand All @@ -124,8 +132,8 @@ export default function AddingEvent() {
if (change !== 'year' && e.target.value.length <= 2) {
setEventInfo({ ...eventInfo, end_date: { ...eventInfo.end_date, [change!]: value } });
}
setError({ ...error, date: false });
}
setError({ ...error, title: false });
};

const validation = () => {
Expand All @@ -134,7 +142,7 @@ export default function AddingEvent() {
setError((prevError) => ({ ...prevError, title: true }));
flag = true;
}
if (editor.length === 0) {
if (eventInfo.content.length === 0) {
setError((prevError) => ({ ...prevError, content: true }));
flag = true;
}
Expand Down Expand Up @@ -185,7 +193,7 @@ export default function AddingEvent() {

const requestData = {
title: eventInfo.title,
content: editor,
content: eventInfo.content,
start_date: startDate,
end_date: endDate,
thumbnail_images: eventInfo.thumbnail_image,
Expand Down Expand Up @@ -292,21 +300,25 @@ export default function AddingEvent() {
<div>
<div className={styles.event__divide}>
<p className={styles.event__paragraph}>이벤트/공지 내용</p>
<small className={styles.event__count} />
<small className={
cn({
[styles.event__count]: true,
[styles['event__count--full']]: eventInfo.content.length === 500,
})
}
>
{`${eventInfo.content.length} / 500`}
</small>
</div>
<div>
<ReactQuill
theme="snow"
value={editor}
onChange={(e) => {
setError({ ...error, content: false });
return setEditor(e);
}}
modules={modules}
placeholder="이벤트/공지 내용을 입력해 주세요."
<textarea
value={eventInfo.content}
placeholder="이벤트 내용을 입력해주세요"
className={cn({
[styles['error-border']]: error.content,
[styles.event__content]: true,
})}
onChange={(e) => changeInput(e, 'content')}
/>
</div>
{error.content && <div className={styles['error-message']}>필수 입력 항목입니다.</div>}
Expand Down
60 changes: 41 additions & 19 deletions src/page/ManageEvent/ModifyEvent/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { useLocation, useNavigate } from 'react-router-dom';
import { useState } from 'react';
import {
initialError, EventInfo, modules, uploadImage, Change, validateDate,
initialError, EventInfo, uploadImage, Change, validateDate,
} from 'page/ManageEvent/AddingEvent/index';
import AlertModal from 'component/common/Modal/alertModal';
import ReactQuill from 'react-quill';
import showToast from 'utils/ts/showToast';
import { getCoopUrl } from 'api/uploadFile';
import { ReactComponent as Delete } from 'assets/svg/myshop/delete.svg';
Expand Down Expand Up @@ -51,24 +50,43 @@ export default function ModifyEvent() {

const [eventInfo, setEventInfo] = useState<EventInfo>(initialState);
const [error, setError] = useState(initialError);
const [editor, setEditor] = useState(event.content);
const [isAlertModalOpen, setIsAlertModalOpen] = useState(false);

const { mutate: modifyEvent, isPending } = useModifyEvent(event.shop_id, event.event_id);
const navigate = useNavigate();

const changeInput = (e: React.ChangeEvent<HTMLInputElement>, type: 'title' | 'start' | 'end', change?: Change) => {
const changeInput = (
e: React.ChangeEvent<HTMLInputElement> | React.ChangeEvent<HTMLTextAreaElement>,
type: 'title' | 'start' | 'end' | 'content',
change?: Change,
) => {
const value = e.target.value.replaceAll(/[\D]/gi, '');
if (type === 'title' && e.target.value.length <= 25) {
setEventInfo({ ...eventInfo, title: e.target.value });
setError({ ...error, title: false });
}
if (type === 'content' && e.target.value.length <= 500) {
setEventInfo({ ...eventInfo, content: e.target.value });
setError({ ...error, content: false });
}
if (type === 'start') {
setEventInfo({ ...eventInfo, start_date: { ...eventInfo.start_date, [change!]: value } });
if (change === 'year' && e.target.value.length <= 4) {
setEventInfo({ ...eventInfo, start_date: { ...eventInfo.start_date, [change!]: value } });
}
if (change !== 'year' && e.target.value.length <= 2) {
setEventInfo({ ...eventInfo, start_date: { ...eventInfo.start_date, [change!]: value } });
}
setError({ ...error, date: false });
}
if (type === 'end') {
setEventInfo({ ...eventInfo, end_date: { ...eventInfo.end_date, [change!]: value } });
if (change === 'year' && e.target.value.length <= 4) {
setEventInfo({ ...eventInfo, end_date: { ...eventInfo.end_date, [change!]: value } });
}
if (change !== 'year' && e.target.value.length <= 2) {
setEventInfo({ ...eventInfo, end_date: { ...eventInfo.end_date, [change!]: value } });
}
setError({ ...error, date: false });
}
setError({ ...error, title: false });
};

const validation = () => {
Expand All @@ -77,7 +95,7 @@ export default function ModifyEvent() {
setError((prevError) => ({ ...prevError, title: true }));
flag = true;
}
if (editor.length === 0) {
if (eventInfo.content.length === 0) {
setError((prevError) => ({ ...prevError, content: true }));
flag = true;
}
Expand Down Expand Up @@ -129,7 +147,7 @@ export default function ModifyEvent() {

const requestData = {
title: eventInfo.title,
content: editor,
content: eventInfo.content,
start_date: startDate,
end_date: endDate,
thumbnail_images: eventInfo.thumbnail_image,
Expand Down Expand Up @@ -215,21 +233,25 @@ export default function ModifyEvent() {
<div>
<div className={styles.event__divide}>
<p className={styles.event__paragraph}>이벤트/공지 내용</p>
<small className={styles.event__count} />
<small className={
cn({
[styles.event__count]: true,
[styles['event__count--full']]: eventInfo.content.length === 500,
})
}
>
{`${eventInfo.content.length} / 500`}
</small>
</div>
<div>
<ReactQuill
theme="snow"
value={editor}
onChange={(e) => {
setError({ ...error, content: false });
return setEditor(e);
}}
modules={modules}
placeholder="이벤트/공지 내용을 입력해 주세요."
<textarea
value={eventInfo.content}
placeholder="이벤트 내용을 입력해주세요"
className={cn({
[styles['error-border']]: error.content,
[styles.event__content]: true,
})}
onChange={(e) => changeInput(e, 'content')}
/>
</div>
{error.content && <div className={styles['error-message']}>필수 입력 항목입니다.</div>}
Expand Down
9 changes: 9 additions & 0 deletions src/page/ManageEvent/index.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,15 @@
height: 40px;
padding: 5px 10px;
}

&__content {
border: 1px solid #e1e1e1;
border-radius: 5px;
width: 100%;
height: 100px;
padding: 5px 10px;
box-sizing: border-box;
}
}

.event-day {
Expand Down
11 changes: 7 additions & 4 deletions src/page/ModifyMenu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,18 @@ import MenuDetail from 'page/AddMenu/components/MenuDetail';
import GoMyShopModal from 'page/AddMenu/components/GoMyShop';
import MobileDivide from 'page/AddMenu/components/MobileDivide';
import useScrollToTop from 'utils/hooks/useScrollToTop';
import useFormValidation from 'page/AddMenu/hook/useFormValidation';

export default function ModifyMenu() {
useScrollToTop();
const { isMobile } = useMediaQuery();
const [isComplete, setIsComplete] = useState<boolean>(false);
const { validateFields } = useFormValidation();
const toggleConfirmClick = () => {
if (validateFields()) {
setIsComplete((prevState) => !prevState);
}
};
const { menuId } = useParams();

assert(menuId != null, 'menuId가 없습니다.');
Expand All @@ -31,10 +38,6 @@ export default function ModifyMenu() {
navigate('/owner');
};

const toggleConfirmClick = () => {
setIsComplete((prevState) => !prevState);
};

const { deleteMenuMutation } = useDeleteMenu();

const handleMobileDeleteMenu = () => {
Expand Down
Loading

0 comments on commit 22a88b9

Please sign in to comment.