Skip to content

Commit

Permalink
Merge pull request #270 from BCSDLab/hotFix/#256/price-input-bug-fix
Browse files Browse the repository at this point in the history
[주변 상점] 가격 인풋 변경
  • Loading branch information
hoooooony authored Apr 17, 2024
2 parents 60b4609 + e68b451 commit 0dc5a64
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 36 deletions.
2 changes: 1 addition & 1 deletion src/model/shopInfo/newMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const NewMenu = z.object({
image_urls: z.array(z.string()),
is_single: z.boolean(),
name: z.string(),
option_prices: z.array(OptionPrice.nullable()),
option_prices: z.array(OptionPrice).nullable(),
single_price: z.number(),
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@
&__price-input {
text-align: right;
box-sizing: border-box;
width: 98%;
width: 95%;
height: 60px;
padding: 16px;
color: #252525;
Expand Down
199 changes: 167 additions & 32 deletions src/page/AddMenu/components/MenuPrice/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import useMediaQuery from 'utils/hooks/useMediaQuery';
import useAddMenuStore from 'store/addMenu';
import { ReactComponent as PlusIcon } from 'assets/svg/main/plus.svg';
import { ReactComponent as DeleteIcon } from 'assets/svg/addmenu/delete-icon.svg';
import { ReactComponent as MobileDeleteIcon } from 'assets/svg/addmenu/mobile-delete-icon.svg';
import { ReactComponent as MobilePlusIcon } from 'assets/svg/addmenu/mobile-plus-icon.svg';
import styles from './MenuPrice.module.scss';

interface MenuPriceProps {
Expand All @@ -10,10 +14,43 @@ export default function MenuPrice({ isComplete }:MenuPriceProps) {
const { isMobile } = useMediaQuery();
const {
optionPrices,
setOptionPrices,
isSingle,
setIsSingle,
singlePrice,
setSinglePrice,
} = useAddMenuStore();
const updatePriceInput = (inputId: number, field: string, newValue: string | number) => {
const updatedOptionPrices = (optionPrices || []).map((price) => {
if (price.id === inputId) {
return { ...price, [field]: newValue };
}
return price;
});
setOptionPrices(updatedOptionPrices);
};

const addPriceInput = () => {
if (optionPrices) {
const lastId = optionPrices.length > 0 ? optionPrices[optionPrices.length - 1].id : 0;
const newId = lastId + 1;
if (!isSingle) {
setOptionPrices([...(optionPrices || []), { id: newId, option: '', price: 0 }]);
} else {
setIsSingle(false);
}
}
};

const deletePriceInput = (id: number) => {
const updatedOptionPrices = optionPrices?.filter((item) => item.id !== id) || [];
setOptionPrices(updatedOptionPrices);

if (updatedOptionPrices.length === 0) {
setIsSingle(true);
setOptionPrices([]);
}
};

return (
<div>
Expand All @@ -24,34 +61,93 @@ export default function MenuPrice({ isComplete }:MenuPriceProps) {
<div className={styles.mobile__header}>
<div className={styles['mobile__header-title--complete']}>가격</div>
</div>
<div className={styles['mobile__price-info-text-box']}>
<div className={styles['mobile__price-info-text']}>
<div className={styles['mobile__price-info-text__price']}>
{singlePrice}
{isSingle ? (
<div className={styles['mobile__price-info-text-box']}>
<div className={styles['mobile__price-info-text']}>
<div className={styles['mobile__price-info-text__price']}>
{singlePrice}
</div>
</div>
</div>
</div>
)
: (optionPrices || []).map((input) => (
<div key={input.id} className={styles['mobile__price-info-text-box']}>
<div className={styles['mobile__price-info-text']}>
<div className={styles['mobile__price-info-text__size']}>
{input.option}
</div>
<div>
/
</div>
<div className={styles['mobile__price-info-text__price']}>
{input.price}
</div>
</div>
</div>
))}
</>
) : (
<>
<div className={styles.mobile__header}>
<div className={styles['mobile__header-title']}>가격</div>
</div>
<div className={styles['mobile__price-info-input-box']}>
<div className={styles['mobile__price-info-inputs']}>

<div className={styles['mobile__price-info-inputs__price-input-box']}>
<input
type="number"
className={styles['mobile__price-info-inputs__price-input']}
value={singlePrice}
onChange={(e) => setSinglePrice(Number(e.target.value))}
/>
<p className={styles['mobile__price-info-inputs__price-input-won']}></p>
{isSingle
? (
<div className={styles['mobile__price-info-input-box']}>
<div className={styles['mobile__price-info-inputs']}>
<div className={styles['mobile__price-info-inputs__price-input-box']}>
<input
type="number"
className={styles['mobile__price-info-inputs__price-input']}
inputMode="decimal"
value={singlePrice === 0 || singlePrice === null ? '' : singlePrice}
onChange={(e) => setSinglePrice(e.target.value === '' ? 0 : Number(e.target.value))}
/>
<p className={styles['mobile__price-info-inputs__price-input-won']}></p>
</div>
</div>
</div>
</div>
</div>
)
: (optionPrices || []).map((input) => (
<div key={input.id} className={styles['mobile__price-info-input-box']}>
<div className={styles['mobile__price-info-inputs']}>
<input
className={styles['mobile__price-info-inputs__size-input']}
placeholder="예) 소 (1~2 인분)"
value={input.option}
onChange={(e) => updatePriceInput(input.id, 'option', e.target.value)}
disabled={isSingle}
/>
<div className={styles['mobile__price-info-inputs__price-input-box']}>
<input
type="number"
className={styles['mobile__price-info-inputs__price-input']}
inputMode="decimal"
value={input.price === 0 ? '' : input.price}
onChange={(e) => updatePriceInput(input.id, 'price', Number(e.target.value))}
/>
<p className={styles['mobile__price-info-inputs__price-input-won']}></p>
</div>
</div>
<button
type="button"
className={styles['mobile__cancle-button']}
onClick={() => deletePriceInput(input.id)}
>
<MobileDeleteIcon className={styles['mobile__cancle-icon']} />
</button>
</div>
))}
<button
type="button"
className={styles['mobile__add-price-button']}
onClick={addPriceInput}
>
<MobilePlusIcon className={styles['mobile__add-price-button__icon']} />
<span className={styles['mobile__add-price-button__text']}>사이즈 추가</span>
</button>
</>
)}
</div>
Expand Down Expand Up @@ -94,20 +190,59 @@ export default function MenuPrice({ isComplete }:MenuPriceProps) {
<div className={styles.header}>
<div className={styles.header__title}>가격</div>
</div>
<div className={styles['price-info-input-box']}>
<div className={styles['price-info-inputs']}>
<div className={styles['price-info-inputs__price-input-box']}>
<input
type="number"
className={styles['price-info-inputs__price-input']}
value={singlePrice === 0 || singlePrice === null ? '' : singlePrice}
onChange={(e) => setSinglePrice(e.target.value === '' ? 0 : Number(e.target.value))}
/>
<p className={styles['price-info-inputs__price-input-won']}></p>
{isSingle
? (
<div className={styles['price-info-input-box']}>
<div className={styles['price-info-inputs']}>
<div className={styles['price-info-inputs__price-input-box']}>
<input
type="number"
className={styles['price-info-inputs__price-input']}
value={singlePrice === 0 || singlePrice === null ? '' : singlePrice}
onChange={(e) => setSinglePrice(e.target.value === '' ? 0 : Number(e.target.value))}
/>
<p className={styles['price-info-inputs__price-input-won']}></p>
</div>
</div>
</div>
</div>

</div>
)
: (optionPrices || []).map((input) => (
<div key={input.id} className={styles['price-info-input-box']}>
<div className={styles['price-info-inputs']}>
<input
className={styles['price-info-inputs__size-input']}
placeholder={isSingle ? '' : '예) 소 (1~2 인분)'}
value={input.option}
onChange={(e) => updatePriceInput(input.id, 'option', e.target.value)}
disabled={isSingle}
/>
<div className={styles['price-info-inputs__price-input-box']}>
<input
type="number"
className={styles['price-info-inputs__price-input']}
value={input.price === 0 ? '' : input.price}
onChange={(e) => updatePriceInput(input.id, 'price', Number(e.target.value))}
/>
<p className={styles['price-info-inputs__price-input-won']}></p>
</div>
</div>
<button
type="button"
className={styles['cancle-button']}
onClick={() => deletePriceInput(input.id)}
>
<DeleteIcon className={styles['cancle-button__icon']} />
</button>
</div>
))}
<button
type="button"
className={styles['add-price-button']}
onClick={addPriceInput}
>
<PlusIcon className={styles['add-price-button__icon']} />
<div className={styles['add-price-button__text']}>사이즈 추가</div>
</button>
</>
)}
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/page/AddMenu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export default function AddMenu() {
image_urls: imageUrl,
is_single: isSingle,
name,
option_prices: optionPrices?.map(({ option, price }) => ({
option_prices: isSingle ? null : optionPrices?.map(({ option, price }) => ({
option: option === '' ? name : option,
price: typeof price === 'string' ? parseInt(price, 10) : price,
})) || [],
Expand Down
6 changes: 5 additions & 1 deletion src/page/ModifyMenu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,17 @@ export default function ModifyMenu() {
optionPrices,
singlePrice,
setMenuInfo,
setOptionPrices,
} = useAddMenuStore();
// 처음 메뉴 데이터 초기화
useEffect(() => {
if (menuData) {
setMenuInfo(menuData);
}
}, [menuData, setMenuInfo]);
if (menuData?.option_prices === null) {
setOptionPrices([{ id: 0, option: '', price: 0 }]);
}
}, [menuData, setMenuInfo, setOptionPrices]);
const createMenuData = () => {
if (isSingle) {
return {
Expand Down
2 changes: 2 additions & 0 deletions src/query/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ const useMenuInfo = (menuId:number) => {
{
queryKey: ['menuInfo', menuId],
queryFn: () => getMenu(menuId),
refetchOnWindowFocus: true,
},
);

const { mutate: modifyMenuMutation, isError: modifyMenuError } = useMutation({
mutationFn: (param: NewMenu) => modifyMenu(menuId, param),
onSuccess: () => {
Expand Down

0 comments on commit 0dc5a64

Please sign in to comment.