Skip to content

Commit

Permalink
Merge pull request #72 from 9oormDari/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
Mintae Kim authored Sep 28, 2024
2 parents 3a8135e + bc8abf3 commit d023113
Show file tree
Hide file tree
Showing 15 changed files with 558 additions and 50 deletions.
34 changes: 11 additions & 23 deletions src/components/Goalpage/GoormScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,16 @@ interface Cloud {

export default function GoormScreen() {
const [stage, setStage] = useState<number>(0);
const [myId, setMyId] = useState<string>('');
const [clouds, setClouds] = useState<Cloud[]>([]);
const [clouds, setClouds] = useState<Cloud[]>([]);

useEffect(() => {
const fetchMyData = async () => {
try {
const response = await API.User.getMyInfo();
const response = await API.User.currentStep();

if (response.status === 'OK' && response.data) {
// μ‚¬μš©μž ID μ„€μ •
setMyId(response.data.id);

// 'data' 배열이 μ‘΄μž¬ν•˜κ³  배열인지 확인 ν›„ 길이 μ„€μ •
if (
response.data.data &&
Array.isArray(response.data.data)
) {
const dataCount = response.data.data.length;
setStage(dataCount);
} else {
// 'data' 배열이 μ—†κ±°λ‚˜ 배열이 μ•„λ‹Œ 경우 0으둜 μ„€μ •
setStage(0);
}
setStage(response.data.currentStep);
console.log('ν˜„μž¬ μŠ€ν…Œμ΄μ§€:', response.data.currentStep);
} else {
console.error(
'응닡 μƒνƒœκ°€ OKκ°€ μ•„λ‹ˆκ±°λ‚˜ 데이터가 μ—†μŠ΅λ‹ˆλ‹€.'
Expand Down Expand Up @@ -89,17 +76,18 @@ export default function GoormScreen() {
}, [stage]); // stageκ°€ 변경될 λ•Œλ§ˆλ‹€ μ‹€ν–‰

// μž„μ‹œλ‘œ 집어넣은 ꡬ름 단계 증가 ν•¨μˆ˜
const increaseStage = () => {
setStage((prev) => (prev < 4 ? prev + 1 : prev));
const increaseStage = (stage:number) => {
setStage((prev) => (prev < stage ? prev + 1 : prev));
};

// ꡬ름 μ¦κ°€μ‹œν‚€λŠ”λ° 천천히 μ¦κ°€ν•˜λ„λ‘ μ„€μ •
useEffect(() => {
if (stage < 4) {
// μ΅œλŒ€ μŠ€ν…Œμ΄μ§€κ°€ 4라면
if (stage === 0) {
return;
} else if (stage < 4) { // μ΅œλŒ€ μŠ€ν…Œμ΄μ§€κ°€ 4라면
const timer = setTimeout(() => {
increaseStage();
}, 1000);
increaseStage(stage);
}, 1500);

return () => clearTimeout(timer);
}
Expand Down
65 changes: 64 additions & 1 deletion src/components/Goalpage/MemberList.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import MemberCard from './MemberList/MemberCard';
import { API } from '../../lib/api/index.ts';
import { useState, useEffect } from 'react';
import cn from '../../lib/cn';
import UploadModal from './MemberList/UploadModal.tsx';
import ShowImageModal from './MemberList/ShowImageModal.tsx';

interface Member {
id: string;
Expand All @@ -9,13 +12,31 @@ interface Member {
}

export default function MemberList() {
const [isModalVisible, setIsModalVisible] = useState(false);
const [isSeeMyImageModalVisible, setIsSeeMyImageModalVisible] = useState(false);
const [members, setMembers] = useState<Member[]>([
{ id: '1', username: 'κΉ€', profileUrl: '' },
{ id: '2', username: 'λ°•', profileUrl: '' },
{ id: '3', username: '졜', profileUrl: '' },
]);
const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null);
const [myId, setMyId] = useState<string>('');
const [myName, setMyName] = useState<string>('');

useEffect(() => {
const fetchMyData = async () => {
try {
const response = await API.User.getMyInfo();
setMyId(response.username);
setMyName(response.nickname);
console.log(myId, myName);
} catch (error) {
console.error('λ‚΄ 정보λ₯Ό λΆˆλŸ¬μ˜€λŠ” 쀑 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€:', error);
}
};
fetchMyData();
}, []);

useEffect(() => {
const fetchMemberList = async () => {
Expand All @@ -37,6 +58,22 @@ export default function MemberList() {
fetchMemberList();
}, []);

const openModal = () => {
setIsModalVisible(true);
};

const closeModal = () => {
setIsModalVisible(false);
};

const openSeeMyImageModal = () => {
setIsSeeMyImageModalVisible(true);
}

const closeSeeMyImageModal = () => {
setIsSeeMyImageModalVisible(false);
}

return (
<>
<div className="w-full text-2xl md:text-4xl font-bold text-left px-4 md:px-10 pt-10">
Expand All @@ -57,6 +94,32 @@ export default function MemberList() {
/>
))}
</div>
</>
<button className={cn(
"w-64 md:w-96 h-12 md:h-16 bg-[#5A82F1] text-white rounded-lg hover:bg-blue-600",
"transition text-sm md:text-xl font-semibold mt-10 "
)}
onClick={openModal}
>
λ‚˜μ˜ 인증 λ“±λ‘ν•˜κΈ°
</button>
{isModalVisible && (
<UploadModal isVisible={isModalVisible} onClose={closeModal} />
)}
<button className={cn(
"w-64 md:w-96 h-12 md:h-16 bg-[#575757] text-white rounded-lg hover:bg-slate-700",
"transition text-sm md:text-xl font-semibold mt-3 "
)}
onClick={openSeeMyImageModal}
>
λ‚˜μ˜ 인증 λ³΄λŸ¬κ°€κΈ°
</button>
{isSeeMyImageModalVisible && myId && myName && (
<ShowImageModal
memberId={myId}
memberName={myName}
onClose={closeSeeMyImageModal}
/>
)}
</>
);
}
18 changes: 9 additions & 9 deletions src/components/Goalpage/MemberList/ShowImageModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default function ShowImageModal({
}: ShowImageModalProps) {
// λ°±μ—”λ“œμ—μ„œ κ°€μ Έμ˜¨ 이미지듀을 μ €μž₯ν•  μƒνƒœ
const [images, setImages] = useState<ImageData[]>([]);

// λ°±μ—”λ“œμ—μ„œ 이미지 데이터λ₯Ό κ°€μ Έμ˜€λŠ” ν•¨μˆ˜
useEffect(() => {
const fetchMemberImages = async () => {
Expand Down Expand Up @@ -82,15 +82,15 @@ export default function ShowImageModal({
</h1>
<div className="mt-8 grid grid-cols-1 sm:grid-cols-2 gap-4">
{displayImages.map((image, index) => (
<div
key={`${image.id}-${index}`}
className="h-32 md:h-48 bg-gray-200 flex justify-center items-center rounded"
<div
key={`${image.id}-${index}`}
className="h-32 md:h-48 bg-gray-200 flex justify-center items-center rounded"
>
<img
src={image.url}
alt={image.alt}
className="w-full h-full object-contain"
/>
<img
src={image.url}
alt={image.alt}
className="w-full h-full object-contain"
/>
</div>
))}
</div>
Expand Down
130 changes: 130 additions & 0 deletions src/components/Goalpage/MemberList/UploadModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import React, { useState } from 'react';
import ImageUpload from './UploadModal/ImageUpload.tsx';
import SelectRoutineList from './UploadModal/SelectRoutineList.tsx';
import cn from '../../../lib/cn.ts';
import { API } from '../../../lib/api/index.ts';
import { LiaCloneSolid } from 'react-icons/lia';

interface MultiStepModalProps {
isVisible: boolean;
onClose: () => void;
}

export default function MultiStepModal({ isVisible, onClose }: MultiStepModalProps) {
const [step, setStep] = useState<number>(1); // 1: 이미지 μ—…λ‘œλ“œ, 2: 루틴 선택
const [index, setIndex] = useState<number>(0); // 루틴 인덱슀
const [image, setImage] = useState<File | null>(null); // 이미지 μƒνƒœ
const [selectedRoutine, setSelectedRoutine] = useState<string>(''); // μ„ νƒλœ 루틴

const handleNextStep = () => {
setStep(step + 1);
};

const handlePreviousStep = () => {
setStep(step - 1);
};

const handleCancel = () => {
onClose(); // λͺ¨λ‹¬ λ‹«κΈ°
};

const handleUpload = async () => {
if (!image || !selectedRoutine) return;

try {
// FormData 객체 생성
const formData = new FormData();
formData.append('routineIndex', index.toString()); // 인덱슀 값을 λ¬Έμžμ—΄λ‘œ λ³€ν™˜ν•˜μ—¬ μΆ”κ°€
formData.append('routineName', selectedRoutine); // 루틴 이름 μΆ”κ°€
formData.append('file', image); // 이미지 파일 μΆ”κ°€

// API 호좜
const response = await API.User.uploadRoutine(
(index + 1).toString(), // 루틴 인덱슀
selectedRoutine, // μ„ νƒν•œ 루틴
image // 전솑할 이미지 파일
);

if (response.status === 'OK') {
setStep(3); // 성곡 μ‹œ 3λ‹¨κ³„λ‘œ 이동
} else {
console.error('μ—…λ‘œλ“œ μ‹€νŒ¨:', response);
setStep(4); // μ‹€νŒ¨ μ‹œ 4λ‹¨κ³„λ‘œ 이동 (μž¬μ‹œλ„ μ•ˆλ‚΄)
}

} catch (error) {
console.error('μ—…λ‘œλ“œ 쀑 였λ₯˜ λ°œμƒ:', error);
setStep(4); // μ‹€νŒ¨ μ‹œ 4λ‹¨κ³„λ‘œ 이동 (μž¬μ‹œλ„ μ•ˆλ‚΄)
}
};

return isVisible ? (
<div
className={cn(
'fixed top-0 left-0 w-full h-full bg-black bg-opacity-50',
'flex items-center justify-center z-50'
)}
>
<div
className={cn(
'w-[500px] bg-white rounded-lg p-8',
'flex flex-col items-center'
)}
>
{step === 1 && (
<>
<h2 className="text-xl font-bold mb-4">이미지 μ—…λ‘œλ“œ</h2>
<ImageUpload
image={image} // 이미지 μƒνƒœ 전달
setImage={setImage} // 이미지 μƒνƒœ μ—…λ°μ΄νŠΈ ν•¨μˆ˜ 전달
onNext={handleNextStep}
onCancel={handleCancel}
/>
</>
)}
{step === 2 && (
<>
<h2 className="text-xl font-bold mb-4">루틴 선택</h2>
<SelectRoutineList
index={index} // 루틴 인덱슀 전달
setIndex={setIndex} // 루틴 인덱슀 μ—…λ°μ΄νŠΈ ν•¨μˆ˜ 전달
selectedRoutine={selectedRoutine} // μ„ νƒλœ 루틴 전달
setSelectedRoutine={setSelectedRoutine} // 루틴 μƒνƒœ μ—…λ°μ΄νŠΈ ν•¨μˆ˜ 전달
onNext={handleUpload} // μ—…λ‘œλ“œ μ‹œλ„ ν•¨μˆ˜ 전달
onPrevious={handlePreviousStep}
onCancel={handleCancel}
/>
</>
)}
{step === 3 && (
<div className="text-center">
<h2 className="text-xl font-bold mb-4">μ„±κ³΅μ μœΌλ‘œ λ“±λ‘λ˜μ—ˆμŠ΅λ‹ˆλ‹€!</h2>
<button
className={cn(
'w-full bg-blue-500 text-white rounded-lg',
'py-2 hover:bg-blue-600 mb-4'
)}
onClick={onClose}
>
λ‹«κΈ°
</button>
</div>
)}
{step === 4 && (
<div className="text-center">
<h2 className="text-xl font-bold mb-4">μ—…λ‘œλ“œ μ‹€νŒ¨. μž¬μ‹œλ„ ν•˜μ„Έμš”.</h2>
<button
className={cn(
'w-full bg-blue-500 text-white rounded-lg',
'py-2 hover:bg-blue-600 mb-4'
)}
onClick={handleCancel}
>
λ‹«κΈ°
</button>
</div>
)}
</div>
</div>
) : null;
}
Loading

0 comments on commit d023113

Please sign in to comment.