You need to sign in or sign up before continuing.
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