diff --git a/src/features/event/ui/LinkInput.tsx b/src/features/event/ui/LinkInput.tsx index dcb3be53..bf967cc0 100644 --- a/src/features/event/ui/LinkInput.tsx +++ b/src/features/event/ui/LinkInput.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { useState, useEffect } from 'react'; import { FunnelState } from '../model/FunnelContext'; import AddButton from '../../../../public/assets/event-manage/creation/AddBtn.svg'; import CloseButton from '../../../../public/assets/event-manage/creation/CloseBtn.svg'; @@ -14,9 +14,10 @@ interface LinkInputProps { onChange?: (value: Link[]) => void; eventState?: FunnelState['eventState']; setEventState?: React.Dispatch>; + onValidationChange?: (isValid: boolean) => void; } -const LinkInput = ({ value, onChange, eventState, setEventState }: LinkInputProps) => { +const LinkInput = ({ value, onChange, eventState, setEventState, onValidationChange }: LinkInputProps) => { const links = value ?? eventState?.referenceLinks ?? []; const [activeInput, setActiveInput] = useState<{ field: 'title' | 'url' | null }>({ @@ -26,6 +27,11 @@ const LinkInput = ({ value, onChange, eventState, setEventState }: LinkInputProp field: null, }); + const validateLinks = (linkArray: Link[]) => { + if (linkArray.length === 0) return true; + return linkArray.every(link => link.title.trim() !== '' && link.url.trim() !== ''); + }; + const updateAll = (newLinks: Link[]) => { onChange?.(newLinks); setEventState?.(prev => ({ ...prev, referenceLinks: newLinks })); @@ -44,9 +50,20 @@ const LinkInput = ({ value, onChange, eventState, setEventState }: LinkInputProp updateAll(newLinks); }; + useEffect(() => { + const isValid = validateLinks(links); + onValidationChange?.(isValid); + }, [links, onValidationChange]); + return (
-

관련 링크

+
+

관련 링크

+ {links.length > 0 && (

+ 링크 추가 시 하이퍼링크와 URL을 모두 입력해주세요 +

)} + +
{links.map((link, index) => (
@@ -64,7 +81,7 @@ const LinkInput = ({ value, onChange, eventState, setEventState }: LinkInputProp value={link.title} onChange={e => updateLink(index, 'title', e.target.value)} 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" - placeholder="참조링크" + placeholder="하이퍼링크" autoFocus={activeInput.field === link.title && activeInput.field === 'title'} />
diff --git a/src/pages/dashboard/ui/EventDetailPage.tsx b/src/pages/dashboard/ui/EventDetailPage.tsx index aeb63b22..6a11c6b0 100644 --- a/src/pages/dashboard/ui/EventDetailPage.tsx +++ b/src/pages/dashboard/ui/EventDetailPage.tsx @@ -20,6 +20,7 @@ const EventDetailPage = () => { const [bannerImageUrl, setBannerImageUrl] = useState(''); const [description, setDescription] = useState(''); const [referenceLinks, setReferenceLinks] = useState([]); + const [isLinkValid, setIsLinkValid] = useState(true); const queryClient = useQueryClient(); @@ -67,16 +68,29 @@ const EventDetailPage = () => { }); }; + const handleLinkValidation = (valid: boolean) => { + setIsLinkValid(valid); + }; + return (

이벤트 상세 정보

- +
-
); diff --git a/src/pages/event/ui/create-event/EventInfoPage.tsx b/src/pages/event/ui/create-event/EventInfoPage.tsx index 73c16675..1b37ef6a 100644 --- a/src/pages/event/ui/create-event/EventInfoPage.tsx +++ b/src/pages/event/ui/create-event/EventInfoPage.tsx @@ -12,6 +12,7 @@ const EventInfoPage = ({ onValidationChange }: EventInfoPageProps) => { const { eventState, setEventState } = useFunnelState(); const [isFileValid, setIsFileValid] = useState(false); const [isTextValid, setIsTextValid] = useState(false); + const [isLinkValid, setIsLinkValid] = useState(true); const handleFileValidation = (valid: boolean) => { setIsFileValid(valid); @@ -20,10 +21,15 @@ const EventInfoPage = ({ onValidationChange }: EventInfoPageProps) => { const handleTextValidation = (valid: boolean) => { setIsTextValid(valid); }; + + const handleLinkValidation = (valid: boolean) => { + setIsLinkValid(valid); + }; + useEffect(() => { - const allValid = isFileValid && isTextValid; + const allValid = isFileValid && isTextValid && isLinkValid; onValidationChange?.(allValid); - }, [isFileValid, isTextValid, onValidationChange]); + }, [isFileValid, isTextValid, isLinkValid,onValidationChange]); return (
@@ -34,13 +40,18 @@ const EventInfoPage = ({ onValidationChange }: EventInfoPageProps) => { useDefaultImage={false} onValidationChange={handleFileValidation} /> - - +
); }; diff --git a/src/shared/ui/backgrounds/EventRegisterLayout.tsx b/src/shared/ui/backgrounds/EventRegisterLayout.tsx index fc4cf4c7..ea6d9c6a 100644 --- a/src/shared/ui/backgrounds/EventRegisterLayout.tsx +++ b/src/shared/ui/backgrounds/EventRegisterLayout.tsx @@ -48,7 +48,7 @@ const EventRegisterLayout = ({
} onClick={() => navigate('/')} iconClassName="cursor-pointer z-30 ml-auto"