Skip to content

Commit

Permalink
Merge pull request #97 from softeerbootcamp4th/feat/#95/AdminEditReward
Browse files Browse the repository at this point in the history
[fix] admin 폴더로 이동
  • Loading branch information
yoonc01 authored Aug 14, 2024
2 parents 841355a + 83d8856 commit d21ebd6
Show file tree
Hide file tree
Showing 15 changed files with 500 additions and 1 deletion.
3 changes: 3 additions & 0 deletions admin/src/assets/icons/imageAddIcon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions admin/src/assets/icons/nextDayArrow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions admin/src/assets/icons/previousDayArrow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions admin/src/components/buttons/BlackButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';
import PropTypes from 'prop-types';

function BlackButton({ onClickFunc }) {
return (
<button
onClick={onClickFunc}
className={`font-bold text-white rounded py-200 px-1000 bg-neutral-700 hover:bg-neutral-black`}
>
수정하기
</button>
);
}

BlackButton.propTypes = {
onClickFunc: PropTypes.func.isRequired,
};

//memo를 이용하여 rerender 방지
export default React.memo(BlackButton);
18 changes: 18 additions & 0 deletions admin/src/components/header/AdminHeader.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react';

function AdminHeader() {
return (
<div className="pt-1000 flex justify-between w-[90%]">
<div className="set-center gap-500">
<span className="text-heading-2-bold text-neutral-black">
이벤트 관리
</span>
<div className="bg-[#AEAEAE] px-4 py-1 rounded-full text-white set-center text-detail-1-semibold">
진행중
</div>
</div>
</div>
);
}

export default AdminHeader;
14 changes: 14 additions & 0 deletions admin/src/pages/AdminIndex.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react';
import { Outlet } from 'react-router-dom';
import AdminHeader from '@/components/header/AdminHeader';

function AdminIndex() {
return (
<div className="bg-[#DADADA] flex flex-col items-center">
<AdminHeader />
<Outlet />
</div>
);
}

export default AdminIndex;
16 changes: 16 additions & 0 deletions admin/src/pages/adminEditEvent/AdminEditEvent.jsx
Original file line number Diff line number Diff line change
@@ -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 (
<div className="w-[90%] flex flex-col items-center pb-2000">
<AdminEditMiniQuiz />
<AdminEditMiniQuizAnswer />
<AdminEditDraw />
</div>
);
}

export default AdminEditEvent;
51 changes: 51 additions & 0 deletions admin/src/pages/adminEditEvent/AdminEditHeader.jsx
Original file line number Diff line number Diff line change
@@ -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 (
<div className="h-[80px] flex justify-center items-center bg-[#F2F2F2] rounded-t-[10px] relative">
<span className="text-neutral-black text-body-3-bold absolute left-[3%]">
{info}
</span>
<div className="flex gap-200">
<img
src={PreviousDayArrow}
alt="PreviousDayArrow"
className={`w-[35px] h-auto ${isPreviousDayDisabled ? 'cursor-default opacity-50' : 'cursor-pointer hover:scale-110 transition-transform duration-200'}`}
onClick={handlePrev}
/>
<span className="text-[#5B5B5B] text-body-3-bold">Day {date}</span>
<img
src={NextDayArrow}
alt="NextDayArrow"
className="w-[35px] h-auto cursor-pointer hover:scale-110 transition-transform duration-200"
onClick={handleNext}
/>
</div>
</div>
);
}

AdminEditMiniQuizHeader.propTypes = {
info: PropTypes.string.isRequired,
date: PropTypes.number,
setDate: PropTypes.func,
};

export default AdminEditMiniQuizHeader;
57 changes: 57 additions & 0 deletions admin/src/pages/adminEditEvent/adminEditDraw/AdminEditDraw.jsx
Original file line number Diff line number Diff line change
@@ -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 (
<div className="w-[100%] mt-1000">
<AdminEditHeader
info="응모 결과 메세지 수정"
date={date}
setDate={setDate}
/>
<div className="flex-col w-[100%] set-center bg-neutral-white rounded-b-[10px] py-1000">
<AdminEditDrawContent
response={quizAnswerData}
onChange={handleChange}
/>
<BlackButton onClickFunc={handleSubmit} />
</div>
</div>
);
}

export default AdminEditDraw;
Original file line number Diff line number Diff line change
@@ -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 (
<>
<div className="flex mb-1000 w-[90%] gap-500">
<label
htmlFor="failMessage"
className="w-[15%] text-detail-1-bold text-neutral-800 set-center"
>
실패 메세지 *
</label>
<input
id="failMessage"
className="w-[85%] px-400 py-200 text-detail-2-medium text-neutral-black placeholder:text-detail-2-medium placeholder:text-neutral-500 border-solid border-neutral-black focus:border-primary-blue border-[2px] rounded-[10px]"
placeholder={response.lose_message}
value={response.lose_message}
onChange={e => onChange('lose_message', e.target.value)}
/>
</div>
<div className="flex mb-1000 w-[90%] gap-500">
<div className="w-[15%]">
<label
htmlFor="answerImage"
className="flex justify-center text-detail-1-bold text-neutral-800"
>
정답 이미지 *
</label>
<p className="text-center text-detail-3-medium text-neutral-400">
포맷: jpg/ png/ jpeg
</p>
</div>
<div className="relative w-[85%] h-[200px] rounded-[10px] border-[2px] border-solid border-neutral-black">
{imagePreview && (
<img
src={imagePreview}
alt="Preview"
className="absolute max-w-full max-h-full transform -translate-x-1/2 -translate-y-1/2 top-1/2 left-1/2"
/>
)}
<img
src={ImageAddIcon}
alt="ImageAddIcon"
className="absolute transform -translate-x-1/2 -translate-y-1/2 top-1/2 left-1/2 w-[50px] h-auto"
/>
<input
type="file"
className="w-full h-full opacity-0 cursor-pointer "
accept="image/png, image/jpg, image/jpeg"
onChange={handleImageChange}
/>
</div>
</div>
</>
);
}

AdminEditDrawContent.propTypes = {
response: PropTypes.object.isRequired,
onChange: PropTypes.func.isRequired,
};

export default AdminEditDrawContent;
Original file line number Diff line number Diff line change
@@ -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 (
<div className="w-[100%] mt-1000">
<AdminEditHeader
info="미니퀴즈 질문 수정"
date={date}
setDate={setDate}
/>
<div className="flex-col w-[100%] set-center bg-neutral-white rounded-b-[10px] py-1000">
<AdminEditMiniQuizContent response={quizData} onChange={handleChange} />
<BlackButton onClickFunc={handleSubmit} />
</div>
</div>
);
}

export default AdminEditMiniQuiz;
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React from 'react';
import PropTypes from 'prop-types';

function AdminEditMiniQuizContent({ response, onChange }) {
return (
<>
<div className="flex mb-1000 w-[90%] gap-500">
<label
htmlFor="question"
className="w-[15%] text-detail-1-bold text-neutral-800 set-center"
>
퀴즈 질문 *
</label>
<input
id="question"
className="w-[85%] px-400 py-200 text-detail-2-medium text-neutral-black placeholder:text-detail-2-medium placeholder:neutral-500 border-solid border-neutral-black focus:border-primary-blue border-[2px] rounded-[10px]"
placeholder={response.quiz_description}
value={response.quiz_description}
onChange={e => onChange('quiz_description', e.target.value)}
/>
</div>

{[1, 2, 3, 4].map(num => (
<div className="flex mb-1000 w-[90%] gap-500" key={num}>
<label
htmlFor={`quizSelect_${num}`}
className="w-[15%] text-detail-2-bold text-neutral-800 set-center"
>
선택지{num} *
</label>
<input
id={`quizSelect_${num}`}
className="w-[85%] px-400 py-200 text-detail-2-medium text-neutral-black placeholder:text-detail-2-medium placeholder:neutral-500 border-solid border-neutral-black focus:border-primary-blue border-[2px] rounded-[10px]"
placeholder={response[`quiz_question_${num}`]}
value={response[`quiz_question_${num}`]}
onChange={e => onChange(`quiz_question_${num}`, e.target.value)}
/>
</div>
))}
</>
);
}

AdminEditMiniQuizContent.propTypes = {
response: PropTypes.object.isRequired,
onChange: PropTypes.func.isRequired,
};

export default AdminEditMiniQuizContent;
Loading

0 comments on commit d21ebd6

Please sign in to comment.