해하!(해승하이란 뜻) 길고길었던 프로젝트의 마지막 단계가 왔다!
홈 화면은 비교적 다른 기능에 비해 나름 삽질도 덜 하고 빠르게 만들었다. 그래도 데이터 구조를 또 바꾸느라 고생쫌 했지만 거두절미하고 마지막 개발 일지를 끄적여보자.
드디어 공개되는 로그인과 홈 화면이다.
나는 컴포넌트를 다음과 같이 세개로 분할했다.
HomeProfile : 유저의 profile 데이터를 불러와서 제공함
Calendars.js : 리액트 네이티브의 오픈소스를 활용함
HomeRecords.js : 날짜에 맞는 데이터를 보여줄 수 있도록 함 (default : 오늘)
홈 화면에 계산된 데이터를 제공하기 위해 유저 프로필에 데이터를 추가해주고 코드를 손봤다. 달리기를 끝내고 저장할때 합산하는 함수를 만들어줬다.
const sumRecord = async () => {
...
sumElapsedTime = moment(sumElapsedTime, 'HH:mm:ss')
.add(moment.duration(elapsedTime))
.format('HH:mm:ss')
const sumData = {
... userData.value,
sumElapsedTime : sumElapsedTime,
sumDistance : (parseFloat(sumDistance) + parseFloat(totalDistance)).toFixed(2),
sumCalories : (parseFloat(sumCalories) + parseFloat(calories)).toFixed(2)
... // user Profile update
}
캘린더 기능은 react native에서 가장 많이 쓰이는 오픈소스인 react-native-calendars 라이브러리를 활용하였다.
코드를 전부 첨부할테니 혹시 참고하실 분이 있다면 도움이 되었으면 좋겠다.
LocaleConfig.locales['fr'] = {
monthNames: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'],
monthNamesShort: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'],
dayNames: ['일', '월', '화', '수', '목', '금', '토'],
dayNamesShort: ['일', '월', '화', '수', '목', '금', '토']
}
LocaleConfig.defaultLocale = 'fr' // 캘린더의 월, 요일 명칭 변경
export default function Calendars({ recordData, setSelected }) {
const markedDates = {} // 마크된 날짜 Style Cumtom
recordData.forEach(([date, data]) => {
if (data.length > 0) {
markedDates[date] = {
marked: true,
dotColor: '#D6E0FA',
customStyles: {
container: { backgroundColor: '#D6E0FA' },
}
}
}
})
return (
<View style={calendarsStyles.container}>
<Calendar
style={calendarsStyles.calendar}
theme={{
textMonthFontSize: 20,
textMonthFontWeight: 'bold',
arrowColor: '#274490',
todayTextColor: '#FFFFFF',
todayBackgroundColor: '#FF0000'
}}
markingType={'custom'} // 마킹 타입을 cumstom으로 해야 마크된 날짜의 Style을 커스텀하여 사용할 수 있음
markedDates={markedDates}
onDayPress={(day) => {
setSelected(day.dateString) // 선택 된 날짜를 HomeMain 컴포넌트로 보냄
}}
/>
</View>
)
}
HomeMain 컴포넌트에서는 기록된 레코드 데이터를 불러오는데 요 데이터를 활용해서 데이터가 존재하는 날짜에 마킹을 하고 운동 기록을 화면에 렌더링 할 수 있다.
const [selected, setSelected] = useState(format(new Date(), "yyyy-MM-dd"))
유저가 클릭하여 선택된 날짜는 Calendars 컴포넌트의 onDayPress를 통해 전달 받는다.
const [recordData, setRecordData] = useState([])
저장된 달리기 기록을 배열 형태로 불러와서 Calendars 컴포넌트로 넘겨주면 날짜별로 비교하여 데이터 존재 유무에 따라 화면에 마킹을 한다.
const [resultData, setResultData] = useState({})
const selectedData = resultData[selected] || []
유저가 선택한 날짜만을 넣어서 HomeRecord 컴포넌트에 전달한 후 화면에 렌더링 한다.
이 두 가지 기능이 완료됐을 때는 아래처럼 동작하는 것을 확인할 수 있다!
(테스트용 더미 데이터로 진행한 거라 전체 기록에 요상한 숫자들은 무시해주길 바란다!)
이렇게 기능 구현이 마무리됐다. 우여곡절 많았고 혼자서 프론트랑 백을 다 하려고 하니 기능 구현 뿐만아니라 고민하는 시간, 삽질하는 시간 전부 많이 들었다. 힘든건 당연하고 괴로웠던 적도 있지만 끝내고 나니까 후련하기도하고 아쉽기도하고 그렇다.
한가지 아쉬운 점은 서버 코드가 CRUD 외엔 기능이 별로 없어서 개발 일지에서도 내용을 다루지 않았다. 다음에는 서버 기능이 재밌는 프로젝트를 구상해서 만들어봐야겠다.
런플립 개발 일지는 이걸로 끝나지만 데이터를 추가로 수집해서 깃허브 리드미에 제대로 정리할 생각이다. 아됴스(찡긋)
[깃허브]
프론트 https://github.com/haeseung123/RunFlip
백 https://github.com/haeseung123/RunFlip-server