Skip to content

Commit 80ad3ee

Browse files
committed
refact: 이벤트 생성 간 관련 링크 입력 예외처리 구현
1 parent c5fdca4 commit 80ad3ee

File tree

3 files changed

+32
-9
lines changed

3 files changed

+32
-9
lines changed

src/features/event/ui/LinkInput.tsx

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState } from 'react';
1+
import { useState, useEffect } from 'react';
22
import { FunnelState } from '../model/FunnelContext';
33
import AddButton from '../../../../public/assets/event-manage/creation/AddBtn.svg';
44
import CloseButton from '../../../../public/assets/event-manage/creation/CloseBtn.svg';
@@ -14,9 +14,10 @@ interface LinkInputProps {
1414
onChange?: (value: Link[]) => void;
1515
eventState?: FunnelState['eventState'];
1616
setEventState?: React.Dispatch<React.SetStateAction<FunnelState['eventState']>>;
17+
onValidationChange?: (isValid: boolean) => void;
1718
}
1819

19-
const LinkInput = ({ value, onChange, eventState, setEventState }: LinkInputProps) => {
20+
const LinkInput = ({ value, onChange, eventState, setEventState, onValidationChange }: LinkInputProps) => {
2021
const links = value ?? eventState?.referenceLinks ?? [];
2122

2223
const [activeInput, setActiveInput] = useState<{ field: 'title' | 'url' | null }>({
@@ -26,6 +27,11 @@ const LinkInput = ({ value, onChange, eventState, setEventState }: LinkInputProp
2627
field: null,
2728
});
2829

30+
const validateLinks = (linkArray: Link[]) => {
31+
if (linkArray.length === 0) return true;
32+
return linkArray.every(link => link.title.trim() !== '' && link.url.trim() !== '');
33+
};
34+
2935
const updateAll = (newLinks: Link[]) => {
3036
onChange?.(newLinks);
3137
setEventState?.(prev => ({ ...prev, referenceLinks: newLinks }));
@@ -44,9 +50,20 @@ const LinkInput = ({ value, onChange, eventState, setEventState }: LinkInputProp
4450
updateAll(newLinks);
4551
};
4652

53+
useEffect(() => {
54+
const isValid = validateLinks(links);
55+
onValidationChange?.(isValid);
56+
}, [links, onValidationChange]);
57+
4758
return (
4859
<div className="flex flex-col gap-1">
49-
<h1 className="font-bold text-black text-lg">관련 링크</h1>
60+
<div className="flex flex-row gap-2 items-center">
61+
<h1 className="font-bold text-black text-lg">관련 링크</h1>
62+
{links.length > 0 && (<p className="text-placeholderText text-12">
63+
링크 추가 시 하이퍼링크와 URL을 모두 입력해주세요
64+
</p>)}
65+
66+
</div>
5067

5168
{links.map((link, index) => (
5269
<div key={index} className="mb-2">
@@ -64,7 +81,7 @@ const LinkInput = ({ value, onChange, eventState, setEventState }: LinkInputProp
6481
value={link.title}
6582
onChange={e => updateLink(index, 'title', e.target.value)}
6683
className="w-full min-w-[3rem] md:min-w-[6rem] h-8 text-placeholderText ml-1 outline-none bg-transparent text-sm md:text-base"
67-
placeholder="참조링크"
84+
placeholder="하이퍼링크"
6885
autoFocus={activeInput.field === link.title && activeInput.field === 'title'}
6986
/>
7087
</div>

src/pages/event/ui/create-event/EventInfoPage.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const EventInfoPage = ({ onValidationChange }: EventInfoPageProps) => {
1212
const { eventState, setEventState } = useFunnelState();
1313
const [isFileValid, setIsFileValid] = useState(false);
1414
const [isTextValid, setIsTextValid] = useState(false);
15+
const [isLinkValid, setIsLinkValid] = useState(false);
1516

1617
const handleFileValidation = (valid: boolean) => {
1718
setIsFileValid(valid);
@@ -20,10 +21,15 @@ const EventInfoPage = ({ onValidationChange }: EventInfoPageProps) => {
2021
const handleTextValidation = (valid: boolean) => {
2122
setIsTextValid(valid);
2223
};
24+
25+
const handleLinkValidation = (valid: boolean) => {
26+
setIsLinkValid(valid);
27+
};
28+
2329
useEffect(() => {
24-
const allValid = isFileValid && isTextValid;
30+
const allValid = isFileValid && isTextValid && isLinkValid;
2531
onValidationChange?.(allValid);
26-
}, [isFileValid, isTextValid, onValidationChange]);
32+
}, [isFileValid, isTextValid, isLinkValid,onValidationChange]);
2733

2834
return (
2935
<div className="w-full px-5 space-y-8">
@@ -34,13 +40,13 @@ const EventInfoPage = ({ onValidationChange }: EventInfoPageProps) => {
3440
useDefaultImage={false}
3541
onValidationChange={handleFileValidation}
3642
/>
37-
<TextEditor
43+
<TextEditor
3844
value={eventState?.description ?? ''}
3945
eventState={eventState}
4046
setEventState={setEventState}
4147
onValidationChange={handleTextValidation}
4248
/>
43-
<LinkInput eventState={eventState} setEventState={setEventState} />
49+
<LinkInput eventState={eventState} setEventState={setEventState} onValidationChange={handleLinkValidation} />
4450
</div>
4551
);
4652
};

src/shared/ui/backgrounds/EventRegisterLayout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ const EventRegisterLayout = ({
4848
<div className="absolute top-0 w-full h-36 md:h-40 bg-gradient-to-br from-[#FF5593] to-[rgb(255,117,119)] rounded-b-[60px] z-10">
4949
<Header
5050
centerContent="이벤트 등록"
51-
leftButtonLabel={goHome ? ( <IconButton
51+
leftButtonLabel={goHome ? (<IconButton
5252
iconPath={<img src={HomeButton} />}
5353
onClick={() => navigate('/')}
5454
iconClassName="cursor-pointer z-30 ml-auto"

0 commit comments

Comments
 (0)