Skip to content

Destiny-star03/HealthNote

Repository files navigation

HealthNote 🩺

나만의 인바디·운동 기록 대시보드 (React + Vite)

체성분(체중, 골격근량, 체지방률)과 운동 기록을 한 화면에서 관리하고, 최근 7일 요약과 그래프까지 보여주는 개인용 헬스 노트 웹 애플리케이션입니다. 모든 데이터는 브라우저 localStorage 에 저장되며, 별도 서버 없이 동작합니다.

  1. 프로젝트 소개

HealthNote는 다음 두 가지 정보를 중심으로 동작합니다.

체성분 기록 (InBody 형태)

날짜별로 체중(kg), 골격근량(kg), 체지방률(%) 기록

최근 기록 카드 / 인바디 스타일 그래프 / 목표와의 차이 확인

운동 기록

날짜별 운동 이름, 운동 시간(분), 칼로리(kcal) 기록

최근 7일 동안의 운동 횟수·평균 운동 시간·총 칼로리를 요약해서 표시

또한, 프로필 정보(나이, 키, 성별) 를 입력해두면 체성분 값에 대해 표준 / 표준 이상 / 표준 이하 를 계산해서 보여줍니다.

  1. 주요 기능 ✅ 2-1. 프로필 관리

나이, 키, 성별(남/여) 입력

첫 접속 시, 프로필이 비어있으면 자동으로 프로필 모달 표시

프로필 정보는 localStorage("healthnote_profile") 에 저장

프로필을 기반으로 인바디 카드에서 표준/이상/이하 상태 계산

사용 컴포넌트 / 훅:

ProfileModal.jsx

useHealthNoteData() – 프로필 상태 및 저장 로직 포함

✅ 2-2. 체성분 기록 관리

기록 항목

날짜

체중(kg)

골격근량(kg)

체지방률(%)

기능

새 기록 추가

기존 기록 선택 후 편집 / 수정

기록 삭제

날짜는 오늘보다 미래 날짜 선택 불가 (max={today})

사용 컴포넌트 / 훅:

BodyForm.jsx

useState, useEffect 를 활용한 편집 모드/추가 모드 전환

editingBody 값이 있을 때는 해당 데이터를 폼에 채워 넣고 수정

BodyTable.jsx

날짜 내림차순(최근 기록 먼저) 정렬

행 클릭 시 해당 기록을 폼으로 올려서 수정

삭제 버튼으로 개별 기록 삭제

BodyRecordModal.jsx

체성분 기록 입력 폼 + 최근 기록 테이블을 하나의 모달로 구성

오버레이 클릭 시 닫힘 처리

useHealthNoteData()

bodyRecords 상태 관리

addBody / updateBody / deleteBody 함수 제공

localStorage("bodyRecords")와 자동 동기화

✅ 2-3. 운동 기록 관리

기록 항목

날짜

운동명

시간(분)

칼로리(kcal)

기능

운동 기록 추가

최근 운동 기록을 날짜 기준으로 정렬해서 조회

기록 삭제

날짜 역시 오늘 이후로는 선택 불가 (max={today})

사용 컴포넌트 / 훅:

ExerciseForm.jsx

useState, useEffect 로 추가 모드와 편집 모드 모두 지원 가능하게 설계

운동명 공백 입력 방지 (trim() + 유효성 검사)

ExerciseTable.jsx

날짜 내림차순 + 같은 날짜에서는 최신 입력 먼저

삭제 버튼 클릭 시 삭제 콜백 호출

ExerciseRecordModal.jsx

상단: 운동 입력 폼

하단: “최근 기록” 리스트

배경 클릭 시 모달 닫기 / 카드 클릭 시 이벤트 전파 차단

useHealthNoteData()

exerciseRecords 상태 관리

addExercises / deleteExercise 함수 제공

localStorage("exerciseRecords")와 자동 동기화

✅ 2-4. 대시보드 & 요약

메인 대시보드는 크게 네 영역으로 구성됩니다.

최근 체성분 카드 (ActivityHeader)

가장 최근 체성분 기록 한 건을 카드 형태로 표시

체중 / 근육량 / 체지방률을 pill 카드로 배치

기록이 없을 때는 안내 메시지 + “기록 관리” 버튼만 표시

목표값 & 달성률 패널 (ActivityGoalPanel)

목표 체중(kg), 목표 근육량(kg) 입력

최근 기록과 비교해 다음 메시지 표시

예: “목표까지 2.1kg 감량 필요”, “목표를 초과했습니다” 등

내부 모달(GoalModal)에서 목표값 편집

목표는 localStorage("goals")에 저장

최근 7일 요약 (ActivitySummary)

최근 7일 동안

운동한 날 수 / 운동 횟수

평균 운동 시간

총 칼로리

운동한 날 수가 3일 이상이면 카드에 강조 배지 표시

체성분 변화 차트 (ActivityChart)

Recharts의 LineChart 사용

세 가지 지표 중 하나 선택해서 라인 차트로 표시

체중(kg), 골격근량(kg), 체지방률(%)

날짜별 데이터를 시계열로 정렬

선택된 측정값의 날짜와 수치를 상단에 표시

현재 선택 지점에 ReferenceLine(수직선) 표시

프로필 정보를 전달해 표준 / 표준 이상 / 표준 이하 상태 계산 (각 metric 별로 색상과 라벨 표현)

  1. 상태 관리 구조 useHealthNoteData() 커스텀 훅

src/hooks/useHealthNoteData.js에서 전체 화면에서 공통으로 사용하는 상태를 관리합니다.

초기 로딩 (useEffect)

localStorage에서 body / exercise / goals / profile 을 한 번에 읽어옴

프로필이 없거나 비어 있으면 자동으로 프로필 모달 오픈

공통 업데이트 헬퍼

updateBodyRecords(updateFn)

updateExerciseRecords(updateFn)

setState와 localStorage 저장을 한 곳에서 처리

체성분 관련

bodyRecords, editingBody, setEditingBody

addBody(record)

updateBody(updatedRecord)

deleteBody(id)

운동 관련

exerciseRecords

addExercises(newRecords[])

deleteExercise(id)

목표 / 프로필 관련

goals, saveGoals(newGoals)

profile, saveProfile(data)

모달 상태

isProfileOpen, isBodyModalOpen, isExerciseModalOpen

openProfileModal / closeProfileModal

openBodyModal / closeBodyModal

openExerciseModal / closeExerciseModal

이 훅을 App.jsx에서 호출해서 상태를 최상단에서 한 번만 관리하고, 필요한 컴포넌트에 props로 내려보내는 구조입니다. (→ “상태 끌어올리기(Lifting State Up)”와 “단방향 데이터 흐름”을 잘 보여줌)

  1. 기술 스택

React (함수형 컴포넌트 + Hooks)

useState, useEffect, useMemo, 커스텀 훅 사용

Vite

개발 서버 및 번들러

Tailwind CSS

유틸리티 클래스 기반의 스타일링

반응형 레이아웃, 그림자, 테두리, 색상 등 UI 디자인

Recharts

체성분 변화 LineChart 표현

localStorage

bodyRecords, exerciseRecords, goals, profile 데이터 영구 저장

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages