-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'develop' into refactor/218
- Loading branch information
Showing
2 changed files
with
398 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
import React, { useEffect, useState } from "react"; | ||
import { useDispatch, useSelector } from "react-redux"; | ||
import { useNavigate, useLocation } from "react-router-dom"; | ||
import queryString from "query-string"; | ||
import { SET_PAGENAME } from "../../redux/modules/PageName"; | ||
import { useNavigate } from "react-router-dom"; | ||
import Button from "../../component/Button"; | ||
import diaryController from "../../api/diary.controller"; | ||
|
||
export const DIARY_MANAGEMENT_PAGE_PATH = "/diarymanagement"; | ||
|
||
const DiaryManagement = () => { | ||
const dispatch = useDispatch(); | ||
const userInfo = useSelector((state) => state.UserInfo); | ||
const [diaries, setDiaries] = useState([]); | ||
|
||
useEffect(() => { | ||
dispatch({ type: SET_PAGENAME, pageName: "일기 관리" }); | ||
}, [dispatch]); | ||
|
||
return ( | ||
<div> | ||
<SearchDiary id={userInfo.userId} setDiaries={setDiaries} /> | ||
<DiaryListCop diaryDates={diaries} /> | ||
</div> | ||
); | ||
}; | ||
|
||
function DiaryListCop({ diaryDates }) { | ||
const navigate = useNavigate(); | ||
const formattedDates = diaryDates.map((dateStr) => { | ||
const date = new Date(dateStr); | ||
const formattedDate = `${date.getFullYear()}년 ${date.getMonth() + 1}월 ${date.getDate()}일`; | ||
return formattedDate; | ||
}); | ||
const handleClick = (index) => { | ||
navigate("/calendar", { state: diaryDates[index] }); | ||
}; | ||
return ( | ||
<div> | ||
{diaryDates.length > 0 ? ( | ||
<div> | ||
{formattedDates.map((date, index) => ( | ||
<div | ||
className="my-3 flex bg-[#e0f4ff] h-[5rem] items-center justify-between px-2" | ||
onClick={() => handleClick(index)} | ||
key={index} | ||
> | ||
<div className="pl-3 text-[#7a7a7a] text-xl bg-white w-[50%] h-12 flex items-center rounded-xl"> | ||
{date} | ||
</div> | ||
<div className="text-xl text-[#82aae3] font-bold"> | ||
일기 확인하기 {">"} | ||
</div> | ||
</div> | ||
))} | ||
</div> | ||
) : ( | ||
<div className="text-xl flex justify-center mt-3"> | ||
일기가 존재하지 않습니다. | ||
</div> | ||
)} | ||
</div> | ||
); | ||
} | ||
|
||
function SearchDiary({ id, setDiaries }) { | ||
const [startDate, setStartDate] = useState(""); | ||
const [endDate, setEndDate] = useState(""); | ||
const [option, setOption] = useState(""); | ||
|
||
const navigate = useNavigate(); | ||
const location = useLocation(); | ||
|
||
const query = queryString.parse(location.search); | ||
|
||
const currentDate = new Date(); | ||
const currentYear = currentDate.getFullYear(); | ||
const currentMonth = String(currentDate.getMonth() + 1).padStart(2, "0"); | ||
const currentDay = String(currentDate.getDate()).padStart(2, "0"); | ||
|
||
const previousDate = new Date(currentDate); | ||
previousDate.setDate(currentDate.getDate() - 1); | ||
const previousYear = previousDate.getFullYear(); | ||
const previousMonth = String(previousDate.getMonth() + 1).padStart(2, "0"); | ||
const previousDay = String(previousDate.getDate()).padStart(2, "0"); | ||
|
||
const defaultDate = `${currentYear}-${currentMonth}-${currentDay}`; | ||
const defaultPreviousDate = `${previousYear}-${previousMonth}-${previousDay}`; | ||
|
||
useEffect(() => { | ||
setStartDate(query.startDate || defaultPreviousDate); | ||
setEndDate(query.endDate || defaultDate); | ||
setOption(query.sortBy || "DES_CREATE_DATE"); | ||
if (query.startDate && query.endDate) { | ||
searchDiaryList(query.startDate, query.endDate, query.sortBy); | ||
} | ||
}, [query.startDate, query.endDate, query.sortBy]); | ||
|
||
useEffect(() => { | ||
searchDiaryList(startDate, endDate, option); | ||
}, [option]); | ||
|
||
const handleStartDateChange = (event) => { | ||
const newStartDate = event.target.value; | ||
setStartDate(newStartDate); | ||
if (newStartDate > endDate) { | ||
setEndDate(""); | ||
} | ||
}; | ||
|
||
const handleEndDateChange = (event) => { | ||
setEndDate(event.target.value); | ||
}; | ||
|
||
const handleOptionChange = (event) => { | ||
setOption(event.target.value); | ||
}; | ||
|
||
const searchDiaryList = async ( | ||
start = startDate, | ||
end = endDate, | ||
sortBy = option | ||
) => { | ||
try { | ||
const response = await diaryController.searchDiaryList({ | ||
userId: id, | ||
startDate: start, | ||
finishDate: end, | ||
sortBy: sortBy, | ||
}); | ||
const diaries = response.data.result.diaries; | ||
const createDateList = diaries.map((diary) => diary.createDate); | ||
setDiaries(createDateList); | ||
|
||
navigate( | ||
`${location.pathname}?startDate=${start}&endDate=${end}&sortBy=${sortBy}`, | ||
{ replace: true } | ||
); | ||
} catch (error) { | ||
console.error("기간별 일기 조회 중 오류", error); | ||
} | ||
}; | ||
|
||
return ( | ||
<div className="mt-5 border-b-2 pb-4"> | ||
<div className="flex items-center justify-evenly mb-5"> | ||
<input | ||
className="text-xl border-b-2 border-[#82aae3] w-[75%]" | ||
type="date" | ||
max={endDate} | ||
value={startDate} | ||
onChange={handleStartDateChange} | ||
/> | ||
<div className="text-xl">부터</div> | ||
</div> | ||
<div className="flex items-center mb-4 justify-evenly"> | ||
<input | ||
className="text-xl border-b-2 border-[#82aae3] w-[75%]" | ||
type="date" | ||
min={startDate} | ||
max={defaultDate} | ||
onChange={handleEndDateChange} | ||
value={endDate} | ||
/> | ||
<div className="text-xl">까지</div> | ||
</div> | ||
<div className="flex justify-end mb-3 text-xl"> | ||
<select value={option} onChange={handleOptionChange}> | ||
<option value="DES_CREATE_DATE">최신순</option> | ||
<option value="ASC_CREATE_DATE">오래된순</option> | ||
</select> | ||
</div> | ||
<Button | ||
text={"검색"} | ||
width={"100%"} | ||
onClick={() => searchDiaryList(startDate, endDate, option)} | ||
/> | ||
</div> | ||
); | ||
} | ||
|
||
export default DiaryManagement; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,215 @@ | ||
import React, { useEffect, useState } from "react"; | ||
import UserController from "../../api/users.controller"; | ||
import { useForm } from "react-hook-form"; | ||
import Button from "../../component/Button"; | ||
import Modal from "../../component/Modal"; | ||
import { useNavigate } from "react-router-dom"; | ||
import { useDispatch, useSelector } from "react-redux"; | ||
<<<<<<< HEAD:src/pages/UserUpdate.js | ||
import { SET_PAGENAME } from "../redux/modules/PageName"; | ||
======= | ||
import { SET_PAGENAME } from "../../redux/modules/PageName"; | ||
import axios from "axios"; | ||
>>>>>>> develop:src/pages/MyPages/UserUpdate.js | ||
|
||
export const USER_UPDATE_PAGE_PATH = "/userupdate"; | ||
|
||
const UserUpdate = () => { | ||
const dispatch = useDispatch(); | ||
const userInfo = useSelector((state) => state.UserInfo); | ||
const navigate = useNavigate(); | ||
|
||
const { | ||
register, | ||
handleSubmit, | ||
watch, | ||
formState: { errors }, | ||
reset, | ||
} = useForm(); | ||
|
||
useEffect(() => { | ||
dispatch({ type: SET_PAGENAME, pageName: "정보 수정" }); | ||
}, [dispatch]); | ||
|
||
useEffect(() => { | ||
reset(userInfo); | ||
console.log(userInfo); | ||
}, [userInfo, reset]); | ||
|
||
const onSubmit = async (data) => { | ||
const accessToken = localStorage.getItem("AccessToken"); | ||
if (!accessToken) { | ||
console.error("엑세스 토큰이 없습니다."); | ||
return; | ||
} | ||
|
||
const userData = { | ||
id: userInfo.userId, | ||
username: data.username, | ||
nickname: data.nickname, | ||
email: data.email, | ||
password: data.password, | ||
birth: data.birth, | ||
}; | ||
|
||
try { | ||
await UserController.updateUser({ userData, accessToken }); | ||
console.log("성공"); | ||
navigate("/mypage"); | ||
} catch (error) { | ||
console.log("정보 수정 중 오류", error); | ||
} | ||
}; | ||
|
||
const [nickname, setNickname] = useState(""); | ||
const nicknameRegister = register("nickname", { | ||
required: "빈 칸 없이 작성해주세요.", | ||
}); | ||
|
||
const handleChange = (event) => { | ||
setNickname(event.target.value); | ||
nicknameRegister.onChange(event); | ||
}; | ||
|
||
const checkNickname = async () => { | ||
if (nickname === "") return; | ||
try { | ||
const res = await UserController.checkNickname({ nickname }); | ||
setIsNicknameExist(false); | ||
} catch (error) { | ||
console.log(error); | ||
setIsNicknameExist(true); | ||
} | ||
setIsModalOpen(true); | ||
}; | ||
|
||
const [isModalOpen, setIsModalOpen] = useState(false); | ||
const closeModal = () => { | ||
setIsModalOpen(false); | ||
}; | ||
const [isNicknameExist, setIsNicknameExist] = useState(false); | ||
|
||
if (!userInfo) return null; | ||
|
||
return ( | ||
<div className="flex flex-col justify-center items-center my-4"> | ||
<form onSubmit={handleSubmit(onSubmit)} className="mb-5"> | ||
<div className="inputField"> | ||
<label>이름</label> | ||
<input | ||
className="input" | ||
type="text" | ||
defaultValue={userInfo.username} | ||
{...register("username", { | ||
required: "빈 칸 없이 작성해주세요.", | ||
minLength: { | ||
value: 2, | ||
message: "두 글자 이상 입력해주세요.", | ||
}, | ||
})} | ||
/> | ||
<div className="error-message"> | ||
{errors.username && errors.username.message} | ||
</div> | ||
</div> | ||
<div className="inputField"> | ||
<label>닉네임</label> | ||
<div className="flex flex-row justify-center items-center"> | ||
<input | ||
className="input" | ||
{...nicknameRegister} | ||
onChange={handleChange} | ||
type="text" | ||
defaultValue={userInfo.nickname} | ||
style={{ width: "283px" }} | ||
/> | ||
<Button | ||
width="50px" | ||
height="30px" | ||
text="확인" | ||
fontSize="15px" | ||
onClick={checkNickname} | ||
/> | ||
</div> | ||
<div className="error-message"> | ||
{errors.nickname && errors.nickname.message} | ||
</div> | ||
</div> | ||
<div className="inputField"> | ||
<label>생년월일</label> | ||
<input | ||
className="input" | ||
type="date" | ||
defaultValue={userInfo.birth} | ||
{...register("birth", { required: "빈 칸 없이 작성해주세요." })} | ||
/> | ||
<div className="error-message"> | ||
{errors.birth && errors.birth.message} | ||
</div> | ||
</div> | ||
<div className="inputField"> | ||
<label>이메일</label> | ||
<input | ||
className="input" | ||
type="text" | ||
defaultValue={userInfo.email} | ||
{...register("email", { | ||
required: "빈 칸 없이 작성해주세요.", | ||
pattern: { | ||
value: /\S+@\S+\.\S+/, | ||
message: "올바른 이메일 형식이 아닙니다.", | ||
}, | ||
})} | ||
/> | ||
<div className="error-message"> | ||
{errors.email && errors.email.message} | ||
</div> | ||
</div> | ||
<div className="inputField"> | ||
<label>비밀번호</label> | ||
<input | ||
className="input" | ||
type="password" | ||
{...register("password", { | ||
required: "빈 칸 없이 작성해주세요.", | ||
minLength: { | ||
value: 6, | ||
message: "비밀번호는 최소 6자 이상이어야 합니다.", | ||
}, | ||
})} | ||
/> | ||
<div className="error-message"> | ||
{errors.password && errors.password.message} | ||
</div> | ||
</div> | ||
<div className="inputField"> | ||
<label>비밀번호 확인</label> | ||
<input | ||
className="input" | ||
type="password" | ||
placeholder="비밀번호를 입력하세요." | ||
{...register("passwordChk", { | ||
required: "빈 칸 없이 작성해주세요.", | ||
validate: (value) => | ||
value === watch("password") || "비밀번호가 일치하지 않습니다.", | ||
})} | ||
/> | ||
<div className="error-message"> | ||
{errors.passwordChk && errors.passwordChk.message} | ||
</div> | ||
</div> | ||
<button id="loginBtn" type="submit"> | ||
완료 | ||
</button> | ||
</form> | ||
{isModalOpen && isNicknameExist && ( | ||
<Modal onClose={closeModal} content="다른 닉네임을 입력해주세요." /> | ||
)} | ||
{isModalOpen && !isNicknameExist && ( | ||
<Modal onClose={closeModal} content="사용 가능한 닉네임입니다." /> | ||
)} | ||
</div> | ||
); | ||
}; | ||
|
||
export default UserUpdate; |