Skip to content

Commit e7e3bb4

Browse files
[fix] 공고 등록/편집 페이지 버그 수정
[fix] 공고 등록/편집 페이지 버그 수정
2 parents c0752c0 + 161dcc3 commit e7e3bb4

File tree

2 files changed

+287
-173
lines changed

2 files changed

+287
-173
lines changed

src/pages/NoticeEditPage.tsx

Lines changed: 162 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { getNotice, putNotice } from "@/apis/services/noticeService";
1010
import { Close } from "@/assets/icon";
1111
import Button from "@/components/Button";
1212
import TextField from "@/components/TextField";
13+
import { ROUTES } from "@/constants/router";
14+
import { MIN_WAGE, MAX_WAGE } from "@/constants/wage";
1315
import { useUserStore } from "@/hooks/useUserStore";
1416
import { useModalStore } from "@/store/useModalStore";
1517
import { extractDigits, numberCommaFormatter } from "@/utils/number";
@@ -44,19 +46,77 @@ export default function NoticeEditPage() {
4446
});
4547

4648
useEffect(() => {
47-
async function fetchNotice() {
48-
if (!shopId || !noticeId) return;
49-
const res = await getNotice(shopId, noticeId);
50-
const { hourlyPay, startsAt, workhour, description } = res.data.item;
51-
setForm({
52-
hourlyPay: numberCommaFormatter(hourlyPay),
53-
startsAt: new Date(startsAt),
54-
workhour: String(workhour),
55-
description: description ?? "",
49+
if (!user) {
50+
openModal({
51+
type: "alert",
52+
iconType: "warning",
53+
message: "로그인 후에 이용 가능한 기능입니다.",
54+
onClose: () => navigate(ROUTES.AUTH.SIGNIN),
55+
});
56+
return;
57+
}
58+
if (user.type === "employee") {
59+
openModal({
60+
type: "alert",
61+
iconType: "warning",
62+
message: "사장님 계정으로만 이용 가능한 기능입니다.",
63+
onClose: () => navigate(ROUTES.PROFILE.ROOT),
5664
});
65+
return;
5766
}
67+
if (!user.shopId) {
68+
openModal({
69+
type: "alert",
70+
iconType: "warning",
71+
message: "가게 정보 등록 후 이용 가능합니다.",
72+
onClose: () => navigate(ROUTES.SHOP.REGISTER),
73+
});
74+
return;
75+
}
76+
}, []);
77+
78+
useEffect(() => {
79+
if (!shopId || !noticeId) return;
80+
const fetchNotice = async () => {
81+
try {
82+
const res = await getNotice(shopId, noticeId);
83+
const {
84+
hourlyPay,
85+
startsAt,
86+
workhour,
87+
description,
88+
shop: noticeShop,
89+
} = res.data.item;
90+
91+
const ownerShopId = noticeShop?.item.id;
92+
93+
if (ownerShopId !== shopId) {
94+
openModal({
95+
type: "alert",
96+
iconType: "warning",
97+
message: "다른 가게의 공고 편집은 불가능합니다.",
98+
onClose: () => navigate(ROUTES.SHOP.ROOT),
99+
});
100+
return;
101+
}
102+
103+
setForm({
104+
hourlyPay: numberCommaFormatter(hourlyPay),
105+
startsAt: new Date(startsAt),
106+
workhour: String(workhour),
107+
description: description ?? "",
108+
});
109+
} catch {
110+
openModal({
111+
type: "alert",
112+
iconType: "warning",
113+
message: "다른 가게의 공고 편집은 불가능합니다.",
114+
onClose: () => navigate(ROUTES.SHOP.ROOT),
115+
});
116+
}
117+
};
58118
fetchNotice();
59-
}, [shopId, noticeId]);
119+
}, [shopId, noticeId, navigate, openModal]);
60120

61121
const handleChange = (key: keyof FormType, value: string | null | Date) => {
62122
setForm((prev) => ({ ...prev, [key]: value }));
@@ -90,11 +150,20 @@ export default function NoticeEditPage() {
90150
}
91151

92152
const hourlyPay = Number(extractDigits(form.hourlyPay));
93-
if (isNaN(hourlyPay) || hourlyPay <= 0) {
153+
const formattedMaxWage = numberCommaFormatter(MAX_WAGE);
154+
155+
if (hourlyPay < MIN_WAGE) {
94156
openModal({
95157
type: "alert",
96158
iconType: "warning",
97-
message: "유효한 시급을 입력해 주세요.",
159+
message: "시급은 최저시급 이상이어야 합니다.",
160+
});
161+
return;
162+
} else if (hourlyPay > MAX_WAGE) {
163+
openModal({
164+
type: "alert",
165+
iconType: "warning",
166+
message: `시급은 ${formattedMaxWage}원 이하여야 합니다.`,
98167
});
99168
return;
100169
}
@@ -153,86 +222,88 @@ export default function NoticeEditPage() {
153222
};
154223

155224
return (
156-
<form
157-
className="w-full max-w-[964px] mx-auto px-4 py-12"
158-
onSubmit={(e) => {
159-
e.preventDefault();
160-
handleSubmit();
161-
}}
162-
>
163-
<div className="flex justify-between items-center mb-8">
164-
<h2 className="sm:text-[1.75rem] text-[1.25rem] font-bold">
165-
공고 수정
166-
</h2>
167-
<button type="button" onClick={() => navigate("/shop")}>
168-
<Close className="sm:w-8 sm:h-8 w-6 h-6 cursor-pointer" />
169-
</button>
170-
</div>
171-
172-
<div className="grid lg:grid-cols-3 sm:grid-cols-2 grid-cols-1 gap-5 mb-6">
173-
<TextField.Input
174-
label="시급*"
175-
placeholder="입력"
176-
fullWidth
177-
value={form.hourlyPay}
178-
onChange={(e) => {
179-
const rawValue = e.target.value;
180-
const digitsOnly = extractDigits(rawValue);
181-
const formatted = digitsOnly
182-
? numberCommaFormatter(Number(digitsOnly))
183-
: "";
184-
handleChange("hourlyPay", formatted);
185-
}}
186-
postfix={<span className="text-black mr-2"></span>}
187-
/>
188-
<div className="flex flex-col">
189-
<label className="inline-block mb-2 leading-[1.625rem]">
190-
시작 일시*
191-
</label>
192-
<DatePicker
193-
selected={form.startsAt}
194-
onChange={(date) => handleChange("startsAt", date)}
195-
showTimeSelect
196-
timeFormat="HH:mm"
197-
timeIntervals={10}
198-
dateFormat="yyyy-MM-dd HH:mm"
199-
placeholderText="선택"
200-
className="w-full border border-gray-30 focus-within:border-blue-20 rounded-[0.375rem] py-4 px-5 text-[1rem]"
225+
<div className="w-full bg-gray-5 min-h-screen">
226+
<form
227+
className="w-full max-w-[964px] mx-auto px-4 py-12"
228+
onSubmit={(e) => {
229+
e.preventDefault();
230+
handleSubmit();
231+
}}
232+
>
233+
<div className="flex justify-between items-center mb-8">
234+
<h2 className="sm:text-[1.75rem] text-[1.25rem] font-bold">
235+
공고 수정
236+
</h2>
237+
<button type="button" onClick={() => navigate("/shop")}>
238+
<Close className="sm:w-8 sm:h-8 w-6 h-6 cursor-pointer" />
239+
</button>
240+
</div>
241+
242+
<div className="grid lg:grid-cols-3 sm:grid-cols-2 grid-cols-1 gap-5 mb-6">
243+
<TextField.Input
244+
label="시급*"
245+
placeholder="입력"
246+
fullWidth
247+
value={form.hourlyPay}
248+
onChange={(e) => {
249+
const rawValue = e.target.value;
250+
const digitsOnly = extractDigits(rawValue);
251+
const formatted = digitsOnly
252+
? numberCommaFormatter(Number(digitsOnly))
253+
: "";
254+
handleChange("hourlyPay", formatted);
255+
}}
256+
postfix={<span className="text-black mr-2"></span>}
201257
/>
258+
<div className="flex flex-col">
259+
<label className="inline-block mb-2 leading-[1.625rem]">
260+
시작 일시*
261+
</label>
262+
<DatePicker
263+
selected={form.startsAt}
264+
onChange={(date) => handleChange("startsAt", date)}
265+
showTimeSelect
266+
timeFormat="HH:mm"
267+
timeIntervals={10}
268+
dateFormat="yyyy-MM-dd HH:mm"
269+
placeholderText="선택"
270+
className="w-full border border-gray-30 focus-within:border-blue-20 rounded-[0.375rem] py-4 px-5 text-[1rem] bg-white"
271+
/>
272+
</div>
273+
<TextField.Input
274+
label="업무 시간*"
275+
placeholder="입력"
276+
fullWidth
277+
value={form.workhour}
278+
onChange={(e) => handleChange("workhour", e.target.value)}
279+
postfix={
280+
<span className="text-black mr-2 whitespace-nowrap">시간</span>
281+
}
282+
/>
283+
</div>
284+
<div className="mb-10">
285+
<TextField.TextArea
286+
label="공고 설명 (최대 500자)"
287+
placeholder="입력"
288+
fullWidth
289+
rows={4}
290+
maxLength={500}
291+
value={form.description}
292+
onChange={(e) => handleChange("description", e.target.value)}
293+
/>
294+
</div>
295+
<div className="text-center">
296+
<Button
297+
variant="primary"
298+
textSize="md"
299+
className="sm:w-[350px] w-full px-34 py-3.5"
300+
disabled={isSubmitting}
301+
type="submit"
302+
>
303+
수정하기
304+
</Button>
202305
</div>
203-
<TextField.Input
204-
label="업무 시간*"
205-
placeholder="입력"
206-
fullWidth
207-
value={form.workhour}
208-
onChange={(e) => handleChange("workhour", e.target.value)}
209-
postfix={
210-
<span className="text-black mr-2 whitespace-nowrap">시간</span>
211-
}
212-
/>
213-
</div>
214-
<div className="mb-10">
215-
<TextField.TextArea
216-
label="공고 설명 (최대 500자)"
217-
placeholder="입력"
218-
fullWidth
219-
rows={4}
220-
maxLength={500}
221-
value={form.description}
222-
onChange={(e) => handleChange("description", e.target.value)}
223-
/>
224-
</div>
225-
<div className="text-center">
226-
<Button
227-
variant="primary"
228-
textSize="md"
229-
className="sm:w-[350px] w-full px-34 py-3.5"
230-
disabled={isSubmitting}
231-
type="submit"
232-
>
233-
수정하기
234-
</Button>
235-
</div>
236-
</form>
306+
</form>
307+
</div>
237308
);
238309
}

0 commit comments

Comments
 (0)