diff --git a/admin/src/assets/icons/imageAddIcon.svg b/admin/src/assets/icons/imageAddIcon.svg new file mode 100644 index 0000000..518b453 --- /dev/null +++ b/admin/src/assets/icons/imageAddIcon.svg @@ -0,0 +1,3 @@ + + + diff --git a/admin/src/assets/icons/nextDayArrow.svg b/admin/src/assets/icons/nextDayArrow.svg new file mode 100644 index 0000000..e8d8177 --- /dev/null +++ b/admin/src/assets/icons/nextDayArrow.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/admin/src/assets/icons/previousDayArrow.svg b/admin/src/assets/icons/previousDayArrow.svg new file mode 100644 index 0000000..60603fe --- /dev/null +++ b/admin/src/assets/icons/previousDayArrow.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/admin/src/components/buttons/BlackButton.jsx b/admin/src/components/buttons/BlackButton.jsx new file mode 100644 index 0000000..3861fc9 --- /dev/null +++ b/admin/src/components/buttons/BlackButton.jsx @@ -0,0 +1,20 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +function BlackButton({ onClickFunc }) { + return ( + + ); +} + +BlackButton.propTypes = { + onClickFunc: PropTypes.func.isRequired, +}; + +//memo를 이용하여 rerender 방지 +export default React.memo(BlackButton); diff --git a/admin/src/components/header/AdminHeader.jsx b/admin/src/components/header/AdminHeader.jsx new file mode 100644 index 0000000..f54110b --- /dev/null +++ b/admin/src/components/header/AdminHeader.jsx @@ -0,0 +1,18 @@ +import React from 'react'; + +function AdminHeader() { + return ( +
+
+ + 이벤트 관리 + +
+ 진행중 +
+
+
+ ); +} + +export default AdminHeader; diff --git a/admin/src/pages/AdminIndex.jsx b/admin/src/pages/AdminIndex.jsx new file mode 100644 index 0000000..6cd7e11 --- /dev/null +++ b/admin/src/pages/AdminIndex.jsx @@ -0,0 +1,14 @@ +import React from 'react'; +import { Outlet } from 'react-router-dom'; +import AdminHeader from '@/components/header/AdminHeader'; + +function AdminIndex() { + return ( +
+ + +
+ ); +} + +export default AdminIndex; diff --git a/admin/src/pages/adminEditEvent/AdminEditEvent.jsx b/admin/src/pages/adminEditEvent/AdminEditEvent.jsx new file mode 100644 index 0000000..aecaaaf --- /dev/null +++ b/admin/src/pages/adminEditEvent/AdminEditEvent.jsx @@ -0,0 +1,16 @@ +import React from 'react'; +import AdminEditMiniQuiz from './adminEditMiniQuiz/AdminEditMiniQuiz'; +import AdminEditMiniQuizAnswer from './adminEditMiniQuizAnswer/AdminEditMiniQuizAnswer'; +import AdminEditDraw from './adminEditDraw/AdminEditDraw'; + +function AdminEditEvent() { + return ( +
+ + + +
+ ); +} + +export default AdminEditEvent; diff --git a/admin/src/pages/adminEditEvent/AdminEditHeader.jsx b/admin/src/pages/adminEditEvent/AdminEditHeader.jsx new file mode 100644 index 0000000..7007270 --- /dev/null +++ b/admin/src/pages/adminEditEvent/AdminEditHeader.jsx @@ -0,0 +1,51 @@ +import React, { useState } from 'react'; +import PropTypes from 'prop-types'; +import NextDayArrow from '@/assets/icons/nextDayArrow.svg'; +import PreviousDayArrow from '@/assets/icons/previousDayArrow.svg'; + +function AdminEditMiniQuizHeader({ info, date, setDate }) { + const [isPreviousDayDisabled, setIsPreviousDayDisabled] = useState( + date === 1, + ); + const handlePrev = () => { + if (isPreviousDayDisabled) { + return; + } + setDate(prev => prev - 1); + setIsPreviousDayDisabled(date < 3); + }; + const handleNext = () => { + setDate(prev => prev + 1); + setIsPreviousDayDisabled(false); + }; + return ( +
+ + {info} + +
+ PreviousDayArrow + Day {date} + NextDayArrow +
+
+ ); +} + +AdminEditMiniQuizHeader.propTypes = { + info: PropTypes.string.isRequired, + date: PropTypes.number, + setDate: PropTypes.func, +}; + +export default AdminEditMiniQuizHeader; diff --git a/admin/src/pages/adminEditEvent/adminEditDraw/AdminEditDraw.jsx b/admin/src/pages/adminEditEvent/adminEditDraw/AdminEditDraw.jsx new file mode 100644 index 0000000..fb154e9 --- /dev/null +++ b/admin/src/pages/adminEditEvent/adminEditDraw/AdminEditDraw.jsx @@ -0,0 +1,57 @@ +import React, { useState, useEffect } from 'react'; +import AdminEditHeader from '../AdminEditHeader'; +import AdminEditDrawContent from './AdminEditDrawContent'; +import BlackButton from '@/components/buttons/BlackButton'; + +function AdminEditDraw() { + const [date, setDate] = useState(1); + const [quizAnswerData, setAnswerData] = useState({ + id: 1, + draw_date: '2024-08-12', + lose_image: + 'https://softeer4-team8.s3.ap-northeast-2.amazonaws.com/%E1%84%8C%E1%85%A1%E1%84%8C%E1%85%A5%E1%86%AB%E1%84%80%E1%85%A5.svg', + lose_message: 'Sorry, you lose! Try again', + lose_scenario: 'The opposing team outplayed you!', + win_image: + 'https://softeer4-team8.s3.ap-northeast-2.amazonaws.com/%E1%84%8C%E1%85%A1%E1%84%8C%E1%85%A5%E1%86%AB%E1%84%80%E1%85%A5.svg', + win_message: 'Congraulation!, You have won!', + daily_message: + '캐스퍼 EV와 떠날 시간!\n 깜빡하고 차키를 안 가져왔네요.. 어떻게 해야할까요?', + }); + + const handleChange = (field, value) => { + setAnswerData(prevState => ({ + ...prevState, + [field]: value, + })); + }; + + const handleSubmit = async () => { + // try { + // const response = await axios.put(`/api/quiz/${quizAnswerData.id}`, quizAnswerData); + // console.log('수정된 데이터가 서버에 저장되었습니다.', response.data); + // } catch (error) { + // console.error('수정 요청 중 오류가 발생했습니다.', error); + // } + console.log('ddddd'); + }; + + return ( +
+ +
+ + +
+
+ ); +} + +export default AdminEditDraw; diff --git a/admin/src/pages/adminEditEvent/adminEditDraw/AdminEditDrawContent.jsx b/admin/src/pages/adminEditEvent/adminEditDraw/AdminEditDrawContent.jsx new file mode 100644 index 0000000..8cf0299 --- /dev/null +++ b/admin/src/pages/adminEditEvent/adminEditDraw/AdminEditDrawContent.jsx @@ -0,0 +1,80 @@ +import React, { useState } from 'react'; +import PropTypes from 'prop-types'; +import ImageAddIcon from '@/assets/icons/imageAddIcon.svg'; + +function AdminEditDrawContent({ response, onChange }) { + const [imagePreview, setImagePreview] = useState(response.quiz_image || ''); + + const handleImageChange = e => { + const file = e.target.files[0]; + if (!file) { + return; + } + const reader = new FileReader(); + reader.onloadend = () => { + setImagePreview(reader.result); + onChange('quiz_image', file); + }; + reader.readAsDataURL(file); + }; + + return ( + <> +
+ + onChange('lose_message', e.target.value)} + /> +
+
+
+ +

+ 포맷: jpg/ png/ jpeg +

+
+
+ {imagePreview && ( + Preview + )} + ImageAddIcon + +
+
+ + ); +} + +AdminEditDrawContent.propTypes = { + response: PropTypes.object.isRequired, + onChange: PropTypes.func.isRequired, +}; + +export default AdminEditDrawContent; diff --git a/admin/src/pages/adminEditEvent/adminEditMiniQuiz/AdminEditMiniQuiz.jsx b/admin/src/pages/adminEditEvent/adminEditMiniQuiz/AdminEditMiniQuiz.jsx new file mode 100644 index 0000000..421cbf6 --- /dev/null +++ b/admin/src/pages/adminEditEvent/adminEditMiniQuiz/AdminEditMiniQuiz.jsx @@ -0,0 +1,50 @@ +import React, { useState, useEffect } from 'react'; +import AdminEditHeader from '../AdminEditHeader'; +import AdminEditMiniQuizContent from './AdminEditMiniQuizContent'; +import BlackButton from '@/components/buttons/BlackButton'; + +function AdminEditMiniQuiz() { + const [date, setDate] = useState(1); + const [quizData, setQuizData] = useState({ + id: 1, + quiz_date: '2024-08-14', + quiz_description: '오늘의 퀴즈는?? 두둥탁!!', + quiz_question_1: '참맛참맛참맛', + quiz_question_2: '보쌈보쌈보쌈', + quiz_question_3: '하이하이하이하이', + quiz_question_4: '이승섭은 롤을 잘해!', + }); + + const handleChange = (field, value) => { + setQuizData(prevState => ({ + ...prevState, + [field]: value, + })); + }; + + const handleSubmit = async () => { + // try { + // const response = await axios.put(`/api/quiz/${quizData.id}`, quizData); + // console.log('수정된 데이터가 서버에 저장되었습니다.', response.data); + // } catch (error) { + // console.error('수정 요청 중 오류가 발생했습니다.', error); + // } + console.log('ddd'); + }; + + return ( +
+ +
+ + +
+
+ ); +} + +export default AdminEditMiniQuiz; diff --git a/admin/src/pages/adminEditEvent/adminEditMiniQuiz/AdminEditMiniQuizContent.jsx b/admin/src/pages/adminEditEvent/adminEditMiniQuiz/AdminEditMiniQuizContent.jsx new file mode 100644 index 0000000..470fbcd --- /dev/null +++ b/admin/src/pages/adminEditEvent/adminEditMiniQuiz/AdminEditMiniQuizContent.jsx @@ -0,0 +1,49 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +function AdminEditMiniQuizContent({ response, onChange }) { + return ( + <> +
+ + onChange('quiz_description', e.target.value)} + /> +
+ + {[1, 2, 3, 4].map(num => ( +
+ + onChange(`quiz_question_${num}`, e.target.value)} + /> +
+ ))} + + ); +} + +AdminEditMiniQuizContent.propTypes = { + response: PropTypes.object.isRequired, + onChange: PropTypes.func.isRequired, +}; + +export default AdminEditMiniQuizContent; diff --git a/admin/src/pages/adminEditEvent/adminEditMiniQuizAnswer/AdminEditMiniQuizAnswer.jsx b/admin/src/pages/adminEditEvent/adminEditMiniQuizAnswer/AdminEditMiniQuizAnswer.jsx new file mode 100644 index 0000000..82e36cd --- /dev/null +++ b/admin/src/pages/adminEditEvent/adminEditMiniQuizAnswer/AdminEditMiniQuizAnswer.jsx @@ -0,0 +1,50 @@ +import React, { useState, useEffect } from 'react'; +import AdminEditHeader from '../AdminEditHeader'; +import AdminEditMiniQuizAnswerContent from './AdminEditMiniQuizAnswerContent'; +import BlackButton from '@/components/buttons/BlackButton'; + +function AdminEditMiniQuizAnswer() { + const [date, setDate] = useState(1); + const [quizAnswerData, setAnswerData] = useState({ + id: 1, + answer_num: 1, + quiz_image: + 'https://softeer4-team8.s3.ap-northeast-2.amazonaws.com/%E1%84%8C%E1%85%A1%E1%84%8C%E1%85%A5%E1%86%AB%E1%84%80%E1%85%A5.svg', + }); + + const handleChange = (field, value) => { + setAnswerData(prevState => ({ + ...prevState, + [field]: value, + })); + }; + + const handleSubmit = async () => { + // try { + // const response = await axios.put(`/api/quiz/${quizAnswerData.id}`, quizAnswerData); + // console.log('수정된 데이터가 서버에 저장되었습니다.', response.data); + // } catch (error) { + // console.error('수정 요청 중 오류가 발생했습니다.', error); + // } + console.log('dddd'); + }; + + return ( +
+ +
+ + +
+
+ ); +} + +export default AdminEditMiniQuizAnswer; diff --git a/admin/src/pages/adminEditEvent/adminEditMiniQuizAnswer/AdminEditMiniQuizAnswerContent.jsx b/admin/src/pages/adminEditEvent/adminEditMiniQuizAnswer/AdminEditMiniQuizAnswerContent.jsx new file mode 100644 index 0000000..92ca1db --- /dev/null +++ b/admin/src/pages/adminEditEvent/adminEditMiniQuizAnswer/AdminEditMiniQuizAnswerContent.jsx @@ -0,0 +1,80 @@ +import React, { useState } from 'react'; +import PropTypes from 'prop-types'; +import ImageAddIcon from '@/assets/icons/imageAddIcon.svg'; + +function AdminEditMiniQuizAnswerContent({ response, onChange }) { + const [imagePreview, setImagePreview] = useState(response.quiz_image || ''); + + const handleImageChange = e => { + const file = e.target.files[0]; + if (!file) { + return; + } + const reader = new FileReader(); + reader.onloadend = () => { + setImagePreview(reader.result); + onChange('quiz_image', file); + }; + reader.readAsDataURL(file); + }; + + return ( + <> +
+ + onChange('answer_num', e.target.value)} + /> +
+
+
+ +

+ 포맷: jpg/ png/ jpeg +

+
+
+ {imagePreview && ( + Preview + )} + ImageAddIcon + +
+
+ + ); +} + +AdminEditMiniQuizAnswerContent.propTypes = { + response: PropTypes.object.isRequired, + onChange: PropTypes.func.isRequired, +}; + +export default AdminEditMiniQuizAnswerContent; diff --git a/admin/src/router.jsx b/admin/src/router.jsx index 612f009..556ad77 100644 --- a/admin/src/router.jsx +++ b/admin/src/router.jsx @@ -1,12 +1,13 @@ import React from 'react'; import { createBrowserRouter } from 'react-router-dom'; import App from '@/App'; +import AdminEditEvent from '@/pages/adminEditEvent/AdminEditEvent'; const router = createBrowserRouter([ { path: '/', element: , - // children: [{ index: true, element: }], + children: [{ index: true, element: }], }, ]);