diff --git a/src/components/FifthModal.js b/src/components/FifthModal.js new file mode 100644 index 0000000..47279a0 --- /dev/null +++ b/src/components/FifthModal.js @@ -0,0 +1,25 @@ +import React from 'react'; +import Modal from 'react-modal'; +import './FourthModal.css'; + +const FirstModal = ({ isOpen, onRequestClose, onSelectNumChild }) => { + return ( + + + + onSelectNumChild('그렇다')} className="modal-button">그렇다 + onSelectNumChild('아니다')} className="modal-button">아니다 + + + + ); +} + +export default FirstModal; \ No newline at end of file diff --git a/src/components/FirstModal.css b/src/components/FirstModal.css index dde98c2..edcd400 100644 --- a/src/components/FirstModal.css +++ b/src/components/FirstModal.css @@ -1,13 +1,10 @@ .Modal { - position: absolute; - top: 40px; - left: 40px; - right: 40px; - bottom: 40px; + width: 100%; + height: auto; background: #fff; overflow: auto; outline: none; - padding: '20px'; + padding: '30px'; } .Overlay { @@ -19,20 +16,22 @@ } .modal-content { + display: block; text-align: center; } .button-container { - margin-top: 20px; + display: block; } .modal-button { - background-color: #A883D8; + background-color: #EAE3FC; + width: 168px; color: black; border: none; padding: 10px 20px; margin: 10px; - border-radius: 20px; + border-radius: 44px; font-size: 16px; cursor: pointer; transition: background-color 0.3s ease; diff --git a/src/components/FirstModal.js b/src/components/FirstModal.js index 75bd562..5b3775b 100644 --- a/src/components/FirstModal.js +++ b/src/components/FirstModal.js @@ -2,21 +2,22 @@ import React from 'react'; import Modal from 'react-modal'; import './FirstModal.css'; -const FirstModal = ({ isOpen, onRequestClose }) => { +const FirstModal = ({ isOpen, onRequestClose, onSelectNumberOfPeople }) => { return ( - 1명 - 2명 - 3명 - 4명 이상 + onSelectNumberOfPeople('1명')} className="modal-button">1명 + onSelectNumberOfPeople('2명')} className="modal-button">2명 + onSelectNumberOfPeople('3명')} className="modal-button">3명 + onSelectNumberOfPeople('4명 이상')} className="modal-button">4명 이상 diff --git a/src/components/FourthModal.css b/src/components/FourthModal.css new file mode 100644 index 0000000..fab6eb0 --- /dev/null +++ b/src/components/FourthModal.css @@ -0,0 +1,43 @@ +.Modal { + width: 110px; + height: auto; + position: absolute; + background: #fff; + overflow: auto; + outline: none; + padding: '30px'; +} + +.Overlay { + position: 'fixed'; + top: 0; + left: 0; + right: 0; + bottom: 0; +} + +.modal-content { + text-align: center; +} + +.button-container { + align-items: center; +} + +.modal-button { + background-color: #EAE3FC; + width: 173px; + height: 44px; + color: black; + border: none; + padding: 10px 20px; + margin: 10px; + border-radius: 20px; + font-size: 16px; + cursor: pointer; + transition: background-color 0.3s ease; +} + +.modal-button.selected { + background-color: #9A8CFF; +} \ No newline at end of file diff --git a/src/components/FourthModal.js b/src/components/FourthModal.js new file mode 100644 index 0000000..0786440 --- /dev/null +++ b/src/components/FourthModal.js @@ -0,0 +1,25 @@ +import React from 'react'; +import Modal from 'react-modal'; +import './FourthModal.css'; + +const FirstModal = ({ isOpen, onRequestClose, onSelectCar }) => { + return ( + + + + onSelectCar('있다')} className="modal-button">있다 + onSelectCar('없다')} className="modal-button">없다 + + + + ); +} + +export default FirstModal; \ No newline at end of file diff --git a/src/components/SecondModal.js b/src/components/SecondModal.js new file mode 100644 index 0000000..5841a40 --- /dev/null +++ b/src/components/SecondModal.js @@ -0,0 +1,27 @@ +import React from 'react'; +import Modal from 'react-modal'; +import './FirstModal.css'; + +const FirstModal = ({ isOpen, onRequestClose, onSelectNumberOfWeek }) => { + return ( + + + + onSelectNumberOfWeek('1주')} className="modal-button">1주 + onSelectNumberOfWeek('2주')} className="modal-button">2주 + onSelectNumberOfWeek('3주')} className="modal-button">3주 + onSelectNumberOfWeek('4주')} className="modal-button">4주 + + + + ); +} + +export default FirstModal; \ No newline at end of file diff --git a/src/components/ThirdModal.css b/src/components/ThirdModal.css new file mode 100644 index 0000000..7bee094 --- /dev/null +++ b/src/components/ThirdModal.css @@ -0,0 +1,42 @@ +.Modal { + width: 110px; + height: auto; + position: absolute; + background: #fff; + overflow: auto; + outline: none; + padding: '30px'; +} + +.Overlay { + position: 'fixed'; + top: 0; + left: 0; + right: 0; + bottom: 0; +} + +.modal-content { + text-align: center; +} + +.button-container { + align-items: center; +} + +.modal-button { + background-color: #EAE3FC; + width: 107px; + color: black; + border: none; + padding: 10px 20px; + margin: 10px; + border-radius: 20px; + font-size: 16px; + cursor: pointer; + transition: background-color 0.3s ease; +} + +.modal-button.selected { + background-color: #9A8CFF; +} \ No newline at end of file diff --git a/src/components/ThirdModal.js b/src/components/ThirdModal.js new file mode 100644 index 0000000..f0b05b6 --- /dev/null +++ b/src/components/ThirdModal.js @@ -0,0 +1,26 @@ +import React from 'react'; +import Modal from 'react-modal'; +import './ThirdModal.css'; + +const FirstModal = ({ isOpen, onRequestClose, onSelectStatus }) => { + return ( + + + + onSelectStatus('학생')} className="modal-button">학생 + onSelectStatus('직장인')} className="modal-button">직장인 + onSelectStatus('기타')} className="modal-button">기타 + + + + ); +} + +export default FirstModal; \ No newline at end of file diff --git a/src/pages/Chat.js b/src/pages/Chat.js index 0148c99..81e216b 100644 --- a/src/pages/Chat.js +++ b/src/pages/Chat.js @@ -2,6 +2,11 @@ import React, { useState, useEffect } from 'react'; import styled, { keyframes } from 'styled-components'; import chatProfile from '../assets/chatProfilePic.svg'; import FirstModal from '../components/FirstModal'; +import SecondModal from '../components/SecondModal'; +import ThirdModal from '../components/ThirdModal'; +import FourthModal from '../components/FourthModal'; +import FifthModal from '../components/FifthModal'; + const StyledChat = styled.div` background-color: #EAE3FC; @@ -25,6 +30,19 @@ const slideIn = keyframes` } `; +const MyChatBubble = styled.div` + background-color: #6750A4; + color: #FFFFFF; + padding: 10px 20px; + border-radius: 20px; + margin-bottom: 10px; + max-width: 70%; + animation: ${slideIn} 0.5s ease-out; + opacity: 0; + animation-fill-mode: forwards; + margin-left: auto; + `; + const ChatBubble = styled.div` background-color: #ffffff; padding: 10px 20px; @@ -40,26 +58,45 @@ const ChatContainer = styled.div` height: 100vh; `; -const customStyles = { - content: { - top: '50%', - left: '50%', - right: 'auto', - bottom: 'auto', - marginRight: '-50%', - transform: 'translate(-50%, -50%)', - padding: '20px', - borderRadius: '10px', - }, -}; - const Chat = () => { const [nickname, setNickname] = useState(''); + const [messages, setMessages] = useState([]); + const [secondMessages, setSecondMessages] = useState([]); + const [thirdMessages, setThirdMessages] = useState([]); + const [fourthMessages, setFourthMessages] = useState([]); + const [fifthMessages, setFifthMessages] = useState([]); + const [finalMessages, setFinalMessages] = useState([]); + const [index, setIndex] = useState(0); + const [secondIndex, setSecondIndex] = useState(0); + const [thirdIndex, setThirdIndex] = useState(0); + const [fourthIndex, setFourthIndex] = useState(0); + const [fifthIndex, setFifthIndex] = useState(0); + const [finalIndex, setFinalIndex] = useState(0); + const [modalOpenFirst, setModalOpenFirst] = useState(false); const [modalOpenSecond, setModalOpenSecond] = useState(false); + const [modalOpenThird, setModalOpenThird] = useState(false); + const [modalOpenFourth, setModalOpenFourth] = useState(false); + const [modalOpenFifth, setModalOpenFifth] = useState(false); + const [modalOpenFinal, setModalOpenFinal] = useState(false); + + const [selectedNumPeople, setSelectedNumPeople] = useState(''); + const [selectedNumWeek, setSelectedNumWeek] = useState(''); + const [selectedStatus, setSelectedStatus] = useState(''); + const [selectedCar, setSelectedCar] = useState(''); + const [selectedNumChild, setSelectedNumChild] = useState(''); + + // chat 끝난 후 + const [firstEffectFinished, setFirstEffectFinished] = useState(false); + const [secondEffectFinished, setSecondEffectFinished] = useState(false); + const [thirdEffectFinished, setThirdEffectFinished] = useState(false); + const [fourthEffectFinished, setFourthEffectFinished] = useState(false); + const [fifthEffectFinished, setFifthEffectFinished] = useState(false); + const [finalEffectFinished, setFinalEffectFinished] = useState(false); + useEffect(() => { const storedNickname = localStorage.getItem('nickname'); @@ -68,22 +105,37 @@ const Chat = () => { } }, []); - const chatMessages = [ + const FirstChatMessages = [ '살아봐유에 오신걸 환영해요!', `${nickname}님에게 딱 맞는 대전 집을 찾기 위해 몇 가지 질문에 대답해주세요!`, '몇명이 살 예정인가요?', + ]; + + const SecondChatMessages = [ '그렇군요!', '그럼 대전에 얼마나 머무를 예정인가요?', + ] + + const ThirdChatMessages = [ '학생이신가요 아니면 직장인이신가요?', + ] + + const FourthChatMessages = [ '아 그러시군요!', '자차가 있으신가요?', + ] + + const FifthChatMessages = [ '마지막 질문입니다!', '아이와 함께 지낼 예정인가요?', + ] + + const FinalChatMessages = [ '마지막까지 성실하게 답변해주셔서 감사해요!', '혹시 저희가 알면 좋은 추가정보가 있을까요?', '예를 들어 휠체어를 이용한다던가, 근처에 병원이 있어야 한다던지요!', '만약 추가정보가 없다면 없다고 답변해주세요' - ]; + ] const showModalFirst = () => { setModalOpenFirst(true); @@ -91,14 +143,31 @@ const Chat = () => { const closeModalFirst = () => { setModalOpenFirst(false); + }; - setIndex((prevIndex) => { - const nextIndex = prevIndex + 1; - if (nextIndex < chatMessages.length) { - setMessages((prevMessages) => [...prevMessages, chatMessages[nextIndex]]); - } - return nextIndex; - }); + const handleSelectNumberOfPeople = (selection) => { + setSelectedNumPeople(selection); + closeModalFirst(); + }; + + const handleSelectNumberOfWeek = (selection) => { + setSelectedNumWeek(selection); + closeModalSecond(); + }; + + const handleSelectStatus = (selection) => { + setSelectedStatus(selection); + closeModalThird(); + }; + + const handleSelectCar = (selection) => { + setSelectedCar(selection); + closeModalFourth(); + }; + + const handleSelectNumberOfChild = (selection) => { + setSelectedNumChild(selection); + closeModalFifth(); }; const showModalSecond = () => { @@ -107,58 +176,200 @@ const Chat = () => { const closeModalSecond = () => { setModalOpenSecond(false); + }; - setIndex((prevIndex) => { - const nextIndex = prevIndex + 1; - if (nextIndex < chatMessages.length) { - setMessages((prevMessages) => [...prevMessages, chatMessages[nextIndex]]); - } - return nextIndex; - }); + const showModalThird = () => { + setModalOpenThird(true); + }; + + const closeModalThird = () => { + setModalOpenThird(false); + }; + + const showModalFourth = () => { + setModalOpenFourth(true); + }; + + const closeModalFourth = () => { + setModalOpenFourth(false); + }; + + const showModalFifth = () => { + setModalOpenFifth(true); + }; + + const closeModalFifth = () => { + setModalOpenFifth(false); }; - useEffect(() => { const intervalId = setInterval(() => { - if (index < chatMessages.length) { - if (chatMessages[index] === '그렇군요!') { + if (index <= FirstChatMessages.length) { + if (index === 3) { showModalFirst(); clearInterval(intervalId); - } - - else if(chatMessages[index] === '그럼 대전에 얼마나 머무를 예정인가요?'){ + setFirstEffectFinished(true); // 첫 번째 useEffect 완료 상태를 true로 설정 + } else { + setMessages(prevMessages => [...prevMessages, FirstChatMessages[index]]); + setIndex(prevIndex => prevIndex + 1); + } + } + }, 1000); + + return () => clearInterval(intervalId); + }, [index]); + + useEffect(() => { + if (!firstEffectFinished || !selectedNumPeople) return; + + const intervalId = setInterval(() => { + if (secondIndex <= SecondChatMessages.length) { + if (secondIndex === 2) { showModalSecond(); clearInterval(intervalId); + setSecondEffectFinished(true); + } else { + setSecondMessages(prevSecondMessages => [...prevSecondMessages, SecondChatMessages[secondIndex]]); + setSecondIndex(prevSecondIndex => prevSecondIndex + 1); } + } + }, 1000); - else if(chatMessages[index] === '학생이신가요 아니면 직장인이신가요?'){ - showModalSecond(); + return () => clearInterval(intervalId); + }, [secondIndex, firstEffectFinished, selectedNumPeople]); + + // 3번째 대화 + useEffect(() => { + if (!firstEffectFinished || !secondEffectFinished || !selectedNumPeople || !selectedNumWeek) + return; + + const intervalId = setInterval(() => { + if (thirdIndex <= ThirdChatMessages.length) { + if (thirdIndex === 1) { + showModalThird(); clearInterval(intervalId); + setThirdEffectFinished(true); + } else { + setThirdMessages(prevThirdMessages => [...prevThirdMessages, ThirdChatMessages[thirdIndex]]); + setThirdIndex(prevThirdIndex => prevThirdIndex + 1); } - else { - setMessages(prevMessages => [...prevMessages, chatMessages[index]]); - setIndex(prevIndex => prevIndex + 1); + } + }, 1000); + + return () => clearInterval(intervalId); + }, [thirdIndex, secondEffectFinished, selectedNumWeek]); + + // 4번째 대화 + useEffect(() => { + if (!firstEffectFinished || !secondEffectFinished || !thirdEffectFinished || !selectedNumPeople || !selectedNumWeek || !selectedStatus) + return; + + const intervalId = setInterval(() => { + if (fourthIndex <= FourthChatMessages.length) { + if (fourthIndex === 2) { + showModalFourth(); + clearInterval(intervalId); + setFourthEffectFinished(true); + } else { + setFourthMessages(prevFourthMessages => [...prevFourthMessages, FourthChatMessages[fourthIndex]]); + setFourthIndex(prevFourthIndex => prevFourthIndex + 1); } - } else { - clearInterval(intervalId); } }, 1000); return () => clearInterval(intervalId); - }, [index, chatMessages]); + }, [fourthIndex, thirdEffectFinished, selectedStatus]); + + // 5번째 대화 + useEffect(() => { + if (!firstEffectFinished || !secondEffectFinished || !thirdEffectFinished || !fourthEffectFinished + || !selectedNumPeople || !selectedNumWeek || !selectedStatus || !selectedCar) + return; + + const intervalId = setInterval(() => { + if (fifthIndex <= FifthChatMessages.length) { + if (fifthIndex === 2) { + showModalFifth(); + clearInterval(intervalId); + setFifthEffectFinished(true); + } else { + setFifthMessages(prevFifthMessages => [...prevFifthMessages, FifthChatMessages[fifthIndex]]); + setFifthIndex(prevFifthIndex => prevFifthIndex + 1); + } + } + }, 1000); + + return () => clearInterval(intervalId); + }, [fifthIndex, fourthEffectFinished, selectedCar]); + + // 6번째 대화 + const [isWaitingForInput, setIsWaitingForInput] = useState(false); + const [userInput, setUserInput] = useState(""); + + useEffect(() => { + if (!firstEffectFinished || !secondEffectFinished || !thirdEffectFinished || !fourthEffectFinished || !fifthEffectFinished + || !selectedNumPeople || !selectedNumWeek || !selectedStatus || !selectedNumChild || isWaitingForInput) + return; + + const intervalId = setInterval(() => { + if (finalIndex <= FinalChatMessages.length) { + if (finalIndex === 4) { + clearInterval(intervalId); + setIsWaitingForInput(true); + } else { + setFinalMessages(prevFinalMessages => [...prevFinalMessages, FinalChatMessages[finalIndex]]); + setFinalIndex(prevFinalIndex => prevFinalIndex + 1); + } + } + }, 1000); + + return () => clearInterval(intervalId); + }, [finalIndex, fifthEffectFinished, selectedNumChild, isWaitingForInput]); + + +return ( + + + {messages.map((message, idx) => ( + {message} + ))} + {selectedNumPeople && {`${selectedNumPeople}이 살거야`}} + {modalOpenFirst && } + + {secondMessages.map((message, idx) => ( + {message} + ))} + {modalOpenSecond && } + {selectedNumWeek && {`${selectedNumWeek}일 지낼 예정이야`}} + + {thirdMessages.map((message, idx) => ( + {message} + ))} + + {modalOpenThird && } + {selectedStatus && {`나는 ${selectedStatus}이야`}} + + {fourthMessages.map((message, idx) => ( + {message} + ))} + + {modalOpenFourth && } + {selectedCar === '있다' ? 나는 주로 운전해서 다녀 : selectedCar === '없다' ? 나는 주로 대중교통을 이용해 : null} + + {fifthMessages.map((message, idx) => ( + {message} + ))} - return ( - - - {messages.map((message, idx) => ( - {message} - ))} + {modalOpenFifth && } + {selectedNumChild === '그렇다' ? 응, 아이가 있어 : selectedNumChild === '아니다' ? 아니, 아이가 없어 : null} - {modalOpenFirst && } + {finalMessages.map((message, idx) => ( + {message} + ))} - - - ); + + +); } export default Chat;