Skip to content

Commit

Permalink
Merge: merge feature/120 to main
Browse files Browse the repository at this point in the history
Fix: edit diary image upload and image slider null value
  • Loading branch information
HeeNamgoong authored May 28, 2024
2 parents 854b34c + ae988f5 commit 8d3f584
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 25 deletions.
2 changes: 1 addition & 1 deletion src/components/common/ImageSlider.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Box from "@mui/material/Box";
import xicon from "../../assets/icons/x-icon.svg";

const ImageSlider = ({ images }) => {
if (images === undefined) {
if (!images || images.length === 0) {
return null;
}
const settings = {
Expand Down
7 changes: 5 additions & 2 deletions src/components/common/MultipleImageUploader.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React, { useRef, useEffect } from "react";
import React, { useRef } from "react";
import styled from "styled-components";
import { COLOR } from "../../styles/color";
import CancelIcon from "@mui/icons-material/Cancel";
import CameraAltIcon from "@mui/icons-material/CameraAlt";
import PropTypes from "prop-types";

const Uploader = ({ onFilesChange, files=[], setFiles }) => {
const Uploader = ({ onFilesChange, files=[], setFiles, onImgModified }) => {
const inputRef = useRef(null);

const saveImage = (e) => {
Expand All @@ -25,13 +25,15 @@ const Uploader = ({ onFilesChange, files=[], setFiles }) => {
...prevFiles,
{ fileObject: e.target.files[0], preview_URL: fileReader.result, type: fileType },
]);
onImgModified(true);
};
};

const deleteImage = (index) => {
const updatedFiles = [...files];
updatedFiles.splice(index, 1);
setFiles(updatedFiles);
onImgModified(true);
};

return (
Expand Down Expand Up @@ -77,6 +79,7 @@ Uploader.propTypes = {
setFiles: PropTypes.node.isRequired,
files: PropTypes.node.isRequired,
onFilesChange: PropTypes.node.isRequired,
onImgModified: PropTypes.func.isRequired,
};

const ImageUploadDiv = styled.div`
Expand Down
12 changes: 2 additions & 10 deletions src/pages/DiaryWritePage.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { tripIdState, diaryIdState } from "../recoil/commonState";
import moment from "moment";

const DiaryWritePage = () => {
const [imgmodified, setImgModified] = useState(false);
const [diaryId, setDiaryId] = useRecoilState(diaryIdState);
const tripId = useRecoilValue(tripIdState);
const [startDate, setStartDate] = useState();
Expand All @@ -24,10 +25,6 @@ const DiaryWritePage = () => {
const [imagePreview, setImagePreview] = useState(null);
const [files, setFiles] = useState([]);
const [travelid, setTravelId] = useState("");
useEffect(() => {
console.log("Travel ID:", travelid); // Travel ID 출력
console.log("일기 생성 files:", files);
});

const navigate = useNavigate();

Expand Down Expand Up @@ -62,13 +59,8 @@ const DiaryWritePage = () => {
formData.append("images", file.fileObject);
});

for (const [key, value] of formData.entries()) {
console.log(`${key}: ${value}`);
}

axios.post(`${process.env.REACT_APP_SERVER_URL}/diary`, formData, { withCredentials: true, headers: {"Content-Type": "multipart/form-data"} })
.then((res) => {
console.log("res.data:", res.data);
setDiaryId(res.data.diaryid);
navigate("/showdiary");
})
Expand Down Expand Up @@ -109,7 +101,7 @@ const DiaryWritePage = () => {
/>
</DiaryDiv>

<Uploader onFilesChange={handleImageUpload} files={files} setFiles={setFiles} />
<Uploader onFilesChange={handleImageUpload} files={files} setFiles={setFiles} onImgModified={setImgModified}/>

<BtnDiv>
<CancelBtn onClick={openCancelModal}>취소</CancelBtn>
Expand Down
156 changes: 144 additions & 12 deletions src/pages/EditDiaryWritePage.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import styled from "styled-components";
import { React, useState, useEffect } from "react";
import { React, useState, useEffect, useRef } from "react";
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import calendar from "../assets/images/calendar.svg";
import Modal from "../components/common/Modal";
import Uploader from "../components/common/MultipleImageUploader";
import { COLOR } from "../styles/color";
import BottomNav from "../layout/BottomNav";
import axios from "axios";
Expand All @@ -14,6 +13,9 @@ import moment from "moment";
import { useRecoilState } from "recoil";
import { diaryIdState } from "../recoil/commonState";

import CancelIcon from "@mui/icons-material/Cancel";
import CameraAltIcon from "@mui/icons-material/CameraAlt";

const EditDiaryWritePage = () => {
const { state } = useLocation();
const [diaryId, setDiaryId] = useRecoilState(diaryIdState);
Expand All @@ -23,7 +25,8 @@ const EditDiaryWritePage = () => {
const [title, setTitle] = useState(diaryInfo?.title || "");
const [content, setContent] = useState(diaryInfo?.content || "");
const [files, setFiles] = useState(diaryInfo?.url || []);
const [files2, setFiles2] = useState();
const [files2, setFiles2] = useState([]);
const [imgmodified, setImgModified] = useState(false);

const goToShowDiary = () => {
navigate("/showdiary");
Expand All @@ -39,8 +42,8 @@ const EditDiaryWritePage = () => {
setFiles2(transformedFiles);
}, []);

const [isCancelModalOpen, setIsCancelModalOpen] = useState(false); // Cancel 버튼을 위한 모달 상태
const [isSaveModalOpen, setIsSaveModalOpen] = useState(false); // Save 버튼을 위한 모달 상태
const [isCancelModalOpen, setIsCancelModalOpen] = useState(false);
const [isSaveModalOpen, setIsSaveModalOpen] = useState(false);
const [imagePreview, setImagePreview] = useState(null);

const navigate = useNavigate();
Expand All @@ -66,15 +69,15 @@ const EditDiaryWritePage = () => {
formData.append("title", title);
formData.append("content", content);
formData.append("date", moment(startDate).startOf("day").format("YYYY-MM-DDTHH:mm:ss.SSS[Z]"));
formData.append("img", files2);
formData.append("imgmodified", imgmodified);

files.forEach((file) => {
formData.append("images", file.fileObject);
files2.forEach((file) => {
formData.append("images", file.fileObject); // edit diary 시 수정한 이미지
});

for (const [key, value] of formData.entries()) {
console.log(`${key}: ${value}`);
}
const files2PreviewURLs = files2.map((file) => file.preview_URL || null);
formData.append("originImage", files2PreviewURLs); // edit diary 시 수정이 아닌 원본 이미지


axios.put(`${process.env.REACT_APP_SERVER_URL}/diary/${diaryId}`, formData, { withCredentials: true, headers: {"Content-Type": "multipart/form-data"} })
.then((res) => {
Expand All @@ -85,6 +88,38 @@ const EditDiaryWritePage = () => {
});
};

//////////// MultipleImageUploader ////////////

const inputRef = useRef(null);

const saveImage = (e) => {
e.preventDefault();

handleImageUpload(files);
if (files2.length >= 10) {
return;
}
const fileReader = new FileReader();
if (e.target.files[0]) {
fileReader.readAsDataURL(e.target.files[0]);
}
fileReader.onload = () => {
const fileType = e.target.files[0].type.split("/")[0];
setFiles2((prevFiles) => [
...prevFiles,
{ fileObject: e.target.files[0], preview_URL: fileReader.result, type: fileType },
]);
setImgModified(true);
};
};

const deleteImage = (index) => {
const updatedFiles = [...files2];
updatedFiles.splice(index, 1);
setFiles2(updatedFiles);
setImgModified(true);
};

return <div>
<div>
<DateDiv>
Expand Down Expand Up @@ -117,7 +152,41 @@ const EditDiaryWritePage = () => {
/>
</DiaryDiv>

<Uploader onFilesChange={handleImageUpload} files={files2} setFiles={setFiles2} />
<div className="uploader-wrapper">
<input
type="file"
accept="image/*"
onChange={saveImage}
onClick={(e) => {
e.target.value = null;
}}
style={{ display: "none" }}
ref={inputRef}
/>

<ImageUploadDiv>
<ImgUploadBtn
variant="contained"
onClick={() => inputRef.current && inputRef.current.click()}
disabled={files2.length >= 10}
>
<CameraAltIcons />
<UploadCount>{files2.length}/10</UploadCount>
</ImgUploadBtn>
<Slider>
{Array.isArray(files2) &&
files2.map((file, index) => (
<div key={index}>
<ImageDiv>
<UploadedImage src={file.preview_URL} />
<CancelIcons
onClick={() => deleteImage(index)} />
</ImageDiv>
</div>
))}
</Slider>
</ImageUploadDiv>
</div>

<BtnDiv>
<CancelBtn onClick={openCancelModal}>취소</CancelBtn>
Expand Down Expand Up @@ -301,6 +370,69 @@ const ContentDiv = styled.div`
margin-top: 4rem;
`;

////////// MultipleImageUploader ////////////

const ImageUploadDiv = styled.div`
display: flex;
flex-direction: row;
align-items: center;
height: 8.5rem;
margin-top: 0.5rem;
margin-left: 8%;
margin-right: 8%;
`;

const ImgUploadBtn = styled.button`
background-color: #eeeeee;
border: none;
border-radius: 0.8rem;
height: 7rem;
width: 7rem;
margin-right: 0.5rem;
min-width: 7rem;
min-height: 7rem;
color: ${COLOR.MAIN_GREEN};
color: ${(props) => props.disabled ? "rgba(46, 171, 161, 0.3)" : "${COLOR.MAIN_GREEN}"}
`;

const UploadedImage = styled.img`
border-radius: 0.8rem;
height: 7rem;
width: 7rem;
margin: 0.5rem;
object-fit: cover;
`;

const CancelIcons = styled(CancelIcon)`
color: ${COLOR.MAIN_GREEN};
height: 2rem;
width: 2rem;
position: absolute;
top: 0;
right: 0;
`;

const Slider = styled.div`
display: flex;
align-items: center;
flex-direction: row;
position: relative;
overflow: auto;
`;

const ImageDiv = styled.div`
position: relative;
`;

const CameraAltIcons= styled(CameraAltIcon)`
height: 3rem;
width: 3rem;
`;

const UploadCount = styled.p`
color: ${COLOR.MAIN_GREEN};
font-weight: 500;
`;

export default EditDiaryWritePage;

Expand Down

0 comments on commit 8d3f584

Please sign in to comment.