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

img수정버튼 done

parent 39e4b1fd
......@@ -39,7 +39,7 @@ export const App = () => {
}
/>
<Route path="admin" element={<Admin />} />
<Route path="rewrite" element={<ImgRewrite/>}/>
<Route path="admin/:imgId" element={<ImgRewrite/>}/>
</Route>
</Route>
</Routes>
......
......@@ -16,3 +16,8 @@ export const getmainimg = async () => {
const { data } = await axios.get(`${baseUrl}/mainimg`);
return data;
};
export const updating = async (img: MainimgType) => {
const { data } = await axios.put(`${baseUrl}/mainimg/${img._id}`, img);
return data;
};
\ No newline at end of file
......@@ -5,6 +5,10 @@ import { catchErrors } from "../helpers";
import { MainimgType } from "../types";
import { MySlide } from "./adminslide";
// export interface ImgState {
// state: MainimgType;
// }
export default function Admin() {
// 이미지 전체 불러오기
const [getimgs, setGetimgs] = useState<MainimgType[]>([]);
......@@ -69,6 +73,7 @@ export default function Admin() {
console.log("picId : ", picId)
const res = await mainimgApi.delmainimg(picId);
console.log("delete img", res);
// setGetimgs(getimgs)
setDelSuccess(true);
setError("");
} else {
......@@ -89,6 +94,9 @@ export default function Admin() {
let limit = 15;
const numPages = Math.ceil(getimgs.length / 15);
// const location = useLocation() as ImgState;
// const img = location.state;
const slides = []
for (let i = 0; i < numPages; i++) {
const k = [
......@@ -103,7 +111,7 @@ export default function Admin() {
</div>
<div className="text-end">
<button className="border-r-2 border-r-indigo-500 text-xs">
<Link to="/rewrite">
<Link to={`/admin/${pic._id}`} state={pic}>
수정
</Link>
</button>
......@@ -118,8 +126,7 @@ export default function Admin() {
return (
<div>
<form
onSubmit={handleSubmit}>
<form onSubmit={handleSubmit}>
<div className="flex flex-wrap justify-center gap-3">
<div className="gap-3 md:flex ">
<select
......
import React, { FormEvent, useEffect, useState, MouseEvent } from "react";
import { Link, Outlet } from "react-router-dom";
import React, { FormEvent, useState} from "react";
import { Link, Outlet, useNavigate, useLocation } from "react-router-dom";
import { mainimgApi } from "../apis";
import isLength from "validator/lib/isLength";
import equals from "validator/lib/equals";
import { catchErrors } from "../helpers";
import { MainimgType } from "../types";
import { MySlide } from "./adminslide";
export interface ImgState {
state: MainimgType;
}
export default function ImgRewrite() {
// 이미지 수정
const [theme, setTheme] = useState<string>("질문종류");
const [city, setCity] = useState<string>("질문종류");
const [url, setUrl] = useState<string>("");
const [title, setTitle] = useState<string>("");
const navigate = useNavigate();
const location = useLocation() as ImgState;
const img = location.state;
const [imgdata, setImgData] = useState<MainimgType>({
_id: img._id,
theme: img.theme,
city: img.city,
url: img.url,
title: img.title,
});
const [loading, setLoading] = useState(false);
const [error, setError] = useState("");
const [disabled, setDisabled] = useState(false);
const [success, setSuccess] = useState(false);
async function reWriteSubmit(event: FormEvent) {
event.preventDefault();
try {
if (confirm("수정하시겠습니까?") == true) {
setError("");
console.log("user data", imgdata);
if (infoFormMatch(imgdata) === true) {
setLoading(true);
const res = await mainimgApi.updating(imgdata);
console.log("clear", res);
navigate("/admin", { replace: true });
setSuccess(true);
setError("");
}
} else {
return false;
}
} catch (error) {
console.log("에러발생");
catchErrors(error, setError);
} finally {
setLoading(false);
}
}
// console.log(user._id)
function infoFormMatch(pic: MainimgType) {
if (!isLength(pic.title ?? "", { min: 1 })) {
setError("제목을 입력해 주세요.");
return false;
} else if (!isLength(pic.url ?? "", { min: 1 })) {
setError("url을 입력해 주세요.");
return false;
} else if (equals(pic.city, "city")) {
setError("도시를 선택해 주세요.");
return false;
} else if (equals(pic.theme, "theme")) {
setError("테마를 선택해 주세요.");
return false;
} else {
return true;
}
}
const cityChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
const city = event.currentTarget.value;
const newUser = { ...imgdata, city: city };
console.log(event.currentTarget.value);
setCity(event.currentTarget.value);
setImgData(newUser);
};
const themeChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
const theme = event.currentTarget.value;
const newUser = { ...imgdata, theme: theme };
console.log(event.currentTarget.value);
setTheme(event.currentTarget.value);
setImgData(newUser);
};
const titleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const title = event.currentTarget.value;
const newUser = { ...imgdata, title: title };
setTitle(event.currentTarget.value);
setImgData(newUser);
};
const urlChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const url = event.currentTarget.value;
const newUser = { ...imgdata, url: url };
setUrl(event.currentTarget.value);
setImgData(newUser);
};
return (
<div>
<div>
<form onSubmit={reWriteSubmit} className="px-10 md:px-40">
<table className="w-full ">
<thead></thead>
<tbody className=" border-separate border border-slate-400 ">
<tr >
<td className="border border-slate-300 min-w-max">
도시이름
</td>
<td>
<select
name="city"
className="border border-3 border-black"
onChange={cityChange}
defaultValue={img.city}
>
<option value="city">도시</option>
<option value="Seoul">서울</option>
<option value="Busan">부산</option>
<option value="Incheon">인천</option>
<option value="Daegoo">대구</option>
<option value="Kwangjoo">광주</option>
<option value="Daejeon">대전</option>
<option value="Woolsan">울산</option>
<option value="Sejong">세종</option>
<option value="Dokdo">독도</option>
<option value="Jeju">제주</option>
</select>
</td>
</tr>
<tr>
<td className="border border-slate-300 min-w-max">
테마이름
</td>
<td>
<select
name="theme"
className="border border-3 border-black"
onChange={themeChange}
defaultValue={img.theme}
>
<option value="theme">테마</option>
<option value="cycling">사이클링</option>
<option value="surfing">서핑</option>
<option value="activity">액티비티</option>
<option value="camping">캠핑</option>
<option value="sking">스키</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>
</td>
</tr>
<tr>
<td className="border border-slate-300">
url
</td>
<td>
<input className="border-2 border-sky-500 rounded w-full"
onChange={urlChange}
defaultValue={img.url}
/>
</td>
</tr>
<tr>
<td className="border border-slate-300">
title
</td>
<td>
<input className="border-2 border-sky-500 rounded w-full"
onChange={titleChange}
defaultValue={img.title}
/>
</td>
</tr>
</tbody>
</table>
<div className="text-end">
<button type="submit" className="border-2">
수정
</button>
<button className="border-2">
<Link to={`/admin`}>
취소
</Link>
</button>
</div>
<Outlet/>
</form>
<Outlet />
</div>
);
};
......@@ -49,5 +49,25 @@ export const deleteMainimg = asyncWrap(async (req, res) => {
return res.json(deleteCount);
});
export const updateMainimg = asyncWrap(async (req, res) => {
const { title, theme, city, url } = req.body as {
title: string;
url: string;
theme: string;
city: string;
};
const { imgId } = req.params;
const updateImg = await mainimgDb.updateOnePost(
{
title,
theme,
city,
url,
},
imgId
);
return res.json(updateImg);
});
......@@ -19,3 +19,17 @@ export const deleteOneMainimg = async (_id: string) => {
const res = await Mainimg.deleteOne({ _id: _id });
return res;
};
export const updateOnePost = async (mainimg: MainimgType, _id: string) => {
const newMainimg = await Mainimg.findOneAndUpdate(
{ _id: _id },
{
theme: mainimg.theme,
city: mainimg.city,
url: mainimg.url,
title: mainimg.title,
},
{ new: true }
);
return newMainimg;
};
\ No newline at end of file
......@@ -11,6 +11,7 @@ router
router
.route("/:imgId")
.delete(authCtrl.requireLogin, mainimgCtrl.deleteMainimg)
.put(authCtrl.requireLogin, 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