1. 달력을 만들기 위해서 moment 패키지를 사용했다.
yarn add moment
or
npm install moment --save
2. 버튼을 누르면 해당 년도와 월이 나올 수 있도록 코드 구현
더보기
더보기
// Diary.js
import React from "react";
import moment from "moment";
const Diary = () => {
const [getMoment, setMoment] = React.useState(moment());
const [monthDay, setMonthDay] = React.useState(0);
const today = getMoment; // today === moment();
React.useEffect(() => {
const day = new Date(today);
const days = new Date(day.getFullYear(), day.getMonth()+1, 0).getDate();
setMonthDay(days);
console.log(day.getFullYear())
console.log(day.getMonth()+1);
console.log(days)
}, [today]);
return (
<>
<div className="App">
<div className="control">
<button
onClick={() => {
setMoment(getMoment.clone().subtract(1, "month"));
}}
>
이전달
</button>
<span>{today.format("YYYY 년 MM 월")}</span>
{/* YYYY는 년도 MM 은 달입니다. */}
<button
onClick={() => {
setMoment(getMoment.clone().add(1, "month"));
}}
>
다음달
</button>
</div>
<table>
<tbody>{monthDay}</tbody>
</table>
</div>
</>
);
};
export default Diary;
3. 해당 월의 일자를 구하는 기능 구현 중 0월이 나옴 → getMonth()+1 해줌.
4. 팀장님과 논의 해본 결과 이번달에는 오늘 날짜까지만 아이콘을 띄우고, 저번달까지의 기록은 해당 월의 일수만큼 아이콘을 띄우고, 다음달 기록은 띄우지 않아야 해서 if문을 많이 사용해서... 코드를 구현했다. 복잡하긴 하지만 최대한 이해하기 쉽도록 코드를 구현했다. (아닐지도...)
더보기
더보기
const [getMoment, setMoment] = React.useState(moment());
const [monthDay, setMonthDay] = React.useState(0);
const month = getMoment; // month === moment();
const arr = new Array(monthDay).fill(""); // 한꺼번에 배열 채우기
React.useEffect(() => {
const today = new Date(moment()); // 오늘 날짜
const day = new Date(month); // 사용자가 선택한 날짜
if (
today.getFullYear() + today.getMonth() ===
day.getFullYear() + day.getMonth()
) {
// 오늘
const days = new Date(today).getDate();
setMonthDay(days);
} else if (today.getFullYear() < day.getFullYear()) {
// 다음년도
setMonthDay(0);
} else if (today.getFullYear() > day.getFullYear()) {
// 전년도
const days = new Date(day.getFullYear(), day.getMonth() + 1, 0).getDate(); // 사용한 선택한 날짜의 일수
setMonthDay(days);
} else {
// 이번년도
if (day.getMonth > today.getMonth()) {
// 다음달
setMonthDay(0);
} else {
// 저번달
const days = new Date(
day.getFullYear(),
day.getMonth() + 1,
0
).getDate(); // 사용한 선택한 날짜의 일수
setMonthDay(days);
}
}
}, [month]);
5. 서버에서 다이어리 관련 데이터를 받아 온다는 가정 하에 사용자가 평점을 남기지 않았을 경우 default 값을 띄워 주도록 처리 해야 함.
1) 서버에서 데이터를 가져 왔다는 가정 하에 일자에 맞춰 arr 배열에 데이터를 넣어줬다.
// index => 0, diaryList => day랑 서로 일치를 해야 함.
// 1) 해당 월의 일수 길이만큼의 배열에 배열 연산자 forEach를 돌린다.
// 2) 서버에서 가져온 diaryList 배열의 길이만큼 forEach를 돌린다.
// ※ 이중 반복문을 돌리는 것과 같다.
// 3) diaryIndex에 있는 객체 데이터를 arr의 index에 넣는다. (이때, index는 0부터 시작하기 때문에 +1을 해줘서 일(day)와 맞춘다.)
arr.forEach((arrItem, arrIndex) => {
diaryList.forEach((diaryItem, diaryIndex) => {
if (arrIndex + 1 === parseInt(diaryList[diaryIndex]?.day)) {
arr[arrIndex] = diaryList[diaryIndex];
}
});
});
2) 일(day) index 안에 데이터가 ""일 경우 default 이미지를 띄운다.
: 이 부분에서 시행착오가 많았다. map을 돌렸을 때 arr의 요소들이 undefined가 떴었다. 이유는 밝히기 못했지만.. arr를useState()에 넣었더니 해결 되었다.
더보기
더보기
import React from "react";
import moment from "moment";
import { useSelector } from "react-redux";
import { history } from "../redux/configureStore";
import Charater from "../elements/Charater";
const Diary = () => {
const [getMoment, setMoment] = React.useState(moment());
const [monthDay, setMonthDay] = React.useState(0);
const arr = new Array(monthDay).fill(1); // 한꺼번에 배열 채우기
const diaryList = useSelector((state) => state.diary.diaryList);
const [test, setTest] = React.useState(arr);
React.useEffect(() => {
const today = new Date(moment()); // 오늘 날짜
const day = new Date(getMoment); // 사용자가 선택한 날짜
if (
today.getFullYear() + "_" + today.getMonth() ===
day.getFullYear() + "_" + day.getMonth()
) {
// 오늘
const days = new Date(today).getDate();
setMonthDay(days);
} else if (today.getFullYear() < day.getFullYear()) {
// 다음년도
setMonthDay(0);
} else if (today.getFullYear() > day.getFullYear()) {
// 전년도
const days = new Date(day.getFullYear(), day.getMonth(), 0).getDate(); // 사용한 선택한 날짜의 일수
setMonthDay(days);
} else {
// 이번년도
if (day.getMonth > today.getMonth()) {
// 다음달
setMonthDay(0);
} else {
// 저번달
const days = new Date(day.getFullYear(), day.getMonth(), 0).getDate(); // 사용한 선택한 날짜의 일수
setMonthDay(days);
}
}
// index => 0, diaryList => day랑 서로 일치를 해야 함.
// 1) 해당 월의 일수 길이만큼의 배열에 배열 연산자 forEach를 돌린다.
// 2) 서버에서 가져온 diaryList 배열의 길이만큼 forEach를 돌린다.
// ※ 이중 반복문을 돌리는 것과 같다.
// 3) diaryIndex에 있는 객체 데이터를 arr의 index에 넣는다. (이때, index는 0부터 시작하기 때문에 +1을 해줘서 일(day)와 맞춘다.)
arr.forEach((arrItem, arrIndex) => {
diaryList.forEach((diaryItem, diaryIndex) => {
if (arrIndex + 1 === parseInt(diaryList[diaryIndex].day)) {
arr[arrIndex] = diaryList[diaryIndex];
}
});
});
setTest(arr);
}, [getMoment, monthDay]);
const diaryDetail = (index) => {
const day = new Date(getMoment);
console.log(day.getMonth() + 1 + "월", index + "일");
};
return (
<>
<div>
<div>
<button
onClick={() => {
setMoment(getMoment.clone().subtract(1, "month"));
}}
>
이전달
</button>
<span>{getMoment.format("YYYY 년 MM 월")}</span>
{/* YYYY는 년도 MM 은 달입니다. */}
<button
onClick={() => {
setMoment(getMoment.clone().add(1, "month"));
}}
>
다음달
</button>
</div>
<p>{monthDay}</p>
<div
style={{
backgroundColor: "#dddddd",
width: "50%",
height: "80vh",
margin: "auto",
display: "flex",
flexWrap: "wrap",
padding: "10px",
}}
>
{test.map((item, index) => {
return (
<div key={index + 1 + "days"}>
{item.feelScore && item.sleepScore ? (
<Charater
shape="charater"
size="70"
feelNumber={item.feelScore}
sleepNumber={item.sleepScore}
_onClick={() => {
diaryDetail(index + 1);
}}
margin="10px"
/>
) : (
<Charater
shape="charater"
size="70"
feelNumber={0}
sleepNumber={0}
_onClick={() => {
diaryDetail(index + 1);
}}
margin="10px"
/>
)}
<div>{index + 1}</div>
</div>
);
})}
</div>
</div>
<button
onClick={() => {
history.push(`/diaryWrite/4`);
}}
>
다이어리 생성,수정
</button>
</>
);
};
export default Diary;
import zIndex from "@mui/material/styles/zIndex";
import { style } from "@mui/system";
import React from "react";
import styled from "styled-components";
const Charater = (props) => {
const { shape, size, src, _onClick, margin } = props;
const styles = {
size: size,
margin: margin
};
if (shape === "circle") {
return <ImageCircle {...styles}></ImageCircle>;
}
if (shape === "charater") {
return (
<React.Fragment>
<IconBox {...styles}>
<ImgIcon
{...styles}
style={{ zIndex: "3" }}
src={require(`../images/character/feel${props.feelNumber}.png`)}
onClick={_onClick}
/>
<ImgIcon
{...styles}
style={{ zIndex: "2" }}
src={require(`../images/character/sleep${props.sleepNumber}.png`)}
onClick={_onClick}
/>
</IconBox>
</React.Fragment>
);
}
return <React.Fragment></React.Fragment>;
};
//-- defaultProps --
Charater.defaultProps = {
shape: "circle",
src: "../images/character/sleep0.png",
size: 24,
onClick: () => {},
};
const ImageCircle = styled.div`
--size: ${(props) => props.size}px;
width: var(--size);
height: var(--size);
border-radius: var(--size);
background-image: url("${(props) => props.src}");
background-size: cover;
`;
const IconBox = styled.div`
--size: ${(props) => props.size}px;
width: var(--size);
height: var(--size);
position: "relative";
border-radius: var(--size);
background-color: aliceblue;
display: flex;
align-items: center;
justify-content: center;
${props => props.margin ? `margin : ${props.margin}` : `margin: 0 auto;`}
`;
const ImgIcon = styled.img`
--size: ${(props) => props.size}px;
width: var(--size);
position: absolute;
`;
export default Charater;
'항해 중 > 8-13주차 실전 프로젝트' 카테고리의 다른 글
[실전 프로젝트] ASMR 페이지 구현 (0) | 2021.12.30 |
---|---|
[실전 프로젝트] 다이어리 페이지 마무리, 네비게이션 바 만들기 (0) | 2021.12.29 |
[실전 프로젝트] 녹음, 녹음 파일 재생 + 보이스 페이지..? (0) | 2021.12.28 |
[실전 프로젝트] 푸쉬 알람 여부 (0) | 2021.12.27 |
[실전 프로젝트] API 설계, 기능 자료 조사, 프로젝트 기본 틀 잡기 (0) | 2021.12.24 |
댓글