diff --git a/package-lock.json b/package-lock.json index 9558ad4..840d0a3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "openmind", "version": "0.0.0", "dependencies": { + "pretendard": "^1.3.9", "react": "^19.2.0", "react-dom": "^19.2.0", "react-router": "^7.10.1", @@ -4286,6 +4287,12 @@ "node": ">= 0.8.0" } }, + "node_modules/pretendard": { + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/pretendard/-/pretendard-1.3.9.tgz", + "integrity": "sha512-PaQAADyLY5v4kYFwkpSJHbSSYIkiriY/1xXw75TKoZ9UQQqeU+tvP05yTdZAWibiIYoo8ZKtRv8PM7w0IaywSw==", + "license": "OFL-1.1" + }, "node_modules/prettier": { "version": "3.7.4", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.7.4.tgz", diff --git a/package.json b/package.json index 17a1f79..e465a1d 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "preview": "vite preview" }, "dependencies": { + "pretendard": "^1.3.9", "react": "^19.2.0", "react-dom": "^19.2.0", "react-router": "^7.10.1", diff --git a/src/components/Modal/ModalTest.jsx b/src/components/Modal/ModalTest.jsx index 5b780aa..00dcf95 100644 --- a/src/components/Modal/ModalTest.jsx +++ b/src/components/Modal/ModalTest.jsx @@ -1,50 +1,46 @@ -// src/pages/ModalTest.jsx import { useState } from 'react'; -import QuestionModal from './QuestionModal'; -import Button from '../../components/Button/Button'; +import Button from '@/components/Button/Button'; +import QuestionModal from '@/components/Modal/QuestionModal'; +/** + * Modal 테스트 페이지 + * + * UI가 잘 작동하는지 테스트 + * - 콘솔에서 질문 내용 확인 + */ export default function ModalTest() { const [isOpen, setIsOpen] = useState(false); - const handleOpenModal = () => setIsOpen(true); - const handleCloseModal = () => setIsOpen(false); + + // 테스트용 받는 사람 정보 + const recipient = { + name: '테스트용', + imageSource: + 'https://fastly.picsum.photos/id/505/200/200.jpg?hmac=c295sjTIAZ_9Gj-PENrzAbATNIiWPL1dmhIhWndYnyo', // 임시 이미지 + }; + const testSubjectId = 12629; // 실제 존재하는 ID Test + + const QuestionSuccess = newQuestion => { + console.log('질문 등록 성공!', newQuestion); + }; return ( -
- {/* // style={{ padding: '40px' }} */} -

모달 테스트 페이지

+
+

Modal 테스트

- +
+
- + {/* QuestionModal 테스트 버튼 */} + - {/* Box 버튼 - 기본 */} - - {/* Box 버튼 - 전체 너비 (외부 제어) */} - - {/* Floating 버튼 */} - - - {/* 비활성화 */} - - {/* 화살표 아이콘 */} - + {/* QuestionModal */} + setIsOpen(false)} + recipient={recipient} + subjectId={testSubjectId} + onSuccess={QuestionSuccess} + />
); } diff --git a/src/components/Modal/QuestionModal.jsx b/src/components/Modal/QuestionModal.jsx index 5e21570..209a4a5 100644 --- a/src/components/Modal/QuestionModal.jsx +++ b/src/components/Modal/QuestionModal.jsx @@ -1,33 +1,25 @@ import { useState } from 'react'; -import Modal from '../Modal/Modal'; -import Button from '../Button/Button'; -import TextArea from '../TextArea/TextArea'; -import QuestionTarget from './QuestionTarget'; -import ModalHeader from './ModalHeader'; -import { createQuestion } from '@/services/questionsApi'; +import Modal from '@/components/Modal/Modal'; +import Button from '@/components/Button/Button'; +import TextArea from '@/components/TextArea/TextArea'; +import QuestionTarget from '@/components/Modal/QuestionTarget'; +import ModalHeader from '@/components/Modal/ModalHeader'; +import { useToast } from '@/contexts/Toast/ToastCopy'; import styles from './QuestionModal.module.css'; /** - * 질문 작성 모달 컴포넌트 (API 연동 완료) - * - * 질문을 작성하고 서버에 전송 + * 질문 작성 모달 컴포넌트 * * @param {boolean} isOpen - 모달 열림/닫힘 (true/false) * @param {function} onClose - 모달 닫기 함수 * @param {object} recipient - 받는 사람 정보 { name, imageSource } - * @param {number} subjectId - 질문 받을 사람의 ID (서버 전송 시 필요) - * @param {function} onSuccess - 질문 등록 성공 시 실행할 함수 + * @param {function} onSuccess - 질문 제출 시 실행할 콜백 함수 (content를 인자로 받음) */ -function QuestionModal({ isOpen, onClose, recipient, subjectId, onSuccess }) { - // 질문 내용 상태 - // 사용자가 textarea에 입력하는 내용을 저장 +function QuestionModal({ isOpen, onClose, recipient, onSuccess }) { + // 입력 내용 상태 const [content, setContent] = useState(''); - - // 전송 중 상태 - // true: API 호출 중 (버튼 비활성화, 중복 클릭 방지) - // false: 대기 중 const [isSubmitting, setIsSubmitting] = useState(false); - + const { showToast } = useToast(); // 모달 닫았을 시 내용 삭제 const handleClose = () => { setContent(''); @@ -38,23 +30,18 @@ function QuestionModal({ isOpen, onClose, recipient, subjectId, onSuccess }) { setIsSubmitting(true); try { - // API 호출 - const newQuestion = await createQuestion(subjectId, { content }); + // 부모가 전달한 callback 실행 (content만 전달) + await onSuccess(content); // 성공 시 처리 - setContent(''); // 입력창 비우기 - onClose(); // 모달 닫기 - - onSuccess(newQuestion); // 부모에게 새 질문 데이터 전달 - console.log('onSuccess 성공내역 ', newQuestion); + setContent(''); + onClose(); + showToast('질문이 등록되었습니다'); } catch (error) { // 실패 시 에러 처리 - console.error('질문 등록 실패:', error); - alert('질문 등록에 실패했습니다. 다시 시도해주세요.'); + showToast('질문 등록에 실패했습니다'); } finally { - // 전송 종료 - alert('질문 등록 성공했습니다.!'); setIsSubmitting(false); // 버튼 보이게 } }; diff --git a/src/components/Modal/QuestionTarget.jsx b/src/components/Modal/QuestionTarget.jsx index 4822ca2..4b3df1e 100644 --- a/src/components/Modal/QuestionTarget.jsx +++ b/src/components/Modal/QuestionTarget.jsx @@ -1,5 +1,5 @@ import styles from './QuestionModal.module.css'; - +import { Avatar } from '@/components/Avatar/Avatar'; /** * 질문 대상자 정보 컴포넌트 * @@ -13,12 +13,14 @@ function QuestionTarget({ target }) {
To. - {/* 프로필 이미지 */} - {`${target.name} + {/* Avatar 컴포넌트로 교체 */} + + {/* 이미지 로딩 시도 */} + + + {/* 이미지 로딩 실패 시 대체 UI (이름 첫 글자) */} + {target.name[0]} + {/* 받는 사람 이름 */} {target.name} diff --git a/src/main.jsx b/src/main.jsx index 8dbc9a6..ad7bdc4 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -11,7 +11,7 @@ import List from './pages/List/ListPage.jsx'; import PostDetail from './pages/Post/PostDetail.jsx'; import PostAnswer from './pages/Post/PostAnswer.jsx'; import Layout from './components/layout/Layout.jsx'; - +import ModalTest from './components/Modal/ModalTest.jsx'; import './index.css'; import { ToastProvider } from './contexts/Toast/ToastCopy.jsx'; @@ -28,6 +28,10 @@ const router = createBrowserRouter([ path: 'list', Component: List, }, + { + path: '/ModalTest', + element: , + }, { path: 'post', children: [