Commit d17da917 authored by 백승민's avatar 백승민
Browse files

버그 수정 1차 완료

parent 769ea9f4
......@@ -37,7 +37,7 @@ export const App = () => {
</RequireAuth>
}
/>
<Route path="admin" element={<Admin />} />
<Route path="admin" element={<RequireAuth><Admin /></RequireAuth>} />
<Route path="admin/:imgId" element={<ImgRewrite />} />
<Route path="rewrite" element={<ImgRewrite />} />
</Route>
......
import { get } from "mongoose";
import React, { FormEvent, useEffect, useState, MouseEvent } from "react";
import { Link } from "react-router-dom";
import { mainimgApi } from "../apis";
......@@ -11,200 +12,214 @@ import { MySlide } from "./adminslide";
// }
export default function Admin() {
// 이미지 전체 불러오기
const [getimgs, setGetimgs] = useState<MainimgType[]>([]);
// 이미지 전체 불러오기
const [getimgs, setGetimgs] = useState<MainimgType[]>([]);
async function imgsData() {
const imgs = await mainimgApi.getmainimg();
setGetimgs(imgs);
}
useEffect(() => {
imgsData();
}, []);
async function imgsData() {
const imgs = await mainimgApi.getmainimg();
setGetimgs(imgs);
}
useEffect(() => {
imgsData();
}, []);
// 이미지 추가하기
const [addimg, setAddimg] = useState<MainimgType>({
_id: "",
theme: "",
city: "",
title: "",
fileInfo: { originalfilename: "", newfilename: "" },
});
// 이미지 추가하기
const [addimg, setAddimg] = useState<MainimgType>({
_id: "",
theme: "",
city: "",
title: "",
pic: { originalfilename: "", newfilename: "" },
});
const [loading, setLoading] = useState(false);
const [error, setError] = useState("");
const [addSuccess, setAddSuccess] = useState(false);
const [delSuccess, setDelSuccess] = useState(false);
const [file, setFile] = useState<File>();
const [loading, setLoading] = useState(false);
const [error, setError] = useState("");
const [addSuccess, setAddSuccess] = useState(false);
const [delSuccess, setDelSuccess] = useState(false);
const [file, setFile] = useState<File>();
function handleSelectChange(event: React.ChangeEvent<HTMLSelectElement>) {
const { name, value } = event.currentTarget;
console.log(value);
setAddimg({ ...addimg, [name]: value });
}
function handleInputeChange(event: React.ChangeEvent<HTMLInputElement>) {
const { name, value } = event.currentTarget;
setAddimg({ ...addimg, [name]: value });
}
function handleSelectChange(event: React.ChangeEvent<HTMLSelectElement>) {
const { name, value } = event.currentTarget;
console.log(value);
setAddimg({ ...addimg, [name]: value });
}
function handleInputeChange(event: React.ChangeEvent<HTMLInputElement>) {
const { name, value } = event.currentTarget;
setAddimg({ ...addimg, [name]: value });
}
function handleFileChange(e: React.ChangeEvent<HTMLInputElement>) {
const file = e.target.files?.[0];
if (!(file === undefined)) {
setFile(file);
function handleFileChange(e: React.ChangeEvent<HTMLInputElement>) {
const file = e.target.files?.[0];
if (!(file === undefined)) {
setFile(file);
}
}
}
async function handleSubmit(event: FormEvent) {
event.preventDefault();
const formdata = new FormData();
console.log(addimg);
formdata.append("city", addimg.city);
formdata.append("theme", addimg.theme);
formdata.append("title", addimg.title);
if (!(file === undefined)) {
formdata.append("mainimg", file);
console.log(formdata);
const res = await mainimgApi.mainimg(formdata);
console.log("확인 중 ", res);
alert("img 추가되었습니다");
async function handleSubmit(event: FormEvent) {
event.preventDefault();
const formdata = new FormData();
console.log(addimg);
formdata.append("city", addimg.city);
formdata.append("theme", addimg.theme);
formdata.append("title", addimg.title);
try {
if (!(file === undefined)) {
formdata.append("mainimg", file);
console.log("fordata", formdata);
const res = await mainimgApi.mainimg(formdata);
console.log("확인 중 ", res);
alert("img 추가되었습니다");
setGetimgs([...getimgs, res])
}
else (
console.log("file === undefined")
)
} catch (error) {
console.log("에러발생");
catchErrors(error, setError);
} finally {
setLoading(false);
}
}
}
// 이미지 삭제하기
async function handleDeleteClick(event: MouseEvent<HTMLButtonElement>) {
try {
if (confirm("삭제하시겠습니까?") == true) {
const picId = event.currentTarget.id;
console.log("picId : ", picId);
const res = await mainimgApi.delmainimg(picId);
console.log("delete img", res);
// setGetimgs(getimgs)
setDelSuccess(true);
setError("");
alert("img 삭제되었습니다");
} else {
return false;
}
} catch (error) {
console.log("에러발생");
catchErrors(error, setError);
} finally {
setLoading(false);
// 이미지 삭제하기
async function handleDeleteClick(event: MouseEvent<HTMLButtonElement>) {
try {
if (confirm("삭제하시겠습니까?") == true) {
const picId = event.currentTarget.id;
console.log("picId : ", picId);
const res = await mainimgApi.delmainimg(picId);
console.log("delete img", res);
// setGetimgs(getimgs)
setDelSuccess(true);
setError("");
alert("img 삭제되었습니다");
const deleteimg = getimgs.filter(pic=>picId!==pic._id)
setGetimgs(deleteimg)
} else {
return false;
}
} catch (error) {
console.log("에러발생");
catchErrors(error, setError);
} finally {
setLoading(false);
}
}
}
let limit = 15;
const numPages = Math.ceil(getimgs.length / 15);
let limit = 15;
const numPages = Math.ceil(getimgs.length / 15);
// const location = useLocation() as ImgState;
// const img = location.state;
// const location = useLocation() as ImgState;
// const img = location.state;
const slides = [];
for (let i = 0; i < numPages; i++) {
const k = [
getimgs
.slice(i * limit, i * limit + limit)
.map((picture, index: number) => (
<div key={index}>
<div className={`m-1 shrink-0 bg-gray-200 rounded shadow-md `}>
<img
src={"http://localhost:3000/images/" + picture.pic.newfilename}
className="w-full h-10 md:h-20 object-center"
/>
<p className="text-center text-xs">{picture.title}</p>
</div>
<div className="text-end">
<button className="border-r-2 border-r-indigo-500 text-xs">
<Link to={`/admin/${picture._id}`} state={picture}>
수정
</Link>
</button>
<button
id={picture._id}
onClick={handleDeleteClick}
className="text-xs"
>
삭제
</button>
</div>
</div>
)),
];
slides.push(k);
}
const slides = [];
for (let i = 0; i < numPages; i++) {
const k = [
getimgs
.slice(i * limit, i * limit + limit)
.map((picture, index: number) => (
<div key={index}>
<div className={`m-1 shrink-0 bg-gray-200 rounded shadow-md `}>
<img
src={"http://localhost:3000/images/" + picture.fileInfo.newfilename}
className="w-full h-10 md:h-20 object-center"
/>
<p className="text-center text-xs">{picture.title}</p>
</div>
<div className="text-end">
<button className="border-r-2 border-r-indigo-500 text-xs">
<Link to={`/admin/${picture._id}`} state={picture}>
수정
</Link>
</button>
<button
id={picture._id}
onClick={handleDeleteClick}
className="text-xs"
>
삭제
</button>
</div>
</div>
)),
];
slides.push(k);
}
return (
<div>
<form onSubmit={handleSubmit}>
<div className="flex flex-wrap justify-center gap-3">
<div className="gap-3 md:flex ">
<select
name="city"
id="Questions"
className="border border-3 border-black w-20 my-5"
defaultValue="질문종류"
onChange={handleSelectChange}
>
<option value="질문종류">도시</option>
<option value="서울">서울</option>
<option value="부산">부산</option>
<option value="인천">인천</option>
<option value="대구">대구</option>
<option value="광주">광주</option>
<option value="대전">대전</option>
<option value="울산">울산</option>
<option value="세종">세종</option>
<option value="독도">독도</option>
<option value="제주">제주</option>
</select>
<select
name="theme"
id="Questions"
className="border border-3 border-black w-20 my-5"
defaultValue="질문종류"
onChange={handleSelectChange}
>
<option value="질문종류">테마</option>
<option value="사이클링">사이클링</option>
<option value="서핑">서핑</option>
<option value="액티비티">액티비티</option>
<option value="캠핑">캠핑</option>
<option value="스키">스키</option>
<option value="보트">보트</option>
<option value="사막">사막</option>
<option value="골프">골프</option>
<option value="동굴">동굴</option>
<option value="문화재">문화재</option>
<option value="동물원">동물원</option>
<option value="사이클링">사이클링</option>
</select>
<div className="flex items-center justify-end gap-3">
<input
type="file"
id="files"
className="hidden"
onChange={handleFileChange}
></input>
<label htmlFor="files" className="border-2 m-5">
이미지 선택
</label>
</div>
<div className="flex items-center justify-end gap-3 mt-2 md:mt-0">
<p>title :</p>
<input
name="title"
className="border-2 border-sky-500"
onChange={handleInputeChange}
/>
return (
<div>
<form onSubmit={handleSubmit}>
<div className="flex flex-wrap justify-center gap-3">
<div className="gap-3 md:flex ">
<select
name="city"
id="Questions"
className="border border-3 border-black w-20 my-5"
defaultValue="질문종류"
onChange={handleSelectChange}
>
<option value="질문종류">도시</option>
<option value="Seoul">서울</option>
<option value="Busan">부산</option>
<option value="Incheon">인천</option>
<option value="Daegoo">대구</option>
<option value="Gwangjoo">광주</option>
<option value="Daejeon">대전</option>
<option value="Woolsan">울산</option>
<option value="Sejong">세종</option>
<option value="Dokdo">독도</option>
<option value="Jeju">제주</option>
</select>
<select
name="theme"
id="Questions"
className="border border-3 border-black w-20 my-5"
defaultValue="질문종류"
onChange={handleSelectChange}
>
<option value="질문종류">테마</option>
<option value="cycling">사이클링</option>
<option value="surfing">서핑</option>
<option value="activity">액티비티</option>
<option value="camping">캠핑</option>
<option value="skiing">스키</option>
<option value="boat">보트</option>
<option value="desert">사막</option>
<option value="golf">골프</option>
<option value="cave">동굴</option>
<option value="history">문화재</option>
<option value="zoo">동물원</option>
<option value="cycling">사이클링</option>
</select>
<div className="flex items-center justify-end gap-3">
<input
type="file"
id="files"
className="hidden"
onChange={handleFileChange}
></input>
<label htmlFor="files" className="border-2 m-5">
이미지 선택
</label>
</div>
<div className="flex items-center justify-end gap-3 mt-2 md:mt-0">
<p>title :</p>
<input
name="title"
className="border-2 border-sky-500"
onChange={handleInputeChange}
/>
</div>
</div>
<div className="my-5 flex items-center">
<button className="border-2 border-gray-500 rounded ">추가</button>
</div>
</div>
</form>
<div className="flex justify-center">
<MySlide key={Math.random()} slides={slides} />
</div>
</div>
<div className="my-5 flex items-center">
<button className="border-2 border-gray-500 rounded ">추가</button>
</div>
</div>
</form>
<div className="flex justify-center">
<MySlide key={Math.random()} slides={slides} />
</div>
</div>
);
);
}
import React, { FormEvent, useState } from "react";
import React, { FormEvent, useState, useEffect } from "react";
import { Link, Outlet, useNavigate, useLocation } from "react-router-dom";
import { mainimgApi } from "../apis";
import isLength from "validator/lib/isLength";
......@@ -27,9 +27,11 @@ export default function ImgRewrite() {
theme: img.theme,
city: img.city,
title: img.title,
pic: { originalfilename: "", newfilename: "" },
fileInfo: { originalfilename: "", newfilename: "" },
});
useEffect(() => {
console.log("수정 전 : ",imgdata);
}, []);
const [loading, setLoading] = useState(false);
const [error, setError] = useState("");
......@@ -86,7 +88,6 @@ export default function ImgRewrite() {
console.log("확인 중 ", res);
}
else {
console.log("ㅇ에러")
formdata.append("updatemainimg","");
console.log("formdata",formdata);
const res = await mainimgApi.updateimg(formdata,imgdata._id);
......@@ -109,7 +110,7 @@ export default function ImgRewrite() {
if (!isLength(pic.title ?? "", { min: 1 })) {
setError("제목을 입력해 주세요.");
return false;
} else if (!isLength(pic.pic.newfilename ?? "", { min: 1 })) {
} else if (!isLength(pic.fileInfo.newfilename ?? "", { min: 1 })) {
setError("파일을 선택해 주세요.");
return false;
} else if (equals(pic.city, "city")) {
......@@ -232,7 +233,7 @@ export default function ImgRewrite() {
/>
) : (
<img
src={"http://localhost:3000/images/" + img.pic.newfilename}
src={"http://localhost:3000/images/" + img.fileInfo.newfilename}
className="object-cover object-center h-full"
/>
)}
......
......@@ -14,6 +14,7 @@ export default function BoardPage() {
useEffect(() => {
getDataList();
}, []);
// posts
const getDataList = async () => {
const res = await postApi.getData();
......
......@@ -67,7 +67,7 @@ export default function Body() {
className={`m-1 shrink-0 rounded shadow-md h-45 relative overflow-hidden`}
key={index}>
<img
src={"http://localhost:3000/images/" + picture.pic.newfilename}
src={"http://localhost:3000/images/" + picture.fileInfo.newfilename}
className="w-full h-40 object-cover hover:scale-110 transition duration-0 hover:duration-500"
/>
<div className="bg-transparent text-neutral-50 text-xs rounded-full absolute bottom-0 ml-1 mb-1 hover:scale-110 transition duration-0 hover:duration-500">
......
......@@ -15,7 +15,7 @@ export default function Header() {
return (
<div className="flex flex-col md:px-56 ">
<div className="flex flex-col-reverse pt-3 pb-12 border-b-2 ">
<div className="flex flex-col-reverse pt-3 pb-12 border-b-2 bg-gradient-to-t from-sky-200">
<div className="flex mt-5 justify-between pr-3">
<button className="ml-3 shrink-0 text-2xl">
<Link to="/" className="hover:text-sky-300 active:text-purple-500">
......
......@@ -29,7 +29,7 @@ export default function Theme({ handleClick }: ThemeProps) {
캠핑
</button>
<button
id={"sking"}
id={"skiing"}
onClick={handleClick}
className="shrink-0 px-5 hover:text-sky-300"
>
......
......@@ -9,70 +9,70 @@ export default function Citylist({ handleClick }: CityProps) {
<div className="overflow-auto w-full flex flex-row md:flex-col md:mr-24 bg-sky-100">
<div className="text-start px-5 py-2 bg-white shrink-0">도시</div>
<button
id={"서울"}
id={"Seoul"}
onClick={handleClick}
className="text-start px-5 py-2 hover:underline shrink-0"
>
서울
</button>
<button
id={"부산"}
id={"Busan"}
onClick={handleClick}
className="text-start px-5 py-2 hover:underline shrink-0"
>
부산
</button>
<button
id={"인천"}
id={"Incheon"}
onClick={handleClick}
className="text-start px-5 py-2 hover:underline shrink-0"
>
인천
</button>
<button
id={"대구"}
id={"Daegoo"}
onClick={handleClick}
className="text-start px-5 py-2 hover:underline shrink-0"
>
대구
</button>
<button
id={"광주"}
id={"Gwangjoo"}
onClick={handleClick}
className="text-start px-5 py-2 hover:underline shrink-0"
>
광주
</button>
<button
id={"대전"}
id={"Daejeon"}
onClick={handleClick}
className="text-start px-5 py-2 hover:underline shrink-0"
>
대전
</button>
<button
id={"울산"}
id={"Woolsan"}
onClick={handleClick}
className="text-start px-5 py-2 hover:underline shrink-0"
>
울산
</button>
<button
id={"세종"}
id={"Sejong"}
onClick={handleClick}
className="text-start px-5 py-2 hover:underline shrink-0"
>
세종
</button>
<button
id={"독도"}
id={"Dokdo"}
onClick={handleClick}
className="text-start px-5 py-2 hover:underline shrink-0"
>
독도
</button>
<button
id={"제주"}
id={"Jeju"}
onClick={handleClick}
className="text-start px-5 py-2 hover:underline shrink-0"
>
......
......@@ -44,7 +44,7 @@ export interface MainimgType {
theme: string;
city: string;
title: string;
pic: {
fileInfo: {
originalfilename: string;
newfilename: string;
};
......
......@@ -17,7 +17,7 @@ export const createMainimg = asyncWrap(async (reqExp, res) => {
multiples: false,
});
form.parse(req, (err, fields, files) => {
form.parse(req, async (err, fields, files) => {
if (!Array.isArray(files.mainimg)) {
//파일 좁히기 중
if (
......@@ -33,37 +33,24 @@ export const createMainimg = asyncWrap(async (reqExp, res) => {
const originalfilename = files.mainimg?.originalFilename;
const newfilename = files.mainimg.newFilename;
if (!(originalfilename === null || newfilename === undefined)) {
mainimgDb.createMainimg(
const imgRes = await mainimgDb.createMainimg(
{ city, title, theme },
{
originalfilename,
newfilename,
}
);
console.log(imgRes)
return res.json(imgRes);
}else{
return res.send("에러")
}
}
}
});
res.json();
});
// if (!isLength(url ?? "", { min: 1 })) {
// return res.status(422).send("이미지 url을 입력해주세요");
// }
// if (!isLength(title ?? "", { min: 1 })) {
// return res.status(422).send("이미지 제목을 입력해주세요");
// }
// const newMainimg = await mainimgDb.createMainimg({
// theme,
// city,
// url,
// title,
// });
// return res.json(newMainimg);
// });
export const getMainimg = asyncWrap(async (req, res) => {
const mainimgs = await mainimgDb.getMainimg();
......@@ -72,8 +59,8 @@ export const getMainimg = asyncWrap(async (req, res) => {
export const deleteMainimg = asyncWrap(async (req, res) => {
const { imgId } = req.params;
console.log(imgId);
const deleteCount = await mainimgDb.deleteOneMainimg(imgId);
console.log(deleteCount);
return res.json(deleteCount);
});
......@@ -107,7 +94,7 @@ export const updateMainimg = asyncWrap(async (reqExp, res) => {
const originalfilename = files.updatemainimg?.originalFilename;
const newfilename = files.updatemainimg.newFilename;
if (!(originalfilename === null || newfilename === undefined)) {
mainimgDb.updateOneMainimg(
const imgRes = mainimgDb.updateOneMainimg(
id,
theme,
city,
......@@ -115,12 +102,13 @@ export const updateMainimg = asyncWrap(async (reqExp, res) => {
originalfilename,
newfilename
);
return res.json(imgRes);
}
} else {
mainimgDb.updateOneMainimg(id, theme, city, title);
const imgRes = mainimgDb.updateOneMainimg(id, theme, city, title);
return res.json(imgRes);
}
}
}
});
res.json();
});
import { ObjectId } from "mongoose";
import { FileInfo, IFileInfo, Mainimg, MainimgType } from "../models";
import fs from "fs/promises";
import { fileInfoCtrl } from "../controllers";
export const createMainimg = async (mainimg: MainimgType, pic: IFileInfo) => {
const newPic = await FileInfo.create({
......@@ -11,21 +13,30 @@ export const createMainimg = async (mainimg: MainimgType, pic: IFileInfo) => {
const newMainimg = await Mainimg.create({
theme: mainimg.theme,
city: mainimg.city,
pic: newPic._id,
fileInfo: newPic._id,
title: mainimg.title,
});
return newMainimg;
return newMainimg.populate("fileInfo");
};
export const getMainimg = async () => {
const img = await Mainimg.find({}).populate("pic");
console.log("Haha")
const img = await Mainimg.find({}).populate("fileInfo");
console.log("adf",img)
return img;
};
export const deleteOneMainimg = async (_id: string) => {
const main = await Mainimg.findById(_id);
if (!(main?.fileInfo === undefined)) {
const ref = await FileInfo.findById(main.fileInfo._id);
if (!(ref?.newfilename === undefined)) {
await fs.unlink("../travel/uploads/" + ref?.newfilename);
}
await FileInfo.deleteOne({ _id: main.fileInfo._id });
const res = await Mainimg.deleteOne({ _id: _id });
return res;
}
};
export const updateOneMainimg = async (
......@@ -69,5 +80,6 @@ export const updateOneMainimg = async (
});
console.log("error5", newfilename, originalfilename, theme, city, title);
}
} else console.log("error3", newMainimg);
};
......@@ -18,7 +18,7 @@ const MainimgSchema = new Schema<MainimgType>({
type: String,
required: true,
},
fileInfo: { type: Schema.Types.ObjectId, ref: "Fileinfo" },
fileInfo: { type: Schema.Types.ObjectId, ref: "FileInfo" },
});
export default model<MainimgType>("Mainimg", MainimgSchema);
......@@ -5,13 +5,13 @@ const router = express.Router();
router
.route("/")
.get(authCtrl.requireLogin, mainimgCtrl.getMainimg)
.post(authCtrl.requireLogin, mainimgCtrl.createMainimg)
.get( mainimgCtrl.getMainimg)
.post(authCtrl.requireLogin,authCtrl.hasRole("admin"), mainimgCtrl.createMainimg)
router
.route("/:imgId")
.delete(authCtrl.requireLogin, mainimgCtrl.deleteMainimg)
.put(authCtrl.requireLogin, authCtrl.hasRole("admin"), mainimgCtrl.updateMainimg);
.delete(authCtrl.requireLogin,authCtrl.hasRole("admin"), mainimgCtrl.deleteMainimg)
.put(authCtrl.requireLogin,authCtrl.hasRole("admin"), mainimgCtrl.updateMainimg);
export default router;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment