v0.1.44 - 날짜 기준과 TODO 정리
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
- 프로젝트명: 10 Minute Planner 웹 UI
|
- 프로젝트명: 10 Minute Planner 웹 UI
|
||||||
- 기술 스택: Vue 3 + Vite + TailwindCSS + JavaScript
|
- 기술 스택: Vue 3 + Vite + TailwindCSS + JavaScript
|
||||||
- 현재 기준 버전: `v0.1.43` 준비 중
|
- 현재 기준 버전: `v0.1.44` 준비 중
|
||||||
- Git 원격 저장소: `https://git.sori.studio/zenn/planner.sori.studio.git`
|
- Git 원격 저장소: `https://git.sori.studio/zenn/planner.sori.studio.git`
|
||||||
|
|
||||||
## 기준 디자인
|
## 기준 디자인
|
||||||
@@ -53,7 +53,8 @@
|
|||||||
- 달력 상단은 월 좌우 화살표, 클릭형 연도 선택, `TODAY` 버튼 구조로 동작한다.
|
- 달력 상단은 월 좌우 화살표, 클릭형 연도 선택, `TODAY` 버튼 구조로 동작한다.
|
||||||
- 입력 내용이 있는 날짜는 달력 하단에 빨간 점으로 표시된다.
|
- 입력 내용이 있는 날짜는 달력 하단에 빨간 점으로 표시된다.
|
||||||
- 상단 날짜 표시에서는 토요일의 `(토)`만 파란색, 일요일의 `(일)`만 빨간색으로 표시한다.
|
- 상단 날짜 표시에서는 토요일의 `(토)`만 파란색, 일요일의 `(일)`만 빨간색으로 표시한다.
|
||||||
- 플래너 상태는 `localStorage`에 저장되며, 날짜별 기록과 선택 날짜, 달력 보고 있던 월까지 복원된다.
|
- 플래너 상태는 `localStorage`에 저장되며, 날짜별 기록과 통계 범위 같은 UI 상태를 복원한다.
|
||||||
|
- 플래너 기록 자체는 로컬에 남기되, 앱을 새로 열 때 기본 기준 날짜는 마지막 열람 날짜가 아니라 항상 오늘 날짜로 맞춘다.
|
||||||
- `localStorage` 접근 로직은 `src/lib/plannerStorage.js`로 분리하기 시작했고, 이후 API/DB adapter로 교체하기 쉬운 구조로 정리 중이다.
|
- `localStorage` 접근 로직은 `src/lib/plannerStorage.js`로 분리하기 시작했고, 이후 API/DB adapter로 교체하기 쉬운 구조로 정리 중이다.
|
||||||
- 프론트는 헤더에서 `LOGIN` / `SIGN UP` 모달을 열 수 있고, 로그인 상태면 닉네임과 `LOGOUT` 버튼을 표시한다.
|
- 프론트는 헤더에서 `LOGIN` / `SIGN UP` 모달을 열 수 있고, 로그인 상태면 닉네임과 `LOGOUT` 버튼을 표시한다.
|
||||||
- 인증 토큰과 현재 사용자 정보는 프론트 로컬 저장소에 따로 유지하고, 앱 시작 시 `/api/auth/me`로 세션 복원을 시도한다.
|
- 인증 토큰과 현재 사용자 정보는 프론트 로컬 저장소에 따로 유지하고, 앱 시작 시 `/api/auth/me`로 세션 복원을 시도한다.
|
||||||
@@ -232,6 +233,7 @@
|
|||||||
- 현재 환경에서는 Docker 데몬이 꺼져 있어서 `docker compose build` 실검증은 하지 못했고, 데몬 시작 후 다시 확인이 필요하다.
|
- 현재 환경에서는 Docker 데몬이 꺼져 있어서 `docker compose build` 실검증은 하지 못했고, 데몬 시작 후 다시 확인이 필요하다.
|
||||||
- 이미지 저장 기능은 추후 `print-only` 또는 별도 export 전용 레이아웃을 기준으로 구현하면 화면/인쇄/공유 결과를 맞추기 쉽다.
|
- 이미지 저장 기능은 추후 `print-only` 또는 별도 export 전용 레이아웃을 기준으로 구현하면 화면/인쇄/공유 결과를 맞추기 쉽다.
|
||||||
- Docker Compose는 프론트엔드와 백엔드를 함께 올리는 기준으로 설계하되, NAS 환경에 맞는 볼륨과 재시작 정책도 함께 고려한다.
|
- Docker Compose는 프론트엔드와 백엔드를 함께 올리는 기준으로 설계하되, NAS 환경에 맞는 볼륨과 재시작 정책도 함께 고려한다.
|
||||||
|
- Docker Compose 개발/배포 파일에는 `TZ=Asia/Seoul`을 명시해 NAS와 컨테이너 내부 기준 시간이 한국 시간으로 맞도록 유지한다.
|
||||||
- 플래너 본문 라벨은 더 이상 `bg-paper` 배경으로 선을 덮지 않는다. `라벨 + 오른쪽 선` 구조로 바꿔 화면과 인쇄에서 노란 배경이 튀지 않도록 정리했다.
|
- 플래너 본문 라벨은 더 이상 `bg-paper` 배경으로 선을 덮지 않는다. `라벨 + 오른쪽 선` 구조로 바꿔 화면과 인쇄에서 노란 배경이 튀지 않도록 정리했다.
|
||||||
- 날짜에 적용되는 목표가 새로 생기면 D-DAY는 기본 표시된다. 사용자가 해당 날짜에서 직접 `D-DAY 사용`을 끈 경우에만 로컬 숨김 목록에 저장해 다시 숨긴다.
|
- 날짜에 적용되는 목표가 새로 생기면 D-DAY는 기본 표시된다. 사용자가 해당 날짜에서 직접 `D-DAY 사용`을 끈 경우에만 로컬 숨김 목록에 저장해 다시 숨긴다.
|
||||||
- 비로그인 랜딩은 모바일에서 `카드 안 카드`처럼 보이지 않도록 기능 설명 카드를 얇은 리스트로 단순화했고, `LOGIN` / `SIGN UP` 버튼은 같은 너비와 높이로 맞췄다. 로그인/회원가입 모달도 하단 전환 영역을 별도 카드 대신 구분선 형태로 정리했다.
|
- 비로그인 랜딩은 모바일에서 `카드 안 카드`처럼 보이지 않도록 기능 설명 카드를 얇은 리스트로 단순화했고, `LOGIN` / `SIGN UP` 버튼은 같은 너비와 높이로 맞췄다. 로그인/회원가입 모달도 하단 전환 영역을 별도 카드 대신 구분선 형태로 정리했다.
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ docker compose up -d --build
|
|||||||
- 프론트엔드 nginx
|
- 프론트엔드 nginx
|
||||||
- 백엔드 Fastify
|
- 백엔드 Fastify
|
||||||
- PostgreSQL
|
- PostgreSQL
|
||||||
|
- 배포/개발 컨테이너 시간대: `Asia/Seoul`
|
||||||
|
|
||||||
### 3. 실행 상태 확인하기
|
### 3. 실행 상태 확인하기
|
||||||
|
|
||||||
|
|||||||
19
TODO.md
19
TODO.md
@@ -51,14 +51,14 @@
|
|||||||
|
|
||||||
## 4단계: 데이터 구조와 저장
|
## 4단계: 데이터 구조와 저장
|
||||||
|
|
||||||
- [ ] 플래너 데이터 구조를 날짜별 상태 중심으로 정리한다.
|
- [x] 플래너 데이터 구조를 날짜별 상태 중심으로 정리한다.
|
||||||
- [x] 입력 데이터의 저장 위치를 결정한다.
|
- [x] 입력 데이터의 저장 위치를 결정한다.
|
||||||
- [x] 로컬 저장 또는 외부 저장 방식 중 우선 구현 방식을 정한다.
|
- [x] 로컬 저장 또는 외부 저장 방식 중 우선 구현 방식을 정한다.
|
||||||
- [x] 입력 상태가 새로고침 후에도 유지되도록 만든다.
|
- [x] 입력 상태가 새로고침 후에도 유지되도록 만든다.
|
||||||
- [x] DB 전환 시점을 잡을 수 있도록 저장 레이어를 분리한다.
|
- [x] DB 전환 시점을 잡을 수 있도록 저장 레이어를 분리한다.
|
||||||
- [x] 회원 가입 및 로그인 구조를 고려한 사용자별 데이터 모델을 설계한다.
|
- [x] 회원 가입 및 로그인 구조를 고려한 사용자별 데이터 모델을 설계한다.
|
||||||
- [x] 사용자별 문서 저장/조회 흐름을 정리한다.
|
- [x] 사용자별 문서 저장/조회 흐름을 정리한다.
|
||||||
- [ ] 출력용 문서 포맷과 프린트 흐름을 고려한 데이터 구조를 정리한다.
|
- [x] 출력용 문서 포맷과 프린트 흐름을 고려한 데이터 구조를 정리한다.
|
||||||
|
|
||||||
## 추가 반영 메모
|
## 추가 반영 메모
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
- [x] 통계 페이지 라우팅 또는 화면 전환 구조를 설계한다.
|
- [x] 통계 페이지 라우팅 또는 화면 전환 구조를 설계한다.
|
||||||
- [x] 집중 시간, 완료율, 연속 기록 같은 핵심 지표를 정의한다.
|
- [x] 집중 시간, 완료율, 연속 기록 같은 핵심 지표를 정의한다.
|
||||||
- [x] 사용자가 시작일과 종료일을 선택해서 기간별 통계를 볼 수 있게 한다.
|
- [x] 사용자가 시작일과 종료일을 선택해서 기간별 통계를 볼 수 있게 한다.
|
||||||
- [ ] 사용자 개인 통계 화면 기준을 정리한다.
|
- [x] 사용자 개인 통계 화면 기준을 정리한다.
|
||||||
|
|
||||||
## 6단계: 계정 및 서비스 확장
|
## 6단계: 계정 및 서비스 확장
|
||||||
|
|
||||||
@@ -79,8 +79,8 @@
|
|||||||
- [x] 사용자 설정 화면에서 닉네임 / 이메일 / 비밀번호 수정 흐름을 분리한다.
|
- [x] 사용자 설정 화면에서 닉네임 / 이메일 / 비밀번호 수정 흐름을 분리한다.
|
||||||
- [x] 상단 헤더를 왼쪽 사이드 내비게이션 구조로 재배치한다.
|
- [x] 상단 헤더를 왼쪽 사이드 내비게이션 구조로 재배치한다.
|
||||||
- [x] 본문과 오른쪽 패널이 각각 독립 스크롤되도록 조정한다.
|
- [x] 본문과 오른쪽 패널이 각각 독립 스크롤되도록 조정한다.
|
||||||
- [ ] 사용자별 문서 분리 저장 구조를 설계한다.
|
- [x] 사용자별 문서 분리 저장 구조를 설계한다.
|
||||||
- [ ] 공유가 아닌 개인 보관용 서비스 흐름으로 요구사항을 정리한다.
|
- [x] 공유가 아닌 개인 보관용 서비스 흐름으로 요구사항을 정리한다.
|
||||||
- [x] 향후 출력 기능을 위한 인쇄 레이아웃 요구사항을 정리한다.
|
- [x] 향후 출력 기능을 위한 인쇄 레이아웃 요구사항을 정리한다.
|
||||||
- [x] A4 가로 기준 2장 출력 모드를 지원한다.
|
- [x] A4 가로 기준 2장 출력 모드를 지원한다.
|
||||||
- [x] `1-UP` 세로 인쇄 / `2-UP` 가로 인쇄 기준을 분리한다.
|
- [x] `1-UP` 세로 인쇄 / `2-UP` 가로 인쇄 기준을 분리한다.
|
||||||
@@ -94,8 +94,8 @@
|
|||||||
- [x] 미완료 항목을 다음 날짜 빈칸으로 이월하는 버튼을 추가한다.
|
- [x] 미완료 항목을 다음 날짜 빈칸으로 이월하는 버튼을 추가한다.
|
||||||
- [x] 이월된 할 일에 배지를 표시하고 원래 시작 날짜를 확인할 수 있게 한다.
|
- [x] 이월된 할 일에 배지를 표시하고 원래 시작 날짜를 확인할 수 있게 한다.
|
||||||
- [x] 이월된 할 일을 체크할 때 이전 날짜까지 함께 완료할지 선택하는 정책을 추가한다.
|
- [x] 이월된 할 일을 체크할 때 이전 날짜까지 함께 완료할지 선택하는 정책을 추가한다.
|
||||||
- [ ] 이메일 인증 플로우를 설계하고 구현한다.
|
- [x] 이메일 인증 플로우를 설계하고 구현한다.
|
||||||
- [ ] 비밀번호 찾기 / 재설정 토큰 흐름을 추가한다.
|
- [x] 비밀번호 찾기 / 재설정 토큰 흐름을 추가한다.
|
||||||
- [ ] 로그인 및 인증 관련 rate limit / 잠금 정책을 추가한다.
|
- [ ] 로그인 및 인증 관련 rate limit / 잠금 정책을 추가한다.
|
||||||
- [x] 로그인 유지 여부를 사용자가 선택할 수 있게 한다.
|
- [x] 로그인 유지 여부를 사용자가 선택할 수 있게 한다.
|
||||||
- [ ] 일정 시간 미사용 시 자동 로그아웃 옵션을 추가한다.
|
- [ ] 일정 시간 미사용 시 자동 로그아웃 옵션을 추가한다.
|
||||||
@@ -109,12 +109,10 @@
|
|||||||
|
|
||||||
## 메모
|
## 메모
|
||||||
|
|
||||||
- D-DAY는 현재 보류 상태다. 목표 패널 설계 후 연결한다.
|
|
||||||
- D-DAY는 본문에 직접 입력하는 방식보다, 별도 목표 목록에서 선택한 대표 목표를 보여주는 구조가 더 적합하다.
|
- D-DAY는 본문에 직접 입력하는 방식보다, 별도 목표 목록에서 선택한 대표 목표를 보여주는 구조가 더 적합하다.
|
||||||
- 목표가 없는 경우 본문 D-DAY 영역은 숨기고, 오른쪽 패널의 `D-DAY 사용` 메뉴에서 검색/선택하도록 유도한다.
|
- 목표가 없는 경우 본문 D-DAY 영역은 숨기고, 오른쪽 패널의 `D-DAY 사용` 메뉴에서 검색/선택하도록 유도한다.
|
||||||
- `TIME TABLE` 드래그는 단순 사각형 선택이 아니라 시간 셀 단위의 연속 선택으로 해석한다.
|
- `TIME TABLE` 드래그는 단순 사각형 선택이 아니라 시간 셀 단위의 연속 선택으로 해석한다.
|
||||||
- 현재는 `localStorage`로 개발을 진행하지만, 적절한 시점에 DB를 붙여 사용자별 저장 구조로 확장해야 한다.
|
- 로컬 저장은 비로그인/데모 보조 용도로만 남기고, 로그인 상태에서는 사용자별 서버 저장을 우선한다.
|
||||||
- 현재 `localStorage` 저장 로직은 분리 가능한 형태로 정리 중이며, 이후 API/DB adapter로 교체하기 쉽게 유지한다.
|
|
||||||
- 최종적으로는 회원 가입 후 각자 자신의 문서를 작성/관리하고, 개인 통계를 확인하며, 특정 날짜 문서를 출력할 수 있어야 한다.
|
- 최종적으로는 회원 가입 후 각자 자신의 문서를 작성/관리하고, 개인 통계를 확인하며, 특정 날짜 문서를 출력할 수 있어야 한다.
|
||||||
- 실제 인쇄는 HTML/CSS 기반 프린트 레이아웃으로 유지하고, 공유용으로는 별도의 이미지 저장 기능을 추가하는 방향이 적합하다.
|
- 실제 인쇄는 HTML/CSS 기반 프린트 레이아웃으로 유지하고, 공유용으로는 별도의 이미지 저장 기능을 추가하는 방향이 적합하다.
|
||||||
- 최종 배포는 UGREEN NAS에서 Docker 기반으로 동작할 예정이며, 포트와 실제 서비스 구성은 추후 확정한다.
|
- 최종 배포는 UGREEN NAS에서 Docker 기반으로 동작할 예정이며, 포트와 실제 서비스 구성은 추후 확정한다.
|
||||||
@@ -134,6 +132,7 @@
|
|||||||
- 현재 날짜에 적용된 목표가 있으면 D-DAY는 기본적으로 보이고, 사용자가 해당 날짜에서만 OFF로 끌 수 있다.
|
- 현재 날짜에 적용된 목표가 있으면 D-DAY는 기본적으로 보이고, 사용자가 해당 날짜에서만 OFF로 끌 수 있다.
|
||||||
- 목표 생성 시 표시 시작일 기본값은 오늘, 표시 종료일 기본값은 목표일로 맞춘다.
|
- 목표 생성 시 표시 시작일 기본값은 오늘, 표시 종료일 기본값은 목표일로 맞춘다.
|
||||||
- 표시 기간이 다른 진행 중 목표와 겹치면 프론트와 백엔드 모두 저장을 막는다.
|
- 표시 기간이 다른 진행 중 목표와 겹치면 프론트와 백엔드 모두 저장을 막는다.
|
||||||
|
- 앱을 새로 열면 마지막 열람 날짜가 아니라 항상 오늘 날짜부터 시작하고, Docker/NAS 컨테이너 시간대는 `Asia/Seoul` 기준으로 맞춘다.
|
||||||
- TASK LABELS는 버튼 묶음 대신 동일한 토글 패턴으로 단순화했다.
|
- TASK LABELS는 버튼 묶음 대신 동일한 토글 패턴으로 단순화했다.
|
||||||
- 구현할 때마다 완료된 항목은 체크하고, 큰 결정사항은 `HANDOFF.md`에도 함께 반영한다.
|
- 구현할 때마다 완료된 항목은 체크하고, 큰 결정사항은 `HANDOFF.md`에도 함께 반영한다.
|
||||||
- Resend 무료 플랜은 도메인 수 제약이 있으므로, 실제 인증 메일은 AWS SES 또는 별도 SMTP 서비스 전환을 전제로 설계하는 편이 안전하다.
|
- Resend 무료 플랜은 도메인 수 제약이 있으므로, 실제 인증 메일은 AWS SES 또는 별도 SMTP 서비스 전환을 전제로 설계하는 편이 안전하다.
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ services:
|
|||||||
container_name: ten-minute-postgres-dev
|
container_name: ten-minute-postgres-dev
|
||||||
env_file:
|
env_file:
|
||||||
- ./.env.dev
|
- ./.env.dev
|
||||||
|
environment:
|
||||||
|
TZ: Asia/Seoul
|
||||||
volumes:
|
volumes:
|
||||||
- postgres_dev_data:/var/lib/postgresql/data
|
- postgres_dev_data:/var/lib/postgresql/data
|
||||||
ports:
|
ports:
|
||||||
@@ -26,6 +28,7 @@ services:
|
|||||||
PORT: 3001
|
PORT: 3001
|
||||||
CORS_ORIGIN: http://localhost:5173
|
CORS_ORIGIN: http://localhost:5173
|
||||||
SESSION_TTL_DAYS: 30
|
SESSION_TTL_DAYS: 30
|
||||||
|
TZ: Asia/Seoul
|
||||||
volumes:
|
volumes:
|
||||||
- ./backend:/app
|
- ./backend:/app
|
||||||
- backend_node_modules:/app/node_modules
|
- backend_node_modules:/app/node_modules
|
||||||
@@ -44,6 +47,7 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
VITE_API_BASE_URL: http://localhost:3001
|
VITE_API_BASE_URL: http://localhost:3001
|
||||||
CHOKIDAR_USEPOLLING: "true"
|
CHOKIDAR_USEPOLLING: "true"
|
||||||
|
TZ: Asia/Seoul
|
||||||
volumes:
|
volumes:
|
||||||
- .:/app
|
- .:/app
|
||||||
- /app/backend
|
- /app/backend
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ services:
|
|||||||
container_name: ten-minute-postgres
|
container_name: ten-minute-postgres
|
||||||
env_file:
|
env_file:
|
||||||
- ./.env
|
- ./.env
|
||||||
|
environment:
|
||||||
|
TZ: Asia/Seoul
|
||||||
volumes:
|
volumes:
|
||||||
- postgres_data:/var/lib/postgresql/data
|
- postgres_data:/var/lib/postgresql/data
|
||||||
ports:
|
ports:
|
||||||
@@ -25,6 +27,7 @@ services:
|
|||||||
PORT: 3001
|
PORT: 3001
|
||||||
CORS_ORIGIN: http://localhost:48081
|
CORS_ORIGIN: http://localhost:48081
|
||||||
SESSION_TTL_DAYS: 30
|
SESSION_TTL_DAYS: 30
|
||||||
|
TZ: Asia/Seoul
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
postgres:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
@@ -38,6 +41,8 @@ services:
|
|||||||
args:
|
args:
|
||||||
VITE_API_BASE_URL: /api
|
VITE_API_BASE_URL: /api
|
||||||
container_name: ten-minute-frontend
|
container_name: ten-minute-frontend
|
||||||
|
environment:
|
||||||
|
TZ: Asia/Seoul
|
||||||
depends_on:
|
depends_on:
|
||||||
- backend
|
- backend
|
||||||
ports:
|
ports:
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "ten-minute-planner",
|
"name": "ten-minute-planner",
|
||||||
"version": "0.1.43",
|
"version": "0.1.44",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "ten-minute-planner",
|
"name": "ten-minute-planner",
|
||||||
"version": "0.1.43",
|
"version": "0.1.44",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"vue": "^3.5.13"
|
"vue": "^3.5.13"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "ten-minute-planner",
|
"name": "ten-minute-planner",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.1.43",
|
"version": "0.1.44",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
13
src/App.vue
13
src/App.vue
@@ -29,7 +29,6 @@ import { deletePlannerEntry, fetchPlannerEntries, savePlannerEntry } from './lib
|
|||||||
import {
|
import {
|
||||||
createInitialPlannerRecords,
|
createInitialPlannerRecords,
|
||||||
persistPlannerState,
|
persistPlannerState,
|
||||||
readPlannerStorageState,
|
|
||||||
restorePlannerUiState,
|
restorePlannerUiState,
|
||||||
} from './lib/plannerStorage'
|
} from './lib/plannerStorage'
|
||||||
|
|
||||||
@@ -1965,16 +1964,8 @@ function replacePlannerRecords(nextRecords) {
|
|||||||
|
|
||||||
function restoreLocalPlannerRecords() {
|
function restoreLocalPlannerRecords() {
|
||||||
replacePlannerRecords(createInitialPlannerRecords(plannerSeed, normalizeRecord))
|
replacePlannerRecords(createInitialPlannerRecords(plannerSeed, normalizeRecord))
|
||||||
|
selectedDate.value = new Date()
|
||||||
const savedState = readPlannerStorageState()
|
calendarViewDate.value = new Date(selectedDate.value)
|
||||||
|
|
||||||
if (savedState.selectedDate) {
|
|
||||||
selectedDate.value = toDateValue(savedState.selectedDate, selectedDate.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (savedState.calendarViewDate) {
|
|
||||||
calendarViewDate.value = toDateValue(savedState.calendarViewDate, selectedDate.value)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function findRecordKey(record) {
|
function findRecordKey(record) {
|
||||||
|
|||||||
@@ -40,16 +40,8 @@ export function restorePlannerUiState({
|
|||||||
toDateValue,
|
toDateValue,
|
||||||
}) {
|
}) {
|
||||||
const savedState = readStorageState()
|
const savedState = readStorageState()
|
||||||
|
selectedDate.value = toDateValue(new Date(), selectedDate.value)
|
||||||
if (savedState.selectedDate) {
|
calendarViewDate.value = new Date(selectedDate.value)
|
||||||
selectedDate.value = toDateValue(savedState.selectedDate, selectedDate.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (savedState.calendarViewDate) {
|
|
||||||
calendarViewDate.value = toDateValue(savedState.calendarViewDate, selectedDate.value)
|
|
||||||
} else {
|
|
||||||
calendarViewDate.value = new Date(selectedDate.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (savedState.statsRangeStart) {
|
if (savedState.statsRangeStart) {
|
||||||
statsRangeStart.value = savedState.statsRangeStart
|
statsRangeStart.value = savedState.statsRangeStart
|
||||||
@@ -75,12 +67,13 @@ export function persistPlannerState({
|
|||||||
const previousState = readStorageState()
|
const previousState = readStorageState()
|
||||||
const nextState = {
|
const nextState = {
|
||||||
...previousState,
|
...previousState,
|
||||||
selectedDate: selectedDate.toISOString(),
|
|
||||||
calendarViewDate: calendarViewDate.toISOString(),
|
|
||||||
statsRangeStart,
|
statsRangeStart,
|
||||||
statsRangeEnd,
|
statsRangeEnd,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete nextState.selectedDate
|
||||||
|
delete nextState.calendarViewDate
|
||||||
|
|
||||||
if (includeRecords) {
|
if (includeRecords) {
|
||||||
nextState.records = Object.fromEntries(
|
nextState.records = Object.fromEntries(
|
||||||
Object.entries(plannerRecords).map(([key, record]) => [
|
Object.entries(plannerRecords).map(([key, record]) => [
|
||||||
|
|||||||
Reference in New Issue
Block a user