Commit e7e56fda authored by Lee Soobeom's avatar Lee Soobeom
Browse files

posting에서 axios.post를 사용해 db에 저장

parent 81cba2c9
import axios from "axios"; import axios from "axios";
export * as authApi from "./auth.api"; export * as authApi from "./auth.api";
export * as postApi from "./post.api";
import axios from "axios";
import baseUrl from "./baseUrl";
import { PostingType } from "../types";
export const posting = async (post: PostingType) => {
const { data } = await axios.post(`${baseUrl}/posts/`, post);
return data;
};
...@@ -14,6 +14,7 @@ interface Posts { ...@@ -14,6 +14,7 @@ interface Posts {
export const fakes = [ export const fakes = [
{ {
id: "a", id: "a",
username: "lsb",
title: "여행가고싶다...", title: "여행가고싶다...",
date: "2022-06-30", date: "2022-06-30",
counts: 0, counts: 0,
...@@ -22,6 +23,7 @@ export const fakes = [ ...@@ -22,6 +23,7 @@ export const fakes = [
}, },
{ {
id: "b", id: "b",
username: "lsb",
title: "바다!바다!바다!", title: "바다!바다!바다!",
date: "2022-08-01", date: "2022-08-01",
counts: 0, counts: 0,
...@@ -30,6 +32,7 @@ export const fakes = [ ...@@ -30,6 +32,7 @@ export const fakes = [
}, },
{ {
id: "c", id: "c",
username: "lsb",
title: "Jeju-island", title: "Jeju-island",
date: "2022-9-10", date: "2022-9-10",
counts: 0, counts: 0,
...@@ -38,6 +41,7 @@ export const fakes = [ ...@@ -38,6 +41,7 @@ export const fakes = [
}, },
{ {
id: "d", id: "d",
username: "lsb",
title: "마! 부싼 가봤나!", title: "마! 부싼 가봤나!",
date: "2022-9-22", date: "2022-9-22",
counts: 0, counts: 0,
...@@ -46,26 +50,29 @@ export const fakes = [ ...@@ -46,26 +50,29 @@ export const fakes = [
}, },
{ {
id: "e", id: "e",
username: "lsb",
title: "Daegu", title: "Daegu",
date: "2022-10-1", date: "2022-10-1",
counts: 0, counts: 0,
theme: "surfing", theme: "ski",
city: "seoul", city: "Daegu",
}, },
{ {
id: "f", id: "f",
username: "lsb",
title: "강원도 감자는 맛있다.", title: "강원도 감자는 맛있다.",
date: "2022-12-12", date: "2022-12-12",
counts: 0, counts: 0,
theme: "surfing", theme: "camping",
city: "seoul", city: "강원도",
}, },
{ {
id: "g", id: "g",
username: "lsb",
title: "부산남자의 서울여행", title: "부산남자의 서울여행",
date: "2022-12-25", date: "2022-12-25",
counts: 0, counts: 0,
theme: "surfing", theme: "activity",
city: "seoul", city: "seoul",
}, },
]; ];
......
import React, { useState } from "react"; import React, { FormEvent, useState } from "react";
import isLength from "validator/lib/isLength";
import equals from "validator/lib/equals";
import { catchErrors } from "../helpers";
import { PostingType } from "../types";
import { postApi } from "../apis";
function Title() { export default function Posting() {
const [title, setTitle] = useState<string>("질문종류"); const [city, setCity] = useState<string>("질문종류");
const [theme, setTheme] = useState<string>("질문종류");
const [title, setTitle] = useState<string>("");
const [text, setText] = useState<string>("");
function TitleChange(e: { target: { value: React.SetStateAction<string> } }) { const [user, setUser] = useState<PostingType>({
setTitle(e.target.value); title: "",
} text: "",
} theme: "",
city: "",
username: "",
});
function Body() { const [loading, setLoading] = useState(false);
const [body, setBody] = useState<string>("질문종류"); const [error, setError] = useState("");
const [disabled, setDisabled] = useState(false);
const [success, setSuccess] = useState(false);
function BodyChange(e: { target: { value: React.SetStateAction<string> } }) { async function handlePostSubmit(event: FormEvent) {
setBody(e.target.value); event.preventDefault(); // prevent onSubmit -> rerendering
try {
setError("");
console.log("user data", user);
if (postingFormMatch()) {
setLoading(true);
const res = await postApi.posting(user);
console.log("서버연결됬나요", res);
console.log("user save");
setSuccess(true);
setError("");
}
} catch (error) {
console.log("에러발생");
catchErrors(error, setError);
} finally {
setLoading(false);
}
} }
}
function SelectCity() {
const [selectCity, setSelectCity] = useState<string>("질문종류");
function CityChange(e: { target: { value: React.SetStateAction<string> } }) { function postingFormMatch() {
setSelectCity(e.target.value); if (!isLength(user.title ?? "", { min: 1 })) {
setError("제목을 입력해 주세요.");
return false;
} else if (!isLength(user.text ?? "", { min: 1 })) {
setError("내용을 입력해 주세요.");
return false;
} else if (equals(city, "질문종류")) {
setError("테마를 선택해 주세요.");
return false;
} else if (equals(theme, "질문종류")) {
setError("도시를 선택해 주세요.");
return false;
} else {
return true;
}
} }
return (
<select
id="Questions"
className="border border-3 border-black w-1/12"
onChange={CityChange}
defaultValue="질문종류"
>
<option value="질문종류">도시</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>
);
}
function SelectTheme() { const titleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
const [selectTheme, setSelectTheme] = useState<string>("질문종류"); const title = event.currentTarget.value;
const newUser = { ...user, title: title };
console.log(event.currentTarget.value);
setTitle(event.currentTarget.value);
setUser(newUser);
};
function ThemeChange(e: { target: { value: React.SetStateAction<string> } }) { const textChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
setSelectTheme(e.target.value); const text = event.currentTarget.value;
} const newUser = { ...user, text: text };
return ( console.log(event.currentTarget.value);
<select setText(event.currentTarget.value);
id="Questions" setUser(newUser);
className="border border-3 border-black w-1/12" };
onChange={ThemeChange}
defaultValue="질문종류"
>
<option value="질문종류">테마</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>
<option value="cycling">{selectTheme}</option>
</select>
);
}
// 눌렀다는 데이터가 어딘가에 있어야 한다. Map 객체를 이용해서 기타등등
// function postup() { const cityChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
// axios.post("localhost:3000/api/post/up", { const city = event.currentTarget.value;
// id: "a", const newUser = { ...user, city: city };
// title: title, console.log(event.currentTarget.value);
// body: body, setCity(event.currentTarget.value);
// date: `${() => new Date()}`, setUser(newUser);
// theme: selectTheme, };
// city: selectCity,
// }); const themeChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
// } const theme = event.currentTarget.value;
const newUser = { ...user, theme: theme };
console.log(event.currentTarget.value);
setTheme(event.currentTarget.value);
setUser(newUser);
};
export default function Posting() {
return ( return (
<div className="flex flex-col border-3"> <div className="flex flex-col border-3">
<form className="w-full items-center"> <form onSubmit={handlePostSubmit} className="w-full items-center">
<div className="flex flex-row relative"> <div className="flex flex-row relative">
<p className="basis-1/12 gap-x-8">Id</p> <p className="basis-1/12 gap-x-8">Id</p>
<p className="basis-8/12 invisible">empty</p> <p className="basis-8/12 invisible">empty</p>
<SelectCity /> <select
<SelectTheme /> name="city"
id="Questions"
className="border border-3 border-black w-1/12"
onChange={cityChange}
defaultValue="질문종류"
>
<option value="질문종류">도시</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>
<select
name="theme"
id="Questions"
className="border border-3 border-black w-1/12"
onChange={themeChange}
defaultValue="질문종류"
>
<option value="질문종류">테마</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>
<button <button
type="submit" type="submit"
...@@ -107,13 +152,19 @@ export default function Posting() { ...@@ -107,13 +152,19 @@ export default function Posting() {
<div className="flex border-4"> <div className="flex border-4">
<textarea <textarea
onChange={Title} name="title"
onChange={titleChange}
placeholder="title" placeholder="title"
className="w-full h-8" className="w-full h-8"
></textarea> ></textarea>
</div> </div>
<div onChange={Body} className="flex border-2"> <div className="flex border-2">
<textarea placeholder="body" className="w-full h-96"></textarea> <textarea
onChange={textChange}
name="text"
placeholder="text"
className="w-full h-96"
></textarea>
</div> </div>
</form> </form>
</div> </div>
......
export interface PostType { export interface PostType extends PostingType {
id: string; date?: string;
title: string;
body?: string;
date: string;
counts: number; counts: number;
theme?: string; id?: string;
city?: string; }
export interface PostingType {
title: string;
text?: string;
theme: string;
city: string;
username: string;
} }
export interface SignupUser { export interface SignupUser {
......
import { NextFunction, Request, Response } from "express"; import { NextFunction, Request, Response } from "express";
import isLength from "validator/lib/isLength";
import equals from "validator/lib/equals";
import { asyncWrap } from "../helpers"; import { asyncWrap } from "../helpers";
import jwt, { JwtPayload } from "jsonwebtoken";
import { jwtCofig, envConfig, cookieConfig } from "../config";
import { postDb } from "../db";
export const posting = asyncWrap(async (req, res) => { export const posting = asyncWrap(async (req, res) => {
const { title, body, date, theme, city } = req.body; const { title, text, date, theme, city } = req.body;
// 1) title 빈 문자열인지 확인
const titleString = postDb.checkTitleNull(title, );
if (!titleString) {
return res.status(422).send(`${title} 제목을 입력해 주세요`);
}
// 2) body 빈 문자열인지 확인
const bodyString = postDb.checkBodyNull(body, );
if (!bodyString) {
return res.status(422).send(`${body} 여행 후기를 입력해 주세요`);
}
// 3) submit 이벤트 발생시 date값 입력 console.log("body", req.body);
const dateGet = postDb.getSubmitDate(date, );
// 1) title 빈 문자열인지 확인
if (!isLength(title ?? "", { min: 1 })) {
return res.status(422).send("제목을 한 글자 이상 입력해주세요");
}
// 4) theme dropdown default-value일 경우 에러 // 2) body 빈 문자열인지 확인
const themeSelect = postDb.selectTheme(theme, ); if (!isLength(text ?? "", { min: 1 })) {
if (!themeSelect) { return res.status(422).send("제목을 한 글자 이상 입력해주세요");
return res.status(422).send(`${theme} 테마를 선택해 주세요`) }
}
// 5) cuty dropdown default-value일 경우 에러 // 3) submit 이벤트 발생시 date값 입력
const citySelect = postDb.selectCity(city, );
if (!citySelect) {
return res.status(422).send(`${city} 도시를 선택해 주세요`)
}
// 6) 토큰 생성
const token = jwt.sign({ }, jwtCofig.secret, {
expiresIn: jwtCofig.expires,
});
// 7) 쿠키에 토큰 저장 // 4) theme dropdown default-value "테마"일 경우 에러
res.cookie(cookieConfig.name, token, { if (equals(theme, "질문종류")) {
maxAge: cookieConfig.maxAge, return res.status(422).send("테마를 입력해 주세요");
path: "/", }
httpOnly: envConfig.mode === "production",
secure: envConfig.mode === "production",
});
// 8) 사용자 반환 // 5) city dropdown default-value "도시"일 경우 에러
res.json({}); if (equals(city, "질문종류")) {
return res.status(422).send("도시를 선택해 주세요");
}
}); });
export * as userDb from "./user.db"; export * as userDb from "./user.db";
export * as postDb from "./post.db"; // export * as postDb from "./post.db";
import { PostType, Post } from "../models";
export const createPost = async (post: PostType) => {
const newPost = await Post.create(post);
return newPost;
};
export const checkTitleNull = async (
title : string,
) => {
}
export const checkBodyNull = async (
body : string,
) => {
}
export const getSubmitDate = async (
date : string,
) => {
}
export const selectTheme = async (
theme : string,
) => {
let user;
if( theme != "테마" ) {
}
}
export const selectCity = async (
city : string,
) => {
let user;
if ( city != "도시" ) {
}
}
...@@ -7,7 +7,7 @@ const router = express.Router(); ...@@ -7,7 +7,7 @@ const router = express.Router();
router.use("/users", userRouter); router.use("/users", userRouter);
router.use("/auth", authRouter); router.use("/auth", authRouter);
router.use("/posts", postRouter); //router.route router.use("/posts", postRouter);
//posting함수 -> mongodb에 posts json형식으로 저장
export default router; export default router;
...@@ -3,6 +3,6 @@ import { postCtrl } from "../controllers"; ...@@ -3,6 +3,6 @@ import { postCtrl } from "../controllers";
const router = express.Router(); const router = express.Router();
router.route("/posting").post(postCtrl.posting); router.route("/").post(postCtrl.posting);
export default router; 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