From 1a676ff59617ccaa17e434dcbf2b8271ff973b39 Mon Sep 17 00:00:00 2001 From: lejuho Date: Wed, 11 Mar 2026 19:39:41 +0900 Subject: [PATCH 01/92] feat : login and MainFE to MainAPP migration --- AUTH_INTEGRATION_CHECKLIST.md | 336 +++++ MAINAPP_MIGRATION_TODO.md | 387 ++++++ app.json | 1 + metro.config.js | 13 + nativewind-env.d.ts | 8 + package-lock.json | 1232 ++++++++++++++++- package.json | 10 + src/apis/avatars/avatarApi.ts | 30 + src/apis/delivery/deliveryApi.ts | 21 + src/apis/follow/followApi.ts | 32 + src/apis/home/homeApi.ts | 15 + src/apis/instance.ts | 89 +- src/apis/missions/missionApi.ts | 61 + src/apis/profile/profileApi.ts | 20 + src/apis/register/registerApi.ts | 21 + src/apis/supabase.ts | 31 + src/assets/icons/common/index.ts | 54 +- src/components/common/CommentComposer.tsx | 77 ++ src/components/common/ScreenHeader.tsx | 47 + src/components/common/StatusView.tsx | 74 + .../dailyMission/ImageAttachmentCard.tsx | 74 + .../dailyMission/QuizOptionCard.tsx | 79 ++ .../dailyMission/QuizResultCard.tsx | 46 + .../delivery/DeliveryRequestSelector.tsx | 104 ++ src/components/delivery/DeliveryTextField.tsx | 74 + src/components/delivery/GardenSlotCard.tsx | 100 ++ src/components/delivery/PlantOptionCard.tsx | 67 + src/components/feed/FeedDetail.tsx | 32 +- src/components/feed/FeedList.tsx | 23 + src/components/follow/UserCard.tsx | 110 ++ src/components/log/MyDiaryDetail.tsx | 142 ++ src/components/profile/ProfileDetail.tsx | 119 ++ .../registration/AvatarPreviewCard.tsx | 60 + .../registration/RegistrationFooter.tsx | 87 ++ .../registration/RegistrationModeCard.tsx | 81 ++ .../registration/RegistrationTextField.tsx | 66 + .../registration/SelectionAvatarCard.tsx | 76 + src/hooks/auth/useBackendLogin.ts | 29 + src/hooks/auth/useSupabaseOAuth.ts | 112 ++ src/hooks/avatars/useAvatarApi.ts | 30 + src/hooks/delivery/useDeliveryApi.ts | 42 + src/hooks/follow/useFollowApi.ts | 64 + src/hooks/home/useHomeApi.ts | 19 + src/hooks/mission/useMissionApi.ts | 66 + src/hooks/profile/useProfileApi.ts | 26 + src/hooks/register/useRegisterApi.ts | 10 +- src/navigation/RootNavigator.tsx | 179 +-- src/navigation/types.ts | 16 +- .../DailyMissionCheckingScreen.tsx | 243 ++++ .../DailyMissionQuizMultipleChoiceScreen.tsx | 188 +++ .../dailyMission/DailyMissionQuizOxScreen.tsx | 194 +++ .../DailyMissionWriteDiaryScreen.tsx | 218 +++ src/pages/delivery/DeliveryCompleteScreen.tsx | 124 ++ src/pages/delivery/DeliveryScreen.tsx | 310 +++++ src/pages/delivery/UnlockGardenScreen.tsx | 356 +++++ src/pages/feed/FeedAvatarScreen.tsx | 184 +-- src/pages/feed/FeedDiaryScreen.tsx | 179 +-- src/pages/follow/FollowScreen.tsx | 156 ++- src/pages/home/HomeScreen.tsx | 398 +++++- src/pages/log/LogDetailScreen.tsx | 122 ++ src/pages/onboarding/OnboardingScreen.tsx | 107 +- src/pages/option/OptionScreen.tsx | 187 ++- src/pages/placeholder/PlaceholderScreen.tsx | 29 - src/pages/profile/ProfileScreen.tsx | 270 ++++ src/pages/register/RegisterScreen.tsx | 5 +- .../registration/RegistrationAvatarScreen.tsx | 105 ++ .../RegistrationCreationDetailScreen.tsx | 250 ++++ .../RegistrationPlantNicknameScreen.tsx | 187 +++ .../RegistrationSelectionDetailScreen.tsx | 164 +++ src/stores/useRegistrationStore.ts | 60 + src/stores/useTokenStore.ts | 14 +- src/types/avatars/index.ts | 42 + src/types/axios.d.ts | 13 + src/types/delivery/index.ts | 15 + src/types/follow/index.ts | 9 + src/types/home/garden.ts | 37 +- src/types/missions/index.ts | 101 ++ src/types/profile/profileApi.type.ts | 29 + src/types/svg.d.ts | 6 + src/utils/auth.ts | 12 + ts_errors.log | Bin 0 -> 10184 bytes ts_final.txt | 28 + 82 files changed, 8350 insertions(+), 484 deletions(-) create mode 100644 AUTH_INTEGRATION_CHECKLIST.md create mode 100644 MAINAPP_MIGRATION_TODO.md create mode 100644 src/apis/avatars/avatarApi.ts create mode 100644 src/apis/delivery/deliveryApi.ts create mode 100644 src/apis/follow/followApi.ts create mode 100644 src/apis/home/homeApi.ts create mode 100644 src/apis/missions/missionApi.ts create mode 100644 src/apis/profile/profileApi.ts create mode 100644 src/apis/supabase.ts create mode 100644 src/components/common/CommentComposer.tsx create mode 100644 src/components/common/ScreenHeader.tsx create mode 100644 src/components/common/StatusView.tsx create mode 100644 src/components/dailyMission/ImageAttachmentCard.tsx create mode 100644 src/components/dailyMission/QuizOptionCard.tsx create mode 100644 src/components/dailyMission/QuizResultCard.tsx create mode 100644 src/components/delivery/DeliveryRequestSelector.tsx create mode 100644 src/components/delivery/DeliveryTextField.tsx create mode 100644 src/components/delivery/GardenSlotCard.tsx create mode 100644 src/components/delivery/PlantOptionCard.tsx create mode 100644 src/components/follow/UserCard.tsx create mode 100644 src/components/log/MyDiaryDetail.tsx create mode 100644 src/components/profile/ProfileDetail.tsx create mode 100644 src/components/registration/AvatarPreviewCard.tsx create mode 100644 src/components/registration/RegistrationFooter.tsx create mode 100644 src/components/registration/RegistrationModeCard.tsx create mode 100644 src/components/registration/RegistrationTextField.tsx create mode 100644 src/components/registration/SelectionAvatarCard.tsx create mode 100644 src/hooks/auth/useBackendLogin.ts create mode 100644 src/hooks/auth/useSupabaseOAuth.ts create mode 100644 src/hooks/avatars/useAvatarApi.ts create mode 100644 src/hooks/delivery/useDeliveryApi.ts create mode 100644 src/hooks/follow/useFollowApi.ts create mode 100644 src/hooks/home/useHomeApi.ts create mode 100644 src/hooks/mission/useMissionApi.ts create mode 100644 src/hooks/profile/useProfileApi.ts create mode 100644 src/pages/dailyMission/DailyMissionCheckingScreen.tsx create mode 100644 src/pages/dailyMission/DailyMissionQuizMultipleChoiceScreen.tsx create mode 100644 src/pages/dailyMission/DailyMissionQuizOxScreen.tsx create mode 100644 src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx create mode 100644 src/pages/delivery/DeliveryCompleteScreen.tsx create mode 100644 src/pages/delivery/DeliveryScreen.tsx create mode 100644 src/pages/delivery/UnlockGardenScreen.tsx create mode 100644 src/pages/log/LogDetailScreen.tsx delete mode 100644 src/pages/placeholder/PlaceholderScreen.tsx create mode 100644 src/pages/profile/ProfileScreen.tsx create mode 100644 src/pages/registration/RegistrationAvatarScreen.tsx create mode 100644 src/pages/registration/RegistrationCreationDetailScreen.tsx create mode 100644 src/pages/registration/RegistrationPlantNicknameScreen.tsx create mode 100644 src/pages/registration/RegistrationSelectionDetailScreen.tsx create mode 100644 src/stores/useRegistrationStore.ts create mode 100644 src/types/avatars/index.ts create mode 100644 src/types/axios.d.ts create mode 100644 src/types/delivery/index.ts create mode 100644 src/types/follow/index.ts create mode 100644 src/types/missions/index.ts create mode 100644 src/types/profile/profileApi.type.ts create mode 100644 src/types/svg.d.ts create mode 100644 src/utils/auth.ts create mode 100644 ts_errors.log create mode 100644 ts_final.txt diff --git a/AUTH_INTEGRATION_CHECKLIST.md b/AUTH_INTEGRATION_CHECKLIST.md new file mode 100644 index 0000000..e0a6166 --- /dev/null +++ b/AUTH_INTEGRATION_CHECKLIST.md @@ -0,0 +1,336 @@ +# Auth Integration Checklist + +이 문서는 `MainFE`, `MainAPP`, `MainBE`가 각각 독립 클라이언트/백엔드로 동작하면서, 공통으로 Supabase OAuth 소셜 로그인을 지원하도록 작업을 쪼갠 체크리스트다. + +## 1. 현재 상태 요약 + +### MainBE +- 공통 인증 백엔드 역할 +- `POST /api/v1/auth/supabase` 구현됨 +- Supabase access token 검증 후 자체 JWT 발급 구현됨 +- refresh API 구현됨 + +### MainAPP +- 모바일 앱 클라이언트 역할 +- Supabase OAuth 로그인 구현 흔적 있음 +- 홈, 로그, 피드 등 일부 실제 화면과 API 연동 있음 +- 일부 화면은 플레이스홀더 +- 서비스 JWT 저장 및 API 인증 부착은 미완성 + +### MainFE +- 웹 클라이언트 역할 +- 현재 기준 Supabase OAuth 로그인 구현 미확인 +- 웹용 callback 처리, 서비스 JWT 저장, 보호 라우트 작업 필요 + +## 2. 목표 상태 + +- `MainAPP`: 모바일 클라이언트로서 주요 기능 완성 + Supabase OAuth 로그인 완성 +- `MainFE`: 웹 클라이언트로서 주요 기능 완성 + Supabase OAuth 로그인 완성 +- `MainBE`: 웹/앱 공통 인증 백엔드로 유지 +- 공통 인증 흐름: + 1. 클라이언트가 Supabase OAuth 시작 + 2. 클라이언트가 Supabase access token 획득 + 3. 클라이언트가 `MainBE /api/v1/auth/supabase` 호출 + 4. `MainBE`가 자체 access/refresh token 발급 + 5. 클라이언트가 서비스 토큰 저장 후 이후 API 호출에 사용 + +## 3. 공통 선행 작업 + +### A. 인증 계약 고정 +- [ ] `POST /api/v1/auth/supabase` 요청 바디 최종 확정 +- [ ] 응답 필드 최종 확정 + - [ ] `accessToken` + - [ ] `refreshToken` + - [ ] `userId` + - [ ] `nickname` + - [ ] `isNewUser` +- [ ] `POST /api/v1/auth/refresh` 호출 규칙 확정 +- [ ] 401, 403, refresh 실패 시 공통 동작 정의 +- [ ] 신규 유저와 기존 유저 분기 기준 문서화 +- [ ] 로그아웃 정책 정의 + - [ ] 로컬 토큰 삭제 + - [ ] Supabase 세션 정리 여부 + - [ ] 백엔드 refresh token revoke 여부 + +### B. Supabase 콘솔 설정 +- [ ] Google provider 설정 확인 +- [ ] Kakao provider 설정 확인 +- [ ] 웹 redirect URL 등록 +- [ ] 앱 deep link redirect URL 등록 +- [ ] 개발/운영 redirect URL 분리 +- [ ] 동일 Supabase 프로젝트를 `MainFE`, `MainAPP`, `MainBE`가 쓰는지 확인 + +### C. 환경변수 정리 +- [ ] `MainFE` env 키 이름 정리 +- [ ] `MainAPP` env 키 이름 정리 +- [ ] `MainBE` env 키 이름 정리 +- [ ] 임시 fallback 값 제거 +- [ ] 개발/운영 env 분리 + +## 4. MainBE 작업 체크리스트 + +### BE-1. 인증 스펙 안정화 +- [ ] `AuthController` 응답 구조 재검토 +- [ ] Swagger 또는 문서에 소셜 로그인 플로우 명시 +- [ ] `SupabaseLoginRequest` 유효성 검증 재확인 +- [ ] `AnonymousRegistrationResponse` 명명 검토 + - [ ] 소셜 로그인 응답용 이름이 맞는지 확인 + - [ ] 필요 시 별도 DTO로 분리 + +### BE-2. 토큰 정책 확정 +- [ ] access token 만료 시간 확인 +- [ ] refresh token 만료 시간 확인 +- [ ] refresh token 재발급 정책 확인 +- [ ] 디바이스별 refresh token 저장 정책 확인 +- [ ] 다중 로그인 허용 범위 확인 + +### BE-3. 소셜 로그인 유저 처리 검증 +- [ ] 신규 유저 생성 규칙 확인 +- [ ] 기존 유저 매핑 규칙 확인 +- [ ] provider/sub 기반 유저 매핑 테스트 +- [ ] 닉네임 생성 규칙 검증 +- [ ] 프로필 이미지 동기화 규칙 검증 +- [ ] 이메일 없는 provider 케이스 처리 확인 + +### BE-4. 인증 보조 API 보완 +- [ ] 로그아웃 API 필요 여부 결정 +- [ ] 전체 로그아웃 API 필요 여부 결정 +- [ ] 현재 사용자 정보 조회 API 필요 여부 결정 +- [ ] 앱/웹 초기 진입용 `me` API 필요 여부 결정 + +### BE-5. 운영 안정성 +- [ ] 인증 관련 예외 메시지 정리 +- [ ] 토큰/개인정보 로그 노출 여부 점검 +- [ ] CORS 설정 검토 +- [ ] `Authorization` 헤더 노출/허용 점검 +- [ ] 인증 실패 모니터링 포인트 정리 + +### BE-6. 테스트 +- [ ] Google 기존 회원 로그인 테스트 +- [ ] Google 신규 회원 로그인 테스트 +- [ ] Kakao 기존 회원 로그인 테스트 +- [ ] Kakao 신규 회원 로그인 테스트 +- [ ] 잘못된 Supabase token 테스트 +- [ ] refresh token 재발급 테스트 +- [ ] deviceId mismatch 테스트 + +## 5. MainAPP 작업 체크리스트 + +### APP-1. 로그인 완료 처리 +- [ ] OAuth 성공 후 백엔드 응답을 토큰 스토어에 저장 +- [ ] 저장 대상 필드 확정 + - [ ] `accessToken` + - [ ] `refreshToken` + - [ ] `userId` + - [ ] 필요 시 `nickname` +- [ ] `isNewUser`에 따른 분기 처리 추가 + +### APP-2. 인증 상태 기반 진입 제어 +- [ ] 앱 시작 시 hydration 완료 전 로딩 처리 +- [ ] 저장된 토큰 존재 시 자동 로그인 분기 +- [ ] 미로그인 시 온보딩/로그인 진입 +- [ ] 로그인 완료 시 `Main` 진입 +- [ ] 로그아웃 시 인증 화면으로 복귀 + +### APP-3. API 인터셉터 완성 +- [ ] `axios instance`에 access token 부착 활성화 +- [ ] 401 감지 시 refresh 시도 로직 추가 +- [ ] refresh 성공 시 원 요청 재시도 +- [ ] refresh 실패 시 토큰 삭제 +- [ ] 중복 refresh 요청 방지 처리 + +### APP-4. 로그아웃 처리 +- [ ] 로컬 토큰 삭제 구현 +- [ ] Supabase local session 정리 구현 +- [ ] 설정 화면 또는 옵션 화면에 로그아웃 연결 + +### APP-5. 인증 이후 기능 연결 +- [ ] 홈 API가 서비스 JWT로 정상 동작하는지 확인 +- [ ] 로그 API가 서비스 JWT로 정상 동작하는지 확인 +- [ ] 피드 API가 서비스 JWT로 정상 동작하는지 확인 +- [ ] 댓글 API가 서비스 JWT로 정상 동작하는지 확인 +- [ ] 상세 화면 API가 서비스 JWT로 정상 동작하는지 확인 + +### APP-6. 플레이스홀더 제거 우선순위 정리 +- [ ] 프로필 화면 구현 +- [ ] 팔로우 화면 구현 +- [ ] 로그 상세 화면 구현 +- [ ] 배송 화면 구현 +- [ ] 정원 잠금 해제 화면 구현 +- [ ] 식물 등록 플로우 구현 +- [ ] 데일리 미션 화면 구현 + +### APP-7. UX 보완 +- [ ] 로그인 중 로딩 표시 개선 +- [ ] 로그인 실패 메시지 처리 +- [ ] OAuth 취소 시 UX 처리 +- [ ] 신규 유저 온보딩 후속 플로우 설계 + +### APP-8. 테스트 +- [ ] 앱 cold start 자동 로그인 테스트 +- [ ] 앱 재실행 후 세션 유지 테스트 +- [ ] access token 만료 후 refresh 테스트 +- [ ] refresh 만료 후 로그아웃 테스트 +- [ ] Google 로그인 테스트 +- [ ] Kakao 로그인 테스트 +- [ ] 비회원 등록 플로우 테스트 + +## 6. MainFE 작업 체크리스트 + +### FE-1. 인증 구조 설계 +- [ ] 웹에서 사용할 상태관리 방식 결정 + - [ ] Context + - [ ] Zustand + - [ ] React Query + store 혼합 +- [ ] 토큰 저장 위치 결정 + - [ ] 메모리 + - [ ] localStorage + - [ ] secure cookie 사용 여부 검토 +- [ ] 보호 라우트 방식 결정 + +### FE-2. Supabase 웹 클라이언트 추가 +- [ ] Supabase client 파일 생성 +- [ ] env 연결 +- [ ] provider 목록 정의 +- [ ] auth 유틸 분리 + +### FE-3. 웹 OAuth 시작 구현 +- [ ] 로그인 화면 또는 진입 버튼 배치 +- [ ] Google 로그인 버튼 구현 +- [ ] Kakao 로그인 버튼 구현 +- [ ] `supabase.auth.signInWithOAuth()` 연결 +- [ ] 웹 redirect URL 적용 + +### FE-4. callback 처리 구현 +- [ ] 웹 callback 라우트 생성 +- [ ] callback 페이지 로딩 상태 추가 +- [ ] Supabase에서 access token 또는 code 처리 +- [ ] 토큰 추출 실패 처리 +- [ ] 중복 호출 방지 처리 + +### FE-5. 백엔드 토큰 교환 구현 +- [ ] `MainBE /api/v1/auth/supabase` 호출 API 추가 +- [ ] 백엔드 응답을 웹 스토어에 저장 +- [ ] `isNewUser` 분기 처리 +- [ ] 로그인 성공 후 리다이렉트 처리 + +### FE-6. 웹 API 인증 연결 +- [ ] axios/fetch 인터셉터에 service access token 부착 +- [ ] 401 시 refresh 호출 구현 +- [ ] refresh 성공 시 재시도 +- [ ] refresh 실패 시 로그인 화면 복귀 + +### FE-7. 라우팅 및 화면 보호 +- [ ] 로그인 필요 페이지 목록 정리 +- [ ] 보호 라우트 적용 +- [ ] 로그인 페이지 접근 제한 처리 +- [ ] 새로고침 시 로그인 상태 복원 +- [ ] 원래 가려던 페이지로 복귀 처리 + +### FE-8. 로그아웃 처리 +- [ ] 서비스 토큰 삭제 +- [ ] Supabase 세션 정리 +- [ ] 로그아웃 버튼 연결 +- [ ] 로그아웃 후 public route 이동 + +### FE-9. 기능 통합 +- [ ] 인증 필요한 기존 API 호출부 점검 +- [ ] 유저 상태 의존 화면 점검 +- [ ] 피드/로그/댓글/프로필 기능을 인증 구조와 연결 +- [ ] 신규 유저 후속 플로우 연결 + +### FE-10. 테스트 +- [ ] 브라우저 새로고침 후 세션 유지 테스트 +- [ ] Google 로그인 테스트 +- [ ] Kakao 로그인 테스트 +- [ ] OAuth 취소 테스트 +- [ ] access token 만료 후 refresh 테스트 +- [ ] refresh 만료 후 로그아웃 테스트 +- [ ] 보호 라우트 접근 테스트 + +## 7. 권장 구현 순서 + +### Phase 1. 공통 계약 정리 +- [ ] BE 응답/refresh/logout 정책 확정 +- [ ] Supabase redirect/env 설정 확정 + +### Phase 2. MainAPP 인증 완성 +- [ ] 로그인 성공 후 서비스 JWT 저장 +- [ ] 인터셉터/refresh/로그아웃 완성 +- [ ] 인증 상태 기반 진입 제어 완성 + +### Phase 3. MainFE 인증 신규 구축 +- [ ] Supabase 웹 로그인 구현 +- [ ] callback 구현 +- [ ] 백엔드 토큰 교환 구현 +- [ ] 보호 라우트/refresh 완성 + +### Phase 4. 기능 마무리 +- [ ] MainAPP 플레이스홀더 제거 +- [ ] MainFE 인증 연동 누락 화면 보완 +- [ ] 웹/앱 통합 QA 수행 + +## 8. 이슈 단위 추천 분해 + +### Epic A. 공통 인증 규격 +- [ ] A-1. 인증 API 응답 스펙 확정 +- [ ] A-2. refresh 정책 확정 +- [ ] A-3. logout 정책 확정 +- [ ] A-4. Supabase provider/redirect 설정 완료 + +### Epic B. MainBE 인증 안정화 +- [ ] B-1. DTO/명명 정리 +- [ ] B-2. 인증 예외/로그 정리 +- [ ] B-3. 로그아웃 및 `me` API 필요 여부 정리 +- [ ] B-4. 소셜 로그인 테스트 케이스 작성 + +### Epic C. MainAPP 인증 완성 +- [ ] C-1. 로그인 후 서비스 토큰 저장 +- [ ] C-2. Authorization 인터셉터 활성화 +- [ ] C-3. refresh 재시도 구현 +- [ ] C-4. 앱 시작 시 인증 상태 복원 +- [ ] C-5. 로그아웃 구현 + +### Epic D. MainAPP 기능 완성 +- [ ] D-1. 프로필/팔로우 화면 구현 +- [ ] D-2. 로그 상세/배송 화면 구현 +- [ ] D-3. 식물 등록 플로우 구현 +- [ ] D-4. 데일리 미션 화면 구현 + +### Epic E. MainFE 인증 구축 +- [ ] E-1. Supabase 웹 클라이언트 추가 +- [ ] E-2. 로그인 버튼/UI 추가 +- [ ] E-3. callback 페이지 구현 +- [ ] E-4. 백엔드 토큰 교환 및 저장 +- [ ] E-5. 보호 라우트/refresh 구현 +- [ ] E-6. 로그아웃 구현 + +### Epic F. MainFE 기능 통합 +- [ ] F-1. 기존 페이지 인증 연결 +- [ ] F-2. 신규 유저 분기 연결 +- [ ] F-3. 새로고침/복귀 UX 정리 +- [ ] F-4. 브라우저 QA + +## 9. 완료 기준 + +### MainAPP 완료 기준 +- [ ] Google/Kakao 로그인 가능 +- [ ] 로그인 후 서비스 API 정상 호출 +- [ ] 앱 재실행 후 세션 복원 +- [ ] 만료 후 refresh 동작 +- [ ] 로그아웃 가능 +- [ ] 주요 플레이스홀더 제거 + +### MainFE 완료 기준 +- [ ] Google/Kakao 로그인 가능 +- [ ] callback 처리 안정화 +- [ ] 로그인 후 서비스 API 정상 호출 +- [ ] 새로고침 후 세션 복원 +- [ ] 보호 라우트 동작 +- [ ] 로그아웃 가능 + +### MainBE 완료 기준 +- [ ] 웹/앱 모두 같은 인증 API로 로그인 가능 +- [ ] 신규/기존 유저 처리 안정화 +- [ ] refresh 정책 검증 완료 +- [ ] 인증 예외와 보안 로그 정리 완료 diff --git a/MAINAPP_MIGRATION_TODO.md b/MAINAPP_MIGRATION_TODO.md new file mode 100644 index 0000000..ab74858 --- /dev/null +++ b/MAINAPP_MIGRATION_TODO.md @@ -0,0 +1,387 @@ +# MainAPP Migration TODO + +기준 문서: +- `C:/MainFE/AUTH_INTEGRATION_CHECKLIST.md` +- `C:/MainFE/MAINAPP_MIGRATION_MATRIX.md` + +문서 목적: +- `MainFE` 종료를 전제로 `MainAPP` 단독 운영에 필요한 기능 이식 범위를 앱 레포 내부 기준으로 고정한다. +- `MainAPP`와 `MainBE`의 현재 구현 상태를 MainFE 종료 이후 운영 기준(source of truth)으로 삼는다. +- 현재 `MainAPP`의 구현 상태를 `완료`, `부분구현`, `미구현`으로 나눠 기록한다. +- 남은 TODO와 정책 미확정 항목을 운영 보완 관점에서 정리한다. + +제외 범위: +- 웹 라우팅, 웹 레이아웃, 웹 CSS, 브라우저 전용 UX는 이식 대상으로 보지 않는다. +- 이번 문서는 기능 구현이 아니라 인벤토리와 작업 기준 문서화만 다룬다. + +## 1. 현재 MainAPP 상태 요약 + +### 전체 상태 +- 인증 기반은 완료 상태다. +- 앱 시작 시 저장된 토큰 기준으로 `Main` 또는 `Onboarding`으로 초기 진입이 분기된다. +- 서비스 API 인증 헤더 자동 부착과 refresh 재시도 기반이 있다. +- 실제 사용자 기능 중 현재 의미 있게 연결된 영역은 `홈 요약 일부`, `피드`, `피드 상세`, `댓글 작성`, `로그 캘린더`, `월별 일기 목록`, `로그 상세`, `프로필`, `팔로우 목록`, `배송 신청`, `정원 해금`, `등록 플로우`, `데일리 미션(일기/퀴즈/오늘의 질문)`이다. +- `설정`은 로그아웃과 계정 상태 확인이 가능한 최소 운영 수준으로 정리되었다. + +### 네비게이션 기준 상태 +- 메인 탭: `Home`, `Log`, `Feed`, `Option` +- 인증 스택: `Onboarding`, `Register` +- 상세 스택 중 실제 연결됨: `FeedDiary`, `FeedAvatar`, `LogDetail`, `Profile`, `Follow`, `Delivery`, `DeliveryComplete`, `UnlockGarden`, `RegistrationAvatar`, `RegistrationCreationDetail`, `RegistrationSelectionDetail`, `RegistrationPlantNickname`, `DailyMissionWriteDiary`, `DailyMissionQuizMultipleChoice`, `DailyMissionQuizOx`, `DailyMissionChecking` +- 상세 스택 중 플레이스홀더: 없음 + +### 구현 분류 요약 +- 완료 + - 인증 기반 + - 온보딩/스플래시 + - OAuth 로그인 + - 피드 목록 API 연동 + - 피드 상세 조회 API 연동 + - 댓글 작성 API 연동 + - 로그 캘린더 API 연동 + - 월별 일기 목록 API 연동 + - 오늘의 질문 미션 +- 부분구현 + - 비회원 등록 + - 홈 메인 + - 로그 화면 일부 + - 피드 상세 UX + - 프로필 + - 팔로우 + - 배송 + - 등록 플로우 + - 데일리 미션 일기 작성 + - 설정/운영 안내 + +## 2. 구현된 기능 목록 + +### 완료 + +| 기능명 | 현재 MainAPP 상태 | 근거 파일 | +|---|---|---| +| 인증 기반 | OAuth 이후 서비스 JWT 저장, 앱 재실행 후 세션 복원, Authorization 자동 부착, refresh 1회 재시도, 로그아웃 기반까지 구현됨 | `src/hooks/auth/useSupabaseOAuth.ts`, `src/hooks/auth/useBackendLogin.ts`, `src/stores/useTokenStore.ts`, `src/apis/instance.ts`, `src/utils/auth.ts`, `src/navigation/RootNavigator.tsx` | +| 온보딩/스플래시 | 온보딩 슬라이드와 OAuth 시작 UI가 있음. 앱 시작 시 splash 처리 포함 | `src/pages/onboarding/OnboardingScreen.tsx`, `src/components/common/Splash.tsx` | +| 피드 목록 | 목록 조회 API와 그리드 렌더링, 게시글 타입별 상세 진입이 동작함 | `src/pages/feed/FeedScreen.tsx`, `src/components/feed/FeedList.tsx`, `src/hooks/feed/useFeedApi.ts`, `src/apis/feed/feedApi.ts` | +| 피드 상세 조회 | 일기형/아바타형 상세 조회, 상태별 로딩/에러/빈 댓글 처리, 댓글 입력 흐름이 구현됨 | `src/pages/feed/FeedDiaryScreen.tsx`, `src/pages/feed/FeedAvatarScreen.tsx`, `src/components/feed/FeedDetail.tsx`, `src/components/common/CommentComposer.tsx`, `src/components/common/ScreenHeader.tsx`, `src/components/common/StatusView.tsx`, `src/hooks/log/useDiaryDetailApi.ts`, `src/hooks/feed/useAvatarPostDetailApi.ts` | +| 댓글 작성 | 상세 화면에서 댓글 등록 후 refetch까지 연결됨 | `src/hooks/comments/useCommentApi.ts`, `src/apis/comments/commentApi.ts`, `src/components/common/Comment.tsx` | +| 로그 캘린더 | 월 이동, 캘린더 조회, 일자별 미션 완료 아이콘 렌더링이 구현됨 | `src/pages/log/LogScreen.tsx`, `src/components/log/LogCalendar.tsx`, `src/hooks/log/useCalendarApi.ts`, `src/apis/log/calendarApi.ts` | +| 월별 일기 목록 | 월 이동, 일기 썸네일 목록 조회와 상세 진입 이벤트가 구현됨 | `src/pages/log/LogScreen.tsx`, `src/components/log/MyDiary.tsx`, `src/hooks/log/useDiariesApi.ts`, `src/apis/log/diariesApi.ts` | +| 로그 상세 | `LogDetail` 실제 화면, 댓글 입력, diary detail API 기반 상세 렌더링이 구현됨 | `src/pages/log/LogDetailScreen.tsx`, `src/components/log/MyDiaryDetail.tsx`, `src/components/common/CommentComposer.tsx`, `src/hooks/log/useDiaryDetailApi.ts`, `src/apis/log/diaryDetailApi.ts` | +| 프로필 조회 | 사용자 기본 정보 조회, 대표 정원 정보, 친구 물주기, 팔로우/언팔로우 버튼이 구현됨 | `src/pages/profile/ProfileScreen.tsx`, `src/components/profile/ProfileDetail.tsx`, `src/hooks/profile/useProfileApi.ts`, `src/apis/profile/profileApi.ts`, `src/hooks/follow/useFollowApi.ts` | +| 팔로우 목록 | 팔로잉/팔로워 목록 조회, 탭 전환, 팔로잉 탭 언팔로우, 프로필 이동이 구현됨 | `src/pages/follow/FollowScreen.tsx`, `src/components/follow/UserCard.tsx`, `src/hooks/follow/useFollowApi.ts`, `src/apis/follow/followApi.ts` | +| 정원 해금 | `POST /api/v1/gardens/unlock` body 없는 호출과 홈 재조회가 연결됨 | `src/pages/delivery/UnlockGardenScreen.tsx`, `src/hooks/delivery/useDeliveryApi.ts`, `src/apis/delivery/deliveryApi.ts`, `src/apis/home/homeApi.ts` | +| 배송 신청 | 배송용 식물 선택, 배송 입력 폼, 신청 완료 화면까지 연결됨 | `src/pages/delivery/UnlockGardenScreen.tsx`, `src/pages/delivery/DeliveryScreen.tsx`, `src/pages/delivery/DeliveryCompleteScreen.tsx`, `src/hooks/delivery/useDeliveryApi.ts`, `src/apis/delivery/deliveryApi.ts` | +| 등록 플로우 | 아바타 시작, 생성형 이미지 업로드, 선택형 상세, 별명 짓기와 홈 복귀까지 연결됨 | `src/pages/registration/RegistrationAvatarScreen.tsx`, `src/pages/registration/RegistrationCreationDetailScreen.tsx`, `src/pages/registration/RegistrationSelectionDetailScreen.tsx`, `src/pages/registration/RegistrationPlantNicknameScreen.tsx`, `src/stores/useRegistrationStore.ts`, `src/hooks/avatars/useAvatarApi.ts`, `src/apis/avatars/avatarApi.ts` | +| 데일리 미션 퀴즈 | 객관식/OX 퀴즈 조회와 답안 제출, 홈 진입점이 연결됨 | `src/pages/dailyMission/DailyMissionQuizMultipleChoiceScreen.tsx`, `src/pages/dailyMission/DailyMissionQuizOxScreen.tsx`, `src/hooks/mission/useMissionApi.ts`, `src/apis/missions/missionApi.ts` | +| 오늘의 질문 미션 | `GET /api/v1/survey` 조회, `POST /api/v1/survey/answer` 제출, 홈 완료 상태 반영이 구현됨. `CHECKING` fallback은 제거되었고 포인트 지급은 서버 책임이다. | `src/pages/dailyMission/DailyMissionCheckingScreen.tsx`, `src/hooks/mission/useMissionApi.ts`, `src/apis/missions/missionApi.ts`, `src/pages/home/HomeScreen.tsx` | +| 설정/로그아웃 | 설정 화면에서 계정 상태 확인, 로그아웃 버튼, 운영 안내를 확인할 수 있음 | `src/pages/option/OptionScreen.tsx`, `src/utils/auth.ts`, `src/stores/useTokenStore.ts`, `src/navigation/RootNavigator.tsx` | + +### 부분구현 + +| 기능명 | 현재 MainAPP 상태 | 보완 필요 사항 | 근거 파일 | +|---|---|---|---| +| 비회원 등록 | 닉네임 입력과 회원가입 API 호출은 있음 | 가입 실패 시에도 등록 플로우로 진입시키는 현재 정책이 운영 기준으로 확정된 것은 아님 | `src/pages/register/RegisterScreen.tsx`, `src/hooks/register/useRegister.ts`, `src/apis/register/registerApi.ts` | +| 홈 메인 | 홈 summary API가 있으면 사용자/정원/미션 요약을 렌더링하고, missionType 기준으로 라우팅함 | `home/panel` 세부 API, 식물 상호작용은 아직 필요 | `src/pages/home/HomeScreen.tsx`, `src/hooks/home/useHomeApi.ts`, `src/apis/home/homeApi.ts` | +| 로그 화면 일부 | 캘린더/일기 목록과 로그 상세까지 연결됨 | 미션 탭 날짜 선택 후 상세 액션은 아직 없음 | `src/pages/log/LogScreen.tsx`, `src/pages/log/LogDetailScreen.tsx`, `src/apis/log/diaryDetailApi.ts` | +| 피드 상세 UX | 조회/댓글/상태 처리와 프로필 이동은 됨 | 공감/신고/댓글 수정·삭제는 아직 없음 | `src/components/feed/FeedDetail.tsx`, `src/pages/feed/FeedDiaryScreen.tsx`, `src/pages/feed/FeedAvatarScreen.tsx` | +| 프로필 | 사용자 조회와 대표 정원/팔로우/물주기까지 연결됨 | 방명록, 다중 정원 상세, 추가 상호작용 API는 아직 필요 | `src/pages/profile/ProfileScreen.tsx`, `src/components/profile/ProfileDetail.tsx`, `src/apis/profile/profileApi.ts` | +| 팔로우 | 팔로잉/팔로워 목록 조회와 탭 전환, 팔로잉 언팔로우가 됨 | 팔로워 목록 쪽 follow-back 액션은 응답 정보 부족으로 아직 없음 | `src/pages/follow/FollowScreen.tsx`, `src/components/follow/UserCard.tsx`, `src/apis/follow/followApi.ts` | +| 배송 | 배송용 식물 목록 조회, 배송 신청, 완료 화면, 홈에서의 진입은 연결됨 | 주소 검색 UI, 배송 조회는 추가 확인 필요 | `src/pages/delivery/UnlockGardenScreen.tsx`, `src/pages/delivery/DeliveryScreen.tsx`, `src/pages/delivery/DeliveryCompleteScreen.tsx`, `src/apis/delivery/deliveryApi.ts` | +| 등록 플로우 | 단계 간 상태 저장과 이동, 생성형 업로드, 선택형/생성형 최종 등록은 구현됨 | 신규 유저 자동 강제 진입 정책은 추가 확인 필요 | `src/pages/registration/RegistrationAvatarScreen.tsx`, `src/pages/registration/RegistrationCreationDetailScreen.tsx`, `src/pages/registration/RegistrationSelectionDetailScreen.tsx`, `src/pages/registration/RegistrationPlantNicknameScreen.tsx`, `src/stores/useRegistrationStore.ts` | +| 데일리 미션 일기 작성 | 텍스트 입력, 공개 설정, 제출 구조는 구현됨 | 이미지 업로드-일기 저장 최종 연결은 아직 미완성 | `src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx`, `src/apis/missions/missionApi.ts`, `src/hooks/mission/useMissionApi.ts` | +| 설정 | 로그아웃과 계정 상태 확인은 가능함 | 버전 표기 자동화, 약관/문의 같은 운영 링크는 아직 없음 | `src/pages/option/OptionScreen.tsx` | + +## 3. 플레이스홀더/미구현 목록 + +### RootNavigator.tsx 기준 플레이스홀더 스택 화면 + +현재 `RootNavigator` 기준 플레이스홀더 스택 화면은 없다. Step 3~7 범위의 상세 화면 교체가 끝난 상태다. + +| 라우트명 | 현재 상태 | 비고 | +|---|---|---| +| 없음 | 모든 대상 라우트가 실제 화면으로 교체됨 | 남은 항목은 운영 보완/정책 정리 성격 | + +### 파일은 있으나 기능적으로 미구현에 가까운 화면 + +| 파일 | 현재 상태 | 판단 | +|---|---|---| +| 없음 | 주요 화면은 모두 실제 기능을 가짐 | 남은 항목은 운영 보완/정책 정리 위주 | + +## 4. MainFE 대비 누락 기능 매트릭스 + +아래 표는 `C:/MainFE/MAINAPP_MIGRATION_MATRIX.md`를 기준으로, `MainAPP`에 아직 없는 기능 또는 부분구현 기능을 정리한 것이다. + +| 기능명 | 현재 MainAPP 상태 | 참조할 MainFE 파일 | 필요한 MainAPP 대상 파일 또는 신규 파일 | 선행조건 | +|---|---|---|---|---| +| 홈 메인 패널 | `/api/v1/home` 응답 기준 요약 UI는 구현됨. `missionType` 기반 라우팅과 today question 연결까지 반영됨 | `C:/MainFE/src/pages/home/Homepage.tsx`, `C:/MainFE/src/apis/home/homeApi.ts`, `C:/MainFE/src/apis/missions/panelApi.ts` | 기존 `src/pages/home/HomeScreen.tsx`, 기존 `src/apis/home/homeApi.ts`, 기존 `src/hooks/home/useHomeApi.ts`, 필요 시 신규 `src/components/home/*` | `panel` 및 상호작용 API 존재 확인 | +| 식물 상호작용(물/햇빛) | 미구현 | `C:/MainFE/src/components/home/FirstPlant.tsx`, `C:/MainFE/src/components/home/SecondPlant.tsx`, `C:/MainFE/src/components/home/ThirdPlant.tsx`, `C:/MainFE/src/components/home/FourthPlant.tsx` | 신규 `src/components/home/*`, 기존 `src/pages/home/HomeScreen.tsx` | 홈 메인 데이터 구조 확정 | +| 로그 상세 | diary detail API 기준 실제 화면 구현 완료. 수정 기능과 추가 소셜 액션만 미완성 | `C:/MainFE/src/pages/log/LogDetailPage.tsx` | 기존 `src/pages/log/LogDetailScreen.tsx`, 기존 `src/components/log/MyDiaryDetail.tsx` | 수정 API 여부 확인 | +| 피드 상세 보완 | 상세 조회, 댓글, 상태 처리는 구현됨. 소셜 상호작용은 미완성 | `C:/MainFE/src/pages/feed/FeedDiaryPage.tsx`, `C:/MainFE/src/pages/feed/FeedAvatarPage.tsx`, `C:/MainFE/src/components/feed/*`, `C:/MainFE/src/components/common/Comment.tsx` | 기존 `src/pages/feed/FeedDiaryScreen.tsx`, 기존 `src/pages/feed/FeedAvatarScreen.tsx`, 기존 `src/components/feed/FeedDetail.tsx`, 기존 `src/components/common/Comment.tsx` | 프로필 화면, 댓글/좋아요 API 범위 확인 | +| 프로필 조회/친구 물주기 | 사용자 조회, 대표 정원 렌더링, 친구 물주기, follow/unfollow까지 구현됨. 방명록 등 추가 기능은 미완성 | `C:/MainFE/src/pages/profile/ProfilePage.tsx`, `C:/MainFE/src/apis/profile/profileApi.ts`, `C:/MainFE/src/components/profile/*` | 기존 `src/pages/profile/ProfileScreen.tsx`, 기존 `src/apis/profile/profileApi.ts`, 기존 `src/hooks/profile/*`, 기존 `src/components/profile/*` | 방명록 및 추가 상호작용 API 확인 | +| 팔로우 목록/관리 | 팔로잉/팔로워 목록 조회와 팔로잉 언팔로우는 구현됨. 팔로워 follow-back은 응답 정보 부족으로 미완성 | `C:/MainFE/src/pages/follow/FollowPage.tsx`, `C:/MainFE/src/apis/follow/followApi.ts`, `C:/MainFE/src/components/follow/*` | 기존 `src/pages/follow/FollowScreen.tsx`, 기존 `src/apis/follow/followApi.ts`, 기존 `src/hooks/follow/*`, 기존 `src/components/follow/*` | 팔로워 목록의 관계 상태 또는 follow-back 정책 확인 | +| 설정/로그아웃 UI | 로그아웃 버튼, 계정 상태, 운영 안내까지 구현됨. 운영 링크와 상세 안내는 미완성 | `C:/MainFE/src/pages/option/OptionPage.tsx` | 기존 `src/pages/option/OptionScreen.tsx`, 기존 `src/utils/auth.ts` | 로그아웃 정책 유지 | +| 배송 신청 | 배송 입력 폼과 제출은 구현됨. 주소 검색과 주문 조회는 미완성 | `C:/MainFE/src/pages/delivery/DeliveryPage.tsx`, `C:/MainFE/src/components/delivery/*` | 기존 `src/pages/delivery/DeliveryScreen.tsx`, 기존 `src/components/delivery/*`, 기존 `src/apis/delivery/deliveryApi.ts` | 주소 검색 방식 확정 | +| 배송 완료 | 완료 화면과 홈 복귀 흐름은 구현됨 | `C:/MainFE/src/pages/delivery/CompletePage.tsx` | 기존 `src/pages/delivery/DeliveryCompleteScreen.tsx` | 배송 상태 조회 API 확인 | +| 정원 확장/잠금 해제 | body 없는 unlock 호출과 홈 재조회가 구현됨 | `C:/MainFE/src/pages/delivery/UnlockGardenPlotPage.tsx`, `C:/MainFE/src/components/delivery/*` | 기존 `src/pages/delivery/UnlockGardenScreen.tsx`, 기존 `src/components/delivery/*`, 기존 `src/apis/delivery/deliveryApi.ts` | 홈 화면 연결점 정의 | +| 등록 플로우 시작 | 시작 화면과 mode 선택, 단계 이동은 구현됨 | `C:/MainFE/src/pages/registration/AvatarCreationPage.tsx`, `C:/MainFE/src/components/registration/*`, `C:/MainFE/src/apis/avatars/avatarApi.ts` | 기존 `src/pages/registration/RegistrationAvatarScreen.tsx`, 기존 `src/components/registration/*`, 기존 `src/stores/useRegistrationStore.ts` | 신규 유저 자동 진입 정책 확정 | +| 생성형 등록 상세 | 이미지 선택과 업로드, 상태 저장은 구현됨 | `C:/MainFE/src/pages/registration/CreationDetailPage.tsx` | 기존 `src/pages/registration/RegistrationCreationDetailScreen.tsx`, 기존 `src/stores/useRegistrationStore.ts`, 기존 `src/apis/avatars/avatarApi.ts` | 기기 권한 UX 보완 | +| 선택형 등록 상세 | 아바타 목록 조회와 선택은 구현됨 | `C:/MainFE/src/pages/registration/SelectionDetailPage.tsx`, `C:/MainFE/src/apis/avatars/avatarApi.ts` | 기존 `src/pages/registration/RegistrationSelectionDetailScreen.tsx`, 기존 `src/apis/avatars/avatarApi.ts`, 기존 `src/hooks/avatars/useAvatarApi.ts` | `GET /api/v1/avatars/masters` 계약 유지 | +| 식물 별명 짓기 | 별명 입력과 완료 흐름은 구현됨. 생성형/선택형 모두 `POST /api/v1/avatars`로 연결됨 | `C:/MainFE/src/pages/registration/PlantNicknamePage.tsx`, `C:/MainFE/src/apis/avatars/avatarApi.ts` | 기존 `src/pages/registration/RegistrationPlantNicknameScreen.tsx`, 기존 `src/apis/avatars/avatarApi.ts`, 기존 `src/hooks/avatars/useAvatarApi.ts` | 신규 유저 분기 정책 확인 | +| 데일리 미션 일기 작성 | 텍스트 입력, 공개 설정, 제출 구조는 구현됨. 이미지 업로드-일기 저장은 미완성 | `C:/MainFE/src/pages/dailyMission/WriteDiaryPage.tsx`, `C:/MainFE/src/components/dailyMission/*`, `C:/MainFE/src/apis/missions/*` | 기존 `src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx`, 기존 `src/components/dailyMission/*`, 기존 `src/apis/missions/missionApi.ts`, 기존 `src/hooks/mission/useMissionApi.ts` | 일기 작성 최종 제출 UX 보완 | +| 데일리 미션 객관식 퀴즈 | 퀴즈 조회, 선택지 렌더링, 답안 제출, 결과 표시가 구현됨 | `C:/MainFE/src/pages/dailyMission/MultipleChoiceQuestionQuizPage.tsx`, `C:/MainFE/src/components/dailyMission/*`, `C:/MainFE/src/apis/missions/*` | 기존 `src/pages/dailyMission/DailyMissionQuizMultipleChoiceScreen.tsx`, 기존 `src/components/dailyMission/*`, 기존 `src/apis/missions/missionApi.ts` | `GET/POST /api/v1/realQuiz` 계약 유지 | +| 데일리 미션 OX 퀴즈 | 퀴즈 조회, O/X 선택, 답안 제출, 결과 표시가 구현됨 | `C:/MainFE/src/pages/dailyMission/OxQuizPage.tsx`, `C:/MainFE/src/components/dailyMission/*`, `C:/MainFE/src/apis/missions/*` | 기존 `src/pages/dailyMission/DailyMissionQuizOxScreen.tsx`, 기존 `src/components/dailyMission/*`, 기존 `src/apis/missions/missionApi.ts` | OX와 객관식 공통 quiz 계약 유지 | +| 데일리 미션 오늘의 질문 | survey 조회, YES/NEUTRAL/NO 답변 제출, 홈 완료 상태 반영이 구현됨 | `C:/MainFE/src/pages/dailyMission/*`, `C:/MainFE/src/apis/missions/*` | 기존 `src/pages/dailyMission/DailyMissionCheckingScreen.tsx`, 기존 `src/apis/missions/missionApi.ts`, 기존 `src/hooks/mission/useMissionApi.ts` | 응답 문구/보상 노출 정책 확정 | + +## 5. 우선순위별 작업 백로그 + +## P0. 인증 기반 후속 점검 항목 + +### P0-1. 로그아웃 UI 연결 +- 기능명: 설정 화면 로그아웃 연결 +- 현재 MainAPP 상태: 완료. 설정 화면에서 로그아웃 버튼과 중복 클릭 방지가 연결됨 +- 참조할 MainFE 파일: `C:/MainFE/src/pages/option/OptionPage.tsx` +- 필요한 MainAPP 대상 파일 또는 신규 파일: 기존 `src/pages/option/OptionScreen.tsx` +- 선행조건: 없음 + +### P0-2. 인증 실패 UX 정리 +- 기능명: 401/403 이후 사용자 경험 정리 +- 현재 MainAPP 상태: 토큰 제거 및 인증 해제는 되지만 안내 UI와 공통 처리 메시지는 없음 +- 참조할 MainFE 파일: `C:/MainFE/AUTH_INTEGRATION_CHECKLIST.md` +- 필요한 MainAPP 대상 파일 또는 신규 파일: 기존 `src/apis/instance.ts`, 필요 시 신규 `src/components/common/*` +- 선행조건: 없음 + +### P0-3. 신규 유저 분기 확정 +- 기능명: OAuth/비회원 등록 이후 신규 유저 후속 플로우 명시 +- 현재 MainAPP 상태: OAuth `newUser`는 `RegistrationAvatar`로 reset되고, 비회원 등록도 등록 플로우로 진입함. 다만 중도 이탈 후 재진입 정책은 확정되지 않음 +- 참조할 MainFE 파일: `C:/MainFE/AUTH_INTEGRATION_CHECKLIST.md` +- 필요한 MainAPP 대상 파일 또는 신규 파일: 기존 `src/hooks/auth/useSupabaseOAuth.ts`, 기존 `src/pages/register/RegisterScreen.tsx`, 향후 등록 플로우 화면들 +- 선행조건: 등록 플로우 목표 화면 구조 합의 + +## P1. 홈/로그/피드 코어 기능 + +### P1-1. 홈 메인 구현 +- 기능명: 홈 메인 화면 및 패널 +- 현재 MainAPP 상태: `HomeScreen`이 `/api/v1/home` 응답 기준 요약 UI를 렌더링하고, `missionType` 기반으로 실제 미션 화면을 연결함 +- 참조할 MainFE 파일: `C:/MainFE/src/pages/home/Homepage.tsx`, `C:/MainFE/src/apis/home/homeApi.ts`, `C:/MainFE/src/apis/missions/panelApi.ts` +- 필요한 MainAPP 대상 파일 또는 신규 파일: 기존 `src/pages/home/HomeScreen.tsx`, 기존 `src/apis/home/homeApi.ts`, 기존 `src/hooks/home/useHomeApi.ts`, 필요 시 신규 `src/components/home/*` +- 선행조건: MainBE 홈/패널 API 확인 + +### P1-2. 로그 상세 구현 +- 기능명: 로그 상세 화면 +- 현재 MainAPP 상태: 실제 상세 화면과 댓글 입력이 연결됨 +- 참조할 MainFE 파일: `C:/MainFE/src/pages/log/LogDetailPage.tsx` +- 필요한 MainAPP 대상 파일 또는 신규 파일: 기존 `src/pages/log/LogDetailScreen.tsx`, 기존 `src/apis/log/diaryDetailApi.ts`, 기존 `src/hooks/log/useDiaryDetailApi.ts` +- 선행조건: 없음 + +### P1-3. 피드 상세 보강 +- 기능명: 피드 상세 UX 및 상호작용 보강 +- 현재 MainAPP 상태: 조회와 댓글 작성은 가능하나 프로필/좋아요/신고 등 소셜 기능이 미완성 +- 참조할 MainFE 파일: `C:/MainFE/src/pages/feed/FeedDiaryPage.tsx`, `C:/MainFE/src/pages/feed/FeedAvatarPage.tsx`, `C:/MainFE/src/components/feed/*`, `C:/MainFE/src/components/common/Comment.tsx` +- 필요한 MainAPP 대상 파일 또는 신규 파일: 기존 `src/pages/feed/FeedDiaryScreen.tsx`, 기존 `src/pages/feed/FeedAvatarScreen.tsx`, 기존 `src/components/feed/FeedDetail.tsx`, 기존 `src/components/common/Comment.tsx` +- 선행조건: 프로필 화면 스펙과 좋아요/신고 API 확인 + +### P1-4. 로그 미션 탭 후속 +- 기능명: 로그 내 미션 탭 상세 연결 +- 현재 MainAPP 상태: 캘린더는 렌더링되나 날짜 선택 후 액션이 없음 +- 참조할 MainFE 파일: `C:/MainFE/src/pages/log/LogPage.tsx`, `C:/MainFE/src/components/log/*` +- 필요한 MainAPP 대상 파일 또는 신규 파일: 기존 `src/components/log/LogCalendar.tsx`, 기존 `src/pages/log/LogScreen.tsx` +- 선행조건: 날짜 선택 시 보여줄 정보 구조 확정 + +## P2. 프로필/팔로우/설정 + +### P2-1. 프로필 화면 구현 +- 기능명: 사용자 프로필 조회 및 친구 물주기 +- 현재 MainAPP 상태: 사용자 조회, 대표 정원, 물주기, 팔로우/언팔로우까지 구현됨 +- 참조할 MainFE 파일: `C:/MainFE/src/pages/profile/ProfilePage.tsx`, `C:/MainFE/src/apis/profile/profileApi.ts`, `C:/MainFE/src/components/profile/*` +- 필요한 MainAPP 대상 파일 또는 신규 파일: 기존 `src/pages/profile/ProfileScreen.tsx`, 기존 `src/apis/profile/profileApi.ts`, 기존 `src/hooks/profile/*`, 기존 `src/components/profile/*` +- 선행조건: 프로필 API 확인 + +### P2-2. 팔로우 화면 구현 +- 기능명: 팔로우 목록 및 관리 +- 현재 MainAPP 상태: 목록 조회, 탭 전환, 팔로잉 언팔로우, 프로필 이동까지 구현됨 +- 참조할 MainFE 파일: `C:/MainFE/src/pages/follow/FollowPage.tsx`, `C:/MainFE/src/apis/follow/followApi.ts`, `C:/MainFE/src/components/follow/*` +- 필요한 MainAPP 대상 파일 또는 신규 파일: 기존 `src/pages/follow/FollowScreen.tsx`, 기존 `src/apis/follow/followApi.ts`, 기존 `src/hooks/follow/*` +- 선행조건: 팔로우 API 확인 + +### P2-3. 설정 화면 마감 +- 기능명: 설정/옵션 +- 현재 MainAPP 상태: 로그아웃과 계정 상태 확인은 가능, 운영 링크는 미완성 +- 참조할 MainFE 파일: `C:/MainFE/src/pages/option/OptionPage.tsx` +- 필요한 MainAPP 대상 파일 또는 신규 파일: 기존 `src/pages/option/OptionScreen.tsx` +- 선행조건: 로그아웃 버튼 정책 확정 + +## P3. 배송/정원확장/등록플로우/데일리미션 + +### P3-1. 배송 신청 +- 기능명: 배송 신청 폼 +- 현재 MainAPP 상태: 기본 배송 입력과 제출이 구현됨 +- 참조할 MainFE 파일: `C:/MainFE/src/pages/delivery/DeliveryPage.tsx`, `C:/MainFE/src/components/delivery/*` +- 필요한 MainAPP 대상 파일 또는 신규 파일: 기존 `src/pages/delivery/DeliveryScreen.tsx`, 기존 `src/components/delivery/*`, 기존 `src/apis/delivery/deliveryApi.ts` +- 선행조건: 배송 API 확인 + +### P3-2. 배송 완료 +- 기능명: 배송 완료 화면 +- 현재 MainAPP 상태: 완료 메시지와 홈 복귀 버튼이 구현됨 +- 참조할 MainFE 파일: `C:/MainFE/src/pages/delivery/CompletePage.tsx` +- 필요한 MainAPP 대상 파일 또는 신규 파일: 기존 `src/pages/delivery/DeliveryCompleteScreen.tsx` +- 선행조건: 배송 신청 플로우 구현 + +### P3-3. 정원 확장 +- 기능명: 정원 잠금 해제/확장 +- 현재 MainAPP 상태: `POST /api/v1/gardens/unlock` body 없는 호출과 홈 재조회가 구현됨 +- 참조할 MainFE 파일: `C:/MainFE/src/pages/delivery/UnlockGardenPlotPage.tsx`, `C:/MainFE/src/components/delivery/*` +- 필요한 MainAPP 대상 파일 또는 신규 파일: 기존 `src/pages/delivery/UnlockGardenScreen.tsx`, 기존 `src/components/delivery/*`, 기존 `src/apis/delivery/deliveryApi.ts` +- 선행조건: 홈 화면 연결점 정의 + +### P3-4. 등록 플로우 +- 기능명: 아바타 선택, 생성형/선택형 상세, 식물 별명 +- 현재 MainAPP 상태: 단계별 화면과 상태 저장, 생성형 업로드, 최종 등록까지 구현됨 +- 참조할 MainFE 파일: `C:/MainFE/src/pages/registration/AvatarCreationPage.tsx`, `C:/MainFE/src/pages/registration/CreationDetailPage.tsx`, `C:/MainFE/src/pages/registration/SelectionDetailPage.tsx`, `C:/MainFE/src/pages/registration/PlantNicknamePage.tsx`, `C:/MainFE/src/components/registration/*`, `C:/MainFE/src/apis/avatars/avatarApi.ts` +- 필요한 MainAPP 대상 파일 또는 신규 파일: 기존 `src/pages/registration/*`, 기존 `src/components/registration/*`, 기존 `src/apis/avatars/avatarApi.ts`, 기존 `src/hooks/avatars/useAvatarApi.ts`, 기존 `src/stores/useRegistrationStore.ts` +- 선행조건: 신규 유저 분기 규칙과 등록 플로우 상태 저장 전략 확정 + +### P3-5. 데일리 미션 +- 기능명: 일기 작성, 객관식 퀴즈, OX 퀴즈, 오늘의 질문 +- 현재 MainAPP 상태: 퀴즈와 오늘의 질문은 구현, 일기 작성은 최종 이미지 업로드-저장 연결만 미완성 +- 참조할 MainFE 파일: `C:/MainFE/src/pages/dailyMission/WriteDiaryPage.tsx`, `C:/MainFE/src/pages/dailyMission/MultipleChoiceQuestionQuizPage.tsx`, `C:/MainFE/src/pages/dailyMission/OxQuizPage.tsx`, `C:/MainFE/src/components/dailyMission/*`, `C:/MainFE/src/apis/missions/*` +- 필요한 MainAPP 대상 파일 또는 신규 파일: 기존 `src/pages/dailyMission/*`, 기존 `src/components/dailyMission/*`, 기존 `src/apis/missions/missionApi.ts`, 기존 `src/hooks/mission/useMissionApi.ts` +- 선행조건: 일기 작성 업로드-저장 UX 마무리 + +## 6. 이후 Codex 작업 순서 + +### Step 3. 홈/로그/피드 공백 메우기 +- `src/pages/home/HomeScreen.tsx` 요약 UI 이후, `panel`과 정원 상호작용 API가 확인되면 홈 상호작용을 확장한다. +- `src/pages/log/LogDetailScreen.tsx` 이후, 수정 기능과 미션 탭 상세 연결을 보완한다. +- 피드 상세의 좋아요/신고/프로필 실화면 연결 등 미완성 소셜 상호작용을 정리한다. +- 필요한 홈/피드 보조 API와 훅을 추가한다. + +### Step 4. 프로필/팔로우 +- `Profile`과 `Follow` 플레이스홀더 교체는 완료되었다. +- 피드 상세 작성자 탭과 팔로우 화면 진입 버튼까지 실제 네비게이션 연결이 완료되었다. +- 이후 남은 작업은 방명록, 팔로워 follow-back, 추가 프로필 상호작용 같은 세부 기능 보강이다. + +### Step 5. 배송/정원 확장 +- `Delivery`, `DeliveryComplete`, `UnlockGarden` 플레이스홀더 교체는 완료되었다. +- 홈 화면에서 `UnlockGarden`으로 이어지는 연결점과 배송 완료 후 홈 복귀 흐름이 정리되었다. +- 이후 남은 작업은 주소 검색과 배송 상태 조회다. + +### Step 6. 등록 플로우 +- `RegistrationAvatar`, `RegistrationCreationDetail`, `RegistrationSelectionDetail`, `RegistrationPlantNickname` 플레이스홀더 교체는 완료되었다. +- 비회원 등록 진입과 OAuth 신규 유저 분기 연결 포인트가 정리되었다. +- 이후 남은 작업은 신규 유저 강제 진입 정책 확정과 생성형 업로드 UX 보완이다. + +### Step 7. 데일리 미션 +- `DailyMissionWriteDiary`, `DailyMissionQuizMultipleChoice`, `DailyMissionQuizOx`, `DailyMissionChecking` 화면이 실제로 연결되었다. +- 홈에서 미션 화면으로 진입하는 연결점과 퀴즈/오늘의 질문 제출 흐름이 정리되었다. +- 이후 남은 작업은 일기 작성 최종 업로드-저장 연결과 운영 보완 성격의 정책 정리다. + +## 7. 운영 마감 상태 + +### 완료된 범위 +- 인증, 온보딩, 로그인, 재실행 세션 복원, 로그아웃 +- 홈 주요 진입점, 피드/로그 상세, 프로필/팔로우 +- 정원 해금, 배송 신청/완료 +- 등록 플로우 기본 구조와 생성형 업로드 +- 데일리 미션 진입, 퀴즈 응답, 오늘의 질문 응답 + +### 부분구현 범위 +- 홈 패널 세부 상호작용 +- 피드 소셜 액션(좋아요/신고/댓글 수정 삭제) +- 프로필 방명록/다중 정원 +- 배송 주소 검색과 배송 조회 +- 비회원 등록/신규 유저 정책 +- 데일리 미션 일기 작성 최종 제출 +- 설정의 운영 링크/버전 자동 표기 + +### 정책 미확정 범위 +- 신규 유저가 등록 플로우를 중도 이탈했을 때 재진입을 강제할지 여부 +- 비회원 등록 실패 시에도 등록 플로우로 진입시키는 현재 동작을 유지할지 여부 +- 오늘의 질문 완료 후 보상/안내 문구를 앱에서 어느 수준까지 노출할지 여부 + +### 백엔드 계약 확인 필요 범위 +- 홈 패널/식물 상호작용 세부 API +- 팔로워 목록의 follow-back 판단용 관계 상태 +- 배송 상태 조회와 주소 검색 대체 정책 +- 데일리 미션 일기 작성의 최종 저장 UX 정책 + +### 운영 보완 필요 범위 +- 설정 화면의 약관/문의/버전 안내 연결 +- 인증 실패 공통 안내 UX +- 문구 일관화와 API 실패 메시지 다듬기 + +## 8. 남은 리스크 + +- 데일리 미션 일기 작성은 이미지 업로드-일기 저장 최종 연결이 아직 완결되지 않았다. +- 비회원 등록 실패 시에도 등록 플로우로 진입시키는 현재 동작은 운영 정책 확정이 필요하다. +- 홈 패널/식물 상호작용 API가 없어 메인 홈 상호작용은 아직 제한적이다. +- 배송 주소 검색과 배송 상태 조회는 아직 앱에서 직접 지원하지 않는다. +- MainFE 종료 이후 기준 문서는 이 파일과 현재 `MainAPP` 코드이며, 남은 보완은 정책/운영 확정 후 `MainAPP`에서 계속 갱신한다. + +## 부록. 현재 파일 기준 빠른 판단 메모 + +### 실제 구현이 있는 현재 화면 +- `src/pages/onboarding/OnboardingScreen.tsx` +- `src/pages/register/RegisterScreen.tsx` +- `src/pages/home/HomeScreen.tsx` +- `src/pages/log/LogScreen.tsx` +- `src/pages/log/LogDetailScreen.tsx` +- `src/pages/feed/FeedScreen.tsx` +- `src/pages/feed/FeedDiaryScreen.tsx` +- `src/pages/feed/FeedAvatarScreen.tsx` +- `src/pages/profile/ProfileScreen.tsx` +- `src/pages/follow/FollowScreen.tsx` +- `src/pages/delivery/UnlockGardenScreen.tsx` +- `src/pages/delivery/DeliveryScreen.tsx` +- `src/pages/delivery/DeliveryCompleteScreen.tsx` +- `src/pages/registration/RegistrationAvatarScreen.tsx` +- `src/pages/registration/RegistrationCreationDetailScreen.tsx` +- `src/pages/registration/RegistrationSelectionDetailScreen.tsx` +- `src/pages/registration/RegistrationPlantNicknameScreen.tsx` +- `src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx` +- `src/pages/dailyMission/DailyMissionQuizMultipleChoiceScreen.tsx` +- `src/pages/dailyMission/DailyMissionQuizOxScreen.tsx` +- `src/pages/dailyMission/DailyMissionCheckingScreen.tsx` +- `src/pages/option/OptionScreen.tsx` + +### 파일은 있으나 운영 보완이 남은 화면 +- `src/pages/option/OptionScreen.tsx` +- `src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx` + +### 실제 구현이 있는 공용 컴포넌트 +- `src/components/common/Splash.tsx` +- `src/components/common/Comment.tsx` +- `src/components/common/ScreenHeader.tsx` +- `src/components/common/StatusView.tsx` +- `src/components/feed/FeedList.tsx` +- `src/components/feed/FeedDetail.tsx` +- `src/components/log/LogCalendar.tsx` +- `src/components/log/MyDiary.tsx` +- `src/components/profile/ProfileDetail.tsx` +- `src/components/follow/UserCard.tsx` +- `src/components/delivery/PlantOptionCard.tsx` +- `src/components/delivery/GardenSlotCard.tsx` +- `src/components/delivery/DeliveryTextField.tsx` +- `src/components/delivery/DeliveryRequestSelector.tsx` +- `src/components/registration/AvatarPreviewCard.tsx` +- `src/components/registration/RegistrationFooter.tsx` +- `src/components/registration/RegistrationModeCard.tsx` +- `src/components/registration/SelectionAvatarCard.tsx` +- `src/components/registration/RegistrationTextField.tsx` +- `src/components/dailyMission/ImageAttachmentCard.tsx` +- `src/components/dailyMission/QuizOptionCard.tsx` +- `src/components/dailyMission/QuizResultCard.tsx` + +### 실제 연결된 API +- `src/apis/feed/feedApi.ts` +- `src/apis/feed/avatarPostDetailApi.ts` +- `src/apis/comments/commentApi.ts` +- `src/apis/log/calendarApi.ts` +- `src/apis/log/diariesApi.ts` +- `src/apis/log/diaryDetailApi.ts` +- `src/apis/profile/profileApi.ts` +- `src/apis/follow/followApi.ts` +- `src/apis/delivery/deliveryApi.ts` +- `src/apis/avatars/avatarApi.ts` +- `src/apis/missions/missionApi.ts` +- `src/apis/register/registerApi.ts` +- `src/apis/instance.ts` + diff --git a/app.json b/app.json index acd9f36..27bd69e 100644 --- a/app.json +++ b/app.json @@ -2,6 +2,7 @@ "expo": { "name": "hanium-app", "slug": "hanium-app", + "scheme": "haniumapp", "version": "1.0.0", "orientation": "portrait", "icon": "./assets/icon.png", diff --git a/metro.config.js b/metro.config.js index b0963fe..8d1f74c 100644 --- a/metro.config.js +++ b/metro.config.js @@ -3,4 +3,17 @@ const { withNativeWind } = require("nativewind/metro"); const config = getDefaultConfig(__dirname); +const { transformer, resolver } = config; + +config.transformer = { + ...transformer, + babelTransformerPath: require.resolve("react-native-svg-transformer") +}; + +config.resolver = { + ...resolver, + assetExts: resolver.assetExts.filter((ext) => ext !== "svg"), + sourceExts: [...resolver.sourceExts, "svg"] +}; + module.exports = withNativeWind(config, { input: "./global.css" }); diff --git a/nativewind-env.d.ts b/nativewind-env.d.ts index a13e313..0270208 100644 --- a/nativewind-env.d.ts +++ b/nativewind-env.d.ts @@ -1 +1,9 @@ /// + +declare module "*.svg" { + import * as React from "react"; + import type { SvgProps } from "react-native-svg"; + + const content: React.FC; + export default content; +} diff --git a/package-lock.json b/package-lock.json index 3a0de91..2e47326 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,25 +13,35 @@ "@react-navigation/native": "^7.1.28", "@react-navigation/native-stack": "^7.10.1", "@react-navigation/stack": "^7.6.16", + "@supabase/supabase-js": "^2.98.0", "@tanstack/react-query": "^5.90.19", "axios": "^1.13.2", "babel-preset-expo": "~54.0.9", "expo": "~54.0.31", + "expo-auth-session": "^55.0.7", + "expo-crypto": "^55.0.9", + "expo-image-picker": "~17.0.10", "expo-linking": "~8.0.11", + "expo-secure-store": "^55.0.8", "expo-status-bar": "~3.0.9", + "expo-web-browser": "^55.0.9", "nativewind": "^4.2.1", "react": "19.1.0", + "react-dom": "19.1.0", "react-native": "0.81.5", "react-native-pager-view": "6.9.1", "react-native-safe-area-context": "~5.6.0", "react-native-screens": "~4.16.0", "react-native-svg": "15.12.1", + "react-native-url-polyfill": "^3.0.0", + "react-native-web": "^0.21.0", "tailwindcss": "^3.4.17", "zustand": "^5.0.10" }, "devDependencies": { "@types/react": "~19.1.0", "babel-plugin-module-resolver": "^5.0.2", + "react-native-svg-transformer": "^1.5.3", "typescript": "~5.9.2" } }, @@ -2079,15 +2089,29 @@ } }, "node_modules/@expo/json-file": { - "version": "10.0.8", - "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-10.0.8.tgz", - "integrity": "sha512-9LOTh1PgKizD1VXfGQ88LtDH0lRwq9lsTb4aichWTWSWqy3Ugfkhfm3BhzBIkJJfQQ5iJu3m/BoRlEIjoCGcnQ==", + "version": "10.0.12", + "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-10.0.12.tgz", + "integrity": "sha512-inbDycp1rMAelAofg7h/mMzIe+Owx6F7pur3XdQ3EPTy00tme+4P6FWgHKUcjN8dBSrnbRNpSyh5/shzHyVCyQ==", "license": "MIT", "dependencies": { - "@babel/code-frame": "~7.10.4", + "@babel/code-frame": "^7.20.0", "json5": "^2.2.3" } }, + "node_modules/@expo/json-file/node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@expo/metro": { "version": "54.2.0", "resolved": "https://registry.npmjs.org/@expo/metro/-/metro-54.2.0.tgz", @@ -2218,6 +2242,39 @@ "xmlbuilder": "^15.1.1" } }, + "node_modules/@expo/require-utils": { + "version": "55.0.2", + "resolved": "https://registry.npmjs.org/@expo/require-utils/-/require-utils-55.0.2.tgz", + "integrity": "sha512-dV5oCShQ1umKBKagMMT4B/N+SREsQe3lU4Zgmko5AO0rxKV0tynZT6xXs+e2JxuqT4Rz997atg7pki0BnZb4uw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.20.0", + "@babel/core": "^7.25.2", + "@babel/plugin-transform-modules-commonjs": "^7.24.8" + }, + "peerDependencies": { + "typescript": "^5.0.0 || ^5.0.0-0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@expo/require-utils/node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@expo/schema-utils": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/@expo/schema-utils/-/schema-utils-0.1.8.tgz", @@ -3275,6 +3332,354 @@ "@sinonjs/commons": "^3.0.0" } }, + "node_modules/@supabase/auth-js": { + "version": "2.98.0", + "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.98.0.tgz", + "integrity": "sha512-GBH361T0peHU91AQNzOlIrjUZw9TZbB9YDRiyFgk/3Kvr3/Z1NWUZ2athWTfHhwNNi8IrW00foyFxQD9IO/Trg==", + "license": "MIT", + "dependencies": { + "tslib": "2.8.1" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@supabase/functions-js": { + "version": "2.98.0", + "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.98.0.tgz", + "integrity": "sha512-N/xEyiNU5Org+d+PNCpv+TWniAXRzxIURxDYsS/m2I/sfAB/HcM9aM2Dmf5edj5oWb9GxID1OBaZ8NMmPXL+Lg==", + "license": "MIT", + "dependencies": { + "tslib": "2.8.1" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@supabase/postgrest-js": { + "version": "2.98.0", + "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-2.98.0.tgz", + "integrity": "sha512-v6e9WeZuJijzUut8HyXu6gMqWFepIbaeaMIm1uKzei4yLg9bC9OtEW9O14LE/9ezqNbSAnSLO5GtOLFdm7Bpkg==", + "license": "MIT", + "dependencies": { + "tslib": "2.8.1" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@supabase/realtime-js": { + "version": "2.98.0", + "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.98.0.tgz", + "integrity": "sha512-rOWt28uGyFipWOSd+n0WVMr9kUXiWaa7J4hvyLCIHjRFqWm1z9CaaKAoYyfYMC1Exn3WT8WePCgiVhlAtWC2yw==", + "license": "MIT", + "dependencies": { + "@types/phoenix": "^1.6.6", + "@types/ws": "^8.18.1", + "tslib": "2.8.1", + "ws": "^8.18.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@supabase/realtime-js/node_modules/ws": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", + "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@supabase/storage-js": { + "version": "2.98.0", + "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.98.0.tgz", + "integrity": "sha512-tzr2mG+v7ILSAZSfZMSL9OPyIH4z1ikgQ8EcQTKfMRz4EwmlFt3UnJaGzSOxyvF5b+fc9So7qdSUWTqGgeLokQ==", + "license": "MIT", + "dependencies": { + "iceberg-js": "^0.8.1", + "tslib": "2.8.1" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@supabase/supabase-js": { + "version": "2.98.0", + "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.98.0.tgz", + "integrity": "sha512-Ohc97CtInLwZyiSASz7tT9/Abm/vqnIbO9REp+PivVUII8UZsuI3bngRQnYgJdFoOIwvaEII1fX1qy8x0CyNiw==", + "license": "MIT", + "dependencies": { + "@supabase/auth-js": "2.98.0", + "@supabase/functions-js": "2.98.0", + "@supabase/postgrest-js": "2.98.0", + "@supabase/realtime-js": "2.98.0", + "@supabase/storage-js": "2.98.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", + "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", + "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", + "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", + "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", + "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", + "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", + "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", + "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", + "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", + "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", + "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", + "@svgr/babel-plugin-transform-svg-component": "8.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/core": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", + "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^8.1.3", + "snake-case": "^3.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", + "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.21.3", + "entities": "^4.4.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", + "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "@svgr/hast-util-to-babel-ast": "8.0.0", + "svg-parser": "^2.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/plugin-svgo": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz", + "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cosmiconfig": "^8.1.3", + "deepmerge": "^4.3.1", + "svgo": "^3.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, "node_modules/@tanstack/query-core": { "version": "5.90.19", "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.19.tgz", @@ -3391,6 +3796,12 @@ "undici-types": "~7.16.0" } }, + "node_modules/@types/phoenix": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.7.tgz", + "integrity": "sha512-oN9ive//QSBkf19rfDv45M7eZPi0eEXylht2OLEXicu5b4KoQ1OzXIw+xDSGWxSxe1JmepRR/ZH283vsu518/Q==", + "license": "MIT" + }, "node_modules/@types/react": { "version": "19.1.17", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.17.tgz", @@ -3407,6 +3818,15 @@ "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", "license": "MIT" }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/yargs": { "version": "17.0.35", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", @@ -4252,6 +4672,16 @@ "node": ">= 0.4" } }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", @@ -4667,6 +5097,62 @@ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "license": "MIT" }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cosmiconfig/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/cosmiconfig/node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/cross-fetch": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz", + "integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==", + "license": "MIT", + "dependencies": { + "node-fetch": "^2.7.0" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -4690,6 +5176,15 @@ "node": ">=8" } }, + "node_modules/css-in-js-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz", + "integrity": "sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==", + "license": "MIT", + "dependencies": { + "hyphenate-style-name": "^1.0.3" + } + }, "node_modules/css-select": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", @@ -4752,6 +5247,42 @@ "node": ">=4" } }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "dev": true, + "license": "CC0-1.0" + }, "node_modules/csstype": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", @@ -4928,6 +5459,17 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/dotenv": { "version": "16.4.7", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", @@ -5017,6 +5559,23 @@ "node": ">=8" } }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/error-ex/node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, "node_modules/error-stack-parser": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", @@ -5166,22 +5725,248 @@ "fingerprint": "bin/fingerprint" }, "peerDependencies": { - "@expo/dom-webview": "*", - "@expo/metro-runtime": "*", - "react": "*", - "react-native": "*", - "react-native-webview": "*" + "@expo/dom-webview": "*", + "@expo/metro-runtime": "*", + "react": "*", + "react-native": "*", + "react-native-webview": "*" + }, + "peerDependenciesMeta": { + "@expo/dom-webview": { + "optional": true + }, + "@expo/metro-runtime": { + "optional": true + }, + "react-native-webview": { + "optional": true + } + } + }, + "node_modules/expo-auth-session": { + "version": "55.0.7", + "resolved": "https://registry.npmjs.org/expo-auth-session/-/expo-auth-session-55.0.7.tgz", + "integrity": "sha512-SWFudyF7K6924cSgPFrtK637aXj6HSs+DO6cP0q5xfwlcLaekkcoOHIrhpy8qaUIpxf7w01Dsk5fwu5RLse4eg==", + "license": "MIT", + "dependencies": { + "expo-application": "~55.0.8", + "expo-constants": "~55.0.7", + "expo-crypto": "~55.0.9", + "expo-linking": "~55.0.7", + "expo-web-browser": "~55.0.9", + "invariant": "^2.2.4" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, + "node_modules/expo-auth-session/node_modules/@expo/config": { + "version": "55.0.8", + "resolved": "https://registry.npmjs.org/@expo/config/-/config-55.0.8.tgz", + "integrity": "sha512-D7RYYHfErCgEllGxNwdYdkgzLna7zkzUECBV3snbUpf7RvIpB5l1LpCgzuVoc5KVew5h7N1Tn4LnT/tBSUZsQg==", + "license": "MIT", + "dependencies": { + "@expo/config-plugins": "~55.0.6", + "@expo/config-types": "^55.0.5", + "@expo/json-file": "^10.0.12", + "@expo/require-utils": "^55.0.2", + "deepmerge": "^4.3.1", + "getenv": "^2.0.0", + "glob": "^13.0.0", + "resolve-from": "^5.0.0", + "resolve-workspace-root": "^2.0.0", + "semver": "^7.6.0", + "slugify": "^1.3.4" + } + }, + "node_modules/expo-auth-session/node_modules/@expo/config-plugins": { + "version": "55.0.6", + "resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-55.0.6.tgz", + "integrity": "sha512-cIox6FjZlFaaX40rbQ3DvP9e87S5X85H9uw+BAxJE5timkMhuByy3GAlOsj1h96EyzSiol7Q6YIGgY1Jiz4M+A==", + "license": "MIT", + "dependencies": { + "@expo/config-types": "^55.0.5", + "@expo/json-file": "~10.0.12", + "@expo/plist": "^0.5.2", + "@expo/sdk-runtime-versions": "^1.0.0", + "chalk": "^4.1.2", + "debug": "^4.3.5", + "getenv": "^2.0.0", + "glob": "^13.0.0", + "resolve-from": "^5.0.0", + "semver": "^7.5.4", + "slugify": "^1.6.6", + "xcode": "^3.0.1", + "xml2js": "0.6.0" + } + }, + "node_modules/expo-auth-session/node_modules/@expo/config-types": { + "version": "55.0.5", + "resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-55.0.5.tgz", + "integrity": "sha512-sCmSUZG4mZ/ySXvfyyBdhjivz8Q539X1NondwDdYG7s3SBsk+wsgPJzYsqgAG/P9+l0xWjUD2F+kQ1cAJ6NNLg==", + "license": "MIT" + }, + "node_modules/expo-auth-session/node_modules/@expo/env": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@expo/env/-/env-2.1.1.tgz", + "integrity": "sha512-rVvHC4I6xlPcg+mAO09ydUi2Wjv1ZytpLmHOSzvXzBAz9mMrJggqCe4s4dubjJvi/Ino/xQCLhbaLCnTtLpikg==", + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "debug": "^4.3.4", + "getenv": "^2.0.0" + }, + "engines": { + "node": ">=20.12.0" + } + }, + "node_modules/expo-auth-session/node_modules/@expo/plist": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.5.2.tgz", + "integrity": "sha512-o4xdVdBpe4aTl3sPMZ2u3fJH4iG1I768EIRk1xRZP+GaFI93MaR3JvoFibYqxeTmLQ1p1kNEVqylfUjezxx45g==", + "license": "MIT", + "dependencies": { + "@xmldom/xmldom": "^0.8.8", + "base64-js": "^1.5.1", + "xmlbuilder": "^15.1.1" + } + }, + "node_modules/expo-auth-session/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/expo-auth-session/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/expo-auth-session/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/expo-auth-session/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/expo-auth-session/node_modules/expo-application": { + "version": "55.0.8", + "resolved": "https://registry.npmjs.org/expo-application/-/expo-application-55.0.8.tgz", + "integrity": "sha512-PeZk4Zj8LlzRcRtK3J4ouSPBoi9lroYsRbbz/0HEvx+uB6HIaM1qfzgpcctvjkdJJfnidBQNyieW5BVO/qUQ6w==", + "license": "MIT", + "peerDependencies": { + "expo": "*" + } + }, + "node_modules/expo-auth-session/node_modules/expo-constants": { + "version": "55.0.7", + "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-55.0.7.tgz", + "integrity": "sha512-kdcO4TsQRRqt0USvjaY5vgQMO9H52K3kBZ/ejC7F6rz70mv08GoowrZ1CYOr5O4JpPDRlIpQfZJUucaS/c+KWQ==", + "license": "MIT", + "dependencies": { + "@expo/config": "~55.0.8", + "@expo/env": "~2.1.1" + }, + "peerDependencies": { + "expo": "*", + "react-native": "*" + } + }, + "node_modules/expo-auth-session/node_modules/expo-linking": { + "version": "55.0.7", + "resolved": "https://registry.npmjs.org/expo-linking/-/expo-linking-55.0.7.tgz", + "integrity": "sha512-MiGCedere1vzQTEi2aGrkzd7eh/rPSz4w6F3GMBuAJzYl+/0VhIuyhozpEGrueyDIXWfzaUVOcn3SfxVi+kwQQ==", + "license": "MIT", + "dependencies": { + "expo-constants": "~55.0.7", + "invariant": "^2.2.4" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, + "node_modules/expo-auth-session/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/expo-auth-session/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/expo-crypto": { + "version": "55.0.9", + "resolved": "https://registry.npmjs.org/expo-crypto/-/expo-crypto-55.0.9.tgz", + "integrity": "sha512-hYiZYRPMXGQXSgKjp/m84l/6Uq8mTeMts1C7bFZXN5M5TUOiRhrLeqMSYZFXrAlkFpXeO46V+Ts1CFauMBLuCw==", + "license": "MIT", + "peerDependencies": { + "expo": "*" + } + }, + "node_modules/expo-image-loader": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/expo-image-loader/-/expo-image-loader-6.0.0.tgz", + "integrity": "sha512-nKs/xnOGw6ACb4g26xceBD57FKLFkSwEUTDXEDF3Gtcu3MqF3ZIYd3YM+sSb1/z9AKV1dYT7rMSGVNgsveXLIQ==", + "license": "MIT", + "peerDependencies": { + "expo": "*" + } + }, + "node_modules/expo-image-picker": { + "version": "17.0.10", + "resolved": "https://registry.npmjs.org/expo-image-picker/-/expo-image-picker-17.0.10.tgz", + "integrity": "sha512-a2xrowp2trmvXyUWgX3O6Q2rZaa2C59AqivKI7+bm+wLvMfTEbZgldLX4rEJJhM8xtmEDTNU+lzjtObwzBRGaw==", + "license": "MIT", + "dependencies": { + "expo-image-loader": "~6.0.0" }, - "peerDependenciesMeta": { - "@expo/dom-webview": { - "optional": true - }, - "@expo/metro-runtime": { - "optional": true - }, - "react-native-webview": { - "optional": true - } + "peerDependencies": { + "expo": "*" } }, "node_modules/expo-linking": { @@ -5311,6 +6096,15 @@ "react-native": "*" } }, + "node_modules/expo-secure-store": { + "version": "55.0.8", + "resolved": "https://registry.npmjs.org/expo-secure-store/-/expo-secure-store-55.0.8.tgz", + "integrity": "sha512-8w9tQe8U6oRo5YIzqCqVhRrOnfoODNDoitBtLXEx+zS6WLUnkRq5kH7ViJuOgiM7PzLr9pvAliRiDOKyvFbTuQ==", + "license": "MIT", + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo-server": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/expo-server/-/expo-server-1.0.5.tgz", @@ -5333,6 +6127,16 @@ "react-native": "*" } }, + "node_modules/expo-web-browser": { + "version": "55.0.9", + "resolved": "https://registry.npmjs.org/expo-web-browser/-/expo-web-browser-55.0.9.tgz", + "integrity": "sha512-PvAVsG401QmZabtTsYh1cYcpPiqvBPs8oiOkSrp0jIXnneiM466HxmeNtvo+fNxqJ2nwOBz9qLPiWRO91VBfsQ==", + "license": "MIT", + "peerDependencies": { + "expo": "*", + "react-native": "*" + } + }, "node_modules/expo/node_modules/@babel/code-frame": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz", @@ -5763,6 +6567,36 @@ "bser": "2.1.1" } }, + "node_modules/fbjs": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.5.tgz", + "integrity": "sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg==", + "license": "MIT", + "dependencies": { + "cross-fetch": "^3.1.5", + "fbjs-css-vars": "^1.0.0", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^1.0.35" + } + }, + "node_modules/fbjs-css-vars": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz", + "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==", + "license": "MIT" + }, + "node_modules/fbjs/node_modules/promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "license": "MIT", + "dependencies": { + "asap": "~2.0.3" + } + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -6222,6 +7056,21 @@ "node": ">= 14" } }, + "node_modules/hyphenate-style-name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz", + "integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==", + "license": "BSD-3-Clause" + }, + "node_modules/iceberg-js": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/iceberg-js/-/iceberg-js-0.8.1.tgz", + "integrity": "sha512-1dhVQZXhcHje7798IVM+xoo/1ZdVfzOMIc8/rgVSijRK38EDqOJoGula9N/8ZI5RD8QTxNQtK/Gozpr+qUqRRA==", + "license": "MIT", + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -6266,6 +7115,33 @@ "node": ">=16.x" } }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -6298,6 +7174,15 @@ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "license": "ISC" }, + "node_modules/inline-style-prefixer": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-7.0.1.tgz", + "integrity": "sha512-lhYo5qNTQp3EvSSp3sRvXMbVQTLrvGV6DycRMJ5dm2BLMiJ30wpXKdDdgX+GmJZ5uQMucwRKHamXSst3Sj/Giw==", + "license": "MIT", + "dependencies": { + "css-in-js-utils": "^3.1.0" + } + }, "node_modules/invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -6913,6 +7798,13 @@ "node": ">=6" } }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -7292,6 +8184,16 @@ "loose-envify": "cli.js" } }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -7896,6 +8798,37 @@ "integrity": "sha512-SrQrok4CATudVzBS7coSz26QRSmlK9TzzoFbeKfcPBUFPjcQM9Rqvr/DlJkOrwI/0KcgvMub1n1g5Jt9EgRn4A==", "license": "MIT" }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/node-forge": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.3.tgz", @@ -8136,6 +9069,38 @@ "node": ">=6" } }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parse-png": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/parse-png/-/parse-png-2.1.0.tgz", @@ -8157,6 +9122,13 @@ "node": ">= 0.8" } }, + "node_modules/path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", + "dev": true, + "license": "MIT" + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -8215,6 +9187,16 @@ "node": "20 || >=22" } }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -8693,6 +9675,18 @@ "ws": "^7" } }, + "node_modules/react-dom": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", + "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.26.0" + }, + "peerDependencies": { + "react": "^19.1.0" + } + }, "node_modules/react-freeze": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/react-freeze/-/react-freeze-1.0.4.tgz", @@ -9131,6 +10125,67 @@ "react-native": "*" } }, + "node_modules/react-native-svg-transformer": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/react-native-svg-transformer/-/react-native-svg-transformer-1.5.3.tgz", + "integrity": "sha512-M4uFg5pUt35OMgjD4rWWbwd6PmxV96W7r/gQTTa+iZA5B+jO6aURhzAZGLHSrg1Kb91cKG0Rildy9q1WJvYstg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@svgr/core": "^8.1.0", + "@svgr/plugin-jsx": "^8.1.0", + "@svgr/plugin-svgo": "^8.1.0", + "path-dirname": "^1.0.2" + }, + "peerDependencies": { + "react-native": ">=0.59.0", + "react-native-svg": ">=12.0.0" + } + }, + "node_modules/react-native-url-polyfill": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-native-url-polyfill/-/react-native-url-polyfill-3.0.0.tgz", + "integrity": "sha512-aA5CiuUCUb/lbrliVCJ6lZ17/RpNJzvTO/C7gC/YmDQhTUoRD5q5HlJfwLWcxz4VgAhHwXKzhxH+wUN24tAdqg==", + "license": "MIT", + "dependencies": { + "whatwg-url-without-unicode": "8.0.0-3" + }, + "peerDependencies": { + "react-native": "*" + } + }, + "node_modules/react-native-web": { + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.21.2.tgz", + "integrity": "sha512-SO2t9/17zM4iEnFvlu2DA9jqNbzNhoUP+AItkoCOyFmDMOhUnBBznBDCYN92fGdfAkfQlWzPoez6+zLxFNsZEg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.6", + "@react-native/normalize-colors": "^0.74.1", + "fbjs": "^3.0.4", + "inline-style-prefixer": "^7.0.1", + "memoize-one": "^6.0.0", + "nullthrows": "^1.1.1", + "postcss-value-parser": "^4.2.0", + "styleq": "^0.1.3" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/react-native-web/node_modules/@react-native/normalize-colors": { + "version": "0.74.89", + "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.74.89.tgz", + "integrity": "sha512-qoMMXddVKVhZ8PA1AbUCk83trpd6N+1nF2A6k1i6LsQObyS92fELuk8kU/lQs6M7BsMHwqyLCpQJ1uFgNvIQXg==", + "license": "MIT" + }, + "node_modules/react-native-web/node_modules/memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", + "license": "MIT" + }, "node_modules/react-native-worklets": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/react-native-worklets/-/react-native-worklets-0.7.2.tgz", @@ -9626,9 +10681,9 @@ "license": "MIT" }, "node_modules/sax": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.4.tgz", - "integrity": "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.5.0.tgz", + "integrity": "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==", "license": "BlueOak-1.0.0", "engines": { "node": ">=11.0.0" @@ -9754,6 +10809,12 @@ "node": ">= 0.8" } }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "license": "MIT" + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -9852,6 +10913,17 @@ "node": ">=8.0.0" } }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -10011,6 +11083,12 @@ "integrity": "sha512-0MP/Cxx5SzeeZ10p/bZI0S6MpgD+yxAhi1BOQ34jgnMXsCq3j1t6tQnZu+KdlL7dvJTLT3g9xN8tl10TqgFMcg==", "license": "MIT" }, + "node_modules/styleq": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/styleq/-/styleq-0.1.3.tgz", + "integrity": "sha512-3ZUifmCDCQanjeej1f6kyl/BeP/Vae5EYkQ9iJfUm/QwZvlgnZzyflqAsAWYURdtea8Vkvswu2GrC57h3qffcA==", + "license": "MIT" + }, "node_modules/sucrase": { "version": "3.35.1", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", @@ -10100,6 +11178,60 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/svgo": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.3.tgz", + "integrity": "sha512-+wn7I4p7YgJhHs38k2TNjy1vCfPIfLIJWR5MnCStsN8WuuTcBnRKcMHQLMM2ijxGZmDoZwNv8ipl5aTTen62ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^7.2.0", + "css-select": "^5.1.0", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.0.0", + "sax": "^1.5.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/svgo/node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/svgo/node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true, + "license": "CC0-1.0" + }, "node_modules/tailwindcss": { "version": "3.4.17", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", @@ -10367,12 +11499,24 @@ "node": ">=0.6" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", "license": "Apache-2.0" }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -10395,7 +11539,7 @@ "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -10405,6 +11549,32 @@ "node": ">=14.17" } }, + "node_modules/ua-parser-js": { + "version": "1.0.41", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.41.tgz", + "integrity": "sha512-LbBDqdIC5s8iROCUjMbW1f5dJQTEFB1+KO9ogbvlb3nm9n4YHa5p4KTvFPWvh2Hs8gZMBuiB1/8+pdfe/tDPug==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "license": "MIT", + "bin": { + "ua-parser-js": "script/cli.js" + }, + "engines": { + "node": "*" + } + }, "node_modules/undici": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz", @@ -10616,6 +11786,16 @@ "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", "license": "MIT" }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/whatwg-url-without-unicode": { "version": "8.0.0-3", "resolved": "https://registry.npmjs.org/whatwg-url-without-unicode/-/whatwg-url-without-unicode-8.0.0-3.tgz", @@ -10630,6 +11810,12 @@ "node": ">=10" } }, + "node_modules/whatwg-url/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index 5370f1b..9f2bae2 100644 --- a/package.json +++ b/package.json @@ -14,25 +14,35 @@ "@react-navigation/native": "^7.1.28", "@react-navigation/native-stack": "^7.10.1", "@react-navigation/stack": "^7.6.16", + "@supabase/supabase-js": "^2.98.0", "@tanstack/react-query": "^5.90.19", "axios": "^1.13.2", "babel-preset-expo": "~54.0.9", "expo": "~54.0.31", + "expo-auth-session": "^55.0.7", + "expo-crypto": "^55.0.9", + "expo-image-picker": "~17.0.10", "expo-linking": "~8.0.11", + "expo-secure-store": "^55.0.8", "expo-status-bar": "~3.0.9", + "expo-web-browser": "^55.0.9", "nativewind": "^4.2.1", "react": "19.1.0", + "react-dom": "19.1.0", "react-native": "0.81.5", "react-native-pager-view": "6.9.1", "react-native-safe-area-context": "~5.6.0", "react-native-screens": "~4.16.0", "react-native-svg": "15.12.1", + "react-native-url-polyfill": "^3.0.0", + "react-native-web": "^0.21.0", "tailwindcss": "^3.4.17", "zustand": "^5.0.10" }, "devDependencies": { "@types/react": "~19.1.0", "babel-plugin-module-resolver": "^5.0.2", + "react-native-svg-transformer": "^1.5.3", "typescript": "~5.9.2" }, "private": true diff --git a/src/apis/avatars/avatarApi.ts b/src/apis/avatars/avatarApi.ts new file mode 100644 index 0000000..e37da50 --- /dev/null +++ b/src/apis/avatars/avatarApi.ts @@ -0,0 +1,30 @@ +import api from "@/apis/instance"; +import type { + FinalChoiceAvatarRequest, + FinalChoiceAvatarResponse, + SelectAvatarResponse, + UploadCreationAvatarResponse, +} from "@/types/avatars"; + +export const getAvatarMastersApi = async (): Promise => { + const res = await api.get("/api/v1/avatars/masters"); + return res.data; +}; + +export const postUploadCreationAvatarApi = async ( + formData: FormData +): Promise => { + const res = await api.post("/api/v1/register/upload", formData, { + headers: { + "Content-Type": "multipart/form-data", + }, + }); + return res.data; +}; + +export const postFinalChoiceAvatarApi = async ( + payload: FinalChoiceAvatarRequest +): Promise => { + const res = await api.post("/api/v1/avatars", payload); + return res.data; +}; diff --git a/src/apis/delivery/deliveryApi.ts b/src/apis/delivery/deliveryApi.ts new file mode 100644 index 0000000..7cb92c1 --- /dev/null +++ b/src/apis/delivery/deliveryApi.ts @@ -0,0 +1,21 @@ +import api from "@/apis/instance"; +import type { GlobalResponse } from "@/types/common/apiResponse.type"; +import type { CreateSeedDeliveryRequest, DeliverablePlant } from "@/types/delivery"; + +export const getDeliverablePlants = async (): Promise< + GlobalResponse +> => { + const res = await api.get("/api/v1/deliveries/plants"); + return res.data; +}; + +export const postSeedDelivery = async ( + payload: CreateSeedDeliveryRequest +): Promise> => { + const res = await api.post("/api/v1/deliveries/seeds", payload); + return res.data; +}; + +export const postUnlockGarden = async (): Promise => { + await api.post("/api/v1/gardens/unlock"); +}; diff --git a/src/apis/follow/followApi.ts b/src/apis/follow/followApi.ts new file mode 100644 index 0000000..f366e3b --- /dev/null +++ b/src/apis/follow/followApi.ts @@ -0,0 +1,32 @@ +import api from "@/apis/instance"; +import type { ApiResponse } from "@/types/common/apiResponse.type"; +import type { FollowResponse } from "@/types/follow"; +import type { FollowUserResponse } from "@/types/profile/profileApi.type"; + +export const getFollowing = async ( + userId: string | number +): ApiResponse => { + const res = await api.get(`/api/v1/users/${userId}/following`); + return res.data; +}; + +export const getFollowers = async ( + userId: string | number +): ApiResponse => { + const res = await api.get(`/api/v1/users/${userId}/followers`); + return res.data; +}; + +export const postFollowUser = async ( + userId: string | number +): ApiResponse => { + const res = await api.post(`/api/v1/users/${userId}/follow`); + return res.data; +}; + +export const deleteFollowUser = async ( + userId: string | number +): ApiResponse => { + const res = await api.delete(`/api/v1/users/${userId}/follow`); + return res.data; +}; diff --git a/src/apis/home/homeApi.ts b/src/apis/home/homeApi.ts new file mode 100644 index 0000000..7f752ad --- /dev/null +++ b/src/apis/home/homeApi.ts @@ -0,0 +1,15 @@ +import api from "@/apis/instance"; +import type { ApiResponse } from "@/types/common/apiResponse.type"; +import { + normalizeHomeSummaryPayload, + type HomeSummaryPayload, +} from "@/types/home/garden"; + +export const getHomeSummary = async (): ApiResponse => { + const res = await api.get("/api/v1/home"); + + return { + ...res.data, + result: normalizeHomeSummaryPayload(res.data.result), + }; +}; diff --git a/src/apis/instance.ts b/src/apis/instance.ts index 21cb983..9c19196 100644 --- a/src/apis/instance.ts +++ b/src/apis/instance.ts @@ -1,10 +1,16 @@ import axios, { + AxiosHeaders, AxiosError, + AxiosRequestHeaders, InternalAxiosRequestConfig, } from "axios"; +import { refreshAuthApi } from "@/apis/register/registerApi"; +import useTokenStore from "@/stores/useTokenStore"; +import { logout } from "@/utils/auth"; type ReqConfig = InternalAxiosRequestConfig & { _skipAuth?: boolean; + _retry?: boolean; }; // 환경변수는 app.config.ts 또는 .env에서 설정 @@ -14,37 +20,92 @@ const api = axios.create({ baseURL: API_URL, }); +let refreshPromise: Promise | null = null; + +const refreshAccessToken = async (): Promise => { + if (!refreshPromise) { + refreshPromise = (async () => { + const { refreshToken, userId } = useTokenStore.getState(); + + if (!refreshToken) { + return null; + } + + try { + const response = await refreshAuthApi(refreshToken); + + if (!response.isSuccess || !response.result?.accessToken) { + return null; + } + + useTokenStore.getState().setAuth({ + accessToken: response.result.accessToken, + refreshToken: response.result.refreshToken || refreshToken, + userId: response.result.userId + ? String(response.result.userId) + : userId, + }); + + return response.result.accessToken; + } catch (refreshError) { + return null; + } finally { + refreshPromise = null; + } + })(); + } + + return refreshPromise; +}; + /** 요청 인터셉터: accessToken 부착 (옵션으로 스킵 가능) */ api.interceptors.request.use((config: ReqConfig) => { if (config._skipAuth) return config; - // TODO: 토큰 스토어 마이그레이션 후 활성화 - // const { accessToken } = useTokenStore.getState(); - // const headers = (config.headers ??= - // new AxiosHeaders()) as AxiosRequestHeaders; - // if (accessToken) headers.Authorization = `Bearer ${accessToken}`; - // else delete headers.Authorization; + const { accessToken } = useTokenStore.getState(); + const headers = (config.headers ??= + new AxiosHeaders()) as AxiosRequestHeaders; + + if (accessToken) { + headers.Authorization = `Bearer ${accessToken}`; + } else { + delete headers.Authorization; + } return config; }); -/** 응답 인터셉터: 403 → onboarding 이동, 401 → 토큰 클리어 */ +/** 응답 인터셉터: 401 refresh 1회 재시도, 실패 시 인증 해제 */ api.interceptors.response.use( res => res, async (error: AxiosError) => { const status = error.response?.status; + const originalRequest = error.config as ReqConfig | undefined; if (status === 403) { - // React Navigation으로 온보딩 화면으로 이동 - // router.replace("/onboarding"); return Promise.reject(error); } - if (status === 401) { - // TODO: 토큰 스토어 마이그레이션 후 활성화 - // const store = useTokenStore.getState(); - // store.clearTokens?.(); - return Promise.reject(error); + if ( + status === 401 && + originalRequest && + !originalRequest._skipAuth && + !originalRequest._retry + ) { + originalRequest._retry = true; + + const nextAccessToken = await refreshAccessToken(); + + if (!nextAccessToken) { + await logout(); + return Promise.reject(error); + } + + const headers = (originalRequest.headers ??= + new AxiosHeaders()) as AxiosRequestHeaders; + headers.Authorization = `Bearer ${nextAccessToken}`; + + return api(originalRequest); } return Promise.reject(error); diff --git a/src/apis/missions/missionApi.ts b/src/apis/missions/missionApi.ts new file mode 100644 index 0000000..3f3a9ab --- /dev/null +++ b/src/apis/missions/missionApi.ts @@ -0,0 +1,61 @@ +import api from "@/apis/instance"; +import type { + AnswerDailySurveyRequest, + AnswerDailySurveyResponse, + AnswerQuizRequest, + AnswerQuizResponse, + DiaryImageUploadResponse, + GetDailySurveyResponse, + GetQuizRequest, + GetQuizResponse, + WriteDiaryRequest, + WriteDiaryResponse, +} from "@/types/missions"; + +export const uploadDiaryImageApi = async ( + formData: FormData +): Promise => { + const res = await api.post("/api/v1/diaries/images", formData, { + headers: { + "Content-Type": "multipart/form-data", + }, + }); + + return res.data; +}; + +export const writeDiaryApi = async ( + payload: WriteDiaryRequest +): Promise => { + const res = await api.post("/api/v1/diaries", payload); + return res.data; +}; + +export const getQuizApi = async ( + params: GetQuizRequest +): Promise => { + const res = await api.get("/api/v1/realQuiz", { params }); + return res.data; +}; + +export const answerQuizApi = async ({ + quizId, + selectedOptionOrder, +}: AnswerQuizRequest): Promise => { + const res = await api.post(`/api/v1/realQuiz/${quizId}/answer`, { + selectedOptionOrder, + }); + return res.data; +}; + +export const getDailySurveyApi = async (): Promise => { + const res = await api.get("/api/v1/survey"); + return res.data; +}; + +export const answerDailySurveyApi = async ( + payload: AnswerDailySurveyRequest +): Promise => { + const res = await api.post("/api/v1/survey/answer", payload); + return res.data; +}; diff --git a/src/apis/profile/profileApi.ts b/src/apis/profile/profileApi.ts new file mode 100644 index 0000000..d325e3c --- /dev/null +++ b/src/apis/profile/profileApi.ts @@ -0,0 +1,20 @@ +import api from "@/apis/instance"; +import type { ApiResponse } from "@/types/common/apiResponse.type"; +import type { + FriendWaterResponse, + GetUserProfileResponse, +} from "@/types/profile/profileApi.type"; + +export const getUserProfile = async ( + userId: string | number +): ApiResponse => { + const res = await api.get(`/api/v1/users/${userId}`); + return res.data; +}; + +export const postFriendWater = async ( + gardenId: number +): ApiResponse => { + const res = await api.post(`/api/v1/gardens/${gardenId}/friendwater`); + return res.data; +}; diff --git a/src/apis/register/registerApi.ts b/src/apis/register/registerApi.ts index 1531ec1..3d6540c 100644 --- a/src/apis/register/registerApi.ts +++ b/src/apis/register/registerApi.ts @@ -7,3 +7,24 @@ export const registerApi = async ( ): ApiResponse => { return axios.post("/api/v1/auth/signup", { nickname }).then(res => res.data); }; + +// [STEP 3] 백엔드 자체 인증 처리 API +// 프론트엔드에서 획득한 Supabase의 AccessToken을 백엔드로 보내어 +// 자체 서비스에서 사용하는 JWT(Access/Refresh Token)로 교환받습니다. +export const loginWithSupabaseApi = async ( + accessToken: string +): ApiResponse => { + return axios.post("/api/v1/auth/supabase", { accessToken }).then(res => res.data); +}; + +export const refreshAuthApi = async ( + refreshToken: string +): ApiResponse => { + return axios + .post( + "/api/v1/auth/refresh", + { refreshToken }, + { _skipAuth: true } as const + ) + .then(res => res.data); +}; diff --git a/src/apis/supabase.ts b/src/apis/supabase.ts new file mode 100644 index 0000000..628cb89 --- /dev/null +++ b/src/apis/supabase.ts @@ -0,0 +1,31 @@ +import { AppState } from 'react-native'; +import 'react-native-url-polyfill/auto'; +import AsyncStorage from '@react-native-async-storage/async-storage'; +import { createClient } from '@supabase/supabase-js'; + +// TODO: 환경변수(.env)로 분리 필요 (현재는 디버깅 및 테스트를 위해 하드코딩 또는 설정값 사용) +// 개발 서버용 임시 키 (실제 프로젝트 환경에 맞게 변경) +const supabaseUrl = process.env.EXPO_PUBLIC_SUPABASE_URL || 'YOUR_SUPABASE_URL'; +const supabaseAnonKey = process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY || 'YOUR_SUPABASE_ANON_KEY'; + +console.log('[Supabase Setup] Initializing Supabase client with URL:', supabaseUrl); + +export const supabase = createClient(supabaseUrl, supabaseAnonKey, { + auth: { + storage: AsyncStorage, + autoRefreshToken: true, + persistSession: true, + detectSessionInUrl: false, + }, +}); + +// AppState 변경 시 (앱이 백그라운드/포그라운드 전환 시) 세션 자동 갱신 처리 +AppState.addEventListener('change', (state) => { + if (state === 'active') { + console.debug('[Supabase Setup] App became active, starting AutoRefresh'); + supabase.auth.startAutoRefresh(); + } else { + console.debug('[Supabase Setup] App went to background, stopping AutoRefresh'); + supabase.auth.stopAutoRefresh(); + } +}); diff --git a/src/assets/icons/common/index.ts b/src/assets/icons/common/index.ts index bf4c18a..140385f 100644 --- a/src/assets/icons/common/index.ts +++ b/src/assets/icons/common/index.ts @@ -1,27 +1,27 @@ -export { default as BookMark } from "./bookmark1.svg?react"; -export { default as ActiveBookMark } from "./bookmark2.svg?react"; -export { default as ActiveCalendar } from "./calendar1.svg?react"; -export { default as Calendar } from "./calendar2.svg?react"; -export { default as Camera } from "./camera.svg?react"; -export { default as Chat } from "./chat.svg?react"; -export { default as Check } from "./Check.svg?react"; -export { default as UnCheck } from "./Check2.svg?react"; -export { default as Edit } from "./edit.svg?react"; -export { default as Heart } from "./heart.svg?react"; -export { default as ActiveHome } from "./home1.svg?react"; -export { default as Home } from "./home2.svg?react"; -export { default as Left } from "./left.svg?react"; -export { default as Level0 } from "./level0.svg?react"; -export { default as Level1 } from "./level1.svg?react"; -export { default as Level2 } from "./level2.svg?react"; -export { default as Level3 } from "./level3.svg?react"; -export { default as Right } from "./right.svg?react"; -export { default as ActiveSearch } from "./search1.svg?react"; -export { default as Search } from "./search2.svg?react"; -export { default as Send } from "./send.svg?react"; -export { default as TogleOn } from "./togle1.svg?react"; -export { default as TogleOff } from "./togle2.svg?react"; -export { default as ActiveUser } from "./user1.svg?react"; -export { default as User } from "./user2.svg?react"; -export { default as UserPlus } from "./userPlus.svg?react"; -export { default as Xmark } from "./Xmack.svg?react"; +export { default as BookMark } from "./bookmark1.svg"; +export { default as ActiveBookMark } from "./bookmark2.svg"; +export { default as ActiveCalendar } from "./calendar1.svg"; +export { default as Calendar } from "./calendar2.svg"; +export { default as Camera } from "./camera.svg"; +export { default as Chat } from "./chat.svg"; +export { default as Check } from "./Check.svg"; +export { default as UnCheck } from "./Check2.svg"; +export { default as Edit } from "./edit.svg"; +export { default as Heart } from "./heart.svg"; +export { default as ActiveHome } from "./home1.svg"; +export { default as Home } from "./home2.svg"; +export { default as Left } from "./left.svg"; +export { default as Level0 } from "./level0.svg"; +export { default as Level1 } from "./level1.svg"; +export { default as Level2 } from "./level2.svg"; +export { default as Level3 } from "./level3.svg"; +export { default as Right } from "./right.svg"; +export { default as ActiveSearch } from "./search1.svg"; +export { default as Search } from "./search2.svg"; +export { default as Send } from "./send.svg"; +export { default as TogleOn } from "./togle1.svg"; +export { default as TogleOff } from "./togle2.svg"; +export { default as ActiveUser } from "./user1.svg"; +export { default as User } from "./user2.svg"; +export { default as UserPlus } from "./userPlus.svg"; +export { default as Xmark } from "./Xmack.svg"; diff --git a/src/components/common/CommentComposer.tsx b/src/components/common/CommentComposer.tsx new file mode 100644 index 0000000..d991c21 --- /dev/null +++ b/src/components/common/CommentComposer.tsx @@ -0,0 +1,77 @@ +import { + StyleSheet, + TextInput, + TouchableOpacity, + View, +} from "react-native"; +import { SendIcon } from "@/assets/icons/CommonIcons"; + +type Props = { + value: string; + onChangeText: (text: string) => void; + onSubmit: () => void; + disabled?: boolean; + placeholder?: string; +}; + +export default function CommentComposer({ + value, + onChangeText, + onSubmit, + disabled = false, + placeholder = "댓글을 입력해주세요.", +}: Props) { + const canSubmit = !disabled && value.trim().length > 0; + + return ( + + + + + + + + + ); +} + +const styles = StyleSheet.create({ + container: { + borderTopWidth: 1, + borderTopColor: "#E5E7EB", + backgroundColor: "#FFFFFF", + paddingHorizontal: 20, + paddingVertical: 12, + }, + row: { + flexDirection: "row", + alignItems: "center", + gap: 12, + }, + input: { + flex: 1, + paddingHorizontal: 16, + paddingVertical: 10, + backgroundColor: "#E5E7EB", + borderRadius: 20, + fontSize: 14, + color: "#171717", + }, + sendDisabled: { + opacity: 0.45, + }, +}); diff --git a/src/components/common/ScreenHeader.tsx b/src/components/common/ScreenHeader.tsx new file mode 100644 index 0000000..66bdc10 --- /dev/null +++ b/src/components/common/ScreenHeader.tsx @@ -0,0 +1,47 @@ +import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import { LeftIcon } from "@/assets/icons/CommonIcons"; + +type Props = { + title: string; + onBack?: () => void; +}; + +export default function ScreenHeader({ title, onBack }: Props) { + return ( + + + + + {title} + + + ); +} + +const styles = StyleSheet.create({ + header: { + height: 56, + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + paddingHorizontal: 12, + borderBottomWidth: 1, + borderBottomColor: "#E5E7EB", + backgroundColor: "#FFFFFF", + }, + sideButton: { + width: 24, + height: 24, + justifyContent: "center", + alignItems: "center", + }, + title: { + fontSize: 18, + fontWeight: "700", + color: "#171717", + }, +}); diff --git a/src/components/common/StatusView.tsx b/src/components/common/StatusView.tsx new file mode 100644 index 0000000..947af9e --- /dev/null +++ b/src/components/common/StatusView.tsx @@ -0,0 +1,74 @@ +import { + ActivityIndicator, + StyleSheet, + Text, + TouchableOpacity, + View, +} from "react-native"; + +type Props = { + title: string; + description?: string; + actionLabel?: string; + onAction?: () => void; + loading?: boolean; +}; + +export default function StatusView({ + title, + description, + actionLabel, + onAction, + loading = false, +}: Props) { + return ( + + {loading ? : null} + {title} + {description ? {description} : null} + {actionLabel && onAction ? ( + + {actionLabel} + + ) : null} + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + alignItems: "center", + justifyContent: "center", + paddingHorizontal: 24, + gap: 8, + }, + title: { + fontSize: 16, + fontWeight: "600", + color: "#171717", + textAlign: "center", + }, + description: { + fontSize: 14, + lineHeight: 20, + color: "#6B7280", + textAlign: "center", + }, + button: { + marginTop: 8, + backgroundColor: "#4CAF50", + borderRadius: 999, + paddingHorizontal: 16, + paddingVertical: 10, + }, + buttonText: { + color: "#FFFFFF", + fontSize: 14, + fontWeight: "600", + }, +}); diff --git a/src/components/dailyMission/ImageAttachmentCard.tsx b/src/components/dailyMission/ImageAttachmentCard.tsx new file mode 100644 index 0000000..f564bc3 --- /dev/null +++ b/src/components/dailyMission/ImageAttachmentCard.tsx @@ -0,0 +1,74 @@ +import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; + +type Props = { + imageUrl?: string | null; + disabled?: boolean; + onPress: () => void; + helperText?: string; +}; + +export default function ImageAttachmentCard({ + imageUrl, + disabled = false, + onPress, + helperText, +}: Props) { + return ( + + 이미지 첨부 + + + {imageUrl ? "업로드된 이미지가 있습니다." : "이미지를 선택하거나 업로드하세요"} + + + {imageUrl + ? imageUrl + : "현재 프로젝트에는 RN 이미지 선택 라이브러리가 없어 업로드 인터페이스만 먼저 정리했습니다."} + + + {helperText ? {helperText} : null} + + ); +} + +const styles = StyleSheet.create({ + container: { + gap: 8, + }, + label: { + fontSize: 14, + fontWeight: "600", + color: "#374151", + }, + card: { + borderRadius: 16, + borderWidth: 1, + borderColor: "#D1D5DB", + padding: 16, + gap: 6, + backgroundColor: "#FFFFFF", + }, + cardDisabled: { + backgroundColor: "#F9FAFB", + }, + title: { + fontSize: 15, + fontWeight: "700", + color: "#171717", + }, + description: { + fontSize: 13, + lineHeight: 18, + color: "#6B7280", + }, + helperText: { + fontSize: 12, + lineHeight: 18, + color: "#92400E", + }, +}); diff --git a/src/components/dailyMission/QuizOptionCard.tsx b/src/components/dailyMission/QuizOptionCard.tsx new file mode 100644 index 0000000..9cf22f1 --- /dev/null +++ b/src/components/dailyMission/QuizOptionCard.tsx @@ -0,0 +1,79 @@ +import { StyleSheet, Text, TouchableOpacity } from "react-native"; + +type Props = { + label: string; + selected: boolean; + disabled?: boolean; + state?: "correct" | "wrong" | "answer" | "idle"; + onPress: () => void; +}; + +export default function QuizOptionCard({ + label, + selected, + disabled = false, + state = "idle", + onPress, +}: Props) { + return ( + + {label} + + {state === "correct" || state === "answer" + ? "정답" + : state === "wrong" + ? "오답" + : selected + ? "선택됨" + : ""} + + + ); +} + +const styles = StyleSheet.create({ + card: { + borderRadius: 14, + borderWidth: 1, + borderColor: "#D1D5DB", + padding: 16, + backgroundColor: "#FFFFFF", + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + gap: 12, + }, + cardSelected: { + backgroundColor: "#F3F4F6", + borderColor: "#9CA3AF", + }, + cardCorrect: { + backgroundColor: "#EDF7ED", + borderColor: "#2F7D32", + }, + cardWrong: { + backgroundColor: "#FEF2F2", + borderColor: "#DC2626", + }, + text: { + flex: 1, + fontSize: 15, + lineHeight: 22, + color: "#171717", + }, + badge: { + fontSize: 12, + fontWeight: "700", + color: "#4B5563", + }, +}); diff --git a/src/components/dailyMission/QuizResultCard.tsx b/src/components/dailyMission/QuizResultCard.tsx new file mode 100644 index 0000000..a5aaf4e --- /dev/null +++ b/src/components/dailyMission/QuizResultCard.tsx @@ -0,0 +1,46 @@ +import { StyleSheet, Text, View } from "react-native"; + +type Props = { + correct: boolean; + description: string; +}; + +export default function QuizResultCard({ correct, description }: Props) { + return ( + + + {correct ? "정답!" : "오답!"} + + {description} + + ); +} + +const styles = StyleSheet.create({ + card: { + borderRadius: 16, + padding: 16, + gap: 6, + }, + correct: { + backgroundColor: "#EDF7ED", + }, + wrong: { + backgroundColor: "#FEF2F2", + }, + title: { + fontSize: 16, + fontWeight: "700", + }, + correctText: { + color: "#1F5C27", + }, + wrongText: { + color: "#B91C1C", + }, + description: { + fontSize: 14, + lineHeight: 20, + color: "#4B5563", + }, +}); diff --git a/src/components/delivery/DeliveryRequestSelector.tsx b/src/components/delivery/DeliveryRequestSelector.tsx new file mode 100644 index 0000000..771a534 --- /dev/null +++ b/src/components/delivery/DeliveryRequestSelector.tsx @@ -0,0 +1,104 @@ +import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import DeliveryTextField from "@/components/delivery/DeliveryTextField"; + +export const DELIVERY_REQUEST_OPTIONS = [ + "문 앞에 놔주세요", + "경비실에 맡겨주세요", + "택배함에 넣어주세요", + "배송 전에 연락 주세요", + "직접 입력", +] as const; + +type Props = { + value: string; + customValue: string; + onChange: (value: string) => void; + onChangeCustom: (value: string) => void; +}; + +export default function DeliveryRequestSelector({ + value, + customValue, + onChange, + onChangeCustom, +}: Props) { + return ( + + 배송 요청사항 + + 현재 확인된 계약 기준으로 요청 문구만 서버에 전송합니다. + + + {DELIVERY_REQUEST_OPTIONS.map(option => { + const selected = value === option; + + return ( + onChange(option)} + > + + {option} + + + ); + })} + + {value === "직접 입력" ? ( + + ) : null} + + ); +} + +const styles = StyleSheet.create({ + container: { + gap: 10, + }, + title: { + fontSize: 16, + fontWeight: "700", + color: "#171717", + }, + subtitle: { + fontSize: 13, + lineHeight: 18, + color: "#6B7280", + }, + options: { + gap: 10, + }, + option: { + borderWidth: 1, + borderColor: "#D1D5DB", + borderRadius: 14, + paddingHorizontal: 14, + paddingVertical: 14, + backgroundColor: "#FFFFFF", + }, + optionSelected: { + borderColor: "#2F7D32", + backgroundColor: "#EDF7ED", + }, + optionText: { + fontSize: 14, + color: "#374151", + }, + optionTextSelected: { + color: "#1F5C27", + fontWeight: "700", + }, +}); diff --git a/src/components/delivery/DeliveryTextField.tsx b/src/components/delivery/DeliveryTextField.tsx new file mode 100644 index 0000000..2a115a1 --- /dev/null +++ b/src/components/delivery/DeliveryTextField.tsx @@ -0,0 +1,74 @@ +import { + StyleSheet, + Text, + TextInput, + type KeyboardTypeOptions, + View, +} from "react-native"; + +type Props = { + label: string; + value: string; + onChangeText: (value: string) => void; + placeholder: string; + keyboardType?: KeyboardTypeOptions; + multiline?: boolean; + helperText?: string; +}; + +export default function DeliveryTextField({ + label, + value, + onChangeText, + placeholder, + keyboardType = "default", + multiline = false, + helperText, +}: Props) { + return ( + + {label} + + {helperText ? {helperText} : null} + + ); +} + +const styles = StyleSheet.create({ + container: { + gap: 8, + }, + label: { + fontSize: 14, + fontWeight: "600", + color: "#374151", + }, + input: { + minHeight: 52, + borderWidth: 1, + borderColor: "#D1D5DB", + borderRadius: 14, + paddingHorizontal: 14, + fontSize: 15, + color: "#171717", + backgroundColor: "#FFFFFF", + }, + multiline: { + minHeight: 92, + paddingVertical: 14, + }, + helperText: { + fontSize: 12, + lineHeight: 18, + color: "#6B7280", + }, +}); diff --git a/src/components/delivery/GardenSlotCard.tsx b/src/components/delivery/GardenSlotCard.tsx new file mode 100644 index 0000000..d1d6d0b --- /dev/null +++ b/src/components/delivery/GardenSlotCard.tsx @@ -0,0 +1,100 @@ +import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import { + getGardenLocked, + getGardenUnlockable, + type GardenSummary, +} from "@/types/home/garden"; + +type Props = { + garden: GardenSummary; + selected: boolean; + onPress: () => void; +}; + +export default function GardenSlotCard({ garden, selected, onPress }: Props) { + const isUnlockable = getGardenUnlockable(garden); + const isLocked = getGardenLocked(garden); + const statusText = isUnlockable ? "해금 가능" : isLocked ? "아직 잠금 상태" : "사용 가능"; + + return ( + + + 정원 슬롯 {garden.gardenSlotNumber} + + {statusText} + + + + {garden.avatar?.avatarName + ? `${garden.avatar.avatarName}와 연결된 슬롯` + : "새 식물을 받을 수 있는 잠금 슬롯"} + + + 해금 버튼을 누르면 `POST /api/v1/gardens/unlock`를 body 없이 호출합니다. + + + ); +} + +const styles = StyleSheet.create({ + card: { + borderRadius: 18, + borderWidth: 1, + borderColor: "#E5E7EB", + backgroundColor: "#FFFFFF", + padding: 16, + gap: 8, + }, + cardSelected: { + borderColor: "#2F7D32", + backgroundColor: "#F2FAF1", + }, + row: { + flexDirection: "row", + justifyContent: "space-between", + alignItems: "center", + gap: 12, + }, + title: { + flex: 1, + fontSize: 16, + fontWeight: "700", + color: "#171717", + }, + badge: { + fontSize: 12, + fontWeight: "700", + paddingHorizontal: 10, + paddingVertical: 5, + borderRadius: 999, + overflow: "hidden", + }, + badgeReady: { + color: "#1F5C27", + backgroundColor: "#DDF3DE", + }, + badgeLocked: { + color: "#92400E", + backgroundColor: "#FEF3C7", + }, + description: { + fontSize: 14, + lineHeight: 20, + color: "#374151", + }, + caption: { + fontSize: 12, + lineHeight: 18, + color: "#6B7280", + }, +}); diff --git a/src/components/delivery/PlantOptionCard.tsx b/src/components/delivery/PlantOptionCard.tsx new file mode 100644 index 0000000..410c983 --- /dev/null +++ b/src/components/delivery/PlantOptionCard.tsx @@ -0,0 +1,67 @@ +import { Image, StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import type { DeliverablePlant } from "@/types/delivery"; + +type Props = { + plant: DeliverablePlant; + selected: boolean; + onPress: () => void; +}; + +export default function PlantOptionCard({ plant, selected, onPress }: Props) { + return ( + + {plant.imageUrl ? ( + + ) : ( + + 이미지 없음 + + )} + {plant.name} + 씨앗 타입 #{plant.seedType} + + ); +} + +const styles = StyleSheet.create({ + card: { + width: 180, + borderRadius: 20, + padding: 14, + borderWidth: 1, + borderColor: "#E5E7EB", + backgroundColor: "#FFFFFF", + gap: 10, + }, + cardSelected: { + borderColor: "#2F7D32", + backgroundColor: "#F2FAF1", + }, + image: { + width: "100%", + height: 180, + borderRadius: 16, + backgroundColor: "#F3F4F6", + }, + imageFallback: { + alignItems: "center", + justifyContent: "center", + }, + fallbackText: { + fontSize: 13, + color: "#6B7280", + }, + name: { + fontSize: 16, + fontWeight: "700", + color: "#171717", + }, + caption: { + fontSize: 12, + color: "#6B7280", + }, +}); diff --git a/src/components/feed/FeedDetail.tsx b/src/components/feed/FeedDetail.tsx index aa56751..3500495 100644 --- a/src/components/feed/FeedDetail.tsx +++ b/src/components/feed/FeedDetail.tsx @@ -86,17 +86,21 @@ export default function FeedDetail({ result }: Props) { {/* 댓글 목록 */} - {result.comments.map(c => ( - - ))} + {result.comments.length > 0 ? ( + result.comments.map(c => ( + + )) + ) : ( + 아직 작성된 댓글이 없습니다. + )} ); @@ -191,4 +195,10 @@ const styles = StyleSheet.create({ paddingVertical: 16, marginHorizontal: -20, }, + emptyText: { + fontSize: 14, + color: "#9CA3AF", + textAlign: "center", + paddingVertical: 24, + }, }); diff --git a/src/components/feed/FeedList.tsx b/src/components/feed/FeedList.tsx index 068d019..451dac7 100644 --- a/src/components/feed/FeedList.tsx +++ b/src/components/feed/FeedList.tsx @@ -50,6 +50,17 @@ export default function FeedList({ ); } + if (!feedData.result.length) { + return ( + + 아직 올라온 게시글이 없습니다. + + 피드 데이터가 준비되면 이 화면에서 바로 상세로 이동할 수 있습니다. + + + ); + } + const renderItem = ({ item }: { item: FeedPost }) => ( void; + onActionPress?: () => void; +}; + +export default function UserCard({ + user, + actionLabel, + actionDisabled = false, + onPress, + onActionPress, +}: Props) { + return ( + + + + {user.userImageUrl ? ( + + ) : null} + + {user.username} + + + {actionLabel ? ( + + + {actionLabel} + + + ) : null} + + ); +} + +const styles = StyleSheet.create({ + card: { + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + paddingHorizontal: 20, + paddingVertical: 16, + borderBottomWidth: 1, + borderBottomColor: "#F3F4F6", + backgroundColor: "#FFFFFF", + }, + userInfo: { + flex: 1, + flexDirection: "row", + alignItems: "center", + gap: 12, + }, + avatarWrap: { + width: 40, + height: 40, + borderRadius: 20, + overflow: "hidden", + backgroundColor: "#E5E7EB", + }, + avatar: { + width: "100%", + height: "100%", + }, + username: { + fontSize: 15, + fontWeight: "500", + color: "#171717", + }, + actionButton: { + borderRadius: 999, + borderWidth: 1, + borderColor: "#D1D5DB", + paddingHorizontal: 12, + paddingVertical: 8, + }, + actionButtonDisabled: { + backgroundColor: "#F3F4F6", + }, + actionButtonText: { + fontSize: 13, + fontWeight: "600", + color: "#374151", + }, + actionButtonTextDisabled: { + color: "#9CA3AF", + }, +}); diff --git a/src/components/log/MyDiaryDetail.tsx b/src/components/log/MyDiaryDetail.tsx new file mode 100644 index 0000000..eadedf6 --- /dev/null +++ b/src/components/log/MyDiaryDetail.tsx @@ -0,0 +1,142 @@ +import { Image, StyleSheet, Text, View } from "react-native"; +import { ChatIcon, EditIcon, HeartIcon } from "@/assets/icons/CommonIcons"; +import Comment from "@/components/common/Comment"; +import type { GETDiaryDetailResponse } from "@/types/log/diaryDetailApi.type"; + +type Props = { + detail: GETDiaryDetailResponse; +}; + +export default function MyDiaryDetail({ detail }: Props) { + const formatDate = (iso: string) => { + const date = new Date(iso); + return `${date.getFullYear()}년 ${date.getMonth() + 1}월 ${date.getDate()}일`; + }; + + return ( + + {formatDate(detail.createdAt)} + {detail.title} + + {detail.imageUrl ? ( + + ) : null} + + {detail.content} + + + + + + 공감 {detail.likeCount} + + + + 댓글 {detail.commentCount} + + + + + 수정 기능 보류 + + + + + {detail.comments.length > 0 ? ( + detail.comments.map(comment => ( + + )) + ) : ( + 아직 작성된 댓글이 없습니다. + )} + + + ); +} + +const styles = StyleSheet.create({ + container: { + paddingTop: 24, + paddingHorizontal: 20, + }, + date: { + fontSize: 13, + color: "#6B7280", + marginBottom: 8, + }, + title: { + fontSize: 24, + fontWeight: "700", + color: "#171717", + marginBottom: 20, + }, + image: { + width: "100%", + aspectRatio: 1, + borderRadius: 12, + marginBottom: 20, + backgroundColor: "#F3F4F6", + }, + content: { + fontSize: 15, + lineHeight: 24, + color: "#171717", + marginBottom: 24, + }, + actionBar: { + flexDirection: "row", + justifyContent: "space-between", + alignItems: "center", + borderTopWidth: 1, + borderBottomWidth: 1, + borderColor: "#E5E7EB", + paddingVertical: 16, + paddingHorizontal: 20, + marginHorizontal: -20, + }, + actionItems: { + flexDirection: "row", + alignItems: "center", + gap: 16, + }, + actionItem: { + flexDirection: "row", + alignItems: "center", + gap: 8, + }, + actionText: { + fontSize: 14, + color: "#171717", + }, + editItem: { + flexDirection: "row", + alignItems: "center", + gap: 4, + }, + editText: { + fontSize: 12, + color: "#6B7280", + }, + commentSection: { + paddingVertical: 16, + marginHorizontal: -20, + }, + emptyText: { + fontSize: 14, + color: "#9CA3AF", + textAlign: "center", + paddingVertical: 24, + }, +}); diff --git a/src/components/profile/ProfileDetail.tsx b/src/components/profile/ProfileDetail.tsx new file mode 100644 index 0000000..c12e47b --- /dev/null +++ b/src/components/profile/ProfileDetail.tsx @@ -0,0 +1,119 @@ +import { Image, StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import type { GardenInfo } from "@/types/profile/profileApi.type"; + +type Props = { + garden: GardenInfo; + leftWaterCountForOthers: number; + onWater: () => void; + waterDisabled?: boolean; +}; + +export default function ProfileDetail({ + garden, + leftWaterCountForOthers, + onWater, + waterDisabled = false, +}: Props) { + const canWater = garden.isWateringAbleByMe && !waterDisabled; + + return ( + + 대표 정원 + + + + {garden.avatarInfo?.avatarImageUrl ? ( + + ) : null} + + + + {garden.avatarInfo?.avatarName ?? "등록된 식물이 없습니다."} + + 남은 친구 물주기 {leftWaterCountForOthers}회 + + + + + {garden.isWateringAbleByMe ? "친구 물주기" : "오늘은 이미 물을 주었습니다"} + + + + + ); +} + +const styles = StyleSheet.create({ + container: { + paddingHorizontal: 20, + paddingVertical: 20, + }, + sectionTitle: { + fontSize: 18, + fontWeight: "700", + color: "#171717", + marginBottom: 12, + }, + card: { + backgroundColor: "#F5F7F1", + borderRadius: 20, + padding: 16, + gap: 16, + }, + avatarRow: { + flexDirection: "row", + alignItems: "center", + gap: 14, + }, + imageWrap: { + width: 72, + height: 72, + borderRadius: 18, + backgroundColor: "#E5E7EB", + overflow: "hidden", + }, + avatarImage: { + width: "100%", + height: "100%", + }, + textWrap: { + flex: 1, + gap: 4, + }, + avatarName: { + fontSize: 18, + fontWeight: "700", + color: "#171717", + }, + metaText: { + fontSize: 13, + lineHeight: 18, + color: "#6B7280", + }, + waterButton: { + borderRadius: 14, + backgroundColor: "#4CAF50", + paddingVertical: 14, + alignItems: "center", + }, + waterButtonDisabled: { + backgroundColor: "#E5E7EB", + }, + waterButtonText: { + color: "#FFFFFF", + fontSize: 14, + fontWeight: "700", + }, + waterButtonTextDisabled: { + color: "#9CA3AF", + }, +}); diff --git a/src/components/registration/AvatarPreviewCard.tsx b/src/components/registration/AvatarPreviewCard.tsx new file mode 100644 index 0000000..576ec5d --- /dev/null +++ b/src/components/registration/AvatarPreviewCard.tsx @@ -0,0 +1,60 @@ +import { Image, StyleSheet, Text, View } from "react-native"; + +type Props = { + imageUrl?: string | null; + title: string; + description?: string; +}; + +export default function AvatarPreviewCard({ + imageUrl, + title, + description, +}: Props) { + return ( + + {imageUrl ? ( + + ) : ( + + {title} + + )} + {description ? {description} : null} + + ); +} + +const styles = StyleSheet.create({ + card: { + borderRadius: 20, + padding: 16, + backgroundColor: "#F2F8EE", + gap: 12, + alignItems: "center", + }, + image: { + width: 220, + height: 220, + borderRadius: 18, + backgroundColor: "#E5E7EB", + }, + placeholder: { + alignItems: "center", + justifyContent: "center", + paddingHorizontal: 16, + }, + placeholderText: { + textAlign: "center", + fontSize: 18, + lineHeight: 26, + fontWeight: "700", + color: "#1F5C27", + }, + description: { + fontSize: 14, + lineHeight: 20, + color: "#4B5563", + textAlign: "center", + }, +}); diff --git a/src/components/registration/RegistrationFooter.tsx b/src/components/registration/RegistrationFooter.tsx new file mode 100644 index 0000000..d290388 --- /dev/null +++ b/src/components/registration/RegistrationFooter.tsx @@ -0,0 +1,87 @@ +import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; + +type Props = { + primaryLabel: string; + onPrimaryPress: () => void; + primaryDisabled?: boolean; + secondaryLabel?: string; + onSecondaryPress?: () => void; + primaryLoading?: boolean; +}; + +export default function RegistrationFooter({ + primaryLabel, + onPrimaryPress, + primaryDisabled = false, + secondaryLabel, + onSecondaryPress, + primaryLoading = false, +}: Props) { + return ( + + {secondaryLabel && onSecondaryPress ? ( + + {secondaryLabel} + + ) : null} + + + {primaryLoading ? "처리 중..." : primaryLabel} + + + + ); +} + +const styles = StyleSheet.create({ + container: { + flexDirection: "row", + gap: 12, + paddingHorizontal: 20, + paddingVertical: 16, + borderTopWidth: 1, + borderTopColor: "#E5E7EB", + backgroundColor: "#FFFFFF", + }, + secondaryButton: { + flex: 1, + minHeight: 52, + borderRadius: 16, + alignItems: "center", + justifyContent: "center", + backgroundColor: "#E5E7EB", + }, + secondaryText: { + fontSize: 15, + fontWeight: "700", + color: "#374151", + }, + primaryButton: { + flex: 1, + minHeight: 52, + borderRadius: 16, + alignItems: "center", + justifyContent: "center", + backgroundColor: "#2F7D32", + }, + primaryButtonDisabled: { + backgroundColor: "#A7D4A5", + }, + primaryText: { + fontSize: 15, + fontWeight: "700", + color: "#FFFFFF", + }, +}); diff --git a/src/components/registration/RegistrationModeCard.tsx b/src/components/registration/RegistrationModeCard.tsx new file mode 100644 index 0000000..a59f1be --- /dev/null +++ b/src/components/registration/RegistrationModeCard.tsx @@ -0,0 +1,81 @@ +import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import type { RegistrationMode } from "@/types/avatars"; + +type Props = { + mode: RegistrationMode; + title: string; + description: string; + previewLabel: string; + selected: boolean; + onPress: () => void; +}; + +export default function RegistrationModeCard({ + title, + description, + previewLabel, + selected, + onPress, +}: Props) { + return ( + + + {title} + {description} + + + {previewLabel} + + + ); +} + +const styles = StyleSheet.create({ + card: { + borderRadius: 22, + padding: 18, + backgroundColor: "#FFFFFF", + borderWidth: 1, + borderColor: "#E5E7EB", + gap: 14, + }, + cardSelected: { + borderColor: "#2F7D32", + backgroundColor: "#F2FAF1", + }, + copy: { + gap: 6, + }, + title: { + fontSize: 20, + fontWeight: "700", + color: "#171717", + }, + description: { + fontSize: 14, + lineHeight: 20, + color: "#4B5563", + }, + preview: { + minHeight: 116, + borderRadius: 18, + backgroundColor: "#F3F4F6", + alignItems: "center", + justifyContent: "center", + paddingHorizontal: 16, + }, + previewSelected: { + backgroundColor: "#DDF3DE", + }, + previewText: { + fontSize: 16, + lineHeight: 24, + fontWeight: "700", + color: "#1F5C27", + textAlign: "center", + }, +}); diff --git a/src/components/registration/RegistrationTextField.tsx b/src/components/registration/RegistrationTextField.tsx new file mode 100644 index 0000000..653af99 --- /dev/null +++ b/src/components/registration/RegistrationTextField.tsx @@ -0,0 +1,66 @@ +import { StyleSheet, Text, TextInput, View } from "react-native"; + +type Props = { + label: string; + value: string; + onChangeText: (value: string) => void; + placeholder: string; + multiline?: boolean; + helperText?: string; +}; + +export default function RegistrationTextField({ + label, + value, + onChangeText, + placeholder, + multiline = false, + helperText, +}: Props) { + return ( + + {label} + + {helperText ? {helperText} : null} + + ); +} + +const styles = StyleSheet.create({ + container: { + gap: 8, + }, + label: { + fontSize: 14, + fontWeight: "600", + color: "#374151", + }, + input: { + minHeight: 52, + borderWidth: 1, + borderColor: "#D1D5DB", + borderRadius: 14, + paddingHorizontal: 14, + fontSize: 15, + color: "#171717", + backgroundColor: "#FFFFFF", + }, + multiline: { + minHeight: 110, + paddingTop: 14, + paddingBottom: 14, + }, + helperText: { + fontSize: 12, + lineHeight: 18, + color: "#6B7280", + }, +}); diff --git a/src/components/registration/SelectionAvatarCard.tsx b/src/components/registration/SelectionAvatarCard.tsx new file mode 100644 index 0000000..e38d8ef --- /dev/null +++ b/src/components/registration/SelectionAvatarCard.tsx @@ -0,0 +1,76 @@ +import { Image, StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import type { AvatarMaster } from "@/types/avatars"; + +type Props = { + avatar: AvatarMaster; + selected: boolean; + onPress: () => void; +}; + +export default function SelectionAvatarCard({ + avatar, + selected, + onPress, +}: Props) { + return ( + + + {avatar.description} + + + {selected ? "선택됨" : "선택하기"} + + + + ); +} + +const styles = StyleSheet.create({ + card: { + width: "48%", + borderRadius: 18, + padding: 12, + borderWidth: 1, + borderColor: "#E5E7EB", + backgroundColor: "#FFFFFF", + gap: 10, + }, + cardSelected: { + borderColor: "#2F7D32", + backgroundColor: "#F2FAF1", + }, + image: { + width: "100%", + aspectRatio: 1, + borderRadius: 14, + backgroundColor: "#F3F4F6", + }, + description: { + fontSize: 14, + lineHeight: 20, + color: "#171717", + fontWeight: "600", + }, + badge: { + alignSelf: "flex-start", + borderRadius: 999, + backgroundColor: "#F3F4F6", + paddingHorizontal: 10, + paddingVertical: 6, + }, + badgeSelected: { + backgroundColor: "#DDF3DE", + }, + badgeText: { + fontSize: 12, + fontWeight: "700", + color: "#6B7280", + }, + badgeTextSelected: { + color: "#1F5C27", + }, +}); diff --git a/src/hooks/auth/useBackendLogin.ts b/src/hooks/auth/useBackendLogin.ts new file mode 100644 index 0000000..673a3d7 --- /dev/null +++ b/src/hooks/auth/useBackendLogin.ts @@ -0,0 +1,29 @@ +import { useMutation } from "@tanstack/react-query"; +import { loginWithSupabaseApi } from "@/apis/register/registerApi"; +import useTokenStore from "@/stores/useTokenStore"; +import { PostRegisterResponse } from "@/types/apis/register"; +import { GlobalResponse } from "@/types/common/apiResponse.type"; + +// [STEP 3.5] 커스텀 훅 - 백엔드 로그인 연동 로직 +// Supabase OAuth 로그인 후 획득한 토큰을 MainBE 백엔드에 보내고 +// 응답으로 받은 자체 JWT 및 UserId를 useTokenStore (Zustand/AsyncStorage)에 영구 저장합니다. +export const useBackendLogin = () => { + const { setAuth } = useTokenStore(); + + return useMutation, Error, string>({ + mutationFn: (accessToken: string) => loginWithSupabaseApi(accessToken), + onSuccess: (data) => { + // 요청이 성공했을 경우 토큰 정보를 상태 및 기기 저장소에 업데이트합니다. + if (data.isSuccess && data.result) { + setAuth({ + accessToken: data.result.accessToken, + refreshToken: data.result.refreshToken, + userId: String(data.result.userId), + }); + } + }, + onError: (error) => { + console.error("[useBackendLogin] Backend login failed:", error); + }, + }); +}; diff --git a/src/hooks/auth/useSupabaseOAuth.ts b/src/hooks/auth/useSupabaseOAuth.ts new file mode 100644 index 0000000..58609db --- /dev/null +++ b/src/hooks/auth/useSupabaseOAuth.ts @@ -0,0 +1,112 @@ +import { useState } from 'react'; +import { makeRedirectUri } from 'expo-auth-session'; +import * as WebBrowser from 'expo-web-browser'; +import * as Linking from 'expo-linking'; +import { supabase } from '@/apis/supabase'; +import { useBackendLogin } from './useBackendLogin'; + +WebBrowser.maybeCompleteAuthSession(); + +export const useSupabaseOAuth = () => { + const [isLoading, setIsLoading] = useState(false); + const { mutateAsync: backendLogin } = useBackendLogin(); + + // Create redirect URI for our scheme + const redirectUri = makeRedirectUri({ + scheme: 'haniumapp', + path: 'auth/callback', + }); + + const performOAuth = async (provider: 'google' | 'kakao') => { + setIsLoading(true); + console.debug(`[SupabaseOAuth] performOAuth started for ${provider}`); + console.debug(`[SupabaseOAuth] Redirect URI: ${redirectUri}`); + + try { + // [STEP 1] Supabase Auth를 통해 제공자(Provider)의 OAuth 로그인 URL 획득 + const { data, error } = await supabase.auth.signInWithOAuth({ + provider, + options: { + redirectTo: redirectUri, + skipBrowserRedirect: true, // 직접 브라우저를 열기 위해 자동 리다이렉트 방지 + }, + }); + + if (error) { + console.error('[SupabaseOAuth] signInWithOAuth error:', error); + throw error; + } + + if (!data?.url) { + console.error('[SupabaseOAuth] No URL returned from signInWithOAuth'); + throw new Error('No URL returned'); + } + + // [STEP 2] Expo WebBrowser를 사용하여 모바일 기기에 내장된 브라우저로 실제 로그인 페이지 오픈 + console.debug(`[SupabaseOAuth] Opening browser for URL: ${data.url}`); + const result = await WebBrowser.openAuthSessionAsync(data.url, redirectUri); + + console.debug('[SupabaseOAuth] Auth session result type:', result.type); + + if (result.type === 'success') { + // [STEP 2-1] 리다이렉트 성공 시, 딥링크 URL 파싱 + const { url } = result; + console.debug('[SupabaseOAuth] URL received on success. Parsing URL...'); + + // App(React Native) 환경에서는 URL Hash Fragment(#) 부분에 토큰이 들어오는 경우가 많음 + const urlObj = new URL(url); + const fragment = urlObj.hash.substring(1); + const urlSearchParams = new URLSearchParams(fragment); + let accessToken = urlSearchParams.get('access_token'); + let refreshToken = urlSearchParams.get('refresh_token'); + + // 쿼리스트링(?) 형태인 경우를 대비한 Fallback + if (!accessToken) { + accessToken = urlObj.searchParams.get('access_token'); + refreshToken = urlObj.searchParams.get('refresh_token'); + } + + if (accessToken) { + // [STEP 3] 토큰 추출 성공 + // 3-1. Supabase Local Session 설정 (앱 구동 내 상태 동기화) + console.debug('[SupabaseOAuth] Access token parsed successfully. Logging into Supabase locally...'); + + await supabase.auth.setSession({ + access_token: accessToken, + refresh_token: refreshToken || '', + }); + + // 3-2. 백엔드(Spring) 토큰 교환 호출 (useBackendLogin 참조) + console.debug('[SupabaseOAuth] Sending access token to backend...'); + const backendRes = await backendLogin(accessToken); + + if (backendRes.isSuccess) { + console.log('[SupabaseOAuth] Backend login complete!'); + return { + success: true, + isNewUser: backendRes.result?.newUser, + nickname: backendRes.result?.nickname + }; + } else { + console.error('[SupabaseOAuth] Backend login failed with message:', backendRes.message); + throw new Error(backendRes.message); + } + } else { + console.warn('[SupabaseOAuth] No access token found in the URL. URL:', url); + throw new Error('No access_token found in URL'); + } + } else { + console.warn(`[SupabaseOAuth] Browser closed or cancelled. Result type: ${result.type}`); + return { success: false, cancelled: true }; + } + } catch (err) { + console.error('[SupabaseOAuth] Exception during performOAuth:', err); + return { success: false, error: err }; + } finally { + setIsLoading(false); + console.debug(`[SupabaseOAuth] performOAuth finished`); + } + }; + + return { performOAuth, isLoading, redirectUri }; +}; diff --git a/src/hooks/avatars/useAvatarApi.ts b/src/hooks/avatars/useAvatarApi.ts new file mode 100644 index 0000000..5ac5e45 --- /dev/null +++ b/src/hooks/avatars/useAvatarApi.ts @@ -0,0 +1,30 @@ +import { useMutation, useQuery } from "@tanstack/react-query"; +import { + getAvatarMastersApi, + postFinalChoiceAvatarApi, + postUploadCreationAvatarApi, +} from "@/apis/avatars/avatarApi"; +import type { + AvatarMaster, + FinalChoiceAvatarRequest, + FinalChoiceAvatarResponse, + SelectAvatarResponse, + UploadCreationAvatarResponse, +} from "@/types/avatars"; + +export const useAvatarMasters = () => + useQuery({ + queryKey: ["avatar-masters"], + queryFn: getAvatarMastersApi, + select: data => data.result, + }); + +export const useUploadCreationAvatar = () => + useMutation({ + mutationFn: formData => postUploadCreationAvatarApi(formData), + }); + +export const useFinalChoiceAvatar = () => + useMutation({ + mutationFn: payload => postFinalChoiceAvatarApi(payload), + }); diff --git a/src/hooks/delivery/useDeliveryApi.ts b/src/hooks/delivery/useDeliveryApi.ts new file mode 100644 index 0000000..a277328 --- /dev/null +++ b/src/hooks/delivery/useDeliveryApi.ts @@ -0,0 +1,42 @@ +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import type { AxiosError } from "axios"; +import { + getDeliverablePlants, + postSeedDelivery, + postUnlockGarden, +} from "@/apis/delivery/deliveryApi"; +import type { GlobalResponse } from "@/types/common/apiResponse.type"; +import type { CreateSeedDeliveryRequest, DeliverablePlant } from "@/types/delivery"; + +export const useDeliverablePlants = () => + useQuery< + GlobalResponse, + AxiosError, + DeliverablePlant[] + >({ + queryKey: ["deliverable-plants"], + queryFn: getDeliverablePlants, + select: data => data.result, + }); + +export const useCreateSeedDelivery = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: (payload: CreateSeedDeliveryRequest) => postSeedDelivery(payload), + onSuccess: async () => { + await queryClient.invalidateQueries({ queryKey: ["home-summary"] }); + }, + }); +}; + +export const useUnlockGarden = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: () => postUnlockGarden(), + onSuccess: async () => { + await queryClient.invalidateQueries({ queryKey: ["home-summary"] }); + }, + }); +}; diff --git a/src/hooks/follow/useFollowApi.ts b/src/hooks/follow/useFollowApi.ts new file mode 100644 index 0000000..a6e422b --- /dev/null +++ b/src/hooks/follow/useFollowApi.ts @@ -0,0 +1,64 @@ +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { + deleteFollowUser, + getFollowers, + getFollowing, + postFollowUser, +} from "@/apis/follow/followApi"; +import type { FollowResponse } from "@/types/follow"; + +export const useFollowing = (userId: string | undefined) => + useQuery< + { result: FollowResponse["result"] }, + unknown, + FollowResponse["result"] + >({ + queryKey: ["following", userId], + queryFn: () => getFollowing(userId ?? ""), + select: data => data.result, + enabled: !!userId, + refetchOnMount: "always", + }); + +export const useFollowers = (userId: string | undefined) => + useQuery< + { result: FollowResponse["result"] }, + unknown, + FollowResponse["result"] + >({ + queryKey: ["followers", userId], + queryFn: () => getFollowers(userId ?? ""), + select: data => data.result, + enabled: !!userId, + refetchOnMount: "always", + }); + +export const useFollowUser = (userId: string | undefined) => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: (targetUserId: string | number) => postFollowUser(targetUserId), + onSuccess: async (_, targetUserId) => { + await Promise.all([ + queryClient.invalidateQueries({ queryKey: ["profile", String(targetUserId)] }), + queryClient.invalidateQueries({ queryKey: ["following", userId] }), + queryClient.invalidateQueries({ queryKey: ["followers", userId] }), + ]); + }, + }); +}; + +export const useUnfollowUser = (userId: string | undefined) => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: (targetUserId: string | number) => deleteFollowUser(targetUserId), + onSuccess: async (_, targetUserId) => { + await Promise.all([ + queryClient.invalidateQueries({ queryKey: ["profile", String(targetUserId)] }), + queryClient.invalidateQueries({ queryKey: ["following", userId] }), + queryClient.invalidateQueries({ queryKey: ["followers", userId] }), + ]); + }, + }); +}; diff --git a/src/hooks/home/useHomeApi.ts b/src/hooks/home/useHomeApi.ts new file mode 100644 index 0000000..06227e1 --- /dev/null +++ b/src/hooks/home/useHomeApi.ts @@ -0,0 +1,19 @@ +import { useQuery } from "@tanstack/react-query"; +import type { AxiosError } from "axios"; +import { getHomeSummary } from "@/apis/home/homeApi"; +import type { GlobalResponse } from "@/types/common/apiResponse.type"; +import type { HomeSummaryPayload } from "@/types/home/garden"; + +export const useHomeApi = () => + useQuery< + GlobalResponse, + AxiosError, + HomeSummaryPayload + >({ + queryKey: ["home-summary"], + queryFn: getHomeSummary, + select: data => data.result, + refetchOnMount: "always", + }); + +export default useHomeApi; diff --git a/src/hooks/mission/useMissionApi.ts b/src/hooks/mission/useMissionApi.ts new file mode 100644 index 0000000..a57a525 --- /dev/null +++ b/src/hooks/mission/useMissionApi.ts @@ -0,0 +1,66 @@ +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { + answerDailySurveyApi, + answerQuizApi, + getDailySurveyApi, + getQuizApi, + uploadDiaryImageApi, + writeDiaryApi, +} from "@/apis/missions/missionApi"; +import type { + AnswerDailySurveyRequest, + AnswerDailySurveyResponse, + AnswerQuizRequest, + AnswerQuizResponse, + DailySurvey, + DiaryImageUploadResponse, + GetDailySurveyResponse, + GetQuizRequest, + GetQuizResponse, + MissionQuiz, + WriteDiaryRequest, + WriteDiaryResponse, +} from "@/types/missions"; + +export const useWriteDiaryImageUpload = () => + useMutation({ + mutationFn: formData => uploadDiaryImageApi(formData), + }); + +export const useWriteDiarySubmit = () => + useMutation({ + mutationFn: payload => writeDiaryApi(payload), + }); + +export const useMissionQuiz = (params: GetQuizRequest) => + useQuery({ + queryKey: ["mission-quiz", params.quizType], + queryFn: () => getQuizApi(params), + select: data => data.result, + }); + +export const useAnswerQuiz = () => + useMutation({ + mutationFn: payload => answerQuizApi(payload), + }); + +export const useDailySurvey = () => + useQuery({ + queryKey: ["daily-survey"], + queryFn: getDailySurveyApi, + select: data => data.result, + }); + +export const useAnswerDailySurvey = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: payload => answerDailySurveyApi(payload), + onSuccess: async () => { + await queryClient.invalidateQueries({ queryKey: ["daily-survey"] }); + await queryClient.invalidateQueries({ queryKey: ["home-summary"] }); + await queryClient.refetchQueries({ queryKey: ["daily-survey"], type: "all" }); + await queryClient.refetchQueries({ queryKey: ["home-summary"], type: "all" }); + }, + }); +}; diff --git a/src/hooks/profile/useProfileApi.ts b/src/hooks/profile/useProfileApi.ts new file mode 100644 index 0000000..1f6e99d --- /dev/null +++ b/src/hooks/profile/useProfileApi.ts @@ -0,0 +1,26 @@ +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { + getUserProfile, + postFriendWater, +} from "@/apis/profile/profileApi"; +import type { GetUserProfileResponse } from "@/types/profile/profileApi.type"; + +export const useUserProfile = (userId: string | number | undefined) => + useQuery<{ result: GetUserProfileResponse }, unknown, GetUserProfileResponse>({ + queryKey: ["profile", userId], + queryFn: () => getUserProfile(String(userId)), + select: data => data.result, + enabled: !!userId, + refetchOnMount: "always", + }); + +export const useFriendWater = (userId: string | number | undefined) => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: (gardenId: number) => postFriendWater(gardenId), + onSuccess: async () => { + await queryClient.invalidateQueries({ queryKey: ["profile", userId] }); + }, + }); +}; diff --git a/src/hooks/register/useRegisterApi.ts b/src/hooks/register/useRegisterApi.ts index b64a060..18e7e1b 100644 --- a/src/hooks/register/useRegisterApi.ts +++ b/src/hooks/register/useRegisterApi.ts @@ -7,7 +7,7 @@ import { registerApi } from "@/apis/register/registerApi"; // useRegisterApi는 TanStack Query의 useMutation을 정의해서 반환 export const useRegisterApi = () => { - const { setAccessToken, setRefreshToken, setUserId } = useTokenStore(); + const { setAuth } = useTokenStore(); const postRegisterMutation = useMutation< GlobalResponse, @@ -16,9 +16,11 @@ export const useRegisterApi = () => { >({ mutationFn: (nickname: string) => registerApi(nickname), onSuccess: res => { - setAccessToken(res.result.accessToken); - setRefreshToken(res.result.refreshToken); - setUserId(String(res.result.userId)); + setAuth({ + accessToken: res.result.accessToken, + refreshToken: res.result.refreshToken, + userId: String(res.result.userId), + }); }, }); diff --git a/src/navigation/RootNavigator.tsx b/src/navigation/RootNavigator.tsx index c8563a6..c516554 100644 --- a/src/navigation/RootNavigator.tsx +++ b/src/navigation/RootNavigator.tsx @@ -1,132 +1,78 @@ import { createNativeStackNavigator } from "@react-navigation/native-stack"; import type { RootStackParamList } from "./types"; +import useTokenStore from "@/stores/useTokenStore"; +import Splash from "@/components/common/Splash"; // 메인 탭 import MainTabNavigator from "./MainTabNavigator"; -// 플레이스홀더 (추후 실제 스크린으로 교체) -import PlaceholderScreen from "@/pages/placeholder/PlaceholderScreen"; - // 실제 스크린 import OnboardingScreen from "@/pages/onboarding/OnboardingScreen"; import RegisterScreen from "@/pages/register/RegisterScreen"; import FeedDiaryScreen from "@/pages/feed/FeedDiaryScreen"; import FeedAvatarScreen from "@/pages/feed/FeedAvatarScreen"; +import LogDetailScreen from "@/pages/log/LogDetailScreen"; +import ProfileScreen from "@/pages/profile/ProfileScreen"; +import FollowScreen from "@/pages/follow/FollowScreen"; +import DeliveryScreen from "@/pages/delivery/DeliveryScreen"; +import DeliveryCompleteScreen from "@/pages/delivery/DeliveryCompleteScreen"; +import UnlockGardenScreen from "@/pages/delivery/UnlockGardenScreen"; +import RegistrationAvatarScreen from "@/pages/registration/RegistrationAvatarScreen"; +import RegistrationCreationDetailScreen from "@/pages/registration/RegistrationCreationDetailScreen"; +import RegistrationSelectionDetailScreen from "@/pages/registration/RegistrationSelectionDetailScreen"; +import RegistrationPlantNicknameScreen from "@/pages/registration/RegistrationPlantNicknameScreen"; +import DailyMissionWriteDiaryScreen from "@/pages/dailyMission/DailyMissionWriteDiaryScreen"; +import DailyMissionQuizMultipleChoiceScreen from "@/pages/dailyMission/DailyMissionQuizMultipleChoiceScreen"; +import DailyMissionQuizOxScreen from "@/pages/dailyMission/DailyMissionQuizOxScreen"; +import DailyMissionCheckingScreen from "@/pages/dailyMission/DailyMissionCheckingScreen"; const Stack = createNativeStackNavigator(); -function ProfileScreen() { - return ; -} - -function FollowScreen() { - return ; -} - -function LogDetailScreen() { - return ; -} - -function DeliveryScreen() { - return ; -} - -function DeliveryCompleteScreen() { - return ; -} - -function UnlockGardenScreen() { - return ( - - ); -} - -// 등록 플로우 스크린들 -function RegistrationAvatarScreen() { - return ( - - ); -} - -function RegistrationCreationDetailScreen() { - return ( - - ); -} - -function RegistrationSelectionDetailScreen() { - return ( - - ); -} - -function RegistrationPlantNicknameScreen() { - return ( - - ); -} - -// 데일리 미션 스크린들 -function DailyMissionWriteDiaryScreen() { - return ; -} - -function DailyMissionQuizMultipleChoiceScreen() { - return ; -} +export default function RootNavigator() { + const { accessToken, hasHydrated } = useTokenStore(); + const isAuthenticated = Boolean(accessToken); -function DailyMissionQuizOxScreen() { - return ; -} + if (!hasHydrated) { + return ; + } -export default function RootNavigator() { return ( - {/* 메인 탭 네비게이터 */} - + {isAuthenticated ? ( + <> + + + ) : ( + <> + + + + )} - {/* 인증/온보딩 */} - - - - {/* 프로필 */} - - {/* 팔로우 */} - - {/* 피드 상세 */} - - {/* 로그 상세 */} - - {/* 배송 */} - - {/* 식물 등록 플로우 */} - - {/* 데일리 미션 */} + ); diff --git a/src/navigation/types.ts b/src/navigation/types.ts index 3f2cb34..0d29e56 100644 --- a/src/navigation/types.ts +++ b/src/navigation/types.ts @@ -30,8 +30,19 @@ export type RootStackParamList = { LogDetail: { id: number }; // 배송 - Delivery: undefined; - DeliveryComplete: undefined; + Delivery: + | { + seedType?: number; + seedName?: string; + gardenId?: number; + } + | undefined; + DeliveryComplete: + | { + seedName?: string; + gardenId?: number; + } + | undefined; UnlockGarden: undefined; // 식물 등록 플로우 @@ -44,6 +55,7 @@ export type RootStackParamList = { DailyMissionWriteDiary: undefined; DailyMissionQuizMultipleChoice: undefined; DailyMissionQuizOx: undefined; + DailyMissionChecking: undefined; }; /** diff --git a/src/pages/dailyMission/DailyMissionCheckingScreen.tsx b/src/pages/dailyMission/DailyMissionCheckingScreen.tsx new file mode 100644 index 0000000..eaa178c --- /dev/null +++ b/src/pages/dailyMission/DailyMissionCheckingScreen.tsx @@ -0,0 +1,243 @@ +import { useState } from "react"; +import { useQueryClient } from "@tanstack/react-query"; +import type { AxiosError } from "axios"; +import { ScrollView, StyleSheet, Text, View } from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; +import ScreenHeader from "@/components/common/ScreenHeader"; +import StatusView from "@/components/common/StatusView"; +import QuizOptionCard from "@/components/dailyMission/QuizOptionCard"; +import RegistrationFooter from "@/components/registration/RegistrationFooter"; +import { + useAnswerDailySurvey, + useDailySurvey, +} from "@/hooks/mission/useMissionApi"; +import type { RootStackScreenProps } from "@/navigation/types"; +import type { ErrorResponse } from "@/types/common/apiResponse.type"; +import { + SURVEY_ANSWER_VALUE_MAP, + type SurveyAnswerKind, +} from "@/types/missions"; + +type Props = RootStackScreenProps<"DailyMissionChecking">; + +type SurveyOption = { + kind: SurveyAnswerKind; + label: string; + description: string; +}; + +const SURVEY_OPTIONS: SurveyOption[] = [ + { kind: "YES", label: "네", description: "YES" }, + { kind: "NEUTRAL", label: "그저 그래요", description: "NEUTRAL" }, + { kind: "NO", label: "아니요", description: "NO" }, +]; + +export default function DailyMissionCheckingScreen({ navigation }: Props) { + const queryClient = useQueryClient(); + const [selected, setSelected] = useState(null); + const [answeredLocally, setAnsweredLocally] = useState(false); + const [submitErrorMessage, setSubmitErrorMessage] = useState(null); + const { data, isLoading, isError, refetch } = useDailySurvey(); + const answerSurvey = useAnswerDailySurvey(); + + const goHome = () => + navigation.reset({ + index: 0, + routes: [{ name: "Main", params: { screen: "Home" } }], + }); + + const handleSubmit = async () => { + if (!data?.id || !selected || answerSurvey.isPending || data.isAnswered || answeredLocally) { + return; + } + + setSubmitErrorMessage(null); + + try { + await answerSurvey.mutateAsync({ + questionId: data.id, + answer: SURVEY_ANSWER_VALUE_MAP[selected], + }); + + await queryClient.refetchQueries({ queryKey: ["daily-survey"], type: "all" }); + await queryClient.refetchQueries({ queryKey: ["home-summary"], type: "all" }); + setAnsweredLocally(true); + } catch (error) { + const axiosError = error as AxiosError; + const status = axiosError.response?.status; + const serverMessage = axiosError.response?.data?.message; + + if (status === 409) { + setAnsweredLocally(true); + setSubmitErrorMessage("이미 오늘의 질문에 답변했습니다. 홈으로 돌아가 완료 상태를 확인해주세요."); + await queryClient.refetchQueries({ queryKey: ["daily-survey"], type: "all" }); + await queryClient.refetchQueries({ queryKey: ["home-summary"], type: "all" }); + return; + } + + setSubmitErrorMessage(serverMessage ?? "답변 저장에 실패했습니다. 잠시 후 다시 시도해주세요."); + } + }; + + if (isLoading) { + return ( + + navigation.goBack()} /> + + + ); + } + + if (isError) { + return ( + + navigation.goBack()} /> + void refetch()} + /> + + ); + } + + if (!data) { + return ( + + navigation.goBack()} /> + + + ); + } + + const isAnswered = data.isAnswered || answeredLocally || answerSurvey.isSuccess; + + return ( + + navigation.goBack()} /> + + + 오늘의 체크인 + {data.question} + + 하루에 한 번만 답할 수 있고, 답변 완료 시 홈 미션 상태가 갱신됩니다. + + + + + {SURVEY_OPTIONS.map(option => ( + + setSelected(option.kind)} + /> + {option.description} + + ))} + + + {isAnswered ? ( + + 오늘의 질문에 이미 답변했습니다. + + 중복 저장은 막혀 있으며, 홈으로 돌아가면 완료 상태를 볼 수 있습니다. + + + ) : null} + + {submitErrorMessage ? ( + + 답변 저장 안내 + {submitErrorMessage} + + ) : null} + + + void handleSubmit()} + primaryDisabled={(!selected && !isAnswered) || answerSurvey.isPending} + primaryLoading={answerSurvey.isPending} + /> + + ); +} + +const styles = StyleSheet.create({ + safeArea: { + flex: 1, + backgroundColor: "#F7F8F4", + }, + content: { + padding: 20, + gap: 18, + }, + headerBlock: { + gap: 8, + }, + eyebrow: { + fontSize: 12, + color: "#2F7D32", + fontWeight: "700", + }, + question: { + fontSize: 24, + lineHeight: 32, + fontWeight: "700", + color: "#171717", + }, + subtitle: { + fontSize: 14, + lineHeight: 20, + color: "#6B7280", + }, + options: { + gap: 12, + }, + optionBlock: { + gap: 6, + }, + optionDescription: { + fontSize: 12, + color: "#6B7280", + paddingHorizontal: 4, + }, + successCard: { + borderRadius: 16, + padding: 16, + backgroundColor: "#EDF7ED", + gap: 6, + }, + successTitle: { + fontSize: 16, + fontWeight: "700", + color: "#1F5C27", + }, + successDescription: { + fontSize: 14, + lineHeight: 20, + color: "#2F5D3B", + }, + errorCard: { + borderRadius: 16, + padding: 16, + backgroundColor: "#FEF2F2", + gap: 6, + }, + errorTitle: { + fontSize: 16, + fontWeight: "700", + color: "#B91C1C", + }, + errorDescription: { + fontSize: 14, + lineHeight: 20, + color: "#7F1D1D", + }, +}); diff --git a/src/pages/dailyMission/DailyMissionQuizMultipleChoiceScreen.tsx b/src/pages/dailyMission/DailyMissionQuizMultipleChoiceScreen.tsx new file mode 100644 index 0000000..bf282d8 --- /dev/null +++ b/src/pages/dailyMission/DailyMissionQuizMultipleChoiceScreen.tsx @@ -0,0 +1,188 @@ +import { useState } from "react"; +import { ScrollView, StyleSheet, Text, View } from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; +import ScreenHeader from "@/components/common/ScreenHeader"; +import StatusView from "@/components/common/StatusView"; +import QuizOptionCard from "@/components/dailyMission/QuizOptionCard"; +import QuizResultCard from "@/components/dailyMission/QuizResultCard"; +import RegistrationFooter from "@/components/registration/RegistrationFooter"; +import { useAnswerQuiz, useMissionQuiz } from "@/hooks/mission/useMissionApi"; +import type { RootStackScreenProps } from "@/navigation/types"; + +type Props = RootStackScreenProps<"DailyMissionQuizMultipleChoice">; + +export default function DailyMissionQuizMultipleChoiceScreen({ + navigation, +}: Props) { + const [selected, setSelected] = useState(null); + const { data, isLoading, isError, refetch } = useMissionQuiz({ + quizType: "MULTI_CHOICE", + }); + const submitAnswer = useAnswerQuiz(); + + const handleSubmit = async () => { + if (!data?.quizId || selected === null || submitAnswer.isPending) { + return; + } + + await submitAnswer.mutateAsync({ + quizId: data.quizId, + selectedOptionOrder: selected, + }); + }; + + if (isLoading) { + return ( + + navigation.goBack()} /> + + + ); + } + + if (isError) { + return ( + + navigation.goBack()} /> + void refetch()} + /> + + ); + } + + if (!data) { + return ( + + navigation.goBack()} /> + + + ); + } + + const answerResult = submitAnswer.data?.result; + + return ( + + navigation.goBack()} /> + + + 오늘의 퀴즈 + {data.quizQuestion} + + + + {data.quizOptions?.map(option => { + const state = + answerResult != null + ? answerResult.isCorrect + ? option.optionOrder === answerResult.answerNumber + ? "correct" + : "idle" + : selected === option.optionOrder + ? "wrong" + : option.optionOrder === answerResult.answerNumber + ? "answer" + : "idle" + : "idle"; + + return ( + setSelected(option.optionOrder)} + /> + ); + })} + + + {answerResult ? ( + + ) : null} + + {submitAnswer.isError ? ( + + 정답 제출에 실패했습니다. + + `POST /api/v1/realQuiz/{'{quizId}'}/answer` 응답을 다시 확인해야 합니다. + + + ) : null} + + + + navigation.reset({ + index: 0, + routes: [{ name: "Main", params: { screen: "Home" } }], + }) + } + primaryLabel={answerResult ? "다음" : "정답 확인하기"} + onPrimaryPress={ + answerResult + ? () => + navigation.reset({ + index: 0, + routes: [{ name: "Main", params: { screen: "Home" } }], + }) + : () => void handleSubmit() + } + primaryDisabled={selected === null || submitAnswer.isPending} + primaryLoading={submitAnswer.isPending} + /> + + ); +} + +const styles = StyleSheet.create({ + safeArea: { + flex: 1, + backgroundColor: "#F7F8F4", + }, + content: { + padding: 20, + gap: 18, + }, + headerBlock: { + gap: 8, + }, + eyebrow: { + fontSize: 12, + color: "#2F7D32", + fontWeight: "700", + }, + question: { + fontSize: 24, + lineHeight: 32, + fontWeight: "700", + color: "#171717", + }, + options: { + gap: 12, + }, + errorCard: { + borderRadius: 16, + padding: 16, + backgroundColor: "#FEF2F2", + gap: 6, + }, + errorTitle: { + fontSize: 16, + fontWeight: "700", + color: "#B91C1C", + }, + errorDescription: { + fontSize: 14, + lineHeight: 20, + color: "#7F1D1D", + }, +}); diff --git a/src/pages/dailyMission/DailyMissionQuizOxScreen.tsx b/src/pages/dailyMission/DailyMissionQuizOxScreen.tsx new file mode 100644 index 0000000..7316fe8 --- /dev/null +++ b/src/pages/dailyMission/DailyMissionQuizOxScreen.tsx @@ -0,0 +1,194 @@ +import { useMemo, useState } from "react"; +import { ScrollView, StyleSheet, Text, View } from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; +import ScreenHeader from "@/components/common/ScreenHeader"; +import StatusView from "@/components/common/StatusView"; +import QuizOptionCard from "@/components/dailyMission/QuizOptionCard"; +import QuizResultCard from "@/components/dailyMission/QuizResultCard"; +import RegistrationFooter from "@/components/registration/RegistrationFooter"; +import { useAnswerQuiz, useMissionQuiz } from "@/hooks/mission/useMissionApi"; +import type { RootStackScreenProps } from "@/navigation/types"; + +type Props = RootStackScreenProps<"DailyMissionQuizOx">; + +export default function DailyMissionQuizOxScreen({ navigation }: Props) { + const [selected, setSelected] = useState(null); + const { data, isLoading, isError, refetch } = useMissionQuiz({ + quizType: "OX", + }); + const submitAnswer = useAnswerQuiz(); + + const options = useMemo( + () => [ + { optionOrder: 0, optionText: "O" }, + { optionOrder: 1, optionText: "X" }, + ], + [] + ); + + const handleSubmit = async () => { + if (!data?.quizId || selected === null || submitAnswer.isPending) { + return; + } + + await submitAnswer.mutateAsync({ + quizId: data.quizId, + selectedOptionOrder: selected, + }); + }; + + if (isLoading) { + return ( + + navigation.goBack()} /> + + + ); + } + + if (isError) { + return ( + + navigation.goBack()} /> + void refetch()} + /> + + ); + } + + if (!data) { + return ( + + navigation.goBack()} /> + + + ); + } + + const answerResult = submitAnswer.data?.result; + + return ( + + navigation.goBack()} /> + + + 오늘의 퀴즈 + {data.quizQuestion} + + + + {options.map(option => { + const state = + answerResult != null + ? answerResult.isCorrect + ? option.optionOrder === answerResult.answerNumber + ? "correct" + : "idle" + : selected === option.optionOrder + ? "wrong" + : option.optionOrder === answerResult.answerNumber + ? "answer" + : "idle" + : "idle"; + + return ( + setSelected(option.optionOrder)} + /> + ); + })} + + + {answerResult ? ( + + ) : null} + + {submitAnswer.isError ? ( + + 정답 제출에 실패했습니다. + + OX 퀴즈도 객관식과 같은 답안 API를 사용합니다. 서버 응답 계약을 다시 확인해야 합니다. + + + ) : null} + + + + navigation.reset({ + index: 0, + routes: [{ name: "Main", params: { screen: "Home" } }], + }) + } + primaryLabel={answerResult ? "다음" : "정답 확인하기"} + onPrimaryPress={ + answerResult + ? () => + navigation.reset({ + index: 0, + routes: [{ name: "Main", params: { screen: "Home" } }], + }) + : () => void handleSubmit() + } + primaryDisabled={selected === null || submitAnswer.isPending} + primaryLoading={submitAnswer.isPending} + /> + + ); +} + +const styles = StyleSheet.create({ + safeArea: { + flex: 1, + backgroundColor: "#F7F8F4", + }, + content: { + padding: 20, + gap: 18, + }, + headerBlock: { + gap: 8, + }, + eyebrow: { + fontSize: 12, + color: "#2F7D32", + fontWeight: "700", + }, + question: { + fontSize: 24, + lineHeight: 32, + fontWeight: "700", + color: "#171717", + }, + options: { + gap: 12, + }, + errorCard: { + borderRadius: 16, + padding: 16, + backgroundColor: "#FEF2F2", + gap: 6, + }, + errorTitle: { + fontSize: 16, + fontWeight: "700", + color: "#B91C1C", + }, + errorDescription: { + fontSize: 14, + lineHeight: 20, + color: "#7F1D1D", + }, +}); diff --git a/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx b/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx new file mode 100644 index 0000000..6a48f30 --- /dev/null +++ b/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx @@ -0,0 +1,218 @@ +import { useState } from "react"; +import { ScrollView, StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; +import ScreenHeader from "@/components/common/ScreenHeader"; +import StatusView from "@/components/common/StatusView"; +import ImageAttachmentCard from "@/components/dailyMission/ImageAttachmentCard"; +import RegistrationFooter from "@/components/registration/RegistrationFooter"; +import RegistrationTextField from "@/components/registration/RegistrationTextField"; +import { useWriteDiarySubmit } from "@/hooks/mission/useMissionApi"; +import type { RootStackScreenProps } from "@/navigation/types"; + +type Props = RootStackScreenProps<"DailyMissionWriteDiary">; + +export default function DailyMissionWriteDiaryScreen({ navigation }: Props) { + const [title, setTitle] = useState(""); + const [content, setContent] = useState(""); + const [isPublic, setIsPublic] = useState(false); + const [imageNoticeVisible, setImageNoticeVisible] = useState(false); + const submitDiary = useWriteDiarySubmit(); + + const handleSubmit = async () => { + if (!title.trim() || !content.trim()) { + return; + } + + // Image picker dependency is not available in the current app. + // Keep the API interface wired but block the actual submit until an image upload path exists. + setImageNoticeVisible(true); + }; + + return ( + + + navigation.reset({ + index: 0, + routes: [{ name: "Main", params: { screen: "Home" } }], + }) + } + /> + + + + 오늘의 식물 이야기를 적어주세요. + + 텍스트 입력과 공개 여부 구조는 구현했고, 이미지 선택은 라이브러리 확정 후 연결합니다. + + + + + + + setImageNoticeVisible(true)} + helperText="`POST /api/v1/diaries/images` 인터페이스는 추가했지만, 현재 프로젝트에는 이미지 선택 라이브러리가 없습니다." + /> + + + 공개 설정 + + setIsPublic(false)} + > + + 비공개 + + + setIsPublic(true)} + > + + 공개 + + + + + + {imageNoticeVisible ? ( + + ) : null} + + {submitDiary.isError ? ( + + 일기 저장에 실패했습니다. + + 현재는 이미지 업로드 경로가 없어 실제 제출까지 이어지지 않습니다. + + + ) : null} + + + + navigation.reset({ + index: 0, + routes: [{ name: "Main", params: { screen: "Home" } }], + }) + } + primaryLabel="제출하기" + onPrimaryPress={() => void handleSubmit()} + primaryDisabled={!title.trim() || !content.trim() || submitDiary.isPending} + primaryLoading={submitDiary.isPending} + /> + + ); +} + +const styles = StyleSheet.create({ + safeArea: { + flex: 1, + backgroundColor: "#F7F8F4", + }, + content: { + padding: 20, + gap: 18, + }, + headerBlock: { + gap: 8, + }, + title: { + fontSize: 24, + lineHeight: 32, + fontWeight: "700", + color: "#171717", + }, + subtitle: { + fontSize: 14, + lineHeight: 20, + color: "#6B7280", + }, + visibilityCard: { + borderRadius: 16, + padding: 16, + backgroundColor: "#FFFFFF", + gap: 12, + }, + visibilityTitle: { + fontSize: 14, + fontWeight: "700", + color: "#171717", + }, + visibilityButtons: { + flexDirection: "row", + gap: 10, + }, + visibilityButton: { + flex: 1, + minHeight: 44, + borderRadius: 12, + borderWidth: 1, + borderColor: "#D1D5DB", + alignItems: "center", + justifyContent: "center", + backgroundColor: "#FFFFFF", + }, + visibilityButtonActive: { + borderColor: "#2F7D32", + backgroundColor: "#EDF7ED", + }, + visibilityButtonText: { + fontSize: 14, + fontWeight: "700", + color: "#4B5563", + }, + visibilityButtonTextActive: { + color: "#1F5C27", + }, + errorCard: { + borderRadius: 16, + padding: 16, + backgroundColor: "#FEF2F2", + gap: 6, + }, + errorTitle: { + fontSize: 16, + fontWeight: "700", + color: "#B91C1C", + }, + errorDescription: { + fontSize: 14, + lineHeight: 20, + color: "#7F1D1D", + }, +}); diff --git a/src/pages/delivery/DeliveryCompleteScreen.tsx b/src/pages/delivery/DeliveryCompleteScreen.tsx new file mode 100644 index 0000000..d1fd7bc --- /dev/null +++ b/src/pages/delivery/DeliveryCompleteScreen.tsx @@ -0,0 +1,124 @@ +import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; +import ScreenHeader from "@/components/common/ScreenHeader"; +import type { RootStackScreenProps } from "@/navigation/types"; + +type Props = RootStackScreenProps<"DeliveryComplete">; + +export default function DeliveryCompleteScreen({ navigation, route }: Props) { + const handleDone = () => { + navigation.reset({ + index: 0, + routes: [{ name: "Main", params: { screen: "Home" } }], + }); + }; + + return ( + + + + + Step 3 / 3 + + 배송 요청이 완료되었어요. + + {route.params?.seedName + ? `${route.params.seedName} 배송 요청이 접수되었습니다.` + : "선택한 식물의 배송 요청이 접수되었습니다."} + + + 웹 기준 메시지처럼 3~7일 내 배송 안내를 노출했고, 이후 홈으로 돌아가서 정원 확장 흐름을 이어갈 수 있게 구성했습니다. + + + + 다음에 이어질 흐름 + + 정원 unlock 완료 처리와 배송 상태 추적은 서버 계약 확인 후 다음 단계에서 보강할 수 있습니다. + + + + + + + 홈으로 돌아가기 + + + + ); +} + +const styles = StyleSheet.create({ + safeArea: { + flex: 1, + backgroundColor: "#F7F8F4", + }, + content: { + flex: 1, + padding: 24, + justifyContent: "center", + gap: 18, + }, + badge: { + alignSelf: "flex-start", + borderRadius: 999, + backgroundColor: "#DDF3DE", + paddingHorizontal: 12, + paddingVertical: 6, + }, + badgeText: { + fontSize: 12, + fontWeight: "700", + color: "#1F5C27", + }, + title: { + fontSize: 28, + lineHeight: 36, + fontWeight: "700", + color: "#171717", + }, + description: { + fontSize: 15, + lineHeight: 24, + color: "#4B5563", + }, + messageCard: { + borderRadius: 20, + padding: 18, + backgroundColor: "#FFFFFF", + gap: 8, + }, + cardTitle: { + fontSize: 16, + fontWeight: "700", + color: "#171717", + }, + cardText: { + fontSize: 14, + lineHeight: 20, + color: "#4B5563", + }, + footer: { + paddingHorizontal: 24, + paddingBottom: 20, + paddingTop: 12, + borderTopWidth: 1, + borderTopColor: "#E5E7EB", + backgroundColor: "#FFFFFF", + }, + primaryButton: { + alignItems: "center", + justifyContent: "center", + minHeight: 54, + borderRadius: 16, + backgroundColor: "#2F7D32", + }, + primaryButtonText: { + fontSize: 15, + fontWeight: "700", + color: "#FFFFFF", + }, +}); diff --git a/src/pages/delivery/DeliveryScreen.tsx b/src/pages/delivery/DeliveryScreen.tsx new file mode 100644 index 0000000..1a2fb25 --- /dev/null +++ b/src/pages/delivery/DeliveryScreen.tsx @@ -0,0 +1,310 @@ +import { useMemo, useState } from "react"; +import { + ScrollView, + StyleSheet, + Text, + TouchableOpacity, + View, +} from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; +import ScreenHeader from "@/components/common/ScreenHeader"; +import StatusView from "@/components/common/StatusView"; +import DeliveryRequestSelector from "@/components/delivery/DeliveryRequestSelector"; +import DeliveryTextField from "@/components/delivery/DeliveryTextField"; +import { useCreateSeedDelivery } from "@/hooks/delivery/useDeliveryApi"; +import type { RootStackScreenProps } from "@/navigation/types"; +import { useHomeSummaryStore } from "@/stores/useHomeSummaryStore"; + +type Props = RootStackScreenProps<"Delivery">; + +export default function DeliveryScreen({ navigation, route }: Props) { + const user = useHomeSummaryStore(state => state.user); + const createSeedDelivery = useCreateSeedDelivery(); + + const [recipientName, setRecipientName] = useState(user?.username ?? ""); + const [recipientPhone, setRecipientPhone] = useState(""); + const [postalCode, setPostalCode] = useState(""); + const [address, setAddress] = useState(""); + const [addressDetail, setAddressDetail] = useState(""); + const [message, setMessage] = useState(""); + const [customMessage, setCustomMessage] = useState(""); + + const seedType = route.params?.seedType; + const seedName = route.params?.seedName; + const resolvedMessage = message === "직접 입력" ? customMessage.trim() : message; + + const isFormValid = useMemo( + () => + Boolean( + seedType && + recipientName.trim() && + recipientPhone.trim() && + postalCode.trim() && + address.trim() && + addressDetail.trim() + ), + [address, addressDetail, postalCode, recipientName, recipientPhone, seedType] + ); + + const handleBack = () => { + if (navigation.canGoBack()) { + navigation.goBack(); + return; + } + + navigation.navigate("UnlockGarden"); + }; + + const handleSubmit = async () => { + if (!seedType || !isFormValid || createSeedDelivery.isPending) { + return; + } + + try { + await createSeedDelivery.mutateAsync({ + seedType, + recipientName: recipientName.trim(), + recipientPhone: recipientPhone.trim(), + postalCode: postalCode.trim(), + address: address.trim(), + addressDetail: addressDetail.trim(), + message: resolvedMessage, + }); + + navigation.replace("DeliveryComplete", { + seedName, + gardenId: route.params?.gardenId, + }); + } catch { + // Error state is rendered below through mutation state. + } + }; + + if (!seedType) { + return ( + + + navigation.replace("UnlockGarden")} + /> + + ); + } + + return ( + + + + + Step 2 / 3 + 배송 받을 정보를 입력해주세요. + + 선택한 식물: {seedName ?? `씨앗 타입 #${seedType}`} + + + + + 받는 분 정보 + + + + + + 주소 정보 + + + + + + + + {createSeedDelivery.isError ? ( + + 배송 요청을 완료하지 못했습니다. + + `POST /api/v1/deliveries/seeds` 호출에 실패했습니다. 요청 필드 계약과 서버 상태를 다시 확인해야 합니다. + + + ) : null} + + + 현재 연결된 범위 + + 배송 신청은 MainFE에서 확인된 payload 구조만 사용합니다. 주소 검색, 배송 조회, 수정 기능은 이번 단계 범위 밖입니다. + + + + + + + 이전 + + void handleSubmit()} + > + + {createSeedDelivery.isPending ? "전송 중..." : "배송 요청 완료"} + + + + + ); +} + +const styles = StyleSheet.create({ + safeArea: { + flex: 1, + backgroundColor: "#F7F8F4", + }, + content: { + padding: 20, + gap: 20, + }, + heroCard: { + borderRadius: 22, + padding: 20, + backgroundColor: "#255137", + gap: 8, + }, + eyebrow: { + fontSize: 12, + color: "#D7E9D8", + }, + heroTitle: { + fontSize: 24, + lineHeight: 32, + fontWeight: "700", + color: "#FFFFFF", + }, + heroDescription: { + fontSize: 14, + lineHeight: 20, + color: "#E5F4E5", + }, + section: { + gap: 12, + }, + sectionTitle: { + fontSize: 18, + fontWeight: "700", + color: "#171717", + }, + errorCard: { + borderRadius: 18, + padding: 16, + backgroundColor: "#FEF2F2", + gap: 6, + }, + errorTitle: { + fontSize: 16, + fontWeight: "700", + color: "#B91C1C", + }, + errorDescription: { + fontSize: 14, + lineHeight: 20, + color: "#7F1D1D", + }, + infoCard: { + borderRadius: 18, + padding: 16, + backgroundColor: "#EEF3EA", + gap: 8, + }, + infoTitle: { + fontSize: 16, + fontWeight: "700", + color: "#171717", + }, + infoDescription: { + fontSize: 14, + lineHeight: 20, + color: "#4B5563", + }, + footer: { + flexDirection: "row", + gap: 12, + paddingHorizontal: 20, + paddingVertical: 16, + borderTopWidth: 1, + borderTopColor: "#E5E7EB", + backgroundColor: "#FFFFFF", + }, + secondaryButton: { + flex: 1, + alignItems: "center", + justifyContent: "center", + minHeight: 52, + borderRadius: 16, + backgroundColor: "#E5E7EB", + }, + secondaryButtonText: { + fontSize: 15, + fontWeight: "700", + color: "#374151", + }, + primaryButton: { + flex: 1, + alignItems: "center", + justifyContent: "center", + minHeight: 52, + borderRadius: 16, + backgroundColor: "#2F7D32", + }, + primaryButtonDisabled: { + backgroundColor: "#A7D4A5", + }, + primaryButtonText: { + fontSize: 15, + fontWeight: "700", + color: "#FFFFFF", + }, +}); diff --git a/src/pages/delivery/UnlockGardenScreen.tsx b/src/pages/delivery/UnlockGardenScreen.tsx new file mode 100644 index 0000000..7e0ccdc --- /dev/null +++ b/src/pages/delivery/UnlockGardenScreen.tsx @@ -0,0 +1,356 @@ +import { useEffect, useMemo, useState } from "react"; +import { + Alert, + ScrollView, + StyleSheet, + Text, + TouchableOpacity, + View, +} from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; +import ScreenHeader from "@/components/common/ScreenHeader"; +import StatusView from "@/components/common/StatusView"; +import GardenSlotCard from "@/components/delivery/GardenSlotCard"; +import PlantOptionCard from "@/components/delivery/PlantOptionCard"; +import { useDeliverablePlants, useUnlockGarden } from "@/hooks/delivery/useDeliveryApi"; +import useHomeApi from "@/hooks/home/useHomeApi"; +import type { RootStackScreenProps } from "@/navigation/types"; +import { useHomeSummaryStore } from "@/stores/useHomeSummaryStore"; +import { getGardenLocked, getGardenUnlockable } from "@/types/home/garden"; + +type Props = RootStackScreenProps<"UnlockGarden">; + +export default function UnlockGardenScreen({ navigation }: Props) { + const { + data: homeData, + refetch: refetchHome, + } = useHomeApi(); + const { + data: plants, + error, + isLoading, + refetch, + } = useDeliverablePlants(); + const unlockGarden = useUnlockGarden(); + const { gardens, hydrate } = useHomeSummaryStore(); + const [selectedSeedType, setSelectedSeedType] = useState(null); + const [selectedGardenId, setSelectedGardenId] = useState(null); + + useEffect(() => { + if (homeData) { + hydrate(homeData); + } + }, [homeData, hydrate]); + + const lockedGardens = useMemo( + () => gardens.filter(garden => getGardenLocked(garden)), + [gardens] + ); + + useEffect(() => { + if (!selectedGardenId && lockedGardens.length > 0) { + const initialGarden = + lockedGardens.find(garden => getGardenUnlockable(garden)) ?? lockedGardens[0]; + setSelectedGardenId(initialGarden.gardenId); + } + }, [lockedGardens, selectedGardenId]); + + useEffect(() => { + if (!selectedSeedType && plants && plants.length > 0) { + setSelectedSeedType(plants[0].seedType); + } + }, [plants, selectedSeedType]); + + const selectedPlant = + plants?.find(plant => plant.seedType === selectedSeedType) ?? null; + const selectedGarden = + lockedGardens.find(garden => garden.gardenId === selectedGardenId) ?? null; + const canUnlock = Boolean(selectedGarden && getGardenUnlockable(selectedGarden)); + + const handleBack = () => { + if (navigation.canGoBack()) { + navigation.goBack(); + return; + } + + navigation.navigate("Main", { screen: "Home" }); + }; + + const handleUnlock = async () => { + if (!canUnlock || unlockGarden.isPending) { + return; + } + + try { + await unlockGarden.mutateAsync(); + await refetchHome(); + Alert.alert("정원 해금 완료", "홈에서 변경된 정원 상태를 확인할 수 있습니다.", [ + { + text: "홈으로 이동", + onPress: () => navigation.navigate("Main", { screen: "Home" }), + }, + ]); + } catch (unlockError) { + const message = + unlockError instanceof Error + ? unlockError.message + : "정원 해금 중 오류가 발생했습니다."; + Alert.alert("정원 해금 실패", message); + } + }; + + if (isLoading) { + return ( + + + + + ); + } + + if (error) { + return ( + + + void refetch()} + /> + + ); + } + + if (!plants || plants.length === 0) { + return ( + + + + + ); + } + + return ( + + + + + 정원 해금 + + 해금 가능한 슬롯을 선택하고 정원을 열어주세요. + + + 정원 해금은 `POST /api/v1/gardens/unlock`를 body 없이 호출하고, 성공 후 홈 데이터를 다시 조회합니다. + + + + + 잠금 슬롯 상태 + + 홈 summary에 내려온 `isLocked`, `isUnlockable` 상태를 기준으로 표시합니다. + + {lockedGardens.length > 0 ? ( + lockedGardens.map(garden => ( + setSelectedGardenId(garden.gardenId)} + /> + )) + ) : ( + + 잠금된 정원 슬롯이 없습니다. + + 홈 summary에 잠금 슬롯이 내려오면 이 화면에서 바로 확인할 수 있습니다. + + + )} + + + + 배송 받을 식물 + + 배송은 정원 해금과 독립적인 흐름이라, 필요할 때만 별도로 진행합니다. + + + {plants.map(plant => ( + setSelectedSeedType(plant.seedType)} + /> + ))} + + + + {unlockGarden.isError ? ( + + 정원 해금에 실패했습니다. + + 서버 공통 에러 응답을 확인한 뒤 다시 시도해주세요. + + + ) : null} + + + + + navigation.navigate("Delivery", { + seedType: selectedPlant?.seedType, + seedName: selectedPlant?.name, + gardenId: selectedGardenId ?? undefined, + }) + } + disabled={!selectedPlant} + > + 배송 정보 입력 + + void handleUnlock()} + > + + {unlockGarden.isPending ? "해금 중..." : "정원 해금하기"} + + + + + ); +} + +const styles = StyleSheet.create({ + safeArea: { + flex: 1, + backgroundColor: "#F7F8F4", + }, + content: { + padding: 20, + gap: 20, + }, + heroCard: { + borderRadius: 22, + padding: 20, + backgroundColor: "#234A2F", + gap: 8, + }, + eyebrow: { + fontSize: 12, + color: "#D7E9D8", + }, + heroTitle: { + fontSize: 24, + lineHeight: 32, + fontWeight: "700", + color: "#FFFFFF", + }, + heroDescription: { + fontSize: 14, + lineHeight: 20, + color: "#E5F4E5", + }, + section: { + gap: 10, + }, + sectionTitle: { + fontSize: 18, + fontWeight: "700", + color: "#171717", + }, + sectionDescription: { + fontSize: 13, + lineHeight: 18, + color: "#6B7280", + }, + horizontalList: { + gap: 12, + paddingRight: 20, + }, + infoCard: { + borderRadius: 18, + padding: 16, + backgroundColor: "#EEF3EA", + gap: 8, + }, + infoTitle: { + fontSize: 16, + fontWeight: "700", + color: "#171717", + }, + infoDescription: { + fontSize: 14, + lineHeight: 20, + color: "#4B5563", + }, + errorCard: { + borderRadius: 18, + padding: 16, + backgroundColor: "#FEF2F2", + gap: 6, + }, + errorTitle: { + fontSize: 16, + fontWeight: "700", + color: "#B91C1C", + }, + errorDescription: { + fontSize: 14, + lineHeight: 20, + color: "#7F1D1D", + }, + footer: { + flexDirection: "row", + gap: 12, + paddingHorizontal: 20, + paddingVertical: 16, + borderTopWidth: 1, + borderTopColor: "#E5E7EB", + backgroundColor: "#FFFFFF", + }, + secondaryButton: { + flex: 1, + alignItems: "center", + justifyContent: "center", + minHeight: 52, + borderRadius: 16, + backgroundColor: "#E5E7EB", + }, + secondaryButtonText: { + fontSize: 15, + fontWeight: "700", + color: "#374151", + }, + primaryButton: { + flex: 1, + alignItems: "center", + justifyContent: "center", + minHeight: 52, + borderRadius: 16, + backgroundColor: "#2F7D32", + }, + primaryButtonDisabled: { + backgroundColor: "#A7D4A5", + }, + primaryButtonText: { + fontSize: 15, + fontWeight: "700", + color: "#FFFFFF", + }, +}); diff --git a/src/pages/feed/FeedAvatarScreen.tsx b/src/pages/feed/FeedAvatarScreen.tsx index f634ae1..dfb7fe6 100644 --- a/src/pages/feed/FeedAvatarScreen.tsx +++ b/src/pages/feed/FeedAvatarScreen.tsx @@ -1,18 +1,15 @@ -import React, { useState } from "react"; +import { useState } from "react"; import { - View, - Text, - TextInput, - TouchableOpacity, - ScrollView, KeyboardAvoidingView, Platform, + ScrollView, StyleSheet, } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; import type { RootStackScreenProps } from "@/navigation/types"; - -import { LeftIcon, SendIcon } from "@/assets/icons/CommonIcons"; +import CommentComposer from "@/components/common/CommentComposer"; +import ScreenHeader from "@/components/common/ScreenHeader"; +import StatusView from "@/components/common/StatusView"; import FeedDetail from "@/components/feed/FeedDetail"; import usePostComment from "@/hooks/comments/useCommentApi"; import { useAvatarPostDetail } from "@/hooks/feed/useAvatarPostDetailApi"; @@ -25,33 +22,82 @@ export default function FeedAvatarScreen({ navigation, route }: Props) { const id = Number(postId); const isValidId = Number.isFinite(id) && id > 0; - const { data, refetch } = useAvatarPostDetail(isValidId ? id : 0); - + const { + data, + error, + isLoading, + refetch, + } = useAvatarPostDetail(isValidId ? id : 0); const [content, setContent] = useState(""); const { mutateAsync, isPending } = usePostComment(() => refetch()); - const handleBackClick = () => navigation.goBack(); + const handleBackClick = () => { + if (navigation.canGoBack()) { + navigation.goBack(); + return; + } + + navigation.navigate("Main", { screen: "Feed" }); + }; const handleSend = async () => { if (!isValidId || !content.trim()) return; - await mutateAsync({ content, targetId: id, targetType: "AVATAR_POST" }); - setContent(""); + + try { + await mutateAsync({ content, targetId: id, targetType: "AVATAR_POST" }); + setContent(""); + } catch (commentError) { + console.error("[FeedAvatarScreen] Failed to post comment:", commentError); + } }; if (!isValidId) { return ( - - 잘못된 게시글 ID입니다. + + + + + ); + } + + if (isLoading) { + return ( + + + + + ); + } + + if (error) { + return ( + + + void refetch()} + /> ); } if (!data) { return ( - - - 로딩 중... - + + + ); } @@ -77,47 +123,17 @@ export default function FeedAvatarScreen({ navigation, route }: Props) { - {/* 헤더 */} - - - - - 둘러보기 - - - - {/* 메인 콘텐츠 */} - + + - - {/* 댓글 입력 */} - - - - - - - - + void handleSend()} + disabled={isPending} + /> ); @@ -131,61 +147,7 @@ const styles = StyleSheet.create({ keyboardView: { flex: 1, }, - header: { - height: 56, - flexDirection: "row", - alignItems: "center", - justifyContent: "space-between", - paddingHorizontal: 12, - borderBottomWidth: 1, - borderBottomColor: "#E5E7EB", - }, - headerTitle: { - fontSize: 18, - fontWeight: "700", - color: "#171717", - }, - headerSpacer: { - width: 24, - height: 24, - }, scrollView: { flex: 1, }, - loadingContainer: { - flex: 1, - justifyContent: "center", - alignItems: "center", - }, - loadingText: { - fontSize: 14, - color: "#6B7280", - }, - errorText: { - fontSize: 14, - color: "#171717", - textAlign: "center", - marginTop: 20, - }, - commentInputContainer: { - borderTopWidth: 1, - borderTopColor: "#E5E7EB", - backgroundColor: "#FFFFFF", - paddingHorizontal: 20, - paddingVertical: 12, - }, - commentInputRow: { - flexDirection: "row", - alignItems: "center", - gap: 12, - }, - commentInput: { - flex: 1, - paddingHorizontal: 16, - paddingVertical: 10, - backgroundColor: "#E5E7EB", - borderRadius: 20, - fontSize: 14, - color: "#171717", - }, }); diff --git a/src/pages/feed/FeedDiaryScreen.tsx b/src/pages/feed/FeedDiaryScreen.tsx index 7a30572..6af81cf 100644 --- a/src/pages/feed/FeedDiaryScreen.tsx +++ b/src/pages/feed/FeedDiaryScreen.tsx @@ -1,18 +1,15 @@ -import React, { useState } from "react"; +import { useState } from "react"; import { - View, - Text, - TextInput, - TouchableOpacity, - ScrollView, KeyboardAvoidingView, Platform, + ScrollView, StyleSheet, } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; import type { RootStackScreenProps } from "@/navigation/types"; - -import { LeftIcon, SendIcon } from "@/assets/icons/CommonIcons"; +import CommentComposer from "@/components/common/CommentComposer"; +import ScreenHeader from "@/components/common/ScreenHeader"; +import StatusView from "@/components/common/StatusView"; import FeedDetail from "@/components/feed/FeedDetail"; import usePostComment from "@/hooks/comments/useCommentApi"; import { useDiaryDetail } from "@/hooks/log/useDiaryDetailApi"; @@ -25,33 +22,77 @@ export default function FeedDiaryScreen({ navigation, route }: Props) { const id = Number(postId); const isValidId = Number.isFinite(id) && id > 0; - const { data, refetch } = useDiaryDetail(isValidId ? id : 0); - + const { data, error, isLoading, refetch } = useDiaryDetail(isValidId ? id : 0); const [content, setContent] = useState(""); const { mutateAsync, isPending } = usePostComment(() => refetch()); - const handleBackClick = () => navigation.goBack(); + const handleBackClick = () => { + if (navigation.canGoBack()) { + navigation.goBack(); + return; + } + + navigation.navigate("Main", { screen: "Feed" }); + }; const handleSend = async () => { if (!isValidId || !content.trim()) return; - await mutateAsync({ content, targetId: id, targetType: "DIARY" }); - setContent(""); + + try { + await mutateAsync({ content, targetId: id, targetType: "DIARY" }); + setContent(""); + } catch (commentError) { + console.error("[FeedDiaryScreen] Failed to post comment:", commentError); + } }; if (!isValidId) { return ( - - 잘못된 게시글 ID입니다. + + + + + ); + } + + if (isLoading) { + return ( + + + + + ); + } + + if (error) { + return ( + + + void refetch()} + /> ); } if (!data) { return ( - - - 로딩 중... - + + + ); } @@ -77,47 +118,17 @@ export default function FeedDiaryScreen({ navigation, route }: Props) { - {/* 헤더 */} - - - - - 둘러보기 - - - - {/* 메인 콘텐츠 */} - + + - - {/* 댓글 입력 */} - - - - - - - - + void handleSend()} + disabled={isPending} + /> ); @@ -131,61 +142,7 @@ const styles = StyleSheet.create({ keyboardView: { flex: 1, }, - header: { - height: 56, - flexDirection: "row", - alignItems: "center", - justifyContent: "space-between", - paddingHorizontal: 12, - borderBottomWidth: 1, - borderBottomColor: "#E5E7EB", - }, - headerTitle: { - fontSize: 18, - fontWeight: "700", - color: "#171717", - }, - headerSpacer: { - width: 24, - height: 24, - }, scrollView: { flex: 1, }, - loadingContainer: { - flex: 1, - justifyContent: "center", - alignItems: "center", - }, - loadingText: { - fontSize: 14, - color: "#6B7280", - }, - errorText: { - fontSize: 14, - color: "#171717", - textAlign: "center", - marginTop: 20, - }, - commentInputContainer: { - borderTopWidth: 1, - borderTopColor: "#E5E7EB", - backgroundColor: "#FFFFFF", - paddingHorizontal: 20, - paddingVertical: 12, - }, - commentInputRow: { - flexDirection: "row", - alignItems: "center", - gap: 12, - }, - commentInput: { - flex: 1, - paddingHorizontal: 16, - paddingVertical: 10, - backgroundColor: "#E5E7EB", - borderRadius: 20, - fontSize: 14, - color: "#171717", - }, }); diff --git a/src/pages/follow/FollowScreen.tsx b/src/pages/follow/FollowScreen.tsx index 3e54aac..f464870 100644 --- a/src/pages/follow/FollowScreen.tsx +++ b/src/pages/follow/FollowScreen.tsx @@ -1,13 +1,155 @@ -import { View, Text } from "react-native"; -import type { MainTabScreenProps } from "@/navigation/types"; +import { useState } from "react"; +import { + ScrollView, + StyleSheet, + Text, + TouchableOpacity, + View, +} from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; +import type { RootStackScreenProps } from "@/navigation/types"; +import ScreenHeader from "@/components/common/ScreenHeader"; +import StatusView from "@/components/common/StatusView"; +import UserCard from "@/components/follow/UserCard"; +import { + useFollowers, + useFollowing, + useUnfollowUser, +} from "@/hooks/follow/useFollowApi"; +import useTokenStore from "@/stores/useTokenStore"; -type Props = MainTabScreenProps<"Follow">; +type Props = RootStackScreenProps<"Follow">; +type Tab = "following" | "followers"; export default function FollowScreen({ navigation }: Props) { + const [activeTab, setActiveTab] = useState("following"); + const userId = useTokenStore(state => state.userId); + const followingQuery = useFollowing(userId); + const followersQuery = useFollowers(userId); + const unfollowMutation = useUnfollowUser(userId); + + const isLoading = + activeTab === "following" ? followingQuery.isLoading : followersQuery.isLoading; + const error = activeTab === "following" ? followingQuery.error : followersQuery.error; + const users = + activeTab === "following" + ? followingQuery.data ?? [] + : followersQuery.data ?? []; + + const handleBack = () => { + if (navigation.canGoBack()) { + navigation.goBack(); + return; + } + + navigation.navigate("Main", { screen: "Feed" }); + }; + + const handleRetry = () => { + if (activeTab === "following") { + void followingQuery.refetch(); + return; + } + + void followersQuery.refetch(); + }; + return ( - - 팔로우 - 친구들의 정원 둘러보기 - + + + + + setActiveTab("following")} + > + + 내가 추가한 + + + setActiveTab("followers")} + > + + 나를 추가한 + + + + + {!userId ? ( + + ) : isLoading ? ( + + ) : error ? ( + + ) : users.length === 0 ? ( + + ) : ( + + {users.map(user => ( + navigation.navigate("Profile", { userId: user.userId })} + actionLabel={activeTab === "following" ? "삭제" : undefined} + actionDisabled={unfollowMutation.isPending} + onActionPress={ + activeTab === "following" + ? () => void unfollowMutation.mutateAsync(user.userId) + : undefined + } + /> + ))} + + )} + ); } + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: "#FFFFFF", + }, + tabRow: { + flexDirection: "row", + marginBottom: 4, + }, + tabButton: { + flex: 1, + alignItems: "center", + paddingVertical: 14, + borderBottomWidth: 2, + borderBottomColor: "transparent", + }, + tabButtonActive: { + borderBottomColor: "#4CAF50", + }, + tabText: { + fontSize: 15, + color: "#9CA3AF", + }, + tabTextActive: { + color: "#171717", + fontWeight: "700", + }, + list: { + flex: 1, + }, +}); diff --git a/src/pages/home/HomeScreen.tsx b/src/pages/home/HomeScreen.tsx index 51f22aa..9d9fdd1 100644 --- a/src/pages/home/HomeScreen.tsx +++ b/src/pages/home/HomeScreen.tsx @@ -1,13 +1,403 @@ -import { View, Text } from "react-native"; +import { useEffect } from "react"; +import { + ScrollView, + StyleSheet, + Text, + TouchableOpacity, + View, +} from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; import type { MainTabScreenProps } from "@/navigation/types"; +import StatusView from "@/components/common/StatusView"; +import useHomeApi from "@/hooks/home/useHomeApi"; +import { useHomeSummaryStore } from "@/stores/useHomeSummaryStore"; +import { + getGardenLocked, + getGardenUnlockable, + getMissionCompleted, + type GardenSummary, + type HomeMissionType, + type TodayMission, +} from "@/types/home/garden"; type Props = MainTabScreenProps<"Home">; +type MissionRouteName = + | "DailyMissionWriteDiary" + | "DailyMissionQuizMultipleChoice" + | "DailyMissionChecking" + | null; export default function HomeScreen({ navigation }: Props) { + const { data, error, isLoading, refetch } = useHomeApi(); + const { user, gardens, missions, hydrate } = useHomeSummaryStore(); + + useEffect(() => { + if (data) { + hydrate(data); + } + }, [data, hydrate]); + + const userInfo = data?.userInfo ?? user; + const gardenSummaries = data?.gardenSummaries ?? gardens; + const todayMissions = data?.todayMissions ?? missions; + + if (isLoading && !userInfo && gardenSummaries.length === 0) { + return ( + + + + ); + } + + if (error && !userInfo && gardenSummaries.length === 0) { + return ( + + void refetch()} + /> + + ); + } + + return ( + + + + 현재 동작하는 홈 정보 + + {userInfo ? `${userInfo.username}님의 정원` : "정원 요약"} + + + {userInfo + ? `레벨 ${userInfo.level} · 알림 ${userInfo.unreadNotificationCount}개` + : "홈 요약 API가 연결되면 사용자 정보와 정원 상태가 여기에 표시됩니다."} + + + + + {todayMissions.length > 0 ? ( + todayMissions.map(mission => ( + { + const routeName = getMissionRouteName(mission); + if (routeName) { + navigation.navigate(routeName); + } + }} + /> + )) + ) : ( + + )} + + + {gardenSummaries.length > 0 ? ( + gardenSummaries.map(garden => ( + + )) + ) : ( + + )} + + + + navigation.navigate("Log")} + /> + navigation.navigate("Feed")} + /> + navigation.navigate("UnlockGarden")} + /> + navigation.navigate("DailyMissionWriteDiary")} + /> + navigation.navigate("DailyMissionQuizMultipleChoice")} + /> + navigation.navigate("DailyMissionChecking")} + /> + + + + + + + ); +} + +function SectionTitle({ + title, + subtitle, +}: { + title: string; + subtitle: string; +}) { return ( - - - 나풀나풀 메인 화면 + + {title} + {subtitle} ); } + +function MissionCard({ + mission, + onPress, +}: { + mission: TodayMission; + onPress?: () => void; +}) { + const routeName = getMissionRouteName(mission); + const completed = getMissionCompleted(mission); + + return ( + + + {mission.missionTitle} + + {completed ? "완료" : routeName ? "진행 전" : "준비 중"} + + + {getMissionLabel(mission.missionType)} + + ); +} + +function getMissionRouteName(mission: TodayMission): MissionRouteName { + switch (mission.missionType as HomeMissionType) { + case "DIARY": + return "DailyMissionWriteDiary"; + case "QUIZ": + return "DailyMissionQuizMultipleChoice"; + case "CHECKING": + return "DailyMissionChecking"; + default: + return null; + } +} + +function getMissionLabel(missionType: TodayMission["missionType"]) { + switch (missionType as HomeMissionType) { + case "DIARY": + return "일기 작성 미션"; + case "QUIZ": + return "퀴즈 미션"; + case "CHECKING": + return "오늘의 질문 미션"; + default: + return `알 수 없는 미션 타입: ${String(missionType)}`; + } +} + +function GardenCard({ garden }: { garden: GardenSummary }) { + const isLocked = getGardenLocked(garden); + const isUnlockable = getGardenUnlockable(garden); + const status = isLocked ? (isUnlockable ? "잠금 해제 가능" : "잠금 상태") : "사용 가능"; + + const actionState = isLocked + ? "정원 해금 대기" + : `${garden.ownerWateringAble ? "물주기 가능" : "물주기 대기"} · ${ + garden.ownerSunlightAble ? "햇빛 가능" : "햇빛 대기" + }`; + + return ( + + + 정원 슬롯 {garden.gardenSlotNumber} + {status} + + + {garden.avatar?.avatarName ?? "배정된 식물이 없습니다."} + + {actionState} + + ); +} + +function QuickAction({ + title, + description, + onPress, +}: { + title: string; + description: string; + onPress: () => void; +}) { + return ( + + {title} + {description} + + ); +} + +function InfoCard({ title, description }: { title: string; description: string }) { + return ( + + {title} + {description} + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: "#F7F8F4", + }, + scrollView: { + flex: 1, + }, + content: { + padding: 20, + gap: 14, + }, + heroCard: { + borderRadius: 20, + padding: 20, + backgroundColor: "#2F5D3B", + }, + eyebrow: { + fontSize: 12, + color: "#D1E7CF", + marginBottom: 8, + }, + heroTitle: { + fontSize: 24, + fontWeight: "700", + color: "#FFFFFF", + marginBottom: 6, + }, + heroDescription: { + fontSize: 14, + lineHeight: 20, + color: "#E7F3E4", + }, + sectionHeader: { + marginTop: 6, + gap: 4, + }, + sectionTitle: { + fontSize: 18, + fontWeight: "700", + color: "#171717", + }, + sectionSubtitle: { + fontSize: 13, + lineHeight: 18, + color: "#6B7280", + }, + card: { + backgroundColor: "#FFFFFF", + borderRadius: 16, + padding: 16, + gap: 8, + }, + infoCard: { + backgroundColor: "#F0F4EC", + }, + rowBetween: { + flexDirection: "row", + justifyContent: "space-between", + alignItems: "center", + gap: 12, + }, + cardTitle: { + flex: 1, + fontSize: 16, + fontWeight: "600", + color: "#171717", + }, + cardDescription: { + fontSize: 14, + lineHeight: 20, + color: "#4B5563", + }, + cardMeta: { + fontSize: 12, + color: "#6B7280", + }, + doneBadge: { + fontSize: 12, + color: "#2F7D32", + fontWeight: "700", + }, + todoBadge: { + fontSize: 12, + color: "#B45309", + fontWeight: "700", + }, + quickActions: { + gap: 12, + }, + quickAction: { + borderRadius: 16, + padding: 16, + backgroundColor: "#FFFFFF", + }, + quickActionTitle: { + fontSize: 16, + fontWeight: "700", + color: "#171717", + marginBottom: 4, + }, + quickActionDescription: { + fontSize: 13, + lineHeight: 18, + color: "#6B7280", + }, +}); diff --git a/src/pages/log/LogDetailScreen.tsx b/src/pages/log/LogDetailScreen.tsx new file mode 100644 index 0000000..25f534f --- /dev/null +++ b/src/pages/log/LogDetailScreen.tsx @@ -0,0 +1,122 @@ +import { useState } from "react"; +import { + KeyboardAvoidingView, + Platform, + ScrollView, + StyleSheet, +} from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; +import type { RootStackScreenProps } from "@/navigation/types"; +import CommentComposer from "@/components/common/CommentComposer"; +import ScreenHeader from "@/components/common/ScreenHeader"; +import StatusView from "@/components/common/StatusView"; +import MyDiaryDetail from "@/components/log/MyDiaryDetail"; +import usePostComment from "@/hooks/comments/useCommentApi"; +import { useDiaryDetail } from "@/hooks/log/useDiaryDetailApi"; + +type Props = RootStackScreenProps<"LogDetail">; + +export default function LogDetailScreen({ navigation, route }: Props) { + const diaryId = Number(route.params.id); + const isValidId = Number.isFinite(diaryId) && diaryId > 0; + const { + data, + error, + isLoading, + refetch, + } = useDiaryDetail(isValidId ? diaryId : 0); + const [content, setContent] = useState(""); + const { mutateAsync, isPending } = usePostComment(() => refetch()); + + const handleBack = () => { + if (navigation.canGoBack()) { + navigation.goBack(); + return; + } + + navigation.navigate("Main", { screen: "Log" }); + }; + + const handleSend = async () => { + if (!isValidId || !content.trim()) return; + + try { + await mutateAsync({ content, targetId: diaryId, targetType: "DIARY" }); + setContent(""); + } catch (commentError) { + console.error("[LogDetailScreen] Failed to post comment:", commentError); + } + }; + + let body; + + if (!isValidId) { + body = ( + + ); + } else if (isLoading) { + body = ; + } else if (error) { + body = ( + void refetch()} + /> + ); + } else if (!data) { + body = ( + + ); + } else { + body = ( + <> + + + + void handleSend()} + disabled={isPending} + /> + + ); + } + + return ( + + + + {body} + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: "#FFFFFF", + }, + keyboardView: { + flex: 1, + }, + scrollView: { + flex: 1, + }, +}); diff --git a/src/pages/onboarding/OnboardingScreen.tsx b/src/pages/onboarding/OnboardingScreen.tsx index d0baad9..9cd912e 100644 --- a/src/pages/onboarding/OnboardingScreen.tsx +++ b/src/pages/onboarding/OnboardingScreen.tsx @@ -14,6 +14,8 @@ import { useNavigation } from "@react-navigation/native"; import type { NativeStackNavigationProp } from "@react-navigation/native-stack"; import type { RootStackParamList } from "@/navigation/types"; import Splash from "@/components/common/Splash"; +import { useSupabaseOAuth } from "@/hooks/auth/useSupabaseOAuth"; +import useRegistrationStore from "@/stores/useRegistrationStore"; const { width } = Dimensions.get("window"); @@ -51,6 +53,8 @@ export default function OnboardingScreen() { const [currentIndex, setCurrentIndex] = useState(0); const flatListRef = useRef(null); const navigation = useNavigation(); + const { performOAuth, isLoading } = useSupabaseOAuth(); + const resetRegistration = useRegistrationStore(state => state.reset); const isLastSlide = currentIndex === onboardingData.length - 1; @@ -71,6 +75,24 @@ export default function OnboardingScreen() { navigation.navigate("Register"); }; + // [UI 연동] 소셜 로그인 버튼 클릭 핸들러 + // SupabaseOAuth 훅을 호출하고, 최종적으로 완료되면 전체 네비게이션을 Main 구조로 리셋합니다. + const handleOAuthLogin = async (provider: 'kakao' | 'google') => { + const result = await performOAuth(provider); + if (result?.success) { + if (result.isNewUser) { + resetRegistration(); + navigation.reset({ + index: 0, + routes: [{ name: "RegistrationAvatar" }], + }); + return; + } + + navigation.reset({ index: 0, routes: [{ name: 'Main' as any }] }); // Main Tab navigator + } + }; + if (isSplash) return ; return ( @@ -110,15 +132,46 @@ export default function OnboardingScreen() { {/* Button */} - - - 나만의 화단 만들러 가기 - - + {isLastSlide ? ( + + handleOAuthLogin('kakao')} + disabled={isLoading} + > + + {isLoading ? "처리 중..." : "카카오로 시작하기"} + + + + handleOAuthLogin('google')} + disabled={isLoading} + > + + {isLoading ? "처리 중..." : "구글로 시작하기"} + + + + + 비회원으로 화단 만들기 + + + ) : ( + + + 나만의 화단 만들러 가기 + + + )} ); @@ -195,4 +248,40 @@ const styles = StyleSheet.create({ buttonTextDisabled: { color: "#9CA3AF", }, + socialAuthContainer: { + gap: 12, + }, + socialButton: { + paddingVertical: 16, + borderRadius: 12, + alignItems: "center", + }, + kakaoButton: { + backgroundColor: "#FEE500", + }, + kakaoButtonText: { + color: "#000000", + fontSize: 16, + fontWeight: "600", + }, + googleButton: { + backgroundColor: "#FFFFFF", + borderWidth: 1, + borderColor: "#E5E7EB", + }, + googleButtonText: { + color: "#000000", + fontSize: 16, + fontWeight: "600", + }, + guestButton: { + paddingVertical: 16, + alignItems: "center", + marginTop: 4, + }, + guestButtonText: { + color: "#6B7280", + fontSize: 14, + textDecorationLine: "underline", + }, }); diff --git a/src/pages/option/OptionScreen.tsx b/src/pages/option/OptionScreen.tsx index dfdf610..e29e36e 100644 --- a/src/pages/option/OptionScreen.tsx +++ b/src/pages/option/OptionScreen.tsx @@ -1,13 +1,188 @@ -import { View, Text } from "react-native"; +import { useState } from "react"; +import { + ActivityIndicator, + Alert, + ScrollView, + StyleSheet, + Text, + TouchableOpacity, + View, +} from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; +import ScreenHeader from "@/components/common/ScreenHeader"; +import { logout } from "@/utils/auth"; +import useTokenStore from "@/stores/useTokenStore"; import type { MainTabScreenProps } from "@/navigation/types"; type Props = MainTabScreenProps<"Option">; -export default function OptionScreen({ navigation }: Props) { +export default function OptionScreen(_: Props) { + const [isLoggingOut, setIsLoggingOut] = useState(false); + const { accessToken, userId, hasHydrated } = useTokenStore(); + + let loginStatus = "로그인 상태"; + + if (!hasHydrated) { + loginStatus = "세션 확인 중"; + } else if (!accessToken) { + loginStatus = "로그아웃 상태"; + } + + const handleLogout = () => { + if (isLoggingOut || !accessToken) { + return; + } + + Alert.alert("로그아웃", "현재 계정에서 로그아웃할까요?", [ + { text: "취소", style: "cancel" }, + { + text: "로그아웃", + style: "destructive", + onPress: async () => { + setIsLoggingOut(true); + await logout(); + }, + }, + ]); + }; + return ( - - 설정 - 앱 설정 및 계정 관리 - + + + + + 계정 + + + 인증 상태 + {loginStatus} + + + + 사용자 ID + {userId ?? "확인되지 않음"} + + + + + + 운영 안내 + + MainAPP 단독 운영 기준 + + MainFE 종료 이후에는 현재 앱 레포와 MainBE 계약이 기준입니다. + + + 버전 표기, 약관, 고객 문의 연결은 운영 정책 확정 후 추가합니다. + + + + + + {isLoggingOut ? ( + + + 로그아웃 중... + + ) : ( + 로그아웃 + )} + + + ); } + +const styles = StyleSheet.create({ + safeArea: { + flex: 1, + backgroundColor: "#FFFFFF", + }, + scrollView: { + flex: 1, + backgroundColor: "#F9FAFB", + }, + contentContainer: { + padding: 20, + gap: 20, + }, + section: { + gap: 10, + }, + sectionTitle: { + fontSize: 15, + fontWeight: "700", + color: "#111827", + }, + card: { + backgroundColor: "#FFFFFF", + borderRadius: 16, + borderWidth: 1, + borderColor: "#E5E7EB", + padding: 16, + gap: 12, + }, + row: { + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + gap: 16, + }, + label: { + fontSize: 14, + color: "#6B7280", + }, + value: { + flex: 1, + fontSize: 14, + fontWeight: "600", + color: "#111827", + textAlign: "right", + }, + divider: { + height: 1, + backgroundColor: "#F3F4F6", + }, + infoTitle: { + fontSize: 15, + fontWeight: "700", + color: "#111827", + }, + infoText: { + fontSize: 14, + lineHeight: 20, + color: "#4B5563", + }, + logoutButton: { + alignItems: "center", + justifyContent: "center", + borderRadius: 14, + backgroundColor: "#DC2626", + paddingVertical: 16, + marginTop: 8, + }, + logoutButtonDisabled: { + backgroundColor: "#D1D5DB", + }, + logoutLoading: { + flexDirection: "row", + alignItems: "center", + gap: 8, + }, + logoutButtonText: { + fontSize: 16, + fontWeight: "700", + color: "#FFFFFF", + }, +}); diff --git a/src/pages/placeholder/PlaceholderScreen.tsx b/src/pages/placeholder/PlaceholderScreen.tsx deleted file mode 100644 index 74b2c56..0000000 --- a/src/pages/placeholder/PlaceholderScreen.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { View, Text, TouchableOpacity } from "react-native"; -import { useNavigation } from "@react-navigation/native"; - -interface PlaceholderScreenProps { - title: string; - description?: string; -} - -export default function PlaceholderScreen({ - title, - description, -}: PlaceholderScreenProps) { - const navigation = useNavigation(); - - return ( - - {title} - {description && ( - {description} - )} - navigation.goBack()} - > - 뒤로 가기 - - - ); -} diff --git a/src/pages/profile/ProfileScreen.tsx b/src/pages/profile/ProfileScreen.tsx new file mode 100644 index 0000000..30ea859 --- /dev/null +++ b/src/pages/profile/ProfileScreen.tsx @@ -0,0 +1,270 @@ +import { useMemo } from "react"; +import { + Image, + ScrollView, + StyleSheet, + Text, + TouchableOpacity, + View, +} from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; +import type { RootStackScreenProps } from "@/navigation/types"; +import ScreenHeader from "@/components/common/ScreenHeader"; +import StatusView from "@/components/common/StatusView"; +import ProfileDetail from "@/components/profile/ProfileDetail"; +import { + useFriendWater, + useUserProfile, +} from "@/hooks/profile/useProfileApi"; +import { useFollowUser, useUnfollowUser } from "@/hooks/follow/useFollowApi"; +import useTokenStore from "@/stores/useTokenStore"; +import { FollowStatus } from "@/types/profile/profileApi.type"; + +type Props = RootStackScreenProps<"Profile">; + +export default function ProfileScreen({ navigation, route }: Props) { + const { userId: myUserId } = useTokenStore(); + const userId = route.params.userId; + const { data, error, isLoading, refetch } = useUserProfile(userId); + const waterMutation = useFriendWater(userId); + const followMutation = useFollowUser(myUserId); + const unfollowMutation = useUnfollowUser(myUserId); + + const isMe = String(userId) === myUserId; + + const handleBack = () => { + if (navigation.canGoBack()) { + navigation.goBack(); + return; + } + + navigation.navigate("Main", { screen: "Feed" }); + }; + + const followAction = useMemo(() => { + if (!data || isMe) return null; + + switch (data.followStatus) { + case FollowStatus.NOT_FOLLOWING: + return { + label: "친구 추가", + onPress: () => void followMutation.mutateAsync(userId), + pending: followMutation.isPending, + }; + case FollowStatus.FOLLOW_BACK_POSSIBLE: + return { + label: "맞팔로우", + onPress: () => void followMutation.mutateAsync(userId), + pending: followMutation.isPending, + }; + case FollowStatus.FOLLOWING: + return { + label: "언팔로우", + onPress: () => void unfollowMutation.mutateAsync(userId), + pending: unfollowMutation.isPending, + }; + default: + return null; + } + }, [data, followMutation, unfollowMutation, userId, isMe]); + + if (isLoading) { + return ( + + + + + ); + } + + if (error) { + return ( + + + void refetch()} + /> + + ); + } + + if (!data) { + return ( + + + + + ); + } + + const primaryGarden = data.userGardens[0]; + + return ( + + + + + + + {data.profileImageUrl ? ( + + ) : null} + + + {data.userNickname} + + 남은 친구 물주기 {data.leftWaterCountForOthers}회 + + + {followAction ? ( + + + {followAction.pending ? "처리 중..." : followAction.label} + + + ) : ( + + {isMe ? "내 프로필" : ""} + + )} + + + + {primaryGarden ? ( + void waterMutation.mutateAsync(primaryGarden.gardenId)} + waterDisabled={waterMutation.isPending} + /> + ) : ( + + 정원 정보가 없습니다. + + 현재 API 기준으로 대표 정원 정보가 없어서 기본 정보만 표시합니다. + + + )} + + + 이번 단계에서 보류된 항목 + + 방명록, 프로필 추가 상호작용, 대표 정원 외 상세 뷰는 API 범위 확인 후 확장합니다. + + + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: "#FFFFFF", + }, + scrollView: { + flex: 1, + }, + summaryCard: { + paddingHorizontal: 20, + paddingTop: 20, + }, + summaryRow: { + flexDirection: "row", + alignItems: "center", + gap: 12, + }, + profileImageWrap: { + width: 56, + height: 56, + borderRadius: 28, + backgroundColor: "#E5E7EB", + overflow: "hidden", + }, + profileImage: { + width: "100%", + height: "100%", + }, + summaryTextWrap: { + flex: 1, + gap: 4, + }, + nickname: { + fontSize: 20, + fontWeight: "700", + color: "#171717", + }, + metaText: { + fontSize: 13, + color: "#6B7280", + }, + followButton: { + borderRadius: 999, + backgroundColor: "#4CAF50", + paddingHorizontal: 14, + paddingVertical: 10, + }, + followButtonText: { + color: "#FFFFFF", + fontSize: 13, + fontWeight: "700", + }, + selfBadge: { + minWidth: 64, + alignItems: "flex-end", + }, + selfBadgeText: { + fontSize: 12, + color: "#6B7280", + }, + emptyGardenWrap: { + paddingHorizontal: 20, + paddingVertical: 28, + gap: 6, + }, + emptyGardenTitle: { + fontSize: 16, + fontWeight: "700", + color: "#171717", + }, + emptyGardenDescription: { + fontSize: 14, + lineHeight: 20, + color: "#6B7280", + }, + todoCard: { + margin: 20, + marginTop: 4, + borderRadius: 16, + backgroundColor: "#F8FAF6", + padding: 16, + gap: 6, + }, + todoTitle: { + fontSize: 15, + fontWeight: "700", + color: "#171717", + }, + todoText: { + fontSize: 13, + lineHeight: 18, + color: "#6B7280", + }, +}); diff --git a/src/pages/register/RegisterScreen.tsx b/src/pages/register/RegisterScreen.tsx index 24cd02a..e575d3c 100644 --- a/src/pages/register/RegisterScreen.tsx +++ b/src/pages/register/RegisterScreen.tsx @@ -13,6 +13,7 @@ import type { NativeStackNavigationProp } from "@react-navigation/native-stack"; import type { RootStackParamList } from "@/navigation/types"; import { LeftIcon, EditIcon } from "@/assets/icons/CommonIcons"; import { useRegister } from "@/hooks/register/useRegister"; +import useRegistrationStore from "@/stores/useRegistrationStore"; type NavigationProp = NativeStackNavigationProp; @@ -21,6 +22,7 @@ export default function RegisterScreen() { const [nickname, setNickname] = useState(""); const navigation = useNavigation(); const { register, isLoading } = useRegister(); + const resetRegistration = useRegistrationStore(state => state.reset); const isValidNickname = nickname.length >= 2 && nickname.length <= 10; @@ -33,10 +35,12 @@ export default function RegisterScreen() { try { await register(nickname); + resetRegistration(); navigation.navigate("RegistrationAvatar"); } catch (error) { console.error(error); // 에러가 발생해도 다음 화면으로 이동 (기존 웹과 동일한 동작) + resetRegistration(); navigation.navigate("RegistrationAvatar"); } }; @@ -82,7 +86,6 @@ export default function RegisterScreen() { placeholderTextColor="#9CA3AF" value={nickname} onChangeText={setNickname} - minLength={2} maxLength={10} /> {nickname.length > 0 ? ( diff --git a/src/pages/registration/RegistrationAvatarScreen.tsx b/src/pages/registration/RegistrationAvatarScreen.tsx new file mode 100644 index 0000000..1be0e8f --- /dev/null +++ b/src/pages/registration/RegistrationAvatarScreen.tsx @@ -0,0 +1,105 @@ +import { ScrollView, StyleSheet, Text, View } from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; +import ScreenHeader from "@/components/common/ScreenHeader"; +import RegistrationFooter from "@/components/registration/RegistrationFooter"; +import RegistrationModeCard from "@/components/registration/RegistrationModeCard"; +import type { RootStackScreenProps } from "@/navigation/types"; +import useRegistrationStore from "@/stores/useRegistrationStore"; + +type Props = RootStackScreenProps<"RegistrationAvatar">; + +export default function RegistrationAvatarScreen({ navigation }: Props) { + const { mode, selectedMaster, selectedPreview, setMode } = useRegistrationStore(); + + const goNext = () => { + if (mode === "selection") { + navigation.navigate("RegistrationSelectionDetail"); + return; + } + + if (mode === "creation") { + navigation.navigate("RegistrationCreationDetail"); + } + }; + + return ( + + navigation.navigate("Main", { screen: "Home" })} + /> + + + 등록 플로우 시작 + 어떤 방식으로 식물을 데려올지 선택하세요. + + 선택형은 제공된 아바타를 고르는 방식이고, 생성형은 이미지를 업로드한 뒤 별명을 붙이는 방식입니다. + + + + setMode("selection")} + /> + + setMode("creation")} + /> + + + + navigation.reset({ + index: 0, + routes: [{ name: "Main", params: { screen: "Home" } }], + }) + } + primaryLabel="다음" + onPrimaryPress={goNext} + primaryDisabled={!mode} + /> + + ); +} + +const styles = StyleSheet.create({ + safeArea: { + flex: 1, + backgroundColor: "#F7F8F4", + }, + content: { + padding: 20, + gap: 16, + }, + heroCard: { + borderRadius: 22, + padding: 20, + backgroundColor: "#234A2F", + gap: 8, + }, + eyebrow: { + fontSize: 12, + color: "#D7E9D8", + }, + heroTitle: { + fontSize: 24, + lineHeight: 32, + fontWeight: "700", + color: "#FFFFFF", + }, + heroDescription: { + fontSize: 14, + lineHeight: 20, + color: "#E5F4E5", + }, +}); diff --git a/src/pages/registration/RegistrationCreationDetailScreen.tsx b/src/pages/registration/RegistrationCreationDetailScreen.tsx new file mode 100644 index 0000000..c17caf4 --- /dev/null +++ b/src/pages/registration/RegistrationCreationDetailScreen.tsx @@ -0,0 +1,250 @@ +import { useState } from "react"; +import * as ImagePicker from "expo-image-picker"; +import { + Alert, + ScrollView, + StyleSheet, + Text, + TouchableOpacity, + View, +} from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; +import ScreenHeader from "@/components/common/ScreenHeader"; +import AvatarPreviewCard from "@/components/registration/AvatarPreviewCard"; +import RegistrationFooter from "@/components/registration/RegistrationFooter"; +import { useUploadCreationAvatar } from "@/hooks/avatars/useAvatarApi"; +import type { RootStackScreenProps } from "@/navigation/types"; +import useRegistrationStore from "@/stores/useRegistrationStore"; + +type Props = RootStackScreenProps<"RegistrationCreationDetail">; + +export default function RegistrationCreationDetailScreen({ navigation }: Props) { + const [permissionRequested, setPermissionRequested] = useState(false); + const uploadCreationAvatar = useUploadCreationAvatar(); + const { + creationDetail, + updateCreationDetail, + setMode, + setSelectedMaster, + setSelectedPreview, + } = useRegistrationStore(); + + const previewImageUrl = + creationDetail.uploadedImageUrl || creationDetail.imageUri || null; + const canProceed = Boolean(creationDetail.uploadedImageUrl); + + const handlePickImage = async () => { + if (!permissionRequested) { + const permission = await ImagePicker.requestMediaLibraryPermissionsAsync(); + setPermissionRequested(true); + + if (!permission.granted) { + Alert.alert("권한 필요", "생성형 아바타 이미지를 고르려면 사진 접근 권한이 필요합니다."); + return; + } + } + + const result = await ImagePicker.launchImageLibraryAsync({ + mediaTypes: ["images"], + allowsEditing: true, + quality: 0.9, + }); + + if (result.canceled || !result.assets[0]) { + return; + } + + const asset = result.assets[0]; + const fileName = asset.fileName ?? `avatar-${Date.now()}.jpg`; + const fileType = asset.mimeType ?? "image/jpeg"; + const formData = new FormData(); + + formData.append("image", { + uri: asset.uri, + name: fileName, + type: fileType, + } as never); + + updateCreationDetail({ + imageUri: asset.uri, + uploadedImageUrl: "", + }); + setSelectedPreview({ + masterId: null, + imageUrl: asset.uri, + description: "선택한 이미지를 업로드하는 중입니다.", + }); + + try { + const response = await uploadCreationAvatar.mutateAsync(formData); + + updateCreationDetail({ + imageUri: asset.uri, + uploadedImageUrl: response.imageUrl, + }); + setMode("creation"); + setSelectedMaster(null); + setSelectedPreview({ + masterId: null, + imageUrl: response.imageUrl, + description: "업로드가 완료되었습니다. 이 이미지를 기반으로 식물을 등록합니다.", + }); + } catch (error) { + const message = + error instanceof Error ? error.message : "이미지 업로드에 실패했습니다."; + Alert.alert("업로드 실패", message); + } + }; + + const goNext = () => { + if (!canProceed) { + return; + } + + navigation.navigate("RegistrationPlantNickname"); + }; + + return ( + + navigation.navigate("RegistrationAvatar")} + /> + + + 이미지를 업로드해주세요. + + 선택한 이미지는 `POST /api/v1/register/upload`로 업로드되고, 응답 `imageUrl`이 최종 등록 단계로 이어집니다. + + + + + + void handlePickImage()} + > + + {uploadCreationAvatar.isPending ? "업로드 중..." : creationDetail.imageUri ? "이미지 다시 선택" : "이미지 선택"} + + + + + 현재 상태 + + {creationDetail.uploadedImageUrl + ? "서버 업로드가 완료되었습니다. 다음 단계에서 별명을 정한 뒤 최종 등록합니다." + : "이미지를 선택하면 업로드를 먼저 수행합니다."} + + {creationDetail.uploadedImageUrl ? ( + {creationDetail.uploadedImageUrl} + ) : null} + + + {uploadCreationAvatar.isError ? ( + + 이미지 업로드에 실패했습니다. + + 같은 이미지를 다시 선택해서 재시도할 수 있습니다. + + + ) : null} + + + navigation.navigate("RegistrationAvatar")} + primaryLabel="별명 정하러 가기" + onPrimaryPress={goNext} + primaryDisabled={!canProceed || uploadCreationAvatar.isPending} + primaryLoading={uploadCreationAvatar.isPending} + /> + + ); +} + +const styles = StyleSheet.create({ + safeArea: { + flex: 1, + backgroundColor: "#F7F8F4", + }, + content: { + padding: 20, + gap: 18, + }, + headerBlock: { + gap: 8, + }, + title: { + fontSize: 24, + lineHeight: 32, + fontWeight: "700", + color: "#171717", + }, + subtitle: { + fontSize: 14, + lineHeight: 20, + color: "#6B7280", + }, + actionButton: { + minHeight: 52, + alignItems: "center", + justifyContent: "center", + borderRadius: 16, + backgroundColor: "#2F7D32", + }, + actionButtonText: { + fontSize: 15, + fontWeight: "700", + color: "#FFFFFF", + }, + infoCard: { + borderRadius: 18, + padding: 16, + backgroundColor: "#EEF3EA", + gap: 8, + }, + infoTitle: { + fontSize: 16, + fontWeight: "700", + color: "#171717", + }, + infoText: { + fontSize: 14, + lineHeight: 20, + color: "#4B5563", + }, + infoUrl: { + fontSize: 12, + lineHeight: 18, + color: "#2563EB", + }, + errorCard: { + borderRadius: 18, + padding: 16, + backgroundColor: "#FEF2F2", + gap: 6, + }, + errorTitle: { + fontSize: 16, + fontWeight: "700", + color: "#B91C1C", + }, + errorDescription: { + fontSize: 14, + lineHeight: 20, + color: "#7F1D1D", + }, +}); diff --git a/src/pages/registration/RegistrationPlantNicknameScreen.tsx b/src/pages/registration/RegistrationPlantNicknameScreen.tsx new file mode 100644 index 0000000..8bab698 --- /dev/null +++ b/src/pages/registration/RegistrationPlantNicknameScreen.tsx @@ -0,0 +1,187 @@ +import { ScrollView, StyleSheet, Text, View } from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; +import ScreenHeader from "@/components/common/ScreenHeader"; +import AvatarPreviewCard from "@/components/registration/AvatarPreviewCard"; +import RegistrationFooter from "@/components/registration/RegistrationFooter"; +import RegistrationTextField from "@/components/registration/RegistrationTextField"; +import { useFinalChoiceAvatar } from "@/hooks/avatars/useAvatarApi"; +import type { RootStackScreenProps } from "@/navigation/types"; +import useRegistrationStore from "@/stores/useRegistrationStore"; + +type Props = RootStackScreenProps<"RegistrationPlantNickname">; + +export default function RegistrationPlantNicknameScreen({ navigation }: Props) { + const { + mode, + nickname, + selectedMaster, + selectedPreview, + creationDetail, + setNickname, + reset, + } = useRegistrationStore(); + const finalChoiceAvatar = useFinalChoiceAvatar(); + + const trimmedNickname = nickname.trim(); + const isInvalid = trimmedNickname.length === 0 || trimmedNickname.length > 6; + const canSubmitToApi = + (mode === "selection" && Boolean(selectedMaster?.id && selectedMaster.defaultImageUrl)) || + (mode === "creation" && Boolean(creationDetail.uploadedImageUrl)); + + const helperText = + mode === "selection" + ? "선택형은 imageUrl과 masterId를 함께 보내 최종 등록합니다." + : "생성형은 업로드된 imageUrl과 masterId:null로 최종 등록합니다."; + + const completeFlow = async () => { + if (isInvalid || !canSubmitToApi) { + return; + } + + const payload = + mode === "selection" && selectedMaster + ? { + nickname: trimmedNickname, + imageUrl: selectedMaster.defaultImageUrl, + masterId: selectedMaster.id, + } + : { + nickname: trimmedNickname, + imageUrl: creationDetail.uploadedImageUrl, + masterId: null, + }; + + try { + await finalChoiceAvatar.mutateAsync(payload); + reset(); + navigation.reset({ + index: 0, + routes: [{ name: "Main", params: { screen: "Home" } }], + }); + } catch { + // Error card below handles the failure case. + } + }; + + const goBackTarget = () => { + if (mode === "selection") { + navigation.navigate("RegistrationSelectionDetail"); + return; + } + + navigation.navigate("RegistrationCreationDetail"); + }; + + return ( + + + + + 식물의 별명을 지어주세요. + + 별명과 imageUrl을 함께 보내 최종 아바타 등록을 완료합니다. + + + + + + + + + + {trimmedNickname.length > 6 + ? "최대 6자까지 입력할 수 있습니다." + : "공백을 제외한 별명을 입력해주세요."} + + {!canSubmitToApi ? ( + + {mode === "creation" + ? "생성형 이미지를 먼저 업로드해야 합니다." + : "선택한 아바타 정보를 다시 확인해주세요."} + + ) : null} + + + {finalChoiceAvatar.isError ? ( + + 최종 등록에 실패했습니다. + + `POST /api/v1/avatars` 호출에 실패했습니다. 같은 정보로 다시 시도할 수 있습니다. + + + ) : null} + + + void completeFlow()} + primaryDisabled={isInvalid || !canSubmitToApi || finalChoiceAvatar.isPending} + primaryLoading={finalChoiceAvatar.isPending} + /> + + ); +} + +const styles = StyleSheet.create({ + safeArea: { + flex: 1, + backgroundColor: "#F7F8F4", + }, + content: { + padding: 20, + gap: 18, + }, + headerBlock: { + gap: 8, + }, + title: { + fontSize: 24, + lineHeight: 32, + fontWeight: "700", + color: "#171717", + }, + subtitle: { + fontSize: 14, + lineHeight: 20, + color: "#6B7280", + }, + captionRow: { + gap: 8, + }, + caption: { + fontSize: 12, + lineHeight: 18, + color: "#6B7280", + }, + captionError: { + color: "#B91C1C", + }, + errorCard: { + borderRadius: 18, + padding: 16, + backgroundColor: "#FEF2F2", + gap: 6, + }, + errorTitle: { + fontSize: 16, + fontWeight: "700", + color: "#B91C1C", + }, + errorDescription: { + fontSize: 14, + lineHeight: 20, + color: "#7F1D1D", + }, +}); diff --git a/src/pages/registration/RegistrationSelectionDetailScreen.tsx b/src/pages/registration/RegistrationSelectionDetailScreen.tsx new file mode 100644 index 0000000..6c18019 --- /dev/null +++ b/src/pages/registration/RegistrationSelectionDetailScreen.tsx @@ -0,0 +1,164 @@ +import { useEffect } from "react"; +import { + ScrollView, + StyleSheet, + Text, + View, +} from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; +import ScreenHeader from "@/components/common/ScreenHeader"; +import StatusView from "@/components/common/StatusView"; +import RegistrationFooter from "@/components/registration/RegistrationFooter"; +import SelectionAvatarCard from "@/components/registration/SelectionAvatarCard"; +import { useAvatarMasters } from "@/hooks/avatars/useAvatarApi"; +import type { RootStackScreenProps } from "@/navigation/types"; +import useRegistrationStore from "@/stores/useRegistrationStore"; + +type Props = RootStackScreenProps<"RegistrationSelectionDetail">; + +export default function RegistrationSelectionDetailScreen({ + navigation, +}: Props) { + const { data, isLoading, isError, refetch } = useAvatarMasters(); + const { + selectedMaster, + setMode, + setSelectedMaster, + setSelectedPreview, + } = useRegistrationStore(); + + useEffect(() => { + if (!selectedMaster && data && data.length > 0) { + setSelectedMaster(data[0]); + setSelectedPreview({ + masterId: data[0].id, + description: data[0].description, + imageUrl: data[0].defaultImageUrl, + }); + } + }, [data, selectedMaster, setSelectedMaster, setSelectedPreview]); + + const goNext = () => { + if (!selectedMaster) { + return; + } + + setMode("selection"); + setSelectedPreview({ + masterId: selectedMaster.id, + description: selectedMaster.description, + imageUrl: selectedMaster.defaultImageUrl, + }); + navigation.navigate("RegistrationPlantNickname"); + }; + + if (isLoading) { + return ( + + navigation.navigate("RegistrationAvatar")} + /> + + + ); + } + + if (isError) { + return ( + + navigation.navigate("RegistrationAvatar")} + /> + void refetch()} + /> + + ); + } + + if (!data || data.length === 0) { + return ( + + navigation.navigate("RegistrationAvatar")} + /> + + + ); + } + + return ( + + navigation.navigate("RegistrationAvatar")} + /> + + + 원하는 식물 아바타를 선택해주세요. + + `GET /api/v1/avatars/masters` 응답 기준으로 목록을 보여줍니다. + + + + {data.map(avatar => ( + setSelectedMaster(avatar)} + /> + ))} + + + + navigation.navigate("RegistrationAvatar")} + primaryLabel="별명 정하러 가기" + onPrimaryPress={goNext} + primaryDisabled={!selectedMaster} + /> + + ); +} + +const styles = StyleSheet.create({ + safeArea: { + flex: 1, + backgroundColor: "#F7F8F4", + }, + content: { + padding: 20, + gap: 18, + }, + headerBlock: { + gap: 8, + }, + title: { + fontSize: 24, + lineHeight: 32, + fontWeight: "700", + color: "#171717", + }, + subtitle: { + fontSize: 14, + lineHeight: 20, + color: "#6B7280", + }, + grid: { + flexDirection: "row", + flexWrap: "wrap", + justifyContent: "space-between", + rowGap: 12, + }, +}); diff --git a/src/stores/useRegistrationStore.ts b/src/stores/useRegistrationStore.ts new file mode 100644 index 0000000..addeca7 --- /dev/null +++ b/src/stores/useRegistrationStore.ts @@ -0,0 +1,60 @@ +import AsyncStorage from "@react-native-async-storage/async-storage"; +import { create } from "zustand"; +import { createJSONStorage, persist } from "zustand/middleware"; +import type { + AvatarMaster, + RegistrationAvatarPreview, + RegistrationCreationDetail, + RegistrationMode, +} from "@/types/avatars"; + +type RegistrationState = { + mode: RegistrationMode | null; + creationDetail: RegistrationCreationDetail; + selectedMaster: AvatarMaster | null; + selectedPreview: RegistrationAvatarPreview | null; + nickname: string; + + setMode: (mode: RegistrationMode | null) => void; + updateCreationDetail: (patch: Partial) => void; + setSelectedMaster: (master: AvatarMaster | null) => void; + setSelectedPreview: (preview: RegistrationAvatarPreview | null) => void; + setNickname: (nickname: string) => void; + reset: () => void; +}; + +const initialCreationDetail: RegistrationCreationDetail = { + imageUri: "", + uploadedImageUrl: "", +}; + +const initialState = { + mode: null, + creationDetail: initialCreationDetail, + selectedMaster: null, + selectedPreview: null, + nickname: "", +}; + +const useRegistrationStore = create()( + persist( + set => ({ + ...initialState, + setMode: mode => set(state => ({ ...state, mode })), + updateCreationDetail: patch => + set(state => ({ + creationDetail: { ...state.creationDetail, ...patch }, + })), + setSelectedMaster: master => set(() => ({ selectedMaster: master })), + setSelectedPreview: preview => set(() => ({ selectedPreview: preview })), + setNickname: nickname => set(() => ({ nickname })), + reset: () => set(() => ({ ...initialState })), + }), + { + name: "registration-flow", + storage: createJSONStorage(() => AsyncStorage), + } + ) +); + +export default useRegistrationStore; diff --git a/src/stores/useTokenStore.ts b/src/stores/useTokenStore.ts index dfde0e5..c89c976 100644 --- a/src/stores/useTokenStore.ts +++ b/src/stores/useTokenStore.ts @@ -6,6 +6,11 @@ interface TokenStore { accessToken: string; refreshToken: string; userId: string; + setAuth: (payload: { + accessToken: string; + refreshToken: string; + userId: string; + }) => void; setAccessToken: (token: string) => void; setRefreshToken: (token: string) => void; setUserId: (id: string) => void; @@ -19,15 +24,22 @@ const useTokenStore = create()( accessToken: "", refreshToken: "", userId: "", + setAuth: ({ accessToken, refreshToken, userId }) => + set({ accessToken, refreshToken, userId }), setAccessToken: token => set({ accessToken: token }), setRefreshToken: token => set({ refreshToken: token }), setUserId: id => set({ userId: id }), - clearTokens: () => set({ accessToken: "", refreshToken: "" }), + clearTokens: () => set({ accessToken: "", refreshToken: "", userId: "" }), hasHydrated: false, }), { name: "napulnapul-token", storage: createJSONStorage(() => AsyncStorage), + partialize: state => ({ + accessToken: state.accessToken, + refreshToken: state.refreshToken, + userId: state.userId, + }), onRehydrateStorage: () => state => { if (state) state.hasHydrated = true; }, diff --git a/src/types/avatars/index.ts b/src/types/avatars/index.ts new file mode 100644 index 0000000..34d48f4 --- /dev/null +++ b/src/types/avatars/index.ts @@ -0,0 +1,42 @@ +export type RegistrationMode = "selection" | "creation"; + +export interface AvatarMaster { + id: number; + defaultImageUrl: string; + description: string; +} + +export interface SelectAvatarResponse { + isSuccess: boolean; + code: string; + message: string; + result: AvatarMaster[]; +} + +export interface UploadCreationAvatarResponse { + imageUrl: string; +} + +export interface FinalChoiceAvatarRequest { + nickname: string; + imageUrl: string; + masterId: number | null; +} + +export interface FinalChoiceAvatarResponse { + isSuccess: boolean; + code: string; + message: string; + result: null; +} + +export interface RegistrationCreationDetail { + imageUri: string; + uploadedImageUrl: string; +} + +export interface RegistrationAvatarPreview { + masterId: number | null; + description: string; + imageUrl: string | null; +} diff --git a/src/types/axios.d.ts b/src/types/axios.d.ts new file mode 100644 index 0000000..4bc6897 --- /dev/null +++ b/src/types/axios.d.ts @@ -0,0 +1,13 @@ +import "axios"; + +declare module "axios" { + interface AxiosRequestConfig { + _skipAuth?: boolean; + _retry?: boolean; + } + + interface InternalAxiosRequestConfig { + _skipAuth?: boolean; + _retry?: boolean; + } +} diff --git a/src/types/delivery/index.ts b/src/types/delivery/index.ts new file mode 100644 index 0000000..5206f8c --- /dev/null +++ b/src/types/delivery/index.ts @@ -0,0 +1,15 @@ +export interface DeliverablePlant { + seedType: number; + imageUrl: string; + name: string; +} + +export interface CreateSeedDeliveryRequest { + seedType: number; + recipientName: string; + recipientPhone: string; + postalCode: string; + address: string; + addressDetail: string; + message?: string; +} diff --git a/src/types/follow/index.ts b/src/types/follow/index.ts new file mode 100644 index 0000000..8eb7d12 --- /dev/null +++ b/src/types/follow/index.ts @@ -0,0 +1,9 @@ +export interface User { + userId: number; + username: string; + userImageUrl: string | null; +} + +export interface FollowResponse { + result: User[]; +} diff --git a/src/types/home/garden.ts b/src/types/home/garden.ts index b3583b2..9ed3076 100644 --- a/src/types/home/garden.ts +++ b/src/types/home/garden.ts @@ -4,12 +4,16 @@ export interface Avatar { avatarImageUrl: string; } +export type HomeMissionType = "DIARY" | "QUIZ" | "CHECKING"; + export interface GardenSummary { gardenId: number; gardenSlotNumber: number; avatar?: Avatar | null; - locked: boolean; - unlockable: boolean; + isLocked?: boolean; + isUnlockable?: boolean; + locked?: boolean; + unlockable?: boolean; ownerWateringAble: boolean | null; ownerSunlightAble: boolean; } @@ -17,8 +21,9 @@ export interface GardenSummary { export interface TodayMission { missionId: number; missionTitle: string; - missionType: string; - completed: boolean; + missionType: HomeMissionType | string; + isCompleted?: boolean; + completed?: boolean; } export interface UserInfo { @@ -35,3 +40,27 @@ export interface HomeSummaryPayload { gardenSummaries: GardenSummary[]; todayMissions: TodayMission[]; } + +export const getGardenLocked = (garden: GardenSummary) => + garden.isLocked ?? garden.locked ?? false; + +export const getGardenUnlockable = (garden: GardenSummary) => + garden.isUnlockable ?? garden.unlockable ?? false; + +export const getMissionCompleted = (mission: TodayMission) => + mission.isCompleted ?? mission.completed ?? false; + +export const normalizeHomeSummaryPayload = ( + payload: HomeSummaryPayload +): HomeSummaryPayload => ({ + ...payload, + gardenSummaries: payload.gardenSummaries.map(garden => ({ + ...garden, + isLocked: getGardenLocked(garden), + isUnlockable: getGardenUnlockable(garden), + })), + todayMissions: payload.todayMissions.map(mission => ({ + ...mission, + isCompleted: getMissionCompleted(mission), + })), +}); diff --git a/src/types/missions/index.ts b/src/types/missions/index.ts new file mode 100644 index 0000000..5d88a4c --- /dev/null +++ b/src/types/missions/index.ts @@ -0,0 +1,101 @@ +export type MissionQuizType = "MULTI_CHOICE" | "OX"; +export type SurveyAnswerKind = "YES" | "NEUTRAL" | "NO"; +export type SurveyAnswerValue = 1 | 2 | 3; + +export const SURVEY_ANSWER_VALUE_MAP: Record = { + YES: 1, + NEUTRAL: 2, + NO: 3, +}; + +export interface DiaryImageUploadResult { + imageId: number; + imageUrl: string; +} + +export interface DiaryImageUploadResponse { + isSuccess: boolean; + code: string; + message: string; + result: DiaryImageUploadResult; +} + +export interface WriteDiaryRequest { + title: string; + content: string; + isPublic: boolean; + imageId: number; + imageUrl: string; +} + +export interface WriteDiaryResponse { + isSuccess: boolean; + code: string; + message: string; + result: string; +} + +export interface QuizOption { + optionOrder: number; + optionText: string; +} + +export interface MissionQuiz { + quizId: number; + quizQuestion: string; + quizOptions?: QuizOption[] | null; +} + +export interface GetQuizRequest { + quizType: MissionQuizType; +} + +export interface GetQuizResponse { + isSuccess: boolean; + code: string; + message: string; + result: MissionQuiz; +} + +export interface AnswerQuizRequest { + quizId: number; + selectedOptionOrder: number; +} + +export interface AnswerQuizResult { + isCorrect: boolean; + answerDescription: string; + answerNumber: number; +} + +export interface AnswerQuizResponse { + isSuccess: boolean; + code: string; + message: string; + result: AnswerQuizResult; +} + +export interface DailySurvey { + id: number; + question: string; + isAnswered: boolean; +} + +export interface GetDailySurveyResponse { + isSuccess: boolean; + code: string; + message: string; + result: DailySurvey; +} + +export interface AnswerDailySurveyRequest { + questionId: number; + answer: SurveyAnswerValue; +} + +export interface AnswerDailySurveyResponse { + isSuccess: boolean; + code: string; + message: string; + result: null; +} diff --git a/src/types/profile/profileApi.type.ts b/src/types/profile/profileApi.type.ts new file mode 100644 index 0000000..c669853 --- /dev/null +++ b/src/types/profile/profileApi.type.ts @@ -0,0 +1,29 @@ +export type AvatarInfo = { + avatarId: number; + avatarName: string; + avatarImageUrl: string; +}; + +export type GardenInfo = { + gardenId: number; + avatarInfo: AvatarInfo | null; + isWateringAbleByMe: boolean; +}; + +export enum FollowStatus { + NOT_FOLLOWING = "NOT_FOLLOWING", + FOLLOWING = "FOLLOWING", + FOLLOW_BACK_POSSIBLE = "FOLLOW_BACK_POSSIBLE", +} + +export type GetUserProfileResponse = { + id: number; + userNickname: string; + profileImageUrl: string | null; + followStatus: FollowStatus; + leftWaterCountForOthers: number; + userGardens: GardenInfo[]; +}; + +export type FriendWaterResponse = string; +export type FollowUserResponse = string; diff --git a/src/types/svg.d.ts b/src/types/svg.d.ts new file mode 100644 index 0000000..624fca2 --- /dev/null +++ b/src/types/svg.d.ts @@ -0,0 +1,6 @@ +declare module "*.svg" { + import React from "react"; + import { SvgProps } from "react-native-svg"; + const content: React.FC; + export default content; +} diff --git a/src/utils/auth.ts b/src/utils/auth.ts new file mode 100644 index 0000000..d0138c0 --- /dev/null +++ b/src/utils/auth.ts @@ -0,0 +1,12 @@ +import { supabase } from "@/apis/supabase"; +import useTokenStore from "@/stores/useTokenStore"; + +export const logout = async () => { + useTokenStore.getState().clearTokens(); + + try { + await supabase.auth.signOut(); + } catch (error) { + console.error("[auth] Failed to clear Supabase session:", error); + } +}; diff --git a/ts_errors.log b/ts_errors.log new file mode 100644 index 0000000000000000000000000000000000000000..eeed1be68da84ecd98902ae1771cb81124213e48 GIT binary patch literal 10184 zcmeHN+iuf95S?cv{=w=4DH3Xko8F)*LP1ECxKuO`yyjxNp@|bEZb^XtI&jX6-K0rM zC0Gls6j{00J3Bjjc4mCM<6l1~GM0{1r6m&_k!1L;N)OkDlInl{8{ptMTTm%TM+c zlRd|=Lrezn6UMtwnPgwlaGgmyaseDNuaG!UBY8iQ|}3j6%r5A@ADjGMZCiYw6Y%{Pphx{j3s zjWgsA{`V`Nma|j(S!;3sXQy-o=93^=S(}WJ*ZVkz@)c)q7tYSXjad2PJ_FZ@o;_IyU93hfV!&A@xg2v?RX#0US&zk`KH2j5 z_C9WUAp3HpXncU3tgiA2eyn)6z${p;W#xb@)Ue>3X)$NbT3kQ3JHVBXE4^!~lk?|p z6fxOGO_mko5p>upu)3VdDNr6E`Z8csw42pUjC@z3qPh}{PiyDvu;?pA6_~TJ3bo-& zJ9#Xw{&$=c<5(>swlU_?mM{3ny7Mulmu(2-2YRJi$L`CCyu=yTaRx*p)kCeZo=x?f zvIA(PMUHA~VU>;^OqXzm&SNE-1@g|zf{cm)n5p=ME9%1dM zkM;2TG_I2@X5aXuHP`A7SNTkqZRK29ec?L+jO{`vt$w2(#o3sr9mA)17^(xbric^9 zc>;-xwKJukP9K!I(a1LcEuz}qh2XPi3LR}-G5QqaVg3$5MLm=ePHQIk?#OGj+m*I@ zu0_Zb^gD&jUD<}N0pGe<*K3`Joj?zD(I2_aM6eJ4S|>Y?nUmX0Qg}Lli*~L%=fp@{ z#g*?@tY$rWzU3(9hZHitqq3T(Ld?qY^xxzuW;T0+Cc|1WSJA8K>9aiZ7T!+3uq?O9 fVM(5wHaV=gBW!Y*@q$ebo9Brlb5C$LEI8tC#5VAM literal 0 HcmV?d00001 diff --git a/ts_final.txt b/ts_final.txt new file mode 100644 index 0000000..4c3691f --- /dev/null +++ b/ts_final.txt @@ -0,0 +1,28 @@ +src/assets/icons/common/index.ts(1,37): error TS2307: Cannot find module './bookmark1.svg?react' or its corresponding type declarations. +src/assets/icons/common/index.ts(2,43): error TS2307: Cannot find module './bookmark2.svg?react' or its corresponding type declarations. +src/assets/icons/common/index.ts(3,43): error TS2307: Cannot find module './calendar1.svg?react' or its corresponding type declarations. +src/assets/icons/common/index.ts(4,37): error TS2307: Cannot find module './calendar2.svg?react' or its corresponding type declarations. +src/assets/icons/common/index.ts(5,35): error TS2307: Cannot find module './camera.svg?react' or its corresponding type declarations. +src/assets/icons/common/index.ts(6,33): error TS2307: Cannot find module './chat.svg?react' or its corresponding type declarations. +src/assets/icons/common/index.ts(7,34): error TS2307: Cannot find module './Check.svg?react' or its corresponding type declarations. +src/assets/icons/common/index.ts(8,36): error TS2307: Cannot find module './Check2.svg?react' or its corresponding type declarations. +src/assets/icons/common/index.ts(9,33): error TS2307: Cannot find module './edit.svg?react' or its corresponding type declarations. +src/assets/icons/common/index.ts(10,34): error TS2307: Cannot find module './heart.svg?react' or its corresponding type declarations. +src/assets/icons/common/index.ts(11,39): error TS2307: Cannot find module './home1.svg?react' or its corresponding type declarations. +src/assets/icons/common/index.ts(12,33): error TS2307: Cannot find module './home2.svg?react' or its corresponding type declarations. +src/assets/icons/common/index.ts(13,33): error TS2307: Cannot find module './left.svg?react' or its corresponding type declarations. +src/assets/icons/common/index.ts(14,35): error TS2307: Cannot find module './level0.svg?react' or its corresponding type declarations. +src/assets/icons/common/index.ts(15,35): error TS2307: Cannot find module './level1.svg?react' or its corresponding type declarations. +src/assets/icons/common/index.ts(16,35): error TS2307: Cannot find module './level2.svg?react' or its corresponding type declarations. +src/assets/icons/common/index.ts(17,35): error TS2307: Cannot find module './level3.svg?react' or its corresponding type declarations. +src/assets/icons/common/index.ts(18,34): error TS2307: Cannot find module './right.svg?react' or its corresponding type declarations. +src/assets/icons/common/index.ts(19,41): error TS2307: Cannot find module './search1.svg?react' or its corresponding type declarations. +src/assets/icons/common/index.ts(20,35): error TS2307: Cannot find module './search2.svg?react' or its corresponding type declarations. +src/assets/icons/common/index.ts(21,33): error TS2307: Cannot find module './send.svg?react' or its corresponding type declarations. +src/assets/icons/common/index.ts(22,36): error TS2307: Cannot find module './togle1.svg?react' or its corresponding type declarations. +src/assets/icons/common/index.ts(23,37): error TS2307: Cannot find module './togle2.svg?react' or its corresponding type declarations. +src/assets/icons/common/index.ts(24,39): error TS2307: Cannot find module './user1.svg?react' or its corresponding type declarations. +src/assets/icons/common/index.ts(25,33): error TS2307: Cannot find module './user2.svg?react' or its corresponding type declarations. +src/assets/icons/common/index.ts(26,37): error TS2307: Cannot find module './userPlus.svg?react' or its corresponding type declarations. +src/assets/icons/common/index.ts(27,34): error TS2307: Cannot find module './Xmack.svg?react' or its corresponding type declarations. +src/pages/follow/FollowScreen.tsx(4,33): error TS2344: Type '"Follow"' does not satisfy the constraint 'keyof MainTabParamList'. From 4e5faffb95775b29dbae3faa047cc43b68ae959d Mon Sep 17 00:00:00 2001 From: lejuho Date: Thu, 12 Mar 2026 13:26:06 +0900 Subject: [PATCH 02/92] =?UTF-8?q?chore=20:=20=EC=B9=B4=EC=B9=B4=EC=98=A4?= =?UTF-8?q?=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EB=94=94=EB=B2=84=EA=B9=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 3 + App.tsx | 56 +- app.json | 12 +- package-lock.json | 827 +++++++++++----------- package.json | 17 +- src/apis/supabase.ts | 86 ++- src/hooks/auth/useSupabaseOAuth.ts | 303 ++++++-- src/navigation/MainTabNavigator.tsx | 9 +- src/navigation/RootNavigator.tsx | 70 +- src/pages/home/HomeScreen.tsx | 62 +- src/pages/onboarding/OnboardingScreen.tsx | 79 ++- src/pages/register/RegisterScreen.tsx | 26 +- src/utils/debug.ts | 12 + 13 files changed, 916 insertions(+), 646 deletions(-) create mode 100644 .env create mode 100644 src/utils/debug.ts diff --git a/.env b/.env new file mode 100644 index 0000000..837439f --- /dev/null +++ b/.env @@ -0,0 +1,3 @@ +EXPO_PUBLIC_SUPABASE_URL=https://zgjxxldhyhofpmrwdsbh.supabase.co +EXPO_PUBLIC_SUPABASE_ANON_KEY=sb_publishable_oYSlVmJ2B9e6-eHsuXyzrw_Ca79lPnr +# EXPO_PUBLIC_API_URL=http://192.168.168.87:8080 diff --git a/App.tsx b/App.tsx index df060c6..2119669 100644 --- a/App.tsx +++ b/App.tsx @@ -1,15 +1,65 @@ import "./global.css"; +import { useEffect, useRef } from "react"; import { StatusBar } from "expo-status-bar"; -import { NavigationContainer } from "@react-navigation/native"; -import { SafeAreaProvider } from "react-native-safe-area-context"; +import { + NavigationContainer, + useNavigationContainerRef, +} from "@react-navigation/native"; +import { SafeAreaProvider, SafeAreaView } from "react-native-safe-area-context"; import { RootNavigator } from "@/navigation"; import QueryProvider from "@/providers/QueryProvider"; +import StatusView from "@/components/common/StatusView"; +import { + SUPABASE_CONFIG_ERROR_MESSAGE, + isSupabaseConfigured, +} from "@/apis/supabase"; +import { debugLog } from "@/utils/debug"; export default function App() { + const navigationRef = useNavigationContainerRef(); + const currentRouteNameRef = useRef(undefined); + + useEffect(() => { + debugLog("App", "App mounted", { isSupabaseConfigured }); + }, []); + + if (!isSupabaseConfigured) { + return ( + + + + + + ); + } + return ( - + { + const routeName = navigationRef.getCurrentRoute()?.name; + currentRouteNameRef.current = routeName; + debugLog("Navigation", "ready", { routeName }); + }} + onStateChange={() => { + const previousRouteName = currentRouteNameRef.current; + const nextRouteName = navigationRef.getCurrentRoute()?.name; + + if (previousRouteName !== nextRouteName) { + debugLog("Navigation", "route changed", { + from: previousRouteName, + to: nextRouteName, + }); + } + + currentRouteNameRef.current = nextRouteName; + }} + > diff --git a/app.json b/app.json index 27bd69e..702577c 100644 --- a/app.json +++ b/app.json @@ -7,7 +7,7 @@ "orientation": "portrait", "icon": "./assets/icon.png", "userInterfaceStyle": "light", - "newArchEnabled": false, + "newArchEnabled": true, "splash": { "image": "./assets/splash-icon.png", "resizeMode": "contain", @@ -22,10 +22,16 @@ "backgroundColor": "#ffffff" }, "edgeToEdgeEnabled": true, - "predictiveBackGestureEnabled": false + "predictiveBackGestureEnabled": false, + "package": "com.anonymous.haniumapp" }, "web": { "favicon": "./assets/favicon.png" - } + }, + "plugins": [ + "expo-dev-client", + "expo-secure-store", + "expo-web-browser" + ] } } diff --git a/package-lock.json b/package-lock.json index 2e47326..90d748c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,15 +16,16 @@ "@supabase/supabase-js": "^2.98.0", "@tanstack/react-query": "^5.90.19", "axios": "^1.13.2", - "babel-preset-expo": "~54.0.9", - "expo": "~54.0.31", - "expo-auth-session": "^55.0.7", - "expo-crypto": "^55.0.9", + "babel-preset-expo": "~54.0.10", + "expo": "~54.0.33", + "expo-auth-session": "~7.0.10", + "expo-crypto": "~15.0.8", + "expo-dev-client": "~6.0.20", "expo-image-picker": "~17.0.10", "expo-linking": "~8.0.11", - "expo-secure-store": "^55.0.8", + "expo-secure-store": "~15.0.8", "expo-status-bar": "~3.0.9", - "expo-web-browser": "^55.0.9", + "expo-web-browser": "~15.0.10", "nativewind": "^4.2.1", "react": "19.1.0", "react-dom": "19.1.0", @@ -2134,26 +2135,161 @@ "metro-transform-worker": "0.83.3" } }, - "node_modules/@expo/osascript": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.3.8.tgz", - "integrity": "sha512-/TuOZvSG7Nn0I8c+FcEaoHeBO07yu6vwDgk7rZVvAXoeAK5rkA09jRyjYsZo+0tMEFaToBeywA6pj50Mb3ny9w==", + "node_modules/@expo/metro-config": { + "version": "54.0.14", + "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-54.0.14.tgz", + "integrity": "sha512-hxpLyDfOR4L23tJ9W1IbJJsG7k4lv2sotohBm/kTYyiG+pe1SYCAWsRmgk+H42o/wWf/HQjE5k45S5TomGLxNA==", "license": "MIT", "dependencies": { + "@babel/code-frame": "^7.20.0", + "@babel/core": "^7.20.0", + "@babel/generator": "^7.20.5", + "@expo/config": "~12.0.13", + "@expo/env": "~2.0.8", + "@expo/json-file": "~10.0.8", + "@expo/metro": "~54.2.0", "@expo/spawn-async": "^1.7.2", - "exec-async": "^2.2.0" + "browserslist": "^4.25.0", + "chalk": "^4.1.0", + "debug": "^4.3.2", + "dotenv": "~16.4.5", + "dotenv-expand": "~11.0.6", + "getenv": "^2.0.0", + "glob": "^13.0.0", + "hermes-parser": "^0.29.1", + "jsc-safe-url": "^0.2.4", + "lightningcss": "^1.30.1", + "minimatch": "^9.0.0", + "postcss": "~8.4.32", + "resolve-from": "^5.0.0" + }, + "peerDependencies": { + "expo": "*" + }, + "peerDependenciesMeta": { + "expo": { + "optional": true + } + } + }, + "node_modules/@expo/metro-config/node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@expo/metro-config/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@expo/metro-config/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@expo/metro-config/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@expo/metro-config/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/@expo/metro-config/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@expo/metro-config/node_modules/hermes-estree": { + "version": "0.29.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.29.1.tgz", + "integrity": "sha512-jl+x31n4/w+wEqm0I2r4CMimukLbLQEYpisys5oCre611CI5fc9TxhqkBBCJ1edDG4Kza0f7CgNz8xVMLZQOmQ==", + "license": "MIT" + }, + "node_modules/@expo/metro-config/node_modules/hermes-parser": { + "version": "0.29.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.29.1.tgz", + "integrity": "sha512-xBHWmUtRC5e/UL0tI7Ivt2riA/YBq9+SiYFU7C1oBa/j2jYGlIF9043oak1F47ihuDIxQ5nbsKueYJDRY02UgA==", + "license": "MIT", + "dependencies": { + "hermes-estree": "0.29.1" + } + }, + "node_modules/@expo/metro-config/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@expo/osascript": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.4.2.tgz", + "integrity": "sha512-/XP7PSYF2hzOZzqfjgkoWtllyeTN8dW3aM4P6YgKcmmPikKL5FdoyQhti4eh6RK5a5VrUXJTOlTNIpIHsfB5Iw==", + "license": "MIT", + "dependencies": { + "@expo/spawn-async": "^1.7.2" }, "engines": { "node": ">=12" } }, "node_modules/@expo/package-manager": { - "version": "1.9.10", - "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.9.10.tgz", - "integrity": "sha512-axJm+NOj3jVxep49va/+L3KkF3YW/dkV+RwzqUJedZrv4LeTqOG4rhrCaCPXHTvLqCTDKu6j0Xyd28N7mnxsGA==", + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.10.3.tgz", + "integrity": "sha512-ZuXiK/9fCrIuLjPSe1VYmfp0Sa85kCMwd8QQpgyi5ufppYKRtLBg14QOgUqj8ZMbJTxE0xqzd0XR7kOs3vAK9A==", "license": "MIT", "dependencies": { - "@expo/json-file": "^10.0.8", + "@expo/json-file": "^10.0.12", "@expo/spawn-async": "^1.7.2", "chalk": "^4.0.0", "npm-package-arg": "^11.0.0", @@ -2242,37 +2378,25 @@ "xmlbuilder": "^15.1.1" } }, - "node_modules/@expo/require-utils": { - "version": "55.0.2", - "resolved": "https://registry.npmjs.org/@expo/require-utils/-/require-utils-55.0.2.tgz", - "integrity": "sha512-dV5oCShQ1umKBKagMMT4B/N+SREsQe3lU4Zgmko5AO0rxKV0tynZT6xXs+e2JxuqT4Rz997atg7pki0BnZb4uw==", + "node_modules/@expo/prebuild-config": { + "version": "54.0.8", + "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-54.0.8.tgz", + "integrity": "sha512-EA7N4dloty2t5Rde+HP0IEE+nkAQiu4A/+QGZGT9mFnZ5KKjPPkqSyYcRvP5bhQE10D+tvz6X0ngZpulbMdbsg==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.20.0", - "@babel/core": "^7.25.2", - "@babel/plugin-transform-modules-commonjs": "^7.24.8" + "@expo/config": "~12.0.13", + "@expo/config-plugins": "~54.0.4", + "@expo/config-types": "^54.0.10", + "@expo/image-utils": "^0.8.8", + "@expo/json-file": "^10.0.8", + "@react-native/normalize-colors": "0.81.5", + "debug": "^4.3.1", + "resolve-from": "^5.0.0", + "semver": "^7.6.0", + "xml2js": "0.6.0" }, "peerDependencies": { - "typescript": "^5.0.0 || ^5.0.0-0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@expo/require-utils/node_modules/@babel/code-frame": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", - "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.28.5", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" + "expo": "*" } }, "node_modules/@expo/schema-utils": { @@ -2312,20 +2436,33 @@ "license": "MIT" }, "node_modules/@expo/xcpretty": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@expo/xcpretty/-/xcpretty-4.3.2.tgz", - "integrity": "sha512-ReZxZ8pdnoI3tP/dNnJdnmAk7uLT4FjsKDGW7YeDdvdOMz2XCQSmSCM9IWlrXuWtMF9zeSB6WJtEhCQ41gQOfw==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@expo/xcpretty/-/xcpretty-4.4.1.tgz", + "integrity": "sha512-KZNxZvnGCtiM2aYYZ6Wz0Ix5r47dAvpNLApFtZWnSoERzAdOMzVBOPysBoM0JlF6FKWZ8GPqgn6qt3dV/8Zlpg==", "license": "BSD-3-Clause", "dependencies": { - "@babel/code-frame": "7.10.4", + "@babel/code-frame": "^7.20.0", "chalk": "^4.1.0", - "find-up": "^5.0.0", "js-yaml": "^4.1.0" }, "bin": { "excpretty": "build/cli.js" } }, + "node_modules/@expo/xcpretty/node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@expo/xcpretty/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -2381,22 +2518,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, - "node_modules/@expo/xcpretty/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@expo/xcpretty/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -2418,36 +2539,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/@expo/xcpretty/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@expo/xcpretty/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@expo/xcpretty/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -3926,6 +4017,22 @@ "node": ">= 14" } }, + "node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/anser": { "version": "1.4.10", "resolved": "https://registry.npmjs.org/anser/-/anser-1.4.10.tgz", @@ -4387,9 +4494,9 @@ } }, "node_modules/babel-preset-expo": { - "version": "54.0.9", - "resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-54.0.9.tgz", - "integrity": "sha512-8J6hRdgEC2eJobjoft6mKJ294cLxmi3khCUy2JJQp4htOYYkllSLUq6vudWJkTJiIuGdVR4bR6xuz2EvJLWHNg==", + "version": "54.0.10", + "resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-54.0.10.tgz", + "integrity": "sha512-wTt7POavLFypLcPW/uC5v8y+mtQKDJiyGLzYCjqr9tx0Qc3vCXcDKk1iCFIj/++Iy5CWhhTflEa7VvVPNWeCfw==", "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.25.9", @@ -5685,33 +5792,27 @@ "node": ">=6" } }, - "node_modules/exec-async": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/exec-async/-/exec-async-2.2.0.tgz", - "integrity": "sha512-87OpwcEiMia/DeiKFzaQNBNFeN3XkkpYIh9FyOqq5mS2oKv3CBE67PXoEKcr6nodWdXNogTiQ0jE2NGuoffXPw==", - "license": "MIT" - }, "node_modules/expo": { - "version": "54.0.31", - "resolved": "https://registry.npmjs.org/expo/-/expo-54.0.31.tgz", - "integrity": "sha512-kQ3RDqA/a59I7y+oqQGyrPbbYlgPMUdKBOgvFLpoHbD2bCM+F75i4N0mUijy7dG5F/CUCu2qHmGGUCXBbMDkCg==", + "version": "54.0.33", + "resolved": "https://registry.npmjs.org/expo/-/expo-54.0.33.tgz", + "integrity": "sha512-3yOEfAKqo+gqHcV8vKcnq0uA5zxlohnhA3fu4G43likN8ct5ZZ3LjAh9wDdKteEkoad3tFPvwxmXW711S5OHUw==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.20.0", - "@expo/cli": "54.0.21", + "@expo/cli": "54.0.23", "@expo/config": "~12.0.13", "@expo/config-plugins": "~54.0.4", "@expo/devtools": "0.1.8", "@expo/fingerprint": "0.15.4", "@expo/metro": "~54.2.0", - "@expo/metro-config": "54.0.13", + "@expo/metro-config": "54.0.14", "@expo/vector-icons": "^15.0.3", "@ungap/structured-clone": "^1.3.0", - "babel-preset-expo": "~54.0.9", + "babel-preset-expo": "~54.0.10", "expo-asset": "~12.0.12", "expo-constants": "~18.0.13", "expo-file-system": "~19.0.21", - "expo-font": "~14.0.10", + "expo-font": "~14.0.11", "expo-keep-awake": "~15.0.8", "expo-modules-autolinking": "3.0.24", "expo-modules-core": "3.0.29", @@ -5744,16 +5845,16 @@ } }, "node_modules/expo-auth-session": { - "version": "55.0.7", - "resolved": "https://registry.npmjs.org/expo-auth-session/-/expo-auth-session-55.0.7.tgz", - "integrity": "sha512-SWFudyF7K6924cSgPFrtK637aXj6HSs+DO6cP0q5xfwlcLaekkcoOHIrhpy8qaUIpxf7w01Dsk5fwu5RLse4eg==", + "version": "7.0.10", + "resolved": "https://registry.npmjs.org/expo-auth-session/-/expo-auth-session-7.0.10.tgz", + "integrity": "sha512-XDnKkudvhHSKkZfJ+KkodM+anQcrxB71i+h0kKabdLa5YDXTQ81aC38KRc3TMqmnBDHAu0NpfbzEVd9WDFY3Qg==", "license": "MIT", "dependencies": { - "expo-application": "~55.0.8", - "expo-constants": "~55.0.7", - "expo-crypto": "~55.0.9", - "expo-linking": "~55.0.7", - "expo-web-browser": "~55.0.9", + "expo-application": "~7.0.8", + "expo-constants": "~18.0.11", + "expo-crypto": "~15.0.8", + "expo-linking": "~8.0.10", + "expo-web-browser": "~15.0.10", "invariant": "^2.2.4" }, "peerDependencies": { @@ -5761,191 +5862,104 @@ "react-native": "*" } }, - "node_modules/expo-auth-session/node_modules/@expo/config": { - "version": "55.0.8", - "resolved": "https://registry.npmjs.org/@expo/config/-/config-55.0.8.tgz", - "integrity": "sha512-D7RYYHfErCgEllGxNwdYdkgzLna7zkzUECBV3snbUpf7RvIpB5l1LpCgzuVoc5KVew5h7N1Tn4LnT/tBSUZsQg==", - "license": "MIT", - "dependencies": { - "@expo/config-plugins": "~55.0.6", - "@expo/config-types": "^55.0.5", - "@expo/json-file": "^10.0.12", - "@expo/require-utils": "^55.0.2", - "deepmerge": "^4.3.1", - "getenv": "^2.0.0", - "glob": "^13.0.0", - "resolve-from": "^5.0.0", - "resolve-workspace-root": "^2.0.0", - "semver": "^7.6.0", - "slugify": "^1.3.4" - } - }, - "node_modules/expo-auth-session/node_modules/@expo/config-plugins": { - "version": "55.0.6", - "resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-55.0.6.tgz", - "integrity": "sha512-cIox6FjZlFaaX40rbQ3DvP9e87S5X85H9uw+BAxJE5timkMhuByy3GAlOsj1h96EyzSiol7Q6YIGgY1Jiz4M+A==", - "license": "MIT", - "dependencies": { - "@expo/config-types": "^55.0.5", - "@expo/json-file": "~10.0.12", - "@expo/plist": "^0.5.2", - "@expo/sdk-runtime-versions": "^1.0.0", - "chalk": "^4.1.2", - "debug": "^4.3.5", - "getenv": "^2.0.0", - "glob": "^13.0.0", - "resolve-from": "^5.0.0", - "semver": "^7.5.4", - "slugify": "^1.6.6", - "xcode": "^3.0.1", - "xml2js": "0.6.0" - } - }, - "node_modules/expo-auth-session/node_modules/@expo/config-types": { - "version": "55.0.5", - "resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-55.0.5.tgz", - "integrity": "sha512-sCmSUZG4mZ/ySXvfyyBdhjivz8Q539X1NondwDdYG7s3SBsk+wsgPJzYsqgAG/P9+l0xWjUD2F+kQ1cAJ6NNLg==", - "license": "MIT" - }, - "node_modules/expo-auth-session/node_modules/@expo/env": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@expo/env/-/env-2.1.1.tgz", - "integrity": "sha512-rVvHC4I6xlPcg+mAO09ydUi2Wjv1ZytpLmHOSzvXzBAz9mMrJggqCe4s4dubjJvi/Ino/xQCLhbaLCnTtLpikg==", - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "debug": "^4.3.4", - "getenv": "^2.0.0" - }, - "engines": { - "node": ">=20.12.0" - } - }, - "node_modules/expo-auth-session/node_modules/@expo/plist": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.5.2.tgz", - "integrity": "sha512-o4xdVdBpe4aTl3sPMZ2u3fJH4iG1I768EIRk1xRZP+GaFI93MaR3JvoFibYqxeTmLQ1p1kNEVqylfUjezxx45g==", + "node_modules/expo-auth-session/node_modules/expo-application": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/expo-application/-/expo-application-7.0.8.tgz", + "integrity": "sha512-qFGyxk7VJbrNOQWBbE09XUuGuvkOgFS9QfToaK2FdagM2aQ+x3CvGV2DuVgl/l4ZxPgIf3b/MNh9xHpwSwn74Q==", "license": "MIT", - "dependencies": { - "@xmldom/xmldom": "^0.8.8", - "base64-js": "^1.5.1", - "xmlbuilder": "^15.1.1" + "peerDependencies": { + "expo": "*" } }, - "node_modules/expo-auth-session/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/expo-auth-session/node_modules/expo-constants": { + "version": "18.0.13", + "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-18.0.13.tgz", + "integrity": "sha512-FnZn12E1dRYKDHlAdIyNFhBurKTS3F9CrfrBDJI5m3D7U17KBHMQ6JEfYlSj7LG7t+Ulr+IKaj58L1k5gBwTcQ==", "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" + "@expo/config": "~12.0.13", + "@expo/env": "~2.0.8" }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "peerDependencies": { + "expo": "*", + "react-native": "*" } }, - "node_modules/expo-auth-session/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/expo-crypto": { + "version": "15.0.8", + "resolved": "https://registry.npmjs.org/expo-crypto/-/expo-crypto-15.0.8.tgz", + "integrity": "sha512-aF7A914TB66WIlTJvl5J6/itejfY78O7dq3ibvFltL9vnTALJ/7LYHvLT4fwmx9yUNS6ekLBtDGWivFWnj2Fcw==", "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" + "base64-js": "^1.3.0" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "peerDependencies": { + "expo": "*" } }, - "node_modules/expo-auth-session/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/expo-dev-client": { + "version": "6.0.20", + "resolved": "https://registry.npmjs.org/expo-dev-client/-/expo-dev-client-6.0.20.tgz", + "integrity": "sha512-5XjoVlj1OxakNxy55j/AUaGPrDOlQlB6XdHLLWAw61w5ffSpUDHDnuZzKzs9xY1eIaogOqTOQaAzZ2ddBkdXLA==", "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "expo-dev-launcher": "6.0.20", + "expo-dev-menu": "7.0.18", + "expo-dev-menu-interface": "2.0.0", + "expo-manifests": "~1.0.10", + "expo-updates-interface": "~2.0.0" }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/expo-auth-session/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/expo-auth-session/node_modules/expo-application": { - "version": "55.0.8", - "resolved": "https://registry.npmjs.org/expo-application/-/expo-application-55.0.8.tgz", - "integrity": "sha512-PeZk4Zj8LlzRcRtK3J4ouSPBoi9lroYsRbbz/0HEvx+uB6HIaM1qfzgpcctvjkdJJfnidBQNyieW5BVO/qUQ6w==", - "license": "MIT", "peerDependencies": { "expo": "*" } }, - "node_modules/expo-auth-session/node_modules/expo-constants": { - "version": "55.0.7", - "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-55.0.7.tgz", - "integrity": "sha512-kdcO4TsQRRqt0USvjaY5vgQMO9H52K3kBZ/ejC7F6rz70mv08GoowrZ1CYOr5O4JpPDRlIpQfZJUucaS/c+KWQ==", + "node_modules/expo-dev-launcher": { + "version": "6.0.20", + "resolved": "https://registry.npmjs.org/expo-dev-launcher/-/expo-dev-launcher-6.0.20.tgz", + "integrity": "sha512-a04zHEeT9sB0L5EB38fz7sNnUKJ2Ar1pXpcyl60Ki8bXPNCs9rjY7NuYrDkP/irM8+1DklMBqHpyHiLyJ/R+EA==", "license": "MIT", "dependencies": { - "@expo/config": "~55.0.8", - "@expo/env": "~2.1.1" + "ajv": "^8.11.0", + "expo-dev-menu": "7.0.18", + "expo-manifests": "~1.0.10" }, "peerDependencies": { - "expo": "*", - "react-native": "*" + "expo": "*" } }, - "node_modules/expo-auth-session/node_modules/expo-linking": { - "version": "55.0.7", - "resolved": "https://registry.npmjs.org/expo-linking/-/expo-linking-55.0.7.tgz", - "integrity": "sha512-MiGCedere1vzQTEi2aGrkzd7eh/rPSz4w6F3GMBuAJzYl+/0VhIuyhozpEGrueyDIXWfzaUVOcn3SfxVi+kwQQ==", + "node_modules/expo-dev-menu": { + "version": "7.0.18", + "resolved": "https://registry.npmjs.org/expo-dev-menu/-/expo-dev-menu-7.0.18.tgz", + "integrity": "sha512-4kTdlHrnZCAWCT6tZRQHSSjZ7vECFisL4T+nsG/GJDo/jcHNaOVGV5qPV9wzlTxyMk3YOPggRw4+g7Ownrg5eA==", "license": "MIT", "dependencies": { - "expo-constants": "~55.0.7", - "invariant": "^2.2.4" + "expo-dev-menu-interface": "2.0.0" }, "peerDependencies": { - "react": "*", - "react-native": "*" + "expo": "*" } }, - "node_modules/expo-auth-session/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/expo-dev-menu-interface": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/expo-dev-menu-interface/-/expo-dev-menu-interface-2.0.0.tgz", + "integrity": "sha512-BvAMPt6x+vyXpThsyjjOYyjwfjREV4OOpQkZ0tNl+nGpsPfcY9mc6DRACoWnH9KpLzyIt3BOgh3cuy/h/OxQjw==", "license": "MIT", - "engines": { - "node": ">=8" + "peerDependencies": { + "expo": "*" } }, - "node_modules/expo-auth-session/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/expo-font": { + "version": "14.0.11", + "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-14.0.11.tgz", + "integrity": "sha512-ga0q61ny4s/kr4k8JX9hVH69exVSIfcIc19+qZ7gt71Mqtm7xy2c6kwsPTCyhBW2Ro5yXTT8EaZOpuRi35rHbg==", "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "fontfaceobserver": "^2.1.0" }, - "engines": { - "node": ">=8" - } - }, - "node_modules/expo-crypto": { - "version": "55.0.9", - "resolved": "https://registry.npmjs.org/expo-crypto/-/expo-crypto-55.0.9.tgz", - "integrity": "sha512-hYiZYRPMXGQXSgKjp/m84l/6Uq8mTeMts1C7bFZXN5M5TUOiRhrLeqMSYZFXrAlkFpXeO46V+Ts1CFauMBLuCw==", - "license": "MIT", "peerDependencies": { - "expo": "*" + "expo": "*", + "react": "*", + "react-native": "*" } }, "node_modules/expo-image-loader": { @@ -5969,6 +5983,12 @@ "expo": "*" } }, + "node_modules/expo-json-utils": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/expo-json-utils/-/expo-json-utils-0.15.0.tgz", + "integrity": "sha512-duRT6oGl80IDzH2LD2yEFWNwGIC2WkozsB6HF3cDYNoNNdUvFk6uN3YiwsTsqVM/D0z6LEAQ01/SlYvN+Fw0JQ==", + "license": "MIT" + }, "node_modules/expo-linking": { "version": "8.0.11", "resolved": "https://registry.npmjs.org/expo-linking/-/expo-linking-8.0.11.tgz", @@ -5997,6 +6017,19 @@ "react-native": "*" } }, + "node_modules/expo-manifests": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/expo-manifests/-/expo-manifests-1.0.10.tgz", + "integrity": "sha512-oxDUnURPcL4ZsOBY6X1DGWGuoZgVAFzp6PISWV7lPP2J0r8u1/ucuChBgpK7u1eLGFp6sDIPwXyEUCkI386XSQ==", + "license": "MIT", + "dependencies": { + "@expo/config": "~12.0.11", + "expo-json-utils": "~0.15.0" + }, + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo-modules-autolinking": { "version": "3.0.24", "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-3.0.24.tgz", @@ -6097,9 +6130,9 @@ } }, "node_modules/expo-secure-store": { - "version": "55.0.8", - "resolved": "https://registry.npmjs.org/expo-secure-store/-/expo-secure-store-55.0.8.tgz", - "integrity": "sha512-8w9tQe8U6oRo5YIzqCqVhRrOnfoODNDoitBtLXEx+zS6WLUnkRq5kH7ViJuOgiM7PzLr9pvAliRiDOKyvFbTuQ==", + "version": "15.0.8", + "resolved": "https://registry.npmjs.org/expo-secure-store/-/expo-secure-store-15.0.8.tgz", + "integrity": "sha512-lHnzvRajBu4u+P99+0GEMijQMFCOYpWRO4dWsXSuMt77+THPIGjzNvVKrGSl6mMrLsfVaKL8BpwYZLGlgA+zAw==", "license": "MIT", "peerDependencies": { "expo": "*" @@ -6127,34 +6160,29 @@ "react-native": "*" } }, - "node_modules/expo-web-browser": { - "version": "55.0.9", - "resolved": "https://registry.npmjs.org/expo-web-browser/-/expo-web-browser-55.0.9.tgz", - "integrity": "sha512-PvAVsG401QmZabtTsYh1cYcpPiqvBPs8oiOkSrp0jIXnneiM466HxmeNtvo+fNxqJ2nwOBz9qLPiWRO91VBfsQ==", + "node_modules/expo-updates-interface": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/expo-updates-interface/-/expo-updates-interface-2.0.0.tgz", + "integrity": "sha512-pTzAIufEZdVPKql6iMi5ylVSPqV1qbEopz9G6TSECQmnNde2nwq42PxdFBaUEd8IZJ/fdJLQnOT3m6+XJ5s7jg==", "license": "MIT", "peerDependencies": { - "expo": "*", - "react-native": "*" + "expo": "*" } }, - "node_modules/expo/node_modules/@babel/code-frame": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz", - "integrity": "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==", + "node_modules/expo-web-browser": { + "version": "15.0.10", + "resolved": "https://registry.npmjs.org/expo-web-browser/-/expo-web-browser-15.0.10.tgz", + "integrity": "sha512-fvDhW4bhmXAeWFNFiInmsGCK83PAqAcQaFyp/3pE/jbdKmFKoRCWr46uZGIfN4msLK/OODhaQ/+US7GSJNDHJg==", "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.28.5", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" + "peerDependencies": { + "expo": "*", + "react-native": "*" } }, "node_modules/expo/node_modules/@expo/cli": { - "version": "54.0.21", - "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-54.0.21.tgz", - "integrity": "sha512-L/FdpyZDsg/Nq6xW6kfiyF9DUzKfLZCKFXEVZcDqCNar6bXxQVotQyvgexRvtUF5nLinuT/UafLOdC3FUALUmA==", + "version": "54.0.23", + "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-54.0.23.tgz", + "integrity": "sha512-km0h72SFfQCmVycH/JtPFTVy69w6Lx1cHNDmfLfQqgKFYeeHTjx7LVDP4POHCtNxFP2UeRazrygJhlh4zz498g==", "license": "MIT", "dependencies": { "@0no-co/graphql.web": "^1.0.8", @@ -6166,9 +6194,9 @@ "@expo/image-utils": "^0.8.8", "@expo/json-file": "^10.0.8", "@expo/metro": "~54.2.0", - "@expo/metro-config": "~54.0.13", + "@expo/metro-config": "~54.0.14", "@expo/osascript": "^2.3.8", - "@expo/package-manager": "^1.9.9", + "@expo/package-manager": "^1.9.10", "@expo/plist": "^0.4.8", "@expo/prebuild-config": "^54.0.8", "@expo/schema-utils": "^0.1.8", @@ -6238,64 +6266,6 @@ } } }, - "node_modules/expo/node_modules/@expo/cli/node_modules/@expo/prebuild-config": { - "version": "54.0.8", - "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-54.0.8.tgz", - "integrity": "sha512-EA7N4dloty2t5Rde+HP0IEE+nkAQiu4A/+QGZGT9mFnZ5KKjPPkqSyYcRvP5bhQE10D+tvz6X0ngZpulbMdbsg==", - "license": "MIT", - "dependencies": { - "@expo/config": "~12.0.13", - "@expo/config-plugins": "~54.0.4", - "@expo/config-types": "^54.0.10", - "@expo/image-utils": "^0.8.8", - "@expo/json-file": "^10.0.8", - "@react-native/normalize-colors": "0.81.5", - "debug": "^4.3.1", - "resolve-from": "^5.0.0", - "semver": "^7.6.0", - "xml2js": "0.6.0" - }, - "peerDependencies": { - "expo": "*" - } - }, - "node_modules/expo/node_modules/@expo/metro-config": { - "version": "54.0.13", - "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-54.0.13.tgz", - "integrity": "sha512-RRufMCgLR2Za1WGsh02OatIJo5qZFt31yCnIOSfoubNc3Qqe92Z41pVsbrFnmw5CIaisv1NgdBy05DHe7pEyuw==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.20.0", - "@babel/core": "^7.20.0", - "@babel/generator": "^7.20.5", - "@expo/config": "~12.0.13", - "@expo/env": "~2.0.8", - "@expo/json-file": "~10.0.8", - "@expo/metro": "~54.2.0", - "@expo/spawn-async": "^1.7.2", - "browserslist": "^4.25.0", - "chalk": "^4.1.0", - "debug": "^4.3.2", - "dotenv": "~16.4.5", - "dotenv-expand": "~11.0.6", - "getenv": "^2.0.0", - "glob": "^13.0.0", - "hermes-parser": "^0.29.1", - "jsc-safe-url": "^0.2.4", - "lightningcss": "^1.30.1", - "minimatch": "^9.0.0", - "postcss": "~8.4.32", - "resolve-from": "^5.0.0" - }, - "peerDependencies": { - "expo": "*" - }, - "peerDependenciesMeta": { - "expo": { - "optional": true - } - } - }, "node_modules/expo/node_modules/@expo/vector-icons": { "version": "15.0.3", "resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-15.0.3.tgz", @@ -6410,20 +6380,6 @@ "react-native": "*" } }, - "node_modules/expo/node_modules/expo-font": { - "version": "14.0.10", - "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-14.0.10.tgz", - "integrity": "sha512-UqyNaaLKRpj4pKAP4HZSLnuDQqueaO5tB1c/NWu5vh1/LF9ulItyyg2kF/IpeOp0DeOLk0GY0HrIXaKUMrwB+Q==", - "license": "MIT", - "dependencies": { - "fontfaceobserver": "^2.1.0" - }, - "peerDependencies": { - "expo": "*", - "react": "*", - "react-native": "*" - } - }, "node_modules/expo/node_modules/expo-keep-awake": { "version": "15.0.8", "resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-15.0.8.tgz", @@ -6443,21 +6399,6 @@ "node": ">=8" } }, - "node_modules/expo/node_modules/hermes-estree": { - "version": "0.29.1", - "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.29.1.tgz", - "integrity": "sha512-jl+x31n4/w+wEqm0I2r4CMimukLbLQEYpisys5oCre611CI5fc9TxhqkBBCJ1edDG4Kza0f7CgNz8xVMLZQOmQ==", - "license": "MIT" - }, - "node_modules/expo/node_modules/hermes-parser": { - "version": "0.29.1", - "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.29.1.tgz", - "integrity": "sha512-xBHWmUtRC5e/UL0tI7Ivt2riA/YBq9+SiYFU7C1oBa/j2jYGlIF9043oak1F47ihuDIxQ5nbsKueYJDRY02UgA==", - "license": "MIT", - "dependencies": { - "hermes-estree": "0.29.1" - } - }, "node_modules/expo/node_modules/picomatch": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-3.0.1.tgz", @@ -6549,6 +6490,22 @@ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "license": "MIT" }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/fastq": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", @@ -7805,6 +7762,12 @@ "dev": true, "license": "MIT" }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -7870,9 +7833,9 @@ "license": "MIT" }, "node_modules/lightningcss": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz", - "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", "license": "MPL-2.0", "dependencies": { "detect-libc": "^2.0.3" @@ -7885,23 +7848,23 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "lightningcss-android-arm64": "1.30.2", - "lightningcss-darwin-arm64": "1.30.2", - "lightningcss-darwin-x64": "1.30.2", - "lightningcss-freebsd-x64": "1.30.2", - "lightningcss-linux-arm-gnueabihf": "1.30.2", - "lightningcss-linux-arm64-gnu": "1.30.2", - "lightningcss-linux-arm64-musl": "1.30.2", - "lightningcss-linux-x64-gnu": "1.30.2", - "lightningcss-linux-x64-musl": "1.30.2", - "lightningcss-win32-arm64-msvc": "1.30.2", - "lightningcss-win32-x64-msvc": "1.30.2" + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" } }, "node_modules/lightningcss-android-arm64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz", - "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", "cpu": [ "arm64" ], @@ -7919,9 +7882,9 @@ } }, "node_modules/lightningcss-darwin-arm64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz", - "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", "cpu": [ "arm64" ], @@ -7939,9 +7902,9 @@ } }, "node_modules/lightningcss-darwin-x64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz", - "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", "cpu": [ "x64" ], @@ -7959,9 +7922,9 @@ } }, "node_modules/lightningcss-freebsd-x64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz", - "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", "cpu": [ "x64" ], @@ -7979,9 +7942,9 @@ } }, "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz", - "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", "cpu": [ "arm" ], @@ -7999,12 +7962,15 @@ } }, "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz", - "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", "cpu": [ "arm64" ], + "libc": [ + "glibc" + ], "license": "MPL-2.0", "optional": true, "os": [ @@ -8019,12 +7985,15 @@ } }, "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz", - "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", "cpu": [ "arm64" ], + "libc": [ + "musl" + ], "license": "MPL-2.0", "optional": true, "os": [ @@ -8039,12 +8008,15 @@ } }, "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz", - "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", "cpu": [ "x64" ], + "libc": [ + "glibc" + ], "license": "MPL-2.0", "optional": true, "os": [ @@ -8059,12 +8031,15 @@ } }, "node_modules/lightningcss-linux-x64-musl": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz", - "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", "cpu": [ "x64" ], + "libc": [ + "musl" + ], "license": "MPL-2.0", "optional": true, "os": [ @@ -8079,9 +8054,9 @@ } }, "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz", - "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", "cpu": [ "arm64" ], @@ -8099,9 +8074,9 @@ } }, "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz", - "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", "cpu": [ "x64" ], @@ -11270,9 +11245,9 @@ } }, "node_modules/tar": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.3.tgz", - "integrity": "sha512-ENg5JUHUm2rDD7IvKNFGzyElLXNjachNLp6RaGf4+JOgxXHkqA+gq81ZAMCUmtMtqBsoU62lcp6S27g1LCYGGQ==", + "version": "7.5.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.11.tgz", + "integrity": "sha512-ChjMH33/KetonMTAtpYdgUFr0tbz69Fp2v7zWxQfYZX4g5ZN2nOBXm1R2xyA+lMIKrLKIoKAwFj93jE/avX9cQ==", "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/fs-minipass": "^4.0.0", @@ -11539,7 +11514,7 @@ "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", diff --git a/package.json b/package.json index 9f2bae2..1268f8d 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,8 @@ "main": "index.ts", "scripts": { "start": "expo start", - "android": "expo start --android", - "ios": "expo start --ios", + "android": "expo run:android", + "ios": "expo run:ios", "web": "expo start --web" }, "dependencies": { @@ -17,15 +17,16 @@ "@supabase/supabase-js": "^2.98.0", "@tanstack/react-query": "^5.90.19", "axios": "^1.13.2", - "babel-preset-expo": "~54.0.9", - "expo": "~54.0.31", - "expo-auth-session": "^55.0.7", - "expo-crypto": "^55.0.9", + "babel-preset-expo": "~54.0.10", + "expo": "~54.0.33", + "expo-auth-session": "~7.0.10", + "expo-crypto": "~15.0.8", + "expo-dev-client": "~6.0.20", "expo-image-picker": "~17.0.10", "expo-linking": "~8.0.11", - "expo-secure-store": "^55.0.8", + "expo-secure-store": "~15.0.8", "expo-status-bar": "~3.0.9", - "expo-web-browser": "^55.0.9", + "expo-web-browser": "~15.0.10", "nativewind": "^4.2.1", "react": "19.1.0", "react-dom": "19.1.0", diff --git a/src/apis/supabase.ts b/src/apis/supabase.ts index 628cb89..6d30f8a 100644 --- a/src/apis/supabase.ts +++ b/src/apis/supabase.ts @@ -1,31 +1,57 @@ -import { AppState } from 'react-native'; -import 'react-native-url-polyfill/auto'; -import AsyncStorage from '@react-native-async-storage/async-storage'; -import { createClient } from '@supabase/supabase-js'; - -// TODO: 환경변수(.env)로 분리 필요 (현재는 디버깅 및 테스트를 위해 하드코딩 또는 설정값 사용) -// 개발 서버용 임시 키 (실제 프로젝트 환경에 맞게 변경) -const supabaseUrl = process.env.EXPO_PUBLIC_SUPABASE_URL || 'YOUR_SUPABASE_URL'; -const supabaseAnonKey = process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY || 'YOUR_SUPABASE_ANON_KEY'; - -console.log('[Supabase Setup] Initializing Supabase client with URL:', supabaseUrl); - -export const supabase = createClient(supabaseUrl, supabaseAnonKey, { - auth: { - storage: AsyncStorage, - autoRefreshToken: true, - persistSession: true, - detectSessionInUrl: false, - }, -}); - -// AppState 변경 시 (앱이 백그라운드/포그라운드 전환 시) 세션 자동 갱신 처리 -AppState.addEventListener('change', (state) => { - if (state === 'active') { - console.debug('[Supabase Setup] App became active, starting AutoRefresh'); - supabase.auth.startAutoRefresh(); - } else { - console.debug('[Supabase Setup] App went to background, stopping AutoRefresh'); - supabase.auth.stopAutoRefresh(); +import { AppState } from "react-native"; +import "react-native-url-polyfill/auto"; +import AsyncStorage from "@react-native-async-storage/async-storage"; +import { createClient, type SupabaseClient } from "@supabase/supabase-js"; +import { debugLog } from "@/utils/debug"; + +const supabaseUrl = process.env.EXPO_PUBLIC_SUPABASE_URL?.trim() ?? ""; +const supabaseAnonKey = process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY?.trim() ?? ""; + +export const getSupabaseConfigErrorMessage = () => { + if (!supabaseUrl || !supabaseAnonKey) { + return "Supabase 환경변수가 비어 있습니다. .env에 EXPO_PUBLIC_SUPABASE_URL, EXPO_PUBLIC_SUPABASE_ANON_KEY를 채워주세요."; } -}); + + if ( + supabaseUrl === "YOUR_SUPABASE_URL" || + supabaseAnonKey === "YOUR_SUPABASE_ANON_KEY" + ) { + return "Supabase 환경변수가 placeholder 상태입니다. 실제 프로젝트 값을 입력해주세요."; + } + + return null; +}; + +export const SUPABASE_CONFIG_ERROR_MESSAGE = getSupabaseConfigErrorMessage(); +export const isSupabaseConfigured = !SUPABASE_CONFIG_ERROR_MESSAGE; + +if (isSupabaseConfigured) { + debugLog("Supabase", "Initializing client", { url: supabaseUrl }); +} else { + debugLog("Supabase", "Configuration missing", { + error: SUPABASE_CONFIG_ERROR_MESSAGE, + }); +} + +export const supabase = (isSupabaseConfigured + ? createClient(supabaseUrl, supabaseAnonKey, { + auth: { + storage: AsyncStorage, + autoRefreshToken: true, + persistSession: true, + detectSessionInUrl: false, + }, + }) + : null) as SupabaseClient; + +if (isSupabaseConfigured) { + AppState.addEventListener("change", state => { + if (state === "active") { + debugLog("Supabase", "App active -> startAutoRefresh"); + supabase.auth.startAutoRefresh(); + } else { + debugLog("Supabase", "App background -> stopAutoRefresh"); + supabase.auth.stopAutoRefresh(); + } + }); +} diff --git a/src/hooks/auth/useSupabaseOAuth.ts b/src/hooks/auth/useSupabaseOAuth.ts index 58609db..4fd4ebb 100644 --- a/src/hooks/auth/useSupabaseOAuth.ts +++ b/src/hooks/auth/useSupabaseOAuth.ts @@ -1,112 +1,265 @@ -import { useState } from 'react'; -import { makeRedirectUri } from 'expo-auth-session'; -import * as WebBrowser from 'expo-web-browser'; -import * as Linking from 'expo-linking'; -import { supabase } from '@/apis/supabase'; -import { useBackendLogin } from './useBackendLogin'; +import { useState } from "react"; +import { AppState, type AppStateStatus } from "react-native"; +import * as WebBrowser from "expo-web-browser"; +import * as Linking from "expo-linking"; +import { supabase } from "@/apis/supabase"; +import { useBackendLogin } from "./useBackendLogin"; +import { debugLog } from "@/utils/debug"; WebBrowser.maybeCompleteAuthSession(); +type OAuthProvider = "google" | "kakao"; + +type OAuthResult = { + success: boolean; + cancelled?: boolean; + error?: unknown; + isNewUser?: boolean; + nickname?: string; +}; + +const REDIRECT_TIMEOUT_MS = 120000; +const DISMISS_REDIRECT_GRACE_MS = 15000; + +function extractSessionTokens(url: string) { + const urlObj = new URL(url); + const fragment = urlObj.hash.startsWith("#") ? urlObj.hash.substring(1) : urlObj.hash; + const fragmentParams = new URLSearchParams(fragment); + + let accessToken = fragmentParams.get("access_token"); + let refreshToken = fragmentParams.get("refresh_token"); + + if (!accessToken) { + accessToken = urlObj.searchParams.get("access_token"); + refreshToken = urlObj.searchParams.get("refresh_token"); + } + + return { + accessToken, + refreshToken, + }; +} + +function getOAuthRedirectUri() { + if (!Linking.hasCustomScheme()) { + return Linking.createURL("auth/callback"); + } + + return Linking.createURL("auth/callback", { + scheme: "haniumapp", + }); +} + export const useSupabaseOAuth = () => { const [isLoading, setIsLoading] = useState(false); const { mutateAsync: backendLogin } = useBackendLogin(); - // Create redirect URI for our scheme - const redirectUri = makeRedirectUri({ - scheme: 'haniumapp', - path: 'auth/callback', - }); + const redirectUri = getOAuthRedirectUri(); + const isExpoGo = !Linking.hasCustomScheme(); + + const completeLogin = async (url: string): Promise => { + debugLog("SupabaseOAuth", "Callback received", { url }); + + const { accessToken, refreshToken } = extractSessionTokens(url); - const performOAuth = async (provider: 'google' | 'kakao') => { + if (!accessToken) { + console.warn("[SupabaseOAuth] No access token found in callback URL.", { url }); + throw new Error("No access_token found in URL"); + } + + debugLog("SupabaseOAuth", "Tokens parsed", { + hasAccessToken: Boolean(accessToken), + hasRefreshToken: Boolean(refreshToken), + }); + debugLog("SupabaseOAuth", "Setting Supabase session"); + await supabase.auth.setSession({ + access_token: accessToken, + refresh_token: refreshToken || "", + }); + + debugLog("SupabaseOAuth", "Supabase session stored"); + debugLog("SupabaseOAuth", "Sending access token to backend"); + const backendRes = await backendLogin(accessToken); + + if (!backendRes.isSuccess) { + console.error("[SupabaseOAuth] Backend login failed with message:", backendRes.message); + throw new Error(backendRes.message); + } + + debugLog("SupabaseOAuth", "Backend login complete", { + isNewUser: backendRes.result?.newUser, + nickname: backendRes.result?.nickname, + }); + return { + success: true, + isNewUser: backendRes.result?.newUser, + nickname: backendRes.result?.nickname, + }; + }; + + const waitForRedirect = (expectedRedirectUri: string) => + new Promise((resolve, reject) => { + let settled = false; + + const cleanup = () => { + urlSubscription.remove(); + appStateSubscription.remove(); + clearTimeout(timeoutId); + }; + + const resolveIfMatches = async (candidateUrl: string | null | undefined, source: string) => { + if (settled || !candidateUrl) { + return; + } + + debugLog("SupabaseOAuth", "Redirect candidate detected", { + source, + url: candidateUrl, + }); + + if (!candidateUrl.startsWith(expectedRedirectUri)) { + debugLog("SupabaseOAuth", "Ignoring unrelated redirect URL", { + expectedRedirectUri, + actualUrl: candidateUrl, + source, + }); + return; + } + + settled = true; + cleanup(); + void WebBrowser.dismissBrowser(); + debugLog("SupabaseOAuth", "Redirect matched expected URI", { source }); + resolve(candidateUrl); + }; + + const urlSubscription = Linking.addEventListener("url", event => { + void resolveIfMatches(event.url, "url_event"); + }); + + const appStateSubscription = AppState.addEventListener("change", (state: AppStateStatus) => { + if (state !== "active" || settled) { + return; + } + + debugLog("SupabaseOAuth", "App became active while waiting for redirect"); + + void Linking.getInitialURL() + .then(url => resolveIfMatches(url, "app_active_initial_url")) + .catch(error => { + debugLog("SupabaseOAuth", "Failed to read initial URL on app resume", { + error: error instanceof Error ? error.message : String(error), + }); + }); + }); + + void Linking.getInitialURL() + .then(url => resolveIfMatches(url, "initial_url")) + .catch(error => { + debugLog("SupabaseOAuth", "Failed to read initial URL before auth", { + error: error instanceof Error ? error.message : String(error), + }); + }); + + const timeoutId = setTimeout(() => { + if (settled) { + return; + } + + settled = true; + cleanup(); + debugLog("SupabaseOAuth", "Redirect wait timed out", { expectedRedirectUri }); + reject(new Error("OAuth redirect timed out")); + }, REDIRECT_TIMEOUT_MS); + }); + + const performOAuth = async (provider: OAuthProvider): Promise => { setIsLoading(true); - console.debug(`[SupabaseOAuth] performOAuth started for ${provider}`); - console.debug(`[SupabaseOAuth] Redirect URI: ${redirectUri}`); + debugLog("SupabaseOAuth", "performOAuth started", { provider, redirectUri }); try { - // [STEP 1] Supabase Auth를 통해 제공자(Provider)의 OAuth 로그인 URL 획득 const { data, error } = await supabase.auth.signInWithOAuth({ provider, options: { redirectTo: redirectUri, - skipBrowserRedirect: true, // 직접 브라우저를 열기 위해 자동 리다이렉트 방지 + skipBrowserRedirect: true, }, }); if (error) { - console.error('[SupabaseOAuth] signInWithOAuth error:', error); + console.error("[SupabaseOAuth] signInWithOAuth error:", error); throw error; } if (!data?.url) { - console.error('[SupabaseOAuth] No URL returned from signInWithOAuth'); - throw new Error('No URL returned'); + console.error("[SupabaseOAuth] No URL returned from signInWithOAuth"); + throw new Error("No URL returned"); } - // [STEP 2] Expo WebBrowser를 사용하여 모바일 기기에 내장된 브라우저로 실제 로그인 페이지 오픈 - console.debug(`[SupabaseOAuth] Opening browser for URL: ${data.url}`); - const result = await WebBrowser.openAuthSessionAsync(data.url, redirectUri); - - console.debug('[SupabaseOAuth] Auth session result type:', result.type); - - if (result.type === 'success') { - // [STEP 2-1] 리다이렉트 성공 시, 딥링크 URL 파싱 - const { url } = result; - console.debug('[SupabaseOAuth] URL received on success. Parsing URL...'); - - // App(React Native) 환경에서는 URL Hash Fragment(#) 부분에 토큰이 들어오는 경우가 많음 - const urlObj = new URL(url); - const fragment = urlObj.hash.substring(1); - const urlSearchParams = new URLSearchParams(fragment); - let accessToken = urlSearchParams.get('access_token'); - let refreshToken = urlSearchParams.get('refresh_token'); - - // 쿼리스트링(?) 형태인 경우를 대비한 Fallback - if (!accessToken) { - accessToken = urlObj.searchParams.get('access_token'); - refreshToken = urlObj.searchParams.get('refresh_token'); - } + debugLog("SupabaseOAuth", "Opening auth browser", { url: data.url }); - if (accessToken) { - // [STEP 3] 토큰 추출 성공 - // 3-1. Supabase Local Session 설정 (앱 구동 내 상태 동기화) - console.debug('[SupabaseOAuth] Access token parsed successfully. Logging into Supabase locally...'); - - await supabase.auth.setSession({ - access_token: accessToken, - refresh_token: refreshToken || '', - }); + const redirectPromise = waitForRedirect(redirectUri); + const browserPromise = WebBrowser.openAuthSessionAsync(data.url, redirectUri); + + const raceResult = await Promise.race([ + redirectPromise.then(url => ({ type: "redirect" as const, url })), + browserPromise.then(result => ({ type: "browser" as const, result })), + ]); + + if (raceResult.type === "redirect") { + debugLog("SupabaseOAuth", "Redirect event won race", { url: raceResult.url }); + const result = await completeLogin(raceResult.url); + debugLog("SupabaseOAuth", "OAuth flow completed", result); + return result; + } + + debugLog("SupabaseOAuth", "Browser result received", { + type: raceResult.result.type, + url: "url" in raceResult.result ? raceResult.result.url : undefined, + }); - // 3-2. 백엔드(Spring) 토큰 교환 호출 (useBackendLogin 참조) - console.debug('[SupabaseOAuth] Sending access token to backend...'); - const backendRes = await backendLogin(accessToken); - - if (backendRes.isSuccess) { - console.log('[SupabaseOAuth] Backend login complete!'); - return { - success: true, - isNewUser: backendRes.result?.newUser, - nickname: backendRes.result?.nickname - }; - } else { - console.error('[SupabaseOAuth] Backend login failed with message:', backendRes.message); - throw new Error(backendRes.message); - } - } else { - console.warn('[SupabaseOAuth] No access token found in the URL. URL:', url); - throw new Error('No access_token found in URL'); + if (raceResult.result.type === "success") { + const result = await completeLogin(raceResult.result.url); + debugLog("SupabaseOAuth", "OAuth flow completed", result); + return result; + } + + if (raceResult.result.type === "dismiss") { + debugLog("SupabaseOAuth", "Browser dismissed before redirect, waiting for grace period", { + graceMs: DISMISS_REDIRECT_GRACE_MS, + }); + + const delayedRedirect = await Promise.race([ + redirectPromise.then(url => ({ type: "redirect" as const, url })), + new Promise<{ type: "grace_timeout" }>(resolve => { + setTimeout(() => resolve({ type: "grace_timeout" }), DISMISS_REDIRECT_GRACE_MS); + }), + ]); + + if (delayedRedirect.type === "redirect") { + debugLog("SupabaseOAuth", "Redirect received during dismiss grace period", { + url: delayedRedirect.url, + }); + const result = await completeLogin(delayedRedirect.url); + debugLog("SupabaseOAuth", "OAuth flow completed", result); + return result; } - } else { - console.warn(`[SupabaseOAuth] Browser closed or cancelled. Result type: ${result.type}`); - return { success: false, cancelled: true }; } + + console.warn(`[SupabaseOAuth] Browser closed or cancelled. Result type: ${raceResult.result.type}`); + debugLog("SupabaseOAuth", "OAuth flow cancelled", { type: raceResult.result.type }); + return { success: false, cancelled: true }; } catch (err) { - console.error('[SupabaseOAuth] Exception during performOAuth:', err); + console.error("[SupabaseOAuth] Exception during performOAuth:", err); + debugLog("SupabaseOAuth", "OAuth flow failed", { + error: err instanceof Error ? err.message : String(err), + }); return { success: false, error: err }; } finally { setIsLoading(false); - console.debug(`[SupabaseOAuth] performOAuth finished`); + debugLog("SupabaseOAuth", "performOAuth finished"); } }; - return { performOAuth, isLoading, redirectUri }; + return { performOAuth, isLoading, redirectUri, isExpoGo }; }; diff --git a/src/navigation/MainTabNavigator.tsx b/src/navigation/MainTabNavigator.tsx index f05c17e..09bed9d 100644 --- a/src/navigation/MainTabNavigator.tsx +++ b/src/navigation/MainTabNavigator.tsx @@ -1,13 +1,11 @@ +import { useEffect } from "react"; import { createBottomTabNavigator } from "@react-navigation/bottom-tabs"; import type { MainTabParamList } from "./types"; -// 스크린 임포트 import HomeScreen from "@/pages/home/HomeScreen"; import FeedScreen from "@/pages/feed/FeedScreen"; import LogScreen from "@/pages/log/LogScreen"; import OptionScreen from "@/pages/option/OptionScreen"; - -// 아이콘 임포트 import { HomeIcon, CalendarIcon, @@ -16,10 +14,15 @@ import { ACTIVE_COLOR, INACTIVE_COLOR, } from "@/assets/icons/TabIcons"; +import { debugLog } from "@/utils/debug"; const Tab = createBottomTabNavigator(); export default function MainTabNavigator() { + useEffect(() => { + debugLog("MainTabNavigator", "mounted"); + }, []); + return ( ; } @@ -63,51 +69,15 @@ export default function RootNavigator() { )} - - - - - - - - - + + + + + + + + + - + ; type MissionRouteName = @@ -31,8 +32,24 @@ export default function HomeScreen({ navigation }: Props) { const { data, error, isLoading, refetch } = useHomeApi(); const { user, gardens, missions, hydrate } = useHomeSummaryStore(); + useEffect(() => { + debugScreenMounted("HomeScreen"); + }, []); + + useEffect(() => { + debugLog("HomeScreen", "query state changed", { + isLoading, + hasData: Boolean(data), + hasError: Boolean(error), + }); + }, [data, error, isLoading]); + useEffect(() => { if (data) { + debugLog("HomeScreen", "hydrate store from home api", { + missionCount: data.todayMissions?.length ?? 0, + gardenCount: data.gardenSummaries?.length ?? 0, + }); hydrate(data); } }, [data, hydrate]); @@ -92,6 +109,11 @@ export default function HomeScreen({ navigation }: Props) { mission={mission} onPress={() => { const routeName = getMissionRouteName(mission); + debugLog("HomeScreen", "Mission card pressed", { + missionId: mission.missionId, + missionType: mission.missionType, + routeName, + }); if (routeName) { navigation.navigate(routeName); } @@ -110,9 +132,7 @@ export default function HomeScreen({ navigation }: Props) { subtitle="홈 API에서 내려온 정원 슬롯만 표시합니다." /> {gardenSummaries.length > 0 ? ( - gardenSummaries.map(garden => ( - - )) + gardenSummaries.map(garden => ) ) : ( navigation.navigate("Log")} + onPress={() => { + debugLog("HomeScreen", "Quick action -> Log"); + navigation.navigate("Log"); + }} /> navigation.navigate("Feed")} + onPress={() => { + debugLog("HomeScreen", "Quick action -> Feed"); + navigation.navigate("Feed"); + }} /> navigation.navigate("UnlockGarden")} + onPress={() => { + debugLog("HomeScreen", "Quick action -> UnlockGarden"); + navigation.navigate("UnlockGarden"); + }} /> navigation.navigate("DailyMissionWriteDiary")} + onPress={() => { + debugLog("HomeScreen", "Quick action -> DailyMissionWriteDiary"); + navigation.navigate("DailyMissionWriteDiary"); + }} /> navigation.navigate("DailyMissionQuizMultipleChoice")} + onPress={() => { + debugLog("HomeScreen", "Quick action -> DailyMissionQuizMultipleChoice"); + navigation.navigate("DailyMissionQuizMultipleChoice"); + }} /> navigation.navigate("DailyMissionChecking")} + onPress={() => { + debugLog("HomeScreen", "Quick action -> DailyMissionChecking"); + navigation.navigate("DailyMissionChecking"); + }} /> @@ -274,11 +312,7 @@ function QuickAction({ onPress: () => void; }) { return ( - + {title} {description} diff --git a/src/pages/onboarding/OnboardingScreen.tsx b/src/pages/onboarding/OnboardingScreen.tsx index 9cd912e..74b43b7 100644 --- a/src/pages/onboarding/OnboardingScreen.tsx +++ b/src/pages/onboarding/OnboardingScreen.tsx @@ -9,6 +9,7 @@ import { FlatList, NativeSyntheticEvent, NativeScrollEvent, + Alert, } from "react-native"; import { useNavigation } from "@react-navigation/native"; import type { NativeStackNavigationProp } from "@react-navigation/native-stack"; @@ -16,6 +17,7 @@ import type { RootStackParamList } from "@/navigation/types"; import Splash from "@/components/common/Splash"; import { useSupabaseOAuth } from "@/hooks/auth/useSupabaseOAuth"; import useRegistrationStore from "@/stores/useRegistrationStore"; +import { debugLog, debugScreenMounted } from "@/utils/debug"; const { width } = Dimensions.get("window"); @@ -53,18 +55,24 @@ export default function OnboardingScreen() { const [currentIndex, setCurrentIndex] = useState(0); const flatListRef = useRef(null); const navigation = useNavigation(); - const { performOAuth, isLoading } = useSupabaseOAuth(); + const { performOAuth, isLoading, isExpoGo } = useSupabaseOAuth(); const resetRegistration = useRegistrationStore(state => state.reset); const isLastSlide = currentIndex === onboardingData.length - 1; useEffect(() => { + debugScreenMounted("OnboardingScreen"); const timer = setTimeout(() => { + debugLog("OnboardingScreen", "Splash timer finished"); setIsSplash(false); }, 2000); return () => clearTimeout(timer); }, []); + useEffect(() => { + debugLog("OnboardingScreen", "Slide changed", { currentIndex }); + }, [currentIndex]); + const handleScroll = (event: NativeSyntheticEvent) => { const contentOffsetX = event.nativeEvent.contentOffset.x; const index = Math.round(contentOffsetX / width); @@ -72,16 +80,34 @@ export default function OnboardingScreen() { }; const handleStart = () => { + debugLog("OnboardingScreen", "Navigate -> Register"); navigation.navigate("Register"); }; - // [UI 연동] 소셜 로그인 버튼 클릭 핸들러 - // SupabaseOAuth 훅을 호출하고, 최종적으로 완료되면 전체 네비게이션을 Main 구조로 리셋합니다. - const handleOAuthLogin = async (provider: 'kakao' | 'google') => { + const handleOAuthLogin = async (provider: "kakao" | "google") => { + debugLog("OnboardingScreen", "OAuth button pressed", { provider }); + + if (provider === "kakao" && isExpoGo) { + debugLog("OnboardingScreen", "Blocked Kakao login in Expo Go"); + Alert.alert( + "카카오 로그인은 Expo Go에서 지원하지 않아요", + "카카오톡 앱 전환 때문에 인증이 초기화될 수 있어요. 카카오 로그인은 development build에서 테스트해주세요." + ); + return; + } + const result = await performOAuth(provider); + debugLog("OnboardingScreen", "OAuth result received", { + provider, + success: result?.success, + isNewUser: result?.isNewUser, + cancelled: result?.cancelled, + }); + if (result?.success) { if (result.isNewUser) { resetRegistration(); + debugLog("OnboardingScreen", "Reset -> RegistrationAvatar for new user"); navigation.reset({ index: 0, routes: [{ name: "RegistrationAvatar" }], @@ -89,7 +115,8 @@ export default function OnboardingScreen() { return; } - navigation.reset({ index: 0, routes: [{ name: 'Main' as any }] }); // Main Tab navigator + debugLog("OnboardingScreen", "Reset -> Main for existing user"); + navigation.reset({ index: 0, routes: [{ name: "Main" as any }] }); } }; @@ -105,7 +132,7 @@ export default function OnboardingScreen() { showsHorizontalScrollIndicator={false} onScroll={handleScroll} scrollEventThrottle={16} - keyExtractor={(item) => item.id.toString()} + keyExtractor={item => item.id.toString()} renderItem={({ item }) => ( @@ -117,7 +144,6 @@ export default function OnboardingScreen() { )} /> - {/* Pagination Dots */} {onboardingData.map((_, index) => ( - {/* Button */} {isLastSlide ? ( handleOAuthLogin('kakao')} - disabled={isLoading} + style={[ + styles.socialButton, + styles.kakaoButton, + (isLoading || isExpoGo) && styles.buttonDisabled, + ]} + onPress={() => handleOAuthLogin("kakao")} + disabled={isLoading || isExpoGo} > {isLoading ? "처리 중..." : "카카오로 시작하기"} + {isExpoGo ? ( + + Expo Go에서는 카카오 로그인 대신 구글 로그인 또는 development build를 사용해주세요. + + ) : null} + handleOAuthLogin('google')} + onPress={() => handleOAuthLogin("google")} disabled={isLoading} > {isLoading ? "처리 중..." : "구글로 시작하기"} - - + + 비회원으로 화단 만들기 ) : ( - + 나만의 화단 만들러 가기 @@ -284,4 +312,11 @@ const styles = StyleSheet.create({ fontSize: 14, textDecorationLine: "underline", }, + helperText: { + color: "#6B7280", + fontSize: 12, + lineHeight: 18, + textAlign: "center", + marginTop: -4, + }, }); diff --git a/src/pages/register/RegisterScreen.tsx b/src/pages/register/RegisterScreen.tsx index e575d3c..0dcd918 100644 --- a/src/pages/register/RegisterScreen.tsx +++ b/src/pages/register/RegisterScreen.tsx @@ -1,4 +1,4 @@ -import { useState, useRef } from "react"; +import { useEffect, useState, useRef } from "react"; import { View, Text, @@ -14,6 +14,7 @@ import type { RootStackParamList } from "@/navigation/types"; import { LeftIcon, EditIcon } from "@/assets/icons/CommonIcons"; import { useRegister } from "@/hooks/register/useRegister"; import useRegistrationStore from "@/stores/useRegistrationStore"; +import { debugLog, debugScreenMounted } from "@/utils/debug"; type NavigationProp = NativeStackNavigationProp; @@ -26,6 +27,10 @@ export default function RegisterScreen() { const isValidNickname = nickname.length >= 2 && nickname.length <= 10; + useEffect(() => { + debugScreenMounted("RegisterScreen"); + }, []); + const handleWrapperPress = () => { inputRef.current?.focus(); }; @@ -33,19 +38,27 @@ export default function RegisterScreen() { const handleRegister = async () => { if (!isValidNickname) return; + debugLog("RegisterScreen", "Guest register submit", { + nicknameLength: nickname.length, + }); + try { await register(nickname); resetRegistration(); + debugLog("RegisterScreen", "Navigate -> RegistrationAvatar after register success"); navigation.navigate("RegistrationAvatar"); } catch (error) { console.error(error); - // 에러가 발생해도 다음 화면으로 이동 (기존 웹과 동일한 동작) + debugLog("RegisterScreen", "Register failed, continuing to RegistrationAvatar", { + error, + }); resetRegistration(); navigation.navigate("RegistrationAvatar"); } }; const handleBackPress = () => { + debugLog("RegisterScreen", "Navigate -> Onboarding"); navigation.navigate("Onboarding"); }; @@ -54,7 +67,6 @@ export default function RegisterScreen() { style={styles.container} behavior={Platform.OS === "ios" ? "padding" : "height"} > - {/* Header */} @@ -63,7 +75,6 @@ export default function RegisterScreen() { - {/* Content */} @@ -88,15 +99,10 @@ export default function RegisterScreen() { onChangeText={setNickname} maxLength={10} /> - {nickname.length > 0 ? ( - - ) : ( - 2~10자 - )} + {nickname.length > 0 ? : 2~10자} - {/* Button */} Date: Thu, 12 Mar 2026 15:20:43 +0900 Subject: [PATCH 03/92] Fix Kakao OAuth redirect handling --- src/hooks/auth/useSupabaseOAuth.ts | 57 ++++------------------- src/pages/onboarding/OnboardingScreen.tsx | 3 -- 2 files changed, 10 insertions(+), 50 deletions(-) diff --git a/src/hooks/auth/useSupabaseOAuth.ts b/src/hooks/auth/useSupabaseOAuth.ts index 4fd4ebb..1853f7a 100644 --- a/src/hooks/auth/useSupabaseOAuth.ts +++ b/src/hooks/auth/useSupabaseOAuth.ts @@ -199,56 +199,19 @@ export const useSupabaseOAuth = () => { debugLog("SupabaseOAuth", "Opening auth browser", { url: data.url }); const redirectPromise = waitForRedirect(redirectUri); - const browserPromise = WebBrowser.openAuthSessionAsync(data.url, redirectUri); - - const raceResult = await Promise.race([ - redirectPromise.then(url => ({ type: "redirect" as const, url })), - browserPromise.then(result => ({ type: "browser" as const, result })), - ]); - - if (raceResult.type === "redirect") { - debugLog("SupabaseOAuth", "Redirect event won race", { url: raceResult.url }); - const result = await completeLogin(raceResult.url); - debugLog("SupabaseOAuth", "OAuth flow completed", result); - return result; - } - - debugLog("SupabaseOAuth", "Browser result received", { - type: raceResult.result.type, - url: "url" in raceResult.result ? raceResult.result.url : undefined, - }); - if (raceResult.result.type === "success") { - const result = await completeLogin(raceResult.result.url); - debugLog("SupabaseOAuth", "OAuth flow completed", result); - return result; - } - - if (raceResult.result.type === "dismiss") { - debugLog("SupabaseOAuth", "Browser dismissed before redirect, waiting for grace period", { - graceMs: DISMISS_REDIRECT_GRACE_MS, + void WebBrowser.openBrowserAsync(data.url).then(result => { + debugLog("SupabaseOAuth", "Browser result received", { + type: result.type, + url: "url" in result ? result.url : undefined, }); + }); - const delayedRedirect = await Promise.race([ - redirectPromise.then(url => ({ type: "redirect" as const, url })), - new Promise<{ type: "grace_timeout" }>(resolve => { - setTimeout(() => resolve({ type: "grace_timeout" }), DISMISS_REDIRECT_GRACE_MS); - }), - ]); - - if (delayedRedirect.type === "redirect") { - debugLog("SupabaseOAuth", "Redirect received during dismiss grace period", { - url: delayedRedirect.url, - }); - const result = await completeLogin(delayedRedirect.url); - debugLog("SupabaseOAuth", "OAuth flow completed", result); - return result; - } - } - - console.warn(`[SupabaseOAuth] Browser closed or cancelled. Result type: ${raceResult.result.type}`); - debugLog("SupabaseOAuth", "OAuth flow cancelled", { type: raceResult.result.type }); - return { success: false, cancelled: true }; + const redirectedUrl = await redirectPromise; + debugLog("SupabaseOAuth", "Redirect event resolved", { url: redirectedUrl }); + const result = await completeLogin(redirectedUrl); + debugLog("SupabaseOAuth", "OAuth flow completed", result); + return result; } catch (err) { console.error("[SupabaseOAuth] Exception during performOAuth:", err); debugLog("SupabaseOAuth", "OAuth flow failed", { diff --git a/src/pages/onboarding/OnboardingScreen.tsx b/src/pages/onboarding/OnboardingScreen.tsx index 74b43b7..86350fb 100644 --- a/src/pages/onboarding/OnboardingScreen.tsx +++ b/src/pages/onboarding/OnboardingScreen.tsx @@ -114,9 +114,6 @@ export default function OnboardingScreen() { }); return; } - - debugLog("OnboardingScreen", "Reset -> Main for existing user"); - navigation.reset({ index: 0, routes: [{ name: "Main" as any }] }); } }; From 01f435c85faa1975d253df848e61e738fa82981c Mon Sep 17 00:00:00 2001 From: lejuho Date: Fri, 13 Mar 2026 00:07:44 +0900 Subject: [PATCH 04/92] =?UTF-8?q?feat:=20=ED=99=88=20=EC=9D=B4=EC=8B=9D=20?= =?UTF-8?q?=EC=B2=B4=ED=81=AC=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EB=AC=B8?= =?UTF-8?q?=EC=84=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HOME_MIGRATION_CHECKLIST.md | 57 +++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 HOME_MIGRATION_CHECKLIST.md diff --git a/HOME_MIGRATION_CHECKLIST.md b/HOME_MIGRATION_CHECKLIST.md new file mode 100644 index 0000000..ddace66 --- /dev/null +++ b/HOME_MIGRATION_CHECKLIST.md @@ -0,0 +1,57 @@ +# Home Migration Checklist + +`MainFE -> MainAPP` 홈 디자인 이식 진행 체크리스트 + +## 1. 현재 상태 점검 + +- [x] `MainFE` 홈 구조 확인 +- [x] `MainAPP` 홈 구현 범위 확인 +- [x] 누락된 API/모달/상호작용 포인트 식별 +- [ ] 현재 디자인 변경 파일 범위 고정 + +## 2. 홈 화면 구조 정리 + +- [x] `PagerView` 기반 정원 슬롯 구조 반영 +- [x] 정원 잠금/빈 슬롯/아바타 상태 분기 반영 +- [x] 하단 미션 시트 1차 UI 반영 +- [ ] `MainFE` 식물별 전용 화면 구조를 RN 컴포넌트로 분리 +- [ ] 홈 공용 컴포넌트 디렉터리 `src/components/home/*` 정리 + +## 3. 홈 상호작용 연결 + +- [ ] 지도 버튼 동작 연결 +- [ ] 트래킹 모달 RN 버전 이식 +- [ ] 감정 체크 모달 RN 버전 이식 +- [ ] 물 주기 액션 연결 +- [ ] 햇빛 주기 액션 연결 + +## 4. 데이터/API 연결 + +- [x] `/api/v1/home` 요약 데이터 연결 +- [ ] `panel` API 존재 여부 재확인 +- [ ] `panel` API 훅/타입 추가 +- [ ] 하단 시트 데이터 소스를 `panel` 기준으로 분리할지 결정 +- [ ] 물/햇빛 액션 API 계약 확인 + +## 5. 홈 UI 마감 + +- [ ] 페이지 인디케이터 디테일 조정 +- [ ] 배경/텍스트/버블 간격 미세 조정 +- [ ] 바텀시트 열림/닫힘 인터랙션 개선 +- [ ] 빈 슬롯 CTA 문구/동선 확정 +- [ ] 잠금 슬롯 CTA 문구/비활성 상태 확정 + +## 6. 연계 화면 점검 + +- [x] `Feed` 헤더 정렬 보정 +- [x] `Follow` 목록 스타일 1차 보정 +- [x] `Option` 리스트형 레이아웃 1차 보정 +- [ ] `Feed/Follow/Option`을 홈 비주얼 톤과 다시 맞추기 + +## 7. 검증 및 정리 + +- [x] 타입체크 통과 +- [ ] 실기기/에뮬레이터에서 홈 스와이프 확인 +- [ ] 안전영역/작은 화면 레이아웃 확인 +- [ ] Android 이미지 로딩/기본 이미지 fallback 확인 +- [ ] 남은 TODO를 `MAINAPP_MIGRATION_TODO.md`와 동기화 From a33eb35d78e52f88e285d00ae7ab39eb35a22e2f Mon Sep 17 00:00:00 2001 From: lejuho Date: Fri, 13 Mar 2026 00:09:20 +0900 Subject: [PATCH 05/92] =?UTF-8?q?refactor:=20=EB=94=94=EC=9E=90=EC=9D=B8?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD=20=EA=B5=AC=EA=B0=84=EC=97=90=20=EB=B8=94?= =?UTF-8?q?=EB=A1=9D=20=EC=A3=BC=EC=84=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/icons/CommonIcons.tsx | 44 ++ src/components/common/ScreenHeader.tsx | 19 +- src/components/feed/FeedDetail.tsx | 6 +- src/pages/feed/FeedScreen.tsx | 15 +- src/pages/follow/FollowScreen.tsx | 115 ++- src/pages/home/HomeScreen.tsx | 996 ++++++++++++++++++------- src/pages/option/OptionScreen.tsx | 229 +++--- 7 files changed, 959 insertions(+), 465 deletions(-) diff --git a/src/assets/icons/CommonIcons.tsx b/src/assets/icons/CommonIcons.tsx index f35ea12..45ced71 100644 --- a/src/assets/icons/CommonIcons.tsx +++ b/src/assets/icons/CommonIcons.tsx @@ -62,6 +62,50 @@ export function RightIcon({ size = 24, color = "#171717" }: IconProps) { ); } +// FE settings and follow designs use simple stroke-based utility icons not covered by the old set. +export function XmarkIcon({ size = 24, color = "#9CA3AF" }: IconProps) { + return ( + + + + + ); +} + +export function ToggleOnIcon({ size = 36 }: IconProps) { + return ( + + + + + ); +} + +export function ToggleOffIcon({ size = 36 }: IconProps) { + return ( + + + + + ); +} + // 하트 아이콘 (좋아요) export function HeartIcon({ size = 24, diff --git a/src/components/common/ScreenHeader.tsx b/src/components/common/ScreenHeader.tsx index 66bdc10..b1a73c0 100644 --- a/src/components/common/ScreenHeader.tsx +++ b/src/components/common/ScreenHeader.tsx @@ -9,13 +9,18 @@ type Props = { export default function ScreenHeader({ title, onBack }: Props) { return ( - - - + {/* Preserve title centering even on screens that do not expose a back action. */} + {onBack ? ( + + + + ) : ( + + )} {title} diff --git a/src/components/feed/FeedDetail.tsx b/src/components/feed/FeedDetail.tsx index 3500495..ecedd46 100644 --- a/src/components/feed/FeedDetail.tsx +++ b/src/components/feed/FeedDetail.tsx @@ -138,7 +138,8 @@ const styles = StyleSheet.create({ }, writerName: { fontSize: 14, - fontWeight: "500", + // Match the lighter author text weight from the current FE detail layout. + fontWeight: "400", color: "#171717", }, createdAt: { @@ -160,7 +161,8 @@ const styles = StyleSheet.create({ content: { fontSize: 14, color: "#171717", - lineHeight: 22, + // Slightly tighter line height keeps multi-line posts closer to the FE proportions. + lineHeight: 20, marginBottom: 24, }, actionBar: { diff --git a/src/pages/feed/FeedScreen.tsx b/src/pages/feed/FeedScreen.tsx index 4972183..8343ac8 100644 --- a/src/pages/feed/FeedScreen.tsx +++ b/src/pages/feed/FeedScreen.tsx @@ -35,7 +35,7 @@ export default function FeedScreen({ navigation }: Props) { return ( - {/* 헤더 */} + {/* Header spacing is tuned to match the centered title layout from the FE design. */} 둘러보기 @@ -48,7 +48,7 @@ export default function FeedScreen({ navigation }: Props) { - {/* 둘러보기 사진 블록 */} + {/* Feed content remains unchanged; only the surrounding layout was tightened. */} ; -type Tab = "following" | "followers"; +type Tab = "added" | "followed"; export default function FollowScreen({ navigation }: Props) { - const [activeTab, setActiveTab] = useState("following"); + const [activeTab, setActiveTab] = useState("added"); const userId = useTokenStore(state => state.userId); const followingQuery = useFollowing(userId); const followersQuery = useFollowers(userId); const unfollowMutation = useUnfollowUser(userId); - const isLoading = - activeTab === "following" ? followingQuery.isLoading : followersQuery.isLoading; - const error = activeTab === "following" ? followingQuery.error : followersQuery.error; + const isLoading = activeTab === "added" ? followingQuery.isLoading : followersQuery.isLoading; + const error = activeTab === "added" ? followingQuery.error : followersQuery.error; const users = - activeTab === "following" + activeTab === "added" ? followingQuery.data ?? [] : followersQuery.data ?? []; @@ -46,7 +46,7 @@ export default function FollowScreen({ navigation }: Props) { }; const handleRetry = () => { - if (activeTab === "following") { + if (activeTab === "added") { void followingQuery.refetch(); return; } @@ -58,24 +58,21 @@ export default function FollowScreen({ navigation }: Props) { + {/* Tabs are renamed to match the app copy while still mapping to following/follower queries. */} setActiveTab("following")} + style={[styles.tabButton, activeTab === "added" && styles.tabButtonActive]} + onPress={() => setActiveTab("added")} > - + 내가 추가한 setActiveTab("followers")} + style={[styles.tabButton, activeTab === "followed" && styles.tabButtonActive]} + onPress={() => setActiveTab("followed")} > - + 나를 추가한 @@ -97,24 +94,39 @@ export default function FollowScreen({ navigation }: Props) { /> ) : users.length === 0 ? ( ) : ( {users.map(user => ( - navigation.navigate("Profile", { userId: user.userId })} - actionLabel={activeTab === "following" ? "삭제" : undefined} - actionDisabled={unfollowMutation.isPending} - onActionPress={ - activeTab === "following" - ? () => void unfollowMutation.mutateAsync(user.userId) - : undefined - } - /> + // The custom row matches the FE design more closely than the previous generic card. + + navigation.navigate("Profile", { userId: user.userId })} + > + + {user.userImageUrl ? ( + + ) : null} + + {user.username} + + {activeTab === "added" ? ( + void unfollowMutation.mutateAsync(user.userId)} + style={styles.removeButton} + > + + + ) : ( + + )} + ))} )} @@ -129,7 +141,7 @@ const styles = StyleSheet.create({ }, tabRow: { flexDirection: "row", - marginBottom: 4, + marginBottom: 24, }, tabButton: { flex: 1, @@ -139,7 +151,7 @@ const styles = StyleSheet.create({ borderBottomColor: "transparent", }, tabButtonActive: { - borderBottomColor: "#4CAF50", + borderBottomColor: "#7DC960", }, tabText: { fontSize: 15, @@ -147,9 +159,44 @@ const styles = StyleSheet.create({ }, tabTextActive: { color: "#171717", - fontWeight: "700", + fontWeight: "400", }, list: { flex: 1, }, + userRow: { + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + paddingHorizontal: 20, + paddingVertical: 20, + backgroundColor: "#FFFFFF", + }, + userInfo: { + flex: 1, + flexDirection: "row", + alignItems: "center", + gap: 12, + }, + avatarWrap: { + width: 40, + height: 40, + borderRadius: 20, + overflow: "hidden", + backgroundColor: "#E5E7EB", + }, + avatar: { + width: "100%", + height: "100%", + }, + username: { + fontSize: 15, + color: "#171717", + }, + removeButton: { + width: 24, + height: 24, + alignItems: "center", + justifyContent: "center", + }, }); diff --git a/src/pages/home/HomeScreen.tsx b/src/pages/home/HomeScreen.tsx index 608337c..ad87b4c 100644 --- a/src/pages/home/HomeScreen.tsx +++ b/src/pages/home/HomeScreen.tsx @@ -1,14 +1,19 @@ -import { useEffect } from "react"; +import { useEffect, useMemo, useState } from "react"; import { - ScrollView, + Alert, + Image, + ImageBackground, + Pressable, StyleSheet, Text, TouchableOpacity, View, } from "react-native"; +import PagerView from "react-native-pager-view"; import { SafeAreaView } from "react-native-safe-area-context"; import type { MainTabScreenProps } from "@/navigation/types"; import StatusView from "@/components/common/StatusView"; +import { RightIcon } from "@/assets/icons/CommonIcons"; import useHomeApi from "@/hooks/home/useHomeApi"; import { useHomeSummaryStore } from "@/stores/useHomeSummaryStore"; import { @@ -20,17 +25,33 @@ import { type TodayMission, } from "@/types/home/garden"; import { debugLog, debugScreenMounted } from "@/utils/debug"; +import { getLevelIcon } from "@/assets/icons/LevelIcons"; type Props = MainTabScreenProps<"Home">; -type MissionRouteName = - | "DailyMissionWriteDiary" - | "DailyMissionQuizMultipleChoice" - | "DailyMissionChecking" - | null; + +const backgrounds = [ + require("@/assets/images/background/background1.webp"), + require("@/assets/images/background/background2.webp"), + require("@/assets/images/background/background3.png"), + require("@/assets/images/background/background4.webp"), +] as const; + +const mapIcon = require("@/assets/images/map.png"); +const plantFallback = require("@/assets/images/plant.png"); +const emptyGardenImage = require("@/assets/images/null.webp"); + +type SceneItem = { + key: string; + slotNumber: number; + background: (typeof backgrounds)[number]; + garden: GardenSummary | null; +}; export default function HomeScreen({ navigation }: Props) { const { data, error, isLoading, refetch } = useHomeApi(); const { user, gardens, missions, hydrate } = useHomeSummaryStore(); + const [currentPage, setCurrentPage] = useState(0); + const [isSheetExpanded, setIsSheetExpanded] = useState(false); useEffect(() => { debugScreenMounted("HomeScreen"); @@ -58,20 +79,33 @@ export default function HomeScreen({ navigation }: Props) { const gardenSummaries = data?.gardenSummaries ?? gardens; const todayMissions = data?.todayMissions ?? missions; - if (isLoading && !userInfo && gardenSummaries.length === 0) { + // Home summary payload is normalized into four fixed garden scenes for the pager UI. + const scenes = useMemo( + () => + backgrounds.map((background, index) => ({ + key: `garden-scene-${index + 1}`, + slotNumber: index + 1, + background, + garden: + gardenSummaries.find(item => item.gardenSlotNumber === index + 1) ?? null, + })), + [gardenSummaries] + ); + + if (isLoading && gardenSummaries.length === 0) { return ( - + ); } - if (error && !userInfo && gardenSummaries.length === 0) { + if (error && gardenSummaries.length === 0) { return ( - + void refetch()} /> @@ -80,358 +114,748 @@ export default function HomeScreen({ navigation }: Props) { } return ( - - + {/* Full-screen garden scenes replace the old list-based home summary layout. */} + { + const position = event.nativeEvent.position; + setCurrentPage(position); + void refetch(); + }} > - - 현재 동작하는 홈 정보 - - {userInfo ? `${userInfo.username}님의 정원` : "정원 요약"} - - - {userInfo - ? `레벨 ${userInfo.level} · 알림 ${userInfo.unreadNotificationCount}개` - : "홈 요약 API가 연결되면 사용자 정보와 정원 상태가 여기에 표시됩니다."} - - - - - {todayMissions.length > 0 ? ( - todayMissions.map(mission => ( - { - const routeName = getMissionRouteName(mission); - debugLog("HomeScreen", "Mission card pressed", { - missionId: mission.missionId, - missionType: mission.missionType, - routeName, + {scenes.map(scene => ( + + { + Alert.alert("지도", "지도/트래킹 모달은 다음 단계에서 연결합니다."); + }} + onPressSun={() => { + debugLog("HomeScreen", "Sun action pressed", { + slotNumber: scene.slotNumber, + }); + }} + onPressWater={() => { + debugLog("HomeScreen", "Water action pressed", { + slotNumber: scene.slotNumber, }); - if (routeName) { - navigation.navigate(routeName); - } }} + onPressUnlock={() => navigation.navigate("UnlockGarden")} + onPressEmpty={() => navigation.navigate("RegistrationAvatar")} /> - )) - ) : ( - - )} + + ))} + - - {gardenSummaries.length > 0 ? ( - gardenSummaries.map(garden => ) - ) : ( - - )} - - - - { - debugLog("HomeScreen", "Quick action -> Log"); - navigation.navigate("Log"); - }} - /> - { - debugLog("HomeScreen", "Quick action -> Feed"); - navigation.navigate("Feed"); - }} - /> - { - debugLog("HomeScreen", "Quick action -> UnlockGarden"); - navigation.navigate("UnlockGarden"); - }} - /> - { - debugLog("HomeScreen", "Quick action -> DailyMissionWriteDiary"); - navigation.navigate("DailyMissionWriteDiary"); - }} - /> - { - debugLog("HomeScreen", "Quick action -> DailyMissionQuizMultipleChoice"); - navigation.navigate("DailyMissionQuizMultipleChoice"); - }} - /> - { - debugLog("HomeScreen", "Quick action -> DailyMissionChecking"); - navigation.navigate("DailyMissionChecking"); - }} - /> + {/* Pagination stays above the scene while the bottom sheet overlays from below. */} + + + {scenes.map((scene, index) => ( + + ))} + - - - - + {/* Mission and wish-tree summary are grouped into a single collapsible bottom sheet. */} + setIsSheetExpanded(prev => !prev)} + missions={todayMissions} + currentExp={userInfo?.currentExp ?? 0} + requiredExp={userInfo?.requiredExpForNextLevel ?? 100} + currentLevel={userInfo?.level ?? 0} + onPressLog={() => navigation.navigate("Log")} + onPressFeed={() => navigation.navigate("Feed")} + onPressUnlockGarden={() => navigation.navigate("UnlockGarden")} + onPressMission={mission => { + const routeName = getMissionRouteName(mission); + if (routeName) { + navigation.navigate(routeName); + } + }} + onPressEmotionCheck={() => { + Alert.alert("마음 건강 체크", "감정 체크 모달은 다음 단계에서 연결합니다."); + }} + /> + ); } -function SectionTitle({ - title, - subtitle, +function GardenScene({ + background, + slotNumber, + userName, + garden, + onPressMap, + onPressSun, + onPressWater, + onPressUnlock, + onPressEmpty, }: { - title: string; - subtitle: string; + background: (typeof backgrounds)[number]; + slotNumber: number; + userName?: string | null; + garden: GardenSummary | null; + onPressMap: () => void; + onPressSun: () => void; + onPressWater: () => void; + onPressUnlock: () => void; + onPressEmpty: () => void; }) { + const isLocked = garden ? getGardenLocked(garden) : false; + const isUnlockable = garden ? getGardenUnlockable(garden) : false; + const hasAvatar = Boolean(garden?.avatar?.avatarImageUrl); + const isEmptySlot = !isLocked && !hasAvatar; + const slotTitle = garden?.avatar?.avatarName ?? `${userName ?? "나풀나풀"}의 정원`; + return ( - - {title} - {subtitle} - + + + + {/* Scene header keeps map affordance and slot title aligned across every garden page. */} + + + + + + {hasAvatar ? slotTitle : `텃밭 ${slotNumber}`} + + + + + {isLocked ? ( + // Locked slots share a common CTA until unlock flow is connected to richer state. + + + {isUnlockable ? "지금 열 수 있어요!" : "아직 해금되지 않았습니다!"} + + + {isUnlockable + ? "아래 버튼을 눌러 씨앗을 배송받고,\n새로운 곳에서 식물을 키워보세요." + : "소망 나무가 충분히 자라면\n새로운 식물을 키울 수 있어요."} + + + + {isUnlockable ? "씨앗 받고 해금하기!" : "충분하지 않아요"} + + + + ) : ( + // Unlocked slots either expose the empty-state registration CTA or the current avatar stage. + + + + + + + {isEmptySlot ? ( + + + 새로운 식물을{"\n"}심어볼까요? + + + + + + ) : ( + + + + 오늘도 만나서 정말 반가워요! + + + + + )} + + )} + + ); } -function MissionCard({ - mission, - onPress, -}: { - mission: TodayMission; - onPress?: () => void; -}) { - const routeName = getMissionRouteName(mission); - const completed = getMissionCompleted(mission); - +function ActionOrb({ label, onPress }: { label: string; onPress: () => void }) { return ( - - - {mission.missionTitle} - - {completed ? "완료" : routeName ? "진행 전" : "준비 중"} - - - {getMissionLabel(mission.missionType)} + + {label} ); } -function getMissionRouteName(mission: TodayMission): MissionRouteName { - switch (mission.missionType as HomeMissionType) { - case "DIARY": - return "DailyMissionWriteDiary"; - case "QUIZ": - return "DailyMissionQuizMultipleChoice"; - case "CHECKING": - return "DailyMissionChecking"; - default: - return null; - } -} - -function getMissionLabel(missionType: TodayMission["missionType"]) { - switch (missionType as HomeMissionType) { - case "DIARY": - return "일기 작성 미션"; - case "QUIZ": - return "퀴즈 미션"; - case "CHECKING": - return "오늘의 질문 미션"; - default: - return `알 수 없는 미션 타입: ${String(missionType)}`; - } +function QuickLink({ label, onPress }: { label: string; onPress: () => void }) { + return ( + + {label} + + ); } -function GardenCard({ garden }: { garden: GardenSummary }) { - const isLocked = getGardenLocked(garden); - const isUnlockable = getGardenUnlockable(garden); - const status = isLocked ? (isUnlockable ? "잠금 해제 가능" : "잠금 상태") : "사용 가능"; +function HomeBottomSheet({ + expanded, + onToggle, + missions, + currentExp, + requiredExp, + currentLevel, + onPressLog, + onPressFeed, + onPressUnlockGarden, + onPressMission, + onPressEmotionCheck, +}: { + expanded: boolean; + onToggle: () => void; + missions: TodayMission[]; + currentExp: number; + requiredExp: number; + currentLevel: number; + onPressLog: () => void; + onPressFeed: () => void; + onPressUnlockGarden: () => void; + onPressMission: (mission: TodayMission) => void; + onPressEmotionCheck: () => void; +}) { + const progressPercent = requiredExp > 0 ? Math.min(100, Math.round((currentExp / requiredExp) * 100)) : 0; + const LevelIcon = getLevelIcon(Math.max(0, Math.min(3, currentLevel))); + const checkingMission = missions.find(mission => mission.missionType === "CHECKING"); + const diaryMission = missions.find(mission => mission.missionType === "DIARY"); + const quizMission = missions.find(mission => mission.missionType === "QUIZ"); - const actionState = isLocked - ? "정원 해금 대기" - : `${garden.ownerWateringAble ? "물주기 가능" : "물주기 대기"} · ${ - garden.ownerSunlightAble ? "햇빛 가능" : "햇빛 대기" - }`; + // The sheet is rendered from mission-type contracts so missing items degrade gracefully. + const missionCards: Array<{ + key: string; + label: string; + mission?: TodayMission; + onPress: () => void; + }> = [ + { + key: "checking", + label: "마음 건강 체크", + mission: checkingMission, + onPress: onPressEmotionCheck, + }, + { + key: "diary", + label: "일기 쓰기", + mission: diaryMission, + onPress: () => diaryMission && onPressMission(diaryMission), + }, + { + key: "quiz", + label: "퀴즈 풀기", + mission: quizMission, + onPress: () => quizMission && onPressMission(quizMission), + }, + ]; return ( - - - 정원 슬롯 {garden.gardenSlotNumber} - {status} + + + + + + + + + 오늘의 미션 + + {missionCards.map(card => ( + + ))} + + + + + {missionCards.map(card => { + const checked = card.mission ? getMissionCompleted(card.mission) : false; + return ( + + + {card.label} + + {checked ? ( + + ) : ( + + )} + + ); + })} + + + {expanded ? ( + <> + + + + + + 소망 나무 + + + {progressPercent >= 100 + ? "지금 바로 새로운 텃밭을 열 수 있어요!" + : `소망 나무 다음 성장까지 ${100 - progressPercent}%가 남았어요!`} + + + + + LV.{currentLevel} + LV.{currentLevel + 1} + + + + + + + + + + + + ) : null} + - - {garden.avatar?.avatarName ?? "배정된 식물이 없습니다."} - - {actionState} ); } -function QuickAction({ - title, - description, - onPress, -}: { - title: string; - description: string; - onPress: () => void; -}) { +function MissionStatusDot({ checked }: { checked: boolean }) { return ( - - {title} - {description} - + + {checked ? : null} + ); } -function InfoCard({ title, description }: { title: string; description: string }) { - return ( - - {title} - {description} - - ); +function getMissionRouteName(mission: TodayMission) { + switch (mission.missionType as HomeMissionType) { + case "DIARY": + return "DailyMissionWriteDiary" as const; + case "QUIZ": + return "DailyMissionQuizMultipleChoice" as const; + case "CHECKING": + return "DailyMissionChecking" as const; + default: + return null; + } } const styles = StyleSheet.create({ container: { flex: 1, - backgroundColor: "#F7F8F4", + backgroundColor: "#DDE8D6", }, - scrollView: { + pager: { flex: 1, }, - content: { - padding: 20, - gap: 14, + page: { + flex: 1, }, - heroCard: { - borderRadius: 20, - padding: 20, - backgroundColor: "#2F5D3B", + sceneBackground: { + flex: 1, }, - eyebrow: { - fontSize: 12, - color: "#D1E7CF", - marginBottom: 8, + sceneShade: { + ...StyleSheet.absoluteFillObject, + backgroundColor: "rgba(8, 20, 10, 0.08)", }, - heroTitle: { - fontSize: 24, + sceneContent: { + flex: 1, + justifyContent: "space-between", + }, + sceneHeader: { + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + paddingHorizontal: 16, + paddingTop: 8, + }, + mapButton: { + width: 48, + height: 48, + alignItems: "center", + justifyContent: "center", + }, + mapIcon: { + width: 48, + height: 48, + }, + sceneTitle: { + flex: 1, + textAlign: "center", + fontSize: 22, fontWeight: "700", color: "#FFFFFF", - marginBottom: 6, + textShadowColor: "rgba(0, 0, 0, 0.18)", + textShadowOffset: { width: 0, height: 1 }, + textShadowRadius: 4, + }, + sceneHeaderSpacer: { + width: 48, + height: 48, + }, + sceneBody: { + flex: 1, + justifyContent: "center", + alignItems: "center", + paddingHorizontal: 24, + paddingBottom: 120, + }, + actionRail: { + position: "absolute", + right: 12, + bottom: 190, + zIndex: 3, + gap: 12, + }, + actionOrb: { + width: 64, + height: 64, + borderRadius: 32, + backgroundColor: "rgba(255,255,255,0.9)", + alignItems: "center", + justifyContent: "center", + shadowColor: "#000000", + shadowOpacity: 0.14, + shadowRadius: 8, + shadowOffset: { width: 0, height: 4 }, + elevation: 4, + }, + actionOrbText: { + fontSize: 14, + fontWeight: "700", + color: "#2B4C2E", }, - heroDescription: { + avatarStage: { + width: "100%", + alignItems: "center", + justifyContent: "center", + position: "relative", + }, + characterBubble: { + marginBottom: 20, + backgroundColor: "rgba(255,255,255,0.94)", + borderRadius: 20, + paddingHorizontal: 22, + paddingVertical: 14, + maxWidth: 260, + }, + characterBubbleText: { fontSize: 14, lineHeight: 20, - color: "#E7F3E4", + color: "#171717", + textAlign: "center", + }, + avatarImage: { + width: 280, + height: 280, + }, + lockedOverlay: { + flex: 1, + marginHorizontal: 24, + marginBottom: 120, + borderRadius: 28, + backgroundColor: "rgba(255,255,255,0.68)", + justifyContent: "center", + alignItems: "center", + paddingHorizontal: 28, + gap: 10, + }, + lockedHeading: { + fontSize: 24, + fontWeight: "700", + color: "#D64545", + textAlign: "center", + }, + unlockHeading: { + color: "#59A647", }, - sectionHeader: { + lockedBody: { + fontSize: 15, + lineHeight: 22, + color: "#171717", + textAlign: "center", + }, + unlockButton: { marginTop: 6, - gap: 4, + borderRadius: 14, + backgroundColor: "#7DC960", + paddingHorizontal: 18, + paddingVertical: 12, }, - sectionTitle: { - fontSize: 18, + unlockButtonDisabled: { + backgroundColor: "#9CA3AF", + }, + unlockButtonText: { + fontSize: 15, fontWeight: "700", + color: "#FFFFFF", + }, + emptySlotWrap: { + width: "100%", + alignItems: "center", + justifyContent: "center", + }, + emptyBubble: { + marginBottom: 12, + borderRadius: 24, + backgroundColor: "rgba(255,255,255,0.95)", + paddingHorizontal: 26, + paddingVertical: 16, + alignItems: "center", + }, + emptyBubbleText: { + fontSize: 15, + lineHeight: 22, color: "#171717", + textAlign: "center", + }, + emptyBubblePlus: { + marginTop: 6, + fontSize: 28, + lineHeight: 30, + color: "#7DC960", + fontWeight: "700", + }, + emptyGardenImage: { + width: 300, + height: 240, + }, + overlaySafeArea: { + position: "absolute", + top: 0, + left: 0, + right: 0, + bottom: 0, + justifyContent: "space-between", + }, + pagination: { + marginTop: 84, + alignSelf: "center", + flexDirection: "row", + alignItems: "center", + gap: 8, + }, + dot: { + width: 8, + height: 8, + borderRadius: 999, + }, + dotActive: { + width: 22, + backgroundColor: "#FFFFFF", + }, + dotInactive: { + backgroundColor: "rgba(255,255,255,0.45)", + }, + quickLink: { + flex: 1, + borderRadius: 14, + backgroundColor: "#EEF3EA", + paddingVertical: 12, + alignItems: "center", }, - sectionSubtitle: { + quickLinkText: { fontSize: 13, - lineHeight: 18, - color: "#6B7280", + color: "#2E5134", + fontWeight: "700", + }, + sheetWrap: { + position: "absolute", + left: 0, + right: 0, + bottom: 0, + alignItems: "center", + }, + sheetWrapCollapsed: { + height: 196, }, - card: { + sheetWrapExpanded: { + height: 430, + }, + sheet: { + width: "100%", + borderTopLeftRadius: 24, + borderTopRightRadius: 24, + borderTopWidth: 1, + borderTopColor: "#E5E7EB", backgroundColor: "#FFFFFF", - borderRadius: 16, - padding: 16, - gap: 8, + paddingHorizontal: 16, + paddingTop: 8, + paddingBottom: 30, + shadowColor: "#000000", + shadowOpacity: 0.12, + shadowRadius: 10, + shadowOffset: { width: 0, height: -4 }, + elevation: 12, + }, + sheetHandleButton: { + alignItems: "center", + paddingBottom: 8, + }, + sheetHandle: { + width: 40, + height: 4, + borderRadius: 999, + backgroundColor: "#9CA3AF", }, - infoCard: { - backgroundColor: "#F0F4EC", + sheetContent: { + paddingHorizontal: 4, }, - rowBetween: { + sheetHeaderRow: { flexDirection: "row", - justifyContent: "space-between", alignItems: "center", - gap: 12, + justifyContent: "space-between", }, - cardTitle: { - flex: 1, - fontSize: 16, - fontWeight: "600", + sheetTitle: { + fontSize: 18, + fontWeight: "700", color: "#171717", }, - cardDescription: { - fontSize: 14, - lineHeight: 20, - color: "#4B5563", + sheetChecks: { + flexDirection: "row", + gap: 8, }, - cardMeta: { - fontSize: 12, - color: "#6B7280", + statusDot: { + width: 28, + height: 28, + borderRadius: 14, + alignItems: "center", + justifyContent: "center", }, - doneBadge: { - fontSize: 12, - color: "#2F7D32", - fontWeight: "700", + statusDotChecked: { + backgroundColor: "#7DC960", }, - todoBadge: { - fontSize: 12, - color: "#B45309", + statusDotUnchecked: { + backgroundColor: "#E5E7EB", + }, + statusDotCheck: { + color: "#FFFFFF", + fontSize: 15, fontWeight: "700", }, - quickActions: { - gap: 12, + sheetMissionList: { + marginTop: 20, + gap: 10, }, - quickAction: { - borderRadius: 16, - padding: 16, + sheetMissionCard: { + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + borderRadius: 12, + borderWidth: 1, + borderColor: "#E5E7EB", backgroundColor: "#FFFFFF", + paddingHorizontal: 16, + paddingVertical: 16, + }, + sheetMissionCardDone: { + borderColor: "transparent", + backgroundColor: "#EEF7E8", + }, + sheetMissionLabel: { + fontSize: 15, + color: "#6B7280", + }, + sheetMissionLabelDone: { + color: "#2E5134", + fontWeight: "700", + }, + sheetDivider: { + marginVertical: 20, + borderTopWidth: 1, + borderTopColor: "#E5E7EB", + }, + wishHeader: { + gap: 6, }, - quickActionTitle: { - fontSize: 16, + wishTitleRow: { + flexDirection: "row", + alignItems: "center", + gap: 4, + }, + wishTitle: { + fontSize: 18, fontWeight: "700", color: "#171717", - marginBottom: 4, }, - quickActionDescription: { + wishBody: { + fontSize: 14, + lineHeight: 20, + color: "#171717", + }, + wishStageRow: { + marginTop: 16, + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + }, + wishCurrent: { fontSize: 13, - lineHeight: 18, - color: "#6B7280", + color: "#59A647", + fontWeight: "700", + }, + wishNext: { + fontSize: 13, + color: "#171717", + fontWeight: "600", + }, + progressTrack: { + marginTop: 10, + height: 8, + borderRadius: 999, + backgroundColor: "#E5E7EB", + overflow: "hidden", + }, + progressFill: { + height: "100%", + borderRadius: 999, + backgroundColor: "#7DC960", + }, + quickLinksRow: { + marginTop: 18, + flexDirection: "row", + gap: 8, + }, + loadingContainer: { + flex: 1, + backgroundColor: "#F4F7F0", }, }); diff --git a/src/pages/option/OptionScreen.tsx b/src/pages/option/OptionScreen.tsx index e29e36e..3960873 100644 --- a/src/pages/option/OptionScreen.tsx +++ b/src/pages/option/OptionScreen.tsx @@ -1,33 +1,23 @@ -import { useState } from "react"; -import { - ActivityIndicator, - Alert, - ScrollView, - StyleSheet, - Text, - TouchableOpacity, - View, -} from "react-native"; +import { useState, type ReactNode } from "react"; +import { Alert, ScrollView, StyleSheet, Text, TouchableOpacity, View } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; +import type { MainTabScreenProps } from "@/navigation/types"; +import { + RightIcon, + ToggleOffIcon, + ToggleOnIcon, +} from "@/assets/icons/CommonIcons"; import ScreenHeader from "@/components/common/ScreenHeader"; -import { logout } from "@/utils/auth"; import useTokenStore from "@/stores/useTokenStore"; -import type { MainTabScreenProps } from "@/navigation/types"; +import { logout } from "@/utils/auth"; type Props = MainTabScreenProps<"Option">; export default function OptionScreen(_: Props) { + const [pushNotification, setPushNotification] = useState(true); const [isLoggingOut, setIsLoggingOut] = useState(false); const { accessToken, userId, hasHydrated } = useTokenStore(); - let loginStatus = "로그인 상태"; - - if (!hasHydrated) { - loginStatus = "세션 확인 중"; - } else if (!accessToken) { - loginStatus = "로그아웃 상태"; - } - const handleLogout = () => { if (isLoggingOut || !accessToken) { return; @@ -46,143 +36,122 @@ export default function OptionScreen(_: Props) { ]); }; + const loginStatus = !hasHydrated ? "세션 확인 중" : accessToken ? "로그인 상태" : "로그아웃 상태"; + return ( - + - - - 계정 - - - 인증 상태 - {loginStatus} - - - - 사용자 ID - {userId ?? "확인되지 않음"} - - - + + {/* Settings are rendered as a simple list so FE-style rows can expand without changing layout structure. */} + setPushNotification(prev => !prev)} + activeOpacity={0.7} + accessibilityRole="switch" + accessibilityState={{ checked: pushNotification }} + > + {pushNotification ? : } + + } + /> + + + + + - - 운영 안내 - - MainAPP 단독 운영 기준 - - MainFE 종료 이후에는 현재 앱 레포와 MainBE 계약이 기준입니다. - - - 버전 표기, 약관, 고객 문의 연결은 운영 정책 확정 후 추가합니다. - - + + {loginStatus} + {userId ? `사용자 ID ${userId}` : "사용자 ID 없음"} - - - {isLoggingOut ? ( - - - 로그아웃 중... - - ) : ( - 로그아웃 - )} - ); } +function OptionRow({ + label, + rightSlot, + danger = false, + disabled = false, + onPress, +}: { + label: string; + rightSlot?: ReactNode; + danger?: boolean; + disabled?: boolean; + onPress?: () => void; +}) { + const content = ( + // A shared row component keeps label-only, toggle, and action rows visually consistent. + + + {label} + + {rightSlot ?? } + + ); + + if (!onPress && !rightSlot) { + return content; + } + + return ( + + {content} + + ); +} + const styles = StyleSheet.create({ - safeArea: { + container: { flex: 1, backgroundColor: "#FFFFFF", }, scrollView: { flex: 1, - backgroundColor: "#F9FAFB", - }, - contentContainer: { - padding: 20, - gap: 20, - }, - section: { - gap: 10, - }, - sectionTitle: { - fontSize: 15, - fontWeight: "700", - color: "#111827", - }, - card: { backgroundColor: "#FFFFFF", - borderRadius: 16, - borderWidth: 1, - borderColor: "#E5E7EB", - padding: 16, - gap: 12, + }, + content: { + paddingHorizontal: 20, + paddingTop: 4, + paddingBottom: 24, }, row: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", - gap: 16, + paddingVertical: 16, }, label: { fontSize: 14, - color: "#6B7280", - }, - value: { - flex: 1, - fontSize: 14, - fontWeight: "600", - color: "#111827", - textAlign: "right", - }, - divider: { - height: 1, - backgroundColor: "#F3F4F6", - }, - infoTitle: { - fontSize: 15, - fontWeight: "700", - color: "#111827", - }, - infoText: { - fontSize: 14, - lineHeight: 20, - color: "#4B5563", + color: "#171717", }, - logoutButton: { - alignItems: "center", - justifyContent: "center", - borderRadius: 14, - backgroundColor: "#DC2626", - paddingVertical: 16, - marginTop: 8, + labelDanger: { + color: "#EF4444", }, - logoutButtonDisabled: { - backgroundColor: "#D1D5DB", + labelDisabled: { + color: "#D1D5DB", }, - logoutLoading: { - flexDirection: "row", - alignItems: "center", - gap: 8, + metaBlock: { + marginTop: 20, + gap: 6, }, - logoutButtonText: { - fontSize: 16, - fontWeight: "700", - color: "#FFFFFF", + metaText: { + fontSize: 12, + color: "#9CA3AF", }, }); From 9c49fd44a534ff1f090ab4e221a351b0df5e1b58 Mon Sep 17 00:00:00 2001 From: lejuho Date: Fri, 13 Mar 2026 00:23:56 +0900 Subject: [PATCH 06/92] =?UTF-8?q?feat:=20=ED=99=88=20=ED=99=94=EB=A9=B4?= =?UTF-8?q?=EC=9D=84=20MainFE=20=EA=B5=AC=EC=A1=B0=EC=97=90=20=EB=A7=9E?= =?UTF-8?q?=EA=B2=8C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/home/homeApi.ts | 10 + src/components/home/HomeAvatarStage.tsx | 158 +++++ src/components/home/HomeBottomSheet.tsx | 326 +++++++++++ src/components/home/HomeEmotionModal.tsx | 173 ++++++ src/components/home/HomeGardenScene.tsx | 342 +++++++++++ src/components/home/HomeToast.tsx | 47 ++ src/components/home/HomeTrackingModal.tsx | 119 ++++ src/hooks/home/useHomeApi.ts | 30 +- src/pages/home/HomeScreen.tsx | 680 +--------------------- 9 files changed, 1232 insertions(+), 653 deletions(-) create mode 100644 src/components/home/HomeAvatarStage.tsx create mode 100644 src/components/home/HomeBottomSheet.tsx create mode 100644 src/components/home/HomeEmotionModal.tsx create mode 100644 src/components/home/HomeGardenScene.tsx create mode 100644 src/components/home/HomeToast.tsx create mode 100644 src/components/home/HomeTrackingModal.tsx diff --git a/src/apis/home/homeApi.ts b/src/apis/home/homeApi.ts index 7f752ad..f992cd4 100644 --- a/src/apis/home/homeApi.ts +++ b/src/apis/home/homeApi.ts @@ -13,3 +13,13 @@ export const getHomeSummary = async (): ApiResponse => { result: normalizeHomeSummaryPayload(res.data.result), }; }; + +export const postGardenSunlight = async (gardenId: number) => { + const res = await api.post(`/api/v1/gardens/${gardenId}/sunlight`); + return res.data; +}; + +export const postGardenMyWater = async (gardenId: number) => { + const res = await api.post(`/api/v1/gardens/${gardenId}/mywater`); + return res.data; +}; diff --git a/src/components/home/HomeAvatarStage.tsx b/src/components/home/HomeAvatarStage.tsx new file mode 100644 index 0000000..2bdaea8 --- /dev/null +++ b/src/components/home/HomeAvatarStage.tsx @@ -0,0 +1,158 @@ +import { Image, Pressable, StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import type { SurveyAnswerKind } from "@/types/missions"; +import { ANSWER_COPY } from "@/components/home/HomeEmotionModal"; + +const wateringImage = require("@/assets/images/background/watering.png"); +const birdImage = require("@/assets/images/bird.webp"); +const characterImage = require("@/assets/images/char2.webp"); +const plantFallback = require("@/assets/images/plant.png"); + +export default function HomeAvatarStage({ + avatarImageUrl, + isWatering, + isEmotionAnswered, + answeredKind, + onPressEmotion, + onPressBird, +}: { + avatarImageUrl?: string | null; + isWatering: boolean; + isEmotionAnswered: boolean; + answeredKind: SurveyAnswerKind | null; + onPressEmotion: () => void; + onPressBird: () => void; +}) { + const answerMessage = answeredKind ? ANSWER_COPY[answeredKind] : null; + + return ( + + + {!isEmotionAnswered ? ( + + + + 오늘도 만나서 정말 반가워요!{"\n"}괜찮으시다면 오늘 하루는 어떠셨는지{"\n"}살짝 알려주시겠어요? + + + 마음 건강 체크 + + + + + ) : answerMessage ? ( + + {answerMessage} + + ) : null} + + + + + + + + + + + ); +} + +const styles = StyleSheet.create({ + stage: { + width: "100%", + alignItems: "center", + justifyContent: "center", + paddingBottom: 12, + }, + characterBlock: { + width: "100%", + alignItems: "center", + minHeight: 166, + }, + balloonWrap: { + alignItems: "center", + }, + balloon: { + borderRadius: 24, + backgroundColor: "#FFFFFF", + paddingHorizontal: 22, + paddingVertical: 18, + alignItems: "center", + maxWidth: 290, + }, + balloonText: { + fontSize: 14, + lineHeight: 21, + color: "#171717", + textAlign: "center", + }, + checkButton: { + marginTop: 14, + borderRadius: 14, + backgroundColor: "#7DC960", + paddingHorizontal: 20, + paddingVertical: 10, + }, + checkButtonText: { + color: "#FFFFFF", + fontSize: 14, + fontWeight: "700", + }, + characterImage: { + width: 78, + height: 78, + marginTop: -2, + }, + answeredBalloon: { + borderRadius: 24, + backgroundColor: "rgba(255,255,255,0.94)", + paddingHorizontal: 22, + paddingVertical: 16, + maxWidth: 280, + }, + answeredBalloonText: { + fontSize: 14, + lineHeight: 20, + color: "#171717", + textAlign: "center", + }, + avatarCluster: { + width: "100%", + minHeight: 320, + alignItems: "center", + justifyContent: "flex-end", + position: "relative", + }, + avatarImage: { + width: 290, + height: 290, + }, + wateringImage: { + position: "absolute", + left: "32%", + bottom: 110, + width: 126, + height: 126, + }, + wateringImageHidden: { + opacity: 0, + }, + birdButton: { + position: "absolute", + right: 48, + bottom: 28, + }, + birdImage: { + width: 86, + height: 86, + }, +}); diff --git a/src/components/home/HomeBottomSheet.tsx b/src/components/home/HomeBottomSheet.tsx new file mode 100644 index 0000000..9757281 --- /dev/null +++ b/src/components/home/HomeBottomSheet.tsx @@ -0,0 +1,326 @@ +import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import { RightIcon } from "@/assets/icons/CommonIcons"; +import { getLevelIcon } from "@/assets/icons/LevelIcons"; +import { getMissionCompleted, type TodayMission } from "@/types/home/garden"; + +export default function HomeBottomSheet({ + expanded, + onToggle, + missions, + currentExp, + requiredExp, + currentLevel, + onPressLog, + onPressFeed, + onPressUnlockGarden, + onPressMission, + onPressEmotionCheck, +}: { + expanded: boolean; + onToggle: () => void; + missions: TodayMission[]; + currentExp: number; + requiredExp: number; + currentLevel: number; + onPressLog: () => void; + onPressFeed: () => void; + onPressUnlockGarden: () => void; + onPressMission: (mission: TodayMission) => void; + onPressEmotionCheck: () => void; +}) { + const progressPercent = + requiredExp > 0 ? Math.min(100, Math.round((currentExp / requiredExp) * 100)) : 0; + const LevelIcon = getLevelIcon(Math.max(0, Math.min(3, currentLevel))); + const checkingMission = missions.find(mission => mission.missionType === "CHECKING"); + const diaryMission = missions.find(mission => mission.missionType === "DIARY"); + const quizMission = missions.find(mission => mission.missionType === "QUIZ"); + + const missionCards: Array<{ + key: string; + label: string; + mission?: TodayMission; + onPress: () => void; + }> = [ + { + key: "checking", + label: "마음 건강 체크", + mission: checkingMission, + onPress: onPressEmotionCheck, + }, + { + key: "diary", + label: "일기 쓰기", + mission: diaryMission, + onPress: () => diaryMission && onPressMission(diaryMission), + }, + { + key: "quiz", + label: "퀴즈 풀기", + mission: quizMission, + onPress: () => quizMission && onPressMission(quizMission), + }, + ]; + + return ( + + + + + + + + + 오늘의 미션 + + {missionCards.map(card => ( + + ))} + + + + + {missionCards.map(card => { + const checked = card.mission ? getMissionCompleted(card.mission) : false; + return ( + + + {card.label} + + {checked ? : } + + ); + })} + + + {expanded ? ( + <> + + + + + + 소망 나무 + + + {progressPercent >= 100 + ? "지금 바로 새로운 텃밭을 열 수 있어요!" + : `소망 나무 다음 성장까지 ${100 - progressPercent}%가 남았어요!`} + + + + + LV.{currentLevel} + LV.{currentLevel + 1} + + + + + + + + + + + + ) : null} + + + + ); +} + +function QuickLink({ label, onPress }: { label: string; onPress: () => void }) { + return ( + + {label} + + ); +} + +function MissionStatusDot({ checked }: { checked: boolean }) { + return ( + + {checked ? : null} + + ); +} + +const styles = StyleSheet.create({ + quickLink: { + flex: 1, + borderRadius: 14, + backgroundColor: "#EEF3EA", + paddingVertical: 12, + alignItems: "center", + }, + quickLinkText: { + fontSize: 13, + color: "#2E5134", + fontWeight: "700", + }, + sheetWrap: { + position: "absolute", + left: 0, + right: 0, + bottom: 0, + alignItems: "center", + }, + sheetWrapCollapsed: { + height: 196, + }, + sheetWrapExpanded: { + height: 430, + }, + sheet: { + width: "100%", + borderTopLeftRadius: 24, + borderTopRightRadius: 24, + borderTopWidth: 1, + borderTopColor: "#E5E7EB", + backgroundColor: "#FFFFFF", + paddingHorizontal: 16, + paddingTop: 8, + paddingBottom: 30, + shadowColor: "#000000", + shadowOpacity: 0.12, + shadowRadius: 10, + shadowOffset: { width: 0, height: -4 }, + elevation: 12, + }, + sheetHandleButton: { + alignItems: "center", + paddingBottom: 8, + }, + sheetHandle: { + width: 40, + height: 4, + borderRadius: 999, + backgroundColor: "#9CA3AF", + }, + sheetContent: { + paddingHorizontal: 4, + }, + sheetHeaderRow: { + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + }, + sheetTitle: { + fontSize: 18, + fontWeight: "700", + color: "#171717", + }, + sheetChecks: { + flexDirection: "row", + gap: 8, + }, + statusDot: { + width: 28, + height: 28, + borderRadius: 14, + alignItems: "center", + justifyContent: "center", + }, + statusDotChecked: { + backgroundColor: "#7DC960", + }, + statusDotUnchecked: { + backgroundColor: "#E5E7EB", + }, + statusDotCheck: { + color: "#FFFFFF", + fontSize: 15, + fontWeight: "700", + }, + sheetMissionList: { + marginTop: 20, + gap: 10, + }, + sheetMissionCard: { + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + borderRadius: 12, + borderWidth: 1, + borderColor: "#E5E7EB", + backgroundColor: "#FFFFFF", + paddingHorizontal: 16, + paddingVertical: 16, + }, + sheetMissionCardDone: { + borderColor: "transparent", + backgroundColor: "#EEF7E8", + }, + sheetMissionLabel: { + fontSize: 15, + color: "#6B7280", + }, + sheetMissionLabelDone: { + color: "#2E5134", + fontWeight: "700", + }, + sheetDivider: { + marginVertical: 20, + borderTopWidth: 1, + borderTopColor: "#E5E7EB", + }, + wishHeader: { + gap: 6, + }, + wishTitleRow: { + flexDirection: "row", + alignItems: "center", + gap: 4, + }, + wishTitle: { + fontSize: 18, + fontWeight: "700", + color: "#171717", + }, + wishBody: { + fontSize: 14, + lineHeight: 20, + color: "#171717", + }, + wishStageRow: { + marginTop: 16, + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + }, + wishCurrent: { + fontSize: 13, + color: "#59A647", + fontWeight: "700", + }, + wishNext: { + fontSize: 13, + color: "#171717", + fontWeight: "600", + }, + progressTrack: { + marginTop: 10, + height: 8, + borderRadius: 999, + backgroundColor: "#E5E7EB", + overflow: "hidden", + }, + progressFill: { + height: "100%", + borderRadius: 999, + backgroundColor: "#7DC960", + }, + quickLinksRow: { + marginTop: 18, + flexDirection: "row", + gap: 8, + }, +}); diff --git a/src/components/home/HomeEmotionModal.tsx b/src/components/home/HomeEmotionModal.tsx new file mode 100644 index 0000000..c4f19ba --- /dev/null +++ b/src/components/home/HomeEmotionModal.tsx @@ -0,0 +1,173 @@ +import { useMemo } from "react"; +import { + Image, + Modal, + Pressable, + StyleSheet, + Text, + TouchableOpacity, + View, +} from "react-native"; +import { useAnswerDailySurvey, useDailySurvey } from "@/hooks/mission/useMissionApi"; +import { + SURVEY_ANSWER_VALUE_MAP, + type SurveyAnswerKind, +} from "@/types/missions"; + +const characterImage = require("@/assets/images/char.webp"); + +const ANSWER_COPY: Record = { + YES: "좋은 기분으로 오늘 하루 계속 이어가요!", + NEUTRAL: "제가 푸른 활력을 선물해 드릴게요.", + NO: "기운을 내볼까요? 제가 곁에 있을게요.", +}; + +export default function HomeEmotionModal({ + visible, + onClose, + onAnswered, +}: { + visible: boolean; + onClose: () => void; + onAnswered: (answer: SurveyAnswerKind) => void; +}) { + const { data, isLoading } = useDailySurvey(); + const answerMutation = useAnswerDailySurvey(); + + const answerOptions = useMemo( + () => + [ + { kind: "YES", label: "그럼요" }, + { kind: "NEUTRAL", label: "글쎄요" }, + { kind: "NO", label: "아니요" }, + ] satisfies Array<{ kind: SurveyAnswerKind; label: string }>, + [] + ); + + const handleAnswer = async (answer: SurveyAnswerKind) => { + if (!data?.id || data.isAnswered || answerMutation.isPending) { + onAnswered(answer); + onClose(); + return; + } + + await answerMutation.mutateAsync({ + questionId: data.id, + answer: SURVEY_ANSWER_VALUE_MAP[answer], + }); + onAnswered(answer); + onClose(); + }; + + const isAnswered = data?.isAnswered ?? false; + + return ( + + + + + 마음 건강 체크 + + + + {isLoading + ? "오늘의 질문을 불러오는 중입니다." + : isAnswered + ? "오늘의 질문에 이미 답변했어요.\n홈에서 완료 상태를 확인해보세요." + : (data?.question ?? "오늘 하루는 어떠셨는지 살짝 알려주시겠어요?")} + + + + {isAnswered ? ( + + 좋아요 + + ) : ( + + {answerOptions.map(option => ( + void handleAnswer(option.kind)} + disabled={answerMutation.isPending} + > + {option.label} + + ))} + + )} + + + + ); +} + +export { ANSWER_COPY }; + +const styles = StyleSheet.create({ + backdrop: { + flex: 1, + backgroundColor: "rgba(0,0,0,0.38)", + alignItems: "center", + justifyContent: "center", + padding: 24, + }, + card: { + width: "100%", + maxWidth: 340, + borderRadius: 28, + backgroundColor: "#FFFFFF", + paddingHorizontal: 24, + paddingTop: 28, + paddingBottom: 24, + alignItems: "center", + gap: 20, + }, + title: { + fontSize: 22, + fontWeight: "700", + color: "#171717", + }, + bodyBlock: { + alignItems: "center", + gap: 12, + }, + characterImage: { + width: 82, + height: 82, + }, + body: { + fontSize: 15, + lineHeight: 23, + color: "#171717", + textAlign: "center", + }, + answerList: { + width: "100%", + gap: 10, + }, + primaryButton: { + width: "100%", + borderRadius: 16, + backgroundColor: "#7DC960", + paddingVertical: 14, + alignItems: "center", + }, + primaryButtonText: { + color: "#FFFFFF", + fontSize: 15, + fontWeight: "700", + }, + secondaryButton: { + width: "100%", + borderRadius: 16, + backgroundColor: "#EEF3EA", + paddingVertical: 14, + alignItems: "center", + }, + secondaryButtonText: { + color: "#2E5134", + fontSize: 15, + fontWeight: "700", + }, +}); diff --git a/src/components/home/HomeGardenScene.tsx b/src/components/home/HomeGardenScene.tsx new file mode 100644 index 0000000..02074da --- /dev/null +++ b/src/components/home/HomeGardenScene.tsx @@ -0,0 +1,342 @@ +import { useEffect, useState } from "react"; +import { + Image, + ImageBackground, + Pressable, + StyleSheet, + Text, + TouchableOpacity, + View, +} from "react-native"; +import type { AxiosError } from "axios"; +import HomeAvatarStage from "@/components/home/HomeAvatarStage"; +import HomeToast from "@/components/home/HomeToast"; +import { useGardenSunlightAction, useGardenWaterAction } from "@/hooks/home/useHomeApi"; +import { + getGardenLocked, + getGardenUnlockable, + type GardenSummary, +} from "@/types/home/garden"; +import type { SurveyAnswerKind } from "@/types/missions"; +import SunIcon from "@/assets/icons/sun.svg"; +import WaterIcon from "@/assets/icons/water.svg"; + +const mapIcon = require("@/assets/images/map.png"); +const emptyGardenImage = require("@/assets/images/null.webp"); +const sunlightOverlay = require("@/assets/images/background/sunlight.png"); + +type Props = { + background: any; + slotNumber: number; + userName?: string | null; + garden: GardenSummary | null; + isEmotionAnswered: boolean; + answeredKind: SurveyAnswerKind | null; + onPressTracking: () => void; + onPressEmotion: () => void; + onPressUnlock: () => void; + onPressEmpty: () => void; +}; + +export default function HomeGardenScene({ + background, + slotNumber, + userName, + garden, + isEmotionAnswered, + answeredKind, + onPressTracking, + onPressEmotion, + onPressUnlock, + onPressEmpty, +}: Props) { + const sunlightMutation = useGardenSunlightAction(); + const waterMutation = useGardenWaterAction(); + const [isSunlightVisible, setIsSunlightVisible] = useState(false); + const [isWateringVisible, setIsWateringVisible] = useState(false); + const [canSunlight, setCanSunlight] = useState(Boolean(garden?.ownerSunlightAble)); + const [canWater, setCanWater] = useState(Boolean(garden?.ownerWateringAble)); + const [toastMessage, setToastMessage] = useState(null); + + useEffect(() => { + setCanSunlight(Boolean(garden?.ownerSunlightAble)); + setCanWater(Boolean(garden?.ownerWateringAble)); + }, [garden?.ownerSunlightAble, garden?.ownerWateringAble]); + + const isLocked = garden ? getGardenLocked(garden) : false; + const isUnlockable = garden ? getGardenUnlockable(garden) : false; + const hasAvatar = Boolean(garden?.avatar?.avatarImageUrl); + const isEmptySlot = !isLocked && !hasAvatar; + const title = hasAvatar ? garden?.avatar?.avatarName : `텃밭 ${slotNumber}`; + const gardenId = garden?.gardenId; + + const handleActionError = (error: unknown) => { + const axiosError = error as AxiosError<{ message?: string }>; + setToastMessage(axiosError.response?.data?.message ?? "홈 상호작용 처리에 실패했습니다."); + }; + + const handleSunlight = async () => { + if (!gardenId) return; + if (!canSunlight) { + setToastMessage("햇빛 주기는 오전 6시에 초기화 됩니다"); + return; + } + + try { + await sunlightMutation.mutateAsync(gardenId); + setCanSunlight(false); + setIsSunlightVisible(true); + setTimeout(() => setIsSunlightVisible(false), 1000); + } catch (error) { + handleActionError(error); + } + }; + + const handleWater = async () => { + if (!gardenId) return; + if (!canWater) { + setToastMessage("물 주기는 오전 12시에 초기화 됩니다"); + return; + } + + try { + await waterMutation.mutateAsync(gardenId); + setCanWater(false); + setIsWateringVisible(true); + setTimeout(() => setIsWateringVisible(false), 1000); + } catch (error) { + handleActionError(error); + } + }; + + return ( + + + + + + {/* Slot header follows the FE layout: map affordance, centered slot title, empty spacer. */} + + + + + {title ?? `${userName ?? "나풀나풀"}의 정원`} + + + + {isLocked ? ( + + + {isUnlockable ? "지금 열 수 있어요!" : "아직 해금되지 않았습니다!"} + + + {isUnlockable + ? "아래 버튼을 눌러 씨앗을 배송받고,\n새로운 곳에서 식물을 키워보세요." + : "소망 나무가 충분히 자라면\n새로운 식물을 키울 수 있어요."} + + + + {isUnlockable ? "씨앗 받고 해금하기!" : "충분하지 않아요"} + + + + ) : ( + + {hasAvatar ? ( + + void handleSunlight()} + style={styles.actionButton} + disabled={sunlightMutation.isPending} + > + + + void handleWater()} + style={styles.actionButton} + disabled={waterMutation.isPending} + > + + + + ) : null} + + {isEmptySlot ? ( + + + 새로운 식물을{"\n"}심어볼까요? + + + + + + ) : ( + + )} + + )} + + + {toastMessage ? setToastMessage(null)} /> : null} + + ); +} + +const styles = StyleSheet.create({ + sceneBackground: { + flex: 1, + }, + sunlightOverlay: { + ...StyleSheet.absoluteFillObject, + opacity: 1, + }, + sunlightOverlayHidden: { + opacity: 0, + }, + sceneShade: { + ...StyleSheet.absoluteFillObject, + backgroundColor: "rgba(8, 20, 10, 0.08)", + }, + sceneContent: { + flex: 1, + justifyContent: "space-between", + }, + sceneHeader: { + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + paddingHorizontal: 16, + paddingTop: 56, + }, + mapButton: { + width: 48, + height: 48, + alignItems: "center", + justifyContent: "center", + }, + mapIcon: { + width: 48, + height: 48, + }, + sceneTitle: { + flex: 1, + textAlign: "center", + fontSize: 22, + fontWeight: "700", + color: "#FFFFFF", + textShadowColor: "rgba(0, 0, 0, 0.18)", + textShadowOffset: { width: 0, height: 1 }, + textShadowRadius: 4, + }, + sceneHeaderSpacer: { + width: 48, + height: 48, + }, + sceneBody: { + flex: 1, + justifyContent: "center", + alignItems: "center", + paddingHorizontal: 24, + paddingBottom: 120, + }, + actionRail: { + position: "absolute", + right: 10, + bottom: 180, + zIndex: 3, + gap: 8, + }, + actionButton: { + width: 64, + height: 64, + alignItems: "center", + justifyContent: "center", + }, + lockedOverlay: { + flex: 1, + marginHorizontal: 24, + marginBottom: 120, + borderRadius: 28, + backgroundColor: "rgba(255,255,255,0.68)", + justifyContent: "center", + alignItems: "center", + paddingHorizontal: 28, + gap: 10, + }, + lockedHeading: { + fontSize: 24, + fontWeight: "700", + color: "#D64545", + textAlign: "center", + }, + unlockHeading: { + color: "#59A647", + }, + lockedBody: { + fontSize: 15, + lineHeight: 22, + color: "#171717", + textAlign: "center", + }, + unlockButton: { + marginTop: 6, + borderRadius: 14, + backgroundColor: "#7DC960", + paddingHorizontal: 18, + paddingVertical: 12, + }, + unlockButtonDisabled: { + backgroundColor: "#9CA3AF", + }, + unlockButtonText: { + fontSize: 15, + fontWeight: "700", + color: "#FFFFFF", + }, + emptySlotWrap: { + width: "100%", + alignItems: "center", + justifyContent: "center", + }, + emptyBubble: { + marginBottom: 12, + borderRadius: 24, + backgroundColor: "rgba(255,255,255,0.95)", + paddingHorizontal: 26, + paddingVertical: 16, + alignItems: "center", + }, + emptyBubbleText: { + fontSize: 15, + lineHeight: 22, + color: "#171717", + textAlign: "center", + }, + emptyBubblePlus: { + marginTop: 6, + fontSize: 28, + lineHeight: 30, + color: "#7DC960", + fontWeight: "700", + }, + emptyGardenImage: { + width: 300, + height: 240, + }, +}); diff --git a/src/components/home/HomeToast.tsx b/src/components/home/HomeToast.tsx new file mode 100644 index 0000000..eed6f2e --- /dev/null +++ b/src/components/home/HomeToast.tsx @@ -0,0 +1,47 @@ +import { useEffect } from "react"; +import { StyleSheet, Text, View } from "react-native"; + +export default function HomeToast({ + message, + onClose, +}: { + message: string; + onClose: () => void; +}) { + useEffect(() => { + const timer = setTimeout(onClose, 2200); + return () => clearTimeout(timer); + }, [onClose]); + + return ( + + + {message} + + + ); +} + +const styles = StyleSheet.create({ + wrap: { + position: "absolute", + left: 0, + right: 0, + bottom: 120, + alignItems: "center", + zIndex: 90, + }, + toast: { + maxWidth: 300, + borderRadius: 18, + backgroundColor: "rgba(23, 23, 23, 0.88)", + paddingHorizontal: 18, + paddingVertical: 12, + }, + message: { + color: "#FFFFFF", + fontSize: 13, + lineHeight: 18, + textAlign: "center", + }, +}); diff --git a/src/components/home/HomeTrackingModal.tsx b/src/components/home/HomeTrackingModal.tsx new file mode 100644 index 0000000..f586ea9 --- /dev/null +++ b/src/components/home/HomeTrackingModal.tsx @@ -0,0 +1,119 @@ +import { useState } from "react"; +import { + Image, + Modal, + Pressable, + StyleSheet, + Text, + TouchableOpacity, + View, +} from "react-native"; + +const trackingImage = require("@/assets/images/tracking.webp"); +const characterImage = require("@/assets/images/char.webp"); + +export default function HomeTrackingModal({ + visible, + onClose, +}: { + visible: boolean; + onClose: () => void; +}) { + const [liked, setLiked] = useState(true); + + return ( + + + + + 함께해요! + {liked ? ( + <> + + + 2주동안 12일 식물을 키우셨습니다!{"\n"}열심히 노력하셨군요{"\n"}앞으로도 같이 열심히 키워봐요! + + setLiked(false)}> + 좋아요 + + + ) : ( + <> + + + 힘든 순간도 결국 지나갑니다.{"\n"}마음도 한결 가벼워질 날이 올 거에요!{"\n"}그때까지 제가 함께하겠습니다. + + + 고마워요 + + + )} + + + + ); +} + +const styles = StyleSheet.create({ + backdrop: { + flex: 1, + backgroundColor: "rgba(0,0,0,0.38)", + alignItems: "center", + justifyContent: "center", + padding: 24, + }, + card: { + width: "100%", + maxWidth: 340, + borderRadius: 28, + backgroundColor: "#FFFFFF", + paddingHorizontal: 24, + paddingTop: 28, + paddingBottom: 24, + alignItems: "center", + gap: 18, + }, + title: { + fontSize: 22, + fontWeight: "700", + color: "#171717", + }, + trackingImage: { + width: 200, + height: 150, + }, + characterImage: { + width: 84, + height: 84, + }, + body: { + fontSize: 15, + lineHeight: 23, + color: "#171717", + textAlign: "center", + }, + primaryButton: { + width: "100%", + borderRadius: 16, + backgroundColor: "#7DC960", + paddingVertical: 14, + alignItems: "center", + }, + primaryButtonText: { + color: "#FFFFFF", + fontSize: 15, + fontWeight: "700", + }, + secondaryButton: { + width: "100%", + borderRadius: 16, + backgroundColor: "#EEF3EA", + paddingVertical: 14, + alignItems: "center", + }, + secondaryButtonText: { + color: "#2E5134", + fontSize: 15, + fontWeight: "700", + }, +}); diff --git a/src/hooks/home/useHomeApi.ts b/src/hooks/home/useHomeApi.ts index 06227e1..e8d0574 100644 --- a/src/hooks/home/useHomeApi.ts +++ b/src/hooks/home/useHomeApi.ts @@ -1,6 +1,10 @@ -import { useQuery } from "@tanstack/react-query"; +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import type { AxiosError } from "axios"; -import { getHomeSummary } from "@/apis/home/homeApi"; +import { + getHomeSummary, + postGardenMyWater, + postGardenSunlight, +} from "@/apis/home/homeApi"; import type { GlobalResponse } from "@/types/common/apiResponse.type"; import type { HomeSummaryPayload } from "@/types/home/garden"; @@ -16,4 +20,26 @@ export const useHomeApi = () => refetchOnMount: "always", }); +export const useGardenSunlightAction = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: (gardenId: number) => postGardenSunlight(gardenId), + onSuccess: async () => { + await queryClient.invalidateQueries({ queryKey: ["home-summary"] }); + }, + }); +}; + +export const useGardenWaterAction = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: (gardenId: number) => postGardenMyWater(gardenId), + onSuccess: async () => { + await queryClient.invalidateQueries({ queryKey: ["home-summary"] }); + }, + }); +}; + export default useHomeApi; diff --git a/src/pages/home/HomeScreen.tsx b/src/pages/home/HomeScreen.tsx index ad87b4c..dcc7663 100644 --- a/src/pages/home/HomeScreen.tsx +++ b/src/pages/home/HomeScreen.tsx @@ -1,31 +1,23 @@ import { useEffect, useMemo, useState } from "react"; -import { - Alert, - Image, - ImageBackground, - Pressable, - StyleSheet, - Text, - TouchableOpacity, - View, -} from "react-native"; +import { StyleSheet, View } from "react-native"; import PagerView from "react-native-pager-view"; import { SafeAreaView } from "react-native-safe-area-context"; -import type { MainTabScreenProps } from "@/navigation/types"; +import HomeBottomSheet from "@/components/home/HomeBottomSheet"; +import HomeEmotionModal from "@/components/home/HomeEmotionModal"; +import HomeGardenScene from "@/components/home/HomeGardenScene"; +import HomeTrackingModal from "@/components/home/HomeTrackingModal"; import StatusView from "@/components/common/StatusView"; -import { RightIcon } from "@/assets/icons/CommonIcons"; import useHomeApi from "@/hooks/home/useHomeApi"; +import { useDailySurvey } from "@/hooks/mission/useMissionApi"; +import type { MainTabScreenProps } from "@/navigation/types"; import { useHomeSummaryStore } from "@/stores/useHomeSummaryStore"; import { - getGardenLocked, - getGardenUnlockable, - getMissionCompleted, type GardenSummary, type HomeMissionType, type TodayMission, } from "@/types/home/garden"; +import type { SurveyAnswerKind } from "@/types/missions"; import { debugLog, debugScreenMounted } from "@/utils/debug"; -import { getLevelIcon } from "@/assets/icons/LevelIcons"; type Props = MainTabScreenProps<"Home">; @@ -36,10 +28,6 @@ const backgrounds = [ require("@/assets/images/background/background4.webp"), ] as const; -const mapIcon = require("@/assets/images/map.png"); -const plantFallback = require("@/assets/images/plant.png"); -const emptyGardenImage = require("@/assets/images/null.webp"); - type SceneItem = { key: string; slotNumber: number; @@ -49,9 +37,13 @@ type SceneItem = { export default function HomeScreen({ navigation }: Props) { const { data, error, isLoading, refetch } = useHomeApi(); + const surveyQuery = useDailySurvey(); const { user, gardens, missions, hydrate } = useHomeSummaryStore(); const [currentPage, setCurrentPage] = useState(0); const [isSheetExpanded, setIsSheetExpanded] = useState(false); + const [isEmotionModalOpen, setIsEmotionModalOpen] = useState(false); + const [isTrackingModalOpen, setIsTrackingModalOpen] = useState(false); + const [emotionAnswerKind, setEmotionAnswerKind] = useState(null); useEffect(() => { debugScreenMounted("HomeScreen"); @@ -78,6 +70,7 @@ export default function HomeScreen({ navigation }: Props) { const userInfo = data?.userInfo ?? user; const gardenSummaries = data?.gardenSummaries ?? gardens; const todayMissions = data?.todayMissions ?? missions; + const isEmotionAnswered = surveyQuery.data?.isAnswered ?? false; // Home summary payload is normalized into four fixed garden scenes for the pager UI. const scenes = useMemo( @@ -115,7 +108,7 @@ export default function HomeScreen({ navigation }: Props) { return ( - {/* Full-screen garden scenes replace the old list-based home summary layout. */} + {/* Full-screen garden scenes follow the MainFE slide-per-plot structure. */} {scenes.map(scene => ( - { - Alert.alert("지도", "지도/트래킹 모달은 다음 단계에서 연결합니다."); - }} - onPressSun={() => { - debugLog("HomeScreen", "Sun action pressed", { - slotNumber: scene.slotNumber, - }); - }} - onPressWater={() => { - debugLog("HomeScreen", "Water action pressed", { - slotNumber: scene.slotNumber, - }); - }} + isEmotionAnswered={isEmotionAnswered} + answeredKind={emotionAnswerKind} + onPressTracking={() => setIsTrackingModalOpen(true)} + onPressEmotion={() => setIsEmotionModalOpen(true)} onPressUnlock={() => navigation.navigate("UnlockGarden")} onPressEmpty={() => navigation.navigate("RegistrationAvatar")} /> @@ -181,286 +165,18 @@ export default function HomeScreen({ navigation }: Props) { navigation.navigate(routeName); } }} - onPressEmotionCheck={() => { - Alert.alert("마음 건강 체크", "감정 체크 모달은 다음 단계에서 연결합니다."); - }} + onPressEmotionCheck={() => setIsEmotionModalOpen(true)} /> - - ); -} - -function GardenScene({ - background, - slotNumber, - userName, - garden, - onPressMap, - onPressSun, - onPressWater, - onPressUnlock, - onPressEmpty, -}: { - background: (typeof backgrounds)[number]; - slotNumber: number; - userName?: string | null; - garden: GardenSummary | null; - onPressMap: () => void; - onPressSun: () => void; - onPressWater: () => void; - onPressUnlock: () => void; - onPressEmpty: () => void; -}) { - const isLocked = garden ? getGardenLocked(garden) : false; - const isUnlockable = garden ? getGardenUnlockable(garden) : false; - const hasAvatar = Boolean(garden?.avatar?.avatarImageUrl); - const isEmptySlot = !isLocked && !hasAvatar; - const slotTitle = garden?.avatar?.avatarName ?? `${userName ?? "나풀나풀"}의 정원`; - - return ( - - - - {/* Scene header keeps map affordance and slot title aligned across every garden page. */} - - - - - - {hasAvatar ? slotTitle : `텃밭 ${slotNumber}`} - - - - - {isLocked ? ( - // Locked slots share a common CTA until unlock flow is connected to richer state. - - - {isUnlockable ? "지금 열 수 있어요!" : "아직 해금되지 않았습니다!"} - - - {isUnlockable - ? "아래 버튼을 눌러 씨앗을 배송받고,\n새로운 곳에서 식물을 키워보세요." - : "소망 나무가 충분히 자라면\n새로운 식물을 키울 수 있어요."} - - - - {isUnlockable ? "씨앗 받고 해금하기!" : "충분하지 않아요"} - - - - ) : ( - // Unlocked slots either expose the empty-state registration CTA or the current avatar stage. - - - - - - - {isEmptySlot ? ( - - - 새로운 식물을{"\n"}심어볼까요? - + - - - - ) : ( - - - - 오늘도 만나서 정말 반가워요! - - - - - )} - - )} - - - ); -} - -function ActionOrb({ label, onPress }: { label: string; onPress: () => void }) { - return ( - - {label} - - ); -} - -function QuickLink({ label, onPress }: { label: string; onPress: () => void }) { - return ( - - {label} - - ); -} - -function HomeBottomSheet({ - expanded, - onToggle, - missions, - currentExp, - requiredExp, - currentLevel, - onPressLog, - onPressFeed, - onPressUnlockGarden, - onPressMission, - onPressEmotionCheck, -}: { - expanded: boolean; - onToggle: () => void; - missions: TodayMission[]; - currentExp: number; - requiredExp: number; - currentLevel: number; - onPressLog: () => void; - onPressFeed: () => void; - onPressUnlockGarden: () => void; - onPressMission: (mission: TodayMission) => void; - onPressEmotionCheck: () => void; -}) { - const progressPercent = requiredExp > 0 ? Math.min(100, Math.round((currentExp / requiredExp) * 100)) : 0; - const LevelIcon = getLevelIcon(Math.max(0, Math.min(3, currentLevel))); - const checkingMission = missions.find(mission => mission.missionType === "CHECKING"); - const diaryMission = missions.find(mission => mission.missionType === "DIARY"); - const quizMission = missions.find(mission => mission.missionType === "QUIZ"); - - // The sheet is rendered from mission-type contracts so missing items degrade gracefully. - const missionCards: Array<{ - key: string; - label: string; - mission?: TodayMission; - onPress: () => void; - }> = [ - { - key: "checking", - label: "마음 건강 체크", - mission: checkingMission, - onPress: onPressEmotionCheck, - }, - { - key: "diary", - label: "일기 쓰기", - mission: diaryMission, - onPress: () => diaryMission && onPressMission(diaryMission), - }, - { - key: "quiz", - label: "퀴즈 풀기", - mission: quizMission, - onPress: () => quizMission && onPressMission(quizMission), - }, - ]; - - return ( - - - - - - - - - 오늘의 미션 - - {missionCards.map(card => ( - - ))} - - - - - {missionCards.map(card => { - const checked = card.mission ? getMissionCompleted(card.mission) : false; - return ( - - - {card.label} - - {checked ? ( - - ) : ( - - )} - - ); - })} - - - {expanded ? ( - <> - - - - - 소망 나무 - - - {progressPercent >= 100 - ? "지금 바로 새로운 텃밭을 열 수 있어요!" - : `소망 나무 다음 성장까지 ${100 - progressPercent}%가 남았어요!`} - - - - - LV.{currentLevel} - LV.{currentLevel + 1} - - - - - - - - - - - - ) : null} - - - - ); -} - -function MissionStatusDot({ checked }: { checked: boolean }) { - return ( - - {checked ? : null} + setIsEmotionModalOpen(false)} + onAnswered={answer => setEmotionAnswerKind(answer)} + /> + setIsTrackingModalOpen(false)} + /> ); } @@ -489,175 +205,6 @@ const styles = StyleSheet.create({ page: { flex: 1, }, - sceneBackground: { - flex: 1, - }, - sceneShade: { - ...StyleSheet.absoluteFillObject, - backgroundColor: "rgba(8, 20, 10, 0.08)", - }, - sceneContent: { - flex: 1, - justifyContent: "space-between", - }, - sceneHeader: { - flexDirection: "row", - alignItems: "center", - justifyContent: "space-between", - paddingHorizontal: 16, - paddingTop: 8, - }, - mapButton: { - width: 48, - height: 48, - alignItems: "center", - justifyContent: "center", - }, - mapIcon: { - width: 48, - height: 48, - }, - sceneTitle: { - flex: 1, - textAlign: "center", - fontSize: 22, - fontWeight: "700", - color: "#FFFFFF", - textShadowColor: "rgba(0, 0, 0, 0.18)", - textShadowOffset: { width: 0, height: 1 }, - textShadowRadius: 4, - }, - sceneHeaderSpacer: { - width: 48, - height: 48, - }, - sceneBody: { - flex: 1, - justifyContent: "center", - alignItems: "center", - paddingHorizontal: 24, - paddingBottom: 120, - }, - actionRail: { - position: "absolute", - right: 12, - bottom: 190, - zIndex: 3, - gap: 12, - }, - actionOrb: { - width: 64, - height: 64, - borderRadius: 32, - backgroundColor: "rgba(255,255,255,0.9)", - alignItems: "center", - justifyContent: "center", - shadowColor: "#000000", - shadowOpacity: 0.14, - shadowRadius: 8, - shadowOffset: { width: 0, height: 4 }, - elevation: 4, - }, - actionOrbText: { - fontSize: 14, - fontWeight: "700", - color: "#2B4C2E", - }, - avatarStage: { - width: "100%", - alignItems: "center", - justifyContent: "center", - position: "relative", - }, - characterBubble: { - marginBottom: 20, - backgroundColor: "rgba(255,255,255,0.94)", - borderRadius: 20, - paddingHorizontal: 22, - paddingVertical: 14, - maxWidth: 260, - }, - characterBubbleText: { - fontSize: 14, - lineHeight: 20, - color: "#171717", - textAlign: "center", - }, - avatarImage: { - width: 280, - height: 280, - }, - lockedOverlay: { - flex: 1, - marginHorizontal: 24, - marginBottom: 120, - borderRadius: 28, - backgroundColor: "rgba(255,255,255,0.68)", - justifyContent: "center", - alignItems: "center", - paddingHorizontal: 28, - gap: 10, - }, - lockedHeading: { - fontSize: 24, - fontWeight: "700", - color: "#D64545", - textAlign: "center", - }, - unlockHeading: { - color: "#59A647", - }, - lockedBody: { - fontSize: 15, - lineHeight: 22, - color: "#171717", - textAlign: "center", - }, - unlockButton: { - marginTop: 6, - borderRadius: 14, - backgroundColor: "#7DC960", - paddingHorizontal: 18, - paddingVertical: 12, - }, - unlockButtonDisabled: { - backgroundColor: "#9CA3AF", - }, - unlockButtonText: { - fontSize: 15, - fontWeight: "700", - color: "#FFFFFF", - }, - emptySlotWrap: { - width: "100%", - alignItems: "center", - justifyContent: "center", - }, - emptyBubble: { - marginBottom: 12, - borderRadius: 24, - backgroundColor: "rgba(255,255,255,0.95)", - paddingHorizontal: 26, - paddingVertical: 16, - alignItems: "center", - }, - emptyBubbleText: { - fontSize: 15, - lineHeight: 22, - color: "#171717", - textAlign: "center", - }, - emptyBubblePlus: { - marginTop: 6, - fontSize: 28, - lineHeight: 30, - color: "#7DC960", - fontWeight: "700", - }, - emptyGardenImage: { - width: 300, - height: 240, - }, overlaySafeArea: { position: "absolute", top: 0, @@ -685,175 +232,6 @@ const styles = StyleSheet.create({ dotInactive: { backgroundColor: "rgba(255,255,255,0.45)", }, - quickLink: { - flex: 1, - borderRadius: 14, - backgroundColor: "#EEF3EA", - paddingVertical: 12, - alignItems: "center", - }, - quickLinkText: { - fontSize: 13, - color: "#2E5134", - fontWeight: "700", - }, - sheetWrap: { - position: "absolute", - left: 0, - right: 0, - bottom: 0, - alignItems: "center", - }, - sheetWrapCollapsed: { - height: 196, - }, - sheetWrapExpanded: { - height: 430, - }, - sheet: { - width: "100%", - borderTopLeftRadius: 24, - borderTopRightRadius: 24, - borderTopWidth: 1, - borderTopColor: "#E5E7EB", - backgroundColor: "#FFFFFF", - paddingHorizontal: 16, - paddingTop: 8, - paddingBottom: 30, - shadowColor: "#000000", - shadowOpacity: 0.12, - shadowRadius: 10, - shadowOffset: { width: 0, height: -4 }, - elevation: 12, - }, - sheetHandleButton: { - alignItems: "center", - paddingBottom: 8, - }, - sheetHandle: { - width: 40, - height: 4, - borderRadius: 999, - backgroundColor: "#9CA3AF", - }, - sheetContent: { - paddingHorizontal: 4, - }, - sheetHeaderRow: { - flexDirection: "row", - alignItems: "center", - justifyContent: "space-between", - }, - sheetTitle: { - fontSize: 18, - fontWeight: "700", - color: "#171717", - }, - sheetChecks: { - flexDirection: "row", - gap: 8, - }, - statusDot: { - width: 28, - height: 28, - borderRadius: 14, - alignItems: "center", - justifyContent: "center", - }, - statusDotChecked: { - backgroundColor: "#7DC960", - }, - statusDotUnchecked: { - backgroundColor: "#E5E7EB", - }, - statusDotCheck: { - color: "#FFFFFF", - fontSize: 15, - fontWeight: "700", - }, - sheetMissionList: { - marginTop: 20, - gap: 10, - }, - sheetMissionCard: { - flexDirection: "row", - alignItems: "center", - justifyContent: "space-between", - borderRadius: 12, - borderWidth: 1, - borderColor: "#E5E7EB", - backgroundColor: "#FFFFFF", - paddingHorizontal: 16, - paddingVertical: 16, - }, - sheetMissionCardDone: { - borderColor: "transparent", - backgroundColor: "#EEF7E8", - }, - sheetMissionLabel: { - fontSize: 15, - color: "#6B7280", - }, - sheetMissionLabelDone: { - color: "#2E5134", - fontWeight: "700", - }, - sheetDivider: { - marginVertical: 20, - borderTopWidth: 1, - borderTopColor: "#E5E7EB", - }, - wishHeader: { - gap: 6, - }, - wishTitleRow: { - flexDirection: "row", - alignItems: "center", - gap: 4, - }, - wishTitle: { - fontSize: 18, - fontWeight: "700", - color: "#171717", - }, - wishBody: { - fontSize: 14, - lineHeight: 20, - color: "#171717", - }, - wishStageRow: { - marginTop: 16, - flexDirection: "row", - alignItems: "center", - justifyContent: "space-between", - }, - wishCurrent: { - fontSize: 13, - color: "#59A647", - fontWeight: "700", - }, - wishNext: { - fontSize: 13, - color: "#171717", - fontWeight: "600", - }, - progressTrack: { - marginTop: 10, - height: 8, - borderRadius: 999, - backgroundColor: "#E5E7EB", - overflow: "hidden", - }, - progressFill: { - height: "100%", - borderRadius: 999, - backgroundColor: "#7DC960", - }, - quickLinksRow: { - marginTop: 18, - flexDirection: "row", - gap: 8, - }, loadingContainer: { flex: 1, backgroundColor: "#F4F7F0", From e061696c03baa12241b7ca1a81c93f1335dc5eb4 Mon Sep 17 00:00:00 2001 From: lejuho Date: Fri, 13 Mar 2026 00:25:14 +0900 Subject: [PATCH 07/92] =?UTF-8?q?refactor:=20=ED=99=88=20=EC=9D=B4?= =?UTF-8?q?=EC=8B=9D=20=EC=B2=B4=ED=81=AC=EB=A6=AC=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=A7=84=ED=96=89=20=EC=83=81=ED=83=9C=20=EA=B0=B1=EC=8B=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HOME_MIGRATION_CHECKLIST.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/HOME_MIGRATION_CHECKLIST.md b/HOME_MIGRATION_CHECKLIST.md index ddace66..0f2189b 100644 --- a/HOME_MIGRATION_CHECKLIST.md +++ b/HOME_MIGRATION_CHECKLIST.md @@ -7,31 +7,31 @@ - [x] `MainFE` 홈 구조 확인 - [x] `MainAPP` 홈 구현 범위 확인 - [x] 누락된 API/모달/상호작용 포인트 식별 -- [ ] 현재 디자인 변경 파일 범위 고정 +- [x] 현재 디자인 변경 파일 범위 고정 ## 2. 홈 화면 구조 정리 - [x] `PagerView` 기반 정원 슬롯 구조 반영 - [x] 정원 잠금/빈 슬롯/아바타 상태 분기 반영 - [x] 하단 미션 시트 1차 UI 반영 -- [ ] `MainFE` 식물별 전용 화면 구조를 RN 컴포넌트로 분리 -- [ ] 홈 공용 컴포넌트 디렉터리 `src/components/home/*` 정리 +- [x] `MainFE` 식물별 전용 화면 구조를 RN 컴포넌트로 분리 +- [x] 홈 공용 컴포넌트 디렉터리 `src/components/home/*` 정리 ## 3. 홈 상호작용 연결 - [ ] 지도 버튼 동작 연결 -- [ ] 트래킹 모달 RN 버전 이식 -- [ ] 감정 체크 모달 RN 버전 이식 -- [ ] 물 주기 액션 연결 -- [ ] 햇빛 주기 액션 연결 +- [x] 트래킹 모달 RN 버전 이식 +- [x] 감정 체크 모달 RN 버전 이식 +- [x] 물 주기 액션 연결 +- [x] 햇빛 주기 액션 연결 ## 4. 데이터/API 연결 - [x] `/api/v1/home` 요약 데이터 연결 - [ ] `panel` API 존재 여부 재확인 -- [ ] `panel` API 훅/타입 추가 +- [x] 홈 액션 API 훅 추가 - [ ] 하단 시트 데이터 소스를 `panel` 기준으로 분리할지 결정 -- [ ] 물/햇빛 액션 API 계약 확인 +- [ ] 물/햇빛 액션 API 계약 상세 확인 ## 5. 홈 UI 마감 From fb38d709d4f6cd26b433467757d5679a1533db9d Mon Sep 17 00:00:00 2001 From: lejuho Date: Fri, 13 Mar 2026 00:34:20 +0900 Subject: [PATCH 08/92] =?UTF-8?q?feat:=20=ED=99=88=20=ED=8C=A8=EB=84=90=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=EC=99=80=20=EC=A7=80=EB=8F=84=20?= =?UTF-8?q?=EB=AA=A8=EB=8B=AC=EC=9D=84=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HOME_MIGRATION_CHECKLIST.md | 8 +-- src/apis/home/homeApi.ts | 6 ++ src/components/home/HomeBottomSheet.tsx | 63 +++++++++++---------- src/components/home/HomeGardenScene.tsx | 4 +- src/components/home/HomeMapModal.tsx | 73 +++++++++++++++++++++++++ src/hooks/home/useHomeApi.ts | 12 ++++ src/pages/home/HomeScreen.tsx | 24 +++++--- src/types/home/garden.ts | 1 + src/types/home/panel.ts | 15 +++++ 9 files changed, 161 insertions(+), 45 deletions(-) create mode 100644 src/components/home/HomeMapModal.tsx create mode 100644 src/types/home/panel.ts diff --git a/HOME_MIGRATION_CHECKLIST.md b/HOME_MIGRATION_CHECKLIST.md index 0f2189b..bff049d 100644 --- a/HOME_MIGRATION_CHECKLIST.md +++ b/HOME_MIGRATION_CHECKLIST.md @@ -19,7 +19,7 @@ ## 3. 홈 상호작용 연결 -- [ ] 지도 버튼 동작 연결 +- [x] 지도 버튼 모달 연결 - [x] 트래킹 모달 RN 버전 이식 - [x] 감정 체크 모달 RN 버전 이식 - [x] 물 주기 액션 연결 @@ -28,9 +28,9 @@ ## 4. 데이터/API 연결 - [x] `/api/v1/home` 요약 데이터 연결 -- [ ] `panel` API 존재 여부 재확인 -- [x] 홈 액션 API 훅 추가 -- [ ] 하단 시트 데이터 소스를 `panel` 기준으로 분리할지 결정 +- [x] `panel` API 존재 여부 재확인 +- [x] `panel` API 훅/타입 추가 +- [x] 하단 시트 데이터 소스를 `panel` 기준으로 분리 - [ ] 물/햇빛 액션 API 계약 상세 확인 ## 5. 홈 UI 마감 diff --git a/src/apis/home/homeApi.ts b/src/apis/home/homeApi.ts index f992cd4..84c4123 100644 --- a/src/apis/home/homeApi.ts +++ b/src/apis/home/homeApi.ts @@ -4,6 +4,7 @@ import { normalizeHomeSummaryPayload, type HomeSummaryPayload, } from "@/types/home/garden"; +import type { HomePanelPayload } from "@/types/home/panel"; export const getHomeSummary = async (): ApiResponse => { const res = await api.get("/api/v1/home"); @@ -14,6 +15,11 @@ export const getHomeSummary = async (): ApiResponse => { }; }; +export const getHomePanel = async (): ApiResponse => { + const res = await api.get("/api/v1/home/panel"); + return res.data; +}; + export const postGardenSunlight = async (gardenId: number) => { const res = await api.post(`/api/v1/gardens/${gardenId}/sunlight`); return res.data; diff --git a/src/components/home/HomeBottomSheet.tsx b/src/components/home/HomeBottomSheet.tsx index 9757281..b785d98 100644 --- a/src/components/home/HomeBottomSheet.tsx +++ b/src/components/home/HomeBottomSheet.tsx @@ -1,14 +1,13 @@ import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; import { RightIcon } from "@/assets/icons/CommonIcons"; -import { getLevelIcon } from "@/assets/icons/LevelIcons"; import { getMissionCompleted, type TodayMission } from "@/types/home/garden"; +import type { HomePanelPayload } from "@/types/home/panel"; export default function HomeBottomSheet({ expanded, onToggle, missions, - currentExp, - requiredExp, + panel, currentLevel, onPressLog, onPressFeed, @@ -19,8 +18,7 @@ export default function HomeBottomSheet({ expanded: boolean; onToggle: () => void; missions: TodayMission[]; - currentExp: number; - requiredExp: number; + panel?: HomePanelPayload; currentLevel: number; onPressLog: () => void; onPressFeed: () => void; @@ -28,35 +26,39 @@ export default function HomeBottomSheet({ onPressMission: (mission: TodayMission) => void; onPressEmotionCheck: () => void; }) { - const progressPercent = - requiredExp > 0 ? Math.min(100, Math.round((currentExp / requiredExp) * 100)) : 0; - const LevelIcon = getLevelIcon(Math.max(0, Math.min(3, currentLevel))); const checkingMission = missions.find(mission => mission.missionType === "CHECKING"); const diaryMission = missions.find(mission => mission.missionType === "DIARY"); const quizMission = missions.find(mission => mission.missionType === "QUIZ"); + const progressPercent = panel?.wishTree.progressPercent ?? 0; + const currentStage = panel?.wishTree.currentStage ?? `LV.${currentLevel}`; + const nextStage = panel?.wishTree.nextStage ?? `LV.${currentLevel + 1}`; const missionCards: Array<{ key: string; label: string; mission?: TodayMission; + checked: boolean; onPress: () => void; }> = [ { key: "checking", label: "마음 건강 체크", mission: checkingMission, + checked: panel?.isCheckingCompleted ?? (checkingMission ? getMissionCompleted(checkingMission) : false), onPress: onPressEmotionCheck, }, { key: "diary", label: "일기 쓰기", mission: diaryMission, + checked: panel?.isDairyCompleted ?? (diaryMission ? getMissionCompleted(diaryMission) : false), onPress: () => diaryMission && onPressMission(diaryMission), }, { key: "quiz", label: "퀴즈 풀기", mission: quizMission, + checked: panel?.isQuizCompleted ?? (quizMission ? getMissionCompleted(quizMission) : false), onPress: () => quizMission && onPressMission(quizMission), }, ]; @@ -73,31 +75,25 @@ export default function HomeBottomSheet({ 오늘의 미션 {missionCards.map(card => ( - + ))} - {missionCards.map(card => { - const checked = card.mission ? getMissionCompleted(card.mission) : false; - return ( - - - {card.label} - - {checked ? : } - - ); - })} + {missionCards.map(card => ( + + + {card.label} + + {card.checked ? : } + + ))} {expanded ? ( @@ -106,7 +102,7 @@ export default function HomeBottomSheet({ - + T 소망 나무 @@ -117,8 +113,8 @@ export default function HomeBottomSheet({ - LV.{currentLevel} - LV.{currentLevel + 1} + {currentStage} + {nextStage} @@ -278,7 +274,10 @@ const styles = StyleSheet.create({ wishTitleRow: { flexDirection: "row", alignItems: "center", - gap: 4, + gap: 6, + }, + wishTreeIcon: { + fontSize: 24, }, wishTitle: { fontSize: 18, diff --git a/src/components/home/HomeGardenScene.tsx b/src/components/home/HomeGardenScene.tsx index 02074da..0714a94 100644 --- a/src/components/home/HomeGardenScene.tsx +++ b/src/components/home/HomeGardenScene.tsx @@ -32,6 +32,7 @@ type Props = { garden: GardenSummary | null; isEmotionAnswered: boolean; answeredKind: SurveyAnswerKind | null; + onPressMap: () => void; onPressTracking: () => void; onPressEmotion: () => void; onPressUnlock: () => void; @@ -45,6 +46,7 @@ export default function HomeGardenScene({ garden, isEmotionAnswered, answeredKind, + onPressMap, onPressTracking, onPressEmotion, onPressUnlock, @@ -121,7 +123,7 @@ export default function HomeGardenScene({ {/* Slot header follows the FE layout: map affordance, centered slot title, empty spacer. */} - + {title ?? `${userName ?? "나풀나풀"}의 정원`} diff --git a/src/components/home/HomeMapModal.tsx b/src/components/home/HomeMapModal.tsx new file mode 100644 index 0000000..b80e42a --- /dev/null +++ b/src/components/home/HomeMapModal.tsx @@ -0,0 +1,73 @@ +import { + Image, + Modal, + Pressable, + StyleSheet, + Text, + TouchableOpacity, + View, +} from "react-native"; + +const mapImages = [ + require("@/assets/images/map/map1.png"), + require("@/assets/images/map/map2.png"), + require("@/assets/images/map/map3.png"), + require("@/assets/images/map/map4.png"), +] as const; + +export default function HomeMapModal({ + visible, + slotNumber, + onClose, +}: { + visible: boolean; + slotNumber: number; + onClose: () => void; +}) { + const imageSource = mapImages[Math.max(0, Math.min(mapImages.length - 1, slotNumber - 1))]; + + return ( + + + + + 텃밭 지도 + + + + + + + ); +} + +const styles = StyleSheet.create({ + backdrop: { + flex: 1, + backgroundColor: "rgba(0,0,0,0.38)", + alignItems: "center", + justifyContent: "center", + padding: 24, + }, + card: { + width: "100%", + maxWidth: 360, + borderRadius: 28, + backgroundColor: "#FFFFFF", + paddingHorizontal: 18, + paddingTop: 20, + paddingBottom: 18, + alignItems: "center", + gap: 12, + }, + title: { + fontSize: 18, + fontWeight: "700", + color: "#171717", + }, + mapImage: { + width: 320, + height: 320, + borderRadius: 18, + }, +}); diff --git a/src/hooks/home/useHomeApi.ts b/src/hooks/home/useHomeApi.ts index e8d0574..a99a65d 100644 --- a/src/hooks/home/useHomeApi.ts +++ b/src/hooks/home/useHomeApi.ts @@ -1,12 +1,14 @@ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import type { AxiosError } from "axios"; import { + getHomePanel, getHomeSummary, postGardenMyWater, postGardenSunlight, } from "@/apis/home/homeApi"; import type { GlobalResponse } from "@/types/common/apiResponse.type"; import type { HomeSummaryPayload } from "@/types/home/garden"; +import type { HomePanelPayload } from "@/types/home/panel"; export const useHomeApi = () => useQuery< @@ -20,6 +22,14 @@ export const useHomeApi = () => refetchOnMount: "always", }); +export const useHomePanelApi = () => + useQuery, AxiosError, HomePanelPayload>({ + queryKey: ["home-panel"], + queryFn: getHomePanel, + select: data => data.result, + refetchOnMount: "always", + }); + export const useGardenSunlightAction = () => { const queryClient = useQueryClient(); @@ -27,6 +37,7 @@ export const useGardenSunlightAction = () => { mutationFn: (gardenId: number) => postGardenSunlight(gardenId), onSuccess: async () => { await queryClient.invalidateQueries({ queryKey: ["home-summary"] }); + await queryClient.invalidateQueries({ queryKey: ["home-panel"] }); }, }); }; @@ -38,6 +49,7 @@ export const useGardenWaterAction = () => { mutationFn: (gardenId: number) => postGardenMyWater(gardenId), onSuccess: async () => { await queryClient.invalidateQueries({ queryKey: ["home-summary"] }); + await queryClient.invalidateQueries({ queryKey: ["home-panel"] }); }, }); }; diff --git a/src/pages/home/HomeScreen.tsx b/src/pages/home/HomeScreen.tsx index dcc7663..dcd9559 100644 --- a/src/pages/home/HomeScreen.tsx +++ b/src/pages/home/HomeScreen.tsx @@ -5,9 +5,10 @@ import { SafeAreaView } from "react-native-safe-area-context"; import HomeBottomSheet from "@/components/home/HomeBottomSheet"; import HomeEmotionModal from "@/components/home/HomeEmotionModal"; import HomeGardenScene from "@/components/home/HomeGardenScene"; +import HomeMapModal from "@/components/home/HomeMapModal"; import HomeTrackingModal from "@/components/home/HomeTrackingModal"; import StatusView from "@/components/common/StatusView"; -import useHomeApi from "@/hooks/home/useHomeApi"; +import useHomeApi, { useHomePanelApi } from "@/hooks/home/useHomeApi"; import { useDailySurvey } from "@/hooks/mission/useMissionApi"; import type { MainTabScreenProps } from "@/navigation/types"; import { useHomeSummaryStore } from "@/stores/useHomeSummaryStore"; @@ -37,12 +38,14 @@ type SceneItem = { export default function HomeScreen({ navigation }: Props) { const { data, error, isLoading, refetch } = useHomeApi(); + const { data: panel } = useHomePanelApi(); const surveyQuery = useDailySurvey(); const { user, gardens, missions, hydrate } = useHomeSummaryStore(); const [currentPage, setCurrentPage] = useState(0); const [isSheetExpanded, setIsSheetExpanded] = useState(false); const [isEmotionModalOpen, setIsEmotionModalOpen] = useState(false); const [isTrackingModalOpen, setIsTrackingModalOpen] = useState(false); + const [isMapModalOpen, setIsMapModalOpen] = useState(false); const [emotionAnswerKind, setEmotionAnswerKind] = useState(null); useEffect(() => { @@ -54,8 +57,9 @@ export default function HomeScreen({ navigation }: Props) { isLoading, hasData: Boolean(data), hasError: Boolean(error), + hasPanel: Boolean(panel), }); - }, [data, error, isLoading]); + }, [data, error, isLoading, panel]); useEffect(() => { if (data) { @@ -71,8 +75,8 @@ export default function HomeScreen({ navigation }: Props) { const gardenSummaries = data?.gardenSummaries ?? gardens; const todayMissions = data?.todayMissions ?? missions; const isEmotionAnswered = surveyQuery.data?.isAnswered ?? false; + const initialPage = Math.max(0, Math.min(3, (userInfo?.lastAccessedSlotNumber ?? 1) - 1)); - // Home summary payload is normalized into four fixed garden scenes for the pager UI. const scenes = useMemo( () => backgrounds.map((background, index) => ({ @@ -110,8 +114,9 @@ export default function HomeScreen({ navigation }: Props) { {/* Full-screen garden scenes follow the MainFE slide-per-plot structure. */} { const position = event.nativeEvent.position; setCurrentPage(position); @@ -127,6 +132,7 @@ export default function HomeScreen({ navigation }: Props) { garden={scene.garden} isEmotionAnswered={isEmotionAnswered} answeredKind={emotionAnswerKind} + onPressMap={() => setIsMapModalOpen(true)} onPressTracking={() => setIsTrackingModalOpen(true)} onPressEmotion={() => setIsEmotionModalOpen(true)} onPressUnlock={() => navigation.navigate("UnlockGarden")} @@ -136,7 +142,6 @@ export default function HomeScreen({ navigation }: Props) { ))} - {/* Pagination stays above the scene while the bottom sheet overlays from below. */} {scenes.map((scene, index) => ( @@ -148,13 +153,11 @@ export default function HomeScreen({ navigation }: Props) { - {/* Mission and wish-tree summary are grouped into a single collapsible bottom sheet. */} setIsSheetExpanded(prev => !prev)} missions={todayMissions} - currentExp={userInfo?.currentExp ?? 0} - requiredExp={userInfo?.requiredExpForNextLevel ?? 100} + panel={panel} currentLevel={userInfo?.level ?? 0} onPressLog={() => navigation.navigate("Log")} onPressFeed={() => navigation.navigate("Feed")} @@ -177,6 +180,11 @@ export default function HomeScreen({ navigation }: Props) { visible={isTrackingModalOpen} onClose={() => setIsTrackingModalOpen(false)} /> + setIsMapModalOpen(false)} + /> ); } diff --git a/src/types/home/garden.ts b/src/types/home/garden.ts index 9ed3076..cf5f7f3 100644 --- a/src/types/home/garden.ts +++ b/src/types/home/garden.ts @@ -33,6 +33,7 @@ export interface UserInfo { currentExp: number; requiredExpForNextLevel: number; unreadNotificationCount: number; + lastAccessedSlotNumber?: number; } export interface HomeSummaryPayload { diff --git a/src/types/home/panel.ts b/src/types/home/panel.ts new file mode 100644 index 0000000..3290741 --- /dev/null +++ b/src/types/home/panel.ts @@ -0,0 +1,15 @@ +export interface HomePanelWishTree { + currentStage: string; + nextStage: string; + currentPoints: number; + requiredPointsForNextStage: number; + progressPercent: number; +} + +export interface HomePanelPayload { + isDairyCompleted: boolean; + isCheckingCompleted: boolean; + isQuizCompleted: boolean; + isQuizResultAvailable?: boolean; + wishTree: HomePanelWishTree; +} From 6929099e622fd92e660640db9d94633fd8240449 Mon Sep 17 00:00:00 2001 From: lejuho Date: Fri, 13 Mar 2026 00:50:30 +0900 Subject: [PATCH 09/92] =?UTF-8?q?fix:=20=ED=99=88=20=ED=99=94=EB=B6=84=20?= =?UTF-8?q?=EC=9C=84=EC=B9=98=EC=99=80=20=EB=A7=90=ED=92=8D=EC=84=A0=20?= =?UTF-8?q?=EB=B0=8F=20=ED=8C=A8=EB=84=90=20=EB=93=9C=EB=9E=98=EA=B7=B8=20?= =?UTF-8?q?=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/home/HomeAvatarStage.tsx | 187 +++++++++++++--------- src/components/home/HomeBottomSheet.tsx | 204 +++++++++++++++--------- src/components/home/HomeGardenScene.tsx | 8 +- src/pages/home/HomeScreen.tsx | 8 +- 4 files changed, 252 insertions(+), 155 deletions(-) diff --git a/src/components/home/HomeAvatarStage.tsx b/src/components/home/HomeAvatarStage.tsx index 2bdaea8..90c3e65 100644 --- a/src/components/home/HomeAvatarStage.tsx +++ b/src/components/home/HomeAvatarStage.tsx @@ -1,3 +1,4 @@ +import { useEffect, useState } from "react"; import { Image, Pressable, StyleSheet, Text, TouchableOpacity, View } from "react-native"; import type { SurveyAnswerKind } from "@/types/missions"; import { ANSWER_COPY } from "@/components/home/HomeEmotionModal"; @@ -22,30 +23,26 @@ export default function HomeAvatarStage({ onPressEmotion: () => void; onPressBird: () => void; }) { - const answerMessage = answeredKind ? ANSWER_COPY[answeredKind] : null; + const [showAnsweredBubble, setShowAnsweredBubble] = useState(false); + const answerMessage = answeredKind ? ANSWER_COPY[answeredKind] : "좋은 기분으로 오늘 하루 계속 이어가요!"; + + useEffect(() => { + if (!isEmotionAnswered) { + setShowAnsweredBubble(false); + } + }, [isEmotionAnswered]); + + const handlePressMascot = () => { + if (isEmotionAnswered) { + setShowAnsweredBubble(prev => !prev); + return; + } + + onPressEmotion(); + }; return ( - - {!isEmotionAnswered ? ( - - - - 오늘도 만나서 정말 반가워요!{"\n"}괜찮으시다면 오늘 하루는 어떠셨는지{"\n"}살짝 알려주시겠어요? - - - 마음 건강 체크 - - - - - ) : answerMessage ? ( - - {answerMessage} - - ) : null} - - + + + {!isEmotionAnswered ? ( + + + + 오늘도 만나서 정말 반가워요!{"\n"}괜찮으시다면 오늘 하루는 어떠셨는지{"\n"}살짝 알려주시겠어요? + + + 마음 건강 체크 + + + + + ) : showAnsweredBubble ? ( + + + {answerMessage} + + + + ) : null} + + + + + + @@ -71,88 +96,102 @@ const styles = StyleSheet.create({ width: "100%", alignItems: "center", justifyContent: "center", - paddingBottom: 12, }, - characterBlock: { + avatarCluster: { width: "100%", + minHeight: 390, + alignItems: "center", + justifyContent: "center", + position: "relative", + paddingBottom: 36, + }, + avatarImage: { + width: 320, + height: 320, + marginBottom: 34, + }, + wateringImage: { + position: "absolute", + left: "36%", + bottom: 160, + width: 118, + height: 118, + }, + wateringImageHidden: { + opacity: 0, + }, + leftCompanion: { + position: "absolute", + left: 22, + bottom: 18, alignItems: "center", - minHeight: 166, + width: 154, }, balloonWrap: { alignItems: "center", + marginBottom: 2, }, balloon: { borderRadius: 24, backgroundColor: "#FFFFFF", - paddingHorizontal: 22, - paddingVertical: 18, + paddingHorizontal: 20, + paddingVertical: 16, alignItems: "center", - maxWidth: 290, + width: 210, + }, + answeredBalloon: { + borderRadius: 24, + backgroundColor: "rgba(255,255,255,0.96)", + paddingHorizontal: 18, + paddingVertical: 14, + width: 200, + }, + balloonTail: { + width: 18, + height: 18, + backgroundColor: "#FFFFFF", + transform: [{ rotate: "45deg" }], + marginTop: -9, + marginLeft: -60, }, balloonText: { - fontSize: 14, - lineHeight: 21, + fontSize: 13, + lineHeight: 19, + color: "#171717", + textAlign: "center", + }, + answeredBalloonText: { + fontSize: 13, + lineHeight: 18, color: "#171717", textAlign: "center", }, checkButton: { - marginTop: 14, + marginTop: 12, borderRadius: 14, backgroundColor: "#7DC960", - paddingHorizontal: 20, - paddingVertical: 10, + paddingHorizontal: 16, + paddingVertical: 9, }, checkButtonText: { color: "#FFFFFF", - fontSize: 14, + fontSize: 13, fontWeight: "700", }, - characterImage: { - width: 78, - height: 78, - marginTop: -2, - }, - answeredBalloon: { - borderRadius: 24, - backgroundColor: "rgba(255,255,255,0.94)", - paddingHorizontal: 22, - paddingVertical: 16, - maxWidth: 280, - }, - answeredBalloonText: { - fontSize: 14, - lineHeight: 20, - color: "#171717", - textAlign: "center", - }, - avatarCluster: { - width: "100%", - minHeight: 320, - alignItems: "center", - justifyContent: "flex-end", - position: "relative", + mascotButton: { + marginTop: -4, }, - avatarImage: { - width: 290, - height: 290, - }, - wateringImage: { - position: "absolute", - left: "32%", - bottom: 110, - width: 126, - height: 126, - }, - wateringImageHidden: { - opacity: 0, + characterImage: { + width: 82, + height: 82, }, birdButton: { position: "absolute", - right: 48, - bottom: 28, + right: 42, + bottom: 42, }, birdImage: { - width: 86, - height: 86, + width: 84, + height: 84, }, }); diff --git a/src/components/home/HomeBottomSheet.tsx b/src/components/home/HomeBottomSheet.tsx index b785d98..285d61b 100644 --- a/src/components/home/HomeBottomSheet.tsx +++ b/src/components/home/HomeBottomSheet.tsx @@ -1,11 +1,23 @@ -import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import { useEffect, useRef } from "react"; +import { + Animated, + PanResponder, + StyleSheet, + Text, + TouchableOpacity, + View, +} from "react-native"; import { RightIcon } from "@/assets/icons/CommonIcons"; import { getMissionCompleted, type TodayMission } from "@/types/home/garden"; import type { HomePanelPayload } from "@/types/home/panel"; +const COLLAPSED_HEIGHT = 196; +const EXPANDED_HEIGHT = 430; +const DRAG_RANGE = EXPANDED_HEIGHT - COLLAPSED_HEIGHT; + export default function HomeBottomSheet({ expanded, - onToggle, + onExpandedChange, missions, panel, currentLevel, @@ -16,7 +28,7 @@ export default function HomeBottomSheet({ onPressEmotionCheck, }: { expanded: boolean; - onToggle: () => void; + onExpandedChange: (next: boolean) => void; missions: TodayMission[]; panel?: HomePanelPayload; currentLevel: number; @@ -26,6 +38,48 @@ export default function HomeBottomSheet({ onPressMission: (mission: TodayMission) => void; onPressEmotionCheck: () => void; }) { + const translateY = useRef(new Animated.Value(expanded ? 0 : DRAG_RANGE)).current; + const dragStart = useRef(DRAG_RANGE); + + useEffect(() => { + Animated.spring(translateY, { + toValue: expanded ? 0 : DRAG_RANGE, + useNativeDriver: true, + tension: 90, + friction: 12, + }).start(); + }, [expanded, translateY]); + + const panResponder = useRef( + PanResponder.create({ + onMoveShouldSetPanResponder: (_, gestureState) => Math.abs(gestureState.dy) > 4, + onPanResponderGrant: () => { + translateY.stopAnimation(value => { + dragStart.current = value; + }); + }, + onPanResponderMove: (_, gestureState) => { + const next = Math.max(0, Math.min(DRAG_RANGE, dragStart.current + gestureState.dy)); + translateY.setValue(next); + }, + onPanResponderRelease: (_, gestureState) => { + const movedUpEnough = gestureState.dy < -40; + const movedDownEnough = gestureState.dy > 40; + const nextExpanded = movedUpEnough ? true : movedDownEnough ? false : !expanded ? false : true; + if (!movedUpEnough && !movedDownEnough) { + translateY.stopAnimation(value => { + onExpandedChange(value < DRAG_RANGE / 2); + }); + return; + } + onExpandedChange(nextExpanded); + }, + onPanResponderTerminate: () => { + onExpandedChange(expanded); + }, + }) + ).current; + const checkingMission = missions.find(mission => mission.missionType === "CHECKING"); const diaryMission = missions.find(mission => mission.missionType === "DIARY"); const quizMission = missions.find(mission => mission.missionType === "QUIZ"); @@ -36,99 +90,95 @@ export default function HomeBottomSheet({ const missionCards: Array<{ key: string; label: string; - mission?: TodayMission; checked: boolean; onPress: () => void; }> = [ { key: "checking", label: "마음 건강 체크", - mission: checkingMission, checked: panel?.isCheckingCompleted ?? (checkingMission ? getMissionCompleted(checkingMission) : false), onPress: onPressEmotionCheck, }, { key: "diary", label: "일기 쓰기", - mission: diaryMission, checked: panel?.isDairyCompleted ?? (diaryMission ? getMissionCompleted(diaryMission) : false), onPress: () => diaryMission && onPressMission(diaryMission), }, { key: "quiz", label: "퀴즈 풀기", - mission: quizMission, checked: panel?.isQuizCompleted ?? (quizMission ? getMissionCompleted(quizMission) : false), onPress: () => quizMission && onPressMission(quizMission), }, ]; return ( - - - - - + + + + + + + + + + 오늘의 미션 + + {missionCards.map(card => ( + + ))} + + - - - 오늘의 미션 - + {missionCards.map(card => ( - + + + {card.label} + + {card.checked ? : } + ))} - - - - {missionCards.map(card => ( - - - {card.label} - - {card.checked ? : } - - ))} - - {expanded ? ( - <> - + - - - T - 소망 나무 + + + + T - - {progressPercent >= 100 - ? "지금 바로 새로운 텃밭을 열 수 있어요!" - : `소망 나무 다음 성장까지 ${100 - progressPercent}%가 남았어요!`} - + 소망 나무 + + {progressPercent >= 100 + ? "지금 바로 새로운 텃밭을 열 수 있어요!" + : `소망 나무 다음 성장까지 ${100 - progressPercent}%가 남았어요!`} + + - - {currentStage} - {nextStage} - - - - + + {currentStage} + {nextStage} + + + + - - - - - - - ) : null} + + + + + + - + ); } @@ -150,6 +200,10 @@ function MissionStatusDot({ checked }: { checked: boolean }) { } const styles = StyleSheet.create({ + sheetOuter: { + ...StyleSheet.absoluteFillObject, + justifyContent: "flex-end", + }, quickLink: { flex: 1, borderRadius: 14, @@ -163,20 +217,11 @@ const styles = StyleSheet.create({ fontWeight: "700", }, sheetWrap: { - position: "absolute", - left: 0, - right: 0, - bottom: 0, - alignItems: "center", - }, - sheetWrapCollapsed: { - height: 196, - }, - sheetWrapExpanded: { - height: 430, + height: EXPANDED_HEIGHT, }, sheet: { width: "100%", + height: EXPANDED_HEIGHT, borderTopLeftRadius: 24, borderTopRightRadius: 24, borderTopWidth: 1, @@ -194,6 +239,7 @@ const styles = StyleSheet.create({ sheetHandleButton: { alignItems: "center", paddingBottom: 8, + paddingTop: 4, }, sheetHandle: { width: 40, @@ -276,8 +322,18 @@ const styles = StyleSheet.create({ alignItems: "center", gap: 6, }, - wishTreeIcon: { - fontSize: 24, + wishTreeBadge: { + width: 26, + height: 26, + borderRadius: 13, + backgroundColor: "#EEF7E8", + alignItems: "center", + justifyContent: "center", + }, + wishTreeBadgeText: { + color: "#59A647", + fontSize: 13, + fontWeight: "700", }, wishTitle: { fontSize: 18, diff --git a/src/components/home/HomeGardenScene.tsx b/src/components/home/HomeGardenScene.tsx index 0714a94..d0d08a6 100644 --- a/src/components/home/HomeGardenScene.tsx +++ b/src/components/home/HomeGardenScene.tsx @@ -121,7 +121,6 @@ export default function HomeGardenScene({ - {/* Slot header follows the FE layout: map affordance, centered slot title, empty spacer. */} @@ -255,12 +254,12 @@ const styles = StyleSheet.create({ justifyContent: "center", alignItems: "center", paddingHorizontal: 24, - paddingBottom: 120, + paddingBottom: 168, }, actionRail: { position: "absolute", right: 10, - bottom: 180, + bottom: 238, zIndex: 3, gap: 8, }, @@ -273,7 +272,7 @@ const styles = StyleSheet.create({ lockedOverlay: { flex: 1, marginHorizontal: 24, - marginBottom: 120, + marginBottom: 168, borderRadius: 28, backgroundColor: "rgba(255,255,255,0.68)", justifyContent: "center", @@ -315,6 +314,7 @@ const styles = StyleSheet.create({ width: "100%", alignItems: "center", justifyContent: "center", + paddingBottom: 30, }, emptyBubble: { marginBottom: 12, diff --git a/src/pages/home/HomeScreen.tsx b/src/pages/home/HomeScreen.tsx index dcd9559..176e159 100644 --- a/src/pages/home/HomeScreen.tsx +++ b/src/pages/home/HomeScreen.tsx @@ -112,7 +112,6 @@ export default function HomeScreen({ navigation }: Props) { return ( - {/* Full-screen garden scenes follow the MainFE slide-per-plot structure. */} setIsSheetExpanded(prev => !prev)} + onExpandedChange={setIsSheetExpanded} missions={todayMissions} panel={panel} currentLevel={userInfo?.level ?? 0} @@ -174,7 +173,10 @@ export default function HomeScreen({ navigation }: Props) { setIsEmotionModalOpen(false)} - onAnswered={answer => setEmotionAnswerKind(answer)} + onAnswered={answer => { + setEmotionAnswerKind(answer); + setIsEmotionModalOpen(false); + }} /> Date: Fri, 13 Mar 2026 00:56:08 +0900 Subject: [PATCH 10/92] =?UTF-8?q?refactor:=20=EC=9D=B8=EC=A6=9D=20?= =?UTF-8?q?=EA=B0=B1=EC=8B=A0=20API=EB=A5=BC=20=EB=B6=84=EB=A6=AC=ED=95=B4?= =?UTF-8?q?=20=EC=88=9C=ED=99=98=20=EC=B0=B8=EC=A1=B0=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/instance.ts | 2 +- src/apis/register/refreshApi.ts | 17 +++++++++++++++++ src/apis/register/registerApi.ts | 12 ------------ 3 files changed, 18 insertions(+), 13 deletions(-) create mode 100644 src/apis/register/refreshApi.ts diff --git a/src/apis/instance.ts b/src/apis/instance.ts index 9c19196..4e90dbf 100644 --- a/src/apis/instance.ts +++ b/src/apis/instance.ts @@ -4,7 +4,7 @@ import axios, { AxiosRequestHeaders, InternalAxiosRequestConfig, } from "axios"; -import { refreshAuthApi } from "@/apis/register/registerApi"; +import { refreshAuthApi } from "@/apis/register/refreshApi"; import useTokenStore from "@/stores/useTokenStore"; import { logout } from "@/utils/auth"; diff --git a/src/apis/register/refreshApi.ts b/src/apis/register/refreshApi.ts new file mode 100644 index 0000000..1e1368b --- /dev/null +++ b/src/apis/register/refreshApi.ts @@ -0,0 +1,17 @@ +import axios from "axios"; +import { PostRegisterResponse } from "@/types/apis/register"; +import { ApiResponse } from "@/types/common/apiResponse.type"; + +const API_URL = process.env.EXPO_PUBLIC_API_URL || "https://api.napulnapul.com"; + +const refreshClient = axios.create({ + baseURL: API_URL, +}); + +export const refreshAuthApi = async ( + refreshToken: string +): ApiResponse => { + return refreshClient + .post("/api/v1/auth/refresh", { refreshToken }) + .then(res => res.data); +}; diff --git a/src/apis/register/registerApi.ts b/src/apis/register/registerApi.ts index 3d6540c..44772bc 100644 --- a/src/apis/register/registerApi.ts +++ b/src/apis/register/registerApi.ts @@ -16,15 +16,3 @@ export const loginWithSupabaseApi = async ( ): ApiResponse => { return axios.post("/api/v1/auth/supabase", { accessToken }).then(res => res.data); }; - -export const refreshAuthApi = async ( - refreshToken: string -): ApiResponse => { - return axios - .post( - "/api/v1/auth/refresh", - { refreshToken }, - { _skipAuth: true } as const - ) - .then(res => res.data); -}; From 48702b7fc27c45ff83ad1343c58fe958815f003e Mon Sep 17 00:00:00 2001 From: lejuho Date: Fri, 13 Mar 2026 01:14:37 +0900 Subject: [PATCH 11/92] =?UTF-8?q?fix:=20=ED=99=88=20=EB=A7=88=EC=9D=8C?= =?UTF-8?q?=EA=B1=B4=EA=B0=95=20=EC=B2=B4=ED=81=AC=20=EC=9D=91=EB=8B=B5=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=20=EC=A6=89=EC=8B=9C=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/home/HomeEmotionModal.tsx | 57 ++++++++++++++++--- src/pages/home/HomeScreen.tsx | 24 +++++++- src/stores/useEmotionSurveyStore.ts | 72 ++++++++++++++++++++++++ 3 files changed, 143 insertions(+), 10 deletions(-) create mode 100644 src/stores/useEmotionSurveyStore.ts diff --git a/src/components/home/HomeEmotionModal.tsx b/src/components/home/HomeEmotionModal.tsx index c4f19ba..9c6a25b 100644 --- a/src/components/home/HomeEmotionModal.tsx +++ b/src/components/home/HomeEmotionModal.tsx @@ -1,4 +1,5 @@ -import { useMemo } from "react"; +import { useMemo, useState } from "react"; +import type { AxiosError } from "axios"; import { Image, Modal, @@ -9,6 +10,7 @@ import { View, } from "react-native"; import { useAnswerDailySurvey, useDailySurvey } from "@/hooks/mission/useMissionApi"; +import type { ErrorResponse } from "@/types/common/apiResponse.type"; import { SURVEY_ANSWER_VALUE_MAP, type SurveyAnswerKind, @@ -33,6 +35,7 @@ export default function HomeEmotionModal({ }) { const { data, isLoading } = useDailySurvey(); const answerMutation = useAnswerDailySurvey(); + const [submitErrorMessage, setSubmitErrorMessage] = useState(null); const answerOptions = useMemo( () => @@ -45,18 +48,44 @@ export default function HomeEmotionModal({ ); const handleAnswer = async (answer: SurveyAnswerKind) => { - if (!data?.id || data.isAnswered || answerMutation.isPending) { + if (!data?.id || answerMutation.isPending) { + return; + } + + if (data.isAnswered) { onAnswered(answer); onClose(); return; } - await answerMutation.mutateAsync({ - questionId: data.id, - answer: SURVEY_ANSWER_VALUE_MAP[answer], - }); - onAnswered(answer); - onClose(); + setSubmitErrorMessage(null); + + try { + await answerMutation.mutateAsync({ + questionId: data.id, + answer: SURVEY_ANSWER_VALUE_MAP[answer], + }); + + /* + * 한글 주석: + * 홈 팝업은 제출 직후 닫히고 말풍선 상태도 즉시 바뀌어야 한다. + * 서버 재조회 완료를 기다리지 않고 성공 시점을 홈 화면에 바로 전달한다. + */ + onAnswered(answer); + onClose(); + } catch (error) { + const axiosError = error as AxiosError; + const status = axiosError.response?.status; + const serverMessage = axiosError.response?.data?.message; + + if (status === 409) { + onAnswered(answer); + onClose(); + return; + } + + setSubmitErrorMessage(serverMessage ?? "답변 저장에 실패했습니다. 잠시 후 다시 시도해주세요."); + } }; const isAnswered = data?.isAnswered ?? false; @@ -96,6 +125,10 @@ export default function HomeEmotionModal({ ))} )} + + {submitErrorMessage ? ( + {submitErrorMessage} + ) : null} @@ -170,4 +203,12 @@ const styles = StyleSheet.create({ fontSize: 15, fontWeight: "700", }, + errorText: { + width: "100%", + fontSize: 13, + lineHeight: 18, + color: "#B91C1C", + textAlign: "center", + }, }); + diff --git a/src/pages/home/HomeScreen.tsx b/src/pages/home/HomeScreen.tsx index 176e159..fbf3671 100644 --- a/src/pages/home/HomeScreen.tsx +++ b/src/pages/home/HomeScreen.tsx @@ -11,6 +11,7 @@ import StatusView from "@/components/common/StatusView"; import useHomeApi, { useHomePanelApi } from "@/hooks/home/useHomeApi"; import { useDailySurvey } from "@/hooks/mission/useMissionApi"; import type { MainTabScreenProps } from "@/navigation/types"; +import { useEmotionSurveyStore, getEmotionSurveyCooldownActive } from "@/stores/useEmotionSurveyStore"; import { useHomeSummaryStore } from "@/stores/useHomeSummaryStore"; import { type GardenSummary, @@ -41,6 +42,12 @@ export default function HomeScreen({ navigation }: Props) { const { data: panel } = useHomePanelApi(); const surveyQuery = useDailySurvey(); const { user, gardens, missions, hydrate } = useHomeSummaryStore(); + const { + lastAnsweredAt, + lastAnswerKind, + markAnswered, + resetIfExpired, + } = useEmotionSurveyStore(); const [currentPage, setCurrentPage] = useState(0); const [isSheetExpanded, setIsSheetExpanded] = useState(false); const [isEmotionModalOpen, setIsEmotionModalOpen] = useState(false); @@ -52,6 +59,10 @@ export default function HomeScreen({ navigation }: Props) { debugScreenMounted("HomeScreen"); }, []); + useEffect(() => { + resetIfExpired(); + }, [lastAnsweredAt, resetIfExpired]); + useEffect(() => { debugLog("HomeScreen", "query state changed", { isLoading, @@ -74,7 +85,15 @@ export default function HomeScreen({ navigation }: Props) { const userInfo = data?.userInfo ?? user; const gardenSummaries = data?.gardenSummaries ?? gardens; const todayMissions = data?.todayMissions ?? missions; - const isEmotionAnswered = surveyQuery.data?.isAnswered ?? false; + const isEmotionCooldownActive = getEmotionSurveyCooldownActive(lastAnsweredAt); + + /* + * 한글 주석: + * 홈 말풍선은 서버 응답과 별개로, 홈에서 방금 답한 직후 상태도 바로 반영해야 한다. + * 로컬 24시간 완료 상태를 함께 보아야 버튼이 다시 나타나는 깜빡임을 막을 수 있다. + */ + const isEmotionAnswered = (surveyQuery.data?.isAnswered ?? false) || isEmotionCooldownActive; + const answeredKind = emotionAnswerKind ?? lastAnswerKind; const initialPage = Math.max(0, Math.min(3, (userInfo?.lastAccessedSlotNumber ?? 1) - 1)); const scenes = useMemo( @@ -130,7 +149,7 @@ export default function HomeScreen({ navigation }: Props) { userName={userInfo?.username} garden={scene.garden} isEmotionAnswered={isEmotionAnswered} - answeredKind={emotionAnswerKind} + answeredKind={answeredKind} onPressMap={() => setIsMapModalOpen(true)} onPressTracking={() => setIsTrackingModalOpen(true)} onPressEmotion={() => setIsEmotionModalOpen(true)} @@ -175,6 +194,7 @@ export default function HomeScreen({ navigation }: Props) { onClose={() => setIsEmotionModalOpen(false)} onAnswered={answer => { setEmotionAnswerKind(answer); + markAnswered(answer); setIsEmotionModalOpen(false); }} /> diff --git a/src/stores/useEmotionSurveyStore.ts b/src/stores/useEmotionSurveyStore.ts new file mode 100644 index 0000000..7825de8 --- /dev/null +++ b/src/stores/useEmotionSurveyStore.ts @@ -0,0 +1,72 @@ +import { create } from "zustand"; +import { createJSONStorage, persist } from "zustand/middleware"; +import AsyncStorage from "@react-native-async-storage/async-storage"; +import type { SurveyAnswerKind } from "@/types/missions"; + +const EMOTION_SURVEY_COOLDOWN_MS = 24 * 60 * 60 * 1000; + +type EmotionSurveyState = { + lastAnsweredAt: number | null; + lastAnswerKind: SurveyAnswerKind | null; + markAnswered: (answerKind: SurveyAnswerKind, answeredAt?: number) => void; + resetIfExpired: () => void; + reset: () => void; +}; + +export const useEmotionSurveyStore = create()( + persist( + set => ({ + lastAnsweredAt: null, + lastAnswerKind: null, + + markAnswered: (answerKind, answeredAt = Date.now()) => + set(() => ({ + lastAnsweredAt: answeredAt, + lastAnswerKind: answerKind, + })), + + resetIfExpired: () => + set(state => { + if (!state.lastAnsweredAt) { + return state; + } + + /* + * 한글 주석: + * 홈 말풍선 노출 여부는 마지막 응답 시각 기준 24시간으로 계산한다. + * 유효 시간이 지나면 로컬 완료 상태를 비워 다음 질문 노출을 허용한다. + */ + if (Date.now() - state.lastAnsweredAt >= EMOTION_SURVEY_COOLDOWN_MS) { + return { + lastAnsweredAt: null, + lastAnswerKind: null, + }; + } + + return state; + }), + + reset: () => + set(() => ({ + lastAnsweredAt: null, + lastAnswerKind: null, + })), + }), + { + name: "emotion-survey", + storage: createJSONStorage(() => AsyncStorage), + partialize: state => ({ + lastAnsweredAt: state.lastAnsweredAt, + lastAnswerKind: state.lastAnswerKind, + }), + } + ) +); + +export const getEmotionSurveyCooldownActive = (lastAnsweredAt: number | null) => { + if (!lastAnsweredAt) { + return false; + } + + return Date.now() - lastAnsweredAt < EMOTION_SURVEY_COOLDOWN_MS; +}; From 9e66505a03569fa80d664e6b2ac39eeb4b40a1e2 Mon Sep 17 00:00:00 2001 From: lejuho Date: Fri, 13 Mar 2026 01:24:17 +0900 Subject: [PATCH 12/92] =?UTF-8?q?refactor:=20=ED=99=88=20=EB=AF=B8?= =?UTF-8?q?=EC=85=98=20=ED=8C=A8=EB=84=90=20=EA=B8=B0=EB=B3=B8=20=EC=9C=84?= =?UTF-8?q?=EC=B9=98=EC=99=80=20=EB=93=9C=EB=9E=98=EA=B7=B8=20=EC=98=81?= =?UTF-8?q?=EC=97=AD=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/home/HomeBottomSheet.tsx | 31 +++++++++++++++++-------- src/components/home/HomeGardenScene.tsx | 11 +++++---- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/components/home/HomeBottomSheet.tsx b/src/components/home/HomeBottomSheet.tsx index 285d61b..16c0550 100644 --- a/src/components/home/HomeBottomSheet.tsx +++ b/src/components/home/HomeBottomSheet.tsx @@ -11,7 +11,7 @@ import { RightIcon } from "@/assets/icons/CommonIcons"; import { getMissionCompleted, type TodayMission } from "@/types/home/garden"; import type { HomePanelPayload } from "@/types/home/panel"; -const COLLAPSED_HEIGHT = 196; +const COLLAPSED_HEIGHT = 104; const EXPANDED_HEIGHT = 430; const DRAG_RANGE = EXPANDED_HEIGHT - COLLAPSED_HEIGHT; @@ -117,11 +117,10 @@ export default function HomeBottomSheet({ - - - - - + + + + 오늘의 미션 @@ -130,7 +129,14 @@ export default function HomeBottomSheet({ ))} + + + {/* + * 한글 주석: + * 접힌 상태에서는 오늘의 미션 제목과 진행도만 위로 남기고, + * 실제 미션 카드와 하단 정보는 패널 안쪽으로 더 들어가 보이도록 간격을 분리한다. + */} {missionCards.map(card => ( Date: Fri, 13 Mar 2026 01:29:26 +0900 Subject: [PATCH 13/92] =?UTF-8?q?fix:=20=ED=99=88=20=EC=95=A1=EC=85=98=20?= =?UTF-8?q?=EC=95=84=EC=9D=B4=EC=BD=98=20=EC=A4=91=EC=95=99=20=EC=A0=95?= =?UTF-8?q?=EB=A0=AC=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/home/HomeGardenScene.tsx | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/components/home/HomeGardenScene.tsx b/src/components/home/HomeGardenScene.tsx index 60d8aff..9edeee4 100644 --- a/src/components/home/HomeGardenScene.tsx +++ b/src/components/home/HomeGardenScene.tsx @@ -162,7 +162,9 @@ export default function HomeGardenScene({ style={styles.actionButton} disabled={sunlightMutation.isPending} > - + + + - + + + ) : null} @@ -272,6 +276,12 @@ const styles = StyleSheet.create({ alignItems: "center", justifyContent: "center", }, + actionIconWrap: { + width: 64, + height: 64, + alignItems: "center", + justifyContent: "center", + }, lockedOverlay: { flex: 1, marginHorizontal: 24, From 59cea52846a1c45929250b1faaae9197f4044fea Mon Sep 17 00:00:00 2001 From: lejuho Date: Fri, 13 Mar 2026 01:34:29 +0900 Subject: [PATCH 14/92] =?UTF-8?q?refactor:=20=ED=99=88=20=ED=99=94?= =?UTF-8?q?=EB=B6=84=EA=B3=BC=20=EC=A3=BC=EB=B3=80=20=EC=98=A4=EB=B8=8C?= =?UTF-8?q?=EC=A0=9D=ED=8A=B8=20=ED=95=98=EB=8B=A8=20=EB=B0=B0=EC=B9=98=20?= =?UTF-8?q?=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/home/HomeAvatarStage.tsx | 24 +++++++++++++++--------- src/components/home/HomeGardenScene.tsx | 12 +++++++++--- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/components/home/HomeAvatarStage.tsx b/src/components/home/HomeAvatarStage.tsx index 90c3e65..d638b8c 100644 --- a/src/components/home/HomeAvatarStage.tsx +++ b/src/components/home/HomeAvatarStage.tsx @@ -99,21 +99,27 @@ const styles = StyleSheet.create({ }, avatarCluster: { width: "100%", - minHeight: 390, + minHeight: 400, alignItems: "center", justifyContent: "center", position: "relative", - paddingBottom: 36, + paddingBottom: 18, }, avatarImage: { width: 320, height: 320, - marginBottom: 34, + + /* + * 한글 주석: + * 화분 밑단을 더 아래로 내리기 위해 하단 여백을 줄였다. + * 주변 오브젝트도 같은 기준선에서 함께 내려오도록 절대 위치 값도 맞춘다. + */ + marginBottom: 8, }, wateringImage: { position: "absolute", left: "36%", - bottom: 160, + bottom: 132, width: 118, height: 118, }, @@ -122,8 +128,8 @@ const styles = StyleSheet.create({ }, leftCompanion: { position: "absolute", - left: 22, - bottom: 18, + left: 26, + bottom: 4, alignItems: "center", width: 154, }, @@ -179,7 +185,7 @@ const styles = StyleSheet.create({ fontWeight: "700", }, mascotButton: { - marginTop: -4, + marginTop: -10, }, characterImage: { width: 82, @@ -187,8 +193,8 @@ const styles = StyleSheet.create({ }, birdButton: { position: "absolute", - right: 42, - bottom: 42, + right: 48, + bottom: 18, }, birdImage: { width: 84, diff --git a/src/components/home/HomeGardenScene.tsx b/src/components/home/HomeGardenScene.tsx index 9edeee4..4e26a22 100644 --- a/src/components/home/HomeGardenScene.tsx +++ b/src/components/home/HomeGardenScene.tsx @@ -25,8 +25,8 @@ const mapIcon = require("@/assets/images/map.png"); const emptyGardenImage = require("@/assets/images/null.webp"); const sunlightOverlay = require("@/assets/images/background/sunlight.png"); -const SCENE_BOTTOM_OFFSET = 110; -const ACTION_RAIL_BOTTOM_OFFSET = 180; +const SCENE_BOTTOM_OFFSET = 64; +const ACTION_RAIL_BOTTOM_OFFSET = 128; type Props = { background: any; @@ -261,11 +261,17 @@ const styles = StyleSheet.create({ justifyContent: "center", alignItems: "center", paddingHorizontal: 24, + + /* + * 한글 주석: + * 화분과 주변 오브젝트를 화면 하단 쪽으로 더 내리되, + * 접힌 패널에 가려지지 않도록 최소 여백을 남긴 위치로 고정한다. + */ paddingBottom: SCENE_BOTTOM_OFFSET, }, actionRail: { position: "absolute", - right: 10, + right: 12, bottom: ACTION_RAIL_BOTTOM_OFFSET, zIndex: 3, gap: 8, From a4b14e5d715a9d12009c94dbe25655265144dc5d Mon Sep 17 00:00:00 2001 From: lejuho Date: Fri, 13 Mar 2026 01:38:02 +0900 Subject: [PATCH 15/92] =?UTF-8?q?chore:=20=ED=99=88=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=EA=B7=B8=EB=A0=88=EC=9D=B4=EC=85=98=20=EB=AC=B8=EC=84=9C=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=20=EB=8F=99=EA=B8=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HOME_MIGRATION_CHECKLIST.md | 2 +- MAINAPP_MIGRATION_TODO.md | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/HOME_MIGRATION_CHECKLIST.md b/HOME_MIGRATION_CHECKLIST.md index bff049d..2ca3937 100644 --- a/HOME_MIGRATION_CHECKLIST.md +++ b/HOME_MIGRATION_CHECKLIST.md @@ -54,4 +54,4 @@ - [ ] 실기기/에뮬레이터에서 홈 스와이프 확인 - [ ] 안전영역/작은 화면 레이아웃 확인 - [ ] Android 이미지 로딩/기본 이미지 fallback 확인 -- [ ] 남은 TODO를 `MAINAPP_MIGRATION_TODO.md`와 동기화 +- [x] 남은 TODO를 `MAINAPP_MIGRATION_TODO.md`와 동기화 diff --git a/MAINAPP_MIGRATION_TODO.md b/MAINAPP_MIGRATION_TODO.md index ab74858..29908a8 100644 --- a/MAINAPP_MIGRATION_TODO.md +++ b/MAINAPP_MIGRATION_TODO.md @@ -20,7 +20,7 @@ - 인증 기반은 완료 상태다. - 앱 시작 시 저장된 토큰 기준으로 `Main` 또는 `Onboarding`으로 초기 진입이 분기된다. - 서비스 API 인증 헤더 자동 부착과 refresh 재시도 기반이 있다. -- 실제 사용자 기능 중 현재 의미 있게 연결된 영역은 `홈 요약 일부`, `피드`, `피드 상세`, `댓글 작성`, `로그 캘린더`, `월별 일기 목록`, `로그 상세`, `프로필`, `팔로우 목록`, `배송 신청`, `정원 해금`, `등록 플로우`, `데일리 미션(일기/퀴즈/오늘의 질문)`이다. +- 실제 사용자 기능 중 현재 의미 있게 연결된 영역은 `홈`, `피드`, `피드 상세`, `댓글 작성`, `로그 캘린더`, `월별 일기 목록`, `로그 상세`, `프로필`, `팔로우 목록`, `배송 신청`, `정원 해금`, `등록 플로우`, `데일리 미션(일기/퀴즈/오늘의 질문)`이다. - `설정`은 로그아웃과 계정 상태 확인이 가능한 최소 운영 수준으로 정리되었다. ### 네비게이션 기준 상태 @@ -42,7 +42,7 @@ - 오늘의 질문 미션 - 부분구현 - 비회원 등록 - - 홈 메인 + - 홈 메인 마감 - 로그 화면 일부 - 피드 상세 UX - 프로필 @@ -80,7 +80,7 @@ | 기능명 | 현재 MainAPP 상태 | 보완 필요 사항 | 근거 파일 | |---|---|---|---| | 비회원 등록 | 닉네임 입력과 회원가입 API 호출은 있음 | 가입 실패 시에도 등록 플로우로 진입시키는 현재 정책이 운영 기준으로 확정된 것은 아님 | `src/pages/register/RegisterScreen.tsx`, `src/hooks/register/useRegister.ts`, `src/apis/register/registerApi.ts` | -| 홈 메인 | 홈 summary API가 있으면 사용자/정원/미션 요약을 렌더링하고, missionType 기준으로 라우팅함 | `home/panel` 세부 API, 식물 상호작용은 아직 필요 | `src/pages/home/HomeScreen.tsx`, `src/hooks/home/useHomeApi.ts`, `src/apis/home/homeApi.ts` | +| 홈 메인 | 홈 summary API, `panel` API, 물/햇빛 액션, 감정 체크 모달, 미션 시트, 잠금/빈 슬롯 분기와 missionType 라우팅이 연결됨 | 실기기 스와이프 검증, 안전영역 점검, 문구/간격 같은 UI 마감과 물/햇빛 API 계약 상세 확인이 남아 있음 | `src/pages/home/HomeScreen.tsx`, `src/hooks/home/useHomeApi.ts`, `src/apis/home/homeApi.ts`, `src/components/home/*`, `src/stores/useEmotionSurveyStore.ts` | | 로그 화면 일부 | 캘린더/일기 목록과 로그 상세까지 연결됨 | 미션 탭 날짜 선택 후 상세 액션은 아직 없음 | `src/pages/log/LogScreen.tsx`, `src/pages/log/LogDetailScreen.tsx`, `src/apis/log/diaryDetailApi.ts` | | 피드 상세 UX | 조회/댓글/상태 처리와 프로필 이동은 됨 | 공감/신고/댓글 수정·삭제는 아직 없음 | `src/components/feed/FeedDetail.tsx`, `src/pages/feed/FeedDiaryScreen.tsx`, `src/pages/feed/FeedAvatarScreen.tsx` | | 프로필 | 사용자 조회와 대표 정원/팔로우/물주기까지 연결됨 | 방명록, 다중 정원 상세, 추가 상호작용 API는 아직 필요 | `src/pages/profile/ProfileScreen.tsx`, `src/components/profile/ProfileDetail.tsx`, `src/apis/profile/profileApi.ts` | @@ -112,8 +112,8 @@ | 기능명 | 현재 MainAPP 상태 | 참조할 MainFE 파일 | 필요한 MainAPP 대상 파일 또는 신규 파일 | 선행조건 | |---|---|---|---|---| -| 홈 메인 패널 | `/api/v1/home` 응답 기준 요약 UI는 구현됨. `missionType` 기반 라우팅과 today question 연결까지 반영됨 | `C:/MainFE/src/pages/home/Homepage.tsx`, `C:/MainFE/src/apis/home/homeApi.ts`, `C:/MainFE/src/apis/missions/panelApi.ts` | 기존 `src/pages/home/HomeScreen.tsx`, 기존 `src/apis/home/homeApi.ts`, 기존 `src/hooks/home/useHomeApi.ts`, 필요 시 신규 `src/components/home/*` | `panel` 및 상호작용 API 존재 확인 | -| 식물 상호작용(물/햇빛) | 미구현 | `C:/MainFE/src/components/home/FirstPlant.tsx`, `C:/MainFE/src/components/home/SecondPlant.tsx`, `C:/MainFE/src/components/home/ThirdPlant.tsx`, `C:/MainFE/src/components/home/FourthPlant.tsx` | 신규 `src/components/home/*`, 기존 `src/pages/home/HomeScreen.tsx` | 홈 메인 데이터 구조 확정 | +| 홈 메인 패널 | `/api/v1/home`와 `panel` 응답 기준 요약 UI, 접힘/펼침 미션 시트, 오늘의 질문 연결까지 구현됨 | `C:/MainFE/src/pages/home/Homepage.tsx`, `C:/MainFE/src/apis/home/homeApi.ts`, `C:/MainFE/src/apis/missions/panelApi.ts` | 기존 `src/pages/home/HomeScreen.tsx`, 기존 `src/apis/home/homeApi.ts`, 기존 `src/hooks/home/useHomeApi.ts`, `src/components/home/*` | 실기기 스와이프와 UI 마감 확인 | +| 식물 상호작용(물/햇빛) | owner 기준 물/햇빛 액션, 버튼 상태, 토스트, 홈 배치까지 구현됨 | `C:/MainFE/src/components/home/FirstPlant.tsx`, `C:/MainFE/src/components/home/SecondPlant.tsx`, `C:/MainFE/src/components/home/ThirdPlant.tsx`, `C:/MainFE/src/components/home/FourthPlant.tsx` | 기존 `src/components/home/HomeGardenScene.tsx`, 기존 `src/hooks/home/useHomeApi.ts`, 기존 `src/pages/home/HomeScreen.tsx` | 액션 API 계약 상세와 실기기 동작 확인 | | 로그 상세 | diary detail API 기준 실제 화면 구현 완료. 수정 기능과 추가 소셜 액션만 미완성 | `C:/MainFE/src/pages/log/LogDetailPage.tsx` | 기존 `src/pages/log/LogDetailScreen.tsx`, 기존 `src/components/log/MyDiaryDetail.tsx` | 수정 API 여부 확인 | | 피드 상세 보완 | 상세 조회, 댓글, 상태 처리는 구현됨. 소셜 상호작용은 미완성 | `C:/MainFE/src/pages/feed/FeedDiaryPage.tsx`, `C:/MainFE/src/pages/feed/FeedAvatarPage.tsx`, `C:/MainFE/src/components/feed/*`, `C:/MainFE/src/components/common/Comment.tsx` | 기존 `src/pages/feed/FeedDiaryScreen.tsx`, 기존 `src/pages/feed/FeedAvatarScreen.tsx`, 기존 `src/components/feed/FeedDetail.tsx`, 기존 `src/components/common/Comment.tsx` | 프로필 화면, 댓글/좋아요 API 범위 확인 | | 프로필 조회/친구 물주기 | 사용자 조회, 대표 정원 렌더링, 친구 물주기, follow/unfollow까지 구현됨. 방명록 등 추가 기능은 미완성 | `C:/MainFE/src/pages/profile/ProfilePage.tsx`, `C:/MainFE/src/apis/profile/profileApi.ts`, `C:/MainFE/src/components/profile/*` | 기존 `src/pages/profile/ProfileScreen.tsx`, 기존 `src/apis/profile/profileApi.ts`, 기존 `src/hooks/profile/*`, 기존 `src/components/profile/*` | 방명록 및 추가 상호작용 API 확인 | @@ -249,7 +249,7 @@ ## 6. 이후 Codex 작업 순서 ### Step 3. 홈/로그/피드 공백 메우기 -- `src/pages/home/HomeScreen.tsx` 요약 UI 이후, `panel`과 정원 상호작용 API가 확인되면 홈 상호작용을 확장한다. +- `src/pages/home/HomeScreen.tsx` 기준 홈 상호작용 기본 연결은 끝났고, 남은 작업은 실기기 스와이프 확인, 안전영역/작은 화면 점검, 문구/간격 마감, 물/햇빛 API 계약 상세 확인이다. - `src/pages/log/LogDetailScreen.tsx` 이후, 수정 기능과 미션 탭 상세 연결을 보완한다. - 피드 상세의 좋아요/신고/프로필 실화면 연결 등 미완성 소셜 상호작용을 정리한다. - 필요한 홈/피드 보조 API와 훅을 추가한다. @@ -278,13 +278,13 @@ ### 완료된 범위 - 인증, 온보딩, 로그인, 재실행 세션 복원, 로그아웃 -- 홈 주요 진입점, 피드/로그 상세, 프로필/팔로우 +- 홈 주요 진입점, `panel` 기반 미션 시트, 감정 체크, 물/햇빛 액션, 피드/로그 상세, 프로필/팔로우 - 정원 해금, 배송 신청/완료 - 등록 플로우 기본 구조와 생성형 업로드 - 데일리 미션 진입, 퀴즈 응답, 오늘의 질문 응답 ### 부분구현 범위 -- 홈 패널 세부 상호작용 +- 홈 UI 마감과 실기기 검증 - 피드 소셜 액션(좋아요/신고/댓글 수정 삭제) - 프로필 방명록/다중 정원 - 배송 주소 검색과 배송 조회 @@ -298,7 +298,7 @@ - 오늘의 질문 완료 후 보상/안내 문구를 앱에서 어느 수준까지 노출할지 여부 ### 백엔드 계약 확인 필요 범위 -- 홈 패널/식물 상호작용 세부 API +- 물/햇빛 액션 API 계약 상세 - 팔로워 목록의 follow-back 판단용 관계 상태 - 배송 상태 조회와 주소 검색 대체 정책 - 데일리 미션 일기 작성의 최종 저장 UX 정책 @@ -312,7 +312,7 @@ - 데일리 미션 일기 작성은 이미지 업로드-일기 저장 최종 연결이 아직 완결되지 않았다. - 비회원 등록 실패 시에도 등록 플로우로 진입시키는 현재 동작은 운영 정책 확정이 필요하다. -- 홈 패널/식물 상호작용 API가 없어 메인 홈 상호작용은 아직 제한적이다. +- 홈 화면은 기본 상호작용이 구현됐지만, 물/햇빛 API 계약 상세와 실기기 레이아웃 검증 전까지는 운영 리스크가 남아 있다. - 배송 주소 검색과 배송 상태 조회는 아직 앱에서 직접 지원하지 않는다. - MainFE 종료 이후 기준 문서는 이 파일과 현재 `MainAPP` 코드이며, 남은 보완은 정책/운영 확정 후 `MainAPP`에서 계속 갱신한다. From e86367dfa16ffd30c98e4c0e1833a5f9295cf59e Mon Sep 17 00:00:00 2001 From: lejuho Date: Fri, 13 Mar 2026 01:42:24 +0900 Subject: [PATCH 16/92] =?UTF-8?q?refactor:=20=ED=99=88=20=EB=B0=94?= =?UTF-8?q?=ED=85=80=EC=8B=9C=ED=8A=B8=20=EC=97=B4=EB=A6=BC=20=EB=8B=AB?= =?UTF-8?q?=ED=9E=98=20=EC=9D=B8=ED=84=B0=EB=9E=99=EC=85=98=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/home/HomeBottomSheet.tsx | 32 ++++++++++++++++++++----- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/components/home/HomeBottomSheet.tsx b/src/components/home/HomeBottomSheet.tsx index 16c0550..7d1a073 100644 --- a/src/components/home/HomeBottomSheet.tsx +++ b/src/components/home/HomeBottomSheet.tsx @@ -2,6 +2,7 @@ import { useEffect, useRef } from "react"; import { Animated, PanResponder, + Pressable, StyleSheet, Text, TouchableOpacity, @@ -65,13 +66,22 @@ export default function HomeBottomSheet({ onPanResponderRelease: (_, gestureState) => { const movedUpEnough = gestureState.dy < -40; const movedDownEnough = gestureState.dy > 40; - const nextExpanded = movedUpEnough ? true : movedDownEnough ? false : !expanded ? false : true; + const flingUp = gestureState.vy < -0.45; + const flingDown = gestureState.vy > 0.45; + const nextExpanded = + movedUpEnough || flingUp + ? true + : movedDownEnough || flingDown + ? false + : expanded; + if (!movedUpEnough && !movedDownEnough) { translateY.stopAnimation(value => { - onExpandedChange(value < DRAG_RANGE / 2); + onExpandedChange(flingUp ? true : flingDown ? false : value < DRAG_RANGE / 2); }); return; } + onExpandedChange(nextExpanded); }, onPanResponderTerminate: () => { @@ -115,13 +125,19 @@ export default function HomeBottomSheet({ return ( + {expanded ? onExpandedChange(false)} /> : null} + - - + onExpandedChange(!expanded)} + style={styles.sheetDragArea} + > + - + 오늘의 미션 {missionCards.map(card => ( @@ -129,7 +145,7 @@ export default function HomeBottomSheet({ ))} - + {/* @@ -210,6 +226,10 @@ const styles = StyleSheet.create({ ...StyleSheet.absoluteFillObject, justifyContent: "flex-end", }, + sheetBackdrop: { + ...StyleSheet.absoluteFillObject, + backgroundColor: "rgba(12, 18, 14, 0.10)", + }, quickLink: { flex: 1, borderRadius: 14, From 543bfbd9ab82e86f62b15d34604ac90ea6411714 Mon Sep 17 00:00:00 2001 From: lejuho Date: Fri, 13 Mar 2026 01:55:34 +0900 Subject: [PATCH 17/92] =?UTF-8?q?refactor:=20=ED=99=88=20=EC=9E=A0?= =?UTF-8?q?=EA=B8=88=20=ED=85=83=EB=B0=AD=20=EC=A0=84=EC=9A=A9=20=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=95=84=EC=9B=83=EA=B3=BC=20=ED=8C=A8=EB=84=90=20?= =?UTF-8?q?=EC=A1=B0=EA=B1=B4=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/home/HomeGardenScene.tsx | 82 ++++++++++++++++--------- src/pages/home/HomeScreen.tsx | 68 ++++++++++++-------- 2 files changed, 96 insertions(+), 54 deletions(-) diff --git a/src/components/home/HomeGardenScene.tsx b/src/components/home/HomeGardenScene.tsx index 4e26a22..32c9793 100644 --- a/src/components/home/HomeGardenScene.tsx +++ b/src/components/home/HomeGardenScene.tsx @@ -116,12 +116,15 @@ export default function HomeGardenScene({ return ( + {isLocked ? : null} + + {isLocked ? : null} @@ -133,22 +136,29 @@ export default function HomeGardenScene({ {isLocked ? ( - - - {isUnlockable ? "지금 열 수 있어요!" : "아직 해금되지 않았습니다!"} - - - {isUnlockable - ? "아래 버튼을 눌러 씨앗을 배송받고,\n새로운 곳에서 식물을 키워보세요." - : "소망 나무가 충분히 자라면\n새로운 식물을 키울 수 있어요."} - + + + + 해금되지 않았습니다 + + + {isUnlockable + ? "지금은 씨앗을 받아 새로운 텃밭을 열 수 있어요." + : "소망 나무가 충분히 자라면 새로운 텃밭을 열 수 있어요."} + + + - - {isUnlockable ? "씨앗 받고 해금하기!" : "충분하지 않아요"} + + {isUnlockable ? "씨앗 받고 해금하기" : "아직 감자가 충분히 모이지 않았어요"} @@ -210,6 +220,9 @@ const styles = StyleSheet.create({ sceneBackground: { flex: 1, }, + lockedBackgroundBlur: { + ...StyleSheet.absoluteFillObject, + }, sunlightOverlay: { ...StyleSheet.absoluteFillObject, opacity: 1, @@ -221,6 +234,10 @@ const styles = StyleSheet.create({ ...StyleSheet.absoluteFillObject, backgroundColor: "rgba(8, 20, 10, 0.08)", }, + lockedScreenFog: { + ...StyleSheet.absoluteFillObject, + backgroundColor: "rgba(242, 246, 241, 0.58)", + }, sceneContent: { flex: 1, justifyContent: "space-between", @@ -231,6 +248,7 @@ const styles = StyleSheet.create({ justifyContent: "space-between", paddingHorizontal: 16, paddingTop: 56, + zIndex: 2, }, mapButton: { width: 48, @@ -269,6 +287,13 @@ const styles = StyleSheet.create({ */ paddingBottom: SCENE_BOTTOM_OFFSET, }, + lockedSceneBody: { + flex: 1, + justifyContent: "space-between", + paddingHorizontal: 20, + paddingBottom: 28, + zIndex: 2, + }, actionRail: { position: "absolute", right: 12, @@ -290,10 +315,6 @@ const styles = StyleSheet.create({ }, lockedOverlay: { flex: 1, - marginHorizontal: 24, - marginBottom: SCENE_BOTTOM_OFFSET, - borderRadius: 28, - backgroundColor: "rgba(255,255,255,0.68)", justifyContent: "center", alignItems: "center", paddingHorizontal: 28, @@ -314,20 +335,25 @@ const styles = StyleSheet.create({ color: "#171717", textAlign: "center", }, - unlockButton: { - marginTop: 6, - borderRadius: 14, - backgroundColor: "#7DC960", - paddingHorizontal: 18, - paddingVertical: 12, + lockedFooterButton: { + width: "100%", + minHeight: 58, + borderRadius: 18, + alignItems: "center", + justifyContent: "center", + paddingHorizontal: 20, }, - unlockButtonDisabled: { - backgroundColor: "#9CA3AF", + lockedFooterButtonActive: { + backgroundColor: "#59A647", }, - unlockButtonText: { - fontSize: 15, + lockedFooterButtonDisabled: { + backgroundColor: "#BFC6BC", + }, + lockedFooterButtonText: { + fontSize: 16, fontWeight: "700", color: "#FFFFFF", + textAlign: "center", }, emptySlotWrap: { width: "100%", diff --git a/src/pages/home/HomeScreen.tsx b/src/pages/home/HomeScreen.tsx index fbf3671..38e3c16 100644 --- a/src/pages/home/HomeScreen.tsx +++ b/src/pages/home/HomeScreen.tsx @@ -14,6 +14,7 @@ import type { MainTabScreenProps } from "@/navigation/types"; import { useEmotionSurveyStore, getEmotionSurveyCooldownActive } from "@/stores/useEmotionSurveyStore"; import { useHomeSummaryStore } from "@/stores/useHomeSummaryStore"; import { + getGardenLocked, type GardenSummary, type HomeMissionType, type TodayMission, @@ -87,15 +88,6 @@ export default function HomeScreen({ navigation }: Props) { const todayMissions = data?.todayMissions ?? missions; const isEmotionCooldownActive = getEmotionSurveyCooldownActive(lastAnsweredAt); - /* - * 한글 주석: - * 홈 말풍선은 서버 응답과 별개로, 홈에서 방금 답한 직후 상태도 바로 반영해야 한다. - * 로컬 24시간 완료 상태를 함께 보아야 버튼이 다시 나타나는 깜빡임을 막을 수 있다. - */ - const isEmotionAnswered = (surveyQuery.data?.isAnswered ?? false) || isEmotionCooldownActive; - const answeredKind = emotionAnswerKind ?? lastAnswerKind; - const initialPage = Math.max(0, Math.min(3, (userInfo?.lastAccessedSlotNumber ?? 1) - 1)); - const scenes = useMemo( () => backgrounds.map((background, index) => ({ @@ -108,6 +100,28 @@ export default function HomeScreen({ navigation }: Props) { [gardenSummaries] ); + const currentScene = scenes[currentPage] ?? scenes[0] ?? null; + const isCurrentGardenLocked = currentScene?.garden ? getGardenLocked(currentScene.garden) : false; + + useEffect(() => { + if (isCurrentGardenLocked && isSheetExpanded) { + setIsSheetExpanded(false); + } + }, [isCurrentGardenLocked, isSheetExpanded]); + + /* + * 한글 주석: + * 홈 말풍선은 서버 응답과 별개로, 홈에서 방금 답한 직후 상태도 바로 반영해야 한다. + * 로컬 24시간 완료 상태를 함께 보아야 버튼이 다시 나타나는 깜빡임을 막을 수 있다. + */ + const isEmotionAnswered = (surveyQuery.data?.isAnswered ?? false) || isEmotionCooldownActive; + const answeredKind = emotionAnswerKind ?? lastAnswerKind; + const initialPage = Math.max(0, Math.min(3, (userInfo?.lastAccessedSlotNumber ?? 1) - 1)); + + useEffect(() => { + setCurrentPage(initialPage); + }, [initialPage]); + if (isLoading && gardenSummaries.length === 0) { return ( @@ -171,23 +185,25 @@ export default function HomeScreen({ navigation }: Props) { - navigation.navigate("Log")} - onPressFeed={() => navigation.navigate("Feed")} - onPressUnlockGarden={() => navigation.navigate("UnlockGarden")} - onPressMission={mission => { - const routeName = getMissionRouteName(mission); - if (routeName) { - navigation.navigate(routeName); - } - }} - onPressEmotionCheck={() => setIsEmotionModalOpen(true)} - /> + {!isCurrentGardenLocked ? ( + navigation.navigate("Log")} + onPressFeed={() => navigation.navigate("Feed")} + onPressUnlockGarden={() => navigation.navigate("UnlockGarden")} + onPressMission={mission => { + const routeName = getMissionRouteName(mission); + if (routeName) { + navigation.navigate(routeName); + } + }} + onPressEmotionCheck={() => setIsEmotionModalOpen(true)} + /> + ) : null} Date: Fri, 13 Mar 2026 02:02:41 +0900 Subject: [PATCH 18/92] =?UTF-8?q?feat:=20=EC=9D=BC=EA=B8=B0=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=97=85=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=EC=99=80=20=EC=A0=9C=EC=B6=9C=20=ED=9D=90=EB=A6=84=20?= =?UTF-8?q?=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dailyMission/ImageAttachmentCard.tsx | 55 ++++-- .../DailyMissionWriteDiaryScreen.tsx | 172 ++++++++++++------ 2 files changed, 158 insertions(+), 69 deletions(-) diff --git a/src/components/dailyMission/ImageAttachmentCard.tsx b/src/components/dailyMission/ImageAttachmentCard.tsx index f564bc3..aeecd3a 100644 --- a/src/components/dailyMission/ImageAttachmentCard.tsx +++ b/src/components/dailyMission/ImageAttachmentCard.tsx @@ -1,4 +1,4 @@ -import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import { Image, StyleSheet, Text, TouchableOpacity, View } from "react-native"; type Props = { imageUrl?: string | null; @@ -22,14 +22,21 @@ export default function ImageAttachmentCard({ disabled={disabled} onPress={onPress} > - - {imageUrl ? "업로드된 이미지가 있습니다." : "이미지를 선택하거나 업로드하세요"} - - - {imageUrl - ? imageUrl - : "현재 프로젝트에는 RN 이미지 선택 라이브러리가 없어 업로드 인터페이스만 먼저 정리했습니다."} - + {imageUrl ? ( + + ) : ( + + + + + )} + + {imageUrl ? "선택한 이미지" : "이미지를 선택해주세요"} + + {imageUrl + ? "다시 누르면 다른 이미지로 바꿀 수 있습니다." + : "사진첩에서 일기에 첨부할 이미지를 고를 수 있습니다."} + + {helperText ? {helperText} : null} @@ -46,16 +53,42 @@ const styles = StyleSheet.create({ color: "#374151", }, card: { - borderRadius: 16, + borderRadius: 20, borderWidth: 1, borderColor: "#D1D5DB", padding: 16, - gap: 6, + gap: 14, backgroundColor: "#FFFFFF", }, cardDisabled: { backgroundColor: "#F9FAFB", }, + previewImage: { + width: "100%", + height: 180, + borderRadius: 16, + backgroundColor: "#E5E7EB", + }, + placeholderBox: { + width: "100%", + height: 180, + borderRadius: 16, + borderWidth: 1, + borderStyle: "dashed", + borderColor: "#D1D5DB", + backgroundColor: "#F9FAFB", + alignItems: "center", + justifyContent: "center", + }, + placeholderPlus: { + fontSize: 34, + lineHeight: 36, + color: "#9CA3AF", + fontWeight: "400", + }, + textBlock: { + gap: 6, + }, title: { fontSize: 15, fontWeight: "700", diff --git a/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx b/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx index 6a48f30..23d374b 100644 --- a/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx +++ b/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx @@ -1,50 +1,134 @@ import { useState } from "react"; -import { ScrollView, StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import * as ImagePicker from "expo-image-picker"; +import { + Alert, + ScrollView, + StyleSheet, + Text, + TouchableOpacity, + View, +} from "react-native"; +import { useQueryClient } from "@tanstack/react-query"; import { SafeAreaView } from "react-native-safe-area-context"; import ScreenHeader from "@/components/common/ScreenHeader"; -import StatusView from "@/components/common/StatusView"; import ImageAttachmentCard from "@/components/dailyMission/ImageAttachmentCard"; import RegistrationFooter from "@/components/registration/RegistrationFooter"; import RegistrationTextField from "@/components/registration/RegistrationTextField"; -import { useWriteDiarySubmit } from "@/hooks/mission/useMissionApi"; +import { + useWriteDiaryImageUpload, + useWriteDiarySubmit, +} from "@/hooks/mission/useMissionApi"; import type { RootStackScreenProps } from "@/navigation/types"; type Props = RootStackScreenProps<"DailyMissionWriteDiary">; export default function DailyMissionWriteDiaryScreen({ navigation }: Props) { + const queryClient = useQueryClient(); const [title, setTitle] = useState(""); const [content, setContent] = useState(""); const [isPublic, setIsPublic] = useState(false); - const [imageNoticeVisible, setImageNoticeVisible] = useState(false); + const [permissionRequested, setPermissionRequested] = useState(false); + const [selectedImageUri, setSelectedImageUri] = useState(null); + const [uploadedImage, setUploadedImage] = useState<{ + imageId: number; + imageUrl: string; + } | null>(null); + const uploadDiaryImage = useWriteDiaryImageUpload(); const submitDiary = useWriteDiarySubmit(); + const goHome = () => + navigation.reset({ + index: 0, + routes: [{ name: "Main", params: { screen: "Home" } }], + }); + + const handlePickImage = async () => { + if (!permissionRequested) { + const permission = await ImagePicker.requestMediaLibraryPermissionsAsync(); + setPermissionRequested(true); + + if (!permission.granted) { + Alert.alert("권한 필요", "일기 이미지를 선택하려면 사진 접근 권한이 필요합니다."); + return; + } + } + + const result = await ImagePicker.launchImageLibraryAsync({ + mediaTypes: ["images"], + allowsEditing: true, + quality: 0.9, + }); + + if (result.canceled || !result.assets[0]) { + return; + } + + const asset = result.assets[0]; + const fileName = asset.fileName ?? `diary-${Date.now()}.jpg`; + const fileType = asset.mimeType ?? "image/jpeg"; + const formData = new FormData(); + + formData.append("file", { + uri: asset.uri, + name: fileName, + type: fileType, + } as never); + + setSelectedImageUri(asset.uri); + setUploadedImage(null); + + try { + const response = await uploadDiaryImage.mutateAsync(formData); + setUploadedImage(response.result); + } catch (error) { + const message = error instanceof Error ? error.message : "이미지 업로드에 실패했습니다."; + Alert.alert("업로드 실패", message); + } + }; + const handleSubmit = async () => { if (!title.trim() || !content.trim()) { return; } - // Image picker dependency is not available in the current app. - // Keep the API interface wired but block the actual submit until an image upload path exists. - setImageNoticeVisible(true); + if (!uploadedImage) { + Alert.alert("이미지 필요", "먼저 이미지를 업로드해주세요."); + return; + } + + try { + await submitDiary.mutateAsync({ + title: title.trim(), + content: content.trim(), + isPublic, + imageId: uploadedImage.imageId, + imageUrl: uploadedImage.imageUrl, + }); + + /* + * 한글 주석: + * 일기 작성 완료 후 홈과 로그에서 최신 상태를 바로 보이게 하려면 + * 관련 쿼리를 함께 갱신하고 홈으로 복귀시키는 흐름이 필요하다. + */ + await queryClient.invalidateQueries({ queryKey: ["home-summary"] }); + await queryClient.invalidateQueries({ queryKey: ["calendar"] }); + await queryClient.invalidateQueries({ queryKey: ["diaries"] }); + goHome(); + } catch (error) { + const message = error instanceof Error ? error.message : "일기 저장에 실패했습니다."; + Alert.alert("일기 저장 실패", message); + } }; return ( - - navigation.reset({ - index: 0, - routes: [{ name: "Main", params: { screen: "Home" } }], - }) - } - /> + 오늘의 식물 이야기를 적어주세요. - 텍스트 입력과 공개 여부 구조는 구현했고, 이미지 선택은 라이브러리 확정 후 연결합니다. + 제목과 내용을 적고 이미지를 첨부한 뒤 공개 여부를 선택해 제출할 수 있습니다. @@ -63,8 +147,15 @@ export default function DailyMissionWriteDiaryScreen({ navigation }: Props) { /> setImageNoticeVisible(true)} - helperText="`POST /api/v1/diaries/images` 인터페이스는 추가했지만, 현재 프로젝트에는 이미지 선택 라이브러리가 없습니다." + imageUrl={selectedImageUri} + onPress={() => void handlePickImage()} + helperText={ + uploadDiaryImage.isPending + ? "이미지를 업로드하는 중입니다. 잠시만 기다려주세요." + : uploadedImage + ? "이미지 업로드가 완료되었습니다." + : undefined + } /> @@ -104,35 +195,16 @@ export default function DailyMissionWriteDiaryScreen({ navigation }: Props) { - - {imageNoticeVisible ? ( - - ) : null} - - {submitDiary.isError ? ( - - 일기 저장에 실패했습니다. - - 현재는 이미지 업로드 경로가 없어 실제 제출까지 이어지지 않습니다. - - - ) : null} - navigation.reset({ - index: 0, - routes: [{ name: "Main", params: { screen: "Home" } }], - }) - } + onSecondaryPress={goHome} primaryLabel="제출하기" onPrimaryPress={() => void handleSubmit()} - primaryDisabled={!title.trim() || !content.trim() || submitDiary.isPending} + primaryDisabled={ + !title.trim() || !content.trim() || !uploadedImage || uploadDiaryImage.isPending || submitDiary.isPending + } primaryLoading={submitDiary.isPending} /> @@ -199,20 +271,4 @@ const styles = StyleSheet.create({ visibilityButtonTextActive: { color: "#1F5C27", }, - errorCard: { - borderRadius: 16, - padding: 16, - backgroundColor: "#FEF2F2", - gap: 6, - }, - errorTitle: { - fontSize: 16, - fontWeight: "700", - color: "#B91C1C", - }, - errorDescription: { - fontSize: 14, - lineHeight: 20, - color: "#7F1D1D", - }, }); From b3cc5e8b2eacd856f71378655f8bdc11669036a4 Mon Sep 17 00:00:00 2001 From: lejuho Date: Fri, 13 Mar 2026 14:37:27 +0900 Subject: [PATCH 19/92] =?UTF-8?q?fix:=20=ED=99=88=20=EB=AF=B8=EC=85=98=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=20=EA=B0=B1=EC=8B=A0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/mission/useMissionApi.ts | 26 +++++++++++++++++-- .../DailyMissionCheckingScreen.tsx | 2 ++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/hooks/mission/useMissionApi.ts b/src/hooks/mission/useMissionApi.ts index a57a525..603e97d 100644 --- a/src/hooks/mission/useMissionApi.ts +++ b/src/hooks/mission/useMissionApi.ts @@ -39,10 +39,24 @@ export const useMissionQuiz = (params: GetQuizRequest) => select: data => data.result, }); -export const useAnswerQuiz = () => - useMutation({ +export const useAnswerQuiz = () => { + const queryClient = useQueryClient(); + + return useMutation({ mutationFn: payload => answerQuizApi(payload), + onSuccess: async () => { + /* + * 한글 주석: + * 퀴즈 완료 직후 홈 미션 패널과 홈 요약을 함께 갱신해야 + * 사용자가 홈으로 돌아왔을 때 완료 상태가 즉시 반영된다. + */ + await queryClient.invalidateQueries({ queryKey: ["home-summary"] }); + await queryClient.invalidateQueries({ queryKey: ["home-panel"] }); + await queryClient.refetchQueries({ queryKey: ["home-summary"], type: "all" }); + await queryClient.refetchQueries({ queryKey: ["home-panel"], type: "all" }); + }, }); +}; export const useDailySurvey = () => useQuery({ @@ -57,10 +71,18 @@ export const useAnswerDailySurvey = () => { return useMutation({ mutationFn: payload => answerDailySurveyApi(payload), onSuccess: async () => { + /* + * 한글 주석: + * 마음 건강 체크는 홈 캐릭터 상태와 미션 패널 양쪽에서 사용하므로 + * 설문 결과와 홈 데이터를 모두 같은 시점에 다시 받아온다. + */ await queryClient.invalidateQueries({ queryKey: ["daily-survey"] }); await queryClient.invalidateQueries({ queryKey: ["home-summary"] }); + await queryClient.invalidateQueries({ queryKey: ["home-panel"] }); await queryClient.refetchQueries({ queryKey: ["daily-survey"], type: "all" }); await queryClient.refetchQueries({ queryKey: ["home-summary"], type: "all" }); + await queryClient.refetchQueries({ queryKey: ["home-panel"], type: "all" }); }, }); }; + diff --git a/src/pages/dailyMission/DailyMissionCheckingScreen.tsx b/src/pages/dailyMission/DailyMissionCheckingScreen.tsx index eaa178c..a7613ba 100644 --- a/src/pages/dailyMission/DailyMissionCheckingScreen.tsx +++ b/src/pages/dailyMission/DailyMissionCheckingScreen.tsx @@ -61,6 +61,7 @@ export default function DailyMissionCheckingScreen({ navigation }: Props) { await queryClient.refetchQueries({ queryKey: ["daily-survey"], type: "all" }); await queryClient.refetchQueries({ queryKey: ["home-summary"], type: "all" }); + await queryClient.refetchQueries({ queryKey: ["home-panel"], type: "all" }); setAnsweredLocally(true); } catch (error) { const axiosError = error as AxiosError; @@ -72,6 +73,7 @@ export default function DailyMissionCheckingScreen({ navigation }: Props) { setSubmitErrorMessage("이미 오늘의 질문에 답변했습니다. 홈으로 돌아가 완료 상태를 확인해주세요."); await queryClient.refetchQueries({ queryKey: ["daily-survey"], type: "all" }); await queryClient.refetchQueries({ queryKey: ["home-summary"], type: "all" }); + await queryClient.refetchQueries({ queryKey: ["home-panel"], type: "all" }); return; } From b59a379a97ea6cdb88550ecd8526554d1c9e2de2 Mon Sep 17 00:00:00 2001 From: lejuho Date: Fri, 13 Mar 2026 14:37:51 +0900 Subject: [PATCH 20/92] =?UTF-8?q?feat:=20=ED=80=B4=EC=A6=88=20=EC=9E=AC?= =?UTF-8?q?=EC=A7=84=EC=9E=85=20=EC=8B=9C=20=EB=8B=B5=EC=95=88=EA=B3=BC=20?= =?UTF-8?q?=ED=95=B4=EC=84=A4=20=EB=B3=B5=EC=9B=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DailyMissionQuizMultipleChoiceScreen.tsx | 72 ++++++++++++------ .../dailyMission/DailyMissionQuizOxScreen.tsx | 76 +++++++++++++------ src/types/missions/index.ts | 10 +++ 3 files changed, 112 insertions(+), 46 deletions(-) diff --git a/src/pages/dailyMission/DailyMissionQuizMultipleChoiceScreen.tsx b/src/pages/dailyMission/DailyMissionQuizMultipleChoiceScreen.tsx index bf282d8..ef31e64 100644 --- a/src/pages/dailyMission/DailyMissionQuizMultipleChoiceScreen.tsx +++ b/src/pages/dailyMission/DailyMissionQuizMultipleChoiceScreen.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useEffect, useMemo, useState } from "react"; import { ScrollView, StyleSheet, Text, View } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; import ScreenHeader from "@/components/common/ScreenHeader"; @@ -8,6 +8,7 @@ import QuizResultCard from "@/components/dailyMission/QuizResultCard"; import RegistrationFooter from "@/components/registration/RegistrationFooter"; import { useAnswerQuiz, useMissionQuiz } from "@/hooks/mission/useMissionApi"; import type { RootStackScreenProps } from "@/navigation/types"; +import type { AnswerQuizResult } from "@/types/missions"; type Props = RootStackScreenProps<"DailyMissionQuizMultipleChoice">; @@ -20,8 +21,43 @@ export default function DailyMissionQuizMultipleChoiceScreen({ }); const submitAnswer = useAnswerQuiz(); + useEffect(() => { + if (data?.selectedOptionNumber != null) { + setSelected(data.selectedOptionNumber); + } + }, [data?.selectedOptionNumber]); + + /* + * 한글 주석: + * 이미 푼 퀴즈에 다시 진입했을 때도 선택한 선지와 해설을 복원해야 하므로 + * 조회 응답에 포함된 완료 상태를 제출 응답과 같은 형태로 맞춰서 사용한다. + */ + const persistedAnswerResult = useMemo(() => { + if ( + !data?.isCompleted || + data.selectedOptionNumber == null || + data.answerNumber == null || + data.isCorrect == null || + data.answerDescription == null + ) { + return null; + } + + return { + isCorrect: data.isCorrect, + answerDescription: data.answerDescription, + answerNumber: data.answerNumber, + isCompleted: true, + selectedOptionNumber: data.selectedOptionNumber, + quizQuestion: data.quizQuestion, + quizType: data.quizType, + }; + }, [data]); + + const answerResult = submitAnswer.data?.result ?? persistedAnswerResult; + const handleSubmit = async () => { - if (!data?.quizId || selected === null || submitAnswer.isPending) { + if (!data?.quizId || selected === null || submitAnswer.isPending || answerResult) { return; } @@ -31,6 +67,12 @@ export default function DailyMissionQuizMultipleChoiceScreen({ }); }; + const goHome = () => + navigation.reset({ + index: 0, + routes: [{ name: "Main", params: { screen: "Home" } }], + }); + if (isLoading) { return ( @@ -62,8 +104,6 @@ export default function DailyMissionQuizMultipleChoiceScreen({ ); } - const answerResult = submitAnswer.data?.result; - return ( navigation.goBack()} /> @@ -81,7 +121,7 @@ export default function DailyMissionQuizMultipleChoiceScreen({ ? option.optionOrder === answerResult.answerNumber ? "correct" : "idle" - : selected === option.optionOrder + : option.optionOrder === answerResult.selectedOptionNumber ? "wrong" : option.optionOrder === answerResult.answerNumber ? "answer" @@ -120,23 +160,10 @@ export default function DailyMissionQuizMultipleChoiceScreen({ - navigation.reset({ - index: 0, - routes: [{ name: "Main", params: { screen: "Home" } }], - }) - } - primaryLabel={answerResult ? "다음" : "정답 확인하기"} - onPrimaryPress={ - answerResult - ? () => - navigation.reset({ - index: 0, - routes: [{ name: "Main", params: { screen: "Home" } }], - }) - : () => void handleSubmit() - } - primaryDisabled={selected === null || submitAnswer.isPending} + onSecondaryPress={goHome} + primaryLabel={answerResult ? "홈으로" : "정답 확인하기"} + onPrimaryPress={answerResult ? goHome : () => void handleSubmit()} + primaryDisabled={answerResult ? false : selected === null || submitAnswer.isPending} primaryLoading={submitAnswer.isPending} /> @@ -186,3 +213,4 @@ const styles = StyleSheet.create({ color: "#7F1D1D", }, }); + diff --git a/src/pages/dailyMission/DailyMissionQuizOxScreen.tsx b/src/pages/dailyMission/DailyMissionQuizOxScreen.tsx index 7316fe8..36812d3 100644 --- a/src/pages/dailyMission/DailyMissionQuizOxScreen.tsx +++ b/src/pages/dailyMission/DailyMissionQuizOxScreen.tsx @@ -1,4 +1,4 @@ -import { useMemo, useState } from "react"; +import { useEffect, useMemo, useState } from "react"; import { ScrollView, StyleSheet, Text, View } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; import ScreenHeader from "@/components/common/ScreenHeader"; @@ -8,6 +8,7 @@ import QuizResultCard from "@/components/dailyMission/QuizResultCard"; import RegistrationFooter from "@/components/registration/RegistrationFooter"; import { useAnswerQuiz, useMissionQuiz } from "@/hooks/mission/useMissionApi"; import type { RootStackScreenProps } from "@/navigation/types"; +import type { AnswerQuizResult } from "@/types/missions"; type Props = RootStackScreenProps<"DailyMissionQuizOx">; @@ -19,15 +20,50 @@ export default function DailyMissionQuizOxScreen({ navigation }: Props) { const submitAnswer = useAnswerQuiz(); const options = useMemo( - () => [ + () => data?.quizOptions?.length ? data.quizOptions : [ { optionOrder: 0, optionText: "O" }, { optionOrder: 1, optionText: "X" }, ], - [] + [data?.quizOptions] ); + useEffect(() => { + if (data?.selectedOptionNumber != null) { + setSelected(data.selectedOptionNumber); + } + }, [data?.selectedOptionNumber]); + + /* + * 한글 주석: + * OX 퀴즈도 객관식과 같은 복원 규칙을 써야 화면을 나갔다 와도 + * 사용자가 고른 답과 해설을 다시 그대로 보여줄 수 있다. + */ + const persistedAnswerResult = useMemo(() => { + if ( + !data?.isCompleted || + data.selectedOptionNumber == null || + data.answerNumber == null || + data.isCorrect == null || + data.answerDescription == null + ) { + return null; + } + + return { + isCorrect: data.isCorrect, + answerDescription: data.answerDescription, + answerNumber: data.answerNumber, + isCompleted: true, + selectedOptionNumber: data.selectedOptionNumber, + quizQuestion: data.quizQuestion, + quizType: data.quizType, + }; + }, [data]); + + const answerResult = submitAnswer.data?.result ?? persistedAnswerResult; + const handleSubmit = async () => { - if (!data?.quizId || selected === null || submitAnswer.isPending) { + if (!data?.quizId || selected === null || submitAnswer.isPending || answerResult) { return; } @@ -37,6 +73,12 @@ export default function DailyMissionQuizOxScreen({ navigation }: Props) { }); }; + const goHome = () => + navigation.reset({ + index: 0, + routes: [{ name: "Main", params: { screen: "Home" } }], + }); + if (isLoading) { return ( @@ -68,8 +110,6 @@ export default function DailyMissionQuizOxScreen({ navigation }: Props) { ); } - const answerResult = submitAnswer.data?.result; - return ( navigation.goBack()} /> @@ -87,7 +127,7 @@ export default function DailyMissionQuizOxScreen({ navigation }: Props) { ? option.optionOrder === answerResult.answerNumber ? "correct" : "idle" - : selected === option.optionOrder + : option.optionOrder === answerResult.selectedOptionNumber ? "wrong" : option.optionOrder === answerResult.answerNumber ? "answer" @@ -126,23 +166,10 @@ export default function DailyMissionQuizOxScreen({ navigation }: Props) { - navigation.reset({ - index: 0, - routes: [{ name: "Main", params: { screen: "Home" } }], - }) - } - primaryLabel={answerResult ? "다음" : "정답 확인하기"} - onPrimaryPress={ - answerResult - ? () => - navigation.reset({ - index: 0, - routes: [{ name: "Main", params: { screen: "Home" } }], - }) - : () => void handleSubmit() - } - primaryDisabled={selected === null || submitAnswer.isPending} + onSecondaryPress={goHome} + primaryLabel={answerResult ? "홈으로" : "정답 확인하기"} + onPrimaryPress={answerResult ? goHome : () => void handleSubmit()} + primaryDisabled={answerResult ? false : selected === null || submitAnswer.isPending} primaryLoading={submitAnswer.isPending} /> @@ -192,3 +219,4 @@ const styles = StyleSheet.create({ color: "#7F1D1D", }, }); + diff --git a/src/types/missions/index.ts b/src/types/missions/index.ts index 5d88a4c..333aa65 100644 --- a/src/types/missions/index.ts +++ b/src/types/missions/index.ts @@ -43,7 +43,13 @@ export interface QuizOption { export interface MissionQuiz { quizId: number; quizQuestion: string; + quizType: MissionQuizType; quizOptions?: QuizOption[] | null; + isCompleted?: boolean; + selectedOptionNumber?: number | null; + answerNumber?: number | null; + isCorrect?: boolean | null; + answerDescription?: string | null; } export interface GetQuizRequest { @@ -66,6 +72,10 @@ export interface AnswerQuizResult { isCorrect: boolean; answerDescription: string; answerNumber: number; + isCompleted: boolean; + selectedOptionNumber: number; + quizQuestion: string; + quizType: MissionQuizType; } export interface AnswerQuizResponse { From c7bc4bf4601876a2ea85f74b465b8b5a9f334cdc Mon Sep 17 00:00:00 2001 From: lejuho Date: Fri, 13 Mar 2026 14:38:10 +0900 Subject: [PATCH 21/92] =?UTF-8?q?feat:=20=EC=99=84=EB=A3=8C=EB=90=9C=20?= =?UTF-8?q?=EC=9D=BC=EA=B8=B0=20=EB=AF=B8=EC=85=98=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=98=A4=EB=8A=98=20=EC=9D=BC=EA=B8=B0=20=EC=83=81=EC=84=B8=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/home/HomeScreen.tsx | 16 ++++++++++++++-- src/stores/useHomeSummaryStore.ts | 4 ++++ src/types/home/garden.ts | 1 + 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/pages/home/HomeScreen.tsx b/src/pages/home/HomeScreen.tsx index 38e3c16..dc4daff 100644 --- a/src/pages/home/HomeScreen.tsx +++ b/src/pages/home/HomeScreen.tsx @@ -42,7 +42,7 @@ export default function HomeScreen({ navigation }: Props) { const { data, error, isLoading, refetch } = useHomeApi(); const { data: panel } = useHomePanelApi(); const surveyQuery = useDailySurvey(); - const { user, gardens, missions, hydrate } = useHomeSummaryStore(); + const { user, gardens, missions, todayDiaryId, hydrate } = useHomeSummaryStore(); const { lastAnsweredAt, lastAnswerKind, @@ -86,6 +86,7 @@ export default function HomeScreen({ navigation }: Props) { const userInfo = data?.userInfo ?? user; const gardenSummaries = data?.gardenSummaries ?? gardens; const todayMissions = data?.todayMissions ?? missions; + const latestTodayDiaryId = data?.todayDiaryId ?? todayDiaryId; const isEmotionCooldownActive = getEmotionSurveyCooldownActive(lastAnsweredAt); const scenes = useMemo( @@ -196,9 +197,19 @@ export default function HomeScreen({ navigation }: Props) { onPressFeed={() => navigation.navigate("Feed")} onPressUnlockGarden={() => navigation.navigate("UnlockGarden")} onPressMission={mission => { + /* + * 한글 주석: + * 완료된 일기 미션은 다시 작성 화면으로 보내지 않고, + * 오늘 방금 작성한 일기 상세로 연결해야 결과 확인 흐름이 자연스럽다. + */ + if (mission.missionType === "DIARY" && mission.isCompleted && latestTodayDiaryId) { + navigation.navigate("LogDetail", { id: latestTodayDiaryId }); + return; + } + const routeName = getMissionRouteName(mission); if (routeName) { - navigation.navigate(routeName); + navigation.navigate(routeName as never); } }} onPressEmotionCheck={() => setIsEmotionModalOpen(true)} @@ -283,3 +294,4 @@ const styles = StyleSheet.create({ backgroundColor: "#F4F7F0", }, }); + diff --git a/src/stores/useHomeSummaryStore.ts b/src/stores/useHomeSummaryStore.ts index 1e03fe0..945740b 100644 --- a/src/stores/useHomeSummaryStore.ts +++ b/src/stores/useHomeSummaryStore.ts @@ -12,6 +12,7 @@ type HomeSummaryState = { user: UserInfo | null; gardens: GardenSummary[]; missions: TodayMission[]; + todayDiaryId: number | null; hydrate: (payload: HomeSummaryPayload) => void; updateGarden: (gardenId: number, patch: Partial) => void; @@ -33,6 +34,7 @@ const initialState: Omit< user: null, gardens: [], missions: [], + todayDiaryId: null, }; export const useHomeSummaryStore = create()( @@ -45,6 +47,7 @@ export const useHomeSummaryStore = create()( user: payload.userInfo, gardens: payload.gardenSummaries, missions: payload.todayMissions, + todayDiaryId: payload.todayDiaryId ?? null, })), updateGarden: (gardenId, patch) => @@ -69,6 +72,7 @@ export const useHomeSummaryStore = create()( user: state.user, gardens: state.gardens, missions: state.missions, + todayDiaryId: state.todayDiaryId, }), } ) diff --git a/src/types/home/garden.ts b/src/types/home/garden.ts index cf5f7f3..1a7ca0b 100644 --- a/src/types/home/garden.ts +++ b/src/types/home/garden.ts @@ -40,6 +40,7 @@ export interface HomeSummaryPayload { userInfo: UserInfo; gardenSummaries: GardenSummary[]; todayMissions: TodayMission[]; + todayDiaryId?: number | null; } export const getGardenLocked = (garden: GardenSummary) => From c9eada51602d90781a75394a732fc650b5b28d87 Mon Sep 17 00:00:00 2001 From: lejuho Date: Fri, 13 Mar 2026 14:38:18 +0900 Subject: [PATCH 22/92] =?UTF-8?q?refactor:=20=EC=9D=BC=EA=B8=B0=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1=20=ED=95=98=EB=8B=A8=20=ED=91=B8=ED=84=B0?= =?UTF-8?q?=EB=A5=BC=20=EB=8B=A8=EC=9D=BC=20=EB=93=B1=EB=A1=9D=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=EC=9C=BC=EB=A1=9C=20=EB=8B=A8=EC=88=9C=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../registration/RegistrationFooter.tsx | 80 ++---- .../DailyMissionWriteDiaryScreen.tsx | 234 ++++++++++-------- 2 files changed, 155 insertions(+), 159 deletions(-) diff --git a/src/components/registration/RegistrationFooter.tsx b/src/components/registration/RegistrationFooter.tsx index d290388..f68beeb 100644 --- a/src/components/registration/RegistrationFooter.tsx +++ b/src/components/registration/RegistrationFooter.tsx @@ -1,87 +1,51 @@ -import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import { StyleSheet, Text, TouchableOpacity } from "react-native"; type Props = { primaryLabel: string; onPrimaryPress: () => void; primaryDisabled?: boolean; + primaryLoading?: boolean; secondaryLabel?: string; onSecondaryPress?: () => void; - primaryLoading?: boolean; }; export default function RegistrationFooter({ primaryLabel, onPrimaryPress, primaryDisabled = false, - secondaryLabel, - onSecondaryPress, primaryLoading = false, }: Props) { return ( - - {secondaryLabel && onSecondaryPress ? ( - - {secondaryLabel} - - ) : null} - - - {primaryLoading ? "처리 중..." : primaryLabel} - - - + + + {primaryLoading ? "처리 중..." : primaryLabel} + + ); } const styles = StyleSheet.create({ - container: { - flexDirection: "row", - gap: 12, - paddingHorizontal: 20, - paddingVertical: 16, - borderTopWidth: 1, - borderTopColor: "#E5E7EB", - backgroundColor: "#FFFFFF", - }, - secondaryButton: { - flex: 1, - minHeight: 52, - borderRadius: 16, - alignItems: "center", - justifyContent: "center", - backgroundColor: "#E5E7EB", - }, - secondaryText: { - fontSize: 15, - fontWeight: "700", - color: "#374151", - }, - primaryButton: { - flex: 1, - minHeight: 52, - borderRadius: 16, + footer: { + height: 72, + backgroundColor: "#2F7D32", alignItems: "center", justifyContent: "center", - backgroundColor: "#2F7D32", + borderTopWidth: StyleSheet.hairlineWidth, + borderTopColor: "#2F7D32", }, - primaryButtonDisabled: { + footerDisabled: { backgroundColor: "#A7D4A5", + borderTopColor: "#A7D4A5", }, - primaryText: { - fontSize: 15, + label: { + fontSize: 16, fontWeight: "700", color: "#FFFFFF", + letterSpacing: 0.3, }, }); diff --git a/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx b/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx index 23d374b..cc988b5 100644 --- a/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx +++ b/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx @@ -1,5 +1,5 @@ -import { useState } from "react"; import * as ImagePicker from "expo-image-picker"; + import { Alert, ScrollView, @@ -8,17 +8,19 @@ import { TouchableOpacity, View, } from "react-native"; -import { useQueryClient } from "@tanstack/react-query"; -import { SafeAreaView } from "react-native-safe-area-context"; -import ScreenHeader from "@/components/common/ScreenHeader"; -import ImageAttachmentCard from "@/components/dailyMission/ImageAttachmentCard"; -import RegistrationFooter from "@/components/registration/RegistrationFooter"; -import RegistrationTextField from "@/components/registration/RegistrationTextField"; import { useWriteDiaryImageUpload, useWriteDiarySubmit, } from "@/hooks/mission/useMissionApi"; + +import ImageAttachmentCard from "@/components/dailyMission/ImageAttachmentCard"; +import RegistrationFooter from "@/components/registration/RegistrationFooter"; +import RegistrationTextField from "@/components/registration/RegistrationTextField"; import type { RootStackScreenProps } from "@/navigation/types"; +import { SafeAreaView } from "react-native-safe-area-context"; +import ScreenHeader from "@/components/common/ScreenHeader"; +import { useQueryClient } from "@tanstack/react-query"; +import { useState } from "react"; type Props = RootStackScreenProps<"DailyMissionWriteDiary">; @@ -44,11 +46,15 @@ export default function DailyMissionWriteDiaryScreen({ navigation }: Props) { const handlePickImage = async () => { if (!permissionRequested) { - const permission = await ImagePicker.requestMediaLibraryPermissionsAsync(); + const permission = + await ImagePicker.requestMediaLibraryPermissionsAsync(); setPermissionRequested(true); if (!permission.granted) { - Alert.alert("권한 필요", "일기 이미지를 선택하려면 사진 접근 권한이 필요합니다."); + Alert.alert( + "권한 필요", + "일기 이미지를 선택하려면 사진 접근 권한이 필요합니다." + ); return; } } @@ -81,7 +87,8 @@ export default function DailyMissionWriteDiaryScreen({ navigation }: Props) { const response = await uploadDiaryImage.mutateAsync(formData); setUploadedImage(response.result); } catch (error) { - const message = error instanceof Error ? error.message : "이미지 업로드에 실패했습니다."; + const message = + error instanceof Error ? error.message : "이미지 업로드에 실패했습니다."; Alert.alert("업로드 실패", message); } }; @@ -115,37 +122,38 @@ export default function DailyMissionWriteDiaryScreen({ navigation }: Props) { await queryClient.invalidateQueries({ queryKey: ["diaries"] }); goHome(); } catch (error) { - const message = error instanceof Error ? error.message : "일기 저장에 실패했습니다."; + const message = + error instanceof Error ? error.message : "일기 저장에 실패했습니다."; Alert.alert("일기 저장 실패", message); } }; + const today = new Date().toLocaleDateString("ko-KR", { + year: "numeric", + month: "long", + day: "numeric", + }); + return ( - - - 오늘의 식물 이야기를 적어주세요. - - 제목과 내용을 적고 이미지를 첨부한 뒤 공개 여부를 선택해 제출할 수 있습니다. - - + + {/* 날짜 */} + {today} + {/* 제목 입력 (라벨 없이 큰 플레이스홀더) */} - + {/* 이미지 첨부 */} void handlePickImage()} @@ -158,52 +166,74 @@ export default function DailyMissionWriteDiaryScreen({ navigation }: Props) { } /> - - 공개 설정 - - + + {/* 공개 설정 — 라디오 버튼 스타일 */} + + setIsPublic(false)} + activeOpacity={0.7} + > + + {!isPublic && } + + + 나만 보기 + + + + setIsPublic(true)} + activeOpacity={0.7} + > + setIsPublic(false)} > - - 비공개 - - - ✓} + + setIsPublic(true)} > - - 공개 - - - + 공개하기 + + void handleSubmit()} primaryDisabled={ - !title.trim() || !content.trim() || !uploadedImage || uploadDiaryImage.isPending || submitDiary.isPending + !title.trim() || + !content.trim() || + !uploadedImage || + uploadDiaryImage.isPending || + submitDiary.isPending } primaryLoading={submitDiary.isPending} /> @@ -217,58 +247,60 @@ const styles = StyleSheet.create({ backgroundColor: "#F7F8F4", }, content: { - padding: 20, - gap: 18, - }, - headerBlock: { - gap: 8, - }, - title: { - fontSize: 24, - lineHeight: 32, - fontWeight: "700", - color: "#171717", - }, - subtitle: { - fontSize: 14, - lineHeight: 20, - color: "#6B7280", + paddingHorizontal: 20, + paddingTop: 20, + paddingBottom: 32, + gap: 20, }, - visibilityCard: { - borderRadius: 16, - padding: 16, - backgroundColor: "#FFFFFF", - gap: 12, + dateText: { + fontSize: 13, + color: "#9CA3AF", + fontWeight: "400", + letterSpacing: 0.2, }, - visibilityTitle: { - fontSize: 14, - fontWeight: "700", - color: "#171717", + + // 공개 설정 — 라디오 버튼 + visibilityRow: { + flexDirection: "row", + gap: 24, + paddingTop: 4, + paddingBottom: 8, }, - visibilityButtons: { + visibilityOption: { flexDirection: "row", - gap: 10, + alignItems: "center", + gap: 8, }, - visibilityButton: { - flex: 1, - minHeight: 44, - borderRadius: 12, - borderWidth: 1, - borderColor: "#D1D5DB", + radioCircle: { + width: 22, + height: 22, + borderRadius: 11, + borderWidth: 1.5, + borderColor: "#C4C9C0", alignItems: "center", justifyContent: "center", - backgroundColor: "#FFFFFF", + backgroundColor: "transparent", }, - visibilityButtonActive: { + radioCircleSelected: { borderColor: "#2F7D32", - backgroundColor: "#EDF7ED", + backgroundColor: "#2F7D32", }, - visibilityButtonText: { - fontSize: 14, + radioCheck: { + fontSize: 12, + color: "#FFFFFF", fontWeight: "700", - color: "#4B5563", + lineHeight: 14, + }, + visibilityLabel: { + fontSize: 14, + color: "#9CA3AF", + fontWeight: "400", }, - visibilityButtonTextActive: { - color: "#1F5C27", + visibilityLabelSelected: { + color: "#171717", + fontWeight: "500", }, }); + + + From d8a062466940451f547a9a6f06b1b98b8bdf5496 Mon Sep 17 00:00:00 2001 From: lejuho Date: Fri, 13 Mar 2026 14:47:12 +0900 Subject: [PATCH 23/92] =?UTF-8?q?chore:=20react=20native=20gesture=20handl?= =?UTF-8?q?er=20=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 3815 ++++++++++++++++++--------------------------- package.json | 1 + 2 files changed, 1508 insertions(+), 2308 deletions(-) diff --git a/package-lock.json b/package-lock.json index 90d748c..a5d5266 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,6 +30,7 @@ "react": "19.1.0", "react-dom": "19.1.0", "react-native": "0.81.5", + "react-native-gesture-handler": "~2.28.0", "react-native-pager-view": "6.9.1", "react-native-safe-area-context": "~5.6.0", "react-native-screens": "~4.16.0", @@ -73,38 +74,43 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "license": "MIT", "dependencies": { - "@babel/highlight": "^7.10.4" + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.6.tgz", - "integrity": "sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.6.tgz", - "integrity": "sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.28.6", - "@babel/generator": "^7.28.6", + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-module-transforms": "^7.28.6", "@babel/helpers": "^7.28.6", - "@babel/parser": "^7.28.6", + "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", - "@babel/traverse": "^7.28.6", - "@babel/types": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", @@ -120,37 +126,14 @@ "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/core/node_modules/@babel/code-frame": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz", - "integrity": "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.28.5", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@babel/generator": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.6.tgz", - "integrity": "sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw==", + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.6", - "@babel/types": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -187,15 +170,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@babel/helper-create-class-features-plugin": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.6.tgz", @@ -217,15 +191,6 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@babel/helper-create-regexp-features-plugin": { "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz", @@ -243,26 +208,17 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz", - "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==", + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.7.tgz", + "integrity": "sha512-6Fqi8MtQ/PweQ9xvux65emkLQ83uB+qAVtfHkC9UodyHMIZdxNI01HjLCLUtybElp2KY2XNE0nOgyP1E1vXw9w==", "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", - "debug": "^4.4.1", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "debug": "^4.4.3", "lodash.debounce": "^4.0.8", - "resolve": "^1.22.10" + "resolve": "^1.22.11" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -457,13 +413,84 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/parser": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.6.tgz", - "integrity": "sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", "license": "MIT", "dependencies": { - "@babel/types": "^7.28.6" + "@babel/types": "^7.29.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -473,9 +500,9 @@ } }, "node_modules/@babel/plugin-proposal-decorators": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.28.6.tgz", - "integrity": "sha512-RVdFPPyY9fCRAX68haPmOk2iyKW8PKJFthmm8NeSI3paNxKWGZIn99+VbIf0FrtCpFnPgnpF/L48tadi617ULg==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.29.0.tgz", + "integrity": "sha512-CVBVv3VY/XRMxRYq5dwr2DS7/MvqPm23cOCjbwNnVrfOqcWlnefua1uUs0sjdKOGjvPUG633o07uWzJq4oI6dA==", "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.28.6", @@ -799,14 +826,14 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.6.tgz", - "integrity": "sha512-9knsChgsMzBV5Yh3kkhrZNxH3oCYAfMBkNNaVN4cP2RVlFPe8wYdwwcnOsAbkdDoV9UjFtOXWrWB52M8W4jNeA==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.0.tgz", + "integrity": "sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-remap-async-to-generator": "^7.27.1", - "@babel/traverse": "^7.28.6" + "@babel/traverse": "^7.29.0" }, "engines": { "node": ">=6.9.0" @@ -1042,13 +1069,13 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz", - "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.0.tgz", + "integrity": "sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1281,9 +1308,9 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.6.tgz", - "integrity": "sha512-eZhoEZHYQLL5uc1gS5e9/oTknS0sSSAtd5TkKMUp3J+S/CaUjagc0kOUPsEbDmMeva0nC3WWl4SxVY6+OBuxfw==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.0.tgz", + "integrity": "sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" @@ -1296,13 +1323,13 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.5.tgz", - "integrity": "sha512-20NUVgOrinudkIBzQ2bNxP08YpKprUkRTiRSd2/Z5GOdPImJGkoN4Z7IQe1T5AdyKI1i5L6RBmluqdSzvaq9/w==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.29.0.tgz", + "integrity": "sha512-jlaRT5dJtMaMCV6fAuLbsQMSwz/QkvaHOHOSXRitGGwSpR1blCY4KUKoyP2tYO8vJcqYe8cEj96cqSztv3uF9w==", "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", "babel-plugin-polyfill-corejs2": "^0.4.14", "babel-plugin-polyfill-corejs3": "^0.13.0", "babel-plugin-polyfill-regenerator": "^0.6.5", @@ -1315,15 +1342,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@babel/plugin-transform-shorthand-properties": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", @@ -1483,32 +1501,18 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/template/node_modules/@babel/code-frame": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz", - "integrity": "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.28.5", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/traverse": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.6.tgz", - "integrity": "sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.28.6", - "@babel/generator": "^7.28.6", + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.6", + "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", - "@babel/types": "^7.28.6", + "@babel/types": "^7.29.0", "debug": "^4.3.1" }, "engines": { @@ -1517,55 +1521,27 @@ }, "node_modules/@babel/traverse--for-generate-function-map": { "name": "@babel/traverse", - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.6.tgz", - "integrity": "sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.28.6", - "@babel/generator": "^7.28.6", + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.6", + "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", - "@babel/types": "^7.28.6", + "@babel/types": "^7.29.0", "debug": "^4.3.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/traverse--for-generate-function-map/node_modules/@babel/code-frame": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz", - "integrity": "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.28.5", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/@babel/code-frame": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz", - "integrity": "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.28.5", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/types": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.6.tgz", - "integrity": "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", @@ -1580,7 +1556,6 @@ "resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz", "integrity": "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==", "license": "MIT", - "peer": true, "dependencies": { "@types/hammerjs": "^2.0.36" }, @@ -1640,74 +1615,103 @@ "xml2js": "0.6.0" } }, - "node_modules/@expo/config-plugins/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@expo/config-plugins/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "18 || 20 || >=22" } }, - "node_modules/@expo/config-plugins/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/@expo/config-plugins/node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "balanced-match": "^4.0.2" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": "18 || 20 || >=22" } }, - "node_modules/@expo/config-plugins/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", + "node_modules/@expo/config-plugins/node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "license": "BlueOak-1.0.0", "dependencies": { - "color-name": "~1.1.4" + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" }, "engines": { - "node": ">=7.0.0" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@expo/config-plugins/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/@expo/config-plugins/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", + "node_modules/@expo/config-plugins/node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=8" + "node": "20 || >=22" } }, - "node_modules/@expo/config-plugins/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", + "node_modules/@expo/config-plugins/node_modules/minimatch": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "license": "BlueOak-1.0.0", "dependencies": { - "has-flag": "^4.0.0" + "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=8" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@expo/config-plugins/node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/@expo/config-plugins/node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@expo/config-plugins/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/@expo/config-types": { @@ -1716,197 +1720,165 @@ "integrity": "sha512-/J16SC2an1LdtCZ67xhSkGXpALYUVUNyZws7v+PVsFZxClYehDSoKLqyRaGkpHlYrCc08bS0RF5E0JV6g50psA==", "license": "MIT" }, - "node_modules/@expo/devcert": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@expo/devcert/-/devcert-1.2.1.tgz", - "integrity": "sha512-qC4eaxmKMTmJC2ahwyui6ud8f3W60Ss7pMkpBq40Hu3zyiAaugPXnZ24145U7K36qO9UHdZUVxsCvIpz2RYYCA==", - "license": "MIT", - "dependencies": { - "@expo/sudo-prompt": "^9.3.1", - "debug": "^3.1.0" - } - }, - "node_modules/@expo/devcert/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "node_modules/@expo/config/node_modules/@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", "license": "MIT", "dependencies": { - "ms": "^2.1.1" + "@babel/highlight": "^7.10.4" } }, - "node_modules/@expo/devtools": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/@expo/devtools/-/devtools-0.1.8.tgz", - "integrity": "sha512-SVLxbuanDjJPgc0sy3EfXUMLb/tXzp6XIHkhtPVmTWJAp+FOr6+5SeiCfJrCzZFet0Ifyke2vX3sFcKwEvCXwQ==", + "node_modules/@expo/config/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "license": "MIT", - "dependencies": { - "chalk": "^4.1.2" - }, - "peerDependencies": { - "react": "*", - "react-native": "*" - }, - "peerDependenciesMeta": { - "react": { - "optional": true - }, - "react-native": { - "optional": true - } + "engines": { + "node": "18 || 20 || >=22" } }, - "node_modules/@expo/devtools/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@expo/config/node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "balanced-match": "^4.0.2" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "18 || 20 || >=22" } }, - "node_modules/@expo/devtools/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", + "node_modules/@expo/config/node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "license": "BlueOak-1.0.0", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" }, "engines": { - "node": ">=10" + "node": "18 || 20 || >=22" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@expo/devtools/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@expo/devtools/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/@expo/devtools/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", + "node_modules/@expo/config/node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=8" + "node": "20 || >=22" } }, - "node_modules/@expo/devtools/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", + "node_modules/@expo/config/node_modules/minimatch": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "license": "BlueOak-1.0.0", "dependencies": { - "has-flag": "^4.0.0" + "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=8" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@expo/env": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/@expo/env/-/env-2.0.8.tgz", - "integrity": "sha512-5VQD6GT8HIMRaSaB5JFtOXuvfDVU80YtZIuUT/GDhUF782usIXY13Tn3IdDz1Tm/lqA9qnRZQ1BF4t7LlvdJPA==", - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "debug": "^4.3.4", - "dotenv": "~16.4.5", - "dotenv-expand": "~11.0.6", - "getenv": "^2.0.0" + "node_modules/@expo/config/node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" } }, - "node_modules/@expo/env/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", + "node_modules/@expo/config/node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "license": "BlueOak-1.0.0", "dependencies": { - "color-convert": "^2.0.1" + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, "engines": { - "node": ">=8" + "node": "18 || 20 || >=22" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@expo/env/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "node_modules/@expo/config/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@expo/env/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/@expo/devcert": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@expo/devcert/-/devcert-1.2.1.tgz", + "integrity": "sha512-qC4eaxmKMTmJC2ahwyui6ud8f3W60Ss7pMkpBq40Hu3zyiAaugPXnZ24145U7K36qO9UHdZUVxsCvIpz2RYYCA==", "license": "MIT", "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "@expo/sudo-prompt": "^9.3.1", + "debug": "^3.1.0" } }, - "node_modules/@expo/env/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/@expo/env/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/@expo/devcert/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "license": "MIT", - "engines": { - "node": ">=8" + "dependencies": { + "ms": "^2.1.1" } }, - "node_modules/@expo/env/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/@expo/devtools": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/@expo/devtools/-/devtools-0.1.8.tgz", + "integrity": "sha512-SVLxbuanDjJPgc0sy3EfXUMLb/tXzp6XIHkhtPVmTWJAp+FOr6+5SeiCfJrCzZFet0Ifyke2vX3sFcKwEvCXwQ==", "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "chalk": "^4.1.2" }, - "engines": { - "node": ">=8" + "peerDependencies": { + "react": "*", + "react-native": "*" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/@expo/env": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@expo/env/-/env-2.0.11.tgz", + "integrity": "sha512-xV+ps6YCW7XIPVUwFVCRN2nox09dnRwy8uIjwHWTODu0zFw4kp4omnVkl0OOjuu2XOe7tdgAHxikrkJt9xB/7Q==", + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "debug": "^4.3.4", + "dotenv": "~16.4.5", + "dotenv-expand": "~11.0.6", + "getenv": "^2.0.0" } }, "node_modules/@expo/fingerprint": { @@ -1931,162 +1903,130 @@ "fingerprint": "bin/cli.js" } }, - "node_modules/@expo/fingerprint/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@expo/fingerprint/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "18 || 20 || >=22" } }, - "node_modules/@expo/fingerprint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/@expo/fingerprint/node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "balanced-match": "^4.0.2" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": "18 || 20 || >=22" } }, - "node_modules/@expo/fingerprint/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", + "node_modules/@expo/fingerprint/node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "license": "BlueOak-1.0.0", "dependencies": { - "color-name": "~1.1.4" + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" }, "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@expo/fingerprint/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/@expo/fingerprint/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@expo/fingerprint/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", + "node_modules/@expo/fingerprint/node_modules/glob/node_modules/minimatch": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "license": "BlueOak-1.0.0", "dependencies": { - "has-flag": "^4.0.0" + "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=8" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@expo/image-utils": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.8.8.tgz", - "integrity": "sha512-HHHaG4J4nKjTtVa1GG9PCh763xlETScfEyNxxOvfTRr8IKPJckjTyqSLEtdJoFNJ1vqiABEjW7tqGhqGibZLeA==", - "license": "MIT", - "dependencies": { - "@expo/spawn-async": "^1.7.2", - "chalk": "^4.0.0", - "getenv": "^2.0.0", - "jimp-compact": "0.16.1", - "parse-png": "^2.1.0", - "resolve-from": "^5.0.0", - "resolve-global": "^1.0.0", - "semver": "^7.6.0", - "temp-dir": "~2.0.0", - "unique-string": "~2.0.0" + "node_modules/@expo/fingerprint/node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" } }, - "node_modules/@expo/image-utils/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, + "node_modules/@expo/fingerprint/node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=16 || 14 >=14.17" } }, - "node_modules/@expo/image-utils/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", + "node_modules/@expo/fingerprint/node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "license": "BlueOak-1.0.0", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, "engines": { - "node": ">=10" + "node": "18 || 20 || >=22" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@expo/image-utils/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" + "node_modules/@expo/fingerprint/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@expo/image-utils/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/@expo/image-utils/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" + "node": ">=10" } - }, - "node_modules/@expo/image-utils/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + }, + "node_modules/@expo/image-utils": { + "version": "0.8.12", + "resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.8.12.tgz", + "integrity": "sha512-3KguH7kyKqq7pNwLb9j6BBdD/bjmNwXZG/HPWT6GWIXbwrvAJt2JNyYTP5agWJ8jbbuys1yuCzmkX+TU6rmI7A==", "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "@expo/spawn-async": "^1.7.2", + "chalk": "^4.0.0", + "getenv": "^2.0.0", + "jimp-compact": "0.16.1", + "parse-png": "^2.1.0", + "resolve-from": "^5.0.0", + "semver": "^7.6.0" + } + }, + "node_modules/@expo/image-utils/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/@expo/json-file": { @@ -2099,20 +2039,6 @@ "json5": "^2.2.3" } }, - "node_modules/@expo/json-file/node_modules/@babel/code-frame": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", - "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.28.5", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@expo/metro": { "version": "54.2.0", "resolved": "https://registry.npmjs.org/@expo/metro/-/metro-54.2.0.tgz", @@ -2172,103 +2098,91 @@ } } }, - "node_modules/@expo/metro-config/node_modules/@babel/code-frame": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", - "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "node_modules/@expo/metro-config/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.28.5", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, "engines": { - "node": ">=6.9.0" + "node": "18 || 20 || >=22" } }, - "node_modules/@expo/metro-config/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@expo/metro-config/node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "balanced-match": "^4.0.2" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "18 || 20 || >=22" } }, - "node_modules/@expo/metro-config/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", + "node_modules/@expo/metro-config/node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "license": "BlueOak-1.0.0", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" }, "engines": { - "node": ">=10" + "node": "18 || 20 || >=22" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@expo/metro-config/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", + "node_modules/@expo/metro-config/node_modules/glob/node_modules/minimatch": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "license": "BlueOak-1.0.0", "dependencies": { - "color-name": "~1.1.4" + "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=7.0.0" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@expo/metro-config/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/@expo/metro-config/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", + "node_modules/@expo/metro-config/node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=8" + "node": "20 || >=22" } }, - "node_modules/@expo/metro-config/node_modules/hermes-estree": { - "version": "0.29.1", - "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.29.1.tgz", - "integrity": "sha512-jl+x31n4/w+wEqm0I2r4CMimukLbLQEYpisys5oCre611CI5fc9TxhqkBBCJ1edDG4Kza0f7CgNz8xVMLZQOmQ==", - "license": "MIT" - }, - "node_modules/@expo/metro-config/node_modules/hermes-parser": { - "version": "0.29.1", - "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.29.1.tgz", - "integrity": "sha512-xBHWmUtRC5e/UL0tI7Ivt2riA/YBq9+SiYFU7C1oBa/j2jYGlIF9043oak1F47ihuDIxQ5nbsKueYJDRY02UgA==", - "license": "MIT", - "dependencies": { - "hermes-estree": "0.29.1" + "node_modules/@expo/metro-config/node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" } }, - "node_modules/@expo/metro-config/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", + "node_modules/@expo/metro-config/node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "license": "BlueOak-1.0.0", "dependencies": { - "has-flag": "^4.0.0" + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, "engines": { - "node": ">=8" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@expo/osascript": { @@ -2297,76 +2211,6 @@ "resolve-workspace-root": "^2.0.0" } }, - "node_modules/@expo/package-manager/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@expo/package-manager/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@expo/package-manager/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@expo/package-manager/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/@expo/package-manager/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@expo/package-manager/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@expo/plist": { "version": "0.4.8", "resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.4.8.tgz", @@ -2399,6 +2243,18 @@ "expo": "*" } }, + "node_modules/@expo/prebuild-config/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@expo/schema-utils": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/@expo/schema-utils/-/schema-utils-0.1.8.tgz", @@ -2429,104 +2285,43 @@ "integrity": "sha512-HHQigo3rQWKMDzYDLkubN5WQOYXJJE2eNqIQC2axC2iO3mHdwnIR7FgZVvHWtBwAdzBgAP0ECp8KqS8TiMKvgw==", "license": "MIT" }, - "node_modules/@expo/ws-tunnel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@expo/ws-tunnel/-/ws-tunnel-1.0.6.tgz", - "integrity": "sha512-nDRbLmSrJar7abvUjp3smDwH8HcbZcoOEa5jVPUv9/9CajgmWw20JNRwTuBRzWIWIkEJDkz20GoNA+tSwUqk0Q==", - "license": "MIT" - }, - "node_modules/@expo/xcpretty": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@expo/xcpretty/-/xcpretty-4.4.1.tgz", - "integrity": "sha512-KZNxZvnGCtiM2aYYZ6Wz0Ix5r47dAvpNLApFtZWnSoERzAdOMzVBOPysBoM0JlF6FKWZ8GPqgn6qt3dV/8Zlpg==", - "license": "BSD-3-Clause", - "dependencies": { - "@babel/code-frame": "^7.20.0", - "chalk": "^4.1.0", - "js-yaml": "^4.1.0" - }, - "bin": { - "excpretty": "build/cli.js" - } - }, - "node_modules/@expo/xcpretty/node_modules/@babel/code-frame": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", - "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.28.5", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@expo/xcpretty/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@expo/xcpretty/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, - "node_modules/@expo/xcpretty/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@expo/xcpretty/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/@expo/vector-icons": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-15.1.1.tgz", + "integrity": "sha512-Iu2VkcoI5vygbtYngm7jb4ifxElNVXQYdDrYkT7UCEIiKLeWnQY0wf2ZhHZ+Wro6Sc5TaumpKUOqDRpLi5rkvw==", "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "peerDependencies": { + "expo-font": ">=14.0.4", + "react": "*", + "react-native": "*" } }, - "node_modules/@expo/xcpretty/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "node_modules/@expo/ws-tunnel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@expo/ws-tunnel/-/ws-tunnel-1.0.6.tgz", + "integrity": "sha512-nDRbLmSrJar7abvUjp3smDwH8HcbZcoOEa5jVPUv9/9CajgmWw20JNRwTuBRzWIWIkEJDkz20GoNA+tSwUqk0Q==", "license": "MIT" }, - "node_modules/@expo/xcpretty/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" + "node_modules/@expo/xcpretty": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@expo/xcpretty/-/xcpretty-4.4.1.tgz", + "integrity": "sha512-KZNxZvnGCtiM2aYYZ6Wz0Ix5r47dAvpNLApFtZWnSoERzAdOMzVBOPysBoM0JlF6FKWZ8GPqgn6qt3dV/8Zlpg==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/code-frame": "^7.20.0", + "chalk": "^4.1.0", + "js-yaml": "^4.1.0" + }, + "bin": { + "excpretty": "build/cli.js" } }, + "node_modules/@expo/xcpretty/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, "node_modules/@expo/xcpretty/node_modules/js-yaml": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", @@ -2539,39 +2334,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/@expo/xcpretty/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@isaacs/balanced-match": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", - "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", - "license": "MIT", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@isaacs/brace-expansion": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", - "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", - "license": "MIT", - "dependencies": { - "@isaacs/balanced-match": "^4.0.1" - }, - "engines": { - "node": "20 || >=22" - } - }, "node_modules/@isaacs/fs-minipass": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", @@ -2584,6 +2346,15 @@ "node": ">=18.0.0" } }, + "node_modules/@isaacs/fs-minipass/node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/@isaacs/ttlcache": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/@isaacs/ttlcache/-/ttlcache-1.4.1.tgz", @@ -2618,252 +2389,173 @@ "node": ">=6" } }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/create-cache-key-function": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz", - "integrity": "sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==", - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/environment": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", - "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", - "license": "MIT", - "dependencies": { - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/fake-timers": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", - "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@sinonjs/fake-timers": "^10.0.2", - "@types/node": "*", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/transform": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", - "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "license": "MIT", "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/@jest/transform/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "p-locate": "^4.1.0" }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@jest/transform/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "p-try": "^2.0.0" }, "engines": { - "node": ">=10" + "node": ">=6" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@jest/transform/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "p-limit": "^2.2.0" }, "engines": { - "node": ">=7.0.0" + "node": ">=8" } }, - "node_modules/@jest/transform/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/@jest/transform/node_modules/has-flag": { + "node_modules/@istanbuljs/load-nyc-config/node_modules/path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/@jest/transform/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, "engines": { "node": ">=8" } }, - "node_modules/@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "node_modules/@jest/create-cache-key-function": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz", + "integrity": "sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==", "license": "MIT", "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" + "@jest/types": "^29.6.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/types/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/types/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/types/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "@sinclair/typebox": "^0.27.8" }, "engines": { - "node": ">=7.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/types/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/@jest/types/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/types/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jridgewell/gen-mapping": { @@ -3049,6 +2741,15 @@ "@babel/core": "*" } }, + "node_modules/@react-native/babel-preset/node_modules/react-refresh": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", + "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@react-native/codegen": { "version": "0.81.5", "resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.81.5.tgz", @@ -3084,7 +2785,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -3101,25 +2802,10 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@react-native/codegen/node_modules/hermes-estree": { - "version": "0.29.1", - "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.29.1.tgz", - "integrity": "sha512-jl+x31n4/w+wEqm0I2r4CMimukLbLQEYpisys5oCre611CI5fc9TxhqkBBCJ1edDG4Kza0f7CgNz8xVMLZQOmQ==", - "license": "MIT" - }, - "node_modules/@react-native/codegen/node_modules/hermes-parser": { - "version": "0.29.1", - "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.29.1.tgz", - "integrity": "sha512-xBHWmUtRC5e/UL0tI7Ivt2riA/YBq9+SiYFU7C1oBa/j2jYGlIF9043oak1F47ihuDIxQ5nbsKueYJDRY02UgA==", - "license": "MIT", - "dependencies": { - "hermes-estree": "0.29.1" - } - }, "node_modules/@react-native/codegen/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -3158,6 +2844,18 @@ } } }, + "node_modules/@react-native/community-cli-plugin/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@react-native/debugger-frontend": { "version": "0.81.5", "resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.81.5.tgz", @@ -3222,41 +2920,18 @@ "integrity": "sha512-0HuJ8YtqlTVRXGZuGeBejLE04wSQsibpTI+RGOyVqxZvgtlLLC/Ssw0UmbHhT4lYMp2fhdtvKZSs5emWB1zR/g==", "license": "MIT" }, - "node_modules/@react-native/virtualized-lists": { - "version": "0.81.5", - "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.81.5.tgz", - "integrity": "sha512-UVXgV/db25OPIvwZySeToXD/9sKKhOdkcWmmf4Jh8iBZuyfML+/5CasaZ1E7Lqg6g3uqVQq75NqIwkYmORJMPw==", - "license": "MIT", - "dependencies": { - "invariant": "^2.2.4", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">= 20.19.4" - }, - "peerDependencies": { - "@types/react": "^19.1.0", - "react": "*", - "react-native": "*" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@react-navigation/bottom-tabs": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-7.10.1.tgz", - "integrity": "sha512-MirOzKEe/rRwPSE9HMrS4niIo0LyUhewlvd01TpzQ1ipuXjH2wJbzAM9gS/r62zriB6HMHz2OY6oIRduwQJtTw==", + "version": "7.15.5", + "resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-7.15.5.tgz", + "integrity": "sha512-wQHredlCrRmShWQ1vF4HUcLdaiJ8fUgnbaeQH7BJ7MQVQh4mdzab0IOY/4QSmUyNRB350oyu1biTycyQ5FKWMQ==", "license": "MIT", "dependencies": { - "@react-navigation/elements": "^2.9.5", + "@react-navigation/elements": "^2.9.10", "color": "^4.2.3", "sf-symbols-typescript": "^2.1.0" }, "peerDependencies": { - "@react-navigation/native": "^7.1.28", + "@react-navigation/native": "^7.1.33", "react": ">= 18.2.0", "react-native": "*", "react-native-safe-area-context": ">= 4.0.0", @@ -3264,9 +2939,9 @@ } }, "node_modules/@react-navigation/core": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-7.14.0.tgz", - "integrity": "sha512-tMpzskBzVp0E7CRNdNtJIdXjk54Kwe/TF9ViXAef+YFM1kSfGv4e/B2ozfXE+YyYgmh4WavTv8fkdJz1CNyu+g==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-7.16.1.tgz", + "integrity": "sha512-xhquoyhKdqDfiL7LuupbwYnmauUGfVFGDEJO34m26k8zSN1eDjQ2stBZcHN8ILOI1PrG9885nf8ZmfaQxPS0ww==", "license": "MIT", "dependencies": { "@react-navigation/routers": "^7.5.3", @@ -3282,28 +2957,10 @@ "react": ">= 18.2.0" } }, - "node_modules/@react-navigation/core/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@react-navigation/core/node_modules/react-is": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.3.tgz", - "integrity": "sha512-qJNJfu81ByyabuG7hPFEbXqNcWSU3+eVus+KJs+0ncpGfMyYdvSmxiJxbWR65lYi1I+/0HBcliO029gc4F+PnA==", - "license": "MIT" - }, "node_modules/@react-navigation/elements": { - "version": "2.9.5", - "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-2.9.5.tgz", - "integrity": "sha512-iHZU8rRN1014Upz73AqNVXDvSMZDh5/ktQ1CMe21rdgnOY79RWtHHBp9qOS3VtqlUVYGkuX5GEw5mDt4tKdl0g==", + "version": "2.9.10", + "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-2.9.10.tgz", + "integrity": "sha512-N8tuBekzTRb0pkMHFJGvmC6Q5OisSbt6gzvw7RHMnp4NDo5auVllT12sWFaTXf8mTduaLKNSrD/NZNaOqThCBg==", "license": "MIT", "dependencies": { "color": "^4.2.3", @@ -3312,7 +2969,7 @@ }, "peerDependencies": { "@react-native-masked-view/masked-view": ">= 0.2.0", - "@react-navigation/native": "^7.1.28", + "@react-navigation/native": "^7.1.33", "react": ">= 18.2.0", "react-native": "*", "react-native-safe-area-context": ">= 4.0.0" @@ -3324,12 +2981,12 @@ } }, "node_modules/@react-navigation/native": { - "version": "7.1.28", - "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-7.1.28.tgz", - "integrity": "sha512-d1QDn+KNHfHGt3UIwOZvupvdsDdiHYZBEj7+wL2yDVo3tMezamYy60H9s3EnNVE1Ae1ty0trc7F2OKqo/RmsdQ==", + "version": "7.1.33", + "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-7.1.33.tgz", + "integrity": "sha512-DpFdWGcgLajKZ1TuIvDNQsblN2QaUFWpTQaB8v7WRP9Mix8H/6TFoIrZd93pbymI2hybd6UYrD+lI408eWVcfw==", "license": "MIT", "dependencies": { - "@react-navigation/core": "^7.14.0", + "@react-navigation/core": "^7.16.1", "escape-string-regexp": "^4.0.0", "fast-deep-equal": "^3.1.3", "nanoid": "^3.3.11", @@ -3341,36 +2998,24 @@ } }, "node_modules/@react-navigation/native-stack": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@react-navigation/native-stack/-/native-stack-7.10.1.tgz", - "integrity": "sha512-8jt7olKysn07HuKKSjT/ahZZTV+WaZa96o9RI7gAwh7ATlUDY02rIRttwvCyjovhSjD9KCiuJ+Hd4kwLidHwJw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@react-navigation/native-stack/-/native-stack-7.14.5.tgz", + "integrity": "sha512-NuyMf21kKk3jODvYgpcDA+HwyWr/KEj72ciqquyEupZlsmQ3WNUGgdaixEB3A19+iPOvHLQzDLcoTrrqZk8Leg==", "license": "MIT", "dependencies": { - "@react-navigation/elements": "^2.9.5", + "@react-navigation/elements": "^2.9.10", "color": "^4.2.3", "sf-symbols-typescript": "^2.1.0", "warn-once": "^0.1.1" }, "peerDependencies": { - "@react-navigation/native": "^7.1.28", + "@react-navigation/native": "^7.1.33", "react": ">= 18.2.0", "react-native": "*", "react-native-safe-area-context": ">= 4.0.0", "react-native-screens": ">= 4.0.0" } }, - "node_modules/@react-navigation/native/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@react-navigation/routers": { "version": "7.5.3", "resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-7.5.3.tgz", @@ -3381,17 +3026,17 @@ } }, "node_modules/@react-navigation/stack": { - "version": "7.6.16", - "resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-7.6.16.tgz", - "integrity": "sha512-kYmogwU2jpxmjIrGO2P9PJCwgBHiju7OdItRkhFEHHppwU4jJQx/ViJtJ9ib3G4pqpurFdmqn1YsVB4bf7Zmxw==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-7.8.5.tgz", + "integrity": "sha512-ZOD1gUhWpbI+1PD5mKZFnLBh3Vfq2bqhO5/NeEruaQwNdXkiiHpi59OUKMnFRQURjjYXf/skTM9hJa6zHdiyFw==", "license": "MIT", "dependencies": { - "@react-navigation/elements": "^2.9.5", + "@react-navigation/elements": "^2.9.10", "color": "^4.2.3", "use-latest-callback": "^0.2.4" }, "peerDependencies": { - "@react-navigation/native": "^7.1.28", + "@react-navigation/native": "^7.1.33", "react": ">= 18.2.0", "react-native": "*", "react-native-gesture-handler": ">= 2.0.0", @@ -3400,9 +3045,9 @@ } }, "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "version": "0.27.10", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.10.tgz", + "integrity": "sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==", "license": "MIT" }, "node_modules/@sinonjs/commons": { @@ -3424,9 +3069,9 @@ } }, "node_modules/@supabase/auth-js": { - "version": "2.98.0", - "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.98.0.tgz", - "integrity": "sha512-GBH361T0peHU91AQNzOlIrjUZw9TZbB9YDRiyFgk/3Kvr3/Z1NWUZ2athWTfHhwNNi8IrW00foyFxQD9IO/Trg==", + "version": "2.99.1", + "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.99.1.tgz", + "integrity": "sha512-x7lKKTvKjABJt/FYcRSPiTT01Xhm2FF8RhfL8+RHMkmlwmRQ88/lREupIHKwFPW0W6pTCJqkZb7Yhpw/EZ+fNw==", "license": "MIT", "dependencies": { "tslib": "2.8.1" @@ -3436,9 +3081,9 @@ } }, "node_modules/@supabase/functions-js": { - "version": "2.98.0", - "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.98.0.tgz", - "integrity": "sha512-N/xEyiNU5Org+d+PNCpv+TWniAXRzxIURxDYsS/m2I/sfAB/HcM9aM2Dmf5edj5oWb9GxID1OBaZ8NMmPXL+Lg==", + "version": "2.99.1", + "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.99.1.tgz", + "integrity": "sha512-WQE62W5geYImCO4jzFxCk/avnK7JmOdtqu2eiPz3zOaNiIJajNRSAwMMDgEGd2EMs+sUVYj1LfBjfmW3EzHgIA==", "license": "MIT", "dependencies": { "tslib": "2.8.1" @@ -3448,9 +3093,9 @@ } }, "node_modules/@supabase/postgrest-js": { - "version": "2.98.0", - "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-2.98.0.tgz", - "integrity": "sha512-v6e9WeZuJijzUut8HyXu6gMqWFepIbaeaMIm1uKzei4yLg9bC9OtEW9O14LE/9ezqNbSAnSLO5GtOLFdm7Bpkg==", + "version": "2.99.1", + "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-2.99.1.tgz", + "integrity": "sha512-gtw2ibJrADvfqrpUWXGNlrYUvxttF4WVWfPpTFKOb2IRj7B6YRWMDgcrYqIuD4ZEabK4m6YKQCCGy6clgf1lPA==", "license": "MIT", "dependencies": { "tslib": "2.8.1" @@ -3460,9 +3105,9 @@ } }, "node_modules/@supabase/realtime-js": { - "version": "2.98.0", - "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.98.0.tgz", - "integrity": "sha512-rOWt28uGyFipWOSd+n0WVMr9kUXiWaa7J4hvyLCIHjRFqWm1z9CaaKAoYyfYMC1Exn3WT8WePCgiVhlAtWC2yw==", + "version": "2.99.1", + "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.99.1.tgz", + "integrity": "sha512-9EDdy/5wOseGFqxW88ShV9JMRhm7f+9JGY5x+LqT8c7R0X1CTLwg5qie8FiBWcXTZ+68yYxVWunI+7W4FhkWOg==", "license": "MIT", "dependencies": { "@types/phoenix": "^1.6.6", @@ -3474,31 +3119,10 @@ "node": ">=20.0.0" } }, - "node_modules/@supabase/realtime-js/node_modules/ws": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", - "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/@supabase/storage-js": { - "version": "2.98.0", - "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.98.0.tgz", - "integrity": "sha512-tzr2mG+v7ILSAZSfZMSL9OPyIH4z1ikgQ8EcQTKfMRz4EwmlFt3UnJaGzSOxyvF5b+fc9So7qdSUWTqGgeLokQ==", + "version": "2.99.1", + "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.99.1.tgz", + "integrity": "sha512-mf7zPfqofI62SOoyQJeNUVxe72E4rQsbWim6lTDPeLu3lHija/cP5utlQADGrjeTgOUN6znx/rWn7SjrETP1dw==", "license": "MIT", "dependencies": { "iceberg-js": "^0.8.1", @@ -3509,16 +3133,16 @@ } }, "node_modules/@supabase/supabase-js": { - "version": "2.98.0", - "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.98.0.tgz", - "integrity": "sha512-Ohc97CtInLwZyiSASz7tT9/Abm/vqnIbO9REp+PivVUII8UZsuI3bngRQnYgJdFoOIwvaEII1fX1qy8x0CyNiw==", + "version": "2.99.1", + "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.99.1.tgz", + "integrity": "sha512-5MRoYD9ffXq8F6a036dm65YoSHisC3by/d22mauKE99Vrwf792KxYIIr/iqCX7E4hkuugbPZ5EGYHTB7MKy6Vg==", "license": "MIT", "dependencies": { - "@supabase/auth-js": "2.98.0", - "@supabase/functions-js": "2.98.0", - "@supabase/postgrest-js": "2.98.0", - "@supabase/realtime-js": "2.98.0", - "@supabase/storage-js": "2.98.0" + "@supabase/auth-js": "2.99.1", + "@supabase/functions-js": "2.99.1", + "@supabase/postgrest-js": "2.99.1", + "@supabase/realtime-js": "2.99.1", + "@supabase/storage-js": "2.99.1" }, "engines": { "node": ">=20.0.0" @@ -3772,9 +3396,9 @@ } }, "node_modules/@tanstack/query-core": { - "version": "5.90.19", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.19.tgz", - "integrity": "sha512-GLW5sjPVIvH491VV1ufddnfldyVB+teCnpPIvweEfkpRx7CfUmUGhoh9cdcUKBh/KwVxk22aNEDxeTsvmyB/WA==", + "version": "5.90.20", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.20.tgz", + "integrity": "sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg==", "license": "MIT", "funding": { "type": "github", @@ -3782,12 +3406,12 @@ } }, "node_modules/@tanstack/react-query": { - "version": "5.90.19", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.19.tgz", - "integrity": "sha512-qTZRZ4QyTzQc+M0IzrbKHxSeISUmRB3RPGmao5bT+sI6ayxSRhn0FXEnT5Hg3as8SBFcRosrXXRFB+yAcxVxJQ==", + "version": "5.90.21", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.21.tgz", + "integrity": "sha512-0Lu6y5t+tvlTJMTO7oh5NSpJfpg/5D41LlThfepTixPYkJ0sE2Jj0m0f6yYqujBwIXlId87e234+MxG3D3g7kg==", "license": "MIT", "dependencies": { - "@tanstack/query-core": "5.90.19" + "@tanstack/query-core": "5.90.20" }, "funding": { "type": "github", @@ -3851,8 +3475,7 @@ "version": "2.0.46", "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.46.tgz", "integrity": "sha512-ynRvcq6wvqexJ9brDMS4BnBLzmr0e14d6ZJTEShTBWKymQiHwlAyGu0ZPEFI2Fh1U53F7tN9ufClWM5KvqkKOw==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", @@ -3879,12 +3502,12 @@ } }, "node_modules/@types/node": { - "version": "25.0.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.9.tgz", - "integrity": "sha512-/rpCXHlCWeqClNBwUhDcusJxXYDjZTyE8v5oTO7WbL8eij2nKhUeU89/6xgjU7N4/Vh3He0BtyhJdQbDyhiXAw==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.0.tgz", + "integrity": "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==", "license": "MIT", "dependencies": { - "undici-types": "~7.16.0" + "undici-types": "~7.18.0" } }, "node_modules/@types/phoenix": { @@ -3997,9 +3620,9 @@ } }, "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -4076,15 +3699,18 @@ } }, "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { - "color-convert": "^1.9.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/any-promise": { @@ -4135,116 +3761,46 @@ }, "node_modules/async-limiter": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "license": "MIT" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "license": "MIT" - }, - "node_modules/axios": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", - "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/babel-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", - "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", - "license": "MIT", - "dependencies": { - "@jest/transform": "^29.7.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.6.3", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "node_modules/babel-jest/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/babel-jest/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/babel-jest/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "license": "MIT" }, - "node_modules/babel-jest/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, - "node_modules/babel-jest/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/axios": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz", + "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==", "license": "MIT", - "engines": { - "node": ">=8" + "dependencies": { + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", + "proxy-from-env": "^1.1.0" } }, - "node_modules/babel-jest/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" } }, "node_modules/babel-plugin-istanbul": { @@ -4292,108 +3848,20 @@ "resolve": "^1.22.8" } }, - "node_modules/babel-plugin-module-resolver/node_modules/glob": { - "version": "9.3.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", - "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "minimatch": "^8.0.2", - "minipass": "^4.2.4", - "path-scurry": "^1.6.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/babel-plugin-module-resolver/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/babel-plugin-module-resolver/node_modules/minimatch": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", - "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/babel-plugin-module-resolver/node_modules/minipass": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", - "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-module-resolver/node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/babel-plugin-module-resolver/node_modules/path-scurry/node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", - "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==", + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.16.tgz", + "integrity": "sha512-xaVwwSfebXf0ooE11BJovZYKhFjIvQo7TsyVpETuIeH2JHv0k/T6Y5j22pPTvqYqmpkxdlPAJlyJ0tfOJAoMxw==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.27.7", - "@babel/helper-define-polyfill-provider": "^0.6.5", + "@babel/compat-data": "^7.28.6", + "@babel/helper-define-polyfill-provider": "^0.6.7", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/babel-plugin-polyfill-corejs3": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", @@ -4408,12 +3876,12 @@ } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz", - "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==", + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.7.tgz", + "integrity": "sha512-OTYbUlSwXhNgr4g6efMZgsO8//jA61P7ZbRX3iTT53VON8l+WQS8IAUEVo4a4cWknrg2W8Cj4gQhRYNCJ8GkAA==", "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.5" + "@babel/helper-define-polyfill-provider": "^0.6.7" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -4443,21 +3911,6 @@ "hermes-parser": "0.29.1" } }, - "node_modules/babel-plugin-syntax-hermes-parser/node_modules/hermes-estree": { - "version": "0.29.1", - "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.29.1.tgz", - "integrity": "sha512-jl+x31n4/w+wEqm0I2r4CMimukLbLQEYpisys5oCre611CI5fc9TxhqkBBCJ1edDG4Kza0f7CgNz8xVMLZQOmQ==", - "license": "MIT" - }, - "node_modules/babel-plugin-syntax-hermes-parser/node_modules/hermes-parser": { - "version": "0.29.1", - "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.29.1.tgz", - "integrity": "sha512-xBHWmUtRC5e/UL0tI7Ivt2riA/YBq9+SiYFU7C1oBa/j2jYGlIF9043oak1F47ihuDIxQ5nbsKueYJDRY02UgA==", - "license": "MIT", - "dependencies": { - "hermes-estree": "0.29.1" - } - }, "node_modules/babel-plugin-transform-flow-enums": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-enums/-/babel-plugin-transform-flow-enums-0.0.2.tgz", @@ -4579,12 +4032,15 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.9.15", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.15.tgz", - "integrity": "sha512-kX8h7K2srmDyYnXRIppo4AH/wYgzWVCs+eKr3RusRSQ5PvRYoEFmR/I0PbdTjKFAoKqp5+kbxnNTFO9jOfSVJg==", + "version": "2.10.7", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.7.tgz", + "integrity": "sha512-1ghYO3HnxGec0TCGBXiDLVns4eCSx4zJpxnHrlqFQajmhfKMQBzUGDdkMK7fUW7PTHTeLf+j87aTuKuuwWzMGw==", "license": "Apache-2.0", "bin": { - "baseline-browser-mapping": "dist/cli.js" + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" } }, "node_modules/better-opn": { @@ -4811,9 +4267,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001764", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001764.tgz", - "integrity": "sha512-9JGuzl2M+vPL+pz70gtMF9sHdMFbY9FJaQBi186cHKH3pSzDvzoUJUPV6fqiKIMyXbud9ZLg4F3Yza1vJ1+93g==", + "version": "1.0.30001778", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001778.tgz", + "integrity": "sha512-PN7uxFL+ExFJO61aVmP1aIEG4i9whQd4eoSCebav62UwDyp5OHh06zN4jqKSMePVgxHifCw1QJxdRkA1Pisekg==", "funding": [ { "type": "opencollective", @@ -4831,17 +4287,19 @@ "license": "CC-BY-4.0" }, "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/chokidar": { @@ -4907,18 +4365,6 @@ "node": ">=12.13.0" } }, - "node_modules/chrome-launcher/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/chromium-edge-launcher": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/chromium-edge-launcher/-/chromium-edge-launcher-0.2.0.tgz", @@ -4933,18 +4379,6 @@ "rimraf": "^3.0.2" } }, - "node_modules/chromium-edge-launcher/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", @@ -5012,18 +4446,21 @@ } }, "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { - "color-name": "1.1.3" + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/color-string": { @@ -5036,24 +4473,6 @@ "simple-swizzle": "^0.2.2" } }, - "node_modules/color/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -5076,13 +4495,12 @@ } }, "node_modules/comment-json": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.5.1.tgz", - "integrity": "sha512-taEtr3ozUmOB7it68Jll7s0Pwm+aoiHyXKrEC8SEodL4rNpdfDLqa7PfBlrgFoCNNdR8ImL+muti5IGvktJAAg==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.6.2.tgz", + "integrity": "sha512-R2rze/hDX30uul4NZoIZ76ImSJLFxn/1/ZxtKC1L77y2X1k+yYu1joKbAtMA2Fg3hZrTOiw0I5mwVMo0cf250w==", "license": "MIT", "dependencies": { "array-timsort": "^1.0.3", - "core-util-is": "^1.0.3", "esprima": "^4.0.1" }, "engines": { @@ -5186,24 +4604,18 @@ "license": "MIT" }, "node_modules/core-js-compat": { - "version": "3.47.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.47.0.tgz", - "integrity": "sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ==", + "version": "3.48.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.48.0.tgz", + "integrity": "sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q==", "license": "MIT", "dependencies": { - "browserslist": "^4.28.0" + "browserslist": "^4.28.1" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" } }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "license": "MIT" - }, "node_modules/cosmiconfig": { "version": "8.3.6", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", @@ -5274,15 +4686,6 @@ "node": ">= 8" } }, - "node_modules/crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/css-in-js-utils": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz", @@ -5625,9 +5028,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.267", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", - "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", + "version": "1.5.313", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.313.tgz", + "integrity": "sha512-QBMrTWEf00GXZmJyx2lbYD45jpI3TUFnNIzJ5BBc8piGUDwMPa1GV6HJWTZVvY/eiN3fSopl7NRbgGp9sZ9LTA==", "license": "ISC" }, "node_modules/emoji-regex": { @@ -5676,13 +5079,6 @@ "is-arrayish": "^0.2.1" } }, - "node_modules/error-ex/node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true, - "license": "MIT" - }, "node_modules/error-stack-parser": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", @@ -5753,12 +5149,15 @@ "license": "MIT" }, "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "license": "MIT", "engines": { - "node": ">=0.8.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/esprima": { @@ -5844,6 +5243,21 @@ } } }, + "node_modules/expo-asset": { + "version": "12.0.12", + "resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-12.0.12.tgz", + "integrity": "sha512-CsXFCQbx2fElSMn0lyTdRIyKlSXOal6ilLJd+yeZ6xaC7I9AICQgscY5nj0QcwgA+KYYCCEQEBndMsmj7drOWQ==", + "license": "MIT", + "dependencies": { + "@expo/image-utils": "^0.8.8", + "expo-constants": "~18.0.12" + }, + "peerDependencies": { + "expo": "*", + "react": "*", + "react-native": "*" + } + }, "node_modules/expo-auth-session": { "version": "7.0.10", "resolved": "https://registry.npmjs.org/expo-auth-session/-/expo-auth-session-7.0.10.tgz", @@ -5871,7 +5285,7 @@ "expo": "*" } }, - "node_modules/expo-auth-session/node_modules/expo-constants": { + "node_modules/expo-constants": { "version": "18.0.13", "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-18.0.13.tgz", "integrity": "sha512-FnZn12E1dRYKDHlAdIyNFhBurKTS3F9CrfrBDJI5m3D7U17KBHMQ6JEfYlSj7LG7t+Ulr+IKaj58L1k5gBwTcQ==", @@ -5948,6 +5362,16 @@ "expo": "*" } }, + "node_modules/expo-file-system": { + "version": "19.0.21", + "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-19.0.21.tgz", + "integrity": "sha512-s3DlrDdiscBHtab/6W1osrjGL+C2bvoInPJD7sOwmxfJ5Woynv2oc+Fz1/xVXaE/V7HE/+xrHC/H45tu6lZzzg==", + "license": "MIT", + "peerDependencies": { + "expo": "*", + "react-native": "*" + } + }, "node_modules/expo-font": { "version": "14.0.11", "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-14.0.11.tgz", @@ -5989,6 +5413,16 @@ "integrity": "sha512-duRT6oGl80IDzH2LD2yEFWNwGIC2WkozsB6HF3cDYNoNNdUvFk6uN3YiwsTsqVM/D0z6LEAQ01/SlYvN+Fw0JQ==", "license": "MIT" }, + "node_modules/expo-keep-awake": { + "version": "15.0.8", + "resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-15.0.8.tgz", + "integrity": "sha512-YK9M1VrnoH1vLJiQzChZgzDvVimVoriibiDIFLbQMpjYBnvyfUeHJcin/Gx1a+XgupNXy92EQJLgI/9ZuXajYQ==", + "license": "MIT", + "peerDependencies": { + "expo": "*", + "react": "*" + } + }, "node_modules/expo-linking": { "version": "8.0.11", "resolved": "https://registry.npmjs.org/expo-linking/-/expo-linking-8.0.11.tgz", @@ -6003,20 +5437,6 @@ "react-native": "*" } }, - "node_modules/expo-linking/node_modules/expo-constants": { - "version": "18.0.13", - "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-18.0.13.tgz", - "integrity": "sha512-FnZn12E1dRYKDHlAdIyNFhBurKTS3F9CrfrBDJI5m3D7U17KBHMQ6JEfYlSj7LG7t+Ulr+IKaj58L1k5gBwTcQ==", - "license": "MIT", - "dependencies": { - "@expo/config": "~12.0.13", - "@expo/env": "~2.0.8" - }, - "peerDependencies": { - "expo": "*", - "react-native": "*" - } - }, "node_modules/expo-manifests": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/expo-manifests/-/expo-manifests-1.0.10.tgz", @@ -6046,76 +5466,6 @@ "expo-modules-autolinking": "bin/expo-modules-autolinking.js" } }, - "node_modules/expo-modules-autolinking/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/expo-modules-autolinking/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/expo-modules-autolinking/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/expo-modules-autolinking/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/expo-modules-autolinking/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/expo-modules-autolinking/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/expo-modules-core": { "version": "3.0.29", "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-3.0.29.tgz", @@ -6266,46 +5616,25 @@ } } }, - "node_modules/expo/node_modules/@expo/vector-icons": { - "version": "15.0.3", - "resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-15.0.3.tgz", - "integrity": "sha512-SBUyYKphmlfUBqxSfDdJ3jAdEVSALS2VUPOUyqn48oZmb2TL/O7t7/PQm5v4NQujYEPLPMTLn9KVw6H7twwbTA==", - "license": "MIT", - "peerDependencies": { - "expo-font": ">=14.0.4", - "react": "*", - "react-native": "*" - } - }, - "node_modules/expo/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/expo/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "18 || 20 || >=22" } }, - "node_modules/expo/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/expo/node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "balanced-match": "^4.0.2" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": "18 || 20 || >=22" } }, "node_modules/expo/node_modules/ci-info": { @@ -6323,80 +5652,70 @@ "node": ">=8" } }, - "node_modules/expo/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", + "node_modules/expo/node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "license": "BlueOak-1.0.0", "dependencies": { - "color-name": "~1.1.4" + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" }, "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/expo/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/expo/node_modules/expo-asset": { - "version": "12.0.12", - "resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-12.0.12.tgz", - "integrity": "sha512-CsXFCQbx2fElSMn0lyTdRIyKlSXOal6ilLJd+yeZ6xaC7I9AICQgscY5nj0QcwgA+KYYCCEQEBndMsmj7drOWQ==", - "license": "MIT", - "dependencies": { - "@expo/image-utils": "^0.8.8", - "expo-constants": "~18.0.12" + "node": "18 || 20 || >=22" }, - "peerDependencies": { - "expo": "*", - "react": "*", - "react-native": "*" + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/expo/node_modules/expo-constants": { - "version": "18.0.13", - "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-18.0.13.tgz", - "integrity": "sha512-FnZn12E1dRYKDHlAdIyNFhBurKTS3F9CrfrBDJI5m3D7U17KBHMQ6JEfYlSj7LG7t+Ulr+IKaj58L1k5gBwTcQ==", - "license": "MIT", + "node_modules/expo/node_modules/glob/node_modules/minimatch": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "license": "BlueOak-1.0.0", "dependencies": { - "@expo/config": "~12.0.13", - "@expo/env": "~2.0.8" + "brace-expansion": "^5.0.2" }, - "peerDependencies": { - "expo": "*", - "react-native": "*" + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/expo/node_modules/expo-file-system": { - "version": "19.0.21", - "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-19.0.21.tgz", - "integrity": "sha512-s3DlrDdiscBHtab/6W1osrjGL+C2bvoInPJD7sOwmxfJ5Woynv2oc+Fz1/xVXaE/V7HE/+xrHC/H45tu6lZzzg==", - "license": "MIT", - "peerDependencies": { - "expo": "*", - "react-native": "*" + "node_modules/expo/node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" } }, - "node_modules/expo/node_modules/expo-keep-awake": { - "version": "15.0.8", - "resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-15.0.8.tgz", - "integrity": "sha512-YK9M1VrnoH1vLJiQzChZgzDvVimVoriibiDIFLbQMpjYBnvyfUeHJcin/Gx1a+XgupNXy92EQJLgI/9ZuXajYQ==", - "license": "MIT", - "peerDependencies": { - "expo": "*", - "react": "*" + "node_modules/expo/node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" } }, - "node_modules/expo/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", + "node_modules/expo/node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, "engines": { - "node": ">=8" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/expo/node_modules/picomatch": { @@ -6411,37 +5730,25 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/expo/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/expo/node_modules/react-refresh": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", + "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/expo/node_modules/ws": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", - "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" + "node_modules/expo/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } + "engines": { + "node": ">=10" } }, "node_modules/exponential-backoff": { @@ -6619,16 +5926,16 @@ } }, "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, "license": "MIT", "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "locate-path": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=6" } }, "node_modules/flow-enums-runtime": { @@ -6800,17 +6107,20 @@ } }, "node_modules/glob": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", - "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", - "license": "BlueOak-1.0.0", + "version": "9.3.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", + "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", "dependencies": { - "minimatch": "^10.1.1", - "minipass": "^7.1.2", - "path-scurry": "^2.0.0" + "fs.realpath": "^1.0.0", + "minimatch": "^8.0.2", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" }, "engines": { - "node": "20 || >=22" + "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -6829,30 +6139,19 @@ } }, "node_modules/glob/node_modules/minimatch": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", - "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", - "license": "BlueOak-1.0.0", + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.7.tgz", + "integrity": "sha512-V+1uQNdzybxa14e/p00HZnQNNcTjnRJjDxg2V8wtkjFctq4M7hXFws4oekyTP0Jebeq7QYtpFyOeBAjc88zvYg==", + "dev": true, + "license": "ISC", "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "20 || >=22" + "node": ">=16 || 14 >=14.17" }, "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/global-dirs": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", - "integrity": "sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==", - "license": "MIT", - "dependencies": { - "ini": "^1.3.4" - }, - "engines": { - "node": ">=4" + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/gopd": { @@ -6874,12 +6173,12 @@ "license": "ISC" }, "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/has-symbols": { @@ -6922,18 +6221,18 @@ } }, "node_modules/hermes-estree": { - "version": "0.32.0", - "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.32.0.tgz", - "integrity": "sha512-KWn3BqnlDOl97Xe1Yviur6NbgIZ+IP+UVSpshlZWkq+EtoHg6/cwiDj/osP9PCEgFE15KBm1O55JRwbMEm5ejQ==", + "version": "0.29.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.29.1.tgz", + "integrity": "sha512-jl+x31n4/w+wEqm0I2r4CMimukLbLQEYpisys5oCre611CI5fc9TxhqkBBCJ1edDG4Kza0f7CgNz8xVMLZQOmQ==", "license": "MIT" }, "node_modules/hermes-parser": { - "version": "0.32.0", - "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.32.0.tgz", - "integrity": "sha512-g4nBOWFpuiTqjR3LZdRxKUkij9iyveWeuks7INEsMX741f3r9xxrOe8TeQfUxtda0eXmiIFiMQzoeSQEno33Hw==", + "version": "0.29.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.29.1.tgz", + "integrity": "sha512-xBHWmUtRC5e/UL0tI7Ivt2riA/YBq9+SiYFU7C1oBa/j2jYGlIF9043oak1F47ihuDIxQ5nbsKueYJDRY02UgA==", "license": "MIT", "dependencies": { - "hermes-estree": "0.32.0" + "hermes-estree": "0.29.1" } }, "node_modules/hoist-non-react-statics": { @@ -6941,7 +6240,6 @@ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", "license": "BSD-3-Clause", - "peer": true, "dependencies": { "react-is": "^16.7.0" } @@ -6950,8 +6248,7 @@ "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/hosted-git-info": { "version": "7.0.2", @@ -7150,9 +6447,10 @@ } }, "node_modules/is-arrayish": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz", - "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, "license": "MIT" }, "node_modules/is-binary-path": { @@ -7288,15 +6586,6 @@ "node": ">=8" } }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/jest-environment-node": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", @@ -7345,323 +6634,99 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "node_modules/jest-message-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", - "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.6.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-message-util/node_modules/@babel/code-frame": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz", - "integrity": "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.28.5", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/jest-message-util/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-message-util/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-message-util/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-message-util/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-message-util/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-message-util/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-mock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", - "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-regex-util": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", - "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-util/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-util/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-util/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-util/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-util/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-util/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-util/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" + "fsevents": "^2.3.2" } }, - "node_modules/jest-validate": { + "node_modules/jest-message-util": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", - "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", "license": "MIT", "dependencies": { + "@babel/code-frame": "^7.12.13", "@jest/types": "^29.6.3", - "camelcase": "^6.2.0", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "leven": "^3.1.0", - "pretty-format": "^29.7.0" + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-validate/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-validate/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-validate/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">=7.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-validate/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-validate/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/jest-util/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/jest-validate/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-worker": { @@ -7679,15 +6744,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-worker/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/jest-worker/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -8112,15 +7168,17 @@ "license": "MIT" }, "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, "license": "MIT", "dependencies": { - "p-locate": "^4.1.0" + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=6" } }, "node_modules/lodash.debounce": { @@ -8147,6 +7205,77 @@ "node": ">=4" } }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, + "node_modules/log-symbols/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -8310,6 +7439,21 @@ "node": ">=20.19.4" } }, + "node_modules/metro-babel-transformer/node_modules/hermes-estree": { + "version": "0.32.0", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.32.0.tgz", + "integrity": "sha512-KWn3BqnlDOl97Xe1Yviur6NbgIZ+IP+UVSpshlZWkq+EtoHg6/cwiDj/osP9PCEgFE15KBm1O55JRwbMEm5ejQ==", + "license": "MIT" + }, + "node_modules/metro-babel-transformer/node_modules/hermes-parser": { + "version": "0.32.0", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.32.0.tgz", + "integrity": "sha512-g4nBOWFpuiTqjR3LZdRxKUkij9iyveWeuks7INEsMX741f3r9xxrOe8TeQfUxtda0eXmiIFiMQzoeSQEno33Hw==", + "license": "MIT", + "dependencies": { + "hermes-estree": "0.32.0" + } + }, "node_modules/metro-cache": { "version": "0.83.3", "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.83.3.tgz", @@ -8497,101 +7641,53 @@ "@babel/parser": "^7.25.3", "@babel/types": "^7.25.2", "flow-enums-runtime": "^0.0.6", - "metro": "0.83.3", - "metro-babel-transformer": "0.83.3", - "metro-cache": "0.83.3", - "metro-cache-key": "0.83.3", - "metro-minify-terser": "0.83.3", - "metro-source-map": "0.83.3", - "metro-transform-plugins": "0.83.3", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">=20.19.4" - } - }, - "node_modules/metro/node_modules/@babel/code-frame": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz", - "integrity": "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.28.5", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/metro/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/metro/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/metro/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" + "metro": "0.83.3", + "metro-babel-transformer": "0.83.3", + "metro-cache": "0.83.3", + "metro-cache-key": "0.83.3", + "metro-minify-terser": "0.83.3", + "metro-source-map": "0.83.3", + "metro-transform-plugins": "0.83.3", + "nullthrows": "^1.1.1" }, "engines": { - "node": ">=7.0.0" + "node": ">=20.19.4" } }, - "node_modules/metro/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "node_modules/metro/node_modules/hermes-estree": { + "version": "0.32.0", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.32.0.tgz", + "integrity": "sha512-KWn3BqnlDOl97Xe1Yviur6NbgIZ+IP+UVSpshlZWkq+EtoHg6/cwiDj/osP9PCEgFE15KBm1O55JRwbMEm5ejQ==", "license": "MIT" }, - "node_modules/metro/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/metro/node_modules/hermes-parser": { + "version": "0.32.0", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.32.0.tgz", + "integrity": "sha512-g4nBOWFpuiTqjR3LZdRxKUkij9iyveWeuks7INEsMX741f3r9xxrOe8TeQfUxtda0eXmiIFiMQzoeSQEno33Hw==", "license": "MIT", - "engines": { - "node": ">=8" + "dependencies": { + "hermes-estree": "0.32.0" } }, - "node_modules/metro/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/metro/node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, "engines": { - "node": ">=8" + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, "node_modules/micromatch": { @@ -8650,12 +7746,12 @@ } }, "node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -8674,12 +7770,13 @@ } }, "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "dev": true, "license": "ISC", "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=8" } }, "node_modules/minizlib": { @@ -8694,6 +7791,15 @@ "node": ">= 18" } }, + "node_modules/minizlib/node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -8742,14 +7848,14 @@ } }, "node_modules/nativewind": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/nativewind/-/nativewind-4.2.1.tgz", - "integrity": "sha512-10uUB2Dlli3MH3NDL5nMHqJHz1A3e/E6mzjTj6cl7hHECClJ7HpE6v+xZL+GXdbwQSnWE+UWMIMsNz7yOQkAJQ==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/nativewind/-/nativewind-4.2.2.tgz", + "integrity": "sha512-kUGbUamKUWdnAIjfBuhIrtDHFtMyL1pEE3AEbCuKeg656pHuB0KtJRk6Lrie/+8haj8hCSlwOleQFJLrE1sZgA==", "license": "MIT", "dependencies": { "comment-json": "^4.2.5", "debug": "^4.3.7", - "react-native-css-interop": "0.2.1" + "react-native-css-interop": "0.2.2" }, "engines": { "node": ">=16" @@ -8820,9 +7926,9 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", - "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "version": "2.0.36", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz", + "integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==", "license": "MIT" }, "node_modules/normalize-path": { @@ -8849,6 +7955,18 @@ "node": "^16.14.0 || >=18.0.0" } }, + "node_modules/npm-package-arg/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", @@ -8981,6 +8099,65 @@ "node": ">=6" } }, + "node_modules/ora/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ora/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/ora/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, + "node_modules/ora/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ora/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/ora/node_modules/strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", @@ -8993,6 +8170,18 @@ "node": ">=6" } }, + "node_modules/ora/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -9009,21 +8198,23 @@ } }, "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, "license": "MIT", "dependencies": { - "p-limit": "^2.2.0" + "p-limit": "^2.0.0" }, "engines": { - "node": ">=8" + "node": ">=6" } }, "node_modules/p-locate/node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, "license": "MIT", "dependencies": { "p-try": "^2.0.0" @@ -9105,12 +8296,13 @@ "license": "MIT" }, "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">=4" } }, "node_modules/path-is-absolute": { @@ -9138,28 +8330,37 @@ "license": "MIT" }, "node_modules/path-scurry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", - "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": "20 || >=22" + "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "11.2.4", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", - "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/path-scurry/node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, "license": "BlueOak-1.0.0", "engines": { - "node": "20 || >=22" + "node": ">=16 || 14 >=14.17" } }, "node_modules/path-type": { @@ -9221,72 +8422,6 @@ "node": ">=8" } }, - "node_modules/pkg-up/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-up/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/plist": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", @@ -9381,9 +8516,9 @@ } }, "node_modules/postcss-load-config": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", - "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz", + "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==", "funding": [ { "type": "opencollective", @@ -9396,21 +8531,28 @@ ], "license": "MIT", "dependencies": { - "lilconfig": "^3.0.0", - "yaml": "^2.3.4" + "lilconfig": "^3.1.1" }, "engines": { - "node": ">= 14" + "node": ">= 18" }, "peerDependencies": { + "jiti": ">=1.21.0", "postcss": ">=8.0.9", - "ts-node": ">=9.0.0" + "tsx": "^4.8.1", + "yaml": "^2.4.2" }, "peerDependenciesMeta": { + "jiti": { + "optional": true + }, "postcss": { "optional": true }, - "ts-node": { + "tsx": { + "optional": true + }, + "yaml": { "optional": true } } @@ -9497,6 +8639,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/pretty-format/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, "node_modules/proc-log": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", @@ -9650,6 +8798,27 @@ "ws": "^7" } }, + "node_modules/react-devtools-core/node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/react-dom": { "version": "19.1.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", @@ -9675,9 +8844,9 @@ } }, "node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.4.tgz", + "integrity": "sha512-W+EWGn2v0ApPKgKKCy/7s7WHXkboGcsrXE+2joLyVxkbyVQfO3MUEaUQDHoSmb8TFFrSKYa9mw64WZHNHSDzYA==", "license": "MIT" }, "node_modules/react-native": { @@ -9738,9 +8907,9 @@ } }, "node_modules/react-native-css-interop": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/react-native-css-interop/-/react-native-css-interop-0.2.1.tgz", - "integrity": "sha512-B88f5rIymJXmy1sNC/MhTkb3xxBej1KkuAt7TiT9iM7oXz3RM8Bn+7GUrfR02TvSgKm4cg2XiSuLEKYfKwNsjA==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/react-native-css-interop/-/react-native-css-interop-0.2.2.tgz", + "integrity": "sha512-2eUyl7RH1RT6TYbe5nm+d4HZ2Pr6Nmve158B57tb5W4Bo52Xzp+PFeWAdFnAr2HNB+r9b6qa8o3xH1YREVQU0g==", "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.22.15", @@ -9895,6 +9064,9 @@ "cpu": [ "arm64" ], + "libc": [ + "glibc" + ], "license": "MPL-2.0", "optional": true, "os": [ @@ -9915,6 +9087,9 @@ "cpu": [ "arm64" ], + "libc": [ + "musl" + ], "license": "MPL-2.0", "optional": true, "os": [ @@ -9935,6 +9110,9 @@ "cpu": [ "x64" ], + "libc": [ + "glibc" + ], "license": "MPL-2.0", "optional": true, "os": [ @@ -9955,6 +9133,9 @@ "cpu": [ "x64" ], + "libc": [ + "musl" + ], "license": "MPL-2.0", "optional": true, "os": [ @@ -10008,12 +9189,23 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/react-native-css-interop/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/react-native-gesture-handler": { - "version": "2.30.0", - "resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.30.0.tgz", - "integrity": "sha512-5YsnKHGa0X9C8lb5oCnKm0fLUPM6CRduvUUw2Bav4RIj/C3HcFh4RIUnF8wgG6JQWCL1//gRx4v+LVWgcIQdGA==", + "version": "2.28.0", + "resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.28.0.tgz", + "integrity": "sha512-0msfJ1vRxXKVgTgvL+1ZOoYw3/0z1R+Ked0+udoJhyplC2jbVKIJ8Z1bzWdpQRCV3QcQ87Op0zJVE5DhKK2A0A==", "license": "MIT", - "peer": true, "dependencies": { "@egjs/hammerjs": "^2.0.17", "hoist-non-react-statics": "^3.3.0", @@ -10025,9 +9217,9 @@ } }, "node_modules/react-native-is-edge-to-edge": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/react-native-is-edge-to-edge/-/react-native-is-edge-to-edge-1.2.1.tgz", - "integrity": "sha512-FLbPWl/MyYQWz+KwqOZsSyj2JmLKglHatd3xLZWskXOpRaio4LfEDEz8E/A6uD8QoTHW6Aobw1jbEwK7KMgR7Q==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/react-native-is-edge-to-edge/-/react-native-is-edge-to-edge-1.3.1.tgz", + "integrity": "sha512-NIXU/iT5+ORyCc7p0z2nnlkouYKX425vuU1OEm6bMMtWWR9yvb+Xg5AZmImTKoF9abxCPqrKC3rOZsKzUYgYZA==", "license": "MIT", "peerDependencies": { "react": "*", @@ -10045,9 +9237,9 @@ } }, "node_modules/react-native-reanimated": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-4.2.1.tgz", - "integrity": "sha512-/NcHnZMyOvsD/wYXug/YqSKw90P9edN0kEPL5lP4PFf1aQ4F1V7MKe/E0tvfkXKIajy3Qocp5EiEnlcrK/+BZg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-4.2.2.tgz", + "integrity": "sha512-o3kKvdD8cVlg12Z4u3jv0MFAt53QV4k7gD9OLwQqU8eZLyd8QvaOjVZIghMZhC2pjP93uUU44PlO5JgF8S4Vxw==", "license": "MIT", "peer": true, "dependencies": { @@ -10060,6 +9252,30 @@ "react-native-worklets": ">=0.7.0" } }, + "node_modules/react-native-reanimated/node_modules/react-native-is-edge-to-edge": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/react-native-is-edge-to-edge/-/react-native-is-edge-to-edge-1.2.1.tgz", + "integrity": "sha512-FLbPWl/MyYQWz+KwqOZsSyj2JmLKglHatd3xLZWskXOpRaio4LfEDEz8E/A6uD8QoTHW6Aobw1jbEwK7KMgR7Q==", + "license": "MIT", + "peer": true, + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, + "node_modules/react-native-reanimated/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "peer": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/react-native-safe-area-context": { "version": "5.6.2", "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-5.6.2.tgz", @@ -10162,9 +9378,9 @@ "license": "MIT" }, "node_modules/react-native-worklets": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/react-native-worklets/-/react-native-worklets-0.7.2.tgz", - "integrity": "sha512-DuLu1kMV/Uyl9pQHp3hehAlThoLw7Yk2FwRTpzASOmI+cd4845FWn3m2bk9MnjUw8FBRIyhwLqYm2AJaXDXsog==", + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/react-native-worklets/-/react-native-worklets-0.7.4.tgz", + "integrity": "sha512-NYOdM1MwBb3n+AtMqy1tFy3Mn8DliQtd8sbzAVRf9Gc+uvQ0zRfxN7dS8ZzoyX7t6cyQL5THuGhlnX+iFlQTag==", "license": "MIT", "peer": true, "dependencies": { @@ -10277,6 +9493,42 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/react-native-worklets/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "peer": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/react-native/node_modules/@react-native/virtualized-lists": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.81.5.tgz", + "integrity": "sha512-UVXgV/db25OPIvwZySeToXD/9sKKhOdkcWmmf4Jh8iBZuyfML+/5CasaZ1E7Lqg6g3uqVQq75NqIwkYmORJMPw==", + "license": "MIT", + "dependencies": { + "invariant": "^2.2.4", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 20.19.4" + }, + "peerDependencies": { + "@types/react": "^19.1.0", + "react": "*", + "react-native": "*" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/react-native/node_modules/brace-expansion": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", @@ -10300,7 +9552,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -10318,9 +9570,9 @@ } }, "node_modules/react-native/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -10329,6 +9581,27 @@ "node": "*" } }, + "node_modules/react-native/node_modules/react-refresh": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", + "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-native/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/react-native/node_modules/ws": { "version": "6.2.3", "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz", @@ -10339,10 +9612,11 @@ } }, "node_modules/react-refresh": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", - "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", + "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -10503,18 +9777,6 @@ "node": ">=8" } }, - "node_modules/resolve-global": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-global/-/resolve-global-1.0.0.tgz", - "integrity": "sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==", - "license": "MIT", - "dependencies": { - "global-dirs": "^0.1.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/resolve-workspace-root": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/resolve-workspace-root/-/resolve-workspace-root-2.0.1.tgz", @@ -10583,7 +9845,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -10601,9 +9863,9 @@ } }, "node_modules/rimraf/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -10671,15 +9933,12 @@ "license": "MIT" }, "node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "license": "ISC", "bin": { "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" } }, "node_modules/send": { @@ -10864,6 +10123,12 @@ "is-arrayish": "^0.3.1" } }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz", + "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==", + "license": "MIT" + }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -11096,15 +10361,15 @@ } }, "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/supports-hyperlinks": { @@ -11120,27 +10385,6 @@ "node": ">=8" } }, - "node_modules/supports-hyperlinks/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -11208,9 +10452,9 @@ "license": "CC0-1.0" }, "node_modules/tailwindcss": { - "version": "3.4.17", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", - "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.19.tgz", + "integrity": "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==", "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", @@ -11221,7 +10465,7 @@ "fast-glob": "^3.3.2", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", - "jiti": "^1.21.6", + "jiti": "^1.21.7", "lilconfig": "^3.1.3", "micromatch": "^4.0.8", "normalize-path": "^3.0.0", @@ -11230,7 +10474,7 @@ "postcss": "^8.4.47", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.2", + "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", "postcss-nested": "^6.2.0", "postcss-selector-parser": "^6.1.2", "resolve": "^1.22.8", @@ -11260,6 +10504,15 @@ "node": ">=18" } }, + "node_modules/tar/node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/tar/node_modules/yallist": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", @@ -11269,15 +10522,6 @@ "node": ">=18" } }, - "node_modules/temp-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", - "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", @@ -11346,7 +10590,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -11364,9 +10608,9 @@ } }, "node_modules/test-exclude/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -11560,9 +10804,9 @@ } }, "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", "license": "MIT" }, "node_modules/unicode-canonical-property-names-ecmascript": { @@ -11605,18 +10849,6 @@ "node": ">=4" } }, - "node_modules/unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "license": "MIT", - "dependencies": { - "crypto-random-string": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -11747,13 +10979,10 @@ } }, "node_modules/webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=8" - } + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" }, "node_modules/whatwg-fetch": { "version": "3.6.20", @@ -11785,11 +11014,14 @@ "node": ">=10" } }, - "node_modules/whatwg-url/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause" + "node_modules/whatwg-url-without-unicode/node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=8" + } }, "node_modules/which": { "version": "2.0.2", @@ -11829,39 +11061,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -11882,16 +11081,16 @@ } }, "node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", + "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", "license": "MIT", "engines": { - "node": ">=8.3.0" + "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -12016,9 +11215,9 @@ } }, "node_modules/zustand": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.10.tgz", - "integrity": "sha512-U1AiltS1O9hSy3rul+Ub82ut2fqIAefiSuwECWt6jlMVUGejvf+5omLcRBSzqbRagSM3hQZbtzdeRc6QVScXTg==", + "version": "5.0.11", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.11.tgz", + "integrity": "sha512-fdZY+dk7zn/vbWNCYmzZULHRrss0jx5pPFiOuMZ/5HJN6Yv3u+1Wswy/4MpZEkEGhtNH+pwxZB8OKgUBPzYAGg==", "license": "MIT", "engines": { "node": ">=12.20.0" diff --git a/package.json b/package.json index 1268f8d..17a72f6 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "react": "19.1.0", "react-dom": "19.1.0", "react-native": "0.81.5", + "react-native-gesture-handler": "~2.28.0", "react-native-pager-view": "6.9.1", "react-native-safe-area-context": "~5.6.0", "react-native-screens": "~4.16.0", From 9c0f17680298505b33b705cf26a0772cb59fd845 Mon Sep 17 00:00:00 2001 From: lejuho Date: Fri, 13 Mar 2026 14:47:43 +0900 Subject: [PATCH 24/92] =?UTF-8?q?refactor:=20=EA=B3=B5=ED=86=B5=20?= =?UTF-8?q?=ED=97=A4=EB=8D=94=20=EC=95=A1=EC=85=98=20=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=95=84=EC=9B=83=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/ScreenHeader.tsx | 40 +++++++++++++++++--------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/components/common/ScreenHeader.tsx b/src/components/common/ScreenHeader.tsx index b1a73c0..0f0206f 100644 --- a/src/components/common/ScreenHeader.tsx +++ b/src/components/common/ScreenHeader.tsx @@ -1,5 +1,4 @@ import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; -import { LeftIcon } from "@/assets/icons/CommonIcons"; type Props = { title: string; @@ -9,44 +8,59 @@ type Props = { export default function ScreenHeader({ title, onBack }: Props) { return ( - {/* Preserve title centering even on screens that do not expose a back action. */} {onBack ? ( - + ) : ( )} {title} - + + 완료 + ); } const styles = StyleSheet.create({ header: { - height: 56, + height: 52, flexDirection: "row", alignItems: "center", justifyContent: "space-between", - paddingHorizontal: 12, - borderBottomWidth: 1, - borderBottomColor: "#E5E7EB", + paddingHorizontal: 16, backgroundColor: "#FFFFFF", + borderBottomWidth: StyleSheet.hairlineWidth, + borderBottomColor: "#E5E7EB", }, sideButton: { - width: 24, - height: 24, + width: 48, + height: 44, justifyContent: "center", alignItems: "center", }, - title: { + closeText: { fontSize: 18, - fontWeight: "700", + color: "#374151", + }, + completeText: { + fontSize: 16, + fontWeight: "600", + color: "#374151", + textAlign: "right", + }, + title: { + fontSize: 17, + fontWeight: "600", color: "#171717", }, -}); +}); \ No newline at end of file From 1bac18a66cc4d7cb8fc78e86075553db326b5939 Mon Sep 17 00:00:00 2001 From: lejuho Date: Fri, 13 Mar 2026 14:47:55 +0900 Subject: [PATCH 25/92] =?UTF-8?q?refactor:=20=EC=9D=BC=EA=B8=B0=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1=20=EC=9E=85=EB=A0=A5=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EC=8A=A4=ED=83=80=EC=9D=BC=20=EC=A1=B0?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dailyMission/ImageAttachmentCard.tsx | 86 +++++++------------ .../registration/RegistrationTextField.tsx | 48 +++++++---- 2 files changed, 63 insertions(+), 71 deletions(-) diff --git a/src/components/dailyMission/ImageAttachmentCard.tsx b/src/components/dailyMission/ImageAttachmentCard.tsx index aeecd3a..a2d4479 100644 --- a/src/components/dailyMission/ImageAttachmentCard.tsx +++ b/src/components/dailyMission/ImageAttachmentCard.tsx @@ -15,28 +15,27 @@ export default function ImageAttachmentCard({ }: Props) { return ( - 이미지 첨부 {imageUrl ? ( - + ) : ( - + + 📷 + 화분을 예쁘게 가꾸고 + + 친구들에게 멋진 식물을 자랑해보아요! + )} - - {imageUrl ? "선택한 이미지" : "이미지를 선택해주세요"} - - {imageUrl - ? "다시 누르면 다른 이미지로 바꿀 수 있습니다." - : "사진첩에서 일기에 첨부할 이미지를 고를 수 있습니다."} - - {helperText ? {helperText} : null} @@ -47,61 +46,40 @@ const styles = StyleSheet.create({ container: { gap: 8, }, - label: { - fontSize: 14, - fontWeight: "600", - color: "#374151", - }, - card: { - borderRadius: 20, - borderWidth: 1, - borderColor: "#D1D5DB", - padding: 16, - gap: 14, - backgroundColor: "#FFFFFF", + imageArea: { + width: "100%", + borderRadius: 16, + overflow: "hidden", + backgroundColor: "#EDEDED", }, - cardDisabled: { - backgroundColor: "#F9FAFB", + imageAreaDisabled: { + opacity: 0.6, }, previewImage: { width: "100%", - height: 180, - borderRadius: 16, - backgroundColor: "#E5E7EB", + height: 260, }, placeholderBox: { - width: "100%", - height: 180, - borderRadius: 16, - borderWidth: 1, - borderStyle: "dashed", - borderColor: "#D1D5DB", - backgroundColor: "#F9FAFB", + height: 260, alignItems: "center", justifyContent: "center", + gap: 8, }, - placeholderPlus: { - fontSize: 34, - lineHeight: 36, - color: "#9CA3AF", - fontWeight: "400", - }, - textBlock: { - gap: 6, - }, - title: { - fontSize: 15, - fontWeight: "700", - color: "#171717", + cameraIcon: { + fontSize: 32, + marginBottom: 4, + opacity: 0.45, }, - description: { + placeholderText: { fontSize: 13, - lineHeight: 18, - color: "#6B7280", + color: "#9CA3AF", + lineHeight: 20, + textAlign: "center", }, helperText: { fontSize: 12, lineHeight: 18, color: "#92400E", + paddingHorizontal: 4, }, -}); +}); \ No newline at end of file diff --git a/src/components/registration/RegistrationTextField.tsx b/src/components/registration/RegistrationTextField.tsx index 653af99..9b11a1c 100644 --- a/src/components/registration/RegistrationTextField.tsx +++ b/src/components/registration/RegistrationTextField.tsx @@ -19,14 +19,18 @@ export default function RegistrationTextField({ }: Props) { return ( - {label} + {label ? {label} : null} {helperText ? {helperText} : null} @@ -36,31 +40,41 @@ export default function RegistrationTextField({ const styles = StyleSheet.create({ container: { - gap: 8, + gap: 2, }, label: { - fontSize: 14, - fontWeight: "600", - color: "#374151", + fontSize: 12, + fontWeight: "500", + color: "#9CA3AF", + letterSpacing: 0.2, + marginBottom: 2, }, input: { - minHeight: 52, - borderWidth: 1, - borderColor: "#D1D5DB", - borderRadius: 14, - paddingHorizontal: 14, fontSize: 15, color: "#171717", - backgroundColor: "#FFFFFF", + backgroundColor: "transparent", + paddingHorizontal: 0, + paddingVertical: 10, + }, + titleInput: { + fontSize: 26, + fontWeight: "400", + letterSpacing: -0.3, + paddingVertical: 6, + }, + singleLine: { + borderBottomWidth: StyleSheet.hairlineWidth, + borderBottomColor: "#E0E0E0", }, multiline: { - minHeight: 110, - paddingTop: 14, - paddingBottom: 14, + minHeight: 80, + lineHeight: 24, + fontSize: 15, + color: "#374151", }, helperText: { fontSize: 12, lineHeight: 18, color: "#6B7280", }, -}); +}); \ No newline at end of file From 1363249e58fa40b9a3ead7af71254a525cd3ed9d Mon Sep 17 00:00:00 2001 From: lejuho Date: Fri, 13 Mar 2026 14:53:07 +0900 Subject: [PATCH 26/92] =?UTF-8?q?fix:=20=EC=99=84=EB=A3=8C=EB=90=9C=20?= =?UTF-8?q?=EB=A7=88=EC=9D=8C=20=EA=B1=B4=EA=B0=95=20=EC=B2=B4=ED=81=AC=20?= =?UTF-8?q?=EB=AF=B8=EC=85=98=20=ED=84=B0=EC=B9=98=20=EB=B9=84=ED=99=9C?= =?UTF-8?q?=EC=84=B1=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/home/HomeBottomSheet.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/home/HomeBottomSheet.tsx b/src/components/home/HomeBottomSheet.tsx index 7d1a073..d1bc0fa 100644 --- a/src/components/home/HomeBottomSheet.tsx +++ b/src/components/home/HomeBottomSheet.tsx @@ -101,12 +101,14 @@ export default function HomeBottomSheet({ key: string; label: string; checked: boolean; + disabled?: boolean; onPress: () => void; }> = [ { key: "checking", label: "마음 건강 체크", checked: panel?.isCheckingCompleted ?? (checkingMission ? getMissionCompleted(checkingMission) : false), + disabled: panel?.isCheckingCompleted ?? (checkingMission ? getMissionCompleted(checkingMission) : false), onPress: onPressEmotionCheck, }, { @@ -157,8 +159,9 @@ export default function HomeBottomSheet({ {missionCards.map(card => ( From 1b6ab800306daca7407ff6a258a165bcffa02aed Mon Sep 17 00:00:00 2001 From: lejuho Date: Fri, 13 Mar 2026 15:03:32 +0900 Subject: [PATCH 27/92] =?UTF-8?q?feat:=20=EC=86=8C=EB=A7=9D=20=EB=82=98?= =?UTF-8?q?=EB=AC=B4=20=EC=A7=84=ED=96=89=EB=8F=84=20=EA=B2=8C=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EC=A0=95=EB=B3=B4=20=EB=B3=B4=EA=B0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/home/HomeBottomSheet.tsx | 55 +++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/src/components/home/HomeBottomSheet.tsx b/src/components/home/HomeBottomSheet.tsx index d1bc0fa..29540b5 100644 --- a/src/components/home/HomeBottomSheet.tsx +++ b/src/components/home/HomeBottomSheet.tsx @@ -96,6 +96,9 @@ export default function HomeBottomSheet({ const progressPercent = panel?.wishTree.progressPercent ?? 0; const currentStage = panel?.wishTree.currentStage ?? `LV.${currentLevel}`; const nextStage = panel?.wishTree.nextStage ?? `LV.${currentLevel + 1}`; + const currentGrowthPoints = panel?.wishTree.currentPoints ?? 0; + const requiredGrowthPoints = panel?.wishTree.requiredPointsForNextStage ?? 0; + const remainingGrowthPoints = Math.max(requiredGrowthPoints - currentGrowthPoints, 0); const missionCards: Array<{ key: string; @@ -195,6 +198,22 @@ export default function HomeBottomSheet({ + + + 현재 성장 + + {currentGrowthPoints} + / {requiredGrowthPoints} + + + + 다음 성장까지 + + {remainingGrowthPoints} + 남음 + + + @@ -397,15 +416,45 @@ const styles = StyleSheet.create({ }, progressTrack: { marginTop: 10, - height: 8, + height: 12, borderRadius: 999, - backgroundColor: "#E5E7EB", + backgroundColor: "#E7EEE1", overflow: "hidden", + borderWidth: 1, + borderColor: "#D6E4CD", }, progressFill: { height: "100%", borderRadius: 999, - backgroundColor: "#7DC960", + backgroundColor: "#6FBE57", + }, + progressMetaRow: { + marginTop: 12, + flexDirection: "row", + gap: 8, + }, + progressMetaCard: { + flex: 1, + borderRadius: 12, + backgroundColor: "#F5F9F0", + paddingHorizontal: 12, + paddingVertical: 10, + gap: 4, + }, + progressMetaLabel: { + fontSize: 12, + color: "#6B7280", + fontWeight: "600", + }, + progressMetaValue: { + fontSize: 16, + color: "#2E5134", + fontWeight: "700", + }, + progressMetaUnit: { + fontSize: 13, + color: "#6B7280", + fontWeight: "600", }, quickLinksRow: { marginTop: 18, From 1b848382326718a04845e2117017b51ff08232a7 Mon Sep 17 00:00:00 2001 From: lejuho Date: Fri, 13 Mar 2026 15:08:44 +0900 Subject: [PATCH 28/92] =?UTF-8?q?fix:=20=ED=99=88=20=EB=AF=B8=EC=85=98=20?= =?UTF-8?q?=ED=8C=A8=EB=84=90=20=ED=99=95=EC=9E=A5=20=EB=86=92=EC=9D=B4?= =?UTF-8?q?=EC=99=80=20=EB=82=B4=EB=B6=80=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20?= =?UTF-8?q?=EB=B3=B4=EC=99=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/home/HomeBottomSheet.tsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/components/home/HomeBottomSheet.tsx b/src/components/home/HomeBottomSheet.tsx index 29540b5..4117d1d 100644 --- a/src/components/home/HomeBottomSheet.tsx +++ b/src/components/home/HomeBottomSheet.tsx @@ -3,6 +3,7 @@ import { Animated, PanResponder, Pressable, + ScrollView, StyleSheet, Text, TouchableOpacity, @@ -13,7 +14,7 @@ import { getMissionCompleted, type TodayMission } from "@/types/home/garden"; import type { HomePanelPayload } from "@/types/home/panel"; const COLLAPSED_HEIGHT = 104; -const EXPANDED_HEIGHT = 430; +const EXPANDED_HEIGHT = 580; const DRAG_RANGE = EXPANDED_HEIGHT - COLLAPSED_HEIGHT; export default function HomeBottomSheet({ @@ -152,7 +153,12 @@ export default function HomeBottomSheet({ - + {/* * 한글 주석: * 접힌 상태에서는 오늘의 미션 제목과 진행도만 위로 남기고, @@ -220,7 +226,7 @@ export default function HomeBottomSheet({ - + @@ -278,6 +284,7 @@ const styles = StyleSheet.create({ paddingHorizontal: 16, paddingTop: 6, paddingBottom: 30, + overflow: "hidden", shadowColor: "#000000", shadowOpacity: 0.12, shadowRadius: 10, From 560f1740d03990f50f8aa075337cfb4367093f6e Mon Sep 17 00:00:00 2001 From: lejuho Date: Fri, 13 Mar 2026 15:11:51 +0900 Subject: [PATCH 29/92] =?UTF-8?q?refactor:=20=ED=99=88=20=EB=AF=B8?= =?UTF-8?q?=EC=85=98=20=ED=8C=A8=EB=84=90=20=ED=80=B5=EB=A7=81=ED=81=AC=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/home/HomeBottomSheet.tsx | 38 ++----------------------- src/pages/home/HomeScreen.tsx | 3 -- 2 files changed, 3 insertions(+), 38 deletions(-) diff --git a/src/components/home/HomeBottomSheet.tsx b/src/components/home/HomeBottomSheet.tsx index 4117d1d..a69ea33 100644 --- a/src/components/home/HomeBottomSheet.tsx +++ b/src/components/home/HomeBottomSheet.tsx @@ -23,9 +23,6 @@ export default function HomeBottomSheet({ missions, panel, currentLevel, - onPressLog, - onPressFeed, - onPressUnlockGarden, onPressMission, onPressEmotionCheck, }: { @@ -34,9 +31,6 @@ export default function HomeBottomSheet({ missions: TodayMission[]; panel?: HomePanelPayload; currentLevel: number; - onPressLog: () => void; - onPressFeed: () => void; - onPressUnlockGarden: () => void; onPressMission: (mission: TodayMission) => void; onPressEmotionCheck: () => void; }) { @@ -221,11 +215,7 @@ export default function HomeBottomSheet({ - - - - - + @@ -233,13 +223,6 @@ export default function HomeBottomSheet({ ); } -function QuickLink({ label, onPress }: { label: string; onPress: () => void }) { - return ( - - {label} - - ); -} function MissionStatusDot({ checked }: { checked: boolean }) { return ( @@ -258,18 +241,7 @@ const styles = StyleSheet.create({ ...StyleSheet.absoluteFillObject, backgroundColor: "rgba(12, 18, 14, 0.10)", }, - quickLink: { - flex: 1, - borderRadius: 14, - backgroundColor: "#EEF3EA", - paddingVertical: 12, - alignItems: "center", - }, - quickLinkText: { - fontSize: 13, - color: "#2E5134", - fontWeight: "700", - }, + sheetWrap: { height: EXPANDED_HEIGHT, }, @@ -463,9 +435,5 @@ const styles = StyleSheet.create({ color: "#6B7280", fontWeight: "600", }, - quickLinksRow: { - marginTop: 18, - flexDirection: "row", - gap: 8, - }, + }); diff --git a/src/pages/home/HomeScreen.tsx b/src/pages/home/HomeScreen.tsx index dc4daff..90a6391 100644 --- a/src/pages/home/HomeScreen.tsx +++ b/src/pages/home/HomeScreen.tsx @@ -193,9 +193,6 @@ export default function HomeScreen({ navigation }: Props) { missions={todayMissions} panel={panel} currentLevel={userInfo?.level ?? 0} - onPressLog={() => navigation.navigate("Log")} - onPressFeed={() => navigation.navigate("Feed")} - onPressUnlockGarden={() => navigation.navigate("UnlockGarden")} onPressMission={mission => { /* * 한글 주석: From 3041d0119d9f560901f0ccd5788f65bb7767c39f Mon Sep 17 00:00:00 2001 From: lejuho Date: Fri, 13 Mar 2026 15:15:25 +0900 Subject: [PATCH 30/92] =?UTF-8?q?fix:=20=ED=99=88=20=EC=95=A1=EC=85=98=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20SVG=20=EC=A0=95=EB=A0=AC=20=EB=B3=B4?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/home/HomeGardenScene.tsx | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/components/home/HomeGardenScene.tsx b/src/components/home/HomeGardenScene.tsx index 32c9793..5aa7934 100644 --- a/src/components/home/HomeGardenScene.tsx +++ b/src/components/home/HomeGardenScene.tsx @@ -172,9 +172,7 @@ export default function HomeGardenScene({ style={styles.actionButton} disabled={sunlightMutation.isPending} > - - - + - - - + ) : null} @@ -304,14 +300,11 @@ const styles = StyleSheet.create({ actionButton: { width: 64, height: 64, + borderRadius: 32, + backgroundColor: "rgba(255,255,255,0.18)", alignItems: "center", justifyContent: "center", - }, - actionIconWrap: { - width: 64, - height: 64, - alignItems: "center", - justifyContent: "center", + overflow: "hidden", }, lockedOverlay: { flex: 1, From cf76acd3159e0c22c064e57f2a071b46c43574b0 Mon Sep 17 00:00:00 2001 From: lejuho Date: Fri, 13 Mar 2026 15:28:51 +0900 Subject: [PATCH 31/92] =?UTF-8?q?fix:=20=EB=AC=BC=EC=A3=BC=EA=B8=B0=20?= =?UTF-8?q?=EC=97=B0=EC=B6=9C=20=EC=9C=84=EC=B9=98=EB=A5=BC=20=EC=8B=9D?= =?UTF-8?q?=EB=AC=BC=20=EC=99=BC=EC=AA=BD=20=EC=83=81=EB=8B=A8=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/home/HomeAvatarStage.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/components/home/HomeAvatarStage.tsx b/src/components/home/HomeAvatarStage.tsx index d638b8c..e229d05 100644 --- a/src/components/home/HomeAvatarStage.tsx +++ b/src/components/home/HomeAvatarStage.tsx @@ -118,8 +118,14 @@ const styles = StyleSheet.create({ }, wateringImage: { position: "absolute", - left: "36%", - bottom: 132, + + /* + * 한글 주석: + * 물뿌리개와 물방울 연출은 식물 중앙이 아니라 + * 식물의 왼쪽 70% 높이 부근에서 시작하도록 고정 위치를 옮긴다. + */ + left: "18%", + bottom: 168, width: 118, height: 118, }, From 6fa72fce083755246e343ca34e9b2829a3cc2d1b Mon Sep 17 00:00:00 2001 From: lejuho Date: Fri, 13 Mar 2026 15:38:38 +0900 Subject: [PATCH 32/92] =?UTF-8?q?feat:=20=EB=B9=84=EB=91=98=EA=B8=B0=20?= =?UTF-8?q?=ED=8A=B8=EB=9E=98=ED=82=B9=20=EB=AA=A8=EB=8B=AC=EC=9D=84=202?= =?UTF-8?q?=EC=A3=BC=20=EC=99=84=EC=88=98=20=EC=A1=B0=EA=B1=B4=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/home/homeApi.ts | 6 ++++++ src/components/home/HomeTrackingModal.tsx | 23 ++++++++++++++++----- src/hooks/home/useHomeApi.ts | 7 +++++++ src/pages/home/HomeScreen.tsx | 25 ++++++++++++++++++++--- src/types/home/tracking.ts | 6 ++++++ 5 files changed, 59 insertions(+), 8 deletions(-) create mode 100644 src/types/home/tracking.ts diff --git a/src/apis/home/homeApi.ts b/src/apis/home/homeApi.ts index 84c4123..5b39895 100644 --- a/src/apis/home/homeApi.ts +++ b/src/apis/home/homeApi.ts @@ -5,6 +5,7 @@ import { type HomeSummaryPayload, } from "@/types/home/garden"; import type { HomePanelPayload } from "@/types/home/panel"; +import type { TrackingReportPayload } from "@/types/home/tracking"; export const getHomeSummary = async (): ApiResponse => { const res = await api.get("/api/v1/home"); @@ -20,6 +21,11 @@ export const getHomePanel = async (): ApiResponse => { return res.data; }; +export const getTrackingReport = async (): ApiResponse => { + const res = await api.get("/api/v1/tracking/report"); + return res.data; +}; + export const postGardenSunlight = async (gardenId: number) => { const res = await api.post(`/api/v1/gardens/${gardenId}/sunlight`); return res.data; diff --git a/src/components/home/HomeTrackingModal.tsx b/src/components/home/HomeTrackingModal.tsx index f586ea9..f1b81fa 100644 --- a/src/components/home/HomeTrackingModal.tsx +++ b/src/components/home/HomeTrackingModal.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useEffect, useState } from "react"; import { Image, Modal, @@ -8,19 +8,32 @@ import { TouchableOpacity, View, } from "react-native"; +import type { TrackingReportPayload } from "@/types/home/tracking"; const trackingImage = require("@/assets/images/tracking.webp"); const characterImage = require("@/assets/images/char.webp"); export default function HomeTrackingModal({ visible, + report, onClose, }: { visible: boolean; + report: TrackingReportPayload | null; onClose: () => void; }) { const [liked, setLiked] = useState(true); + useEffect(() => { + if (visible) { + setLiked(true); + } + }, [visible]); + + if (!report) { + return null; + } + return ( @@ -31,7 +44,9 @@ export default function HomeTrackingModal({ <> - 2주동안 12일 식물을 키우셨습니다!{"\n"}열심히 노력하셨군요{"\n"}앞으로도 같이 열심히 키워봐요! + 2주동안 {report.praiseDayCount}일 물과 햇빛을 모두 챙기셨어요!{"\n"} + 열심히 돌봐주셨군요{"\n"} + 앞으로도 같이 잘 키워봐요! setLiked(false)}> 좋아요 @@ -40,9 +55,7 @@ export default function HomeTrackingModal({ ) : ( <> - - 힘든 순간도 결국 지나갑니다.{"\n"}마음도 한결 가벼워질 날이 올 거에요!{"\n"}그때까지 제가 함께하겠습니다. - + {report.message} 고마워요 diff --git a/src/hooks/home/useHomeApi.ts b/src/hooks/home/useHomeApi.ts index a99a65d..4cda228 100644 --- a/src/hooks/home/useHomeApi.ts +++ b/src/hooks/home/useHomeApi.ts @@ -3,12 +3,14 @@ import type { AxiosError } from "axios"; import { getHomePanel, getHomeSummary, + getTrackingReport, postGardenMyWater, postGardenSunlight, } from "@/apis/home/homeApi"; import type { GlobalResponse } from "@/types/common/apiResponse.type"; import type { HomeSummaryPayload } from "@/types/home/garden"; import type { HomePanelPayload } from "@/types/home/panel"; +import type { TrackingReportPayload } from "@/types/home/tracking"; export const useHomeApi = () => useQuery< @@ -30,6 +32,11 @@ export const useHomePanelApi = () => refetchOnMount: "always", }); +export const useTrackingReport = () => + useMutation, AxiosError>({ + mutationFn: getTrackingReport, + }); + export const useGardenSunlightAction = () => { const queryClient = useQueryClient(); diff --git a/src/pages/home/HomeScreen.tsx b/src/pages/home/HomeScreen.tsx index 90a6391..b702721 100644 --- a/src/pages/home/HomeScreen.tsx +++ b/src/pages/home/HomeScreen.tsx @@ -8,7 +8,7 @@ import HomeGardenScene from "@/components/home/HomeGardenScene"; import HomeMapModal from "@/components/home/HomeMapModal"; import HomeTrackingModal from "@/components/home/HomeTrackingModal"; import StatusView from "@/components/common/StatusView"; -import useHomeApi, { useHomePanelApi } from "@/hooks/home/useHomeApi"; +import useHomeApi, { useHomePanelApi, useTrackingReport } from "@/hooks/home/useHomeApi"; import { useDailySurvey } from "@/hooks/mission/useMissionApi"; import type { MainTabScreenProps } from "@/navigation/types"; import { useEmotionSurveyStore, getEmotionSurveyCooldownActive } from "@/stores/useEmotionSurveyStore"; @@ -19,6 +19,7 @@ import { type HomeMissionType, type TodayMission, } from "@/types/home/garden"; +import type { TrackingReportPayload } from "@/types/home/tracking"; import type { SurveyAnswerKind } from "@/types/missions"; import { debugLog, debugScreenMounted } from "@/utils/debug"; @@ -42,6 +43,7 @@ export default function HomeScreen({ navigation }: Props) { const { data, error, isLoading, refetch } = useHomeApi(); const { data: panel } = useHomePanelApi(); const surveyQuery = useDailySurvey(); + const trackingReport = useTrackingReport(); const { user, gardens, missions, todayDiaryId, hydrate } = useHomeSummaryStore(); const { lastAnsweredAt, @@ -55,6 +57,7 @@ export default function HomeScreen({ navigation }: Props) { const [isTrackingModalOpen, setIsTrackingModalOpen] = useState(false); const [isMapModalOpen, setIsMapModalOpen] = useState(false); const [emotionAnswerKind, setEmotionAnswerKind] = useState(null); + const [trackingReportData, setTrackingReportData] = useState(null); useEffect(() => { debugScreenMounted("HomeScreen"); @@ -123,6 +126,22 @@ export default function HomeScreen({ navigation }: Props) { setCurrentPage(initialPage); }, [initialPage]); + const handlePressTracking = async () => { + const response = await trackingReport.mutateAsync(); + + /* + * 한글 주석: + * 1차 조건은 백엔드가 계산한 14일 완수 일수(praiseDayCount)를 그대로 사용한다. + * 최근 14일 동안 물과 햇빛을 모두 준 날이 14일일 때만 비둘기 리포트를 연다. + */ + if (response.result.praiseDayCount < 14) { + return; + } + + setTrackingReportData(response.result); + setIsTrackingModalOpen(true); + }; + if (isLoading && gardenSummaries.length === 0) { return ( @@ -166,7 +185,7 @@ export default function HomeScreen({ navigation }: Props) { isEmotionAnswered={isEmotionAnswered} answeredKind={answeredKind} onPressMap={() => setIsMapModalOpen(true)} - onPressTracking={() => setIsTrackingModalOpen(true)} + onPressTracking={() => void handlePressTracking()} onPressEmotion={() => setIsEmotionModalOpen(true)} onPressUnlock={() => navigation.navigate("UnlockGarden")} onPressEmpty={() => navigation.navigate("RegistrationAvatar")} @@ -224,6 +243,7 @@ export default function HomeScreen({ navigation }: Props) { /> setIsTrackingModalOpen(false)} /> Date: Fri, 13 Mar 2026 15:52:46 +0900 Subject: [PATCH 33/92] =?UTF-8?q?feat:=20=EB=B9=84=EB=91=98=EA=B8=B0=20?= =?UTF-8?q?=EC=95=8C=EB=A6=BC=20=EB=AA=A8=EB=8B=AC=EC=97=90=20=EB=B0=A9?= =?UTF-8?q?=EB=AA=85=EB=A1=9D=EA=B3=BC=20=EA=B8=B0=EB=A1=9D=20=ED=83=AD=20?= =?UTF-8?q?=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/home/homeApi.ts | 13 ++ src/components/home/HomeAlertsModal.tsx | 287 ++++++++++++++++++++++++ src/components/home/HomeGardenScene.tsx | 10 +- src/hooks/home/useHomeApi.ts | 19 ++ src/pages/home/HomeScreen.tsx | 35 +-- src/types/home/alerts.ts | 15 ++ 6 files changed, 347 insertions(+), 32 deletions(-) create mode 100644 src/components/home/HomeAlertsModal.tsx create mode 100644 src/types/home/alerts.ts diff --git a/src/apis/home/homeApi.ts b/src/apis/home/homeApi.ts index 5b39895..0a1ed0c 100644 --- a/src/apis/home/homeApi.ts +++ b/src/apis/home/homeApi.ts @@ -4,6 +4,7 @@ import { normalizeHomeSummaryPayload, type HomeSummaryPayload, } from "@/types/home/garden"; +import type { GuestbookEntry, NotificationItem } from "@/types/home/alerts"; import type { HomePanelPayload } from "@/types/home/panel"; import type { TrackingReportPayload } from "@/types/home/tracking"; @@ -26,6 +27,18 @@ export const getTrackingReport = async (): ApiResponse => return res.data; }; +export const getNotifications = async (): ApiResponse => { + const res = await api.get("/api/v1/notifications"); + return res.data; +}; + +export const getGuestbookList = async ( + userId: number +): ApiResponse => { + const res = await api.get(`/api/v1/users/guestbook/${userId}/list`); + return res.data; +}; + export const postGardenSunlight = async (gardenId: number) => { const res = await api.post(`/api/v1/gardens/${gardenId}/sunlight`); return res.data; diff --git a/src/components/home/HomeAlertsModal.tsx b/src/components/home/HomeAlertsModal.tsx new file mode 100644 index 0000000..d7a24e7 --- /dev/null +++ b/src/components/home/HomeAlertsModal.tsx @@ -0,0 +1,287 @@ +import { useMemo, useState } from "react"; +import { + Modal, + Pressable, + ScrollView, + StyleSheet, + Text, + TouchableOpacity, + View, +} from "react-native"; +import { useGuestbookList, useNotifications } from "@/hooks/home/useHomeApi"; +import type { GuestbookEntry, NotificationItem } from "@/types/home/alerts"; + +type AlertTab = "GUESTBOOK" | "RECORD"; + +export default function HomeAlertsModal({ + visible, + userId, + onClose, +}: { + visible: boolean; + userId: number | null; + onClose: () => void; +}) { + const [activeTab, setActiveTab] = useState("GUESTBOOK"); + const notificationsQuery = useNotifications(visible); + const guestbookQuery = useGuestbookList(userId, visible); + + const activeState = useMemo(() => { + if (activeTab === "GUESTBOOK") { + return { + isLoading: guestbookQuery.isLoading, + isError: guestbookQuery.isError, + items: guestbookQuery.data ?? [], + }; + } + + return { + isLoading: notificationsQuery.isLoading, + isError: notificationsQuery.isError, + items: notificationsQuery.data ?? [], + }; + }, [ + activeTab, + guestbookQuery.data, + guestbookQuery.isError, + guestbookQuery.isLoading, + notificationsQuery.data, + notificationsQuery.isError, + notificationsQuery.isLoading, + ]); + + return ( + + + + + + + 알림 + + 닫기 + + + + + setActiveTab("GUESTBOOK")} + /> + setActiveTab("RECORD")} + /> + + + + {activeState.isLoading ? ( + 불러오는 중입니다. + ) : activeState.isError ? ( + 알림을 불러오지 못했습니다. + ) : activeState.items.length === 0 ? ( + + {activeTab === "GUESTBOOK" + ? "아직 방문한 친구들이 남긴 방명록이 없어요." + : "아직 기록이 없어요."} + + ) : activeTab === "GUESTBOOK" ? ( + (activeState.items as GuestbookEntry[]).map((item, index) => ( + + + {item.author} + {formatDateTime(item.createdAt)} + + {item.content} + + )) + ) : ( + (activeState.items as NotificationItem[]).map(item => ( + + + {getNotificationLabel(item.notificationType)} + {formatDateTime(item.createdAt)} + + {item.content} + {!item.isRead ? : null} + + )) + )} + + + + + ); +} + +function TabButton({ + label, + active, + onPress, +}: { + label: string; + active: boolean; + onPress: () => void; +}) { + return ( + + {label} + + ); +} + +function formatDateTime(iso: string) { + const date = new Date(iso); + return `${date.getMonth() + 1}월 ${date.getDate()}일 ${String(date.getHours()).padStart(2, "0")}:${String(date.getMinutes()).padStart(2, "0")}`; +} + +function getNotificationLabel(type: string) { + switch (type) { + case "guestbook": + return "방명록"; + case "follow": + return "친구"; + case "watering_by_friend": + return "물주기"; + case "seed_delivery": + return "씨앗 배송"; + case "diary_like": + case "avatar_post_like": + case "feed_like": + return "좋아요"; + case "diary_comment": + case "avatar_post_comment": + case "feed_comment": + return "댓글"; + default: + return "알림"; + } +} + +const styles = StyleSheet.create({ + backdrop: { + flex: 1, + backgroundColor: "rgba(0,0,0,0.38)", + alignItems: "center", + justifyContent: "center", + padding: 24, + }, + card: { + width: "100%", + maxWidth: 360, + maxHeight: "80%", + borderRadius: 28, + backgroundColor: "#FFFFFF", + paddingHorizontal: 20, + paddingTop: 22, + paddingBottom: 18, + }, + header: { + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + marginBottom: 12, + }, + headerSpacer: { + width: 44, + }, + title: { + fontSize: 22, + fontWeight: "700", + color: "#171717", + }, + closeButton: { + minWidth: 44, + alignItems: "flex-end", + }, + closeText: { + fontSize: 14, + fontWeight: "600", + color: "#6B7280", + }, + tabRow: { + flexDirection: "row", + gap: 10, + marginBottom: 14, + }, + tabButton: { + flex: 1, + borderRadius: 14, + paddingVertical: 12, + alignItems: "center", + backgroundColor: "#F3F4F6", + }, + tabButtonActive: { + backgroundColor: "#7DC960", + }, + tabButtonText: { + fontSize: 15, + fontWeight: "700", + color: "#6B7280", + }, + tabButtonTextActive: { + color: "#FFFFFF", + }, + content: { + flexGrow: 0, + }, + contentContainer: { + gap: 10, + paddingBottom: 6, + }, + messageText: { + paddingVertical: 36, + fontSize: 14, + lineHeight: 22, + color: "#9CA3AF", + textAlign: "center", + }, + listCard: { + borderRadius: 18, + backgroundColor: "#F8FAF6", + paddingHorizontal: 16, + paddingVertical: 14, + gap: 6, + position: "relative", + }, + listHeader: { + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + gap: 12, + }, + primaryText: { + flex: 1, + fontSize: 14, + fontWeight: "700", + color: "#171717", + }, + metaText: { + fontSize: 12, + color: "#6B7280", + }, + secondaryText: { + fontSize: 14, + lineHeight: 20, + color: "#374151", + }, + unreadDot: { + position: "absolute", + top: 14, + right: 14, + width: 8, + height: 8, + borderRadius: 999, + backgroundColor: "#EF4444", + }, +}); diff --git a/src/components/home/HomeGardenScene.tsx b/src/components/home/HomeGardenScene.tsx index 5aa7934..297c001 100644 --- a/src/components/home/HomeGardenScene.tsx +++ b/src/components/home/HomeGardenScene.tsx @@ -36,7 +36,7 @@ type Props = { isEmotionAnswered: boolean; answeredKind: SurveyAnswerKind | null; onPressMap: () => void; - onPressTracking: () => void; + onPressBird: () => void; onPressEmotion: () => void; onPressUnlock: () => void; onPressEmpty: () => void; @@ -50,7 +50,7 @@ export default function HomeGardenScene({ isEmotionAnswered, answeredKind, onPressMap, - onPressTracking, + onPressBird, onPressEmotion, onPressUnlock, onPressEmpty, @@ -172,7 +172,7 @@ export default function HomeGardenScene({ style={styles.actionButton} disabled={sunlightMutation.isPending} > - + - + ) : null} @@ -200,7 +200,7 @@ export default function HomeGardenScene({ isEmotionAnswered={isEmotionAnswered} answeredKind={answeredKind} onPressEmotion={onPressEmotion} - onPressBird={isEmotionAnswered ? onPressTracking : onPressEmotion} + onPressBird={onPressBird} /> )} diff --git a/src/hooks/home/useHomeApi.ts b/src/hooks/home/useHomeApi.ts index 4cda228..83f8957 100644 --- a/src/hooks/home/useHomeApi.ts +++ b/src/hooks/home/useHomeApi.ts @@ -1,13 +1,16 @@ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import type { AxiosError } from "axios"; import { + getGuestbookList, getHomePanel, getHomeSummary, + getNotifications, getTrackingReport, postGardenMyWater, postGardenSunlight, } from "@/apis/home/homeApi"; import type { GlobalResponse } from "@/types/common/apiResponse.type"; +import type { GuestbookEntry, NotificationItem } from "@/types/home/alerts"; import type { HomeSummaryPayload } from "@/types/home/garden"; import type { HomePanelPayload } from "@/types/home/panel"; import type { TrackingReportPayload } from "@/types/home/tracking"; @@ -37,6 +40,22 @@ export const useTrackingReport = () => mutationFn: getTrackingReport, }); +export const useNotifications = (enabled: boolean) => + useQuery, AxiosError, NotificationItem[]>({ + queryKey: ["notifications"], + queryFn: getNotifications, + select: data => data.result, + enabled, + }); + +export const useGuestbookList = (userId: number | null, enabled: boolean) => + useQuery, AxiosError, GuestbookEntry[]>({ + queryKey: ["guestbook-list", userId], + queryFn: () => getGuestbookList(userId as number), + select: data => data.result, + enabled: enabled && userId !== null, + }); + export const useGardenSunlightAction = () => { const queryClient = useQueryClient(); diff --git a/src/pages/home/HomeScreen.tsx b/src/pages/home/HomeScreen.tsx index b702721..4c4ac97 100644 --- a/src/pages/home/HomeScreen.tsx +++ b/src/pages/home/HomeScreen.tsx @@ -3,12 +3,12 @@ import { StyleSheet, View } from "react-native"; import PagerView from "react-native-pager-view"; import { SafeAreaView } from "react-native-safe-area-context"; import HomeBottomSheet from "@/components/home/HomeBottomSheet"; +import HomeAlertsModal from "@/components/home/HomeAlertsModal"; import HomeEmotionModal from "@/components/home/HomeEmotionModal"; import HomeGardenScene from "@/components/home/HomeGardenScene"; import HomeMapModal from "@/components/home/HomeMapModal"; -import HomeTrackingModal from "@/components/home/HomeTrackingModal"; import StatusView from "@/components/common/StatusView"; -import useHomeApi, { useHomePanelApi, useTrackingReport } from "@/hooks/home/useHomeApi"; +import useHomeApi, { useHomePanelApi } from "@/hooks/home/useHomeApi"; import { useDailySurvey } from "@/hooks/mission/useMissionApi"; import type { MainTabScreenProps } from "@/navigation/types"; import { useEmotionSurveyStore, getEmotionSurveyCooldownActive } from "@/stores/useEmotionSurveyStore"; @@ -19,7 +19,6 @@ import { type HomeMissionType, type TodayMission, } from "@/types/home/garden"; -import type { TrackingReportPayload } from "@/types/home/tracking"; import type { SurveyAnswerKind } from "@/types/missions"; import { debugLog, debugScreenMounted } from "@/utils/debug"; @@ -43,7 +42,6 @@ export default function HomeScreen({ navigation }: Props) { const { data, error, isLoading, refetch } = useHomeApi(); const { data: panel } = useHomePanelApi(); const surveyQuery = useDailySurvey(); - const trackingReport = useTrackingReport(); const { user, gardens, missions, todayDiaryId, hydrate } = useHomeSummaryStore(); const { lastAnsweredAt, @@ -54,10 +52,9 @@ export default function HomeScreen({ navigation }: Props) { const [currentPage, setCurrentPage] = useState(0); const [isSheetExpanded, setIsSheetExpanded] = useState(false); const [isEmotionModalOpen, setIsEmotionModalOpen] = useState(false); - const [isTrackingModalOpen, setIsTrackingModalOpen] = useState(false); + const [isAlertsModalOpen, setIsAlertsModalOpen] = useState(false); const [isMapModalOpen, setIsMapModalOpen] = useState(false); const [emotionAnswerKind, setEmotionAnswerKind] = useState(null); - const [trackingReportData, setTrackingReportData] = useState(null); useEffect(() => { debugScreenMounted("HomeScreen"); @@ -126,22 +123,6 @@ export default function HomeScreen({ navigation }: Props) { setCurrentPage(initialPage); }, [initialPage]); - const handlePressTracking = async () => { - const response = await trackingReport.mutateAsync(); - - /* - * 한글 주석: - * 1차 조건은 백엔드가 계산한 14일 완수 일수(praiseDayCount)를 그대로 사용한다. - * 최근 14일 동안 물과 햇빛을 모두 준 날이 14일일 때만 비둘기 리포트를 연다. - */ - if (response.result.praiseDayCount < 14) { - return; - } - - setTrackingReportData(response.result); - setIsTrackingModalOpen(true); - }; - if (isLoading && gardenSummaries.length === 0) { return ( @@ -185,7 +166,7 @@ export default function HomeScreen({ navigation }: Props) { isEmotionAnswered={isEmotionAnswered} answeredKind={answeredKind} onPressMap={() => setIsMapModalOpen(true)} - onPressTracking={() => void handlePressTracking()} + onPressBird={() => setIsAlertsModalOpen(true)} onPressEmotion={() => setIsEmotionModalOpen(true)} onPressUnlock={() => navigation.navigate("UnlockGarden")} onPressEmpty={() => navigation.navigate("RegistrationAvatar")} @@ -241,10 +222,10 @@ export default function HomeScreen({ navigation }: Props) { setIsEmotionModalOpen(false); }} /> - setIsTrackingModalOpen(false)} + setIsAlertsModalOpen(false)} /> Date: Fri, 13 Mar 2026 15:56:14 +0900 Subject: [PATCH 34/92] =?UTF-8?q?feat:=20=ED=99=88=20=EB=B9=84=EB=91=98?= =?UTF-8?q?=EA=B8=B0=20=EC=95=8C=EB=A6=BC=20=EB=B0=B0=EC=A7=80=20=ED=91=9C?= =?UTF-8?q?=EC=8B=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/home/HomeAvatarStage.tsx | 27 +++++++++++++++++++++++++ src/components/home/HomeGardenScene.tsx | 1 + src/pages/home/HomeScreen.tsx | 1 + 3 files changed, 29 insertions(+) diff --git a/src/components/home/HomeAvatarStage.tsx b/src/components/home/HomeAvatarStage.tsx index e229d05..76f82d6 100644 --- a/src/components/home/HomeAvatarStage.tsx +++ b/src/components/home/HomeAvatarStage.tsx @@ -13,6 +13,7 @@ export default function HomeAvatarStage({ isWatering, isEmotionAnswered, answeredKind, + unreadNotificationCount = 0, onPressEmotion, onPressBird, }: { @@ -20,6 +21,7 @@ export default function HomeAvatarStage({ isWatering: boolean; isEmotionAnswered: boolean; answeredKind: SurveyAnswerKind | null; + unreadNotificationCount?: number; onPressEmotion: () => void; onPressBird: () => void; }) { @@ -84,6 +86,13 @@ export default function HomeAvatarStage({ + {unreadNotificationCount > 0 ? ( + + + {unreadNotificationCount > 99 ? "99+" : unreadNotificationCount} + + + ) : null} @@ -202,6 +211,24 @@ const styles = StyleSheet.create({ right: 48, bottom: 18, }, + notificationBadge: { + position: "absolute", + right: 2, + top: -4, + minWidth: 22, + height: 22, + borderRadius: 999, + paddingHorizontal: 6, + backgroundColor: "#EF4444", + alignItems: "center", + justifyContent: "center", + zIndex: 2, + }, + notificationBadgeText: { + fontSize: 11, + fontWeight: "700", + color: "#FFFFFF", + }, birdImage: { width: 84, height: 84, diff --git a/src/components/home/HomeGardenScene.tsx b/src/components/home/HomeGardenScene.tsx index 297c001..c8b6a48 100644 --- a/src/components/home/HomeGardenScene.tsx +++ b/src/components/home/HomeGardenScene.tsx @@ -380,3 +380,4 @@ const styles = StyleSheet.create({ height: 240, }, }); + diff --git a/src/pages/home/HomeScreen.tsx b/src/pages/home/HomeScreen.tsx index 4c4ac97..a121ed3 100644 --- a/src/pages/home/HomeScreen.tsx +++ b/src/pages/home/HomeScreen.tsx @@ -292,3 +292,4 @@ const styles = StyleSheet.create({ backgroundColor: "#F4F7F0", }, }); + From 291a1d648ae0593e8cff8a45ae8960fdecc237a1 Mon Sep 17 00:00:00 2001 From: lejuho Date: Sat, 14 Mar 2026 15:04:16 +0900 Subject: [PATCH 35/92] =?UTF-8?q?feat=20:=20=ED=8A=B8=EB=9E=98=ED=82=B9=20?= =?UTF-8?q?=EB=A6=AC=ED=8F=AC=ED=8A=B8=20=EC=83=81=ED=83=9C=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=EC=99=80=20=ED=99=95=EC=9D=B8=20API=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/home/homeApi.ts | 21 ++++++++++++++++++--- src/hooks/home/useHomeApi.ts | 35 ++++++++++++++++++++++++++++++----- src/types/home/tracking.ts | 15 +++++++++++---- 3 files changed, 59 insertions(+), 12 deletions(-) diff --git a/src/apis/home/homeApi.ts b/src/apis/home/homeApi.ts index 0a1ed0c..e2f2d2d 100644 --- a/src/apis/home/homeApi.ts +++ b/src/apis/home/homeApi.ts @@ -6,7 +6,10 @@ import { } from "@/types/home/garden"; import type { GuestbookEntry, NotificationItem } from "@/types/home/alerts"; import type { HomePanelPayload } from "@/types/home/panel"; -import type { TrackingReportPayload } from "@/types/home/tracking"; +import type { + TrackingPromptConfirmRequest, + TrackingPromptStatusPayload, +} from "@/types/home/tracking"; export const getHomeSummary = async (): ApiResponse => { const res = await api.get("/api/v1/home"); @@ -22,8 +25,20 @@ export const getHomePanel = async (): ApiResponse => { return res.data; }; -export const getTrackingReport = async (): ApiResponse => { - const res = await api.get("/api/v1/tracking/report"); +export const getTrackingPromptStatus = + async (): ApiResponse => { + // 한글 주석: + // 홈 자동 팝업 여부는 앱이 계산하지 않고 서버의 eligible 판정만 그대로 조회한다. + const res = await api.get("/api/v1/tracking/report/status"); + return res.data; + }; + +export const postTrackingPromptConfirm = async ( + payload: TrackingPromptConfirmRequest +) => { + // 한글 주석: + // 사용자가 이번 주기 리포트를 확인했다는 사실을 서버에 저장해 같은 cycle 재노출을 막는다. + const res = await api.post("/api/v1/tracking/report/confirm", payload); return res.data; }; diff --git a/src/hooks/home/useHomeApi.ts b/src/hooks/home/useHomeApi.ts index 83f8957..fdd917e 100644 --- a/src/hooks/home/useHomeApi.ts +++ b/src/hooks/home/useHomeApi.ts @@ -5,15 +5,19 @@ import { getHomePanel, getHomeSummary, getNotifications, - getTrackingReport, + getTrackingPromptStatus, postGardenMyWater, postGardenSunlight, + postTrackingPromptConfirm, } from "@/apis/home/homeApi"; import type { GlobalResponse } from "@/types/common/apiResponse.type"; import type { GuestbookEntry, NotificationItem } from "@/types/home/alerts"; import type { HomeSummaryPayload } from "@/types/home/garden"; import type { HomePanelPayload } from "@/types/home/panel"; -import type { TrackingReportPayload } from "@/types/home/tracking"; +import type { + TrackingPromptConfirmRequest, + TrackingPromptStatusPayload, +} from "@/types/home/tracking"; export const useHomeApi = () => useQuery< @@ -35,9 +39,28 @@ export const useHomePanelApi = () => refetchOnMount: "always", }); -export const useTrackingReport = () => - useMutation, AxiosError>({ - mutationFn: getTrackingReport, +export const useTrackingPromptStatus = () => + useQuery< + GlobalResponse, + AxiosError, + TrackingPromptStatusPayload + >({ + // 한글 주석: + // 홈 진입, 홈 복귀, 액션 성공 뒤 모두 같은 키를 invalidate/refetch 해서 + // tracking 리포트 노출 여부를 한 군데 기준으로 맞춘다. + queryKey: ["tracking-report-status"], + queryFn: getTrackingPromptStatus, + select: data => data.result, + refetchOnMount: "always", + }); + +export const useTrackingPromptConfirm = () => + useMutation< + GlobalResponse>, + AxiosError, + TrackingPromptConfirmRequest + >({ + mutationFn: postTrackingPromptConfirm, }); export const useNotifications = (enabled: boolean) => @@ -64,6 +87,7 @@ export const useGardenSunlightAction = () => { onSuccess: async () => { await queryClient.invalidateQueries({ queryKey: ["home-summary"] }); await queryClient.invalidateQueries({ queryKey: ["home-panel"] }); + await queryClient.invalidateQueries({ queryKey: ["tracking-report-status"] }); }, }); }; @@ -76,6 +100,7 @@ export const useGardenWaterAction = () => { onSuccess: async () => { await queryClient.invalidateQueries({ queryKey: ["home-summary"] }); await queryClient.invalidateQueries({ queryKey: ["home-panel"] }); + await queryClient.invalidateQueries({ queryKey: ["tracking-report-status"] }); }, }); }; diff --git a/src/types/home/tracking.ts b/src/types/home/tracking.ts index 355ba10..ff3a851 100644 --- a/src/types/home/tracking.ts +++ b/src/types/home/tracking.ts @@ -1,6 +1,13 @@ -export interface TrackingReportPayload { - trackingType: string; - totalScore: number; - praiseDayCount: number; +export interface TrackingPromptStatusPayload { + eligible: boolean; + alreadyViewed: boolean; + perfectDayCount: number; + cycleKey: string; + windowStart: string; + windowEnd: string; message: string; } + +export interface TrackingPromptConfirmRequest { + cycleKey: string; +} From 3ed69c6b04938a05033e5e616bd4d8516a22cf30 Mon Sep 17 00:00:00 2001 From: lejuho Date: Sat, 14 Mar 2026 15:04:29 +0900 Subject: [PATCH 36/92] =?UTF-8?q?feat=20:=20=ED=99=88=EC=97=90=EC=84=9C=20?= =?UTF-8?q?2=EC=A3=BC=20=EB=A6=AC=ED=8F=AC=ED=8A=B8=20=EC=9E=90=EB=8F=99?= =?UTF-8?q?=20=EB=85=B8=EC=B6=9C=20=ED=9D=90=EB=A6=84=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/home/HomeTrackingModal.tsx | 85 +++++++++-------------- src/pages/home/HomeScreen.tsx | 84 ++++++++++++++++++++-- 2 files changed, 110 insertions(+), 59 deletions(-) diff --git a/src/components/home/HomeTrackingModal.tsx b/src/components/home/HomeTrackingModal.tsx index f1b81fa..1299a9b 100644 --- a/src/components/home/HomeTrackingModal.tsx +++ b/src/components/home/HomeTrackingModal.tsx @@ -1,4 +1,3 @@ -import { useEffect, useState } from "react"; import { Image, Modal, @@ -8,59 +7,49 @@ import { TouchableOpacity, View, } from "react-native"; -import type { TrackingReportPayload } from "@/types/home/tracking"; +import type { TrackingPromptStatusPayload } from "@/types/home/tracking"; const trackingImage = require("@/assets/images/tracking.webp"); -const characterImage = require("@/assets/images/char.webp"); export default function HomeTrackingModal({ visible, report, - onClose, + isConfirming, + onConfirm, }: { visible: boolean; - report: TrackingReportPayload | null; - onClose: () => void; + report: TrackingPromptStatusPayload | null; + isConfirming: boolean; + onConfirm: () => void; }) { - const [liked, setLiked] = useState(true); - - useEffect(() => { - if (visible) { - setLiked(true); - } - }, [visible]); - if (!report) { return null; } return ( - + - + - 함께해요! - {liked ? ( - <> - - - 2주동안 {report.praiseDayCount}일 물과 햇빛을 모두 챙기셨어요!{"\n"} - 열심히 돌봐주셨군요{"\n"} - 앞으로도 같이 잘 키워봐요! - - setLiked(false)}> - 좋아요 - - - ) : ( - <> - - {report.message} - - 고마워요 - - - )} + 2주 리포트가 도착했어요 + + + 최근 14일 동안 {report.perfectDayCount}일을 완벽하게 돌봤어요.{"\n"} + {report.message} + + + + {isConfirming ? "확인 중..." : "리포트 확인했어요"} + + @@ -90,15 +79,12 @@ const styles = StyleSheet.create({ fontSize: 22, fontWeight: "700", color: "#171717", + textAlign: "center", }, trackingImage: { width: 200, height: 150, }, - characterImage: { - width: 84, - height: 84, - }, body: { fontSize: 15, lineHeight: 23, @@ -112,21 +98,12 @@ const styles = StyleSheet.create({ paddingVertical: 14, alignItems: "center", }, + primaryButtonDisabled: { + opacity: 0.6, + }, primaryButtonText: { color: "#FFFFFF", fontSize: 15, fontWeight: "700", }, - secondaryButton: { - width: "100%", - borderRadius: 16, - backgroundColor: "#EEF3EA", - paddingVertical: 14, - alignItems: "center", - }, - secondaryButtonText: { - color: "#2E5134", - fontSize: 15, - fontWeight: "700", - }, }); diff --git a/src/pages/home/HomeScreen.tsx b/src/pages/home/HomeScreen.tsx index a121ed3..85b7faf 100644 --- a/src/pages/home/HomeScreen.tsx +++ b/src/pages/home/HomeScreen.tsx @@ -1,5 +1,7 @@ -import { useEffect, useMemo, useState } from "react"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { StyleSheet, View } from "react-native"; +import { useQueryClient } from "@tanstack/react-query"; +import { useFocusEffect } from "@react-navigation/native"; import PagerView from "react-native-pager-view"; import { SafeAreaView } from "react-native-safe-area-context"; import HomeBottomSheet from "@/components/home/HomeBottomSheet"; @@ -7,11 +9,19 @@ import HomeAlertsModal from "@/components/home/HomeAlertsModal"; import HomeEmotionModal from "@/components/home/HomeEmotionModal"; import HomeGardenScene from "@/components/home/HomeGardenScene"; import HomeMapModal from "@/components/home/HomeMapModal"; +import HomeTrackingModal from "@/components/home/HomeTrackingModal"; import StatusView from "@/components/common/StatusView"; -import useHomeApi, { useHomePanelApi } from "@/hooks/home/useHomeApi"; +import useHomeApi, { + useHomePanelApi, + useTrackingPromptConfirm, + useTrackingPromptStatus, +} from "@/hooks/home/useHomeApi"; import { useDailySurvey } from "@/hooks/mission/useMissionApi"; import type { MainTabScreenProps } from "@/navigation/types"; -import { useEmotionSurveyStore, getEmotionSurveyCooldownActive } from "@/stores/useEmotionSurveyStore"; +import { + getEmotionSurveyCooldownActive, + useEmotionSurveyStore, +} from "@/stores/useEmotionSurveyStore"; import { useHomeSummaryStore } from "@/stores/useHomeSummaryStore"; import { getGardenLocked, @@ -39,8 +49,14 @@ type SceneItem = { }; export default function HomeScreen({ navigation }: Props) { + const queryClient = useQueryClient(); const { data, error, isLoading, refetch } = useHomeApi(); const { data: panel } = useHomePanelApi(); + const { + data: trackingPromptStatus, + refetch: refetchTrackingPromptStatus, + } = useTrackingPromptStatus(); + const trackingPromptConfirmMutation = useTrackingPromptConfirm(); const surveyQuery = useDailySurvey(); const { user, gardens, missions, todayDiaryId, hydrate } = useHomeSummaryStore(); const { @@ -54,7 +70,9 @@ export default function HomeScreen({ navigation }: Props) { const [isEmotionModalOpen, setIsEmotionModalOpen] = useState(false); const [isAlertsModalOpen, setIsAlertsModalOpen] = useState(false); const [isMapModalOpen, setIsMapModalOpen] = useState(false); + const [isTrackingModalOpen, setIsTrackingModalOpen] = useState(false); const [emotionAnswerKind, setEmotionAnswerKind] = useState(null); + const openedTrackingCycleKeysRef = useRef>(new Set()); useEffect(() => { debugScreenMounted("HomeScreen"); @@ -64,14 +82,26 @@ export default function HomeScreen({ navigation }: Props) { resetIfExpired(); }, [lastAnsweredAt, resetIfExpired]); + useFocusEffect( + useCallback(() => { + // 한글 주석: + // 홈 복귀 시점에도 서버 기준 eligible 상태를 다시 읽어야 + // 방금 물/햇빛을 완료한 뒤 즉시 2주 리포트 팝업을 띄울 수 있다. + void refetch(); + void refetchTrackingPromptStatus(); + }, [refetch, refetchTrackingPromptStatus]) + ); + useEffect(() => { debugLog("HomeScreen", "query state changed", { isLoading, hasData: Boolean(data), hasError: Boolean(error), hasPanel: Boolean(panel), + trackingEligible: trackingPromptStatus?.eligible ?? false, + trackingCycleKey: trackingPromptStatus?.cycleKey ?? null, }); - }, [data, error, isLoading, panel]); + }, [data, error, isLoading, panel, trackingPromptStatus]); useEffect(() => { if (data) { @@ -83,6 +113,24 @@ export default function HomeScreen({ navigation }: Props) { } }, [data, hydrate]); + useEffect(() => { + if (!trackingPromptStatus?.eligible || !trackingPromptStatus.cycleKey) { + return; + } + + /* + * 한글 주석: + * 서버가 eligible 을 내려줘도 같은 앱 세션 안에서 이미 연 cycleKey 라면 + * 홈 재포커스나 추가 refetch 때문에 같은 모달이 연속으로 다시 뜨지 않게 막는다. + */ + if (openedTrackingCycleKeysRef.current.has(trackingPromptStatus.cycleKey)) { + return; + } + + openedTrackingCycleKeysRef.current.add(trackingPromptStatus.cycleKey); + setIsTrackingModalOpen(true); + }, [trackingPromptStatus]); + const userInfo = data?.userInfo ?? user; const gardenSummaries = data?.gardenSummaries ?? gardens; const todayMissions = data?.todayMissions ?? missions; @@ -123,6 +171,27 @@ export default function HomeScreen({ navigation }: Props) { setCurrentPage(initialPage); }, [initialPage]); + const handleTrackingPromptConfirm = useCallback(async () => { + if (!trackingPromptStatus?.cycleKey || trackingPromptConfirmMutation.isPending) { + return; + } + + try { + /* + * 한글 주석: + * 닫기와 CTA 모두 같은 confirm API 로 모아 처리해서 + * 이번 cycle 확인 완료 여부를 서버에 한 번만 기록한다. + */ + await trackingPromptConfirmMutation.mutateAsync({ + cycleKey: trackingPromptStatus.cycleKey, + }); + await queryClient.invalidateQueries({ queryKey: ["tracking-report-status"] }); + setIsTrackingModalOpen(false); + } catch (confirmError) { + debugLog("HomeScreen", "tracking prompt confirm failed", { confirmError }); + } + }, [queryClient, trackingPromptConfirmMutation, trackingPromptStatus?.cycleKey]); + if (isLoading && gardenSummaries.length === 0) { return ( @@ -232,6 +301,12 @@ export default function HomeScreen({ navigation }: Props) { slotNumber={currentPage + 1} onClose={() => setIsMapModalOpen(false)} /> + void handleTrackingPromptConfirm()} + /> ); } @@ -292,4 +367,3 @@ const styles = StyleSheet.create({ backgroundColor: "#F4F7F0", }, }); - From 924bcc12749f4b572b357d1d17e18ff23eeb71ae Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 16:58:57 +0900 Subject: [PATCH 37/92] =?UTF-8?q?chore:=20=ED=94=BC=EB=93=9C=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=EB=AC=B4=ED=95=9C=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20?= =?UTF-8?q?=EA=B3=84=ED=9A=8D=20=EB=AC=B8=EC=84=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FEED_INFINITE_SCROLL_PLAN.md | 66 ++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 FEED_INFINITE_SCROLL_PLAN.md diff --git a/FEED_INFINITE_SCROLL_PLAN.md b/FEED_INFINITE_SCROLL_PLAN.md new file mode 100644 index 0000000..3c87ae0 --- /dev/null +++ b/FEED_INFINITE_SCROLL_PLAN.md @@ -0,0 +1,66 @@ +# Feed 상세 무한 스크롤 구현 계획 + +## 목표 + +- 둘러보기에서 선택한 포스트를 상세 진입 시 첫 카드로 고정한다. +- 첫 카드 아래로는 랜덤 포스트를 세션 기반으로 이어 붙여 인스타형 세로 스크롤 경험을 만든다. +- 사용자가 다시 맨 위로 올리면 처음 선택한 포스트가 항상 첫 카드에 남아 있어야 한다. + +## 현재 상태 + +- MainAPP 상세 화면은 선택한 포스트 1개만 `ScrollView`로 보여준다. +- MainBE는 랜덤 피드 세션 API를 제공하지만, seed 포스트를 첫 카드로 고정하는 기능은 없다. +- 따라서 MainAPP에서 `선택 포스트 고정 + 랜덤 세션 아이템 후행 배치`를 직접 조합해야 한다. + +## 구현 원칙 + +- 첫 카드 고정은 프론트에서 책임진다. +- 랜덤 피드는 MainBE의 `/api/v1/feed/random/session`, `/api/v1/feed/random/next`를 사용한다. +- 랜덤 세션 응답은 상세 데이터가 아니므로, 각 아이템은 타입별 상세 API로 보강 조회한다. +- seed 포스트와 중복되는 랜덤 아이템은 클라이언트에서 제거한다. + +## 단계별 작업 + +### 1단계. 타입과 API 훅 추가 + +- 랜덤 피드 세션 응답 타입 추가 +- 세션 시작/다음 페이지 API 추가 +- `useInfiniteQuery` 기반 랜덤 세션 훅 추가 + +### 2단계. 상세 화면 공통 리스트 구조 전환 + +- `ScrollView` 기반 상세 화면을 `FlatList` 기반으로 전환 +- 첫 item은 seed 포스트로 고정 +- 이후 item은 랜덤 세션 아이템을 이어 붙임 + +### 3단계. 카드 렌더링 분리 + +- 기존 `FeedDetail`은 상세 표시 블록으로 유지 +- seed 포스트는 기존 상세 API 결과를 바로 사용 +- 랜덤 포스트는 타입별 상세 API를 내부에서 조회해 카드 렌더링 + +### 4단계. 댓글 입력 UX 정리 + +- 하단 고정 `CommentComposer`는 seed 포스트에만 붙인다 +- 랜덤 카드에는 댓글 입력을 붙이지 않는다 +- seed 포스트의 기존 댓글 작성 기능은 유지한다 + +### 5단계. 중복 제거와 로딩 처리 + +- seed 포스트와 같은 `(postType, postId)` 랜덤 아이템 제거 +- 페이지 간 중복 방지 +- 랜덤 카드 상세 로딩/에러 상태 표시 +- 다음 페이지 자동 로딩 시 과도한 중복 호출 방지 + +### 6단계. 검증 + +- 둘러보기에서 일기 선택 시 seed 일기 고정 확인 +- 둘러보기에서 아바타 포스트 선택 시 seed 아바타 포스트 고정 확인 +- 아래로 내리면 랜덤 카드가 이어지는지 확인 +- 위로 다시 올리면 처음 선택한 포스트가 첫 카드인지 확인 +- seed 포스트 댓글 작성 후 refetch 정상 반영 확인 + +## 주의사항 + +- 백엔드 랜덤 세션 시작 API는 seed 제외를 받지 않으므로, 첫 페이지에서 seed 중복이 내려와도 프론트에서 제거해야 한다. +- 랜덤 카드가 많아질수록 상세 API 호출 수가 늘어나므로 한 페이지 크기는 과하게 크게 잡지 않는다. From 4a2ecbf8d6bf09e4027eecc06c712541adc16b8c Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 16:59:04 +0900 Subject: [PATCH 38/92] =?UTF-8?q?feat:=20=ED=94=BC=EB=93=9C=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=EB=AC=B4=ED=95=9C=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/feed/randomFeedApi.ts | 21 +++ src/components/feed/FeedAvatarDetailCard.tsx | 60 +++++++++ src/components/feed/FeedDiaryDetailCard.tsx | 60 +++++++++ .../feed/FeedInfiniteDetailItem.tsx | 45 +++++++ src/components/feed/FeedSeedDetailCard.tsx | 46 +++++++ src/hooks/feed/useRandomFeedSession.ts | 54 ++++++++ src/pages/feed/FeedAvatarScreen.tsx | 122 +++++++++++++++--- src/pages/feed/FeedDiaryScreen.tsx | 113 ++++++++++++++-- src/types/feed/randomFeedApi.type.ts | 32 +++++ 9 files changed, 519 insertions(+), 34 deletions(-) create mode 100644 src/apis/feed/randomFeedApi.ts create mode 100644 src/components/feed/FeedAvatarDetailCard.tsx create mode 100644 src/components/feed/FeedDiaryDetailCard.tsx create mode 100644 src/components/feed/FeedInfiniteDetailItem.tsx create mode 100644 src/components/feed/FeedSeedDetailCard.tsx create mode 100644 src/hooks/feed/useRandomFeedSession.ts create mode 100644 src/types/feed/randomFeedApi.type.ts diff --git a/src/apis/feed/randomFeedApi.ts b/src/apis/feed/randomFeedApi.ts new file mode 100644 index 0000000..4b5eeee --- /dev/null +++ b/src/apis/feed/randomFeedApi.ts @@ -0,0 +1,21 @@ +import api from "@/apis/instance"; +import type { ApiResponse } from "@/types/common/apiResponse.type"; +import type { + RandomFeedSessionNextRequest, + RandomFeedSessionPayload, + RandomFeedSessionStartRequest, +} from "@/types/feed/randomFeedApi.type"; + +export const startRandomFeedSession = async ( + payload: RandomFeedSessionStartRequest +): ApiResponse => { + const res = await api.post("/api/v1/feed/random/session", payload); + return res.data; +}; + +export const getRandomFeedSessionNext = async ( + payload: RandomFeedSessionNextRequest +): ApiResponse => { + const res = await api.post("/api/v1/feed/random/next", payload); + return res.data; +}; diff --git a/src/components/feed/FeedAvatarDetailCard.tsx b/src/components/feed/FeedAvatarDetailCard.tsx new file mode 100644 index 0000000..4797861 --- /dev/null +++ b/src/components/feed/FeedAvatarDetailCard.tsx @@ -0,0 +1,60 @@ +import { ActivityIndicator, StyleSheet, Text, View } from "react-native"; +import FeedDetail from "@/components/feed/FeedDetail"; +import { useAvatarPostDetail } from "@/hooks/feed/useAvatarPostDetailApi"; +import type { FeedDetailResult } from "@/types/feed/detail"; + +type Props = { + postId: number; +}; + +export default function FeedAvatarDetailCard({ postId }: Props) { + const { data, isLoading, error } = useAvatarPostDetail(postId); + + if (isLoading) { + return ( + + + 아바타 포스트 상세를 불러오는 중입니다. + + ); + } + + if (error || !data) { + return ( + + 아바타 포스트 상세를 불러오지 못했습니다. + + ); + } + + const result: FeedDetailResult = { + id: data.id, + writerId: data.writerId, + writerName: data.writerName, + profileImageUrl: data.profileImageUrl, + content: data.content, + imageUrl: data.imageUrl, + isLiked: data.isLiked, + likeCount: data.likeCount, + commentCount: data.commentCount, + comments: data.comments, + createdAt: data.createdAt, + updatedAt: data.updatedAt, + isPublic: data.isPublic, + }; + + return ; +} + +const styles = StyleSheet.create({ + statusCard: { + paddingHorizontal: 20, + paddingVertical: 32, + alignItems: "center", + gap: 12, + }, + statusText: { + fontSize: 14, + color: "#6B7280", + }, +}); diff --git a/src/components/feed/FeedDiaryDetailCard.tsx b/src/components/feed/FeedDiaryDetailCard.tsx new file mode 100644 index 0000000..5fc9140 --- /dev/null +++ b/src/components/feed/FeedDiaryDetailCard.tsx @@ -0,0 +1,60 @@ +import { ActivityIndicator, StyleSheet, Text, View } from "react-native"; +import FeedDetail from "@/components/feed/FeedDetail"; +import { useDiaryDetail } from "@/hooks/log/useDiaryDetailApi"; +import type { FeedDetailResult } from "@/types/feed/detail"; + +type Props = { + postId: number; +}; + +export default function FeedDiaryDetailCard({ postId }: Props) { + const { data, isLoading, error } = useDiaryDetail(postId); + + if (isLoading) { + return ( + + + 일기 상세를 불러오는 중입니다. + + ); + } + + if (error || !data) { + return ( + + 일기 상세를 불러오지 못했습니다. + + ); + } + + const result: FeedDetailResult = { + id: data.id, + writerId: data.writerId, + writerName: data.writerName, + profileImageUrl: data.profileImageUrl, + content: data.content, + imageUrl: data.imageUrl, + isLiked: data.isLiked, + likeCount: data.likeCount, + commentCount: data.commentCount, + comments: data.comments, + createdAt: data.createdAt, + updatedAt: data.updatedAt, + isPublic: data.isPublic, + }; + + return ; +} + +const styles = StyleSheet.create({ + statusCard: { + paddingHorizontal: 20, + paddingVertical: 32, + alignItems: "center", + gap: 12, + }, + statusText: { + fontSize: 14, + color: "#6B7280", + }, +}); diff --git a/src/components/feed/FeedInfiniteDetailItem.tsx b/src/components/feed/FeedInfiniteDetailItem.tsx new file mode 100644 index 0000000..74b9de1 --- /dev/null +++ b/src/components/feed/FeedInfiniteDetailItem.tsx @@ -0,0 +1,45 @@ +import FeedAvatarDetailCard from "@/components/feed/FeedAvatarDetailCard"; +import FeedDiaryDetailCard from "@/components/feed/FeedDiaryDetailCard"; +import FeedSeedDetailCard from "@/components/feed/FeedSeedDetailCard"; +import type { FeedDetailResult } from "@/types/feed/detail"; +import type { RandomFeedPostType } from "@/types/feed/randomFeedApi.type"; + +type Props = { + postId: number; + postType: RandomFeedPostType; + isSeed: boolean; + seedResult?: FeedDetailResult; + commentValue?: string; + onChangeComment?: (value: string) => void; + onSubmitComment?: () => void; + isCommentPending?: boolean; +}; + +export default function FeedInfiniteDetailItem({ + postId, + postType, + isSeed, + seedResult, + commentValue = "", + onChangeComment, + onSubmitComment, + isCommentPending = false, +}: Props) { + if (isSeed && seedResult && onChangeComment && onSubmitComment) { + return ( + + ); + } + + return postType === "DIARY" ? ( + + ) : ( + + ); +} diff --git a/src/components/feed/FeedSeedDetailCard.tsx b/src/components/feed/FeedSeedDetailCard.tsx new file mode 100644 index 0000000..3c196a6 --- /dev/null +++ b/src/components/feed/FeedSeedDetailCard.tsx @@ -0,0 +1,46 @@ +import { StyleSheet, View } from "react-native"; +import CommentComposer from "@/components/common/CommentComposer"; +import FeedDetail from "@/components/feed/FeedDetail"; +import type { FeedDetailResult } from "@/types/feed/detail"; + +type Props = { + result: FeedDetailResult; + commentValue: string; + onChangeComment: (value: string) => void; + onSubmitComment: () => void; + isCommentPending: boolean; +}; + +export default function FeedSeedDetailCard({ + result, + commentValue, + onChangeComment, + onSubmitComment, + isCommentPending, +}: Props) { + return ( + + {/* 한글 주석: + 사용자가 둘러보기에서 처음 선택한 포스트는 항상 첫 카드로 고정하고, + 기존 상세 댓글 작성 UX도 이 카드 안에서만 유지한다. */} + + + + + + ); +} + +const styles = StyleSheet.create({ + container: { + backgroundColor: "#FFFFFF", + }, + composerWrapper: { + marginTop: 4, + }, +}); diff --git a/src/hooks/feed/useRandomFeedSession.ts b/src/hooks/feed/useRandomFeedSession.ts new file mode 100644 index 0000000..d50a86a --- /dev/null +++ b/src/hooks/feed/useRandomFeedSession.ts @@ -0,0 +1,54 @@ +import { useInfiniteQuery } from "@tanstack/react-query"; +import { + getRandomFeedSessionNext, + startRandomFeedSession, +} from "@/apis/feed/randomFeedApi"; +import type { + RandomFeedSessionNextRequest, + RandomFeedSessionPayload, +} from "@/types/feed/randomFeedApi.type"; + +type SessionPageParam = string | null; + +export const useRandomFeedSession = ({ + enabled, + sessionKey, + size = 6, +}: { + enabled: boolean; + sessionKey: string; + size?: number; +}) => + useInfiniteQuery< + { result: RandomFeedSessionPayload }, + unknown, + RandomFeedSessionPayload, + [string, string, number], + SessionPageParam + >({ + queryKey: ["random-feed-session", sessionKey, size], + enabled, + initialPageParam: null, + queryFn: ({ pageParam }) => { + if (!pageParam) { + return startRandomFeedSession({ size }); + } + + const payload: RandomFeedSessionNextRequest = { + sessionToken: pageParam, + size, + }; + return getRandomFeedSessionNext(payload); + }, + select: data => ({ + sessionToken: + data.pages[data.pages.length - 1]?.result.sessionToken ?? "", + items: data.pages.flatMap(page => page.result.items), + hasMore: data.pages[data.pages.length - 1]?.result.hasMore ?? false, + remaining: data.pages[data.pages.length - 1]?.result.remaining ?? 0, + }), + getNextPageParam: lastPage => + lastPage.result.hasMore ? lastPage.result.sessionToken : undefined, + }); + +export default useRandomFeedSession; diff --git a/src/pages/feed/FeedAvatarScreen.tsx b/src/pages/feed/FeedAvatarScreen.tsx index dfb7fe6..3e373a2 100644 --- a/src/pages/feed/FeedAvatarScreen.tsx +++ b/src/pages/feed/FeedAvatarScreen.tsx @@ -1,35 +1,53 @@ import { useState } from "react"; import { + ActivityIndicator, + FlatList, KeyboardAvoidingView, Platform, - ScrollView, StyleSheet, + Text, + View, } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; import type { RootStackScreenProps } from "@/navigation/types"; -import CommentComposer from "@/components/common/CommentComposer"; import ScreenHeader from "@/components/common/ScreenHeader"; import StatusView from "@/components/common/StatusView"; -import FeedDetail from "@/components/feed/FeedDetail"; +import FeedInfiniteDetailItem from "@/components/feed/FeedInfiniteDetailItem"; import usePostComment from "@/hooks/comments/useCommentApi"; import { useAvatarPostDetail } from "@/hooks/feed/useAvatarPostDetailApi"; +import { useRandomFeedSession } from "@/hooks/feed/useRandomFeedSession"; import type { FeedDetailResult } from "@/types/feed/detail"; +import type { RandomFeedPostType } from "@/types/feed/randomFeedApi.type"; type Props = RootStackScreenProps<"FeedAvatar">; +type FeedListItem = { + key: string; + postId: number; + postType: RandomFeedPostType; + isSeed: boolean; +}; + export default function FeedAvatarScreen({ navigation, route }: Props) { const { postId } = route.params; const id = Number(postId); const isValidId = Number.isFinite(id) && id > 0; - const { - data, - error, - isLoading, - refetch, - } = useAvatarPostDetail(isValidId ? id : 0); + const { data, error, isLoading, refetch } = useAvatarPostDetail(isValidId ? id : 0); const [content, setContent] = useState(""); const { mutateAsync, isPending } = usePostComment(() => refetch()); + const { + data: randomSession, + isLoading: isRandomLoading, + isError: isRandomError, + fetchNextPage, + hasNextPage, + isFetchingNextPage, + } = useRandomFeedSession({ + enabled: isValidId && Boolean(data), + sessionKey: `AVATAR_POST:${id}`, + size: 6, + }); const handleBackClick = () => { if (navigation.canGoBack()) { @@ -102,7 +120,7 @@ export default function FeedAvatarScreen({ navigation, route }: Props) { ); } - const result: FeedDetailResult = { + const seedResult: FeedDetailResult = { id: data.id, writerId: data.writerId, writerName: data.writerName, @@ -118,6 +136,30 @@ export default function FeedAvatarScreen({ navigation, route }: Props) { isPublic: data.isPublic, }; + const seenKeys = new Set([`AVATAR_POST:${id}`]); + const listData: FeedListItem[] = [ + { + key: `seed-AVATAR_POST-${id}`, + postId: id, + postType: "AVATAR_POST", + isSeed: true, + }, + ]; + + for (const item of randomSession?.items ?? []) { + const itemKey = `${item.postType}:${item.postId}`; + if (seenKeys.has(itemKey)) { + continue; + } + seenKeys.add(itemKey); + listData.push({ + key: `random-${item.postType}-${item.postId}`, + postId: item.postId, + postType: item.postType, + isSeed: false, + }); + } + return ( - - - - void handleSend()} - disabled={isPending} + item.key} + showsVerticalScrollIndicator={false} + contentContainerStyle={styles.listContent} + onEndReached={() => { + if (hasNextPage && !isFetchingNextPage) { + void fetchNextPage(); + } + }} + onEndReachedThreshold={0.45} + renderItem={({ item }) => ( + void handleSend() : undefined} + isCommentPending={item.isSeed ? isPending : false} + /> + )} + ListFooterComponent={ + + {isFetchingNextPage ? ( + + ) : null} + {!isFetchingNextPage && isRandomLoading ? ( + + ) : null} + {isRandomError ? ( + + 랜덤 피드를 이어서 불러오지 못했습니다. + + ) : null} + + } /> @@ -147,7 +219,17 @@ const styles = StyleSheet.create({ keyboardView: { flex: 1, }, - scrollView: { - flex: 1, + listContent: { + paddingBottom: 24, + }, + footer: { + alignItems: "center", + justifyContent: "center", + paddingVertical: 20, + gap: 8, + }, + footerText: { + fontSize: 13, + color: "#6B7280", }, }); diff --git a/src/pages/feed/FeedDiaryScreen.tsx b/src/pages/feed/FeedDiaryScreen.tsx index 6af81cf..47ef6ed 100644 --- a/src/pages/feed/FeedDiaryScreen.tsx +++ b/src/pages/feed/FeedDiaryScreen.tsx @@ -1,22 +1,33 @@ import { useState } from "react"; import { + ActivityIndicator, + FlatList, KeyboardAvoidingView, Platform, - ScrollView, StyleSheet, + Text, + View, } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; import type { RootStackScreenProps } from "@/navigation/types"; -import CommentComposer from "@/components/common/CommentComposer"; import ScreenHeader from "@/components/common/ScreenHeader"; import StatusView from "@/components/common/StatusView"; -import FeedDetail from "@/components/feed/FeedDetail"; +import FeedInfiniteDetailItem from "@/components/feed/FeedInfiniteDetailItem"; import usePostComment from "@/hooks/comments/useCommentApi"; +import { useRandomFeedSession } from "@/hooks/feed/useRandomFeedSession"; import { useDiaryDetail } from "@/hooks/log/useDiaryDetailApi"; import type { FeedDetailResult } from "@/types/feed/detail"; +import type { RandomFeedPostType } from "@/types/feed/randomFeedApi.type"; type Props = RootStackScreenProps<"FeedDiary">; +type FeedListItem = { + key: string; + postId: number; + postType: RandomFeedPostType; + isSeed: boolean; +}; + export default function FeedDiaryScreen({ navigation, route }: Props) { const { postId } = route.params; @@ -25,6 +36,18 @@ export default function FeedDiaryScreen({ navigation, route }: Props) { const { data, error, isLoading, refetch } = useDiaryDetail(isValidId ? id : 0); const [content, setContent] = useState(""); const { mutateAsync, isPending } = usePostComment(() => refetch()); + const { + data: randomSession, + isLoading: isRandomLoading, + isError: isRandomError, + fetchNextPage, + hasNextPage, + isFetchingNextPage, + } = useRandomFeedSession({ + enabled: isValidId && Boolean(data), + sessionKey: `DIARY:${id}`, + size: 6, + }); const handleBackClick = () => { if (navigation.canGoBack()) { @@ -97,7 +120,7 @@ export default function FeedDiaryScreen({ navigation, route }: Props) { ); } - const result: FeedDetailResult = { + const seedResult: FeedDetailResult = { id: data.id, writerId: data.writerId, writerName: data.writerName, @@ -113,6 +136,25 @@ export default function FeedDiaryScreen({ navigation, route }: Props) { isPublic: data.isPublic, }; + const seenKeys = new Set([`DIARY:${id}`]); + const listData: FeedListItem[] = [ + { key: `seed-DIARY-${id}`, postId: id, postType: "DIARY", isSeed: true }, + ]; + + for (const item of randomSession?.items ?? []) { + const itemKey = `${item.postType}:${item.postId}`; + if (seenKeys.has(itemKey)) { + continue; + } + seenKeys.add(itemKey); + listData.push({ + key: `random-${item.postType}-${item.postId}`, + postId: item.postId, + postType: item.postType, + isSeed: false, + }); + } + return ( - - - - void handleSend()} - disabled={isPending} + item.key} + showsVerticalScrollIndicator={false} + contentContainerStyle={styles.listContent} + onEndReached={() => { + if (hasNextPage && !isFetchingNextPage) { + void fetchNextPage(); + } + }} + onEndReachedThreshold={0.45} + renderItem={({ item }) => ( + void handleSend() : undefined} + isCommentPending={item.isSeed ? isPending : false} + /> + )} + ListFooterComponent={ + + {/* 한글 주석: + seed 포스트 아래 랜덤 카드가 이어 붙기 때문에, + 다음 페이지 로딩 상태만 하단에서 가볍게 노출한다. */} + {isFetchingNextPage ? ( + + ) : null} + {!isFetchingNextPage && isRandomLoading ? ( + + ) : null} + {isRandomError ? ( + + 랜덤 피드를 이어서 불러오지 못했습니다. + + ) : null} + + } /> @@ -142,7 +217,17 @@ const styles = StyleSheet.create({ keyboardView: { flex: 1, }, - scrollView: { - flex: 1, + listContent: { + paddingBottom: 24, + }, + footer: { + alignItems: "center", + justifyContent: "center", + paddingVertical: 20, + gap: 8, + }, + footerText: { + fontSize: 13, + color: "#6B7280", }, }); diff --git a/src/types/feed/randomFeedApi.type.ts b/src/types/feed/randomFeedApi.type.ts new file mode 100644 index 0000000..ce56cc1 --- /dev/null +++ b/src/types/feed/randomFeedApi.type.ts @@ -0,0 +1,32 @@ +export type RandomFeedPostType = "DIARY" | "AVATAR_POST"; + +export interface RandomFeedAuthor { + userId: number; + username: string; + profileImageUrl: string | null; +} + +export interface RandomFeedSessionItem { + postId: number; + postType: RandomFeedPostType; + author: RandomFeedAuthor; + likeCount: number; + commentCount: number; + createdAt: string; +} + +export interface RandomFeedSessionPayload { + sessionToken: string; + items: RandomFeedSessionItem[]; + hasMore: boolean; + remaining: number; +} + +export interface RandomFeedSessionStartRequest { + size: number; +} + +export interface RandomFeedSessionNextRequest { + sessionToken: string; + size: number; +} From d7dbbb3a5db9042cdb12c52a5b511a7794dd58ad Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 18:00:27 +0900 Subject: [PATCH 39/92] =?UTF-8?q?feat:=20=ED=94=BC=EB=93=9C=20=EB=8C=93?= =?UTF-8?q?=EA=B8=80=20=ED=95=98=EB=8B=A8=20=EC=8B=9C=ED=8A=B8=20UX=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/feed/FeedDetail.tsx | 234 +++++++++++++++------ src/components/feed/FeedSeedDetailCard.tsx | 22 +- 2 files changed, 172 insertions(+), 84 deletions(-) diff --git a/src/components/feed/FeedDetail.tsx b/src/components/feed/FeedDetail.tsx index ecedd46..6af8a37 100644 --- a/src/components/feed/FeedDetail.tsx +++ b/src/components/feed/FeedDetail.tsx @@ -1,8 +1,13 @@ -import React from "react"; +import React, { useMemo, useState } from "react"; import { + FlatList, View, Text, Image, + Modal, + Pressable, + KeyboardAvoidingView, + Platform, TouchableOpacity, StyleSheet, } from "react-native"; @@ -12,15 +17,38 @@ import type { RootStackParamList } from "@/navigation/types"; import { HeartIcon, ChatIcon } from "@/assets/icons/CommonIcons"; import Comment from "@/components/common/Comment"; +import CommentComposer from "@/components/common/CommentComposer"; import type { FeedDetailResult } from "@/types/feed/detail"; type Props = { result: FeedDetailResult; + commentValue?: string; + onChangeComment?: (text: string) => void; + onSubmitComment?: () => void; + isCommentPending?: boolean; }; -export default function FeedDetail({ result }: Props) { +export default function FeedDetail({ + result, + commentValue = "", + onChangeComment, + onSubmitComment, + isCommentPending = false, +}: Props) { const navigation = useNavigation>(); + const [isCommentSheetVisible, setCommentSheetVisible] = useState(false); + + const comments = useMemo( + () => + result.comments.map(c => ({ + id: c.commentId, + profileImageUrl: c.profileImageUrl, + writer: c.writer, + content: c.content, + })), + [result.comments] + ); const formatDate = (iso: string) => { const d = new Date(iso); @@ -31,78 +59,112 @@ export default function FeedDetail({ result }: Props) { navigation.navigate("Profile", { userId: result.writerId }); }; + const handleOpenComments = () => { + setCommentSheetVisible(true); + }; + + const handleCloseComments = () => { + setCommentSheetVisible(false); + }; + return ( - - {/* 작성자 영역 */} - - - - {result.profileImageUrl && ( - - )} - - - {result.writerName} - {formatDate(result.createdAt)} - - - 신고 - + <> + + {/* 작성자 영역 */} + + + + {result.profileImageUrl && ( + + )} + + + {result.writerName} + {formatDate(result.createdAt)} + + + 신고 + - {/* 이미지 */} - + {/* 이미지 */} + - {/* 내용 */} - {result.content} + {/* 내용 */} + {result.content} - {/* 액션 바 */} - - - {/* 공감 */} - - - 공감 {result.likeCount} - - {/* 댓글 */} - - - 댓글 {result.commentCount} + {/* 액션 바 */} + + + {/* 공감 */} + + + 공감 {result.likeCount} + + {/* 댓글 */} + + + 댓글 {result.commentCount} + + - - {/* 댓글 목록 */} - - {result.comments.length > 0 ? ( - result.comments.map(c => ( - - )) - ) : ( - 아직 작성된 댓글이 없습니다. - )} - - + + + + + + 댓글 {result.commentCount} + {comments.length > 0 ? ( + item.id.toString()} + renderItem={({ item }) => } + style={styles.commentList} + showsVerticalScrollIndicator={false} + /> + ) : ( + + 아직 작성된 댓글이 없습니다. + + )} + {onChangeComment && onSubmitComment ? ( + + ) : null} + + + + ); } @@ -193,14 +255,46 @@ const styles = StyleSheet.create({ spacer: { width: 40, }, - commentsContainer: { - paddingVertical: 16, - marginHorizontal: -20, + backdrop: { + flex: 1, + backgroundColor: "rgba(0,0,0,0.28)", + }, + sheetKeyboard: { + justifyContent: "flex-end", + }, + sheet: { + maxHeight: "78%", + backgroundColor: "#FFFFFF", + borderTopLeftRadius: 24, + borderTopRightRadius: 24, + overflow: "hidden", + }, + sheetHandle: { + alignSelf: "center", + width: 44, + height: 5, + borderRadius: 999, + backgroundColor: "#D1D5DB", + marginTop: 10, + marginBottom: 14, + }, + sheetTitle: { + fontSize: 16, + fontWeight: "700", + color: "#171717", + textAlign: "center", + marginBottom: 8, + }, + commentList: { + maxHeight: 420, + }, + emptyState: { + paddingVertical: 28, + paddingHorizontal: 20, }, emptyText: { fontSize: 14, color: "#9CA3AF", textAlign: "center", - paddingVertical: 24, }, }); diff --git a/src/components/feed/FeedSeedDetailCard.tsx b/src/components/feed/FeedSeedDetailCard.tsx index 3c196a6..e1de13a 100644 --- a/src/components/feed/FeedSeedDetailCard.tsx +++ b/src/components/feed/FeedSeedDetailCard.tsx @@ -1,5 +1,4 @@ import { StyleSheet, View } from "react-native"; -import CommentComposer from "@/components/common/CommentComposer"; import FeedDetail from "@/components/feed/FeedDetail"; import type { FeedDetailResult } from "@/types/feed/detail"; @@ -22,16 +21,14 @@ export default function FeedSeedDetailCard({ {/* 한글 주석: 사용자가 둘러보기에서 처음 선택한 포스트는 항상 첫 카드로 고정하고, - 기존 상세 댓글 작성 UX도 이 카드 안에서만 유지한다. */} - - - - + 기존 상세 댓글 작성 UX도 댓글 시트 안에서만 유지한다. */} + ); } @@ -40,7 +37,4 @@ const styles = StyleSheet.create({ container: { backgroundColor: "#FFFFFF", }, - composerWrapper: { - marginTop: 4, - }, }); From 6cbf2c5101017c2115067e76666f3304a41a2e7d Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 18:12:53 +0900 Subject: [PATCH 40/92] =?UTF-8?q?fix:=20=ED=94=BC=EB=93=9C=20=EB=8C=93?= =?UTF-8?q?=EA=B8=80=20=EC=8B=9C=ED=8A=B8=20=EB=B0=B0=EA=B2=BD=20=EC=A0=95?= =?UTF-8?q?=EB=A0=AC=20=EB=B3=B4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/feed/FeedDetail.tsx | 71 ++++++++++++++++-------------- 1 file changed, 39 insertions(+), 32 deletions(-) diff --git a/src/components/feed/FeedDetail.tsx b/src/components/feed/FeedDetail.tsx index 6af8a37..b5d595c 100644 --- a/src/components/feed/FeedDetail.tsx +++ b/src/components/feed/FeedDetail.tsx @@ -132,37 +132,39 @@ export default function FeedDetail({ animationType="slide" onRequestClose={handleCloseComments} > - - - - - 댓글 {result.commentCount} - {comments.length > 0 ? ( - item.id.toString()} - renderItem={({ item }) => } - style={styles.commentList} - showsVerticalScrollIndicator={false} - /> - ) : ( - - 아직 작성된 댓글이 없습니다. - - )} - {onChangeComment && onSubmitComment ? ( - - ) : null} - - + + + + + + 댓글 {result.commentCount} + {comments.length > 0 ? ( + item.id.toString()} + renderItem={({ item }) => } + style={styles.commentList} + showsVerticalScrollIndicator={false} + /> + ) : ( + + 아직 작성된 댓글이 없습니다. + + )} + {onChangeComment && onSubmitComment ? ( + + ) : null} + + + ); @@ -255,11 +257,16 @@ const styles = StyleSheet.create({ spacer: { width: 40, }, - backdrop: { + modalRoot: { flex: 1, + justifyContent: "flex-end", + }, + backdrop: { + ...StyleSheet.absoluteFillObject, backgroundColor: "rgba(0,0,0,0.28)", }, sheetKeyboard: { + flexShrink: 1, justifyContent: "flex-end", }, sheet: { From ef7611044f3c61a65024a1a45a29d0cd3534d40e Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 19:57:09 +0900 Subject: [PATCH 41/92] =?UTF-8?q?fix:=20=ED=94=BC=EB=93=9C=20=EB=8C=93?= =?UTF-8?q?=EA=B8=80=20=EC=8B=9C=ED=8A=B8=20=EC=A0=84=EC=B2=B4=20=EB=86=92?= =?UTF-8?q?=EC=9D=B4=20=EA=B3=A0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/feed/FeedDetail.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/feed/FeedDetail.tsx b/src/components/feed/FeedDetail.tsx index b5d595c..d65ce8b 100644 --- a/src/components/feed/FeedDetail.tsx +++ b/src/components/feed/FeedDetail.tsx @@ -266,7 +266,7 @@ const styles = StyleSheet.create({ backgroundColor: "rgba(0,0,0,0.28)", }, sheetKeyboard: { - flexShrink: 1, + flex: 1, justifyContent: "flex-end", }, sheet: { From 0b3b701817a6a329e6230a2a03fc0195d6ffe4bd Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 20:09:02 +0900 Subject: [PATCH 42/92] =?UTF-8?q?feat:=20=ED=94=BC=EB=93=9C=20=EB=8C=93?= =?UTF-8?q?=EA=B8=80=20=EC=8B=9C=ED=8A=B8=20=EB=86=92=EC=9D=B4=20=EB=B9=84?= =?UTF-8?q?=EC=9C=A8=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/feed/FeedDetail.tsx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/components/feed/FeedDetail.tsx b/src/components/feed/FeedDetail.tsx index d65ce8b..64441ca 100644 --- a/src/components/feed/FeedDetail.tsx +++ b/src/components/feed/FeedDetail.tsx @@ -10,6 +10,7 @@ import { Platform, TouchableOpacity, StyleSheet, + useWindowDimensions, } from "react-native"; import { useNavigation } from "@react-navigation/native"; import type { NativeStackNavigationProp } from "@react-navigation/native-stack"; @@ -38,6 +39,7 @@ export default function FeedDetail({ const navigation = useNavigation>(); const [isCommentSheetVisible, setCommentSheetVisible] = useState(false); + const { height: windowHeight } = useWindowDimensions(); const comments = useMemo( () => @@ -138,7 +140,14 @@ export default function FeedDetail({ behavior={Platform.OS === "ios" ? "padding" : "height"} style={styles.sheetKeyboard} > - + 댓글 {result.commentCount} {comments.length > 0 ? ( From 6fcce33c8f3917f1e32f9702be09c82de083105a Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 20:09:42 +0900 Subject: [PATCH 43/92] =?UTF-8?q?feat:=20=ED=94=BC=EB=93=9C=20=EB=8C=93?= =?UTF-8?q?=EA=B8=80=20=EC=9E=85=EB=A0=A5=EC=B0=BD=20=ED=95=98=EB=8B=A8=20?= =?UTF-8?q?=EA=B3=A0=EC=A0=95=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/feed/FeedDetail.tsx | 63 +++++++++++++++++++----------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/src/components/feed/FeedDetail.tsx b/src/components/feed/FeedDetail.tsx index 64441ca..b255d3a 100644 --- a/src/components/feed/FeedDetail.tsx +++ b/src/components/feed/FeedDetail.tsx @@ -150,26 +150,34 @@ export default function FeedDetail({ > 댓글 {result.commentCount} - {comments.length > 0 ? ( - item.id.toString()} - renderItem={({ item }) => } - style={styles.commentList} - showsVerticalScrollIndicator={false} - /> - ) : ( - - 아직 작성된 댓글이 없습니다. - - )} + + {comments.length > 0 ? ( + item.id.toString()} + renderItem={({ item }) => } + style={styles.commentList} + contentContainerStyle={styles.commentListContent} + showsVerticalScrollIndicator={false} + /> + ) : ( + + 아직 작성된 댓글이 없습니다. + + )} + {onChangeComment && onSubmitComment ? ( - + + {/* 한글 주석: + 인스타처럼 댓글 입력창은 시트 하단에 고정하고, + 위쪽 댓글 목록만 독립적으로 스크롤되게 분리한다. */} + + ) : null} @@ -279,7 +287,6 @@ const styles = StyleSheet.create({ justifyContent: "flex-end", }, sheet: { - maxHeight: "78%", backgroundColor: "#FFFFFF", borderTopLeftRadius: 24, borderTopRightRadius: 24, @@ -301,11 +308,18 @@ const styles = StyleSheet.create({ textAlign: "center", marginBottom: 8, }, + sheetContent: { + flex: 1, + }, commentList: { - maxHeight: 420, + flex: 1, + }, + commentListContent: { + paddingBottom: 16, }, emptyState: { - paddingVertical: 28, + flex: 1, + justifyContent: "center", paddingHorizontal: 20, }, emptyText: { @@ -313,4 +327,9 @@ const styles = StyleSheet.create({ color: "#9CA3AF", textAlign: "center", }, + composerContainer: { + borderTopWidth: 1, + borderTopColor: "#E5E7EB", + backgroundColor: "#FFFFFF", + }, }); From 7299c2f1f8234fa39771742f192be7951791a777 Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 20:15:20 +0900 Subject: [PATCH 44/92] =?UTF-8?q?feat:=20=ED=94=BC=EB=93=9C=20=EB=8C=93?= =?UTF-8?q?=EA=B8=80=20=EC=8B=9C=ED=8A=B8=20=EB=93=9C=EB=9E=98=EA=B7=B8=20?= =?UTF-8?q?=EC=A0=9C=EC=8A=A4=EC=B2=98=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App.tsx | 55 ++++++------ index.ts | 1 + src/components/feed/FeedDetail.tsx | 130 ++++++++++++++++++++++++++--- 3 files changed, 149 insertions(+), 37 deletions(-) diff --git a/App.tsx b/App.tsx index 2119669..4f3d96c 100644 --- a/App.tsx +++ b/App.tsx @@ -5,6 +5,7 @@ import { NavigationContainer, useNavigationContainerRef, } from "@react-navigation/native"; +import { GestureHandlerRootView } from "react-native-gesture-handler"; import { SafeAreaProvider, SafeAreaView } from "react-native-safe-area-context"; import { RootNavigator } from "@/navigation"; import QueryProvider from "@/providers/QueryProvider"; @@ -37,33 +38,35 @@ export default function App() { } return ( - - - { - const routeName = navigationRef.getCurrentRoute()?.name; - currentRouteNameRef.current = routeName; - debugLog("Navigation", "ready", { routeName }); - }} - onStateChange={() => { - const previousRouteName = currentRouteNameRef.current; - const nextRouteName = navigationRef.getCurrentRoute()?.name; + + + + { + const routeName = navigationRef.getCurrentRoute()?.name; + currentRouteNameRef.current = routeName; + debugLog("Navigation", "ready", { routeName }); + }} + onStateChange={() => { + const previousRouteName = currentRouteNameRef.current; + const nextRouteName = navigationRef.getCurrentRoute()?.name; - if (previousRouteName !== nextRouteName) { - debugLog("Navigation", "route changed", { - from: previousRouteName, - to: nextRouteName, - }); - } + if (previousRouteName !== nextRouteName) { + debugLog("Navigation", "route changed", { + from: previousRouteName, + to: nextRouteName, + }); + } - currentRouteNameRef.current = nextRouteName; - }} - > - - - - - + currentRouteNameRef.current = nextRouteName; + }} + > + + + + + + ); } diff --git a/index.ts b/index.ts index 1d6e981..ff163fa 100644 --- a/index.ts +++ b/index.ts @@ -1,3 +1,4 @@ +import "react-native-gesture-handler"; import { registerRootComponent } from 'expo'; import App from './App'; diff --git a/src/components/feed/FeedDetail.tsx b/src/components/feed/FeedDetail.tsx index b255d3a..87d2178 100644 --- a/src/components/feed/FeedDetail.tsx +++ b/src/components/feed/FeedDetail.tsx @@ -1,4 +1,4 @@ -import React, { useMemo, useState } from "react"; +import React, { useEffect, useMemo, useState } from "react"; import { FlatList, View, @@ -14,6 +14,16 @@ import { } from "react-native"; import { useNavigation } from "@react-navigation/native"; import type { NativeStackNavigationProp } from "@react-navigation/native-stack"; +import { Gesture, GestureDetector } from "react-native-gesture-handler"; +import Animated, { + Easing, + Extrapolation, + interpolate, + runOnJS, + useAnimatedStyle, + useSharedValue, + withTiming, +} from "react-native-reanimated"; import type { RootStackParamList } from "@/navigation/types"; import { HeartIcon, ChatIcon } from "@/assets/icons/CommonIcons"; @@ -40,6 +50,9 @@ export default function FeedDetail({ useNavigation>(); const [isCommentSheetVisible, setCommentSheetVisible] = useState(false); const { height: windowHeight } = useWindowDimensions(); + const sheetHeight = Math.min(windowHeight * 0.6, 560); + const translateY = useSharedValue(sheetHeight); + const backdropOpacity = useSharedValue(0); const comments = useMemo( () => @@ -66,9 +79,93 @@ export default function FeedDetail({ }; const handleCloseComments = () => { - setCommentSheetVisible(false); + translateY.value = withTiming( + sheetHeight, + { + duration: 240, + easing: Easing.out(Easing.cubic), + }, + finished => { + if (finished) { + runOnJS(setCommentSheetVisible)(false); + } + } + ); + backdropOpacity.value = withTiming(0, { + duration: 220, + easing: Easing.out(Easing.quad), + }); }; + useEffect(() => { + if (!isCommentSheetVisible) { + return; + } + + translateY.value = sheetHeight; + backdropOpacity.value = 0; + translateY.value = withTiming(0, { + duration: 260, + easing: Easing.out(Easing.cubic), + }); + backdropOpacity.value = withTiming(1, { + duration: 220, + easing: Easing.out(Easing.quad), + }); + }, [backdropOpacity, isCommentSheetVisible, sheetHeight, translateY]); + + const panGesture = Gesture.Pan() + .onUpdate(event => { + translateY.value = Math.max(0, event.translationY); + backdropOpacity.value = interpolate( + translateY.value, + [0, sheetHeight], + [1, 0], + Extrapolation.CLAMP + ); + }) + .onEnd(event => { + const shouldClose = + event.velocityY > 900 || translateY.value > sheetHeight * 0.28; + + if (shouldClose) { + translateY.value = withTiming( + sheetHeight, + { + duration: 220, + easing: Easing.out(Easing.cubic), + }, + finished => { + if (finished) { + runOnJS(setCommentSheetVisible)(false); + } + } + ); + backdropOpacity.value = withTiming(0, { + duration: 200, + easing: Easing.out(Easing.quad), + }); + return; + } + + translateY.value = withTiming(0, { + duration: 220, + easing: Easing.out(Easing.cubic), + }); + backdropOpacity.value = withTiming(1, { + duration: 200, + easing: Easing.out(Easing.quad), + }); + }); + + const backdropAnimatedStyle = useAnimatedStyle(() => ({ + opacity: backdropOpacity.value, + })); + + const sheetAnimatedStyle = useAnimatedStyle(() => ({ + transform: [{ translateY: translateY.value }], + })); + return ( <> @@ -131,25 +228,30 @@ export default function FeedDetail({ - + + + - - - 댓글 {result.commentCount} + + + + 댓글 {result.commentCount} + + {comments.length > 0 ? ( ) : null} - + @@ -282,6 +384,9 @@ const styles = StyleSheet.create({ ...StyleSheet.absoluteFillObject, backgroundColor: "rgba(0,0,0,0.28)", }, + backdropPressable: { + flex: 1, + }, sheetKeyboard: { flex: 1, justifyContent: "flex-end", @@ -292,6 +397,9 @@ const styles = StyleSheet.create({ borderTopRightRadius: 24, overflow: "hidden", }, + dragArea: { + paddingBottom: 8, + }, sheetHandle: { alignSelf: "center", width: 44, From e3db030197446f170ef3e8b7f354f18d1af1c8b7 Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 20:21:42 +0900 Subject: [PATCH 45/92] =?UTF-8?q?refactor:=20=ED=94=BC=EB=93=9C=20?= =?UTF-8?q?=EB=8C=93=EA=B8=80=20=EC=8B=9C=ED=8A=B8=EB=A5=BC=20bottom=20she?= =?UTF-8?q?et=EB=A1=9C=20=EC=A0=84=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 73 +++++--- package.json | 2 + src/components/feed/FeedDetail.tsx | 260 +++++++++-------------------- 3 files changed, 133 insertions(+), 202 deletions(-) diff --git a/package-lock.json b/package-lock.json index a5d5266..2df44a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "hanium-app", "version": "1.0.0", "dependencies": { + "@gorhom/bottom-sheet": "^5.2.8", "@react-native-async-storage/async-storage": "^2.2.0", "@react-navigation/bottom-tabs": "^7.10.1", "@react-navigation/native": "^7.1.28", @@ -32,6 +33,7 @@ "react-native": "0.81.5", "react-native-gesture-handler": "~2.28.0", "react-native-pager-view": "6.9.1", + "react-native-reanimated": "~4.1.1", "react-native-safe-area-context": "~5.6.0", "react-native-screens": "~4.16.0", "react-native-svg": "15.12.1", @@ -2334,6 +2336,45 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/@gorhom/bottom-sheet": { + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/@gorhom/bottom-sheet/-/bottom-sheet-5.2.8.tgz", + "integrity": "sha512-+N27SMpbBxXZQ/IA2nlEV6RGxL/qSFHKfdFKcygvW+HqPG5jVNb1OqehLQsGfBP+Up42i0gW5ppI+DhpB7UCzA==", + "license": "MIT", + "dependencies": { + "@gorhom/portal": "1.0.14", + "invariant": "^2.2.4" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-native": "*", + "react": "*", + "react-native": "*", + "react-native-gesture-handler": ">=2.16.1", + "react-native-reanimated": ">=3.16.0 || >=4.0.0-" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-native": { + "optional": true + } + } + }, + "node_modules/@gorhom/portal": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/@gorhom/portal/-/portal-1.0.14.tgz", + "integrity": "sha512-MXyL4xvCjmgaORr/rtryDNFy3kU4qUbKlwtQqqsygd0xX3mhKjOLn6mQK8wfu0RkoE0pBE0nAasRoHua+/QZ7A==", + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.1" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, "node_modules/@isaacs/fs-minipass": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", @@ -9237,38 +9278,26 @@ } }, "node_modules/react-native-reanimated": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-4.2.2.tgz", - "integrity": "sha512-o3kKvdD8cVlg12Z4u3jv0MFAt53QV4k7gD9OLwQqU8eZLyd8QvaOjVZIghMZhC2pjP93uUU44PlO5JgF8S4Vxw==", + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-4.1.6.tgz", + "integrity": "sha512-F+ZJBYiok/6Jzp1re75F/9aLzkgoQCOh4yxrnwATa8392RvM3kx+fiXXFvwcgE59v48lMwd9q0nzF1oJLXpfxQ==", "license": "MIT", - "peer": true, "dependencies": { - "react-native-is-edge-to-edge": "1.2.1", - "semver": "7.7.3" + "react-native-is-edge-to-edge": "^1.2.1", + "semver": "7.7.2" }, "peerDependencies": { + "@babel/core": "^7.0.0-0", "react": "*", "react-native": "*", - "react-native-worklets": ">=0.7.0" - } - }, - "node_modules/react-native-reanimated/node_modules/react-native-is-edge-to-edge": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/react-native-is-edge-to-edge/-/react-native-is-edge-to-edge-1.2.1.tgz", - "integrity": "sha512-FLbPWl/MyYQWz+KwqOZsSyj2JmLKglHatd3xLZWskXOpRaio4LfEDEz8E/A6uD8QoTHW6Aobw1jbEwK7KMgR7Q==", - "license": "MIT", - "peer": true, - "peerDependencies": { - "react": "*", - "react-native": "*" + "react-native-worklets": ">=0.5.0" } }, "node_modules/react-native-reanimated/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "license": "ISC", - "peer": true, "bin": { "semver": "bin/semver.js" }, diff --git a/package.json b/package.json index 17a72f6..c883f5d 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "web": "expo start --web" }, "dependencies": { + "@gorhom/bottom-sheet": "^5.2.8", "@react-native-async-storage/async-storage": "^2.2.0", "@react-navigation/bottom-tabs": "^7.10.1", "@react-navigation/native": "^7.1.28", @@ -33,6 +34,7 @@ "react-native": "0.81.5", "react-native-gesture-handler": "~2.28.0", "react-native-pager-view": "6.9.1", + "react-native-reanimated": "~4.1.1", "react-native-safe-area-context": "~5.6.0", "react-native-screens": "~4.16.0", "react-native-svg": "15.12.1", diff --git a/src/components/feed/FeedDetail.tsx b/src/components/feed/FeedDetail.tsx index 87d2178..cd6f460 100644 --- a/src/components/feed/FeedDetail.tsx +++ b/src/components/feed/FeedDetail.tsx @@ -1,29 +1,23 @@ -import React, { useEffect, useMemo, useState } from "react"; +import React, { useCallback, useMemo, useRef, useState } from "react"; import { FlatList, + ListRenderItem, View, Text, Image, - Modal, - Pressable, KeyboardAvoidingView, Platform, TouchableOpacity, StyleSheet, - useWindowDimensions, } from "react-native"; import { useNavigation } from "@react-navigation/native"; import type { NativeStackNavigationProp } from "@react-navigation/native-stack"; -import { Gesture, GestureDetector } from "react-native-gesture-handler"; -import Animated, { - Easing, - Extrapolation, - interpolate, - runOnJS, - useAnimatedStyle, - useSharedValue, - withTiming, -} from "react-native-reanimated"; +import { + BottomSheetBackdrop, + BottomSheetFlatList, + BottomSheetModal, + BottomSheetView, +} from "@gorhom/bottom-sheet"; import type { RootStackParamList } from "@/navigation/types"; import { HeartIcon, ChatIcon } from "@/assets/icons/CommonIcons"; @@ -48,11 +42,8 @@ export default function FeedDetail({ }: Props) { const navigation = useNavigation>(); - const [isCommentSheetVisible, setCommentSheetVisible] = useState(false); - const { height: windowHeight } = useWindowDimensions(); - const sheetHeight = Math.min(windowHeight * 0.6, 560); - const translateY = useSharedValue(sheetHeight); - const backdropOpacity = useSharedValue(0); + const bottomSheetModalRef = useRef(null); + const snapPoints = useMemo(() => ["60%", "90%"], []); const comments = useMemo( () => @@ -65,6 +56,12 @@ export default function FeedDetail({ [result.comments] ); + const renderCommentItem: ListRenderItem<(typeof comments)[number]> = ({ + item, + }) => ; + + const getCommentKey = (item: (typeof comments)[number]) => item.id.toString(); + const formatDate = (iso: string) => { const d = new Date(iso); return `${d.getFullYear()}년 ${d.getMonth() + 1}월 ${d.getDate()}일`; @@ -75,96 +72,25 @@ export default function FeedDetail({ }; const handleOpenComments = () => { - setCommentSheetVisible(true); + bottomSheetModalRef.current?.present(); }; const handleCloseComments = () => { - translateY.value = withTiming( - sheetHeight, - { - duration: 240, - easing: Easing.out(Easing.cubic), - }, - finished => { - if (finished) { - runOnJS(setCommentSheetVisible)(false); - } - } - ); - backdropOpacity.value = withTiming(0, { - duration: 220, - easing: Easing.out(Easing.quad), - }); + bottomSheetModalRef.current?.dismiss(); }; - useEffect(() => { - if (!isCommentSheetVisible) { - return; - } - - translateY.value = sheetHeight; - backdropOpacity.value = 0; - translateY.value = withTiming(0, { - duration: 260, - easing: Easing.out(Easing.cubic), - }); - backdropOpacity.value = withTiming(1, { - duration: 220, - easing: Easing.out(Easing.quad), - }); - }, [backdropOpacity, isCommentSheetVisible, sheetHeight, translateY]); - - const panGesture = Gesture.Pan() - .onUpdate(event => { - translateY.value = Math.max(0, event.translationY); - backdropOpacity.value = interpolate( - translateY.value, - [0, sheetHeight], - [1, 0], - Extrapolation.CLAMP - ); - }) - .onEnd(event => { - const shouldClose = - event.velocityY > 900 || translateY.value > sheetHeight * 0.28; - - if (shouldClose) { - translateY.value = withTiming( - sheetHeight, - { - duration: 220, - easing: Easing.out(Easing.cubic), - }, - finished => { - if (finished) { - runOnJS(setCommentSheetVisible)(false); - } - } - ); - backdropOpacity.value = withTiming(0, { - duration: 200, - easing: Easing.out(Easing.quad), - }); - return; - } - - translateY.value = withTiming(0, { - duration: 220, - easing: Easing.out(Easing.cubic), - }); - backdropOpacity.value = withTiming(1, { - duration: 200, - easing: Easing.out(Easing.quad), - }); - }); - - const backdropAnimatedStyle = useAnimatedStyle(() => ({ - opacity: backdropOpacity.value, - })); - - const sheetAnimatedStyle = useAnimatedStyle(() => ({ - transform: [{ translateY: translateY.value }], - })); + const renderBackdrop = useCallback( + (props: React.ComponentProps) => ( + + ), + [] + ); return ( <> @@ -225,66 +151,53 @@ export default function FeedDetail({ - - - - - - - - - - - 댓글 {result.commentCount} + + + 댓글 {result.commentCount} + + {comments.length > 0 ? ( + + data={comments} + keyExtractor={getCommentKey} + renderItem={renderCommentItem} + style={styles.commentList} + contentContainerStyle={styles.commentListContent} + showsVerticalScrollIndicator={false} + /> + ) : ( + + 아직 작성된 댓글이 없습니다. - - - {comments.length > 0 ? ( - item.id.toString()} - renderItem={({ item }) => } - style={styles.commentList} - contentContainerStyle={styles.commentListContent} - showsVerticalScrollIndicator={false} - /> - ) : ( - - 아직 작성된 댓글이 없습니다. - - )} + )} + + {onChangeComment && onSubmitComment ? ( + + {/* 한글 주석: + 라이브러리 바텀시트로 교체해 드래그와 스냅은 시트가 맡고, + 입력창은 하단 고정, 댓글 목록은 독립 스크롤 구조를 유지한다. */} + - {onChangeComment && onSubmitComment ? ( - - {/* 한글 주석: - 인스타처럼 댓글 입력창은 시트 하단에 고정하고, - 위쪽 댓글 목록만 독립적으로 스크롤되게 분리한다. */} - - - ) : null} - - - - + ) : null} + + + ); } @@ -376,44 +289,31 @@ const styles = StyleSheet.create({ spacer: { width: 40, }, - modalRoot: { - flex: 1, - justifyContent: "flex-end", - }, - backdrop: { - ...StyleSheet.absoluteFillObject, - backgroundColor: "rgba(0,0,0,0.28)", - }, - backdropPressable: { - flex: 1, - }, sheetKeyboard: { flex: 1, - justifyContent: "flex-end", }, - sheet: { + sheetBackground: { backgroundColor: "#FFFFFF", borderTopLeftRadius: 24, borderTopRightRadius: 24, - overflow: "hidden", }, - dragArea: { - paddingBottom: 8, + sheet: { + flex: 1, + backgroundColor: "#FFFFFF", + overflow: "hidden", }, sheetHandle: { - alignSelf: "center", width: 44, height: 5, borderRadius: 999, backgroundColor: "#D1D5DB", - marginTop: 10, - marginBottom: 14, }, sheetTitle: { fontSize: 16, fontWeight: "700", color: "#171717", textAlign: "center", + marginTop: 8, marginBottom: 8, }, sheetContent: { From e967b1cf29ec343503baffabf7599a6016e0ef8c Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 20:32:25 +0900 Subject: [PATCH 46/92] =?UTF-8?q?fix:=20=EB=A6=AC=EC=95=A0=EB=8B=88?= =?UTF-8?q?=EB=A9=94=EC=9D=B4=ED=8B=B0=EB=93=9C=20=EB=B2=84=EC=A0=84=20?= =?UTF-8?q?=EB=B6=88=EC=9D=BC=EC=B9=98=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- babel.config.js | 1 + package-lock.json | 31 ++++++++++++++++++++----------- package.json | 2 +- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/babel.config.js b/babel.config.js index cbccaaf..6139352 100644 --- a/babel.config.js +++ b/babel.config.js @@ -12,6 +12,7 @@ module.exports = function (api) { }, }, ], + "react-native-reanimated/plugin", ], }; }; diff --git a/package-lock.json b/package-lock.json index 2df44a9..2bc9c93 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,7 +33,7 @@ "react-native": "0.81.5", "react-native-gesture-handler": "~2.28.0", "react-native-pager-view": "6.9.1", - "react-native-reanimated": "~4.1.1", + "react-native-reanimated": "~4.2.1", "react-native-safe-area-context": "~5.6.0", "react-native-screens": "~4.16.0", "react-native-svg": "15.12.1", @@ -9278,25 +9278,34 @@ } }, "node_modules/react-native-reanimated": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-4.1.6.tgz", - "integrity": "sha512-F+ZJBYiok/6Jzp1re75F/9aLzkgoQCOh4yxrnwATa8392RvM3kx+fiXXFvwcgE59v48lMwd9q0nzF1oJLXpfxQ==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-4.2.2.tgz", + "integrity": "sha512-o3kKvdD8cVlg12Z4u3jv0MFAt53QV4k7gD9OLwQqU8eZLyd8QvaOjVZIghMZhC2pjP93uUU44PlO5JgF8S4Vxw==", "license": "MIT", "dependencies": { - "react-native-is-edge-to-edge": "^1.2.1", - "semver": "7.7.2" + "react-native-is-edge-to-edge": "1.2.1", + "semver": "7.7.3" }, "peerDependencies": { - "@babel/core": "^7.0.0-0", "react": "*", "react-native": "*", - "react-native-worklets": ">=0.5.0" + "react-native-worklets": ">=0.7.0" + } + }, + "node_modules/react-native-reanimated/node_modules/react-native-is-edge-to-edge": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/react-native-is-edge-to-edge/-/react-native-is-edge-to-edge-1.2.1.tgz", + "integrity": "sha512-FLbPWl/MyYQWz+KwqOZsSyj2JmLKglHatd3xLZWskXOpRaio4LfEDEz8E/A6uD8QoTHW6Aobw1jbEwK7KMgR7Q==", + "license": "MIT", + "peerDependencies": { + "react": "*", + "react-native": "*" } }, "node_modules/react-native-reanimated/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "license": "ISC", "bin": { "semver": "bin/semver.js" diff --git a/package.json b/package.json index c883f5d..07d8dc6 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "react-native": "0.81.5", "react-native-gesture-handler": "~2.28.0", "react-native-pager-view": "6.9.1", - "react-native-reanimated": "~4.1.1", + "react-native-reanimated": "~4.2.1", "react-native-safe-area-context": "~5.6.0", "react-native-screens": "~4.16.0", "react-native-svg": "15.12.1", From 3f55ccac12e7df1ffe9edb3d11f064d1433bc102 Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 20:36:17 +0900 Subject: [PATCH 47/92] =?UTF-8?q?fix:=20=EB=B0=94=ED=85=80=EC=8B=9C?= =?UTF-8?q?=ED=8A=B8=20=EB=AA=A8=EB=8B=AC=20=ED=94=84=EB=A1=9C=EB=B0=94?= =?UTF-8?q?=EC=9D=B4=EB=8D=94=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App.tsx | 50 ++++++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/App.tsx b/App.tsx index 4f3d96c..8265138 100644 --- a/App.tsx +++ b/App.tsx @@ -5,6 +5,7 @@ import { NavigationContainer, useNavigationContainerRef, } from "@react-navigation/native"; +import { BottomSheetModalProvider } from "@gorhom/bottom-sheet"; import { GestureHandlerRootView } from "react-native-gesture-handler"; import { SafeAreaProvider, SafeAreaView } from "react-native-safe-area-context"; import { RootNavigator } from "@/navigation"; @@ -41,30 +42,35 @@ export default function App() { - { - const routeName = navigationRef.getCurrentRoute()?.name; - currentRouteNameRef.current = routeName; - debugLog("Navigation", "ready", { routeName }); - }} - onStateChange={() => { - const previousRouteName = currentRouteNameRef.current; - const nextRouteName = navigationRef.getCurrentRoute()?.name; + {/* 한글 주석: + BottomSheetModal을 앱 어디서든 안정적으로 열 수 있도록 + 네비게이션 루트를 모달 provider로 감싼다. */} + + { + const routeName = navigationRef.getCurrentRoute()?.name; + currentRouteNameRef.current = routeName; + debugLog("Navigation", "ready", { routeName }); + }} + onStateChange={() => { + const previousRouteName = currentRouteNameRef.current; + const nextRouteName = navigationRef.getCurrentRoute()?.name; - if (previousRouteName !== nextRouteName) { - debugLog("Navigation", "route changed", { - from: previousRouteName, - to: nextRouteName, - }); - } + if (previousRouteName !== nextRouteName) { + debugLog("Navigation", "route changed", { + from: previousRouteName, + to: nextRouteName, + }); + } - currentRouteNameRef.current = nextRouteName; - }} - > - - - + currentRouteNameRef.current = nextRouteName; + }} + > + + + + From 237d8a02854ca99d93fae2907043cbc7931117af Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 20:44:49 +0900 Subject: [PATCH 48/92] =?UTF-8?q?feat:=20=ED=94=BC=EB=93=9C=20=EB=8C=93?= =?UTF-8?q?=EA=B8=80=20=EC=8B=9C=ED=8A=B8=20=EC=B4=88=EA=B8=B0=20=EB=86=92?= =?UTF-8?q?=EC=9D=B4=EC=99=80=20=EB=9E=9C=EB=8D=A4=20=EB=8C=93=EA=B8=80=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=20=EC=A7=80=EC=9B=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/feed/FeedAvatarDetailCard.tsx | 32 ++++++++++++++++++-- src/components/feed/FeedDetail.tsx | 2 ++ src/components/feed/FeedDiaryDetailCard.tsx | 32 ++++++++++++++++++-- 3 files changed, 62 insertions(+), 4 deletions(-) diff --git a/src/components/feed/FeedAvatarDetailCard.tsx b/src/components/feed/FeedAvatarDetailCard.tsx index 4797861..512df97 100644 --- a/src/components/feed/FeedAvatarDetailCard.tsx +++ b/src/components/feed/FeedAvatarDetailCard.tsx @@ -1,5 +1,7 @@ +import { useState } from "react"; import { ActivityIndicator, StyleSheet, Text, View } from "react-native"; import FeedDetail from "@/components/feed/FeedDetail"; +import usePostComment from "@/hooks/comments/useCommentApi"; import { useAvatarPostDetail } from "@/hooks/feed/useAvatarPostDetailApi"; import type { FeedDetailResult } from "@/types/feed/detail"; @@ -8,7 +10,25 @@ type Props = { }; export default function FeedAvatarDetailCard({ postId }: Props) { - const { data, isLoading, error } = useAvatarPostDetail(postId); + const { data, isLoading, error, refetch } = useAvatarPostDetail(postId); + const [content, setContent] = useState(""); + const { mutateAsync, isPending } = usePostComment(() => void refetch()); + + const handleSendComment = async () => { + if (!content.trim()) { + return; + } + + try { + await mutateAsync({ content, targetId: postId, targetType: "AVATAR_POST" }); + setContent(""); + } catch (commentError) { + console.error( + "[FeedAvatarDetailCard] Failed to post comment:", + commentError + ); + } + }; if (isLoading) { return ( @@ -43,7 +63,15 @@ export default function FeedAvatarDetailCard({ postId }: Props) { isPublic: data.isPublic, }; - return ; + return ( + void handleSendComment()} + isCommentPending={isPending} + /> + ); } const styles = StyleSheet.create({ diff --git a/src/components/feed/FeedDetail.tsx b/src/components/feed/FeedDetail.tsx index cd6f460..03c9e2e 100644 --- a/src/components/feed/FeedDetail.tsx +++ b/src/components/feed/FeedDetail.tsx @@ -153,7 +153,9 @@ export default function FeedDetail({ void refetch()); + + const handleSendComment = async () => { + if (!content.trim()) { + return; + } + + try { + await mutateAsync({ content, targetId: postId, targetType: "DIARY" }); + setContent(""); + } catch (commentError) { + console.error( + "[FeedDiaryDetailCard] Failed to post comment:", + commentError + ); + } + }; if (isLoading) { return ( @@ -43,7 +63,15 @@ export default function FeedDiaryDetailCard({ postId }: Props) { isPublic: data.isPublic, }; - return ; + return ( + void handleSendComment()} + isCommentPending={isPending} + /> + ); } const styles = StyleSheet.create({ From 13a22629fc126d8c0a11c608886b588223537601 Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 20:48:52 +0900 Subject: [PATCH 49/92] =?UTF-8?q?fix:=20=ED=94=BC=EB=93=9C=20=EB=8C=93?= =?UTF-8?q?=EA=B8=80=20=EC=9E=85=EB=A0=A5=EC=B0=BD=20=ED=95=98=EB=8B=A8=20?= =?UTF-8?q?=EA=B3=A0=EC=A0=95=20=EB=B3=B4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/feed/FeedDetail.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/feed/FeedDetail.tsx b/src/components/feed/FeedDetail.tsx index 03c9e2e..1fccb8b 100644 --- a/src/components/feed/FeedDetail.tsx +++ b/src/components/feed/FeedDetail.tsx @@ -338,6 +338,7 @@ const styles = StyleSheet.create({ textAlign: "center", }, composerContainer: { + marginTop: "auto", borderTopWidth: 1, borderTopColor: "#E5E7EB", backgroundColor: "#FFFFFF", From 742162df7378ed9646ff495cb8e1782a55175b72 Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 20:56:27 +0900 Subject: [PATCH 50/92] =?UTF-8?q?refactor:=20=ED=94=BC=EB=93=9C=20?= =?UTF-8?q?=EB=8C=93=EA=B8=80=20=EC=9E=85=EB=A0=A5=EC=B0=BD=EC=9D=84=20?= =?UTF-8?q?=EB=B0=94=ED=85=80=EC=8B=9C=ED=8A=B8=20=ED=91=B8=ED=84=B0?= =?UTF-8?q?=EB=A1=9C=20=EA=B3=A0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/feed/FeedDetail.tsx | 45 +++++++++++++++++++----------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/src/components/feed/FeedDetail.tsx b/src/components/feed/FeedDetail.tsx index 1fccb8b..0b19703 100644 --- a/src/components/feed/FeedDetail.tsx +++ b/src/components/feed/FeedDetail.tsx @@ -14,6 +14,7 @@ import { useNavigation } from "@react-navigation/native"; import type { NativeStackNavigationProp } from "@react-navigation/native-stack"; import { BottomSheetBackdrop, + BottomSheetFooter, BottomSheetFlatList, BottomSheetModal, BottomSheetView, @@ -92,6 +93,31 @@ export default function FeedDetail({ [] ); + const renderFooter = useCallback( + (props: React.ComponentProps) => { + if (!onChangeComment || !onSubmitComment) { + return null; + } + + return ( + + + {/* 한글 주석: + 댓글 입력창은 바텀시트 본문 흐름과 분리된 footer로 렌더링해 + 댓글 수와 관계없이 항상 시트 최하단에 고정한다. */} + + + + ); + }, + [commentValue, isCommentPending, onChangeComment, onSubmitComment] + ); + return ( <> @@ -158,6 +184,7 @@ export default function FeedDetail({ enableDynamicSizing={false} enablePanDownToClose backdropComponent={renderBackdrop} + footerComponent={renderFooter} handleIndicatorStyle={styles.sheetHandle} backgroundStyle={styles.sheetBackground} onDismiss={handleCloseComments} @@ -184,19 +211,6 @@ export default function FeedDetail({ )} - {onChangeComment && onSubmitComment ? ( - - {/* 한글 주석: - 라이브러리 바텀시트로 교체해 드래그와 스냅은 시트가 맡고, - 입력창은 하단 고정, 댓글 목록은 독립 스크롤 구조를 유지한다. */} - - - ) : null} @@ -325,7 +339,7 @@ const styles = StyleSheet.create({ flex: 1, }, commentListContent: { - paddingBottom: 16, + paddingBottom: 120, }, emptyState: { flex: 1, @@ -338,9 +352,6 @@ const styles = StyleSheet.create({ textAlign: "center", }, composerContainer: { - marginTop: "auto", - borderTopWidth: 1, - borderTopColor: "#E5E7EB", backgroundColor: "#FFFFFF", }, }); From 7b2a084ebbfdb9757cd951683e90923936ab799f Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 21:11:49 +0900 Subject: [PATCH 51/92] =?UTF-8?q?feat:=20=ED=94=BC=EB=93=9C=20=EA=B3=B5?= =?UTF-8?q?=EA=B0=90=20=ED=86=A0=EA=B8=80=20API=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/feed/likeApi.ts | 30 ++++++++ src/components/feed/FeedAvatarDetailCard.tsx | 13 ++++ src/components/feed/FeedDetail.tsx | 30 +++++++- src/components/feed/FeedDiaryDetailCard.tsx | 13 ++++ .../feed/FeedInfiniteDetailItem.tsx | 6 +- src/components/feed/FeedSeedDetailCard.tsx | 18 +++++ src/hooks/feed/useFeedLikeToggle.ts | 77 +++++++++++++++++++ src/pages/feed/FeedAvatarScreen.tsx | 1 + src/pages/feed/FeedDiaryScreen.tsx | 1 + 9 files changed, 184 insertions(+), 5 deletions(-) create mode 100644 src/apis/feed/likeApi.ts create mode 100644 src/hooks/feed/useFeedLikeToggle.ts diff --git a/src/apis/feed/likeApi.ts b/src/apis/feed/likeApi.ts new file mode 100644 index 0000000..eef3436 --- /dev/null +++ b/src/apis/feed/likeApi.ts @@ -0,0 +1,30 @@ +import api from "@/apis/instance"; +import type { ApiResponse, NoResponse } from "@/types/common/apiResponse.type"; + +export type FeedLikeTargetType = "DIARY" | "AVATAR_POST"; + +export const likeFeedTarget = async ( + targetId: number, + targetType: FeedLikeTargetType +): ApiResponse => { + const endpoint = + targetType === "DIARY" + ? `/api/v1/diaries/${targetId}/likes` + : `/api/v1/avatar-posts/${targetId}/likes`; + + const res = await api.post(endpoint); + return res.data; +}; + +export const unlikeFeedTarget = async ( + targetId: number, + targetType: FeedLikeTargetType +): ApiResponse => { + const endpoint = + targetType === "DIARY" + ? `/api/v1/diaries/${targetId}/likes` + : `/api/v1/avatar-posts/${targetId}/likes`; + + const res = await api.delete(endpoint); + return res.data; +}; diff --git a/src/components/feed/FeedAvatarDetailCard.tsx b/src/components/feed/FeedAvatarDetailCard.tsx index 512df97..b9ffc65 100644 --- a/src/components/feed/FeedAvatarDetailCard.tsx +++ b/src/components/feed/FeedAvatarDetailCard.tsx @@ -2,6 +2,7 @@ import { useState } from "react"; import { ActivityIndicator, StyleSheet, Text, View } from "react-native"; import FeedDetail from "@/components/feed/FeedDetail"; import usePostComment from "@/hooks/comments/useCommentApi"; +import useFeedLikeToggle from "@/hooks/feed/useFeedLikeToggle"; import { useAvatarPostDetail } from "@/hooks/feed/useAvatarPostDetailApi"; import type { FeedDetailResult } from "@/types/feed/detail"; @@ -63,9 +64,21 @@ export default function FeedAvatarDetailCard({ postId }: Props) { isPublic: data.isPublic, }; + const { liked, likeCount, toggleLike, isLikePending } = useFeedLikeToggle({ + targetId: postId, + targetType: "AVATAR_POST", + initialLiked: result.isLiked, + initialLikeCount: result.likeCount, + onSuccessRefetch: refetch, + }); + return ( void handleSendComment()} diff --git a/src/components/feed/FeedDetail.tsx b/src/components/feed/FeedDetail.tsx index 0b19703..47646b6 100644 --- a/src/components/feed/FeedDetail.tsx +++ b/src/components/feed/FeedDetail.tsx @@ -28,6 +28,10 @@ import type { FeedDetailResult } from "@/types/feed/detail"; type Props = { result: FeedDetailResult; + liked?: boolean; + likeCount?: number; + onToggleLike?: () => void; + isLikePending?: boolean; commentValue?: string; onChangeComment?: (text: string) => void; onSubmitComment?: () => void; @@ -36,6 +40,10 @@ type Props = { export default function FeedDetail({ result, + liked = result.isLiked, + likeCount = result.likeCount, + onToggleLike, + isLikePending = false, commentValue = "", onChangeComment, onSubmitComment, @@ -159,10 +167,21 @@ export default function FeedDetail({ {/* 공감 */} - - - 공감 {result.likeCount} - + + + + 공감 {likeCount} + + {/* 댓글 */} void handleSendComment()} diff --git a/src/components/feed/FeedInfiniteDetailItem.tsx b/src/components/feed/FeedInfiniteDetailItem.tsx index 74b9de1..196e661 100644 --- a/src/components/feed/FeedInfiniteDetailItem.tsx +++ b/src/components/feed/FeedInfiniteDetailItem.tsx @@ -9,6 +9,7 @@ type Props = { postType: RandomFeedPostType; isSeed: boolean; seedResult?: FeedDetailResult; + onSeedRefetch?: () => void | Promise; commentValue?: string; onChangeComment?: (value: string) => void; onSubmitComment?: () => void; @@ -20,15 +21,18 @@ export default function FeedInfiniteDetailItem({ postType, isSeed, seedResult, + onSeedRefetch, commentValue = "", onChangeComment, onSubmitComment, isCommentPending = false, }: Props) { - if (isSeed && seedResult && onChangeComment && onSubmitComment) { + if (isSeed && seedResult && onSeedRefetch && onChangeComment && onSubmitComment) { return ( void | Promise; commentValue: string; onChangeComment: (value: string) => void; onSubmitComment: () => void; @@ -12,11 +16,21 @@ type Props = { export default function FeedSeedDetailCard({ result, + postType, + onRefetch, commentValue, onChangeComment, onSubmitComment, isCommentPending, }: Props) { + const { liked, likeCount, toggleLike, isLikePending } = useFeedLikeToggle({ + targetId: result.id, + targetType: postType, + initialLiked: result.isLiked, + initialLikeCount: result.likeCount, + onSuccessRefetch: onRefetch, + }); + return ( {/* 한글 주석: @@ -24,6 +38,10 @@ export default function FeedSeedDetailCard({ 기존 상세 댓글 작성 UX도 댓글 시트 안에서만 유지한다. */} void | Promise; +}; + +export default function useFeedLikeToggle({ + targetId, + targetType, + initialLiked, + initialLikeCount, + onSuccessRefetch, +}: Params) { + const [liked, setLiked] = useState(initialLiked); + const [likeCount, setLikeCount] = useState(initialLikeCount); + + useEffect(() => { + setLiked(initialLiked); + setLikeCount(initialLikeCount); + }, [initialLiked, initialLikeCount]); + + const mutation = useMutation({ + mutationFn: async () => { + if (liked) { + await unlikeFeedTarget(targetId, targetType); + return false; + } + + await likeFeedTarget(targetId, targetType); + return true; + }, + onMutate: () => { + const nextLiked = !liked; + const nextLikeCount = Math.max(0, likeCount + (nextLiked ? 1 : -1)); + + setLiked(nextLiked); + setLikeCount(nextLikeCount); + + return { previousLiked: liked, previousLikeCount: likeCount }; + }, + onError: (_error, _variables, context) => { + if (!context) { + return; + } + + setLiked(context.previousLiked); + setLikeCount(context.previousLikeCount); + }, + onSuccess: () => { + void onSuccessRefetch?.(); + }, + }); + + return { + liked, + likeCount, + toggleLike: () => { + if (mutation.isPending) { + return; + } + + mutation.mutate(); + }, + isLikePending: mutation.isPending, + }; +} diff --git a/src/pages/feed/FeedAvatarScreen.tsx b/src/pages/feed/FeedAvatarScreen.tsx index 3e373a2..6d4d927 100644 --- a/src/pages/feed/FeedAvatarScreen.tsx +++ b/src/pages/feed/FeedAvatarScreen.tsx @@ -184,6 +184,7 @@ export default function FeedAvatarScreen({ navigation, route }: Props) { postType={item.postType} isSeed={item.isSeed} seedResult={item.isSeed ? seedResult : undefined} + onSeedRefetch={item.isSeed ? refetch : undefined} commentValue={item.isSeed ? content : ""} onChangeComment={item.isSeed ? setContent : undefined} onSubmitComment={item.isSeed ? () => void handleSend() : undefined} diff --git a/src/pages/feed/FeedDiaryScreen.tsx b/src/pages/feed/FeedDiaryScreen.tsx index 47ef6ed..b457b83 100644 --- a/src/pages/feed/FeedDiaryScreen.tsx +++ b/src/pages/feed/FeedDiaryScreen.tsx @@ -179,6 +179,7 @@ export default function FeedDiaryScreen({ navigation, route }: Props) { postType={item.postType} isSeed={item.isSeed} seedResult={item.isSeed ? seedResult : undefined} + onSeedRefetch={item.isSeed ? refetch : undefined} commentValue={item.isSeed ? content : ""} onChangeComment={item.isSeed ? setContent : undefined} onSubmitComment={item.isSeed ? () => void handleSend() : undefined} From e7cefe8ce81251532fa40b6133957d811e5429e5 Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 21:24:33 +0900 Subject: [PATCH 52/92] =?UTF-8?q?fix:=20=ED=94=BC=EB=93=9C=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=ED=9B=85=20=ED=98=B8=EC=B6=9C=20=EC=88=9C=EC=84=9C?= =?UTF-8?q?=20=EB=B3=B4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/feed/FeedAvatarDetailCard.tsx | 15 +++++++-------- src/components/feed/FeedDiaryDetailCard.tsx | 15 +++++++-------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/components/feed/FeedAvatarDetailCard.tsx b/src/components/feed/FeedAvatarDetailCard.tsx index b9ffc65..0762858 100644 --- a/src/components/feed/FeedAvatarDetailCard.tsx +++ b/src/components/feed/FeedAvatarDetailCard.tsx @@ -14,6 +14,13 @@ export default function FeedAvatarDetailCard({ postId }: Props) { const { data, isLoading, error, refetch } = useAvatarPostDetail(postId); const [content, setContent] = useState(""); const { mutateAsync, isPending } = usePostComment(() => void refetch()); + const { liked, likeCount, toggleLike, isLikePending } = useFeedLikeToggle({ + targetId: postId, + targetType: "AVATAR_POST", + initialLiked: data?.isLiked ?? false, + initialLikeCount: data?.likeCount ?? 0, + onSuccessRefetch: refetch, + }); const handleSendComment = async () => { if (!content.trim()) { @@ -64,14 +71,6 @@ export default function FeedAvatarDetailCard({ postId }: Props) { isPublic: data.isPublic, }; - const { liked, likeCount, toggleLike, isLikePending } = useFeedLikeToggle({ - targetId: postId, - targetType: "AVATAR_POST", - initialLiked: result.isLiked, - initialLikeCount: result.likeCount, - onSuccessRefetch: refetch, - }); - return ( void refetch()); + const { liked, likeCount, toggleLike, isLikePending } = useFeedLikeToggle({ + targetId: postId, + targetType: "DIARY", + initialLiked: data?.isLiked ?? false, + initialLikeCount: data?.likeCount ?? 0, + onSuccessRefetch: refetch, + }); const handleSendComment = async () => { if (!content.trim()) { @@ -64,14 +71,6 @@ export default function FeedDiaryDetailCard({ postId }: Props) { isPublic: data.isPublic, }; - const { liked, likeCount, toggleLike, isLikePending } = useFeedLikeToggle({ - targetId: postId, - targetType: "DIARY", - initialLiked: result.isLiked, - initialLikeCount: result.likeCount, - onSuccessRefetch: refetch, - }); - return ( Date: Sun, 15 Mar 2026 21:30:28 +0900 Subject: [PATCH 53/92] =?UTF-8?q?fix:=20=ED=94=BC=EB=93=9C=20=EA=B3=B5?= =?UTF-8?q?=EA=B0=90=20=ED=86=A0=EA=B8=80=20=EC=9A=94=EC=B2=AD=20=EB=B0=A9?= =?UTF-8?q?=ED=96=A5=20=EA=B3=A0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/feed/useFeedLikeToggle.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hooks/feed/useFeedLikeToggle.ts b/src/hooks/feed/useFeedLikeToggle.ts index 2eaed43..ac6d26c 100644 --- a/src/hooks/feed/useFeedLikeToggle.ts +++ b/src/hooks/feed/useFeedLikeToggle.ts @@ -31,8 +31,8 @@ export default function useFeedLikeToggle({ }, [initialLiked, initialLikeCount]); const mutation = useMutation({ - mutationFn: async () => { - if (liked) { + mutationFn: async (nextLiked: boolean) => { + if (!nextLiked) { await unlikeFeedTarget(targetId, targetType); return false; } @@ -40,8 +40,7 @@ export default function useFeedLikeToggle({ await likeFeedTarget(targetId, targetType); return true; }, - onMutate: () => { - const nextLiked = !liked; + onMutate: nextLiked => { const nextLikeCount = Math.max(0, likeCount + (nextLiked ? 1 : -1)); setLiked(nextLiked); @@ -70,7 +69,8 @@ export default function useFeedLikeToggle({ return; } - mutation.mutate(); + const nextLiked = !liked; + mutation.mutate(nextLiked); }, isLikePending: mutation.isPending, }; From 9411f97414c7abc65a2d25fdbbc39170744b910e Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 22:14:24 +0900 Subject: [PATCH 54/92] =?UTF-8?q?refactor:=20=ED=83=80=EC=9D=B8=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=EC=9D=84=20=EC=A0=95=EC=9B=90=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A0=80=20=EA=B5=AC=EC=A1=B0=EB=A1=9C=20?= =?UTF-8?q?=EC=9E=AC=EA=B5=AC=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/profile/ProfileGardenScene.tsx | 226 +++++++++++++++++ src/pages/profile/ProfileScreen.tsx | 236 ++++++++++-------- 2 files changed, 363 insertions(+), 99 deletions(-) create mode 100644 src/components/profile/ProfileGardenScene.tsx diff --git a/src/components/profile/ProfileGardenScene.tsx b/src/components/profile/ProfileGardenScene.tsx new file mode 100644 index 0000000..cc50cd1 --- /dev/null +++ b/src/components/profile/ProfileGardenScene.tsx @@ -0,0 +1,226 @@ +import { Image, ImageBackground, StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import { useSafeAreaInsets } from "react-native-safe-area-context"; +import type { GardenInfo } from "@/types/profile/profileApi.type"; +import WaterIcon from "@/assets/icons/water.svg"; + +const ACTION_RAIL_BOTTOM_OFFSET = 128; + +type FollowAction = { + label: string; + onPress: () => void; + pending: boolean; +}; + +type Props = { + background: any; + garden: GardenInfo; + userNickname: string; + leftWaterCountForOthers: number; + isMe: boolean; + followAction: FollowAction | null; + onBack: () => void; + onWater: () => void; + waterDisabled?: boolean; +}; + +export default function ProfileGardenScene({ + background, + garden, + userNickname, + leftWaterCountForOthers, + isMe, + followAction, + onBack, + onWater, + waterDisabled = false, +}: Props) { + const insets = useSafeAreaInsets(); + const canWater = !isMe && garden.isWateringAbleByMe && !waterDisabled; + const avatarName = garden.avatarInfo?.avatarName ?? `${userNickname}의 정원`; + + return ( + + + + + + {"<"} + + + {avatarName} + + + {followAction ? ( + + + {followAction.pending ? "처리 중..." : followAction.label} + + + ) : isMe ? ( + 내 프로필 + ) : null} + + + + {!isMe ? ( + + + {leftWaterCountForOthers}회 + + ) : null} + + + {garden.avatarInfo?.avatarImageUrl ? ( + + ) : ( + + 정원 정보가 준비되지 않았습니다. + + 현재 프로필 API 기준으로 표시할 식물 이미지가 없습니다. + + + )} + + + {!isMe ? ( + + + + + + ) : null} + + ); +} + +const styles = StyleSheet.create({ + sceneBackground: { + flex: 1, + }, + sceneShade: { + ...StyleSheet.absoluteFillObject, + backgroundColor: "rgba(8, 20, 10, 0.08)", + }, + sceneHeader: { + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + paddingHorizontal: 16, + zIndex: 2, + }, + headerSideButton: { + width: 72, + alignItems: "center", + justifyContent: "center", + minHeight: 44, + }, + backArrow: { + fontSize: 22, + fontWeight: "700", + color: "#FFFFFF", + textShadowColor: "rgba(0,0,0,0.18)", + textShadowOffset: { width: 0, height: 1 }, + textShadowRadius: 4, + }, + sceneTitle: { + flex: 1, + textAlign: "center", + fontSize: 22, + fontWeight: "700", + color: "#FFFFFF", + textShadowColor: "rgba(0, 0, 0, 0.18)", + textShadowOffset: { width: 0, height: 1 }, + textShadowRadius: 4, + }, + followTextButton: { + fontSize: 14, + fontWeight: "600", + color: "#FFFFFF", + textShadowColor: "rgba(0,0,0,0.18)", + textShadowOffset: { width: 0, height: 1 }, + textShadowRadius: 4, + textAlign: "center", + }, + selfBadgeText: { + fontSize: 13, + color: "rgba(255,255,255,0.7)", + }, + waterCountBadge: { + position: "absolute", + right: 16, + flexDirection: "row", + alignItems: "center", + gap: 4, + zIndex: 3, + }, + waterCountText: { + fontSize: 16, + fontWeight: "700", + color: "#FFFFFF", + textShadowColor: "rgba(0,0,0,0.18)", + textShadowOffset: { width: 0, height: 1 }, + textShadowRadius: 4, + }, + sceneBody: { + flex: 1, + justifyContent: "center", + alignItems: "center", + paddingHorizontal: 24, + paddingBottom: 64, + }, + avatarImage: { + width: 300, + height: 300, + }, + emptyAvatarBubble: { + borderRadius: 24, + backgroundColor: "rgba(255,255,255,0.92)", + paddingHorizontal: 24, + paddingVertical: 18, + alignItems: "center", + gap: 6, + }, + emptyAvatarTitle: { + fontSize: 16, + fontWeight: "700", + color: "#171717", + textAlign: "center", + }, + emptyAvatarBody: { + fontSize: 14, + lineHeight: 20, + color: "#4B5563", + textAlign: "center", + }, + actionRail: { + position: "absolute", + right: 12, + zIndex: 3, + gap: 8, + }, + actionButton: { + width: 64, + height: 64, + borderRadius: 32, + backgroundColor: "rgba(255,255,255,0.18)", + alignItems: "center", + justifyContent: "center", + overflow: "hidden", + }, + actionButtonDisabled: { + backgroundColor: "rgba(255,255,255,0.08)", + }, +}); diff --git a/src/pages/profile/ProfileScreen.tsx b/src/pages/profile/ProfileScreen.tsx index 30ea859..a4ca490 100644 --- a/src/pages/profile/ProfileScreen.tsx +++ b/src/pages/profile/ProfileScreen.tsx @@ -1,4 +1,4 @@ -import { useMemo } from "react"; +import { useMemo, useState } from "react"; import { Image, ScrollView, @@ -7,21 +7,25 @@ import { TouchableOpacity, View, } from "react-native"; +import PagerView from "react-native-pager-view"; import { SafeAreaView } from "react-native-safe-area-context"; import type { RootStackScreenProps } from "@/navigation/types"; -import ScreenHeader from "@/components/common/ScreenHeader"; import StatusView from "@/components/common/StatusView"; -import ProfileDetail from "@/components/profile/ProfileDetail"; -import { - useFriendWater, - useUserProfile, -} from "@/hooks/profile/useProfileApi"; +import ProfileGardenScene from "@/components/profile/ProfileGardenScene"; +import { useFriendWater, useUserProfile } from "@/hooks/profile/useProfileApi"; import { useFollowUser, useUnfollowUser } from "@/hooks/follow/useFollowApi"; import useTokenStore from "@/stores/useTokenStore"; import { FollowStatus } from "@/types/profile/profileApi.type"; type Props = RootStackScreenProps<"Profile">; +const backgrounds = [ + require("@/assets/images/background/background1.webp"), + require("@/assets/images/background/background2.webp"), + require("@/assets/images/background/background3.png"), + require("@/assets/images/background/background4.webp"), +] as const; + export default function ProfileScreen({ navigation, route }: Props) { const { userId: myUserId } = useTokenStore(); const userId = route.params.userId; @@ -29,6 +33,7 @@ export default function ProfileScreen({ navigation, route }: Props) { const waterMutation = useFriendWater(userId); const followMutation = useFollowUser(myUserId); const unfollowMutation = useUnfollowUser(myUserId); + const [currentPage, setCurrentPage] = useState(0); const isMe = String(userId) === myUserId; @@ -71,7 +76,6 @@ export default function ProfileScreen({ navigation, route }: Props) { if (isLoading) { return ( - ); @@ -80,7 +84,6 @@ export default function ProfileScreen({ navigation, route }: Props) { if (error) { return ( - - ({ + key: `profile-garden-${garden.gardenId}`, + background: backgrounds[index % backgrounds.length], + garden, + })); + + if (scenes.length === 0) { + return ( + + + + + 뒤로가기 + + - return ( - - - - {data.profileImageUrl ? ( @@ -122,79 +133,141 @@ export default function ProfileScreen({ navigation, route }: Props) { /> ) : null} - - {data.userNickname} - - 남은 친구 물주기 {data.leftWaterCountForOthers}회 - - + {data.userNickname} {followAction ? ( - + {followAction.pending ? "처리 중..." : followAction.label} - ) : ( - - {isMe ? "내 프로필" : ""} - - )} + ) : isMe ? ( + 내 프로필 + ) : null} - - {primaryGarden ? ( - void waterMutation.mutateAsync(primaryGarden.gardenId)} - waterDisabled={waterMutation.isPending} - /> - ) : ( 정원 정보가 없습니다. - 현재 API 기준으로 대표 정원 정보가 없어서 기본 정보만 표시합니다. + 현재 API 기준으로 표시할 정원 데이터가 없어 기본 정보만 표시합니다. - )} + + + ); + } - - 이번 단계에서 보류된 항목 - - 방명록, 프로필 추가 상호작용, 대표 정원 외 상세 뷰는 API 범위 확인 후 확장합니다. - + return ( + + setCurrentPage(event.nativeEvent.position)} + > + {scenes.map(scene => ( + + {/* 한글 주석: + 타인 프로필은 홈처럼 정원 중심 화면을 쓰되, + 정원 개수는 해금된 userGardens 길이만큼만 페이지를 만든다. */} + void waterMutation.mutateAsync(scene.garden.gardenId)} + waterDisabled={waterMutation.isPending} + /> + + ))} + + + + + {scenes.map((scene, index) => ( + + ))} - - + + ); } const styles = StyleSheet.create({ container: { flex: 1, + backgroundColor: "#F4F7F0", + }, + sceneContainer: { + flex: 1, + backgroundColor: "#DDE8D6", + }, + pager: { + flex: 1, + }, + page: { + flex: 1, + }, + overlaySafeArea: { + position: "absolute", + top: 0, + left: 0, + right: 0, + }, + pagination: { + marginTop: 84, + alignSelf: "center", + flexDirection: "row", + alignItems: "center", + gap: 8, + }, + dot: { + width: 8, + height: 8, + borderRadius: 999, + }, + dotActive: { + width: 22, backgroundColor: "#FFFFFF", }, - scrollView: { + dotInactive: { + backgroundColor: "rgba(255,255,255,0.45)", + }, + emptyContainer: { flex: 1, + backgroundColor: "#FFFFFF", }, - summaryCard: { + emptyHeader: { paddingHorizontal: 20, - paddingTop: 20, + paddingTop: 16, + }, + emptyBackText: { + fontSize: 14, + fontWeight: "600", + color: "#6B7280", }, summaryRow: { flexDirection: "row", alignItems: "center", - gap: 12, + paddingHorizontal: 20, + paddingVertical: 14, + gap: 10, }, profileImageWrap: { - width: 56, - height: 56, - borderRadius: 28, + width: 40, + height: 40, + borderRadius: 20, backgroundColor: "#E5E7EB", overflow: "hidden", }, @@ -202,37 +275,20 @@ const styles = StyleSheet.create({ width: "100%", height: "100%", }, - summaryTextWrap: { - flex: 1, - gap: 4, - }, nickname: { - fontSize: 20, - fontWeight: "700", + flex: 1, + fontSize: 16, + fontWeight: "600", color: "#171717", }, - metaText: { - fontSize: 13, - color: "#6B7280", - }, - followButton: { - borderRadius: 999, - backgroundColor: "#4CAF50", - paddingHorizontal: 14, - paddingVertical: 10, - }, - followButtonText: { - color: "#FFFFFF", - fontSize: 13, - fontWeight: "700", - }, - selfBadge: { - minWidth: 64, - alignItems: "flex-end", + followTextButton: { + fontSize: 14, + fontWeight: "600", + color: "#4CAF50", }, selfBadgeText: { - fontSize: 12, - color: "#6B7280", + fontSize: 13, + color: "#9CA3AF", }, emptyGardenWrap: { paddingHorizontal: 20, @@ -249,22 +305,4 @@ const styles = StyleSheet.create({ lineHeight: 20, color: "#6B7280", }, - todoCard: { - margin: 20, - marginTop: 4, - borderRadius: 16, - backgroundColor: "#F8FAF6", - padding: 16, - gap: 6, - }, - todoTitle: { - fontSize: 15, - fontWeight: "700", - color: "#171717", - }, - todoText: { - fontSize: 13, - lineHeight: 18, - color: "#6B7280", - }, }); From e05e2eb8a4b090036a2c99bad7a0ab4935f06832 Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 22:17:44 +0900 Subject: [PATCH 55/92] =?UTF-8?q?feat:=20=EB=B0=A9=EB=AA=85=EB=A1=9D=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=EC=99=80=20=EC=9E=91=EC=84=B1=20API=20?= =?UTF-8?q?=ED=9B=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/profile/guestbookApi.ts | 21 +++++++++++++++++++ src/hooks/profile/useGuestbookApi.ts | 28 ++++++++++++++++++++++++++ src/types/profile/guestbookApi.type.ts | 11 ++++++++++ 3 files changed, 60 insertions(+) create mode 100644 src/apis/profile/guestbookApi.ts create mode 100644 src/hooks/profile/useGuestbookApi.ts create mode 100644 src/types/profile/guestbookApi.type.ts diff --git a/src/apis/profile/guestbookApi.ts b/src/apis/profile/guestbookApi.ts new file mode 100644 index 0000000..69e902a --- /dev/null +++ b/src/apis/profile/guestbookApi.ts @@ -0,0 +1,21 @@ +import api from "@/apis/instance"; +import type { ApiResponse, NoResponse } from "@/types/common/apiResponse.type"; +import type { + CreateGuestbookRequest, + GuestbookEntry, +} from "@/types/profile/guestbookApi.type"; + +export const getGuestbookList = async ( + userId: string | number +): ApiResponse => { + const res = await api.get(`/api/v1/users/guestbook/${userId}/list`); + return res.data; +}; + +export const postGuestbook = async ( + userId: string | number, + body: CreateGuestbookRequest +): ApiResponse => { + const res = await api.post(`/api/v1/users/${userId}/guestbook`, body); + return res.data; +}; diff --git a/src/hooks/profile/useGuestbookApi.ts b/src/hooks/profile/useGuestbookApi.ts new file mode 100644 index 0000000..de70b7e --- /dev/null +++ b/src/hooks/profile/useGuestbookApi.ts @@ -0,0 +1,28 @@ +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import type { AxiosError } from "axios"; +import type { GlobalResponse } from "@/types/common/apiResponse.type"; +import type { + CreateGuestbookRequest, + GuestbookEntry, +} from "@/types/profile/guestbookApi.type"; +import { getGuestbookList, postGuestbook } from "@/apis/profile/guestbookApi"; + +export const useGuestbookList = (userId: string | number | undefined) => + useQuery, AxiosError, GuestbookEntry[]>({ + queryKey: ["guestbook-list", userId], + queryFn: () => getGuestbookList(String(userId)), + select: data => data.result, + enabled: !!userId, + refetchOnMount: "always", + }); + +export const useCreateGuestbook = (userId: string | number | undefined) => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: (body: CreateGuestbookRequest) => postGuestbook(String(userId), body), + onSuccess: async () => { + await queryClient.invalidateQueries({ queryKey: ["guestbook-list", userId] }); + }, + }); +}; diff --git a/src/types/profile/guestbookApi.type.ts b/src/types/profile/guestbookApi.type.ts new file mode 100644 index 0000000..d02b6e2 --- /dev/null +++ b/src/types/profile/guestbookApi.type.ts @@ -0,0 +1,11 @@ +export type GuestbookEntry = { + author: string; + content: string; + createdAt: string; +}; + +export type CreateGuestbookRequest = { + content: string; +}; + +export type CreateGuestbookResponse = Record; From a1e9875338ee9a6251a7f7708c6f8a4fbfd2e93b Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 22:21:34 +0900 Subject: [PATCH 56/92] =?UTF-8?q?feat:=20=EB=B0=A9=EB=AA=85=EB=A1=9D=20?= =?UTF-8?q?=EC=A0=84=EC=B2=B4=20=ED=99=94=EB=A9=B4=EA=B3=BC=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=ED=95=84=20=EC=A7=84=EC=9E=85=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/profile/ProfileGardenScene.tsx | 33 ++++ src/navigation/RootNavigator.tsx | 2 + src/navigation/types.ts | 1 + src/pages/profile/GuestbookScreen.tsx | 187 ++++++++++++++++++ src/pages/profile/ProfileScreen.tsx | 8 + 5 files changed, 231 insertions(+) create mode 100644 src/pages/profile/GuestbookScreen.tsx diff --git a/src/components/profile/ProfileGardenScene.tsx b/src/components/profile/ProfileGardenScene.tsx index cc50cd1..ac49588 100644 --- a/src/components/profile/ProfileGardenScene.tsx +++ b/src/components/profile/ProfileGardenScene.tsx @@ -20,6 +20,7 @@ type Props = { followAction: FollowAction | null; onBack: () => void; onWater: () => void; + onPressGuestbook: () => void; waterDisabled?: boolean; }; @@ -32,6 +33,7 @@ export default function ProfileGardenScene({ followAction, onBack, onWater, + onPressGuestbook, waterDisabled = false, }: Props) { const insets = useSafeAreaInsets(); @@ -102,6 +104,17 @@ export default function ProfileGardenScene({ ) : null} + + {!isMe ? ( + + {/* 한글 주석: + 타인 프로필의 방명록 버튼은 별도 전체 화면 방명록 페이지로 이동시키고, + 목록 확인과 새 글 작성은 그 화면에서 처리한다. */} + + 방명록 작성 + + + ) : null} ); } @@ -223,4 +236,24 @@ const styles = StyleSheet.create({ actionButtonDisabled: { backgroundColor: "rgba(255,255,255,0.08)", }, + guestbookWrap: { + paddingHorizontal: 16, + paddingTop: 8, + }, + guestbookButton: { + borderRadius: 18, + backgroundColor: "rgba(255,255,255,0.92)", + paddingVertical: 18, + alignItems: "center", + shadowColor: "#000", + shadowOffset: { width: 0, height: 2 }, + shadowOpacity: 0.08, + shadowRadius: 8, + elevation: 3, + }, + guestbookButtonText: { + fontSize: 15, + fontWeight: "700", + color: "#4CAF50", + }, }); diff --git a/src/navigation/RootNavigator.tsx b/src/navigation/RootNavigator.tsx index b58d701..583a17a 100644 --- a/src/navigation/RootNavigator.tsx +++ b/src/navigation/RootNavigator.tsx @@ -12,6 +12,7 @@ import FeedDiaryScreen from "@/pages/feed/FeedDiaryScreen"; import FeedAvatarScreen from "@/pages/feed/FeedAvatarScreen"; import LogDetailScreen from "@/pages/log/LogDetailScreen"; import ProfileScreen from "@/pages/profile/ProfileScreen"; +import GuestbookScreen from "@/pages/profile/GuestbookScreen"; import FollowScreen from "@/pages/follow/FollowScreen"; import DeliveryScreen from "@/pages/delivery/DeliveryScreen"; import DeliveryCompleteScreen from "@/pages/delivery/DeliveryCompleteScreen"; @@ -70,6 +71,7 @@ export default function RootNavigator() { )} + diff --git a/src/navigation/types.ts b/src/navigation/types.ts index 0d29e56..831f31e 100644 --- a/src/navigation/types.ts +++ b/src/navigation/types.ts @@ -18,6 +18,7 @@ export type RootStackParamList = { // 프로필 Profile: { userId: number }; + Guestbook: { userId: number; userNickname?: string }; // 팔로우 Follow: undefined; diff --git a/src/pages/profile/GuestbookScreen.tsx b/src/pages/profile/GuestbookScreen.tsx new file mode 100644 index 0000000..bddeddf --- /dev/null +++ b/src/pages/profile/GuestbookScreen.tsx @@ -0,0 +1,187 @@ +import { useState } from "react"; +import { + FlatList, + KeyboardAvoidingView, + Platform, + StyleSheet, + Text, + TouchableOpacity, + View, +} from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; +import ScreenHeader from "@/components/common/ScreenHeader"; +import StatusView from "@/components/common/StatusView"; +import CommentComposer from "@/components/common/CommentComposer"; +import { useCreateGuestbook, useGuestbookList } from "@/hooks/profile/useGuestbookApi"; +import type { RootStackScreenProps } from "@/navigation/types"; +import type { GuestbookEntry } from "@/types/profile/guestbookApi.type"; + + +type Props = RootStackScreenProps<"Guestbook">; + +export default function GuestbookScreen({ navigation, route }: Props) { + const { userId, userNickname } = route.params; + const [content, setContent] = useState(""); + const { data, error, isLoading, refetch } = useGuestbookList(userId); + const createMutation = useCreateGuestbook(userId); + + const handleBack = () => { + if (navigation.canGoBack()) { + navigation.goBack(); + return; + } + + navigation.navigate("Main", { screen: "Home" }); + }; + + const handleSubmit = async () => { + if (!content.trim()) { + return; + } + + try { + await createMutation.mutateAsync({ content: content.trim() }); + setContent(""); + } catch (guestbookError) { + console.error("[GuestbookScreen] Failed to create guestbook:", guestbookError); + } + }; + + const renderItem = ({ item }: { item: GuestbookEntry }) => ( + + + {item.author} + {formatDateTime(item.createdAt)} + + {item.content} + + ); + + return ( + + + + + {isLoading ? ( + + ) : error ? ( + void refetch()} + /> + ) : ( + `${item.author}-${item.createdAt}-${index}`} + renderItem={renderItem} + contentContainerStyle={[ + styles.listContent, + (data?.length ?? 0) === 0 ? styles.listContentEmpty : null, + ]} + showsVerticalScrollIndicator={false} + ListEmptyComponent={ + + 아직 작성된 방명록이 없습니다. + + 가장 먼저 인사를 남겨보세요. + + + } + /> + )} + + + {/* 한글 주석: + 방명록 페이지는 댓글처럼 목록은 위에서 스크롤되고, + 입력창은 전체 화면 하단에 고정해 언제든 바로 작성할 수 있게 한다. */} + void handleSubmit()} + disabled={createMutation.isPending} + placeholder="방명록을 남겨보세요." + /> + + + + ); +} + +function formatDateTime(iso: string) { + const date = new Date(iso); + return `${date.getMonth() + 1}월 ${date.getDate()}일 ${String(date.getHours()).padStart(2, "0")}:${String(date.getMinutes()).padStart(2, "0")}`; +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: "#FFFFFF", + }, + keyboardView: { + flex: 1, + }, + listContent: { + paddingHorizontal: 20, + paddingTop: 16, + paddingBottom: 120, + gap: 12, + }, + listContentEmpty: { + flexGrow: 1, + }, + entryCard: { + borderRadius: 18, + backgroundColor: "#F8FAF6", + paddingHorizontal: 16, + paddingVertical: 14, + gap: 8, + }, + entryHeader: { + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + gap: 12, + }, + entryAuthor: { + flex: 1, + fontSize: 14, + fontWeight: "700", + color: "#171717", + }, + entryDate: { + fontSize: 12, + color: "#6B7280", + }, + entryContent: { + fontSize: 14, + lineHeight: 20, + color: "#374151", + }, + emptyState: { + flex: 1, + alignItems: "center", + justifyContent: "center", + paddingHorizontal: 20, + gap: 8, + }, + emptyTitle: { + fontSize: 16, + fontWeight: "700", + color: "#171717", + textAlign: "center", + }, + emptyDescription: { + fontSize: 14, + lineHeight: 20, + color: "#6B7280", + textAlign: "center", + }, + composerWrap: { + backgroundColor: "#FFFFFF", + }, +}); diff --git a/src/pages/profile/ProfileScreen.tsx b/src/pages/profile/ProfileScreen.tsx index a4ca490..73de0c4 100644 --- a/src/pages/profile/ProfileScreen.tsx +++ b/src/pages/profile/ProfileScreen.tsx @@ -46,6 +46,13 @@ export default function ProfileScreen({ navigation, route }: Props) { navigation.navigate("Main", { screen: "Feed" }); }; + const handleOpenGuestbook = () => { + navigation.navigate("Guestbook", { + userId, + userNickname: data?.userNickname, + }); + }; + const followAction = useMemo(() => { if (!data || isMe) return null; @@ -181,6 +188,7 @@ export default function ProfileScreen({ navigation, route }: Props) { followAction={followAction} onBack={handleBack} onWater={() => void waterMutation.mutateAsync(scene.garden.gardenId)} + onPressGuestbook={handleOpenGuestbook} waterDisabled={waterMutation.isPending} /> From 9ab86d86243b2b0271a39767be8e3a1fdbbd43db Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 22:28:37 +0900 Subject: [PATCH 57/92] =?UTF-8?q?feat:=20=ED=83=80=EC=9D=B8=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=ED=95=84=20=EC=9A=B0=ED=8E=B8=ED=95=A8=20=EC=9E=A5?= =?UTF-8?q?=EC=8B=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/profile/ProfileGardenScene.tsx | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/components/profile/ProfileGardenScene.tsx b/src/components/profile/ProfileGardenScene.tsx index ac49588..8b25b1d 100644 --- a/src/components/profile/ProfileGardenScene.tsx +++ b/src/components/profile/ProfileGardenScene.tsx @@ -3,6 +3,7 @@ import { useSafeAreaInsets } from "react-native-safe-area-context"; import type { GardenInfo } from "@/types/profile/profileApi.type"; import WaterIcon from "@/assets/icons/water.svg"; +const mailboxImage = require("@/assets/images/profile/letterbox.png"); const ACTION_RAIL_BOTTOM_OFFSET = 128; type FollowAction = { @@ -90,6 +91,15 @@ export default function ProfileGardenScene({ )} + + {!isMe ? ( + + {/* 한글 주석: + 타인 프로필의 우편함은 홈의 비둘기처럼 식물 우하단에 붙는 장식 요소로만 두고, + 실제 방명록 진입은 하단 버튼에서 처리한다. */} + + + ) : null} {!isMe ? ( @@ -193,11 +203,22 @@ const styles = StyleSheet.create({ alignItems: "center", paddingHorizontal: 24, paddingBottom: 64, + position: "relative", }, avatarImage: { width: 300, height: 300, }, + mailboxWrap: { + position: "absolute", + right: 48, + bottom: 18, + zIndex: 2, + }, + mailboxImage: { + width: 84, + height: 84, + }, emptyAvatarBubble: { borderRadius: 24, backgroundColor: "rgba(255,255,255,0.92)", From 4cfc04de93c2bb11b8affab0f51ad06e8d112d61 Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 22:32:01 +0900 Subject: [PATCH 58/92] =?UTF-8?q?refactor:=20=ED=99=88=20=EB=B0=A9?= =?UTF-8?q?=EB=AA=85=EB=A1=9D=20=EB=AA=A8=EB=8B=AC=20=EB=AC=B8=EA=B5=AC?= =?UTF-8?q?=EB=A5=BC=20=EC=88=98=EC=8B=A0=20=ED=9D=90=EB=A6=84=EC=97=90=20?= =?UTF-8?q?=EB=A7=9E=EC=B6=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/home/HomeAlertsModal.tsx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/components/home/HomeAlertsModal.tsx b/src/components/home/HomeAlertsModal.tsx index d7a24e7..da60025 100644 --- a/src/components/home/HomeAlertsModal.tsx +++ b/src/components/home/HomeAlertsModal.tsx @@ -57,7 +57,7 @@ export default function HomeAlertsModal({ - 알림 + 받은 소식 닫기 @@ -65,7 +65,7 @@ export default function HomeAlertsModal({ setActiveTab("GUESTBOOK")} /> @@ -84,11 +84,15 @@ export default function HomeAlertsModal({ {activeState.isLoading ? ( 불러오는 중입니다. ) : activeState.isError ? ( - 알림을 불러오지 못했습니다. + + {activeTab === "GUESTBOOK" + ? "받은 방명록을 불러오지 못했습니다." + : "알림을 불러오지 못했습니다."} + ) : activeState.items.length === 0 ? ( {activeTab === "GUESTBOOK" - ? "아직 방문한 친구들이 남긴 방명록이 없어요." + ? "아직 받은 방명록이 없어요." : "아직 기록이 없어요."} ) : activeTab === "GUESTBOOK" ? ( From df75ef96666c743943f80a6401c159dc1b9ffd11 Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 22:39:53 +0900 Subject: [PATCH 59/92] =?UTF-8?q?refactor:=20=EB=B0=A9=EB=AA=85=EB=A1=9D?= =?UTF-8?q?=20=EC=9E=91=EC=84=B1=20=ED=9B=84=20=ED=99=88=20=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=20=EC=A1=B0=ED=9A=8C=EB=8F=84=20=EA=B0=B1=EC=8B=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/profile/useGuestbookApi.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/hooks/profile/useGuestbookApi.ts b/src/hooks/profile/useGuestbookApi.ts index de70b7e..c1b141b 100644 --- a/src/hooks/profile/useGuestbookApi.ts +++ b/src/hooks/profile/useGuestbookApi.ts @@ -22,7 +22,13 @@ export const useCreateGuestbook = (userId: string | number | undefined) => { return useMutation({ mutationFn: (body: CreateGuestbookRequest) => postGuestbook(String(userId), body), onSuccess: async () => { - await queryClient.invalidateQueries({ queryKey: ["guestbook-list", userId] }); + /* + * 한글 주석: + * 방명록 작성 후에는 현재 프로필 화면의 목록뿐 아니라 + * 홈 비둘기 모달이 바라보는 방명록/알림 조회도 함께 새로 읽게 맞춘다. + */ + await queryClient.invalidateQueries({ queryKey: ["guestbook-list"] }); + await queryClient.invalidateQueries({ queryKey: ["notifications"] }); }, }); }; From c3b6ee972e9ceb5267a770c46ab4647542fe113d Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 22:47:07 +0900 Subject: [PATCH 60/92] =?UTF-8?q?chore:=20=EC=86=8C=EC=85=9C=20=EB=8B=89?= =?UTF-8?q?=EB=84=A4=EC=9E=84=EA=B3=BC=20=ED=94=84=EB=A1=9C=ED=95=84=20?= =?UTF-8?q?=ED=97=A4=EB=8D=94=20=EA=B3=84=ED=9A=8D=20=EB=AC=B8=EC=84=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PROFILE_SOCIAL_NICKNAME_AND_HEADER_PLAN.md | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 PROFILE_SOCIAL_NICKNAME_AND_HEADER_PLAN.md diff --git a/PROFILE_SOCIAL_NICKNAME_AND_HEADER_PLAN.md b/PROFILE_SOCIAL_NICKNAME_AND_HEADER_PLAN.md new file mode 100644 index 0000000..f0e7bdd --- /dev/null +++ b/PROFILE_SOCIAL_NICKNAME_AND_HEADER_PLAN.md @@ -0,0 +1,35 @@ +# Profile And Social Nickname Plan + +## 목표 + +- 소셜 신규 가입 유저도 사람이 읽을 수 있는 닉네임을 직접 한 번 설정하게 한다. +- 타인 프로필 상단 구조를 방명록 화면과 톤이 맞는 박스형 헤더로 정리한다. + +## 현재 확인된 상태 + +- 비회원 가입은 `RegisterScreen`에서 닉네임을 입력한 뒤 가입한다. +- 소셜 로그인 신규 유저는 `RegistrationAvatar`로 바로 이동해서 닉네임 입력 단계가 없다. +- MainBE에는 `PATCH /api/v1/users/me/nickname` 엔드포인트가 이미 있다. +- 타인 프로필은 현재 정원 씬 내부에 헤더가 섞여 있어서 페이지 정체성이 약하다. + +## 작업 단계 + +### 1. 소셜 신규 유저 닉네임 설정 플로우 추가 + +- `SocialNickname` 전용 화면을 추가한다. +- 소셜 로그인 결과가 `newUser=true`면 `RegistrationAvatar`가 아니라 `SocialNickname`으로 보낸다. +- 닉네임 저장 성공 후에만 `RegistrationAvatar`로 이동시킨다. +- 이 단계는 유저 닉네임만 확정하는 단계이므로 식물 등록 상태와 분리한다. + +### 2. 타인 프로필 상단 헤더 박스형으로 리팩터링 + +- 정원 씬 바깥에 고정 상단 헤더를 둔다. +- 좌측은 뒤로가기, 가운데는 `프로필`, 우측은 친구 추가/맞팔/언팔로우를 둔다. +- 정원 씬 내부 헤더는 제거해서 역할을 분리한다. +- 물주기 횟수와 물주기 액션, 우편함, 방명록 버튼은 정원 씬에 남긴다. + +### 3. 검증 + +- 소셜 신규 유저 로그인 시 닉네임 설정 화면이 먼저 나오는지 확인한다. +- 닉네임 저장 후 `RegistrationAvatar`로 정상 이동하는지 확인한다. +- 타인 프로필에서 상단 헤더가 고정되고, 페이지 인디케이터와 씬 요소가 겹치지 않는지 확인한다. From c229d73ec3fc2d88cd9b87161d2bcb493db12977 Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 22:52:31 +0900 Subject: [PATCH 61/92] =?UTF-8?q?feat:=20=EC=86=8C=EC=85=9C=20=EC=8B=A0?= =?UTF-8?q?=EA=B7=9C=20=EC=9C=A0=EC=A0=80=20=EB=8B=89=EB=84=A4=EC=9E=84=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EB=8B=A8=EA=B3=84=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/profile/profileApi.ts | 7 + src/hooks/profile/useProfileApi.ts | 19 +++ src/navigation/RootNavigator.tsx | 2 + src/navigation/types.ts | 1 + src/pages/onboarding/OnboardingScreen.tsx | 9 +- src/pages/register/SocialNicknameScreen.tsx | 158 ++++++++++++++++++++ 6 files changed, 194 insertions(+), 2 deletions(-) create mode 100644 src/pages/register/SocialNicknameScreen.tsx diff --git a/src/apis/profile/profileApi.ts b/src/apis/profile/profileApi.ts index d325e3c..a28ac2b 100644 --- a/src/apis/profile/profileApi.ts +++ b/src/apis/profile/profileApi.ts @@ -18,3 +18,10 @@ export const postFriendWater = async ( const res = await api.post(`/api/v1/gardens/${gardenId}/friendwater`); return res.data; }; + +export const patchMyNickname = async (newNickname: string): ApiResponse => { + const res = await api.patch("/api/v1/users/me/nickname", { + newNickname, + }); + return res.data; +}; diff --git a/src/hooks/profile/useProfileApi.ts b/src/hooks/profile/useProfileApi.ts index 1f6e99d..093623f 100644 --- a/src/hooks/profile/useProfileApi.ts +++ b/src/hooks/profile/useProfileApi.ts @@ -1,6 +1,7 @@ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { getUserProfile, + patchMyNickname, postFriendWater, } from "@/apis/profile/profileApi"; import type { GetUserProfileResponse } from "@/types/profile/profileApi.type"; @@ -24,3 +25,21 @@ export const useFriendWater = (userId: string | number | undefined) => { }, }); }; + +export const useUpdateMyNickname = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: (newNickname: string) => patchMyNickname(newNickname), + onSuccess: async () => { + // 한글 주석: + // 유저 닉네임은 프로필, 방명록, 알림 문구에 함께 노출되므로 + // 저장 직후 관련 캐시를 함께 갱신해서 임시 닉네임이 남지 않게 맞춘다. + await Promise.all([ + queryClient.invalidateQueries({ queryKey: ["profile"] }), + queryClient.invalidateQueries({ queryKey: ["guestbook-list"] }), + queryClient.invalidateQueries({ queryKey: ["notifications"] }), + ]); + }, + }); +}; diff --git a/src/navigation/RootNavigator.tsx b/src/navigation/RootNavigator.tsx index 583a17a..a0203f2 100644 --- a/src/navigation/RootNavigator.tsx +++ b/src/navigation/RootNavigator.tsx @@ -8,6 +8,7 @@ import MainTabNavigator from "./MainTabNavigator"; import OnboardingScreen from "@/pages/onboarding/OnboardingScreen"; import RegisterScreen from "@/pages/register/RegisterScreen"; +import SocialNicknameScreen from "@/pages/register/SocialNicknameScreen"; import FeedDiaryScreen from "@/pages/feed/FeedDiaryScreen"; import FeedAvatarScreen from "@/pages/feed/FeedAvatarScreen"; import LogDetailScreen from "@/pages/log/LogDetailScreen"; @@ -70,6 +71,7 @@ export default function RootNavigator() { )} + diff --git a/src/navigation/types.ts b/src/navigation/types.ts index 831f31e..a179024 100644 --- a/src/navigation/types.ts +++ b/src/navigation/types.ts @@ -15,6 +15,7 @@ export type RootStackParamList = { // 인증/온보딩 Onboarding: undefined; Register: undefined; + SocialNickname: { initialNickname?: string } | undefined; // 프로필 Profile: { userId: number }; diff --git a/src/pages/onboarding/OnboardingScreen.tsx b/src/pages/onboarding/OnboardingScreen.tsx index 86350fb..3bfe5eb 100644 --- a/src/pages/onboarding/OnboardingScreen.tsx +++ b/src/pages/onboarding/OnboardingScreen.tsx @@ -107,10 +107,15 @@ export default function OnboardingScreen() { if (result?.success) { if (result.isNewUser) { resetRegistration(); - debugLog("OnboardingScreen", "Reset -> RegistrationAvatar for new user"); + debugLog("OnboardingScreen", "Reset -> SocialNickname for new social user"); navigation.reset({ index: 0, - routes: [{ name: "RegistrationAvatar" }], + routes: [ + { + name: "SocialNickname", + params: { initialNickname: result.nickname }, + }, + ], }); return; } diff --git a/src/pages/register/SocialNicknameScreen.tsx b/src/pages/register/SocialNicknameScreen.tsx new file mode 100644 index 0000000..018a16a --- /dev/null +++ b/src/pages/register/SocialNicknameScreen.tsx @@ -0,0 +1,158 @@ +import { useMemo, useState } from "react"; +import { Alert, ScrollView, StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; +import type { RootStackScreenProps } from "@/navigation/types"; +import RegistrationFooter from "@/components/registration/RegistrationFooter"; +import RegistrationTextField from "@/components/registration/RegistrationTextField"; +import { useUpdateMyNickname } from "@/hooks/profile/useProfileApi"; +import { logout } from "@/utils/auth"; + +type Props = RootStackScreenProps<"SocialNickname">; + +export default function SocialNicknameScreen({ navigation, route }: Props) { + const initialNickname = route.params?.initialNickname?.trim() ?? ""; + const [nickname, setNickname] = useState( + initialNickname.startsWith("user") ? "" : initialNickname + ); + const updateNickname = useUpdateMyNickname(); + + const trimmedNickname = nickname.trim(); + const isValidNickname = trimmedNickname.length >= 2 && trimmedNickname.length <= 10; + + const helperText = useMemo(() => { + if (trimmedNickname.length === 0) { + return "방명록과 피드에 표시될 이름을 입력해주세요."; + } + if (trimmedNickname.length < 2) { + return "닉네임은 2자 이상이어야 합니다."; + } + if (trimmedNickname.length > 10) { + return "닉네임은 10자 이하로 입력해주세요."; + } + return "이 닉네임으로 프로필과 방명록 작성자명이 표시됩니다."; + }, [trimmedNickname]); + + const handleBack = async () => { + await logout(); + navigation.reset({ + index: 0, + routes: [{ name: "Onboarding" }], + }); + }; + + const handleSubmit = async () => { + if (!isValidNickname || updateNickname.isPending) { + return; + } + + try { + await updateNickname.mutateAsync(trimmedNickname); + navigation.reset({ + index: 0, + routes: [{ name: "RegistrationAvatar" }], + }); + } catch { + Alert.alert( + "닉네임 저장에 실패했습니다", + "네트워크 상태를 확인한 뒤 다시 시도해주세요." + ); + } + }; + + return ( + + + void handleBack()} activeOpacity={0.7} style={styles.sideButton}> + 뒤로 + + 닉네임 설정 + + + + + + 소셜 로그인 완료 + 먼저 사용할 닉네임을 정해주세요. + + {/* 한글 주석: + 소셜 신규 유저는 기존 비회원 가입처럼 닉네임 입력 화면을 거치지 않았기 때문에 + 식물 등록으로 넘어가기 전에 유저 닉네임을 먼저 확정한다. */} + 방명록 작성자명과 프로필 이름으로 바로 노출되기 때문에, 지금 한 번 먼저 정하고 시작합니다. + + + + + + + void handleSubmit()} + primaryDisabled={!isValidNickname || updateNickname.isPending} + primaryLoading={updateNickname.isPending} + /> + + ); +} + +const styles = StyleSheet.create({ + safeArea: { + flex: 1, + backgroundColor: "#F7F8F4", + }, + header: { + height: 56, + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + paddingHorizontal: 16, + backgroundColor: "#FFFFFF", + borderBottomWidth: StyleSheet.hairlineWidth, + borderBottomColor: "#E5E7EB", + }, + sideButton: { + width: 56, + height: 44, + justifyContent: "center", + }, + backText: { + fontSize: 14, + fontWeight: "600", + color: "#374151", + }, + headerTitle: { + fontSize: 17, + fontWeight: "700", + color: "#171717", + }, + content: { + padding: 20, + gap: 18, + }, + heroCard: { + borderRadius: 22, + padding: 20, + backgroundColor: "#234A2F", + gap: 8, + }, + eyebrow: { + fontSize: 12, + color: "#D7E9D8", + }, + heroTitle: { + fontSize: 24, + lineHeight: 32, + fontWeight: "700", + color: "#FFFFFF", + }, + heroDescription: { + fontSize: 14, + lineHeight: 20, + color: "#E5F4E5", + }, +}); From 5ddf48a49c8c05c30cb116bb90733fd63ffcc2bc Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 22:54:54 +0900 Subject: [PATCH 62/92] =?UTF-8?q?refactor:=20=ED=83=80=EC=9D=B8=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EC=83=81=EB=8B=A8=20=ED=97=A4?= =?UTF-8?q?=EB=8D=94=EB=A5=BC=20=EB=B0=95=EC=8A=A4=ED=98=95=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/profile/ProfileGardenScene.tsx | 89 +-------- src/pages/profile/ProfileScreen.tsx | 184 ++++++++++++------ 2 files changed, 128 insertions(+), 145 deletions(-) diff --git a/src/components/profile/ProfileGardenScene.tsx b/src/components/profile/ProfileGardenScene.tsx index 8b25b1d..ed1d3de 100644 --- a/src/components/profile/ProfileGardenScene.tsx +++ b/src/components/profile/ProfileGardenScene.tsx @@ -6,20 +6,11 @@ import WaterIcon from "@/assets/icons/water.svg"; const mailboxImage = require("@/assets/images/profile/letterbox.png"); const ACTION_RAIL_BOTTOM_OFFSET = 128; -type FollowAction = { - label: string; - onPress: () => void; - pending: boolean; -}; - type Props = { background: any; garden: GardenInfo; - userNickname: string; - leftWaterCountForOthers: number; isMe: boolean; - followAction: FollowAction | null; - onBack: () => void; + leftWaterCountForOthers: number; onWater: () => void; onPressGuestbook: () => void; waterDisabled?: boolean; @@ -28,49 +19,22 @@ type Props = { export default function ProfileGardenScene({ background, garden, - userNickname, - leftWaterCountForOthers, isMe, - followAction, - onBack, + leftWaterCountForOthers, onWater, onPressGuestbook, waterDisabled = false, }: Props) { const insets = useSafeAreaInsets(); const canWater = !isMe && garden.isWateringAbleByMe && !waterDisabled; - const avatarName = garden.avatarInfo?.avatarName ?? `${userNickname}의 정원`; + const topOverlayOffset = insets.top + 92; return ( - - - {"<"} - - - {avatarName} - - - {followAction ? ( - - - {followAction.pending ? "처리 중..." : followAction.label} - - - ) : isMe ? ( - 내 프로필 - ) : null} - - - {!isMe ? ( - + {leftWaterCountForOthers}회 @@ -137,50 +101,6 @@ const styles = StyleSheet.create({ ...StyleSheet.absoluteFillObject, backgroundColor: "rgba(8, 20, 10, 0.08)", }, - sceneHeader: { - flexDirection: "row", - alignItems: "center", - justifyContent: "space-between", - paddingHorizontal: 16, - zIndex: 2, - }, - headerSideButton: { - width: 72, - alignItems: "center", - justifyContent: "center", - minHeight: 44, - }, - backArrow: { - fontSize: 22, - fontWeight: "700", - color: "#FFFFFF", - textShadowColor: "rgba(0,0,0,0.18)", - textShadowOffset: { width: 0, height: 1 }, - textShadowRadius: 4, - }, - sceneTitle: { - flex: 1, - textAlign: "center", - fontSize: 22, - fontWeight: "700", - color: "#FFFFFF", - textShadowColor: "rgba(0, 0, 0, 0.18)", - textShadowOffset: { width: 0, height: 1 }, - textShadowRadius: 4, - }, - followTextButton: { - fontSize: 14, - fontWeight: "600", - color: "#FFFFFF", - textShadowColor: "rgba(0,0,0,0.18)", - textShadowOffset: { width: 0, height: 1 }, - textShadowRadius: 4, - textAlign: "center", - }, - selfBadgeText: { - fontSize: 13, - color: "rgba(255,255,255,0.7)", - }, waterCountBadge: { position: "absolute", right: 16, @@ -202,6 +122,7 @@ const styles = StyleSheet.create({ justifyContent: "center", alignItems: "center", paddingHorizontal: 24, + paddingTop: 44, paddingBottom: 64, position: "relative", }, diff --git a/src/pages/profile/ProfileScreen.tsx b/src/pages/profile/ProfileScreen.tsx index 73de0c4..f645f01 100644 --- a/src/pages/profile/ProfileScreen.tsx +++ b/src/pages/profile/ProfileScreen.tsx @@ -120,50 +120,66 @@ export default function ProfileScreen({ navigation, route }: Props) { garden, })); - if (scenes.length === 0) { - return ( - - - - - 뒤로가기 + const renderProfileHeader = () => ( + + {/* 한글 주석: + 프로필 화면의 상단은 방명록 화면과 톤을 맞춘 박스형 헤더로 분리해서, + 뒤로가기/프로필/친구추가 역할이 정원 씬 위에 명확하게 보이도록 정리한다. */} + + + 뒤로 + + + 프로필 + + + {followAction ? ( + + + {followAction.pending ? "처리 중..." : followAction.label} + - + ) : isMe ? ( + 내 프로필 + ) : null} + + + + ); - - - {data.profileImageUrl ? ( - - ) : null} + if (scenes.length === 0) { + return ( + + {renderProfileHeader()} + + + + + {data.profileImageUrl ? ( + + ) : null} + + {data.userNickname} - {data.userNickname} - {followAction ? ( - - - {followAction.pending ? "처리 중..." : followAction.label} - - - ) : isMe ? ( - 내 프로필 - ) : null} - - - 정원 정보가 없습니다. - - 현재 API 기준으로 표시할 정원 데이터가 없어 기본 정보만 표시합니다. - - - - + + 정원 정보가 없습니다. + + 현재 API 기준으로 표시할 정원 데이터가 없어 기본 정보만 표시합니다. + + + + + ); } @@ -182,11 +198,8 @@ export default function ProfileScreen({ navigation, route }: Props) { void waterMutation.mutateAsync(scene.garden.gardenId)} onPressGuestbook={handleOpenGuestbook} waterDisabled={waterMutation.isPending} @@ -195,6 +208,8 @@ export default function ProfileScreen({ navigation, route }: Props) { ))} + {renderProfileHeader()} + {scenes.map((scene, index) => ( @@ -227,6 +242,64 @@ const styles = StyleSheet.create({ page: { flex: 1, }, + headerSafeArea: { + position: "absolute", + top: 0, + left: 0, + right: 0, + }, + headerCard: { + marginHorizontal: 16, + marginTop: 8, + minHeight: 56, + borderRadius: 18, + backgroundColor: "rgba(255,255,255,0.96)", + flexDirection: "row", + alignItems: "center", + paddingHorizontal: 12, + shadowColor: "#000", + shadowOffset: { width: 0, height: 2 }, + shadowOpacity: 0.08, + shadowRadius: 10, + elevation: 3, + }, + headerSideButton: { + width: 56, + minHeight: 44, + justifyContent: "center", + }, + headerBackText: { + fontSize: 14, + fontWeight: "600", + color: "#374151", + }, + headerTitle: { + flex: 1, + textAlign: "center", + fontSize: 18, + fontWeight: "700", + color: "#171717", + }, + headerActionWrap: { + minWidth: 72, + alignItems: "flex-end", + }, + followButton: { + borderRadius: 12, + backgroundColor: "#E9F6EA", + paddingHorizontal: 12, + paddingVertical: 8, + }, + followButtonText: { + fontSize: 13, + fontWeight: "700", + color: "#2F7D32", + }, + selfBadgeText: { + fontSize: 13, + fontWeight: "600", + color: "#6B7280", + }, overlaySafeArea: { position: "absolute", top: 0, @@ -234,7 +307,7 @@ const styles = StyleSheet.create({ right: 0, }, pagination: { - marginTop: 84, + marginTop: 86, alignSelf: "center", flexDirection: "row", alignItems: "center", @@ -256,14 +329,12 @@ const styles = StyleSheet.create({ flex: 1, backgroundColor: "#FFFFFF", }, - emptyHeader: { - paddingHorizontal: 20, - paddingTop: 16, + emptyScrollSafeArea: { + flex: 1, }, - emptyBackText: { - fontSize: 14, - fontWeight: "600", - color: "#6B7280", + emptyScrollContent: { + paddingTop: 104, + paddingBottom: 28, }, summaryRow: { flexDirection: "row", @@ -289,15 +360,6 @@ const styles = StyleSheet.create({ fontWeight: "600", color: "#171717", }, - followTextButton: { - fontSize: 14, - fontWeight: "600", - color: "#4CAF50", - }, - selfBadgeText: { - fontSize: 13, - color: "#9CA3AF", - }, emptyGardenWrap: { paddingHorizontal: 20, paddingVertical: 28, From 607bc714058318889699d7f1ff6957ae70156038 Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 23:04:59 +0900 Subject: [PATCH 63/92] =?UTF-8?q?chore:=20=EC=86=8C=EC=85=9C=20=EC=98=A8?= =?UTF-8?q?=EB=B3=B4=EB=94=A9=EA=B3=BC=20=EC=84=A4=EC=A0=95=20=EB=A9=94?= =?UTF-8?q?=EB=89=B4=20=ED=98=84=ED=99=A9=20=EB=AC=B8=EC=84=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SOCIAL_ONBOARDING_AND_OPTION_STATUS.md | 112 +++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 SOCIAL_ONBOARDING_AND_OPTION_STATUS.md diff --git a/SOCIAL_ONBOARDING_AND_OPTION_STATUS.md b/SOCIAL_ONBOARDING_AND_OPTION_STATUS.md new file mode 100644 index 0000000..4a32033 --- /dev/null +++ b/SOCIAL_ONBOARDING_AND_OPTION_STATUS.md @@ -0,0 +1,112 @@ +# Social Onboarding And Option Menu Status + +## 1. 소셜 신규 가입을 임시 상태 기반으로 바꾸는 백엔드 계획 + +### 목표 + +- 소셜 인증 직후에는 계정을 최소 정보로만 생성하거나 온보딩 미완료 상태로 둔다. +- 유저 닉네임이 확정되기 전에는 서비스 내 노출 이름을 정식 값으로 사용하지 않는다. +- 닉네임 저장이 끝난 뒤에만 식물 등록과 서비스 온보딩을 이어간다. + +### 현재 상태 + +- MainAPP는 소셜 신규 유저를 `SocialNickname` 화면으로 보낸다. +- 하지만 MainBE는 `/api/v1/auth/supabase` 처리 시점에 이미 사용자를 저장한다. +- 이때 `AuthService.buildUniqueNickname()`으로 임시 닉네임을 즉시 생성한다. +- 그래서 프론트가 닉네임을 받기 전에 임시 닉네임이 방명록, 프로필 등에 남을 수 있다. + +### MainBE에서 바꿔야 할 점 + +#### 1. AuthService 신규 소셜 가입 처리 + +- 파일: `domain/member/auth/service/AuthService.java` +- 현재: + - 신규 소셜 유저면 즉시 `User` 저장 + - `buildUniqueNickname()`으로 임시 닉네임 생성 +- 변경: + - 닉네임 미확정 상태를 표현하는 필드를 두고 저장 + - 또는 별도 임시 유저 상태를 둔다 + - 응답에 `requiresNicknameSetup` 같은 명시적 값을 내려준다 + +#### 2. User 엔티티 온보딩 상태 필드 + +- 파일: `domain/member/user/domain/User.java` +- 후보 필드: + - `nicknameConfirmed` + - `onboardingCompleted` +- 목적: + - 닉네임 확정 전/후를 서버가 명확히 구분 + +#### 3. 닉네임 확정 API 의미 강화 + +- 현재 엔드포인트: `PATCH /api/v1/users/me/nickname` +- 이 API를 최초 닉네임 확정에도 사용하거나, +- 별도 `POST /api/v1/users/me/onboarding/nickname` 같은 전용 엔드포인트를 둘 수 있다 + +#### 4. 서비스 접근 가드 + +- 닉네임 미확정 유저는 일부 기능 진입 전 프론트가 닉네임 화면으로 유도 +- 백엔드도 필요하면 온보딩 미완료 상태에서 특정 쓰기 기능을 제한 + +### MainAPP에서 맞춰야 할 점 + +- 소셜 로그인 성공 후 `newUser` 또는 `requiresNicknameSetup`이면 닉네임 화면으로 이동 +- 닉네임 저장 성공 후에만 `RegistrationAvatar`로 진행 +- 로그인 직후 프로필/방명록/알림 캐시를 갱신해서 임시 닉네임이 남지 않게 한다 + +### 권장 순서 + +1. MainBE에 온보딩 상태 필드 추가 +2. `/api/v1/auth/supabase` 응답에 `requiresNicknameSetup` 추가 +3. 닉네임 확정 API 의미 정리 +4. MainAPP 분기값을 `newUser` 중심에서 `requiresNicknameSetup` 중심으로 전환 + +## 2. 설정 화면 메뉴 현황 점검 + +대상 메뉴: +- 유저 닉네임 변경 +- 아바타 닉네임 변경 +- 이용 약관 +- 서비스 안내 + +### 유저 닉네임 변경 + +- Option 메뉴 행 존재: 있음 +- 전용 설정 화면: 없음 +- 관련 프론트 화면: `SocialNicknameScreen`은 존재하지만 온보딩용이고 설정 메뉴와는 미연결 +- 백엔드 API: 있음 + - `PATCH /api/v1/users/me/nickname` +- 현재 API 연결: 설정 메뉴에는 안 되어 있음 + +### 아바타 닉네임 변경 + +- Option 메뉴 행 존재: 있음 +- 전용 설정 화면: 없음 +- 백엔드 API: 있음 + - `PATCH /api/v1/users/me/{avatarId}` + - body의 `newAvatarName`으로 변경 가능 +- 현재 API 연결: 설정 메뉴에는 안 되어 있음 + +### 이용 약관 + +- Option 메뉴 행 존재: 있음 +- 전용 프론트 화면: 없음 +- 백엔드 API: 있음 + - `GET /api/v1/policy` +- 현재 API 연결: 안 되어 있음 + +### 서비스 안내 + +- Option 메뉴 행 존재: 있음 +- 전용 프론트 화면: 없음 +- 백엔드 API: 확인되지 않음 +- 현재 API 연결: 안 되어 있음 + +## 결론 + +- 설정 메뉴 4개 중 실제로 메뉴와 연결된 것은 없다. +- 백엔드 API가 확인된 것은 + - 유저 닉네임 변경 + - 아바타 닉네임 변경 + - 이용 약관 조회 +- 서비스 안내는 현재 코드 기준으로 전용 화면도 없고 백엔드 API도 보이지 않는다. From 6e2816e157abbf94d2a2b0ae7907372e7193bf57 Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 23:09:38 +0900 Subject: [PATCH 64/92] =?UTF-8?q?feat:=20=EC=84=A4=EC=A0=95=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=9C=A0=EC=A0=80=20=EB=8B=89=EB=84=A4=EC=9E=84=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20=ED=99=94=EB=A9=B4=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/navigation/RootNavigator.tsx | 2 + src/navigation/types.ts | 3 + src/pages/option/OptionScreen.tsx | 4 +- src/pages/option/UserNicknameEditScreen.tsx | 170 ++++++++++++++++++++ 4 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 src/pages/option/UserNicknameEditScreen.tsx diff --git a/src/navigation/RootNavigator.tsx b/src/navigation/RootNavigator.tsx index a0203f2..0db2e74 100644 --- a/src/navigation/RootNavigator.tsx +++ b/src/navigation/RootNavigator.tsx @@ -15,6 +15,7 @@ import LogDetailScreen from "@/pages/log/LogDetailScreen"; import ProfileScreen from "@/pages/profile/ProfileScreen"; import GuestbookScreen from "@/pages/profile/GuestbookScreen"; import FollowScreen from "@/pages/follow/FollowScreen"; +import UserNicknameEditScreen from "@/pages/option/UserNicknameEditScreen"; import DeliveryScreen from "@/pages/delivery/DeliveryScreen"; import DeliveryCompleteScreen from "@/pages/delivery/DeliveryCompleteScreen"; import UnlockGardenScreen from "@/pages/delivery/UnlockGardenScreen"; @@ -74,6 +75,7 @@ export default function RootNavigator() { + diff --git a/src/navigation/types.ts b/src/navigation/types.ts index a179024..d3e4285 100644 --- a/src/navigation/types.ts +++ b/src/navigation/types.ts @@ -21,6 +21,9 @@ export type RootStackParamList = { Profile: { userId: number }; Guestbook: { userId: number; userNickname?: string }; + // 설정 + UserNicknameEdit: undefined; + // 팔로우 Follow: undefined; diff --git a/src/pages/option/OptionScreen.tsx b/src/pages/option/OptionScreen.tsx index 3960873..7ec29e1 100644 --- a/src/pages/option/OptionScreen.tsx +++ b/src/pages/option/OptionScreen.tsx @@ -13,7 +13,7 @@ import { logout } from "@/utils/auth"; type Props = MainTabScreenProps<"Option">; -export default function OptionScreen(_: Props) { +export default function OptionScreen({ navigation }: Props) { const [pushNotification, setPushNotification] = useState(true); const [isLoggingOut, setIsLoggingOut] = useState(false); const { accessToken, userId, hasHydrated } = useTokenStore(); @@ -56,7 +56,7 @@ export default function OptionScreen(_: Props) { } /> - + navigation.navigate("UserNicknameEdit")} /> diff --git a/src/pages/option/UserNicknameEditScreen.tsx b/src/pages/option/UserNicknameEditScreen.tsx new file mode 100644 index 0000000..4b5b2b7 --- /dev/null +++ b/src/pages/option/UserNicknameEditScreen.tsx @@ -0,0 +1,170 @@ +import { useMemo, useState } from "react"; +import { Alert, ScrollView, StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; +import type { RootStackScreenProps } from "@/navigation/types"; +import RegistrationFooter from "@/components/registration/RegistrationFooter"; +import RegistrationTextField from "@/components/registration/RegistrationTextField"; +import StatusView from "@/components/common/StatusView"; +import { useUpdateMyNickname, useUserProfile } from "@/hooks/profile/useProfileApi"; +import useTokenStore from "@/stores/useTokenStore"; + +type Props = RootStackScreenProps<"UserNicknameEdit">; + +export default function UserNicknameEditScreen({ navigation }: Props) { + const { userId } = useTokenStore(); + const { data, isLoading, error, refetch } = useUserProfile(userId); + const updateNickname = useUpdateMyNickname(); + const [draftNickname, setDraftNickname] = useState(""); + + const nickname = draftNickname || data?.userNickname || ""; + const trimmedNickname = nickname.trim(); + const isValidNickname = trimmedNickname.length >= 2 && trimmedNickname.length <= 10; + const isChanged = trimmedNickname.length > 0 && trimmedNickname !== (data?.userNickname ?? ""); + + const helperText = useMemo(() => { + if (trimmedNickname.length === 0) { + return "프로필과 방명록에 표시될 이름입니다."; + } + if (trimmedNickname.length < 2) { + return "닉네임은 2자 이상이어야 합니다."; + } + if (trimmedNickname.length > 10) { + return "닉네임은 10자 이하로 입력해주세요."; + } + return "저장하면 프로필, 피드, 방명록에 새 이름이 반영됩니다."; + }, [trimmedNickname]); + + const handleBack = () => { + navigation.goBack(); + }; + + const handleSubmit = async () => { + if (!isValidNickname || !isChanged || updateNickname.isPending) { + return; + } + + try { + await updateNickname.mutateAsync(trimmedNickname); + navigation.goBack(); + } catch { + Alert.alert("닉네임 변경에 실패했습니다", "잠시 후 다시 시도해주세요."); + } + }; + + if (isLoading) { + return ( + + + + ); + } + + if (error || !data) { + return ( + + void refetch()} + /> + + ); + } + + return ( + + + + 뒤로 + + 유저 닉네임 변경 + + + + + + 설정 + 보여질 이름을 수정합니다. + + {/* 한글 주석: + 설정 메뉴에서 바꾸는 유저 닉네임은 프로필 이름뿐 아니라 + 피드 작성자명과 방명록 작성자명에도 함께 쓰이는 공통 이름이다. */} + 현재 닉네임을 바꾸면 프로필과 소셜 영역 전반에 같은 이름으로 반영됩니다. + + + + + + + void handleSubmit()} + primaryDisabled={!isValidNickname || !isChanged || updateNickname.isPending} + primaryLoading={updateNickname.isPending} + /> + + ); +} + +const styles = StyleSheet.create({ + safeArea: { + flex: 1, + backgroundColor: "#F7F8F4", + }, + header: { + height: 56, + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + paddingHorizontal: 16, + backgroundColor: "#FFFFFF", + borderBottomWidth: StyleSheet.hairlineWidth, + borderBottomColor: "#E5E7EB", + }, + sideButton: { + width: 56, + height: 44, + justifyContent: "center", + }, + backText: { + fontSize: 14, + fontWeight: "600", + color: "#374151", + }, + headerTitle: { + fontSize: 17, + fontWeight: "700", + color: "#171717", + }, + content: { + padding: 20, + gap: 18, + }, + heroCard: { + borderRadius: 22, + padding: 20, + backgroundColor: "#234A2F", + gap: 8, + }, + eyebrow: { + fontSize: 12, + color: "#D7E9D8", + }, + heroTitle: { + fontSize: 24, + lineHeight: 32, + fontWeight: "700", + color: "#FFFFFF", + }, + heroDescription: { + fontSize: 14, + lineHeight: 20, + color: "#E5F4E5", + }, +}); From d7180d2c76d5efb1a41e46952a718729cbfa02fd Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 23:15:02 +0900 Subject: [PATCH 65/92] =?UTF-8?q?feat:=20=EC=84=A4=EC=A0=95=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=9D=B4=EC=9A=A9=EC=95=BD=EA=B4=80=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/option/policyApi.ts | 7 ++ src/hooks/option/usePolicyApi.ts | 9 +++ src/navigation/RootNavigator.tsx | 2 + src/navigation/types.ts | 1 + src/pages/option/OptionScreen.tsx | 2 +- src/pages/option/PolicyScreen.tsx | 103 ++++++++++++++++++++++++++++++ 6 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 src/apis/option/policyApi.ts create mode 100644 src/hooks/option/usePolicyApi.ts create mode 100644 src/pages/option/PolicyScreen.tsx diff --git a/src/apis/option/policyApi.ts b/src/apis/option/policyApi.ts new file mode 100644 index 0000000..66859fa --- /dev/null +++ b/src/apis/option/policyApi.ts @@ -0,0 +1,7 @@ +import api from "@/apis/instance"; +import type { ApiResponse } from "@/types/common/apiResponse.type"; + +export const getPolicy = async (): ApiResponse => { + const res = await api.get("/api/v1/policy"); + return res.data; +}; diff --git a/src/hooks/option/usePolicyApi.ts b/src/hooks/option/usePolicyApi.ts new file mode 100644 index 0000000..273ff2b --- /dev/null +++ b/src/hooks/option/usePolicyApi.ts @@ -0,0 +1,9 @@ +import { useQuery } from "@tanstack/react-query"; +import { getPolicy } from "@/apis/option/policyApi"; + +export const usePolicy = () => + useQuery<{ result: string }, unknown, string>({ + queryKey: ["policy"], + queryFn: () => getPolicy(), + select: data => data.result, + }); diff --git a/src/navigation/RootNavigator.tsx b/src/navigation/RootNavigator.tsx index 0db2e74..f3d7ef5 100644 --- a/src/navigation/RootNavigator.tsx +++ b/src/navigation/RootNavigator.tsx @@ -16,6 +16,7 @@ import ProfileScreen from "@/pages/profile/ProfileScreen"; import GuestbookScreen from "@/pages/profile/GuestbookScreen"; import FollowScreen from "@/pages/follow/FollowScreen"; import UserNicknameEditScreen from "@/pages/option/UserNicknameEditScreen"; +import PolicyScreen from "@/pages/option/PolicyScreen"; import DeliveryScreen from "@/pages/delivery/DeliveryScreen"; import DeliveryCompleteScreen from "@/pages/delivery/DeliveryCompleteScreen"; import UnlockGardenScreen from "@/pages/delivery/UnlockGardenScreen"; @@ -76,6 +77,7 @@ export default function RootNavigator() { + diff --git a/src/navigation/types.ts b/src/navigation/types.ts index d3e4285..103699d 100644 --- a/src/navigation/types.ts +++ b/src/navigation/types.ts @@ -23,6 +23,7 @@ export type RootStackParamList = { // 설정 UserNicknameEdit: undefined; + Policy: undefined; // 팔로우 Follow: undefined; diff --git a/src/pages/option/OptionScreen.tsx b/src/pages/option/OptionScreen.tsx index 7ec29e1..5ee83fa 100644 --- a/src/pages/option/OptionScreen.tsx +++ b/src/pages/option/OptionScreen.tsx @@ -58,7 +58,7 @@ export default function OptionScreen({ navigation }: Props) { /> navigation.navigate("UserNicknameEdit")} /> - + navigation.navigate("Policy")} /> ; + +export default function PolicyScreen({ navigation }: Props) { + const { data, isLoading, error, refetch } = usePolicy(); + + const handleBack = () => { + navigation.goBack(); + }; + + if (isLoading) { + return ( + + + + ); + } + + if (error || !data) { + return ( + + void refetch()} + /> + + ); + } + + return ( + + + + 뒤로 + + 이용 약관 + + + + + + + {/* 한글 주석: + 약관 API는 현재 문자열 본문 하나를 내려주기 때문에, + 프론트에서는 스크롤 가능한 읽기 화면으로만 단순하게 구성한다. */} + {data} + + + + + ); +} + +const styles = StyleSheet.create({ + safeArea: { + flex: 1, + backgroundColor: "#F7F8F4", + }, + header: { + height: 56, + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + paddingHorizontal: 16, + backgroundColor: "#FFFFFF", + borderBottomWidth: StyleSheet.hairlineWidth, + borderBottomColor: "#E5E7EB", + }, + sideButton: { + width: 56, + height: 44, + justifyContent: "center", + }, + backText: { + fontSize: 14, + fontWeight: "600", + color: "#374151", + }, + headerTitle: { + fontSize: 17, + fontWeight: "700", + color: "#171717", + }, + content: { + padding: 20, + }, + card: { + borderRadius: 22, + backgroundColor: "#FFFFFF", + padding: 20, + }, + body: { + fontSize: 14, + lineHeight: 24, + color: "#374151", + }, +}); From 697472a027466c49b34829c29e8aa57738f0d849 Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 23:23:12 +0900 Subject: [PATCH 66/92] =?UTF-8?q?feat:=20=EC=84=A4=EC=A0=95=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=95=84=EB=B0=94=ED=83=80=20=EB=8B=89=EB=84=A4?= =?UTF-8?q?=EC=9E=84=20=EB=B3=80=EA=B2=BD=20=ED=99=94=EB=A9=B4=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/option/avatarApi.ts | 16 + src/hooks/option/useAvatarNicknameApi.ts | 20 ++ src/navigation/RootNavigator.tsx | 2 + src/navigation/types.ts | 1 + src/pages/option/AvatarNicknameEditScreen.tsx | 273 ++++++++++++++++++ src/pages/option/OptionScreen.tsx | 2 +- 6 files changed, 313 insertions(+), 1 deletion(-) create mode 100644 src/apis/option/avatarApi.ts create mode 100644 src/hooks/option/useAvatarNicknameApi.ts create mode 100644 src/pages/option/AvatarNicknameEditScreen.tsx diff --git a/src/apis/option/avatarApi.ts b/src/apis/option/avatarApi.ts new file mode 100644 index 0000000..7889c51 --- /dev/null +++ b/src/apis/option/avatarApi.ts @@ -0,0 +1,16 @@ +import api from "@/apis/instance"; +import type { ApiResponse } from "@/types/common/apiResponse.type"; + +export type UpdateAvatarPayload = { + avatarId: number; + newAvatarName: string; +}; + +export const updateAvatarNickname = async ( + payload: UpdateAvatarPayload +): ApiResponse => { + const res = await api.patch(`/api/v1/users/me/${payload.avatarId}`, { + newAvatarName: payload.newAvatarName, + }); + return res.data; +}; diff --git a/src/hooks/option/useAvatarNicknameApi.ts b/src/hooks/option/useAvatarNicknameApi.ts new file mode 100644 index 0000000..a8be8e2 --- /dev/null +++ b/src/hooks/option/useAvatarNicknameApi.ts @@ -0,0 +1,20 @@ +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { updateAvatarNickname, type UpdateAvatarPayload } from "@/apis/option/avatarApi"; + +export const useUpdateAvatarNickname = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: (payload: UpdateAvatarPayload) => updateAvatarNickname(payload), + onSuccess: async () => { + // 한글 주석: + // 아바타 닉네임은 홈, 프로필, 피드에 동시에 노출되므로 + // 저장 직후 관련 캐시를 함께 갱신해 같은 식물이 다른 이름으로 남지 않게 맞춘다. + await Promise.all([ + queryClient.invalidateQueries({ queryKey: ["home-summary"] }), + queryClient.invalidateQueries({ queryKey: ["profile"] }), + queryClient.invalidateQueries({ queryKey: ["feed-detail"] }), + ]); + }, + }); +}; diff --git a/src/navigation/RootNavigator.tsx b/src/navigation/RootNavigator.tsx index f3d7ef5..a6bac59 100644 --- a/src/navigation/RootNavigator.tsx +++ b/src/navigation/RootNavigator.tsx @@ -16,6 +16,7 @@ import ProfileScreen from "@/pages/profile/ProfileScreen"; import GuestbookScreen from "@/pages/profile/GuestbookScreen"; import FollowScreen from "@/pages/follow/FollowScreen"; import UserNicknameEditScreen from "@/pages/option/UserNicknameEditScreen"; +import AvatarNicknameEditScreen from "@/pages/option/AvatarNicknameEditScreen"; import PolicyScreen from "@/pages/option/PolicyScreen"; import DeliveryScreen from "@/pages/delivery/DeliveryScreen"; import DeliveryCompleteScreen from "@/pages/delivery/DeliveryCompleteScreen"; @@ -77,6 +78,7 @@ export default function RootNavigator() { + diff --git a/src/navigation/types.ts b/src/navigation/types.ts index 103699d..93cefc9 100644 --- a/src/navigation/types.ts +++ b/src/navigation/types.ts @@ -23,6 +23,7 @@ export type RootStackParamList = { // 설정 UserNicknameEdit: undefined; + AvatarNicknameEdit: undefined; Policy: undefined; // 팔로우 diff --git a/src/pages/option/AvatarNicknameEditScreen.tsx b/src/pages/option/AvatarNicknameEditScreen.tsx new file mode 100644 index 0000000..c03b94f --- /dev/null +++ b/src/pages/option/AvatarNicknameEditScreen.tsx @@ -0,0 +1,273 @@ +import { useMemo, useState } from "react"; +import { + Alert, + Image, + ScrollView, + StyleSheet, + Text, + TouchableOpacity, + View, +} from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; +import type { RootStackScreenProps } from "@/navigation/types"; +import RegistrationFooter from "@/components/registration/RegistrationFooter"; +import RegistrationTextField from "@/components/registration/RegistrationTextField"; +import StatusView from "@/components/common/StatusView"; +import useHomeApi from "@/hooks/home/useHomeApi"; +import { useUpdateAvatarNickname } from "@/hooks/option/useAvatarNicknameApi"; +import type { GardenSummary } from "@/types/home/garden"; + +type Props = RootStackScreenProps<"AvatarNicknameEdit">; + +type SelectableAvatar = { + gardenId: number; + gardenSlotNumber: number; + avatarId: number; + avatarName: string; + avatarImageUrl: string; +}; + +export default function AvatarNicknameEditScreen({ navigation }: Props) { + const { data, isLoading, error, refetch } = useHomeApi(); + const updateAvatarNickname = useUpdateAvatarNickname(); + const [selectedAvatarId, setSelectedAvatarId] = useState(null); + const [draftNickname, setDraftNickname] = useState(""); + + const avatars = useMemo(() => { + if (!data?.gardenSummaries) { + return []; + } + + return data.gardenSummaries + .filter((garden: GardenSummary) => Boolean(garden.avatar?.avatarId)) + .map((garden: GardenSummary) => ({ + gardenId: garden.gardenId, + gardenSlotNumber: garden.gardenSlotNumber, + avatarId: garden.avatar!.avatarId, + avatarName: garden.avatar!.avatarName, + avatarImageUrl: garden.avatar!.avatarImageUrl, + })); + }, [data]); + + const selectedAvatar = + avatars.find(avatar => avatar.avatarId === selectedAvatarId) ?? avatars[0] ?? null; + + const nickname = draftNickname || selectedAvatar?.avatarName || ""; + const trimmedNickname = nickname.trim(); + const isValidNickname = trimmedNickname.length >= 1 && trimmedNickname.length <= 6; + const isChanged = trimmedNickname.length > 0 && trimmedNickname !== (selectedAvatar?.avatarName ?? ""); + + const handleBack = () => { + navigation.goBack(); + }; + + const handleSelectAvatar = (avatarId: number, avatarName: string) => { + setSelectedAvatarId(avatarId); + setDraftNickname(avatarName); + }; + + const handleSubmit = async () => { + if (!selectedAvatar || !isValidNickname || !isChanged || updateAvatarNickname.isPending) { + return; + } + + try { + await updateAvatarNickname.mutateAsync({ + avatarId: selectedAvatar.avatarId, + newAvatarName: trimmedNickname, + }); + navigation.goBack(); + } catch { + Alert.alert("아바타 닉네임 변경에 실패했습니다", "잠시 후 다시 시도해주세요."); + } + }; + + if (isLoading) { + return ( + + + + ); + } + + if (error || !data) { + return ( + + void refetch()} + /> + + ); + } + + if (avatars.length === 0) { + return ( + + + + ); + } + + return ( + + + + 뒤로 + + 아바타 닉네임 변경 + + + + + + 설정 + 식물별 이름을 수정합니다. + + {/* 한글 주석: + 유저 닉네임과 달리 아바타 닉네임은 식물별로 따로 가지므로, + 먼저 변경할 식물을 선택한 뒤 1개 대상만 수정하도록 분리한다. */} + 홈과 프로필에 보이는 식물 이름을 선택해서 바꿀 수 있습니다. + + + + + {avatars.map(avatar => { + const selected = avatar.avatarId === (selectedAvatar?.avatarId ?? null); + return ( + handleSelectAvatar(avatar.avatarId, avatar.avatarName)} + > + + + {avatar.avatarName} + 텃밭 {avatar.gardenSlotNumber} + + + ); + })} + + + 6 + ? "아바타 닉네임은 6자 이하로 입력해주세요." + : "선택한 식물에만 반영됩니다." + } + /> + + + void handleSubmit()} + primaryDisabled={!selectedAvatar || !isValidNickname || !isChanged || updateAvatarNickname.isPending} + primaryLoading={updateAvatarNickname.isPending} + /> + + ); +} + +const styles = StyleSheet.create({ + safeArea: { + flex: 1, + backgroundColor: "#F7F8F4", + }, + header: { + height: 56, + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + paddingHorizontal: 16, + backgroundColor: "#FFFFFF", + borderBottomWidth: StyleSheet.hairlineWidth, + borderBottomColor: "#E5E7EB", + }, + sideButton: { + width: 56, + height: 44, + justifyContent: "center", + }, + backText: { + fontSize: 14, + fontWeight: "600", + color: "#374151", + }, + headerTitle: { + fontSize: 17, + fontWeight: "700", + color: "#171717", + }, + content: { + padding: 20, + gap: 18, + }, + heroCard: { + borderRadius: 22, + padding: 20, + backgroundColor: "#234A2F", + gap: 8, + }, + eyebrow: { + fontSize: 12, + color: "#D7E9D8", + }, + heroTitle: { + fontSize: 24, + lineHeight: 32, + fontWeight: "700", + color: "#FFFFFF", + }, + heroDescription: { + fontSize: 14, + lineHeight: 20, + color: "#E5F4E5", + }, + avatarList: { + gap: 10, + }, + avatarCard: { + flexDirection: "row", + alignItems: "center", + gap: 14, + borderRadius: 18, + backgroundColor: "#FFFFFF", + paddingHorizontal: 16, + paddingVertical: 14, + borderWidth: 1, + borderColor: "#E5E7EB", + }, + avatarCardSelected: { + borderColor: "#2F7D32", + backgroundColor: "#F1FBF1", + }, + avatarImage: { + width: 52, + height: 52, + }, + avatarTextWrap: { + flex: 1, + gap: 4, + }, + avatarCardTitle: { + fontSize: 16, + fontWeight: "700", + color: "#171717", + }, + avatarCardCaption: { + fontSize: 13, + color: "#6B7280", + }, +}); diff --git a/src/pages/option/OptionScreen.tsx b/src/pages/option/OptionScreen.tsx index 5ee83fa..edaabbb 100644 --- a/src/pages/option/OptionScreen.tsx +++ b/src/pages/option/OptionScreen.tsx @@ -57,7 +57,7 @@ export default function OptionScreen({ navigation }: Props) { } /> navigation.navigate("UserNicknameEdit")} /> - + navigation.navigate("AvatarNicknameEdit")} /> navigation.navigate("Policy")} /> Date: Sun, 15 Mar 2026 23:31:14 +0900 Subject: [PATCH 67/92] =?UTF-8?q?refactor:=20=EC=84=9C=EB=B9=84=EC=8A=A4?= =?UTF-8?q?=20=EC=95=88=EB=82=B4=EC=97=90=20=EC=98=A8=EB=B3=B4=EB=94=A9=20?= =?UTF-8?q?=EC=8A=AC=EB=9D=BC=EC=9D=B4=EB=93=9C=20=EC=9E=AC=EC=82=AC?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onboarding/OnboardingCarousel.tsx | 110 ++++++++ src/constants/onboardingSlides.ts | 28 ++ src/navigation/RootNavigator.tsx | 2 + src/navigation/types.ts | 1 + src/pages/onboarding/OnboardingScreen.tsx | 246 ++++-------------- src/pages/option/OptionScreen.tsx | 2 +- src/pages/option/ServiceGuideScreen.tsx | 74 ++++++ 7 files changed, 266 insertions(+), 197 deletions(-) create mode 100644 src/components/onboarding/OnboardingCarousel.tsx create mode 100644 src/constants/onboardingSlides.ts create mode 100644 src/pages/option/ServiceGuideScreen.tsx diff --git a/src/components/onboarding/OnboardingCarousel.tsx b/src/components/onboarding/OnboardingCarousel.tsx new file mode 100644 index 0000000..e9a91f5 --- /dev/null +++ b/src/components/onboarding/OnboardingCarousel.tsx @@ -0,0 +1,110 @@ +import { useState } from "react"; +import { + Dimensions, + FlatList, + Image, + NativeScrollEvent, + NativeSyntheticEvent, + StyleSheet, + Text, + View, +} from "react-native"; +import { onboardingSlides } from "@/constants/onboardingSlides"; + +const { width } = Dimensions.get("window"); + +type Props = { + paginationBottom?: number; +}; + +export default function OnboardingCarousel({ paginationBottom = 80 }: Props) { + const [currentIndex, setCurrentIndex] = useState(0); + + const handleScroll = (event: NativeSyntheticEvent) => { + const contentOffsetX = event.nativeEvent.contentOffset.x; + const index = Math.round(contentOffsetX / width); + setCurrentIndex(index); + }; + + return ( + <> + item.id.toString()} + renderItem={({ item }) => ( + + + + {item.title} + {item.subtitle} + + + )} + /> + + + {onboardingSlides.map((slide, index) => ( + + ))} + + + ); +} + +const styles = StyleSheet.create({ + slide: { + width, + flex: 1, + alignItems: "center", + justifyContent: "center", + paddingHorizontal: 32, + gap: 48, + }, + image: { + width: 256, + height: 256, + }, + textContainer: { + alignItems: "center", + gap: 8, + }, + title: { + fontSize: 20, + fontWeight: "bold", + color: "#000000", + textAlign: "center", + }, + subtitle: { + fontSize: 14, + color: "#4B5563", + textAlign: "center", + }, + pagination: { + flexDirection: "row", + justifyContent: "center", + alignItems: "center", + gap: 8, + }, + dot: { + width: 8, + height: 8, + borderRadius: 4, + }, + dotActive: { + backgroundColor: "#4CAF50", + }, + dotInactive: { + backgroundColor: "#D1D5DB", + }, +}); diff --git a/src/constants/onboardingSlides.ts b/src/constants/onboardingSlides.ts new file mode 100644 index 0000000..226cb68 --- /dev/null +++ b/src/constants/onboardingSlides.ts @@ -0,0 +1,28 @@ +export const onboardingSlides = [ + { + id: 1, + image: require("@/assets/images/onboarding/onboarding1.png"), + title: "나만의 식물을 화면 속에서 만나보세요", + subtitle: "물과 햇빛을 주며 직접 키울 수 있어요", + }, + { + id: 2, + image: require("@/assets/images/onboarding/onboarding2.png"), + title: "실제 식물을 배송받아 키워보세요", + subtitle: "식물 아바타에 해당하는 실제 식물을 키울 수 있어요", + }, + { + id: 3, + image: require("@/assets/images/onboarding/onboarding3.png"), + title: "미션을 통해 나무 레벨을 올리고\n새로운 식물을 키울 수 있어요", + subtitle: "미션 기록은 키움일지에 기록돼요", + }, + { + id: 4, + image: require("@/assets/images/onboarding/onboarding4.png"), + title: "다른 친구들의 이야기를 들을 수 있어요", + subtitle: "둘러보기로 친구를 만들고 방명록을 남겨보세요", + }, +] as const; + +export type OnboardingSlide = (typeof onboardingSlides)[number]; diff --git a/src/navigation/RootNavigator.tsx b/src/navigation/RootNavigator.tsx index a6bac59..bedd752 100644 --- a/src/navigation/RootNavigator.tsx +++ b/src/navigation/RootNavigator.tsx @@ -18,6 +18,7 @@ import FollowScreen from "@/pages/follow/FollowScreen"; import UserNicknameEditScreen from "@/pages/option/UserNicknameEditScreen"; import AvatarNicknameEditScreen from "@/pages/option/AvatarNicknameEditScreen"; import PolicyScreen from "@/pages/option/PolicyScreen"; +import ServiceGuideScreen from "@/pages/option/ServiceGuideScreen"; import DeliveryScreen from "@/pages/delivery/DeliveryScreen"; import DeliveryCompleteScreen from "@/pages/delivery/DeliveryCompleteScreen"; import UnlockGardenScreen from "@/pages/delivery/UnlockGardenScreen"; @@ -80,6 +81,7 @@ export default function RootNavigator() { + diff --git a/src/navigation/types.ts b/src/navigation/types.ts index 93cefc9..973e498 100644 --- a/src/navigation/types.ts +++ b/src/navigation/types.ts @@ -25,6 +25,7 @@ export type RootStackParamList = { UserNicknameEdit: undefined; AvatarNicknameEdit: undefined; Policy: undefined; + ServiceGuide: undefined; // 팔로우 Follow: undefined; diff --git a/src/pages/onboarding/OnboardingScreen.tsx b/src/pages/onboarding/OnboardingScreen.tsx index 3bfe5eb..5153783 100644 --- a/src/pages/onboarding/OnboardingScreen.tsx +++ b/src/pages/onboarding/OnboardingScreen.tsx @@ -1,65 +1,29 @@ -import { useEffect, useState, useRef } from "react"; +import { useEffect, useState } from "react"; import { View, Text, - Image, StyleSheet, - Dimensions, TouchableOpacity, - FlatList, - NativeSyntheticEvent, - NativeScrollEvent, Alert, } from "react-native"; import { useNavigation } from "@react-navigation/native"; import type { NativeStackNavigationProp } from "@react-navigation/native-stack"; import type { RootStackParamList } from "@/navigation/types"; import Splash from "@/components/common/Splash"; +import OnboardingCarousel from "@/components/onboarding/OnboardingCarousel"; +import { onboardingSlides } from "@/constants/onboardingSlides"; import { useSupabaseOAuth } from "@/hooks/auth/useSupabaseOAuth"; import useRegistrationStore from "@/stores/useRegistrationStore"; import { debugLog, debugScreenMounted } from "@/utils/debug"; -const { width } = Dimensions.get("window"); - -const onboardingData = [ - { - id: 1, - image: require("@/assets/images/onboarding/onboarding1.png"), - title: "나만의 식물을 화면 속에서 만나보세요", - subtitle: "물과 햇빛을 주며 직접 키울 수 있어요", - }, - { - id: 2, - image: require("@/assets/images/onboarding/onboarding2.png"), - title: "실제 식물을 배송받아 키워보세요", - subtitle: "식물 아바타에 해당하는 실제 식물을 키울 수 있어요", - }, - { - id: 3, - image: require("@/assets/images/onboarding/onboarding3.png"), - title: "미션을 통해 나무 레벨을 올리고\n새로운 식물을 키울 수 있어요", - subtitle: "미션 기록은 키움일지에 기록돼요", - }, - { - id: 4, - image: require("@/assets/images/onboarding/onboarding4.png"), - title: "다른 친구들의 이야기를 들을 수 있어요", - subtitle: "둘러보기로 친구를 만들고 방명록을 남겨보세요", - }, -]; - type NavigationProp = NativeStackNavigationProp; export default function OnboardingScreen() { const [isSplash, setIsSplash] = useState(true); - const [currentIndex, setCurrentIndex] = useState(0); - const flatListRef = useRef(null); const navigation = useNavigation(); const { performOAuth, isLoading, isExpoGo } = useSupabaseOAuth(); const resetRegistration = useRegistrationStore(state => state.reset); - const isLastSlide = currentIndex === onboardingData.length - 1; - useEffect(() => { debugScreenMounted("OnboardingScreen"); const timer = setTimeout(() => { @@ -69,16 +33,6 @@ export default function OnboardingScreen() { return () => clearTimeout(timer); }, []); - useEffect(() => { - debugLog("OnboardingScreen", "Slide changed", { currentIndex }); - }, [currentIndex]); - - const handleScroll = (event: NativeSyntheticEvent) => { - const contentOffsetX = event.nativeEvent.contentOffset.x; - const index = Math.round(contentOffsetX / width); - setCurrentIndex(index); - }; - const handleStart = () => { debugLog("OnboardingScreen", "Navigate -> Register"); navigation.navigate("Register"); @@ -104,21 +58,18 @@ export default function OnboardingScreen() { cancelled: result?.cancelled, }); - if (result?.success) { - if (result.isNewUser) { - resetRegistration(); - debugLog("OnboardingScreen", "Reset -> SocialNickname for new social user"); - navigation.reset({ - index: 0, - routes: [ - { - name: "SocialNickname", - params: { initialNickname: result.nickname }, - }, - ], - }); - return; - } + if (result?.success && result.isNewUser) { + resetRegistration(); + debugLog("OnboardingScreen", "Reset -> SocialNickname for new social user"); + navigation.reset({ + index: 0, + routes: [ + { + name: "SocialNickname", + params: { initialNickname: result.nickname }, + }, + ], + }); } }; @@ -126,82 +77,44 @@ export default function OnboardingScreen() { return ( - item.id.toString()} - renderItem={({ item }) => ( - - - - {item.title} - {item.subtitle} - - - )} - /> + - - {onboardingData.map((_, index) => ( - + + - ))} - - - - {isLastSlide ? ( - - handleOAuthLogin("kakao")} - disabled={isLoading || isExpoGo} - > - - {isLoading ? "처리 중..." : "카카오로 시작하기"} - - - - {isExpoGo ? ( - - Expo Go에서는 카카오 로그인 대신 구글 로그인 또는 development build를 사용해주세요. - - ) : null} - - handleOAuthLogin("google")} - disabled={isLoading} - > - - {isLoading ? "처리 중..." : "구글로 시작하기"} - - + onPress={() => handleOAuthLogin("kakao")} + disabled={isLoading || isExpoGo} + > + + {isLoading ? "처리 중..." : "카카오로 시작하기"} + + - - 비회원으로 화단 만들기 - - - ) : ( - - - 나만의 화단 만들러 가기 + {isExpoGo ? ( + + Expo Go에서는 카카오 로그인 대신 구글 로그인 또는 development build를 사용해주세요. + + ) : null} + + handleOAuthLogin("google")} + disabled={isLoading} + > + + {isLoading ? "처리 중..." : "구글로 시작하기"} - )} + + + 비회원으로 화단 만들기 + + ); @@ -212,72 +125,10 @@ const styles = StyleSheet.create({ flex: 1, backgroundColor: "#FFFFFF", }, - slide: { - width, - flex: 1, - alignItems: "center", - justifyContent: "center", - paddingHorizontal: 32, - gap: 48, - }, - image: { - width: 256, - height: 256, - }, - textContainer: { - alignItems: "center", - gap: 8, - }, - title: { - fontSize: 20, - fontWeight: "bold", - color: "#000000", - textAlign: "center", - }, - subtitle: { - fontSize: 14, - color: "#4B5563", - textAlign: "center", - }, - pagination: { - flexDirection: "row", - justifyContent: "center", - alignItems: "center", - gap: 8, - marginBottom: 80, - }, - dot: { - width: 8, - height: 8, - borderRadius: 4, - }, - dotActive: { - backgroundColor: "#4CAF50", - }, - dotInactive: { - backgroundColor: "#D1D5DB", - }, buttonContainer: { paddingHorizontal: 32, paddingBottom: 32, }, - button: { - backgroundColor: "#4CAF50", - paddingVertical: 16, - borderRadius: 12, - alignItems: "center", - }, - buttonDisabled: { - backgroundColor: "#E5E7EB", - }, - buttonText: { - color: "#FFFFFF", - fontSize: 16, - fontWeight: "600", - }, - buttonTextDisabled: { - color: "#9CA3AF", - }, socialAuthContainer: { gap: 12, }, @@ -304,6 +155,9 @@ const styles = StyleSheet.create({ fontSize: 16, fontWeight: "600", }, + buttonDisabled: { + backgroundColor: "#E5E7EB", + }, guestButton: { paddingVertical: 16, alignItems: "center", diff --git a/src/pages/option/OptionScreen.tsx b/src/pages/option/OptionScreen.tsx index edaabbb..68d2ec3 100644 --- a/src/pages/option/OptionScreen.tsx +++ b/src/pages/option/OptionScreen.tsx @@ -59,7 +59,7 @@ export default function OptionScreen({ navigation }: Props) { navigation.navigate("UserNicknameEdit")} /> navigation.navigate("AvatarNicknameEdit")} /> navigation.navigate("Policy")} /> - + navigation.navigate("ServiceGuide")} /> ; + +export default function ServiceGuideScreen({ navigation }: Props) { + return ( + + + navigation.goBack()} + activeOpacity={0.7} + style={styles.headerSideButton} + > + 뒤로 + + 서비스 안내 + + + + + {/* 한글 주석: + 서비스 안내는 별도 API 없이 온보딩의 4장 소개 슬라이드를 그대로 재사용하되, + 설정 화면 진입 문맥에 맞게 상단 헤더만 박스형으로 따로 얹는다. */} + + + + ); +} + +const styles = StyleSheet.create({ + safeArea: { + flex: 1, + backgroundColor: "#FFFFFF", + }, + headerCard: { + marginHorizontal: 16, + marginTop: 8, + marginBottom: 8, + minHeight: 56, + borderRadius: 18, + backgroundColor: "rgba(255,255,255,0.96)", + flexDirection: "row", + alignItems: "center", + paddingHorizontal: 12, + shadowColor: "#000", + shadowOffset: { width: 0, height: 2 }, + shadowOpacity: 0.08, + shadowRadius: 10, + elevation: 3, + }, + headerSideButton: { + width: 56, + minHeight: 44, + justifyContent: "center", + }, + backText: { + fontSize: 14, + fontWeight: "600", + color: "#374151", + }, + headerTitle: { + flex: 1, + textAlign: "center", + fontSize: 18, + fontWeight: "700", + color: "#171717", + }, + carouselWrap: { + flex: 1, + }, +}); From 4b790f304086654fe5b1bcd02090d0ce9f296d51 Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 23:39:11 +0900 Subject: [PATCH 68/92] =?UTF-8?q?chore:=20=EB=B9=84=ED=9A=8C=EC=9B=90=20?= =?UTF-8?q?=EC=86=8C=EC=85=9C=20=EC=97=B0=EB=8F=99=20=EC=A0=84=ED=99=98=20?= =?UTF-8?q?=EA=B3=84=ED=9A=8D=20=EB=AC=B8=EC=84=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- GUEST_TO_SOCIAL_LINKING_PLAN.md | 125 ++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 GUEST_TO_SOCIAL_LINKING_PLAN.md diff --git a/GUEST_TO_SOCIAL_LINKING_PLAN.md b/GUEST_TO_SOCIAL_LINKING_PLAN.md new file mode 100644 index 0000000..db8e4f0 --- /dev/null +++ b/GUEST_TO_SOCIAL_LINKING_PLAN.md @@ -0,0 +1,125 @@ +# Guest To Social Linking Plan + +## 목표 + +- 현재의 `비회원으로 화단 만들기` 진입 장점을 유지한다. +- 사용자가 식물, 방명록, 피드 등을 써본 뒤 원할 때 소셜 계정으로 연동할 수 있게 한다. +- 장기적으로는 계정 복구와 다기기 사용성을 확보한다. + +## 현재 판단 + +### 지금 UX 상태 + +- 비회원 시작도 초반에 닉네임을 입력한다. +- 소셜 신규 가입도 초반에 닉네임을 입력한다. +- 그래서 둘의 초기 마찰은 현재 거의 비슷하다. + +### 바로 비회원 가입을 없애지 않는 이유 + +- 첫 진입 장벽은 비회원이 가장 낮다. +- 소셜 로그인 강제는 첫 사용 이탈을 늘릴 가능성이 있다. +- 서비스 특성상 먼저 써보고 나중에 계정 보존 필요성을 느끼게 만드는 쪽이 자연스럽다. + +## 추천 방향 + +### 단기 + +- 비회원 가입 유지 +- 소셜 신규 가입도 유지 +- 설정 화면 또는 특정 시점에서 `소셜 계정 연동` 진입점 제공 + +### 중기 + +- 비회원 유저가 식물 등록, 방명록 작성, 피드 참여 등 핵심 행동 후 + 계정 연동의 장점을 설명하며 연동을 유도 +- 예시 문구: + - 기기 변경 시 기록을 보존할 수 있어요 + - 방명록과 식물 기록을 안전하게 저장할 수 있어요 + +### 장기 + +- 연동률과 이탈률을 보고 비회원 축소 여부 판단 +- 실제 데이터상 문제 없을 때만 소셜 우선 정책 검토 + +## MainAPP 변경 포인트 + +### 1. 설정 화면에 소셜 계정 연동 메뉴 추가 + +- 위치: `OptionScreen` +- 목적: 언제든 사용자가 계정을 승격할 수 있게 함 + +### 2. 연동 전용 화면 또는 바텀시트 추가 + +- 선택지: + - 구글 연동 + - 카카오 연동 +- 주의: + - 이미 다른 계정에 연결된 소셜 계정인지 에러 처리 필요 + +### 3. 연동 유도 진입 타이밍 설계 + +- 예시: + - 첫 방명록 작성 직후 + - 첫 아바타 등록 완료 후 + - 설정 화면 상단 배너 + +### 4. 연동 완료 후 사용자 안내 + +- 문구 예시: + - 이제 소셜 계정으로 로그인해도 현재 텃밭을 그대로 이어서 사용할 수 있어요. + +## MainBE 변경 포인트 + +### 1. 비회원 계정과 소셜 계정 연결 API 추가 + +- 예시 엔드포인트: + - `POST /api/v1/auth/link-social` +- 입력값 예시: + - Supabase access token +- 처리 내용: + - 현재 로그인된 비회원 사용자와 소셜 계정을 연결 + - 이미 다른 유저에 연결된 소셜 계정이면 차단 + +### 2. User 엔티티에 계정 상태 구분 정리 + +- 현재는 비회원/소셜 구분이 명확하지 않을 수 있음 +- 최소한 아래 식별값이 필요함 + - anonymous/guest 여부 + - oauthProvider + - oauthSubject + - linkedAt + +### 3. 중복 계정 충돌 처리 + +- 같은 소셜 계정이 이미 다른 사용자에 연결된 경우 +- 현재 게스트 계정 데이터와 병합할지, 차단할지 정책 필요 +- 추천은 초기엔 `병합 금지, 연결 차단`이다 + +### 4. 로그인 응답 구조 정리 + +- 연동된 계정인지 +- 신규 소셜 가입인지 +- 기존 연동 계정 로그인인지 +- 프론트가 명확히 분기할 수 있게 응답값 보강 필요 + +## 권장 정책 + +### 초기 정책 + +- 비회원 -> 소셜 연동: 허용 +- 이미 독립적으로 생성된 다른 소셜 계정과 데이터 병합: 금지 +- 충돌 시 사용자에게 새 계정 생성 대신 기존 계정이 존재한다고 안내 + +### 이유 + +- 병합 로직은 방명록, 피드, 정원, 아바타, 알림, 팔로우 등 전체 도메인을 건드려 리스크가 크다. +- 먼저 `단일 사용자에 소셜 식별자 연결`까지만 구현하는 것이 안전하다. + +## 결론 + +- 지금은 `비회원 가입 제거`보다 `비회원 유지 + 나중에 소셜 연동`이 더 적절하다. +- 구현 우선순위는 + 1. 설정의 소셜 연동 진입점 + 2. MainBE 계정 연결 API + 3. 충돌 처리 정책 + 순서가 맞다. From 18dd0d72fa804cf83c525de9f62cb8bc74bb4cd3 Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 15 Mar 2026 23:58:54 +0900 Subject: [PATCH 69/92] =?UTF-8?q?feat:=20=EC=86=8C=EC=85=9C=20=EB=8B=89?= =?UTF-8?q?=EB=84=A4=EC=9E=84=20=EC=84=A4=EC=A0=95=20=ED=95=84=EC=9A=94=20?= =?UTF-8?q?=EC=9D=91=EB=8B=B5=20=EB=B6=84=EA=B8=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/auth/useSupabaseOAuth.ts | 3 +++ src/pages/onboarding/OnboardingScreen.tsx | 6 +++--- src/types/apis/register.ts | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/hooks/auth/useSupabaseOAuth.ts b/src/hooks/auth/useSupabaseOAuth.ts index 1853f7a..4598589 100644 --- a/src/hooks/auth/useSupabaseOAuth.ts +++ b/src/hooks/auth/useSupabaseOAuth.ts @@ -15,6 +15,7 @@ type OAuthResult = { cancelled?: boolean; error?: unknown; isNewUser?: boolean; + requiresNicknameSetup?: boolean; nickname?: string; }; @@ -88,11 +89,13 @@ export const useSupabaseOAuth = () => { debugLog("SupabaseOAuth", "Backend login complete", { isNewUser: backendRes.result?.newUser, + requiresNicknameSetup: backendRes.result?.requiresNicknameSetup, nickname: backendRes.result?.nickname, }); return { success: true, isNewUser: backendRes.result?.newUser, + requiresNicknameSetup: backendRes.result?.requiresNicknameSetup, nickname: backendRes.result?.nickname, }; }; diff --git a/src/pages/onboarding/OnboardingScreen.tsx b/src/pages/onboarding/OnboardingScreen.tsx index 5153783..b3aea28 100644 --- a/src/pages/onboarding/OnboardingScreen.tsx +++ b/src/pages/onboarding/OnboardingScreen.tsx @@ -11,7 +11,6 @@ import type { NativeStackNavigationProp } from "@react-navigation/native-stack"; import type { RootStackParamList } from "@/navigation/types"; import Splash from "@/components/common/Splash"; import OnboardingCarousel from "@/components/onboarding/OnboardingCarousel"; -import { onboardingSlides } from "@/constants/onboardingSlides"; import { useSupabaseOAuth } from "@/hooks/auth/useSupabaseOAuth"; import useRegistrationStore from "@/stores/useRegistrationStore"; import { debugLog, debugScreenMounted } from "@/utils/debug"; @@ -55,12 +54,13 @@ export default function OnboardingScreen() { provider, success: result?.success, isNewUser: result?.isNewUser, + requiresNicknameSetup: result?.requiresNicknameSetup, cancelled: result?.cancelled, }); - if (result?.success && result.isNewUser) { + if (result?.success && (result.requiresNicknameSetup || result.isNewUser)) { resetRegistration(); - debugLog("OnboardingScreen", "Reset -> SocialNickname for new social user"); + debugLog("OnboardingScreen", "Reset -> SocialNickname for nickname-incomplete social user"); navigation.reset({ index: 0, routes: [ diff --git a/src/types/apis/register.ts b/src/types/apis/register.ts index 40f9987..ff2cf69 100644 --- a/src/types/apis/register.ts +++ b/src/types/apis/register.ts @@ -4,4 +4,5 @@ export type PostRegisterResponse = { userId: number; nickname: string; newUser: boolean; + requiresNicknameSetup: boolean; }; From fdbaf51f71a86ff2b57d9f8ce7a644ac9f0ef87c Mon Sep 17 00:00:00 2001 From: lejuho Date: Mon, 16 Mar 2026 00:38:25 +0900 Subject: [PATCH 70/92] =?UTF-8?q?feat:=20=ED=83=80=EC=9D=B8=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=ED=95=84=20=EB=AC=BC=EC=A3=BC=EA=B8=B0=20=EC=97=B0?= =?UTF-8?q?=EC=B6=9C=EA=B3=BC=20=EC=83=81=ED=83=9C=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/profile/ProfileGardenScene.tsx | 37 +++++++++++++++---- src/pages/profile/ProfileScreen.tsx | 14 ++++++- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/components/profile/ProfileGardenScene.tsx b/src/components/profile/ProfileGardenScene.tsx index ed1d3de..299e569 100644 --- a/src/components/profile/ProfileGardenScene.tsx +++ b/src/components/profile/ProfileGardenScene.tsx @@ -1,9 +1,11 @@ import { Image, ImageBackground, StyleSheet, Text, TouchableOpacity, View } from "react-native"; -import { useSafeAreaInsets } from "react-native-safe-area-context"; + import type { GardenInfo } from "@/types/profile/profileApi.type"; import WaterIcon from "@/assets/icons/water.svg"; +import { useSafeAreaInsets } from "react-native-safe-area-context"; const mailboxImage = require("@/assets/images/profile/letterbox.png"); +const wateringImage = require("@/assets/images/background/watering.png"); const ACTION_RAIL_BOTTOM_OFFSET = 128; type Props = { @@ -11,6 +13,7 @@ type Props = { garden: GardenInfo; isMe: boolean; leftWaterCountForOthers: number; + isWateringVisible: boolean; onWater: () => void; onPressGuestbook: () => void; waterDisabled?: boolean; @@ -21,6 +24,7 @@ export default function ProfileGardenScene({ garden, isMe, leftWaterCountForOthers, + isWateringVisible, onWater, onPressGuestbook, waterDisabled = false, @@ -42,11 +46,18 @@ export default function ProfileGardenScene({ {garden.avatarInfo?.avatarImageUrl ? ( - + <> + + + ) : ( 정원 정보가 준비되지 않았습니다. @@ -122,14 +133,24 @@ const styles = StyleSheet.create({ justifyContent: "center", alignItems: "center", paddingHorizontal: 24, - paddingTop: 44, - paddingBottom: 64, + paddingTop: 340, + paddingBottom: -32, position: "relative", }, avatarImage: { width: 300, height: 300, }, + wateringImage: { + position: "absolute", + left: "24%", + bottom: 196, + width: 118, + height: 118, + }, + wateringImageHidden: { + opacity: 0, + }, mailboxWrap: { position: "absolute", right: 48, diff --git a/src/pages/profile/ProfileScreen.tsx b/src/pages/profile/ProfileScreen.tsx index f645f01..ac92271 100644 --- a/src/pages/profile/ProfileScreen.tsx +++ b/src/pages/profile/ProfileScreen.tsx @@ -34,6 +34,7 @@ export default function ProfileScreen({ navigation, route }: Props) { const followMutation = useFollowUser(myUserId); const unfollowMutation = useUnfollowUser(myUserId); const [currentPage, setCurrentPage] = useState(0); + const [wateringGardenId, setWateringGardenId] = useState(null); const isMe = String(userId) === myUserId; @@ -53,6 +54,16 @@ export default function ProfileScreen({ navigation, route }: Props) { }); }; + const handleFriendWater = async (gardenId: number) => { + await waterMutation.mutateAsync(gardenId); + + // Show the watering overlay briefly on the just-watered garden. + setWateringGardenId(gardenId); + setTimeout(() => { + setWateringGardenId(prev => (prev === gardenId ? null : prev)); + }, 1000); + }; + const followAction = useMemo(() => { if (!data || isMe) return null; @@ -200,7 +211,8 @@ export default function ProfileScreen({ navigation, route }: Props) { garden={scene.garden} isMe={isMe} leftWaterCountForOthers={data.leftWaterCountForOthers} - onWater={() => void waterMutation.mutateAsync(scene.garden.gardenId)} + isWateringVisible={wateringGardenId === scene.garden.gardenId} + onWater={() => void handleFriendWater(scene.garden.gardenId)} onPressGuestbook={handleOpenGuestbook} waterDisabled={waterMutation.isPending} /> From de6a3d0a99db6e8dd787868b3f44907192119ca7 Mon Sep 17 00:00:00 2001 From: lejuho Date: Mon, 16 Mar 2026 00:42:05 +0900 Subject: [PATCH 71/92] =?UTF-8?q?feat:=20=ED=83=80=EC=9D=B8=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=ED=95=84=20=EB=AC=BC=EC=A3=BC=EA=B8=B0=20=EC=84=B1?= =?UTF-8?q?=EA=B3=B5=20=ED=86=A0=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/profile/ProfileScreen.tsx | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/pages/profile/ProfileScreen.tsx b/src/pages/profile/ProfileScreen.tsx index ac92271..6a51776 100644 --- a/src/pages/profile/ProfileScreen.tsx +++ b/src/pages/profile/ProfileScreen.tsx @@ -7,10 +7,12 @@ import { TouchableOpacity, View, } from "react-native"; +import type { AxiosError } from "axios"; import PagerView from "react-native-pager-view"; import { SafeAreaView } from "react-native-safe-area-context"; import type { RootStackScreenProps } from "@/navigation/types"; import StatusView from "@/components/common/StatusView"; +import HomeToast from "@/components/home/HomeToast"; import ProfileGardenScene from "@/components/profile/ProfileGardenScene"; import { useFriendWater, useUserProfile } from "@/hooks/profile/useProfileApi"; import { useFollowUser, useUnfollowUser } from "@/hooks/follow/useFollowApi"; @@ -35,6 +37,7 @@ export default function ProfileScreen({ navigation, route }: Props) { const unfollowMutation = useUnfollowUser(myUserId); const [currentPage, setCurrentPage] = useState(0); const [wateringGardenId, setWateringGardenId] = useState(null); + const [toastMessage, setToastMessage] = useState(null); const isMe = String(userId) === myUserId; @@ -55,13 +58,21 @@ export default function ProfileScreen({ navigation, route }: Props) { }; const handleFriendWater = async (gardenId: number) => { - await waterMutation.mutateAsync(gardenId); + try { + await waterMutation.mutateAsync(gardenId); - // Show the watering overlay briefly on the just-watered garden. - setWateringGardenId(gardenId); - setTimeout(() => { - setWateringGardenId(prev => (prev === gardenId ? null : prev)); - }, 1000); + // Show a short overlay and toast so the success state is obvious. + setWateringGardenId(gardenId); + setToastMessage("\uce5c\uad6c \uc815\uc6d0\uc5d0 \ubb3c\uc744 \uc8fc\uc5c8\uc2b5\ub2c8\ub2e4."); + setTimeout(() => { + setWateringGardenId(prev => (prev === gardenId ? null : prev)); + }, 1000); + } catch (error) { + const axiosError = error as AxiosError<{ message?: string }>; + setToastMessage( + axiosError.response?.data?.message ?? "\uce5c\uad6c \ubb3c\uc8fc\uae30\uc5d0 \uc2e4\ud328\ud588\uc2b5\ub2c8\ub2e4." + ); + } }; const followAction = useMemo(() => { @@ -235,6 +246,10 @@ export default function ProfileScreen({ navigation, route }: Props) { ))} + + {toastMessage ? ( + setToastMessage(null)} /> + ) : null} ); } From 586addc14f416d344338af4db805a087da8c0d9d Mon Sep 17 00:00:00 2001 From: lejuho Date: Mon, 16 Mar 2026 01:01:07 +0900 Subject: [PATCH 72/92] =?UTF-8?q?fix:=20=EB=AC=BC=EC=A3=BC=EA=B8=B0=20?= =?UTF-8?q?=EC=97=B0=EC=86=8D=20=ED=83=AD=20=EC=BF=A8=EB=8B=A4=EC=9A=B4=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/home/HomeGardenScene.tsx | 12 +++++++++--- src/pages/profile/ProfileScreen.tsx | 5 ++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/components/home/HomeGardenScene.tsx b/src/components/home/HomeGardenScene.tsx index c8b6a48..2abe254 100644 --- a/src/components/home/HomeGardenScene.tsx +++ b/src/components/home/HomeGardenScene.tsx @@ -25,8 +25,9 @@ const mapIcon = require("@/assets/images/map.png"); const emptyGardenImage = require("@/assets/images/null.webp"); const sunlightOverlay = require("@/assets/images/background/sunlight.png"); -const SCENE_BOTTOM_OFFSET = 64; +const SCENE_BOTTOM_OFFSET = -16; const ACTION_RAIL_BOTTOM_OFFSET = 128; +const WATER_ACTION_COOLDOWN_MS = 700; type Props = { background: any; @@ -61,6 +62,7 @@ export default function HomeGardenScene({ const [isWateringVisible, setIsWateringVisible] = useState(false); const [canSunlight, setCanSunlight] = useState(Boolean(garden?.ownerSunlightAble)); const [canWater, setCanWater] = useState(Boolean(garden?.ownerWateringAble)); + const [isWaterCooldownActive, setIsWaterCooldownActive] = useState(false); const [toastMessage, setToastMessage] = useState(null); useEffect(() => { @@ -178,9 +180,13 @@ export default function HomeGardenScene({ activeOpacity={0.85} onPress={() => void handleWater()} style={styles.actionButton} - disabled={waterMutation.isPending} + disabled={waterMutation.isPending || isWaterCooldownActive} > - + ) : null} diff --git a/src/pages/profile/ProfileScreen.tsx b/src/pages/profile/ProfileScreen.tsx index 6a51776..7cf952f 100644 --- a/src/pages/profile/ProfileScreen.tsx +++ b/src/pages/profile/ProfileScreen.tsx @@ -21,6 +21,8 @@ import { FollowStatus } from "@/types/profile/profileApi.type"; type Props = RootStackScreenProps<"Profile">; +const FRIEND_WATER_ACTION_COOLDOWN_MS = 700; + const backgrounds = [ require("@/assets/images/background/background1.webp"), require("@/assets/images/background/background2.webp"), @@ -37,6 +39,7 @@ export default function ProfileScreen({ navigation, route }: Props) { const unfollowMutation = useUnfollowUser(myUserId); const [currentPage, setCurrentPage] = useState(0); const [wateringGardenId, setWateringGardenId] = useState(null); + const [isFriendWaterCooldownActive, setIsFriendWaterCooldownActive] = useState(false); const [toastMessage, setToastMessage] = useState(null); const isMe = String(userId) === myUserId; @@ -225,7 +228,7 @@ export default function ProfileScreen({ navigation, route }: Props) { isWateringVisible={wateringGardenId === scene.garden.gardenId} onWater={() => void handleFriendWater(scene.garden.gardenId)} onPressGuestbook={handleOpenGuestbook} - waterDisabled={waterMutation.isPending} + waterDisabled={waterMutation.isPending || isFriendWaterCooldownActive} /> ))} From 0f8d16488357b61bef414e01360e11feb51c070b Mon Sep 17 00:00:00 2001 From: lejuho Date: Mon, 16 Mar 2026 01:21:04 +0900 Subject: [PATCH 73/92] =?UTF-8?q?feat:=20=ED=99=88=20=EB=B9=84=EB=91=98?= =?UTF-8?q?=EA=B8=B0=20=EA=B8=B0=EB=A1=9D=20unread=20=EB=B0=B0=EC=A7=80?= =?UTF-8?q?=EC=99=80=20=EC=9D=BD=EC=9D=8C=20=EC=B2=98=EB=A6=AC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/home/homeApi.ts | 5 ++++ src/components/home/HomeAlertsModal.tsx | 36 +++++++++++++++++++++++-- src/components/home/HomeGardenScene.tsx | 3 +++ src/hooks/home/useHomeApi.ts | 23 ++++++++++++++++ src/pages/home/HomeScreen.tsx | 1 + 5 files changed, 66 insertions(+), 2 deletions(-) diff --git a/src/apis/home/homeApi.ts b/src/apis/home/homeApi.ts index e2f2d2d..2d4c5e4 100644 --- a/src/apis/home/homeApi.ts +++ b/src/apis/home/homeApi.ts @@ -47,6 +47,11 @@ export const getNotifications = async (): ApiResponse => { return res.data; }; +export const patchNotificationRead = async (notificationId: number) => { + const res = await api.patch(`/api/v1/notifications/${notificationId}/read`); + return res.data; +}; + export const getGuestbookList = async ( userId: number ): ApiResponse => { diff --git a/src/components/home/HomeAlertsModal.tsx b/src/components/home/HomeAlertsModal.tsx index da60025..86fa5f9 100644 --- a/src/components/home/HomeAlertsModal.tsx +++ b/src/components/home/HomeAlertsModal.tsx @@ -1,4 +1,4 @@ -import { useMemo, useState } from "react"; +import { useEffect, useMemo, useState } from "react"; import { Modal, Pressable, @@ -8,7 +8,7 @@ import { TouchableOpacity, View, } from "react-native"; -import { useGuestbookList, useNotifications } from "@/hooks/home/useHomeApi"; +import { useGuestbookList, useNotifications, useReadNotifications } from "@/hooks/home/useHomeApi"; import type { GuestbookEntry, NotificationItem } from "@/types/home/alerts"; type AlertTab = "GUESTBOOK" | "RECORD"; @@ -23,8 +23,10 @@ export default function HomeAlertsModal({ onClose: () => void; }) { const [activeTab, setActiveTab] = useState("GUESTBOOK"); + const [hasMarkedRecordAsReadThisOpen, setHasMarkedRecordAsReadThisOpen] = useState(false); const notificationsQuery = useNotifications(visible); const guestbookQuery = useGuestbookList(userId, visible); + const readNotificationsMutation = useReadNotifications(); const activeState = useMemo(() => { if (activeTab === "GUESTBOOK") { @@ -50,6 +52,36 @@ export default function HomeAlertsModal({ notificationsQuery.isLoading, ]); + useEffect(() => { + if (!visible) { + setHasMarkedRecordAsReadThisOpen(false); + return; + } + + if (activeTab !== "RECORD" || hasMarkedRecordAsReadThisOpen) { + return; + } + + const unreadNotificationIds = + notificationsQuery.data + ?.filter(item => !item.isRead) + .map(item => item.id) ?? []; + + setHasMarkedRecordAsReadThisOpen(true); + + if (unreadNotificationIds.length === 0) { + return; + } + + void readNotificationsMutation.mutateAsync(unreadNotificationIds); + }, [ + activeTab, + hasMarkedRecordAsReadThisOpen, + notificationsQuery.data, + readNotificationsMutation, + visible, + ]); + return ( diff --git a/src/components/home/HomeGardenScene.tsx b/src/components/home/HomeGardenScene.tsx index 2abe254..5f336f7 100644 --- a/src/components/home/HomeGardenScene.tsx +++ b/src/components/home/HomeGardenScene.tsx @@ -36,6 +36,7 @@ type Props = { garden: GardenSummary | null; isEmotionAnswered: boolean; answeredKind: SurveyAnswerKind | null; + unreadNotificationCount?: number; onPressMap: () => void; onPressBird: () => void; onPressEmotion: () => void; @@ -50,6 +51,7 @@ export default function HomeGardenScene({ garden, isEmotionAnswered, answeredKind, + unreadNotificationCount = 0, onPressMap, onPressBird, onPressEmotion, @@ -205,6 +207,7 @@ export default function HomeGardenScene({ isWatering={isWateringVisible} isEmotionAnswered={isEmotionAnswered} answeredKind={answeredKind} + unreadNotificationCount={unreadNotificationCount} onPressEmotion={onPressEmotion} onPressBird={onPressBird} /> diff --git a/src/hooks/home/useHomeApi.ts b/src/hooks/home/useHomeApi.ts index fdd917e..9b969db 100644 --- a/src/hooks/home/useHomeApi.ts +++ b/src/hooks/home/useHomeApi.ts @@ -6,6 +6,7 @@ import { getHomeSummary, getNotifications, getTrackingPromptStatus, + patchNotificationRead, postGardenMyWater, postGardenSunlight, postTrackingPromptConfirm, @@ -71,6 +72,28 @@ export const useNotifications = (enabled: boolean) => enabled, }); +export const useReadNotifications = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: async (notificationIds: number[]) => { + await Promise.all( + notificationIds.map(notificationId => patchNotificationRead(notificationId)) + ); + }, + onSuccess: async (_, notificationIds) => { + queryClient.setQueryData(["notifications"], previous => + previous?.map(item => + notificationIds.includes(item.id) ? { ...item, isRead: true } : item + ) ?? previous + ); + + await queryClient.invalidateQueries({ queryKey: ["notifications"] }); + await queryClient.invalidateQueries({ queryKey: ["home-summary"] }); + }, + }); +}; + export const useGuestbookList = (userId: number | null, enabled: boolean) => useQuery, AxiosError, GuestbookEntry[]>({ queryKey: ["guestbook-list", userId], diff --git a/src/pages/home/HomeScreen.tsx b/src/pages/home/HomeScreen.tsx index 85b7faf..b702dbf 100644 --- a/src/pages/home/HomeScreen.tsx +++ b/src/pages/home/HomeScreen.tsx @@ -234,6 +234,7 @@ export default function HomeScreen({ navigation }: Props) { garden={scene.garden} isEmotionAnswered={isEmotionAnswered} answeredKind={answeredKind} + unreadNotificationCount={userInfo?.unreadNotificationCount ?? 0} onPressMap={() => setIsMapModalOpen(true)} onPressBird={() => setIsAlertsModalOpen(true)} onPressEmotion={() => setIsEmotionModalOpen(true)} From d18d851f67749aa57e5c385332a56c99158b8701 Mon Sep 17 00:00:00 2001 From: lejuho Date: Mon, 16 Mar 2026 01:26:01 +0900 Subject: [PATCH 74/92] =?UTF-8?q?fix:=20=ED=99=88=20=EC=95=8C=EB=A6=BC=20?= =?UTF-8?q?=EC=9D=BD=EC=9D=8C=20=EC=BA=90=EC=8B=9C=EC=99=80=20=EB=B0=B0?= =?UTF-8?q?=EC=A7=80=20=EB=8F=99=EA=B8=B0=ED=99=94=20=EB=B3=B4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/home/HomeAlertsModal.tsx | 12 +++++--- src/hooks/home/useHomeApi.ts | 41 ++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/src/components/home/HomeAlertsModal.tsx b/src/components/home/HomeAlertsModal.tsx index 86fa5f9..12c35e2 100644 --- a/src/components/home/HomeAlertsModal.tsx +++ b/src/components/home/HomeAlertsModal.tsx @@ -62,10 +62,13 @@ export default function HomeAlertsModal({ return; } - const unreadNotificationIds = - notificationsQuery.data - ?.filter(item => !item.isRead) - .map(item => item.id) ?? []; + if (notificationsQuery.isLoading || !notificationsQuery.data) { + return; + } + + const unreadNotificationIds = notificationsQuery.data + .filter(item => !item.isRead) + .map(item => item.id); setHasMarkedRecordAsReadThisOpen(true); @@ -78,6 +81,7 @@ export default function HomeAlertsModal({ activeTab, hasMarkedRecordAsReadThisOpen, notificationsQuery.data, + notificationsQuery.isLoading, readNotificationsMutation, visible, ]); diff --git a/src/hooks/home/useHomeApi.ts b/src/hooks/home/useHomeApi.ts index 9b969db..5b72490 100644 --- a/src/hooks/home/useHomeApi.ts +++ b/src/hooks/home/useHomeApi.ts @@ -82,10 +82,43 @@ export const useReadNotifications = () => { ); }, onSuccess: async (_, notificationIds) => { - queryClient.setQueryData(["notifications"], previous => - previous?.map(item => - notificationIds.includes(item.id) ? { ...item, isRead: true } : item - ) ?? previous + queryClient.setQueryData>( + ["notifications"], + previous => + previous + ? { + ...previous, + result: previous.result.map(item => + notificationIds.includes(item.id) ? { ...item, isRead: true } : item + ), + } + : previous + ); + + queryClient.setQueryData>( + ["home-summary"], + previous => { + if (!previous) { + return previous; + } + + const unreadDelta = previous.result.userInfo.unreadNotificationCount; + const nextUnreadCount = Math.max( + 0, + unreadDelta - notificationIds.length + ); + + return { + ...previous, + result: { + ...previous.result, + userInfo: { + ...previous.result.userInfo, + unreadNotificationCount: nextUnreadCount, + }, + }, + }; + } ); await queryClient.invalidateQueries({ queryKey: ["notifications"] }); From 69d118ad33e9ba65ca3e8f10b541fd5ec8912ee5 Mon Sep 17 00:00:00 2001 From: lejuho Date: Mon, 16 Mar 2026 02:06:58 +0900 Subject: [PATCH 75/92] =?UTF-8?q?fix:=20=ED=99=88=20=EC=95=8C=EB=A6=BC=20?= =?UTF-8?q?=EC=9D=BD=EC=9D=8C=20=ED=95=84=EB=93=9C=20=ED=98=B8=ED=99=98=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/home/HomeAlertsModal.tsx | 6 +++++- src/hooks/home/useHomeApi.ts | 4 +++- src/types/home/alerts.ts | 1 + 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/components/home/HomeAlertsModal.tsx b/src/components/home/HomeAlertsModal.tsx index 12c35e2..d3e0ea5 100644 --- a/src/components/home/HomeAlertsModal.tsx +++ b/src/components/home/HomeAlertsModal.tsx @@ -11,6 +11,10 @@ import { import { useGuestbookList, useNotifications, useReadNotifications } from "@/hooks/home/useHomeApi"; import type { GuestbookEntry, NotificationItem } from "@/types/home/alerts"; +function isNotificationRead(item: NotificationItem) { + return item.isRead ?? item.read ?? false; +} + type AlertTab = "GUESTBOOK" | "RECORD"; export default function HomeAlertsModal({ @@ -149,7 +153,7 @@ export default function HomeAlertsModal({ {formatDateTime(item.createdAt)} {item.content} - {!item.isRead ? : null} + {!isNotificationRead(item) ? : null} )) )} diff --git a/src/hooks/home/useHomeApi.ts b/src/hooks/home/useHomeApi.ts index 5b72490..6d6386b 100644 --- a/src/hooks/home/useHomeApi.ts +++ b/src/hooks/home/useHomeApi.ts @@ -89,7 +89,9 @@ export const useReadNotifications = () => { ? { ...previous, result: previous.result.map(item => - notificationIds.includes(item.id) ? { ...item, isRead: true } : item + notificationIds.includes(item.id) + ? { ...item, isRead: true, read: true } + : item ), } : previous diff --git a/src/types/home/alerts.ts b/src/types/home/alerts.ts index 058c57f..4753515 100644 --- a/src/types/home/alerts.ts +++ b/src/types/home/alerts.ts @@ -10,6 +10,7 @@ export interface NotificationItem { url: string | null; thumbnailUrl: string | null; isRead: boolean; + read?: boolean; notificationType: string; createdAt: string; } From 9848986dc852b0f56f677c53f419e033b0668518 Mon Sep 17 00:00:00 2001 From: lejuho Date: Mon, 16 Mar 2026 02:07:49 +0900 Subject: [PATCH 76/92] =?UTF-8?q?refactor=20:=20=EC=A4=91=EA=B0=84=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MAINBE_TRACKING_REPORT_TODO.md | 238 +++++++++++++++++++++++ PROFILE_GUESTBOOK_REWORK_PLAN.md | 246 ++++++++++++++++++++++++ TRACKING_REWARD_FLOW_PLAN.md | 205 ++++++++++++++++++++ src/assets/icons/sun.svg | 2 +- src/assets/icons/water.svg | 2 +- src/components/home/HomeAvatarStage.tsx | 7 +- 6 files changed, 695 insertions(+), 5 deletions(-) create mode 100644 MAINBE_TRACKING_REPORT_TODO.md create mode 100644 PROFILE_GUESTBOOK_REWORK_PLAN.md create mode 100644 TRACKING_REWARD_FLOW_PLAN.md diff --git a/MAINBE_TRACKING_REPORT_TODO.md b/MAINBE_TRACKING_REPORT_TODO.md new file mode 100644 index 0000000..5ee6295 --- /dev/null +++ b/MAINBE_TRACKING_REPORT_TODO.md @@ -0,0 +1,238 @@ +# MainBE 2주 리포트 구현 TODO + +## 목적 + +- 홈에서 자동 노출되는 `2주 리포트 확인 모달`의 판단 기준을 MainBE에서 단일화한다. +- MainAPP은 `eligible`만 신뢰하고, 주기 계산과 확인 여부 저장은 모두 MainBE가 담당한다. + +## 완료 기준 + +- `GET /api/v1/tracking/report/status` 응답으로 홈 자동 노출 여부를 정확히 판단할 수 있어야 한다. +- `POST /api/v1/tracking/report/confirm` 호출 후 같은 `cycleKey`는 다시 노출되지 않아야 한다. +- 최근 14일 perfect day 계산 기준이 앱과 분리되고, 서버 기준으로만 동작해야 한다. + +--- + +## 1단계. 응답/요청 DTO 정의 + +### 해야 할 일 + +- 상태 조회 응답 DTO 추가 +- 확인 완료 요청 DTO 추가 + +### 권장 DTO + +#### 상태 조회 응답 + +```json +{ + "eligible": true, + "alreadyViewed": false, + "perfectDayCount": 14, + "cycleKey": "2026-03-13", + "windowStart": "2026-02-28", + "windowEnd": "2026-03-13", + "message": "2주 동안 꾸준히 돌봐주셨어요." +} +``` + +#### 확인 완료 요청 + +```json +{ + "cycleKey": "2026-03-13" +} +``` + +### 체크 포인트 + +- `eligible`는 앱 표시용 최종 boolean 이어야 한다. +- `cycleKey`는 같은 주기를 식별할 수 있는 고정 값이어야 한다. +- `message`는 기존 리포트 문구 재사용 가능하도록 열어둔다. + +--- + +## 2단계. 확인 이력 저장 모델 추가 + +### 해야 할 일 + +- `TrackingReportView` 같은 확인 이력 엔티티/테이블 추가 + +### 권장 필드 + +- `id` +- `user` +- `cycleKey` +- `viewedAt` + +### 제약 조건 + +- `user + cycleKey` unique + +### 체크 포인트 + +- 같은 사용자가 같은 주기를 중복 confirm 해도 데이터가 꼬이지 않아야 한다. +- 이후 운영 중 확인 이력 조회가 가능하도록 최소 필드는 남긴다. + +--- + +## 3단계. perfect day 계산 로직 분리 + +### 해야 할 일 + +- 최근 14일 기준 perfect day 계산 메서드 추가 +- 현재 주기의 `windowStart`, `windowEnd`, `cycleKey` 계산 로직 추가 + +### perfect day 기준 + +- 해당 날짜에 `물 주기`와 `햇빛 주기`를 모두 완료한 날 + +### 체크 포인트 + +- 앱에서 계산하지 않고 서버에서만 계산해야 한다. +- 최근 14일 윈도우 기준이 고정되어야 한다. +- `cycleKey`는 이 14일 윈도우를 안정적으로 식별할 수 있어야 한다. + +--- + +## 4단계. 상태 조회 API 추가 + +### 엔드포인트 + +- `GET /api/v1/tracking/report/status` + +### 해야 할 일 + +- 최근 14일 perfect day 수 계산 +- 현재 주기 식별 +- 해당 주기 confirm 여부 조회 +- `eligible` 계산 + +### 권장 계산식 + +```text +eligible = perfectDayCount >= 14 && alreadyViewed == false +``` + +### 체크 포인트 + +- MainAPP은 이 값만 보고 모달을 띄우므로, 여기서 최종 판단이 끝나야 한다. +- 홈 재진입 시에도 결과가 일관되어야 한다. + +--- + +## 5단계. 확인 완료 API 추가 + +### 엔드포인트 + +- `POST /api/v1/tracking/report/confirm` + +### 해야 할 일 + +- 요청으로 받은 `cycleKey` 검증 +- 현재 사용자 기준 확인 이력 저장 +- 이미 존재하면 중복 저장 없이 성공 처리하거나 안전하게 예외 처리 + +### 체크 포인트 + +- 앱에서 닫기/CTA 둘 다 이 API를 호출하므로 idempotent 하게 만드는 편이 안전하다. +- 다른 주기의 `cycleKey`를 잘못 넣었을 때 처리 정책을 정해야 한다. + +--- + +## 6단계. 기존 activity 기록 로직과 연결 확인 + +### 해야 할 일 + +- 현재 물/햇빛 기록 로직은 유지 +- 상태 조회 시점에만 perfect day 조건이 반영되도록 연결 확인 + +### 체크 포인트 + +- 실시간 push 없이도 홈에서 상태 조회만 하면 즉시 반영되어야 한다. +- 14번째 perfect day가 완성된 당일, 다음 상태 조회에서 `eligible=true`가 나와야 한다. + +--- + +## 7단계. 서비스 계층 구조 정리 + +### 권장 분리 + +- `TrackingReportService` +- `TrackingReportQueryService` 또는 기존 서비스 내부 메서드 분리 + +### 포함되면 좋은 메서드 + +- `getTrackingPromptStatus(userId)` +- `confirmTrackingPrompt(userId, cycleKey)` +- `calculatePerfectDayCount(userId, windowStart, windowEnd)` +- `resolveCycleKey(windowStart, windowEnd)` + +### 체크 포인트 + +- 컨트롤러에서 계산 로직이 직접 섞이지 않게 한다. +- 테스트 가능한 단위로 메서드를 나눈다. + +--- + +## 8단계. 예외 처리 정책 정리 + +### 확인할 항목 + +- 잘못된 `cycleKey` 요청 +- 인증되지 않은 사용자 요청 +- 중복 confirm 요청 +- activity 데이터가 일부 비정상인 사용자 + +### 권장 방향 + +- 중복 confirm 은 성공 처리 +- 잘못된 요청만 명확히 4xx 처리 + +--- + +## 9단계. 테스트 코드 작성 + +### 최소 테스트 케이스 + +- 14일 미만이면 `eligible=false` +- 14일 달성 직후 `eligible=true` +- 같은 `cycleKey` confirm 후 `eligible=false` +- 다음 주기 달성 시 새 `cycleKey`로 다시 `eligible=true` +- 중복 confirm 요청 시 안전하게 처리 + +### 추가 테스트 케이스 + +- 최근 14일 경계 날짜 포함 여부 +- 당일 물만 완료 / 햇빛만 완료인 경우 perfect day 제외 + +--- + +## 10단계. MainAPP 연동 확인 포인트 + +### MainBE 완료 후 확인할 것 + +- 홈 진입 시 `status` 응답 정상 +- 물/햇빛 완료 후 홈 복귀 시 `eligible` 갱신 정상 +- 모달 확인 후 같은 주기 재노출 없음 +- 다음 주기에서 다시 노출됨 + +--- + +## 구현 순서 요약 + +1. DTO 추가 +2. 확인 이력 엔티티/테이블 추가 +3. perfect day 및 cycleKey 계산 로직 구현 +4. `GET /tracking/report/status` 추가 +5. `POST /tracking/report/confirm` 추가 +6. 서비스 분리 및 예외 처리 정리 +7. 테스트 코드 작성 +8. MainAPP 연동 QA + +--- + +## 메모 + +- MainAPP 쪽은 이미 `status` 조회와 `confirm` 호출 기준으로 연결되어 있다. +- MainBE는 반드시 앱 계산이 아닌 서버 계산 기준으로 `eligible`을 내려줘야 한다. diff --git a/PROFILE_GUESTBOOK_REWORK_PLAN.md b/PROFILE_GUESTBOOK_REWORK_PLAN.md new file mode 100644 index 0000000..8c695fe --- /dev/null +++ b/PROFILE_GUESTBOOK_REWORK_PLAN.md @@ -0,0 +1,246 @@ +# 타인 프로필 / 방명록 재구성 계획 + +## 목표 + +타인 프로필 화면을 현재의 "대표 정원 1개 + 카드형 상세" 구조에서 벗어나, +홈 화면과 유사한 정원 중심 화면으로 재구성한다. + +핵심 UX 목표는 아래와 같다. + +1. 타인 프로필도 정원 중심의 전체 화면 레이아웃을 사용한다. +2. 정원은 홈처럼 좌우 스와이프가 가능하다. +3. 단, 타인 프로필은 해금된 정원 개수만큼만 스와이프 가능하다. +4. 상단에는 뒤로가기, 정원/식물 이름, 친구 추가/언팔로우 버튼이 함께 보여야 한다. +5. 우측 액션 레일에는 홈처럼 물주기 아이콘이 떠야 한다. +6. 남은 친구 물주기 횟수도 함께 보여야 한다. +7. 하단에는 방명록 진입 버튼이 있어야 한다. +8. 방명록 버튼을 누르면 별도 전체 화면의 방명록 페이지로 이동해야 한다. +9. 방명록 페이지에서는 기존 방명록 목록이 위에서부터 스크롤되고, + 하단 고정 입력창으로 새 방명록을 작성할 수 있어야 한다. +10. 받은 유저는 홈의 비둘기 알림에서 방명록 목록을 확인할 수 있어야 한다. + +## 현재 상태와 의도 불일치 + +현재 프로필 구현은 아래와 같은 한계가 있다. + +1. `ProfileScreen`은 `data.userGardens[0]`만 사용한다. + 즉, 다중 정원 / 스와이프 UX가 전혀 없다. +2. `ProfileDetail`은 카드형 상세 구조라 홈 화면의 몰입형 정원 화면과 다르다. +3. 현재 프로필 타입의 `GardenInfo`에는 `gardenImageUrl`, `gardenSlotNumber`, `isLocked` 같은 정보가 없다. + 따라서 홈 화면의 정원 배경/슬롯 로직을 그대로 재사용할 수 없다. +4. 방명록은 홈의 `HomeAlertsModal`에서 읽기만 가능하고, + 별도 전체 화면 작성 플로우가 없다. +5. 프로필에서 방명록 버튼을 눌렀을 때 이동할 라우트/페이지가 아직 없다. + +## 데이터 전제 + +현재 백엔드 기준으로 프로필 API는 아래 데이터만 확실하다. + +- `GetUserProfileResponse` + - `id` + - `userNickname` + - `profileImageUrl` + - `followStatus` + - `leftWaterCountForOthers` + - `userGardens` +- `GardenInfo` + - `gardenId` + - `avatarInfo` + - `isWateringAbleByMe` + +현재 스펙 기준으로는 아래 사항을 가정해야 한다. + +1. `userGardens`는 "해금된 정원만" 내려온다. +2. 타인 프로필은 `userGardens.length`만큼만 페이지를 만들면 된다. +3. 정원 배경 이미지가 없다면 홈 배경의 fallback 이미지를 사용한다. +4. 물주기 카운트 표기는 당장은 `leftWaterCountForOthers`만 노출한다. + `1/5` 같은 최대치 표기는 API가 보장하지 않으므로 하드코딩을 피한다. + +추후 백엔드가 아래 필드를 내려주면 더 정확하게 확장 가능하다. + +- `gardenSlotNumber` +- `gardenImageUrl` +- `isLocked` +- `maxWaterCountForOthers` + +## 목표 화면 구조 + +### 1. 타인 프로필 화면 + +`ProfileScreen`을 홈과 유사한 구조로 재편한다. + +- 최상위는 전체 화면 배경형 레이아웃 +- 내부에 `PagerView` 사용 +- `userGardens.length`만큼만 페이지 생성 +- 각 페이지는 `ProfileGardenScene` 컴포넌트로 렌더링 + +페이지마다 보여야 하는 요소: + +- 상단 + - 뒤로가기 + - 현재 정원의 식물 이름 또는 기본 이름 + - 친구 추가 / 맞팔로우 / 언팔로우 +- 우측 상단 + - 남은 친구 물주기 횟수 +- 중앙 + - 정원/아바타 비주얼 +- 우측 하단 + - 물주기 아이콘 버튼 +- 하단 + - 방명록 진입 버튼 + +### 2. 방명록 전체 화면 + +새 `GuestbookScreen`을 추가한다. + +- 전체 화면 페이지 +- 상단 헤더 +- 방명록 목록 `FlatList` +- 하단 고정 입력창 +- 댓글 UX처럼 입력창은 목록과 분리된 하단 고정 구조 + +화면 진입 경로는 두 가지다. + +1. 타인 프로필 하단 `방명록 작성` +2. 내 홈 비둘기 흐름에서 방명록 목록 보기 + +## 구현 방향 + +### A. 프로필 화면 재구성 + +새 구조 제안: + +- `ProfileScreen` + - 데이터 로딩 + - `followAction` 계산 + - `PagerView` 페이지 관리 + - 방명록 화면 이동 +- `ProfileGardenScene` + - 홈의 `HomeGardenScene` 스타일을 참고한 정원 중심 씬 + - 물주기 버튼 포함 + - 방명록 버튼 포함 + +`ProfileDetail`은 아래 둘 중 하나로 정리한다. + +1. 제거하고 `ProfileGardenScene`으로 대체 +2. 이름을 `ProfileGardenScene`으로 바꾸고 홈형 UI로 전환 + +권장: + +- 기존 `ProfileDetail`을 억지로 확장하지 말고, + `ProfileGardenScene`을 새 컴포넌트로 분리하는 편이 구조가 깔끔하다. + +### B. 방명록 페이지 추가 + +새 파일 후보: + +- `src/pages/profile/GuestbookScreen.tsx` +- `src/components/profile/GuestbookListItem.tsx` +- `src/apis/profile/guestbookApi.ts` +- `src/hooks/profile/useGuestbookApi.ts` +- `src/types/profile/guestbookApi.type.ts` + +필요 API: + +- GET `/api/v1/users/guestbook/{userId}/list` +- POST `/api/v1/users/{userId}/guestbook` + +### C. 홈 비둘기와의 관계 + +기존 `HomeAlertsModal`은 당장 제거하지 않는다. + +단계별 정리 방향: + +1. 우선 `GuestbookScreen`을 새로 만든다. +2. 타인 프로필에서 방명록 버튼으로 `GuestbookScreen` 진입을 붙인다. +3. 이후 홈 비둘기에서 방명록 탭을 눌렀을 때도 + 필요하면 `GuestbookScreen(myUserId)`로 연결할 수 있게 확장한다. + +## 작업 단위 + +### 1단계. 문서화 + +- 이 문서 추가 + +커밋 메시지: + +- `chore: 타인 프로필과 방명록 재구성 계획 문서 추가` + +### 2단계. 프로필 라우트/타입 기반 정리 + +- `ProfileScreen`이 다중 정원 배열을 사용할 수 있게 구조 변경 +- 현재 타입 기준으로 해금된 정원 수만큼 페이저 페이지 생성 +- `ProfileGardenScene` 뼈대 추가 + +커밋 메시지: + +- `refactor: 타인 프로필을 정원 페이저 구조로 재구성` + +### 3단계. 프로필 씬 홈 스타일 적용 + +- 홈과 유사한 배경형 정원 씬 적용 +- 상단 헤더 / 팔로우 버튼 / 물주기 카운트 / 액션 레일 / 방명록 버튼 반영 +- 물주기 버튼은 기존 `useFriendWater`와 연결 + +커밋 메시지: + +- `feat: 타인 프로필 정원 씬과 물주기 UI 적용` + +### 4단계. 방명록 API / 타입 / 훅 추가 + +- 방명록 목록 조회 API +- 방명록 작성 API +- react-query 훅 추가 + +커밋 메시지: + +- `feat: 방명록 조회와 작성 API 훅 추가` + +### 5단계. 방명록 전체 화면 추가 + +- `GuestbookScreen` 라우트 추가 +- 목록 스크롤 + 하단 고정 입력창 구현 +- 빈 상태 문구 처리 + +커밋 메시지: + +- `feat: 방명록 전체 화면과 입력 UX 구현` + +### 6단계. 프로필 방명록 버튼 연결 + +- 타인 프로필의 `방명록 작성` 버튼을 `GuestbookScreen(userId)`로 연결 + +커밋 메시지: + +- `feat: 타인 프로필 방명록 진입 연결` + +### 7단계. 홈 비둘기와 방명록 흐름 정리 + +- `HomeAlertsModal`에서 방명록 진입 전략 결정 +- 필요 시 내 방명록 전체 보기로 연결 + +커밋 메시지: + +- `refactor: 홈 비둘기와 방명록 조회 흐름 정리` + +## 구현 시 주의점 + +1. 타인 프로필은 홈과 비슷해도 완전히 같은 규칙을 쓰면 안 된다. + 홈은 4슬롯 고정, 타인 프로필은 해금된 정원 수만큼만 페이지 생성해야 한다. +2. 현재 프로필 API엔 정원 배경 정보가 없으므로 fallback 배경 전략이 필요하다. +3. 방명록 입력창은 댓글 시트처럼 "하단 고정"이 핵심이다. +4. 방명록 버튼은 동작 없는 더미 상태로 두지 않는다. +5. 비둘기 모달과 새 방명록 페이지가 역할 충돌하지 않도록, + 모달은 요약/알림, 화면은 읽기+작성 전체 흐름으로 분리한다. + +## 최종 기대 결과 + +구현 완료 후에는 아래가 성립해야 한다. + +1. 타인 프로필에 들어가면 홈과 유사한 정원 중심 화면이 보인다. +2. 해금된 정원 수만큼만 좌우 스와이프가 된다. +3. 친구 추가 / 맞팔 / 언팔로우 버튼이 상단에서 동작한다. +4. 우측 액션 레일의 물주기 버튼으로 실제 친구 물주기가 가능하다. +5. 하단 `방명록 작성` 버튼을 누르면 별도 전체 화면의 방명록 페이지로 이동한다. +6. 방명록 페이지에서 기존 글을 스크롤로 보고, 하단 입력창으로 새 글을 남길 수 있다. +7. 받은 유저는 홈 비둘기 알림에서도 방명록 흐름을 확인할 수 있다. diff --git a/TRACKING_REWARD_FLOW_PLAN.md b/TRACKING_REWARD_FLOW_PLAN.md new file mode 100644 index 0000000..826ecee --- /dev/null +++ b/TRACKING_REWARD_FLOW_PLAN.md @@ -0,0 +1,205 @@ +# 2주 리포트 상태 저장 및 확인 모달 계획 + +## 목표 + +- 비둘기 클릭 기본 동선은 `알림 모달(방명록/기록)`로 유지한다. +- `2주 리포트 확인 모달`은 비둘기 클릭과 분리된 별도 흐름으로 처리한다. +- 앱은 백엔드의 `perfectDay` 조건을 그대로 따른다. +- 모달은 `최근 14일 perfect day 충족` 상태가 된 직후 한 번만 뜬다. +- 사용자가 이미 확인한 같은 주기의 모달은 다시 뜨지 않는다. + +## 기준 해석 + +- `perfect day`: + - 해당 날짜에 `물 주기`와 `햇빛 주기`를 모두 완료한 날 +- `2주 리포트 대상 주기`: + - 백엔드가 계산하는 최근 14일 윈도우 기준 +- `모달 노출 시점`: + - 앱 임의 계산이 아니라 백엔드가 `이번 주기 리포트를 지금 띄워도 되는지`를 판단한 뒤 내려준다. + - 실질적으로는 `14번째 perfect day가 완성된 뒤`, 즉 당일 물/햇빛 둘 다 완료되어 조건을 만족한 직후가 된다. + +## 권장 동작 + +1. 사용자가 당일 물 또는 햇빛 중 하나를 수행한다. +2. 백엔드는 daily activity를 갱신한다. +3. 백엔드는 해당 시점에 `최근 14일 perfectDayCount`, `이번 주기 식별자`, `이미 확인했는지`를 계산한다. +4. 조건을 만족하면 앱은 홈 진입 시점 또는 홈 복귀 시점에 `2주 리포트 확인 모달`을 자동 노출한다. +5. 사용자가 모달을 닫거나 CTA를 누르면 백엔드에 `이번 주기 확인 완료`를 저장한다. +6. 같은 주기 동안은 다시 노출하지 않는다. + +## MainBE 단계별 계획 + +### 1단계: 주기 상태 응답 정의 + +- 새 응답 DTO 추가 + - 예시: `TrackingPromptStatusResponse` +- 포함 필드 + - `eligible`: 지금 모달 노출 대상인지 + - `perfectDayCount`: 최근 14일 perfect day 수 + - `windowStart` + - `windowEnd` + - `cycleKey`: 이번 2주 주기를 식별하는 값 + - `alreadyViewed`: 이번 주기를 이미 확인했는지 + - `message`: 기존 리포트 문구 재사용 가능 + +### 2단계: 확인 이력 저장 모델 추가 + +- 새 엔티티 추가 권장 + - 예시: `TrackingReportView` +- 필드 예시 + - `id` + - `user` + - `cycleKey` + - `viewedAt` +- 제약 조건 + - `user + cycleKey` unique + +### 3단계: 상태 조회 API 추가 + +- 예시 + - `GET /api/v1/tracking/report/status` +- 역할 + - 최근 14일 perfect day 계산 + - 현재 주기 식별 + - 이번 주기 확인 여부 확인 + - `eligible = perfectDayCount >= 14 && alreadyViewed == false` + +### 4단계: 확인 완료 API 추가 + +- 예시 + - `POST /api/v1/tracking/report/confirm` +- 요청값 + - `cycleKey` +- 역할 + - 사용자가 이번 주기 리포트를 확인했다는 상태 저장 + +### 5단계: 기존 activity 기록 로직과 연결 + +- 현재 `GardenService`의 일일 활동 기록 로직은 유지 +- 별도 복잡한 실시간 push 없이도 충분 +- 핵심은 홈에서 상태 조회 시 `eligible`을 정확히 계산하는 것 + +### 6단계: 판단 기준 단일화 + +- 앱은 `praiseDayCount >= 14`만 보고 띄우지 않는다. +- 백엔드 `eligible`만 신뢰한다. +- 이렇게 해야 다음 문제를 막을 수 있다. + - 같은 주기 재노출 + - 홈 재진입 때 중복 노출 + - 클라이언트와 서버 계산 불일치 + +## MainAPP 단계별 계획 + +### 1단계: 비둘기 동선 유지 + +- 현재 비둘기 클릭: + - `알림 모달(방명록/기록)` +- 유지 +- 2주 리포트 모달은 비둘기 클릭에서 열지 않는다. + +### 2단계: 홈 진입 시 상태 조회 + +- 홈 API와 별도 query 또는 home-summary 확장 중 하나 선택 +- 권장 + - 별도 query: `useTrackingPromptStatus` +- 조회 시점 + - 홈 첫 진입 + - 물/햇빛 액션 성공 후 invalidate + - 홈 화면 복귀 시 refetch + +### 3단계: 자동 노출 조건 + +- 앱 조건 + - `visibleCandidate = status.eligible === true` +- 자동 노출 위치 + - `HomeScreen` +- 추가 가드 + - 같은 앱 세션에서 이미 연 경우 local state로 중복 open 방지 + +### 4단계: 확인 모달 컴포넌트 연결 + +- 기존 `HomeTrackingModal` 재사용 또는 분리 +- 권장 + - 현재 `HomeTrackingModal`을 `2주 리포트 확인 모달` 전용으로 유지 +- 표시 내용 + - `perfectDayCount` + - 백엔드 `message` + - 확인 CTA + +### 5단계: 확인 완료 처리 + +- 사용자가 모달 닫기 또는 CTA 누를 때 + - `POST /api/v1/tracking/report/confirm` +- 성공 후 + - status query invalidate + - 모달 닫기 + +### 6단계: 물/햇빛 액션과의 연결 + +- 현재 `postGardenSunlight`, `postGardenMyWater` 성공 시 홈 query만 invalidate 중 +- 이후 추가 + - `tracking-report-status` invalidate +- 이유 + - 2주째 되는 날 당일 두 액션을 모두 완료한 직후, + 홈에 돌아왔을 때 곧바로 모달 노출 가능해야 함 + +## 추천 API 계약 + +### 상태 조회 응답 예시 + +```json +{ + "isSuccess": true, + "code": "COMMON200", + "message": "성공입니다.", + "result": { + "eligible": true, + "alreadyViewed": false, + "perfectDayCount": 14, + "cycleKey": "2026-03-13", + "windowStart": "2026-02-28", + "windowEnd": "2026-03-13", + "message": "2주 동안 꾸준히 돌봐주셨어요." + } +} +``` + +### 확인 완료 요청 예시 + +```json +{ + "cycleKey": "2026-03-13" +} +``` + +## UX 기준 + +- 비둘기: + - 항상 알림 모달 +- 2주 리포트: + - 조건 충족 직후 홈에서 자동 팝업 +- 이미 본 같은 주기 리포트: + - 다시 자동 팝업 금지 +- 다음 주기: + - 새 `cycleKey`에서 다시 가능 + +## 구현 순서 + +1. MainBE + - 상태 조회 DTO/API 추가 + - 확인 이력 저장 테이블/엔티티 추가 + - 확인 완료 API 추가 +2. MainAPP + - 상태 query 추가 + - 홈 자동 노출 로직 추가 + - 확인 완료 mutation 추가 + - 물/햇빛 성공 후 상태 query invalidate 추가 +3. QA + - 14일 미만: 모달 미노출 + - 14일 달성 직후: 1회 노출 + - 확인 후 홈 재진입: 재노출 없음 + - 다음 주기 달성: 다시 노출 + +## 메모 + +- 다음 커밋에서는 현재 워킹트리에 남아 있는 `src/assets/icons/sun.svg`, `src/assets/icons/water.svg`도 함께 정리해서 포함한다. diff --git a/src/assets/icons/sun.svg b/src/assets/icons/sun.svg index 9b9e46f..633e77b 100644 --- a/src/assets/icons/sun.svg +++ b/src/assets/icons/sun.svg @@ -1,6 +1,6 @@ - + diff --git a/src/assets/icons/water.svg b/src/assets/icons/water.svg index a000625..a41f505 100644 --- a/src/assets/icons/water.svg +++ b/src/assets/icons/water.svg @@ -1,6 +1,6 @@ - + diff --git a/src/components/home/HomeAvatarStage.tsx b/src/components/home/HomeAvatarStage.tsx index 76f82d6..13760da 100644 --- a/src/components/home/HomeAvatarStage.tsx +++ b/src/components/home/HomeAvatarStage.tsx @@ -1,7 +1,8 @@ -import { useEffect, useState } from "react"; import { Image, Pressable, StyleSheet, Text, TouchableOpacity, View } from "react-native"; -import type { SurveyAnswerKind } from "@/types/missions"; +import { useEffect, useState } from "react"; + import { ANSWER_COPY } from "@/components/home/HomeEmotionModal"; +import type { SurveyAnswerKind } from "@/types/missions"; const wateringImage = require("@/assets/images/background/watering.png"); const birdImage = require("@/assets/images/bird.webp"); @@ -123,7 +124,7 @@ const styles = StyleSheet.create({ * 화분 밑단을 더 아래로 내리기 위해 하단 여백을 줄였다. * 주변 오브젝트도 같은 기준선에서 함께 내려오도록 절대 위치 값도 맞춘다. */ - marginBottom: 8, + marginBottom: -96, }, wateringImage: { position: "absolute", From 7c5fc7e537e5438b554672fdcbb4611bfdefa963 Mon Sep 17 00:00:00 2001 From: lejuho Date: Mon, 16 Mar 2026 02:12:28 +0900 Subject: [PATCH 77/92] =?UTF-8?q?chore:=20=EC=84=B1=EB=8A=A5=20=EC=A0=90?= =?UTF-8?q?=EA=B2=80=20=EA=B3=84=ED=9A=8D=20=EB=AC=B8=EC=84=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PERFORMANCE_DIAGNOSIS_PLAN.md | 199 ++++++++++++++++++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 PERFORMANCE_DIAGNOSIS_PLAN.md diff --git a/PERFORMANCE_DIAGNOSIS_PLAN.md b/PERFORMANCE_DIAGNOSIS_PLAN.md new file mode 100644 index 0000000..94b53fd --- /dev/null +++ b/PERFORMANCE_DIAGNOSIS_PLAN.md @@ -0,0 +1,199 @@ +# 성능 점검 계획 + +## 결론 + +현재 체감되는 "전체적으로 조금 느림"은 `CDN 하나로 해결될 가능성`보다 +`API 호출 수`, `불필요한 refetch`, `이미지 로딩`, `Railway ↔ Supabase 응답 시간` 문제일 가능성이 더 높다. + +즉 우선순위는 다음과 같다. + +1. 어떤 화면에서 느린지 계측 +2. 어떤 API가 느린지 확인 +3. 프론트의 중복 refetch / invalidate 정리 +4. 이미지 최적화 +5. 마지막으로 CDN 검토 + +## CDN이 직접 해결하는 영역 + +CDN이 효과적인 경우: + +- 큰 이미지 +- 썸네일 +- 배경 이미지 +- 정적 에셋 + +CDN만으로 잘 안 풀리는 경우: + +- 홈 진입 시 API 여러 개 동시 호출 +- Railway 서버 응답 지연 +- Supabase 쿼리 지연 +- 화면 전환 때 과한 refetch +- 모달/상세 진입마다 같은 데이터를 다시 읽는 구조 + +## 현재 구조에서 우선 의심할 부분 + +### 1. 홈 화면 + +홈은 진입/복귀 시 여러 쿼리가 겹칠 가능성이 있다. + +- `home-summary` +- `home-panel` +- `tracking-report-status` +- 알림/방명록 모달 진입 시 추가 조회 + +특히 `invalidateQueries`가 많은 구조라 +작은 액션 뒤에도 홈 관련 API가 연쇄적으로 다시 호출될 수 있다. + +### 2. 피드 상세 / 무한 스크롤 + +피드 상세는 선택 포스트 + 랜덤 세션 + 댓글/공감 갱신이 섞여 있어서 +한 번의 진입에서 네트워크 왕복이 누적될 수 있다. + +### 3. 타인 프로필 + +타인 프로필은 다음 요소가 겹친다. + +- 프로필 조회 +- 친구 물주기 +- 방명록 화면 진입 +- 방명록 작성 후 invalidate + +즉 프로필 화면이 단순 조회처럼 보여도 +실제론 상호작용 이후 재조회 비용이 있다. + +### 4. 이미지 로딩 + +배경 / 식물 / 프로필 / 피드 이미지가 최적화되지 않은 원본이면 +네트워크보다 렌더 체감이 더 느릴 수 있다. + +특히 다음을 의심한다. + +- 원본 해상도 이미지 직접 사용 +- 썸네일 URL 부재 +- 캐시 정책 불명확 + +## 먼저 확인할 화면 + +다음 4개 화면을 우선 계측한다. + +1. 홈 첫 진입 +2. 피드 상세 진입 +3. 타인 프로필 진입 +4. 비둘기 모달 / 방명록 모달 열기 + +각 화면에서 확인할 값: + +- 첫 화면 표시까지 걸린 시간 +- API 응답 시간 +- 이미지가 다 보일 때까지 걸린 시간 +- 같은 API가 중복 호출되는지 여부 + +## 프론트 점검 항목 + +### 1. 중복 refetch + +다음을 우선 확인한다. + +- `useFocusEffect`에서 매번 refetch하는 쿼리 +- 액션 성공 후 `invalidateQueries`를 여러 번 호출하는 구조 +- 이미 최신 캐시가 있는데도 상세 진입 시 다시 읽는 구조 + +### 2. 낙관적 업데이트 가능한 부분 + +다음은 서버 재조회 대신 로컬 반영이 가능한 후보다. + +- 알림 읽음 처리 +- 좋아요 토글 +- 댓글 수 증가 +- 친구 물주기 후 버튼 상태 + +### 3. 이미지 표시 최적화 + +확인 포인트: + +- 큰 원본 이미지를 그대로 쓰는지 +- 썸네일과 상세 이미지를 분리할 수 있는지 +- 리스트에서는 작은 이미지, 상세에서 큰 이미지를 쓰는지 + +## 백엔드 점검 항목 + +### 1. 느린 API 찾기 + +우선 로그로 응답 시간이 느린 API를 찾는다. + +- `/api/v1/home` +- `/api/v1/home/panel` +- `/api/v1/notifications` +- `/api/v1/users/{id}` +- 피드 상세 관련 API + +### 2. Supabase 쿼리 비용 + +확인 포인트: + +- N+1 조회 +- 정렬 + 조인 + 카운트가 한 번에 많은 API +- 인덱스 없는 조건 검색 + +### 3. Railway 환경 + +확인 포인트: + +- cold start 체감 여부 +- 연결 풀 초기화 시간 +- 외부 스토리지/DB 왕복 시간 + +## 추천 계측 방법 + +### 프론트 + +- 화면 진입 시점 로그 +- API 요청 시작/종료 시간 로그 +- 이미지 onLoad 완료 시간 로그 + +### 백엔드 + +- 주요 API의 시작/종료 시간 로그 +- 느린 쿼리 로그 +- 필요한 경우 endpoint 별 응답 시간 측정 + +## 개선 우선순위 + +### 1차 + +- 과한 refetch / invalidate 줄이기 +- 알림/좋아요/물주기 같은 짧은 액션은 로컬 상태 우선 반영 +- 홈/피드/프로필 진입 시 중복 호출 제거 + +### 2차 + +- 이미지 최적화 +- 썸네일 도입 +- 캐시 전략 정리 + +### 3차 + +- 백엔드 느린 쿼리 최적화 +- 인덱스 / fetch 전략 조정 + +### 4차 + +- CDN 적용 +- 이미지/정적 에셋 위주로 우선 적용 + +## 실무 판단 + +현재는 `CDN부터 붙이는 단계`가 아니라 +`어디가 느린지 계측해서 병목을 찾는 단계`다. + +가장 먼저 할 일은 다음 둘이다. + +1. 홈 / 피드 / 프로필 / 알림 모달의 실제 체감 지연 구간을 로그로 잡기 +2. 각 구간에서 API와 이미지 중 무엇이 병목인지 분리하기 + +이후 결과에 따라 + +- API 병목이면 쿼리/호출 수 최적화 +- 이미지 병목이면 CDN + 썸네일 + +순서로 들어가는 것이 맞다. From d0c790b4cfa03d84e2cd25fa0e53e9e6c1ffd6f9 Mon Sep 17 00:00:00 2001 From: lejuho Date: Mon, 16 Mar 2026 02:24:12 +0900 Subject: [PATCH 78/92] =?UTF-8?q?chore:=20=ED=99=94=EB=A9=B4=20=EB=A1=9C?= =?UTF-8?q?=EB=94=A9=20=ED=83=80=EC=9D=B4=EB=B0=8D=20=EB=A1=9C=EA=B7=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/home/HomeAlertsModal.tsx | 30 +++++++++++++++++++++++-- src/pages/feed/FeedAvatarScreen.tsx | 17 +++++++++++++- src/pages/feed/FeedDiaryScreen.tsx | 17 +++++++++++++- src/pages/home/HomeScreen.tsx | 16 ++++++++++++- src/pages/profile/ProfileScreen.tsx | 17 +++++++++++++- src/utils/debug.ts | 12 ++++++++++ 6 files changed, 103 insertions(+), 6 deletions(-) diff --git a/src/components/home/HomeAlertsModal.tsx b/src/components/home/HomeAlertsModal.tsx index d3e0ea5..e1e09a9 100644 --- a/src/components/home/HomeAlertsModal.tsx +++ b/src/components/home/HomeAlertsModal.tsx @@ -1,4 +1,4 @@ -import { useEffect, useMemo, useState } from "react"; +import { useEffect, useMemo, useRef, useState } from "react"; import { Modal, Pressable, @@ -10,6 +10,7 @@ import { } from "react-native"; import { useGuestbookList, useNotifications, useReadNotifications } from "@/hooks/home/useHomeApi"; import type { GuestbookEntry, NotificationItem } from "@/types/home/alerts"; +import { createTimingLogger } from "@/utils/debug"; function isNotificationRead(item: NotificationItem) { return item.isRead ?? item.read ?? false; @@ -28,6 +29,7 @@ export default function HomeAlertsModal({ }) { const [activeTab, setActiveTab] = useState("GUESTBOOK"); const [hasMarkedRecordAsReadThisOpen, setHasMarkedRecordAsReadThisOpen] = useState(false); + const openTimingRef = useRef | null>(null); const notificationsQuery = useNotifications(visible); const guestbookQuery = useGuestbookList(userId, visible); const readNotificationsMutation = useReadNotifications(); @@ -59,6 +61,7 @@ export default function HomeAlertsModal({ useEffect(() => { if (!visible) { setHasMarkedRecordAsReadThisOpen(false); + openTimingRef.current = null; return; } @@ -71,7 +74,7 @@ export default function HomeAlertsModal({ } const unreadNotificationIds = notificationsQuery.data - .filter(item => !item.isRead) + .filter(item => !isNotificationRead(item)) .map(item => item.id); setHasMarkedRecordAsReadThisOpen(true); @@ -90,6 +93,29 @@ export default function HomeAlertsModal({ visible, ]); + useEffect(() => { + if (!visible) { + return; + } + + openTimingRef.current = createTimingLogger("HomeAlertsModal", "modal open", { + activeTab, + }); + }, [activeTab, visible]); + + useEffect(() => { + if (!visible || !openTimingRef.current || activeState.isLoading) { + return; + } + + openTimingRef.current({ + activeTab, + itemCount: activeState.items.length, + isError: activeState.isError, + }); + openTimingRef.current = null; + }, [activeState.isError, activeState.isLoading, activeState.items.length, activeTab, visible]); + return ( diff --git a/src/pages/feed/FeedAvatarScreen.tsx b/src/pages/feed/FeedAvatarScreen.tsx index 6d4d927..24990df 100644 --- a/src/pages/feed/FeedAvatarScreen.tsx +++ b/src/pages/feed/FeedAvatarScreen.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { ActivityIndicator, FlatList, @@ -18,6 +18,7 @@ import { useAvatarPostDetail } from "@/hooks/feed/useAvatarPostDetailApi"; import { useRandomFeedSession } from "@/hooks/feed/useRandomFeedSession"; import type { FeedDetailResult } from "@/types/feed/detail"; import type { RandomFeedPostType } from "@/types/feed/randomFeedApi.type"; +import { createTimingLogger } from "@/utils/debug"; type Props = RootStackScreenProps<"FeedAvatar">; @@ -35,6 +36,7 @@ export default function FeedAvatarScreen({ navigation, route }: Props) { const isValidId = Number.isFinite(id) && id > 0; const { data, error, isLoading, refetch } = useAvatarPostDetail(isValidId ? id : 0); const [content, setContent] = useState(""); + const initialLoadTimingRef = useRef | null>(null); const { mutateAsync, isPending } = usePostComment(() => refetch()); const { data: randomSession, @@ -49,6 +51,19 @@ export default function FeedAvatarScreen({ navigation, route }: Props) { size: 6, }); + useEffect(() => { + initialLoadTimingRef.current = createTimingLogger("FeedAvatarScreen", "initial detail load", { postId: id }); + }, [id]); + + useEffect(() => { + if (!data || !initialLoadTimingRef.current) { + return; + } + + initialLoadTimingRef.current({ hasRandomSession: Boolean(randomSession) }); + initialLoadTimingRef.current = null; + }, [data, randomSession]); + const handleBackClick = () => { if (navigation.canGoBack()) { navigation.goBack(); diff --git a/src/pages/feed/FeedDiaryScreen.tsx b/src/pages/feed/FeedDiaryScreen.tsx index b457b83..e2cf15b 100644 --- a/src/pages/feed/FeedDiaryScreen.tsx +++ b/src/pages/feed/FeedDiaryScreen.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { ActivityIndicator, FlatList, @@ -18,6 +18,7 @@ import { useRandomFeedSession } from "@/hooks/feed/useRandomFeedSession"; import { useDiaryDetail } from "@/hooks/log/useDiaryDetailApi"; import type { FeedDetailResult } from "@/types/feed/detail"; import type { RandomFeedPostType } from "@/types/feed/randomFeedApi.type"; +import { createTimingLogger } from "@/utils/debug"; type Props = RootStackScreenProps<"FeedDiary">; @@ -35,6 +36,7 @@ export default function FeedDiaryScreen({ navigation, route }: Props) { const isValidId = Number.isFinite(id) && id > 0; const { data, error, isLoading, refetch } = useDiaryDetail(isValidId ? id : 0); const [content, setContent] = useState(""); + const initialLoadTimingRef = useRef | null>(null); const { mutateAsync, isPending } = usePostComment(() => refetch()); const { data: randomSession, @@ -49,6 +51,19 @@ export default function FeedDiaryScreen({ navigation, route }: Props) { size: 6, }); + useEffect(() => { + initialLoadTimingRef.current = createTimingLogger("FeedDiaryScreen", "initial detail load", { postId: id }); + }, [id]); + + useEffect(() => { + if (!data || !initialLoadTimingRef.current) { + return; + } + + initialLoadTimingRef.current({ hasRandomSession: Boolean(randomSession) }); + initialLoadTimingRef.current = null; + }, [data, randomSession]); + const handleBackClick = () => { if (navigation.canGoBack()) { navigation.goBack(); diff --git a/src/pages/home/HomeScreen.tsx b/src/pages/home/HomeScreen.tsx index b702dbf..2bfcc34 100644 --- a/src/pages/home/HomeScreen.tsx +++ b/src/pages/home/HomeScreen.tsx @@ -30,7 +30,7 @@ import { type TodayMission, } from "@/types/home/garden"; import type { SurveyAnswerKind } from "@/types/missions"; -import { debugLog, debugScreenMounted } from "@/utils/debug"; +import { createTimingLogger, debugLog, debugScreenMounted } from "@/utils/debug"; type Props = MainTabScreenProps<"Home">; @@ -73,9 +73,11 @@ export default function HomeScreen({ navigation }: Props) { const [isTrackingModalOpen, setIsTrackingModalOpen] = useState(false); const [emotionAnswerKind, setEmotionAnswerKind] = useState(null); const openedTrackingCycleKeysRef = useRef>(new Set()); + const initialLoadTimingRef = useRef | null>(null); useEffect(() => { debugScreenMounted("HomeScreen"); + initialLoadTimingRef.current = createTimingLogger("HomeScreen", "initial data load"); }, []); useEffect(() => { @@ -113,6 +115,18 @@ export default function HomeScreen({ navigation }: Props) { } }, [data, hydrate]); + useEffect(() => { + if (!data || !initialLoadTimingRef.current) { + return; + } + + initialLoadTimingRef.current({ + gardenCount: data.gardenSummaries?.length ?? 0, + missionCount: data.todayMissions?.length ?? 0, + }); + initialLoadTimingRef.current = null; + }, [data]); + useEffect(() => { if (!trackingPromptStatus?.eligible || !trackingPromptStatus.cycleKey) { return; diff --git a/src/pages/profile/ProfileScreen.tsx b/src/pages/profile/ProfileScreen.tsx index 7cf952f..1b949bc 100644 --- a/src/pages/profile/ProfileScreen.tsx +++ b/src/pages/profile/ProfileScreen.tsx @@ -1,4 +1,4 @@ -import { useMemo, useState } from "react"; +import { useEffect, useMemo, useRef, useState } from "react"; import { Image, ScrollView, @@ -17,6 +17,7 @@ import ProfileGardenScene from "@/components/profile/ProfileGardenScene"; import { useFriendWater, useUserProfile } from "@/hooks/profile/useProfileApi"; import { useFollowUser, useUnfollowUser } from "@/hooks/follow/useFollowApi"; import useTokenStore from "@/stores/useTokenStore"; +import { createTimingLogger } from "@/utils/debug"; import { FollowStatus } from "@/types/profile/profileApi.type"; type Props = RootStackScreenProps<"Profile">; @@ -41,9 +42,23 @@ export default function ProfileScreen({ navigation, route }: Props) { const [wateringGardenId, setWateringGardenId] = useState(null); const [isFriendWaterCooldownActive, setIsFriendWaterCooldownActive] = useState(false); const [toastMessage, setToastMessage] = useState(null); + const initialLoadTimingRef = useRef | null>(null); const isMe = String(userId) === myUserId; + useEffect(() => { + initialLoadTimingRef.current = createTimingLogger("ProfileScreen", "initial profile load", { userId }); + }, [userId]); + + useEffect(() => { + if (!data || !initialLoadTimingRef.current) { + return; + } + + initialLoadTimingRef.current({ gardenCount: data.userGardens.length }); + initialLoadTimingRef.current = null; + }, [data]); + const handleBack = () => { if (navigation.canGoBack()) { navigation.goBack(); diff --git a/src/utils/debug.ts b/src/utils/debug.ts index 5efc204..5ae429a 100644 --- a/src/utils/debug.ts +++ b/src/utils/debug.ts @@ -10,3 +10,15 @@ export function debugLog(scope: string, message: string, payload?: unknown) { export function debugScreenMounted(screenName: string, payload?: unknown) { debugLog("Screen", `${screenName} mounted`, payload); } + +export function createTimingLogger(scope: string, eventName: string, payload?: unknown) { + const startedAt = Date.now(); + debugLog(scope, `${eventName} started`, payload); + + return (extra?: Record) => { + debugLog(scope, `${eventName} finished`, { + durationMs: Date.now() - startedAt, + ...(extra ?? {}), + }); + }; +} From c9f895925f45130e3fe54730ed5f93c4f30df81c Mon Sep 17 00:00:00 2001 From: lejuho Date: Tue, 17 Mar 2026 19:18:17 +0900 Subject: [PATCH 79/92] =?UTF-8?q?fix=20:=20=EC=95=84=EB=B0=94=ED=83=80=20?= =?UTF-8?q?=EB=8B=89=EB=84=A4=EC=9E=84=20=EB=B3=80=EA=B2=BD=201=EB=8B=A8?= =?UTF-8?q?=EA=B3=84=20=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20=EC=9C=84?= =?UTF-8?q?=EC=B9=98=20=EC=A1=B0=EC=A0=95=20=EB=B0=8F=20=ED=95=9C=EA=B8=80?= =?UTF-8?q?=20=EC=A3=BC=EC=84=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- src/pages/option/AvatarNicknameEditScreen.tsx | 328 +++++++++--------- 1 file changed, 165 insertions(+), 163 deletions(-) diff --git a/src/pages/option/AvatarNicknameEditScreen.tsx b/src/pages/option/AvatarNicknameEditScreen.tsx index c03b94f..a0be2bf 100644 --- a/src/pages/option/AvatarNicknameEditScreen.tsx +++ b/src/pages/option/AvatarNicknameEditScreen.tsx @@ -1,87 +1,70 @@ -import { useMemo, useState } from "react"; import { - Alert, + FlatList, Image, - ScrollView, StyleSheet, Text, TouchableOpacity, View, + useWindowDimensions, } from "react-native"; -import { SafeAreaView } from "react-native-safe-area-context"; +import { useMemo, useRef, useState } from "react"; + +import type { GardenSummary } from "@/types/home/garden"; +import { LeftIcon } from "@/assets/icons/CommonIcons"; import type { RootStackScreenProps } from "@/navigation/types"; -import RegistrationFooter from "@/components/registration/RegistrationFooter"; -import RegistrationTextField from "@/components/registration/RegistrationTextField"; +import { SafeAreaView } from "react-native-safe-area-context"; import StatusView from "@/components/common/StatusView"; import useHomeApi from "@/hooks/home/useHomeApi"; -import { useUpdateAvatarNickname } from "@/hooks/option/useAvatarNicknameApi"; -import type { GardenSummary } from "@/types/home/garden"; type Props = RootStackScreenProps<"AvatarNicknameEdit">; type SelectableAvatar = { - gardenId: number; - gardenSlotNumber: number; avatarId: number; avatarName: string; avatarImageUrl: string; }; +// 캐러셀 아이템 너비 및 아이템 간 간격 +const ITEM_WIDTH = 258; +const ITEM_GAP = 16; + export default function AvatarNicknameEditScreen({ navigation }: Props) { + const { width: screenWidth } = useWindowDimensions(); const { data, isLoading, error, refetch } = useHomeApi(); - const updateAvatarNickname = useUpdateAvatarNickname(); - const [selectedAvatarId, setSelectedAvatarId] = useState(null); - const [draftNickname, setDraftNickname] = useState(""); + const [currentIndex, setCurrentIndex] = useState(0); + const flatListRef = useRef(null); - const avatars = useMemo(() => { - if (!data?.gardenSummaries) { - return []; - } + // 캐러셀 아이템이 화면 중앙에 오도록 좌우 패딩 계산 + const sidePadding = (screenWidth - ITEM_WIDTH) / 2; + // 아바타가 있는 정원 목록만 필터링 + const avatars = useMemo(() => { + if (!data?.gardenSummaries) return []; return data.gardenSummaries - .filter((garden: GardenSummary) => Boolean(garden.avatar?.avatarId)) - .map((garden: GardenSummary) => ({ - gardenId: garden.gardenId, - gardenSlotNumber: garden.gardenSlotNumber, - avatarId: garden.avatar!.avatarId, - avatarName: garden.avatar!.avatarName, - avatarImageUrl: garden.avatar!.avatarImageUrl, + .filter((g: GardenSummary) => Boolean(g.avatar?.avatarId)) + .map((g: GardenSummary) => ({ + avatarId: g.avatar!.avatarId, + avatarName: g.avatar!.avatarName, + avatarImageUrl: g.avatar!.avatarImageUrl, })); }, [data]); - const selectedAvatar = - avatars.find(avatar => avatar.avatarId === selectedAvatarId) ?? avatars[0] ?? null; + const selectedAvatar = avatars[currentIndex] ?? null; + const isButtonEnabled = selectedAvatar !== null; - const nickname = draftNickname || selectedAvatar?.avatarName || ""; - const trimmedNickname = nickname.trim(); - const isValidNickname = trimmedNickname.length >= 1 && trimmedNickname.length <= 6; - const isChanged = trimmedNickname.length > 0 && trimmedNickname !== (selectedAvatar?.avatarName ?? ""); + const handleBack = () => navigation.goBack(); - const handleBack = () => { - navigation.goBack(); - }; - - const handleSelectAvatar = (avatarId: number, avatarName: string) => { - setSelectedAvatarId(avatarId); - setDraftNickname(avatarName); - }; - - const handleSubmit = async () => { - if (!selectedAvatar || !isValidNickname || !isChanged || updateAvatarNickname.isPending) { - return; - } - - try { - await updateAvatarNickname.mutateAsync({ - avatarId: selectedAvatar.avatarId, - newAvatarName: trimmedNickname, - }); - navigation.goBack(); - } catch { - Alert.alert("아바타 닉네임 변경에 실패했습니다", "잠시 후 다시 시도해주세요."); - } + // 선택한 아바타 정보를 다음 단계(닉네임 입력)로 전달 + const handleNext = () => { + if (!selectedAvatar) return; + navigation.navigate("AvatarNicknameEditStep2", { + avatarId: selectedAvatar.avatarId, + avatarName: selectedAvatar.avatarName, + avatarImageUrl: selectedAvatar.avatarImageUrl, + }); }; + // --- 로딩 / 에러 / 빈 상태 처리 --- if (isLoading) { return ( @@ -116,66 +99,69 @@ export default function AvatarNicknameEditScreen({ navigation }: Props) { } return ( - + + {/* 상단 헤더 */} - - 뒤로 + + 아바타 닉네임 변경 - + - - - 설정 - 식물별 이름을 수정합니다. - - {/* 한글 주석: - 유저 닉네임과 달리 아바타 닉네임은 식물별로 따로 가지므로, - 먼저 변경할 식물을 선택한 뒤 1개 대상만 수정하도록 분리한다. */} - 홈과 프로필에 보이는 식물 이름을 선택해서 바꿀 수 있습니다. - - + 변경할 식물을 선택해주세요 - - {avatars.map(avatar => { - const selected = avatar.avatarId === (selectedAvatar?.avatarId ?? null); + {/* 아바타 캐러셀 + 이름 + 페이지 점 */} + + String(item.avatarId)} + horizontal + showsHorizontalScrollIndicator={false} + snapToInterval={ITEM_WIDTH + ITEM_GAP} + decelerationRate="fast" + contentContainerStyle={{ paddingHorizontal: sidePadding }} + ItemSeparatorComponent={() => } + onMomentumScrollEnd={e => { + // 스크롤 위치로 현재 선택 인덱스 갱신 + const index = Math.round(e.nativeEvent.contentOffset.x / (ITEM_WIDTH + ITEM_GAP)); + setCurrentIndex(Math.max(0, Math.min(index, avatars.length - 1))); + }} + renderItem={({ item, index }) => { + const isSelected = index === currentIndex; return ( - handleSelectAvatar(avatar.avatarId, avatar.avatarName)} - > - - - {avatar.avatarName} - 텃밭 {avatar.gardenSlotNumber} - - + + + ); - })} - - - 6 - ? "아바타 닉네임은 6자 이하로 입력해주세요." - : "선택한 식물에만 반영됩니다." - } + }} /> - + {/* 선택된 아바타 이름 */} + {selectedAvatar?.avatarName ?? ""} + {/* 페이지 인디케이터 점 */} + + {avatars.map((_, i) => ( + + ))} + + - void handleSubmit()} - primaryDisabled={!selectedAvatar || !isValidNickname || !isChanged || updateAvatarNickname.isPending} - primaryLoading={updateAvatarNickname.isPending} - /> + {/* 하단 다음 버튼 */} + + + 다음 + + ); } @@ -183,91 +169,107 @@ export default function AvatarNicknameEditScreen({ navigation }: Props) { const styles = StyleSheet.create({ safeArea: { flex: 1, - backgroundColor: "#F7F8F4", + backgroundColor: "#FFFFFF", }, + // 상단 헤더 영역 header: { height: 56, flexDirection: "row", alignItems: "center", justifyContent: "space-between", - paddingHorizontal: 16, - backgroundColor: "#FFFFFF", - borderBottomWidth: StyleSheet.hairlineWidth, - borderBottomColor: "#E5E7EB", + paddingHorizontal: 13, + borderBottomWidth: 1, + borderBottomColor: "#EFEFEF", }, - sideButton: { - width: 56, + backButton: { + width: 44, height: 44, justifyContent: "center", }, - backText: { - fontSize: 14, + headerTitle: { + fontSize: 18, fontWeight: "600", - color: "#374151", + color: "#171717", }, - headerTitle: { - fontSize: 17, - fontWeight: "700", + // 안내 타이틀 + title: { + fontSize: 20, + fontWeight: "600", color: "#171717", + marginTop: 32, + marginLeft: 25, }, - content: { - padding: 20, - gap: 18, + // 캐러셀 + 이름 + 점 묶음 영역 + // paddingTop으로 이미지 상단 여백 조정 (수동 조정 가능) + carouselWrapper: { + flex: 1, + justifyContent: "flex-start", + alignItems: "center", + gap: 16, + paddingTop: 160, }, - heroCard: { - borderRadius: 22, - padding: 20, - backgroundColor: "#234A2F", - gap: 8, + // 개별 아바타 카드 + carouselItem: { + width: ITEM_WIDTH, + height: 292, + borderRadius: 12, + borderWidth: 2, + borderColor: "#72D14E", + overflow: "hidden", }, - eyebrow: { - fontSize: 12, - color: "#D7E9D8", + carouselItemSelected: { + backgroundColor: "#EEF9EA", + opacity: 1, }, - heroTitle: { - fontSize: 24, - lineHeight: 32, - fontWeight: "700", - color: "#FFFFFF", + carouselItemDimmed: { + opacity: 0.5, }, - heroDescription: { - fontSize: 14, - lineHeight: 20, - color: "#E5F4E5", + carouselImage: { + width: "100%", + height: "100%", }, - avatarList: { - gap: 10, + // 아바타 이름 텍스트 + carouselName: { + fontSize: 18, + fontWeight: "600", + color: "#171717", + textAlign: "center", }, - avatarCard: { + // 페이지 인디케이터 점 행 + dotRow: { flexDirection: "row", - alignItems: "center", - gap: 14, - borderRadius: 18, - backgroundColor: "#FFFFFF", - paddingHorizontal: 16, - paddingVertical: 14, - borderWidth: 1, - borderColor: "#E5E7EB", + gap: 12, + marginBottom: 100, }, - avatarCardSelected: { - borderColor: "#2F7D32", - backgroundColor: "#F1FBF1", + dot: { + width: 8, + height: 8, + borderRadius: 4, + backgroundColor: "#BFBFBF", }, - avatarImage: { - width: 52, - height: 52, + dotActive: { + backgroundColor: "#171717", }, - avatarTextWrap: { - flex: 1, - gap: 4, + // 하단 버튼 영역 + footer: { + paddingHorizontal: 20, + paddingBottom: 16, }, - avatarCardTitle: { - fontSize: 16, - fontWeight: "700", - color: "#171717", + button: { + height: 56, + borderRadius: 8, + alignItems: "center", + justifyContent: "center", + }, + buttonActive: { + backgroundColor: "#72D14E", + }, + buttonDisabled: { + backgroundColor: "#7C7C7C", }, - avatarCardCaption: { - fontSize: 13, - color: "#6B7280", + buttonText: { + fontSize: 18, + fontWeight: "600", + color: "#FFFFFF", }, }); From 2f78e1886750efd485d30b558c3092ca11f15b72 Mon Sep 17 00:00:00 2001 From: lejuho Date: Tue, 17 Mar 2026 19:18:46 +0900 Subject: [PATCH 80/92] =?UTF-8?q?chore=20:=20=EC=A4=91=EA=B0=84=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .claude/settings.local.json | 18 + .../dailyMission/QuizOptionCard.tsx | 53 +- src/components/home/HomeBottomSheet.tsx | 76 +- src/components/home/HomeEmotionModal.tsx | 24 +- src/components/home/HomeGardenScene.tsx | 91 +- src/components/home/WishTreeInfoModal.tsx | 171 ++ src/hooks/home/useHomeApi.ts | 47 +- src/hooks/mission/useMissionApi.ts | 35 +- src/hooks/profile/useProfileApi.ts | 20 +- src/navigation/RootNavigator.tsx | 2 + src/navigation/types.ts | 5 + .../DailyMissionWriteDiaryScreen.tsx | 123 +- .../option/AvatarNicknameEditStep2Screen.tsx | 170 ++ src/pages/option/PolicyScreen.tsx | 43 +- src/pages/option/UserNicknameEditScreen.tsx | 184 ++- src/pages/profile/ProfileScreen.tsx | 1437 ++++++++++++----- 16 files changed, 1790 insertions(+), 709 deletions(-) create mode 100644 .claude/settings.local.json create mode 100644 src/components/home/WishTreeInfoModal.tsx create mode 100644 src/pages/option/AvatarNicknameEditStep2Screen.tsx diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000..419f0f0 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,18 @@ +{ + "permissions": { + "allow": [ + "Skill(update-config)", + "mcp__figma-desktop__get_design_context", + "Bash(python3 -c \"import json,sys; d=json.load\\(sys.stdin\\); print\\(json.dumps\\(d.get\\(''''mcpServers'''', {}\\), indent=2\\)\\)\")", + "Bash(claude mcp:*)", + "mcp__plugin_figma_figma__whoami", + "mcp__plugin_figma_figma__get_design_context", + "mcp__plugin_figma_figma__get_metadata", + "Bash(python3:*)", + "mcp__figma-desktop__get_screenshot", + "mcp__plugin_figma_figma__get_screenshot", + "Bash(git add:*)", + "Bash(git commit:*)" + ] + } +} diff --git a/src/components/dailyMission/QuizOptionCard.tsx b/src/components/dailyMission/QuizOptionCard.tsx index 9cf22f1..3cd9a07 100644 --- a/src/components/dailyMission/QuizOptionCard.tsx +++ b/src/components/dailyMission/QuizOptionCard.tsx @@ -1,4 +1,6 @@ -import { StyleSheet, Text, TouchableOpacity } from "react-native"; +import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import CheckIcon from "@/assets/icons/Check.svg"; +import Check2Icon from "@/assets/icons/Check2.svg"; type Props = { label: string; @@ -15,6 +17,17 @@ export default function QuizOptionCard({ state = "idle", onPress, }: Props) { + const BadgeIcon = + state === "correct" || state === "answer" || selected ? CheckIcon : Check2Icon; + const badgeText = + state === "correct" || state === "answer" + ? "\uC815\uB2F5" + : state === "wrong" + ? "\uC624\uB2F5" + : selected + ? "\uC120\uD0DD\uB428" + : null; + return ( {label} - - {state === "correct" || state === "answer" - ? "정답" - : state === "wrong" - ? "오답" - : selected - ? "선택됨" - : ""} - + + + {badgeText ? ( + + {badgeText} + + ) : null} + ); } @@ -71,9 +89,22 @@ const styles = StyleSheet.create({ lineHeight: 22, color: "#171717", }, - badge: { + badgeWrap: { + flexDirection: "row", + alignItems: "center", + gap: 6, + minWidth: 54, + justifyContent: "flex-end", + }, + badgeText: { fontSize: 12, fontWeight: "700", color: "#4B5563", }, + badgeTextCorrect: { + color: "#2F7D32", + }, + badgeTextWrong: { + color: "#DC2626", + }, }); diff --git a/src/components/home/HomeBottomSheet.tsx b/src/components/home/HomeBottomSheet.tsx index a69ea33..635e5a8 100644 --- a/src/components/home/HomeBottomSheet.tsx +++ b/src/components/home/HomeBottomSheet.tsx @@ -1,4 +1,4 @@ -import { useEffect, useRef } from "react"; +import { useEffect, useRef, useState } from "react"; import { Animated, PanResponder, @@ -9,7 +9,10 @@ import { TouchableOpacity, View, } from "react-native"; -import { RightIcon } from "@/assets/icons/CommonIcons"; +import CheckIcon from "@/assets/icons/Check.svg"; +import Check2Icon from "@/assets/icons/Check2.svg"; +import PlantBadgeIcon from "@/assets/icons/bottom-sheet/plant.svg"; +import WishTreeInfoModal from "@/components/home/WishTreeInfoModal"; import { getMissionCompleted, type TodayMission } from "@/types/home/garden"; import type { HomePanelPayload } from "@/types/home/panel"; @@ -36,6 +39,7 @@ export default function HomeBottomSheet({ }) { const translateY = useRef(new Animated.Value(expanded ? 0 : DRAG_RANGE)).current; const dragStart = useRef(DRAG_RANGE); + const [isWishInfoVisible, setIsWishInfoVisible] = useState(false); useEffect(() => { Animated.spring(translateY, { @@ -170,7 +174,7 @@ export default function HomeBottomSheet({ {card.label} - {card.checked ? : } + ))} @@ -180,9 +184,17 @@ export default function HomeBottomSheet({ - T + - 소망 나무 + {"\uC18C\uB9DD \uB098\uBB34"} + + setIsWishInfoVisible(true)} + style={styles.wishInfoButton} + > + ? + {progressPercent >= 100 @@ -219,6 +231,10 @@ export default function HomeBottomSheet({ + setIsWishInfoVisible(false)} + /> ); } @@ -226,8 +242,8 @@ export default function HomeBottomSheet({ function MissionStatusDot({ checked }: { checked: boolean }) { return ( - - {checked ? : null} + + {checked ? : } ); } @@ -297,23 +313,11 @@ const styles = StyleSheet.create({ gap: 8, }, statusDot: { - width: 28, - height: 28, - borderRadius: 14, + width: 24, + height: 24, alignItems: "center", justifyContent: "center", }, - statusDotChecked: { - backgroundColor: "#7DC960", - }, - statusDotUnchecked: { - backgroundColor: "#E5E7EB", - }, - statusDotCheck: { - color: "#FFFFFF", - fontSize: 15, - fontWeight: "700", - }, sheetMissionList: { marginTop: 8, gap: 10, @@ -334,6 +338,7 @@ const styles = StyleSheet.create({ backgroundColor: "#EEF7E8", }, sheetMissionLabel: { + flex: 1, fontSize: 15, color: "#6B7280", }, @@ -355,23 +360,34 @@ const styles = StyleSheet.create({ gap: 6, }, wishTreeBadge: { - width: 26, - height: 26, - borderRadius: 13, + width: 28, + height: 28, + borderRadius: 14, backgroundColor: "#EEF7E8", alignItems: "center", justifyContent: "center", - }, - wishTreeBadgeText: { - color: "#59A647", - fontSize: 13, - fontWeight: "700", + overflow: "hidden", }, wishTitle: { fontSize: 18, fontWeight: "700", color: "#171717", }, + wishInfoButton: { + width: 26, + height: 26, + borderRadius: 13, + borderWidth: 1.5, + borderColor: "#9CA3AF", + alignItems: "center", + justifyContent: "center", + }, + wishInfoIcon: { + fontSize: 13, + fontWeight: "700", + color: "#9CA3AF", + lineHeight: 16, + }, wishBody: { fontSize: 14, lineHeight: 20, @@ -437,3 +453,5 @@ const styles = StyleSheet.create({ }, }); + + diff --git a/src/components/home/HomeEmotionModal.tsx b/src/components/home/HomeEmotionModal.tsx index 9c6a25b..c363c92 100644 --- a/src/components/home/HomeEmotionModal.tsx +++ b/src/components/home/HomeEmotionModal.tsx @@ -1,4 +1,4 @@ -import { useMemo, useState } from "react"; +import { useMemo, useState } from "react"; import type { AxiosError } from "axios"; import { Image, @@ -15,6 +15,7 @@ import { SURVEY_ANSWER_VALUE_MAP, type SurveyAnswerKind, } from "@/types/missions"; +import { createTimingLogger, debugLog } from "@/utils/debug"; const characterImage = require("@/assets/images/char.webp"); @@ -58,6 +59,11 @@ export default function HomeEmotionModal({ return; } + const finishSubmitTiming = createTimingLogger("HomeEmotionModal", "answer submit", { + answer, + questionId: data.id, + }); + setSubmitErrorMessage(null); try { @@ -67,12 +73,12 @@ export default function HomeEmotionModal({ }); /* - * 한글 주석: - * 홈 팝업은 제출 직후 닫히고 말풍선 상태도 즉시 바뀌어야 한다. - * 서버 재조회 완료를 기다리지 않고 성공 시점을 홈 화면에 바로 전달한다. + * Close the modal as soon as submit succeeds. + * Home state is updated immediately and query refresh continues in the background. */ onAnswered(answer); onClose(); + finishSubmitTiming({ closedImmediately: true }); } catch (error) { const axiosError = error as AxiosError; const status = axiosError.response?.status; @@ -81,9 +87,18 @@ export default function HomeEmotionModal({ if (status === 409) { onAnswered(answer); onClose(); + finishSubmitTiming({ closedImmediately: true, treatedAsAlreadyAnswered: true }); return; } + finishSubmitTiming({ + closedImmediately: false, + status: status ?? null, + }); + debugLog("HomeEmotionModal", "answer submit failed", { + status: status ?? null, + serverMessage: serverMessage ?? null, + }); setSubmitErrorMessage(serverMessage ?? "답변 저장에 실패했습니다. 잠시 후 다시 시도해주세요."); } }; @@ -212,3 +227,4 @@ const styles = StyleSheet.create({ }, }); + diff --git a/src/components/home/HomeGardenScene.tsx b/src/components/home/HomeGardenScene.tsx index 5f336f7..12ff849 100644 --- a/src/components/home/HomeGardenScene.tsx +++ b/src/components/home/HomeGardenScene.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from "react"; +import { useEffect, useState } from "react"; import { Image, ImageBackground, @@ -20,6 +20,9 @@ import { import type { SurveyAnswerKind } from "@/types/missions"; import SunIcon from "@/assets/icons/sun.svg"; import WaterIcon from "@/assets/icons/water.svg"; +import LockIcon from "@/assets/icons/lock.svg"; +import UnlockedIcon from "@/assets/icons/unlocked.svg"; +import { createTimingLogger, debugLog } from "@/utils/debug"; const mapIcon = require("@/assets/images/map.png"); const emptyGardenImage = require("@/assets/images/null.webp"); @@ -78,43 +81,86 @@ export default function HomeGardenScene({ const isEmptySlot = !isLocked && !hasAvatar; const title = hasAvatar ? garden?.avatar?.avatarName : `텃밭 ${slotNumber}`; const gardenId = garden?.gardenId; + const LockStatusIcon = isUnlockable ? UnlockedIcon : LockIcon; - const handleActionError = (error: unknown) => { + const handleActionError = (action: "sunlight" | "water", error: unknown) => { const axiosError = error as AxiosError<{ message?: string }>; - setToastMessage(axiosError.response?.data?.message ?? "홈 상호작용 처리에 실패했습니다."); + const status = axiosError.response?.status; + const serverMessage = axiosError.response?.data?.message; + + debugLog("HomeGardenScene", `${action} action failed`, { + gardenId, + slotNumber, + status: status ?? null, + serverMessage: serverMessage ?? null, + }); + setToastMessage(serverMessage ?? "홈 상호작용 처리에 실패했습니다."); }; const handleSunlight = async () => { if (!gardenId) return; - if (!canSunlight) { - setToastMessage("햇빛 주기는 오전 6시에 초기화 됩니다"); + if (!canSunlight || sunlightMutation.isPending) { + if (!canSunlight) { + setToastMessage("햇빛 주기는 오전 6시에 초기화 됩니다"); + } return; } + const finishActionTiming = createTimingLogger("HomeGardenScene", "sunlight action", { + gardenId, + slotNumber, + }); + + setCanSunlight(false); + setIsSunlightVisible(true); + setTimeout(() => setIsSunlightVisible(false), 1000); + try { await sunlightMutation.mutateAsync(gardenId); - setCanSunlight(false); - setIsSunlightVisible(true); - setTimeout(() => setIsSunlightVisible(false), 1000); + finishActionTiming({ startedImmediately: true }); } catch (error) { - handleActionError(error); + setCanSunlight(true); + setIsSunlightVisible(false); + finishActionTiming({ + startedImmediately: true, + rolledBack: true, + }); + handleActionError("sunlight", error); } }; const handleWater = async () => { if (!gardenId) return; - if (!canWater) { - setToastMessage("물 주기는 오전 12시에 초기화 됩니다"); + if (!canWater || waterMutation.isPending || isWaterCooldownActive) { + if (!canWater) { + setToastMessage("물 주기는 오전 12시에 초기화 됩니다"); + } return; } + const finishActionTiming = createTimingLogger("HomeGardenScene", "water action", { + gardenId, + slotNumber, + }); + + setCanWater(false); + setIsWaterCooldownActive(true); + setIsWateringVisible(true); + setTimeout(() => setIsWateringVisible(false), 1000); + setTimeout(() => setIsWaterCooldownActive(false), WATER_ACTION_COOLDOWN_MS); + try { await waterMutation.mutateAsync(gardenId); - setCanWater(false); - setIsWateringVisible(true); - setTimeout(() => setIsWateringVisible(false), 1000); + finishActionTiming({ startedImmediately: true }); } catch (error) { - handleActionError(error); + setCanWater(true); + setIsWateringVisible(false); + setIsWaterCooldownActive(false); + finishActionTiming({ + startedImmediately: true, + rolledBack: true, + }); + handleActionError("water", error); } }; @@ -142,13 +188,18 @@ export default function HomeGardenScene({ {isLocked ? ( + - 해금되지 않았습니다 + {isUnlockable ? "\uC9C0\uAE08 \uC5F4 \uC218 \uC788\uC5B4\uC694" : "\uD574\uAE08\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4"} {isUnlockable - ? "지금은 씨앗을 받아 새로운 텃밭을 열 수 있어요." - : "소망 나무가 충분히 자라면 새로운 텃밭을 열 수 있어요."} + ? "\uC528\uC557\uC744 \uBC1B\uC544 \uC0C8\uB85C\uC6B4 \uD143\uBC2D\uC744 \uC5F4 \uC218 \uC788\uC5B4\uC694." + : "\uC18C\uB9DD \uB098\uBB34\uAC00 \uCDA9\uBD84\uD788 \uC790\uB77C\uBA74 \uC0C8\uB85C\uC6B4 \uD143\uBC2D\uC744 \uC5F4 \uC218 \uC788\uC5B4\uC694."} @@ -322,6 +373,9 @@ const styles = StyleSheet.create({ paddingHorizontal: 28, gap: 10, }, + lockStatusIcon: { + marginBottom: 6, + }, lockedHeading: { fontSize: 24, fontWeight: "700", @@ -390,3 +444,4 @@ const styles = StyleSheet.create({ }, }); + diff --git a/src/components/home/WishTreeInfoModal.tsx b/src/components/home/WishTreeInfoModal.tsx new file mode 100644 index 0000000..7a12644 --- /dev/null +++ b/src/components/home/WishTreeInfoModal.tsx @@ -0,0 +1,171 @@ +import { + Modal, + Pressable, + ScrollView, + StyleSheet, + Text, + View, +} from "react-native"; + +function StageIcon({ label }: { label: string }) { + return ( + + + {label[0]} + + {label} + + ); +} + +function StageDash() { + return ; +} + +const DAILY_SOURCES = [ + "내 식물 물 주기", + "햇빛 주기", + "일일 미션 - 마음 건강 체크, 일기, 퀴즈", + "친구에게 물 주기", + "방명록 쓰기", +]; + +type Props = { + visible: boolean; + onClose: () => void; +}; + +export default function WishTreeInfoModal({ visible, onClose }: Props) { + return ( + + + {}}> + + {"소망 나무"} + + + + + + + + + + + + + + + + + + {"\uAC01 \uB2E8\uACC4\uC5D0 \uD544\uC694\uD55C \uC810\uC218\uB97C \uC5BB\uC73C\uBA74\n\uB2E4\uC74C \uB2E8\uACC4\uB85C \uB118\uC5B4\uAC00\uACE0 \uC0C8 \uD143\uBC2D\uC744 \uC5F4 \uC218 \uC788\uC5B4\uC694."} + + + {"일일 점수 획득처"} + {DAILY_SOURCES.map(source => ( + + {source} + + ))} + + + + + ); +} + +const styles = StyleSheet.create({ + backdrop: { + flex: 1, + backgroundColor: "rgba(0,0,0,0.35)", + justifyContent: "center", + alignItems: "center", + paddingHorizontal: 24, + }, + card: { + width: "100%", + maxWidth: 380, + backgroundColor: "#FFFFFF", + borderRadius: 24, + paddingHorizontal: 24, + paddingTop: 24, + paddingBottom: 28, + }, + header: { + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + marginBottom: 24, + }, + title: { + fontSize: 20, + fontWeight: "700", + color: "#171717", + }, + closeButton: { + width: 32, + height: 32, + alignItems: "center", + justifyContent: "center", + }, + closeIcon: { + fontSize: 18, + color: "#9CA3AF", + }, + body: { + gap: 0, + }, + stagesRow: { + flexDirection: "row", + alignItems: "center", + justifyContent: "center", + marginBottom: 24, + }, + stageIconWrap: { + alignItems: "center", + gap: 8, + }, + stageIconPlaceholder: { + width: 52, + height: 52, + borderRadius: 26, + backgroundColor: "#F0F4EC", + alignItems: "center", + justifyContent: "center", + }, + stageIconText: { + fontSize: 20, + color: "#4CAF50", + fontWeight: "700", + }, + stageLabel: { + fontSize: 13, + color: "#6B7280", + marginTop: 4, + }, + stageDash: { + width: 20, + height: 1.5, + backgroundColor: "#D1D5DB", + marginBottom: 18, + marginHorizontal: 2, + }, + description: { + fontSize: 14, + lineHeight: 22, + color: "#374151", + marginBottom: 20, + }, + sectionTitle: { + fontSize: 15, + fontWeight: "700", + color: "#171717", + marginBottom: 10, + }, + sourceItem: { + fontSize: 14, + lineHeight: 26, + color: "#6B7280", + }, +}); diff --git a/src/hooks/home/useHomeApi.ts b/src/hooks/home/useHomeApi.ts index 6d6386b..6e07919 100644 --- a/src/hooks/home/useHomeApi.ts +++ b/src/hooks/home/useHomeApi.ts @@ -19,6 +19,7 @@ import type { TrackingPromptConfirmRequest, TrackingPromptStatusPayload, } from "@/types/home/tracking"; +import { createTimingLogger, debugLog } from "@/utils/debug"; export const useHomeApi = () => useQuery< @@ -142,10 +143,25 @@ export const useGardenSunlightAction = () => { return useMutation({ mutationFn: (gardenId: number) => postGardenSunlight(gardenId), - onSuccess: async () => { - await queryClient.invalidateQueries({ queryKey: ["home-summary"] }); - await queryClient.invalidateQueries({ queryKey: ["home-panel"] }); - await queryClient.invalidateQueries({ queryKey: ["tracking-report-status"] }); + onSuccess: () => { + const finishRefreshTiming = createTimingLogger( + "useGardenSunlightAction", + "post-action background refresh" + ); + + void Promise.allSettled([ + queryClient.invalidateQueries({ queryKey: ["home-summary"] }), + queryClient.invalidateQueries({ queryKey: ["home-panel"] }), + queryClient.invalidateQueries({ queryKey: ["tracking-report-status"] }), + ]).then(results => { + const rejectedCount = results.filter(result => result.status === "rejected").length; + + finishRefreshTiming({ rejectedCount }); + + if (rejectedCount > 0) { + debugLog("useGardenSunlightAction", "background refresh had failures", { results }); + } + }); }, }); }; @@ -155,10 +171,25 @@ export const useGardenWaterAction = () => { return useMutation({ mutationFn: (gardenId: number) => postGardenMyWater(gardenId), - onSuccess: async () => { - await queryClient.invalidateQueries({ queryKey: ["home-summary"] }); - await queryClient.invalidateQueries({ queryKey: ["home-panel"] }); - await queryClient.invalidateQueries({ queryKey: ["tracking-report-status"] }); + onSuccess: () => { + const finishRefreshTiming = createTimingLogger( + "useGardenWaterAction", + "post-action background refresh" + ); + + void Promise.allSettled([ + queryClient.invalidateQueries({ queryKey: ["home-summary"] }), + queryClient.invalidateQueries({ queryKey: ["home-panel"] }), + queryClient.invalidateQueries({ queryKey: ["tracking-report-status"] }), + ]).then(results => { + const rejectedCount = results.filter(result => result.status === "rejected").length; + + finishRefreshTiming({ rejectedCount }); + + if (rejectedCount > 0) { + debugLog("useGardenWaterAction", "background refresh had failures", { results }); + } + }); }, }); }; diff --git a/src/hooks/mission/useMissionApi.ts b/src/hooks/mission/useMissionApi.ts index 603e97d..f4451c7 100644 --- a/src/hooks/mission/useMissionApi.ts +++ b/src/hooks/mission/useMissionApi.ts @@ -21,6 +21,7 @@ import type { WriteDiaryRequest, WriteDiaryResponse, } from "@/types/missions"; +import { createTimingLogger, debugLog } from "@/utils/debug"; export const useWriteDiaryImageUpload = () => useMutation({ @@ -70,18 +71,32 @@ export const useAnswerDailySurvey = () => { return useMutation({ mutationFn: payload => answerDailySurveyApi(payload), - onSuccess: async () => { + onSuccess: () => { /* - * 한글 주석: - * 마음 건강 체크는 홈 캐릭터 상태와 미션 패널 양쪽에서 사용하므로 - * 설문 결과와 홈 데이터를 모두 같은 시점에 다시 받아온다. + * Keep the survey modal responsive. + * Refresh related queries in the background after submit succeeds. */ - await queryClient.invalidateQueries({ queryKey: ["daily-survey"] }); - await queryClient.invalidateQueries({ queryKey: ["home-summary"] }); - await queryClient.invalidateQueries({ queryKey: ["home-panel"] }); - await queryClient.refetchQueries({ queryKey: ["daily-survey"], type: "all" }); - await queryClient.refetchQueries({ queryKey: ["home-summary"], type: "all" }); - await queryClient.refetchQueries({ queryKey: ["home-panel"], type: "all" }); + const finishRefreshTiming = createTimingLogger( + "useAnswerDailySurvey", + "post-submit background refresh" + ); + + void Promise.allSettled([ + queryClient.invalidateQueries({ queryKey: ["daily-survey"] }), + queryClient.invalidateQueries({ queryKey: ["home-summary"] }), + queryClient.invalidateQueries({ queryKey: ["home-panel"] }), + queryClient.refetchQueries({ queryKey: ["daily-survey"], type: "all" }), + queryClient.refetchQueries({ queryKey: ["home-summary"], type: "all" }), + queryClient.refetchQueries({ queryKey: ["home-panel"], type: "all" }), + ]).then(results => { + const rejectedCount = results.filter(result => result.status === "rejected").length; + + finishRefreshTiming({ rejectedCount }); + + if (rejectedCount > 0) { + debugLog("useAnswerDailySurvey", "background refresh had failures", { results }); + } + }); }, }); }; diff --git a/src/hooks/profile/useProfileApi.ts b/src/hooks/profile/useProfileApi.ts index 093623f..5ccd0cf 100644 --- a/src/hooks/profile/useProfileApi.ts +++ b/src/hooks/profile/useProfileApi.ts @@ -5,6 +5,7 @@ import { postFriendWater, } from "@/apis/profile/profileApi"; import type { GetUserProfileResponse } from "@/types/profile/profileApi.type"; +import { createTimingLogger, debugLog } from "@/utils/debug"; export const useUserProfile = (userId: string | number | undefined) => useQuery<{ result: GetUserProfileResponse }, unknown, GetUserProfileResponse>({ @@ -20,8 +21,23 @@ export const useFriendWater = (userId: string | number | undefined) => { return useMutation({ mutationFn: (gardenId: number) => postFriendWater(gardenId), - onSuccess: async () => { - await queryClient.invalidateQueries({ queryKey: ["profile", userId] }); + onSuccess: () => { + const finishRefreshTiming = createTimingLogger( + "useFriendWater", + "post-action background refresh" + ); + + void Promise.allSettled([ + queryClient.invalidateQueries({ queryKey: ["profile", userId] }), + ]).then(results => { + const rejectedCount = results.filter(result => result.status === "rejected").length; + + finishRefreshTiming({ rejectedCount }); + + if (rejectedCount > 0) { + debugLog("useFriendWater", "background refresh had failures", { results, userId }); + } + }); }, }); }; diff --git a/src/navigation/RootNavigator.tsx b/src/navigation/RootNavigator.tsx index bedd752..55944b0 100644 --- a/src/navigation/RootNavigator.tsx +++ b/src/navigation/RootNavigator.tsx @@ -17,6 +17,7 @@ import GuestbookScreen from "@/pages/profile/GuestbookScreen"; import FollowScreen from "@/pages/follow/FollowScreen"; import UserNicknameEditScreen from "@/pages/option/UserNicknameEditScreen"; import AvatarNicknameEditScreen from "@/pages/option/AvatarNicknameEditScreen"; +import AvatarNicknameEditStep2Screen from "@/pages/option/AvatarNicknameEditStep2Screen"; import PolicyScreen from "@/pages/option/PolicyScreen"; import ServiceGuideScreen from "@/pages/option/ServiceGuideScreen"; import DeliveryScreen from "@/pages/delivery/DeliveryScreen"; @@ -80,6 +81,7 @@ export default function RootNavigator() { + diff --git a/src/navigation/types.ts b/src/navigation/types.ts index 973e498..dd64e01 100644 --- a/src/navigation/types.ts +++ b/src/navigation/types.ts @@ -24,6 +24,11 @@ export type RootStackParamList = { // 설정 UserNicknameEdit: undefined; AvatarNicknameEdit: undefined; + AvatarNicknameEditStep2: { + avatarId: number; + avatarName: string; + avatarImageUrl: string; + }; Policy: undefined; ServiceGuide: undefined; diff --git a/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx b/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx index cc988b5..086a131 100644 --- a/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx +++ b/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx @@ -1,26 +1,16 @@ import * as ImagePicker from "expo-image-picker"; - -import { - Alert, - ScrollView, - StyleSheet, - Text, - TouchableOpacity, - View, -} from "react-native"; -import { - useWriteDiaryImageUpload, - useWriteDiarySubmit, -} from "@/hooks/mission/useMissionApi"; - +import { Alert, ScrollView, StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import { useQueryClient } from "@tanstack/react-query"; +import { useState } from "react"; +import { SafeAreaView } from "react-native-safe-area-context"; +import ScreenHeader from "@/components/common/ScreenHeader"; +import CheckIcon from "@/assets/icons/Check.svg"; +import Check2Icon from "@/assets/icons/Check2.svg"; import ImageAttachmentCard from "@/components/dailyMission/ImageAttachmentCard"; import RegistrationFooter from "@/components/registration/RegistrationFooter"; import RegistrationTextField from "@/components/registration/RegistrationTextField"; +import { useWriteDiaryImageUpload, useWriteDiarySubmit } from "@/hooks/mission/useMissionApi"; import type { RootStackScreenProps } from "@/navigation/types"; -import { SafeAreaView } from "react-native-safe-area-context"; -import ScreenHeader from "@/components/common/ScreenHeader"; -import { useQueryClient } from "@tanstack/react-query"; -import { useState } from "react"; type Props = RootStackScreenProps<"DailyMissionWriteDiary">; @@ -46,15 +36,11 @@ export default function DailyMissionWriteDiaryScreen({ navigation }: Props) { const handlePickImage = async () => { if (!permissionRequested) { - const permission = - await ImagePicker.requestMediaLibraryPermissionsAsync(); + const permission = await ImagePicker.requestMediaLibraryPermissionsAsync(); setPermissionRequested(true); if (!permission.granted) { - Alert.alert( - "권한 필요", - "일기 이미지를 선택하려면 사진 접근 권한이 필요합니다." - ); + Alert.alert("권한 필요", "일기 이미지를 선택하려면 사진 접근 권한이 필요합니다."); return; } } @@ -74,11 +60,14 @@ export default function DailyMissionWriteDiaryScreen({ navigation }: Props) { const fileType = asset.mimeType ?? "image/jpeg"; const formData = new FormData(); - formData.append("file", { - uri: asset.uri, - name: fileName, - type: fileType, - } as never); + formData.append( + "file", + { + uri: asset.uri, + name: fileName, + type: fileType, + } as never + ); setSelectedImageUri(asset.uri); setUploadedImage(null); @@ -87,8 +76,7 @@ export default function DailyMissionWriteDiaryScreen({ navigation }: Props) { const response = await uploadDiaryImage.mutateAsync(formData); setUploadedImage(response.result); } catch (error) { - const message = - error instanceof Error ? error.message : "이미지 업로드에 실패했습니다."; + const message = error instanceof Error ? error.message : "이미지 업로드에 실패했습니다."; Alert.alert("업로드 실패", message); } }; @@ -113,17 +101,14 @@ export default function DailyMissionWriteDiaryScreen({ navigation }: Props) { }); /* - * 한글 주석: - * 일기 작성 완료 후 홈과 로그에서 최신 상태를 바로 보이게 하려면 - * 관련 쿼리를 함께 갱신하고 홈으로 복귀시키는 흐름이 필요하다. + * Invalidate related queries so home and log reflect the new diary immediately. */ await queryClient.invalidateQueries({ queryKey: ["home-summary"] }); await queryClient.invalidateQueries({ queryKey: ["calendar"] }); await queryClient.invalidateQueries({ queryKey: ["diaries"] }); goHome(); } catch (error) { - const message = - error instanceof Error ? error.message : "일기 저장에 실패했습니다."; + const message = error instanceof Error ? error.message : "일기 저장에 실패했습니다."; Alert.alert("일기 저장 실패", message); } }; @@ -138,14 +123,9 @@ export default function DailyMissionWriteDiaryScreen({ navigation }: Props) { - - {/* 날짜 */} + {today} - {/* 제목 입력 (라벨 없이 큰 플레이스홀더) */} - {/* 이미지 첨부 */} void handlePickImage()} @@ -166,7 +145,6 @@ export default function DailyMissionWriteDiaryScreen({ navigation }: Props) { } /> - {/* 내용 입력 */} - {/* 공개 설정 — 라디오 버튼 스타일 */} setIsPublic(false)} activeOpacity={0.7} > - - {!isPublic && } + + {!isPublic ? : } - - 나만 보기 + + {"나만 보기"} @@ -205,21 +172,11 @@ export default function DailyMissionWriteDiaryScreen({ navigation }: Props) { onPress={() => setIsPublic(true)} activeOpacity={0.7} > - - {isPublic && } + + {isPublic ? : } - - 공개하기 + + {"공개하기"} @@ -258,8 +215,6 @@ const styles = StyleSheet.create({ fontWeight: "400", letterSpacing: 0.2, }, - - // 공개 설정 — 라디오 버튼 visibilityRow: { flexDirection: "row", gap: 24, @@ -274,23 +229,10 @@ const styles = StyleSheet.create({ radioCircle: { width: 22, height: 22, - borderRadius: 11, - borderWidth: 1.5, - borderColor: "#C4C9C0", alignItems: "center", justifyContent: "center", - backgroundColor: "transparent", - }, - radioCircleSelected: { - borderColor: "#2F7D32", - backgroundColor: "#2F7D32", - }, - radioCheck: { - fontSize: 12, - color: "#FFFFFF", - fontWeight: "700", - lineHeight: 14, }, + radioCircleSelected: {}, visibilityLabel: { fontSize: 14, color: "#9CA3AF", @@ -301,6 +243,3 @@ const styles = StyleSheet.create({ fontWeight: "500", }, }); - - - diff --git a/src/pages/option/AvatarNicknameEditStep2Screen.tsx b/src/pages/option/AvatarNicknameEditStep2Screen.tsx new file mode 100644 index 0000000..48ff498 --- /dev/null +++ b/src/pages/option/AvatarNicknameEditStep2Screen.tsx @@ -0,0 +1,170 @@ +import { useState } from "react"; +import { + Alert, + Image, + StyleSheet, + Text, + TextInput, + TouchableOpacity, + View, +} from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; +import type { RootStackScreenProps } from "@/navigation/types"; +import { LeftIcon } from "@/assets/icons/CommonIcons"; +import { EditIcon } from "@/assets/icons/CommonIcons"; +import { useUpdateAvatarNickname } from "@/hooks/option/useAvatarNicknameApi"; + +type Props = RootStackScreenProps<"AvatarNicknameEditStep2">; + +export default function AvatarNicknameEditStep2Screen({ navigation, route }: Props) { + const { avatarId, avatarName, avatarImageUrl } = route.params; + const updateAvatarNickname = useUpdateAvatarNickname(); + const [draftName, setDraftName] = useState(avatarName); + + const trimmed = draftName.trim(); + const isValid = trimmed.length >= 1 && trimmed.length <= 6; + const isChanged = trimmed !== avatarName; + const isButtonEnabled = isValid && isChanged && !updateAvatarNickname.isPending; + + const handleBack = () => navigation.goBack(); + + const handleSubmit = async () => { + if (!isButtonEnabled) return; + try { + await updateAvatarNickname.mutateAsync({ avatarId, newAvatarName: trimmed }); + navigation.pop(2); + } catch { + Alert.alert("아바타 닉네임 변경에 실패했습니다", "잠시 후 다시 시도해주세요."); + } + }; + + return ( + + + + + + 아바타 닉네임 변경 + + + + + + + + + + + + + + + + void handleSubmit()} + disabled={!isButtonEnabled} + activeOpacity={0.85} + > + + {updateAvatarNickname.isPending ? "처리 중..." : "확인"} + + + + + ); +} + +const styles = StyleSheet.create({ + safeArea: { + flex: 1, + backgroundColor: "#FFFFFF", + }, + header: { + height: 56, + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + paddingHorizontal: 13, + borderBottomWidth: 1, + borderBottomColor: "#EFEFEF", + }, + backButton: { + width: 44, + height: 44, + justifyContent: "center", + }, + headerTitle: { + fontSize: 18, + fontWeight: "600", + color: "#171717", + }, + content: { + flex: 1, + alignItems: "center", + justifyContent: "center", + gap: 16, + paddingHorizontal: 20, + }, + avatarCard: { + width: 258, + height: 292, + borderRadius: 12, + borderWidth: 2, + borderColor: "#72D14E", + backgroundColor: "#EEF9EA", + overflow: "hidden", + }, + avatarImage: { + width: "100%", + height: "100%", + }, + inputRow: { + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + height: 60, + paddingHorizontal: 16, + borderWidth: 1, + borderColor: "#171717", + borderRadius: 8, + width: "100%", + }, + input: { + flex: 1, + fontSize: 16, + color: "#171717", + paddingVertical: 0, + }, + footer: { + paddingHorizontal: 20, + paddingBottom: 16, + }, + button: { + height: 56, + borderRadius: 8, + alignItems: "center", + justifyContent: "center", + }, + buttonActive: { + backgroundColor: "#72D14E", + }, + buttonDisabled: { + backgroundColor: "#EFEFEF", + }, + buttonText: { + fontSize: 18, + fontWeight: "600", + color: "#FFFFFF", + }, + buttonTextDisabled: { + color: "#BFBFBF", + }, +}); diff --git a/src/pages/option/PolicyScreen.tsx b/src/pages/option/PolicyScreen.tsx index 083d587..2902449 100644 --- a/src/pages/option/PolicyScreen.tsx +++ b/src/pages/option/PolicyScreen.tsx @@ -1,38 +1,30 @@ import { ScrollView, StyleSheet, Text, TouchableOpacity, View } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; import type { RootStackScreenProps } from "@/navigation/types"; -import StatusView from "@/components/common/StatusView"; import { usePolicy } from "@/hooks/option/usePolicyApi"; type Props = RootStackScreenProps<"Policy">; +const POLICY_TEXT = `제1조 (목적) +이 약관은 나풀나풀이가 제공하는 반려식물 아바타 키우기 서비스(이하 "서비스")의 이용과 관련하여 회사와 회원 간의 권리, 의무 및 책임 사항을 규정함을 목적으로 합니다. + +제2조 (정의) +"회원"이라 함은 본 약관에 동의하고 회사가 제공하는 서비스를 이용하는 자를 말합니다. +"아바타 식물"이라 함은 회원이 앱 내에서 돌보고 성장시키는 가상의 식물을 의미합니다. +"콘텐츠"라 함은 서비스 내에서 제공되는 이미지, 텍스트, 데이터 등을 말합니다. + +제3조 (약관의 효력 및 변경) +본 약관은 회원이 동의함과 동시에 효력이 발생합니다. +회사는 필요 시 관련 법령을 위배하지 않는 범위 내에서 약관을 변경할 수 있습니다.`; + export default function PolicyScreen({ navigation }: Props) { - const { data, isLoading, error, refetch } = usePolicy(); + const { data } = usePolicy(); + const policyText = data?.trim() ? data : POLICY_TEXT; const handleBack = () => { navigation.goBack(); }; - if (isLoading) { - return ( - - - - ); - } - - if (error || !data) { - return ( - - void refetch()} - /> - - ); - } - return ( @@ -45,12 +37,7 @@ export default function PolicyScreen({ navigation }: Props) { - - {/* 한글 주석: - 약관 API는 현재 문자열 본문 하나를 내려주기 때문에, - 프론트에서는 스크롤 가능한 읽기 화면으로만 단순하게 구성한다. */} - {data} - + {policyText} diff --git a/src/pages/option/UserNicknameEditScreen.tsx b/src/pages/option/UserNicknameEditScreen.tsx index 4b5b2b7..603ff5c 100644 --- a/src/pages/option/UserNicknameEditScreen.tsx +++ b/src/pages/option/UserNicknameEditScreen.tsx @@ -1,10 +1,9 @@ -import { useMemo, useState } from "react"; -import { Alert, ScrollView, StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import { useState } from "react"; +import { Alert, StyleSheet, Text, TextInput, TouchableOpacity, View } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; import type { RootStackScreenProps } from "@/navigation/types"; -import RegistrationFooter from "@/components/registration/RegistrationFooter"; -import RegistrationTextField from "@/components/registration/RegistrationTextField"; import StatusView from "@/components/common/StatusView"; +import { LeftIcon } from "@/assets/icons/CommonIcons"; import { useUpdateMyNickname, useUserProfile } from "@/hooks/profile/useProfileApi"; import useTokenStore from "@/stores/useTokenStore"; @@ -20,28 +19,14 @@ export default function UserNicknameEditScreen({ navigation }: Props) { const trimmedNickname = nickname.trim(); const isValidNickname = trimmedNickname.length >= 2 && trimmedNickname.length <= 10; const isChanged = trimmedNickname.length > 0 && trimmedNickname !== (data?.userNickname ?? ""); - - const helperText = useMemo(() => { - if (trimmedNickname.length === 0) { - return "프로필과 방명록에 표시될 이름입니다."; - } - if (trimmedNickname.length < 2) { - return "닉네임은 2자 이상이어야 합니다."; - } - if (trimmedNickname.length > 10) { - return "닉네임은 10자 이하로 입력해주세요."; - } - return "저장하면 프로필, 피드, 방명록에 새 이름이 반영됩니다."; - }, [trimmedNickname]); + const isButtonEnabled = isValidNickname && isChanged && !updateNickname.isPending; const handleBack = () => { navigation.goBack(); }; const handleSubmit = async () => { - if (!isValidNickname || !isChanged || updateNickname.isPending) { - return; - } + if (!isButtonEnabled) return; try { await updateNickname.mutateAsync(trimmedNickname); @@ -72,42 +57,42 @@ export default function UserNicknameEditScreen({ navigation }: Props) { } return ( - + - - 뒤로 + + 유저 닉네임 변경 - + - - - 설정 - 보여질 이름을 수정합니다. - - {/* 한글 주석: - 설정 메뉴에서 바꾸는 유저 닉네임은 프로필 이름뿐 아니라 - 피드 작성자명과 방명록 작성자명에도 함께 쓰이는 공통 이름이다. */} - 현재 닉네임을 바꾸면 프로필과 소셜 영역 전반에 같은 이름으로 반영됩니다. - + + 변경할 닉네임을 입력해주세요 + + + 최대 10자 + - - - - void handleSubmit()} - primaryDisabled={!isValidNickname || !isChanged || updateNickname.isPending} - primaryLoading={updateNickname.isPending} - /> + + void handleSubmit()} + disabled={!isButtonEnabled} + activeOpacity={0.85} + > + + {updateNickname.isPending ? "처리 중..." : "확인"} + + + ); } @@ -115,56 +100,87 @@ export default function UserNicknameEditScreen({ navigation }: Props) { const styles = StyleSheet.create({ safeArea: { flex: 1, - backgroundColor: "#F7F8F4", + backgroundColor: "#FFFFFF", }, header: { height: 56, flexDirection: "row", alignItems: "center", justifyContent: "space-between", - paddingHorizontal: 16, - backgroundColor: "#FFFFFF", - borderBottomWidth: StyleSheet.hairlineWidth, - borderBottomColor: "#E5E7EB", + paddingHorizontal: 13, + borderBottomWidth: 1, + borderBottomColor: "#EFEFEF", }, - sideButton: { - width: 56, + backButton: { + width: 44, height: 44, justifyContent: "center", }, - backText: { - fontSize: 14, - fontWeight: "600", - color: "#374151", - }, headerTitle: { - fontSize: 17, - fontWeight: "700", + fontSize: 18, + fontWeight: "600", color: "#171717", }, content: { - padding: 20, - gap: 18, - }, - heroCard: { - borderRadius: 22, - padding: 20, - backgroundColor: "#234A2F", - gap: 8, - }, - eyebrow: { - fontSize: 12, - color: "#D7E9D8", - }, - heroTitle: { - fontSize: 24, - lineHeight: 32, - fontWeight: "700", - color: "#FFFFFF", + paddingHorizontal: 20, + paddingTop: 32, + gap: 24, }, - heroDescription: { + title: { + fontSize: 20, + fontWeight: "600", + color: "#171717", + lineHeight: 28, + }, + inputRow: { + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + height: 60, + paddingHorizontal: 16, + borderWidth: 1, + borderColor: "#BFBFBF", + borderRadius: 8, + }, + input: { + flex: 1, + fontSize: 16, + color: "#171717", + paddingVertical: 0, + }, + maxLength: { fontSize: 14, - lineHeight: 20, - color: "#E5F4E5", + color: "#7C7C7C", + marginLeft: 8, + }, + footer: { + position: "absolute", + bottom: 0, + left: 0, + right: 0, + paddingHorizontal: 20, + paddingBottom: 34, + }, + button: { + height: 56, + borderRadius: 8, + alignItems: "center", + justifyContent: "center", + }, + buttonActive: { + backgroundColor: "#2F7D32", + }, + buttonDisabled: { + backgroundColor: "#EFEFEF", + }, + buttonText: { + fontSize: 18, + fontWeight: "600", + }, + buttonTextActive: { + color: "#FFFFFF", + }, + buttonTextDisabled: { + color: "#BFBFBF", }, }); diff --git a/src/pages/profile/ProfileScreen.tsx b/src/pages/profile/ProfileScreen.tsx index 1b949bc..35cd641 100644 --- a/src/pages/profile/ProfileScreen.tsx +++ b/src/pages/profile/ProfileScreen.tsx @@ -1,423 +1,1014 @@ -import { useEffect, useMemo, useRef, useState } from "react"; -import { - Image, - ScrollView, - StyleSheet, - Text, - TouchableOpacity, - View, -} from "react-native"; -import type { AxiosError } from "axios"; -import PagerView from "react-native-pager-view"; -import { SafeAreaView } from "react-native-safe-area-context"; -import type { RootStackScreenProps } from "@/navigation/types"; -import StatusView from "@/components/common/StatusView"; -import HomeToast from "@/components/home/HomeToast"; -import ProfileGardenScene from "@/components/profile/ProfileGardenScene"; -import { useFriendWater, useUserProfile } from "@/hooks/profile/useProfileApi"; -import { useFollowUser, useUnfollowUser } from "@/hooks/follow/useFollowApi"; -import useTokenStore from "@/stores/useTokenStore"; -import { createTimingLogger } from "@/utils/debug"; -import { FollowStatus } from "@/types/profile/profileApi.type"; - -type Props = RootStackScreenProps<"Profile">; - -const FRIEND_WATER_ACTION_COOLDOWN_MS = 700; - -const backgrounds = [ - require("@/assets/images/background/background1.webp"), - require("@/assets/images/background/background2.webp"), - require("@/assets/images/background/background3.png"), - require("@/assets/images/background/background4.webp"), -] as const; - -export default function ProfileScreen({ navigation, route }: Props) { - const { userId: myUserId } = useTokenStore(); - const userId = route.params.userId; - const { data, error, isLoading, refetch } = useUserProfile(userId); - const waterMutation = useFriendWater(userId); - const followMutation = useFollowUser(myUserId); - const unfollowMutation = useUnfollowUser(myUserId); - const [currentPage, setCurrentPage] = useState(0); - const [wateringGardenId, setWateringGardenId] = useState(null); - const [isFriendWaterCooldownActive, setIsFriendWaterCooldownActive] = useState(false); - const [toastMessage, setToastMessage] = useState(null); - const initialLoadTimingRef = useRef | null>(null); - - const isMe = String(userId) === myUserId; - - useEffect(() => { - initialLoadTimingRef.current = createTimingLogger("ProfileScreen", "initial profile load", { userId }); - }, [userId]); - - useEffect(() => { - if (!data || !initialLoadTimingRef.current) { - return; - } - - initialLoadTimingRef.current({ gardenCount: data.userGardens.length }); - initialLoadTimingRef.current = null; - }, [data]); - - const handleBack = () => { - if (navigation.canGoBack()) { - navigation.goBack(); - return; - } - - navigation.navigate("Main", { screen: "Feed" }); - }; - - const handleOpenGuestbook = () => { - navigation.navigate("Guestbook", { - userId, - userNickname: data?.userNickname, - }); - }; - - const handleFriendWater = async (gardenId: number) => { - try { - await waterMutation.mutateAsync(gardenId); - - // Show a short overlay and toast so the success state is obvious. - setWateringGardenId(gardenId); - setToastMessage("\uce5c\uad6c \uc815\uc6d0\uc5d0 \ubb3c\uc744 \uc8fc\uc5c8\uc2b5\ub2c8\ub2e4."); - setTimeout(() => { - setWateringGardenId(prev => (prev === gardenId ? null : prev)); - }, 1000); - } catch (error) { - const axiosError = error as AxiosError<{ message?: string }>; - setToastMessage( - axiosError.response?.data?.message ?? "\uce5c\uad6c \ubb3c\uc8fc\uae30\uc5d0 \uc2e4\ud328\ud588\uc2b5\ub2c8\ub2e4." - ); - } - }; - - const followAction = useMemo(() => { - if (!data || isMe) return null; - - switch (data.followStatus) { - case FollowStatus.NOT_FOLLOWING: - return { - label: "친구 추가", - onPress: () => void followMutation.mutateAsync(userId), - pending: followMutation.isPending, - }; - case FollowStatus.FOLLOW_BACK_POSSIBLE: - return { - label: "맞팔로우", - onPress: () => void followMutation.mutateAsync(userId), - pending: followMutation.isPending, - }; - case FollowStatus.FOLLOWING: - return { - label: "언팔로우", - onPress: () => void unfollowMutation.mutateAsync(userId), - pending: unfollowMutation.isPending, - }; - default: - return null; - } - }, [data, followMutation, unfollowMutation, userId, isMe]); - - if (isLoading) { - return ( - - - - ); - } - - if (error) { - return ( - - void refetch()} - /> - - ); - } - - if (!data) { - return ( - - - - ); - } - - const scenes = data.userGardens.map((garden, index) => ({ - key: `profile-garden-${garden.gardenId}`, - background: backgrounds[index % backgrounds.length], - garden, - })); - - const renderProfileHeader = () => ( - - {/* 한글 주석: - 프로필 화면의 상단은 방명록 화면과 톤을 맞춘 박스형 헤더로 분리해서, - 뒤로가기/프로필/친구추가 역할이 정원 씬 위에 명확하게 보이도록 정리한다. */} - - - 뒤로 - - - 프로필 - - - {followAction ? ( - - - {followAction.pending ? "처리 중..." : followAction.label} - - - ) : isMe ? ( - 내 프로필 - ) : null} - - - - ); - - if (scenes.length === 0) { - return ( - - {renderProfileHeader()} - - - - - {data.profileImageUrl ? ( - - ) : null} - - {data.userNickname} - - - - 정원 정보가 없습니다. - - 현재 API 기준으로 표시할 정원 데이터가 없어 기본 정보만 표시합니다. - - - - - - ); - } - - return ( - - setCurrentPage(event.nativeEvent.position)} - > - {scenes.map(scene => ( - - {/* 한글 주석: - 타인 프로필은 홈처럼 정원 중심 화면을 쓰되, - 정원 개수는 해금된 userGardens 길이만큼만 페이지를 만든다. */} - void handleFriendWater(scene.garden.gardenId)} - onPressGuestbook={handleOpenGuestbook} - waterDisabled={waterMutation.isPending || isFriendWaterCooldownActive} - /> - - ))} - - - {renderProfileHeader()} - - - - {scenes.map((scene, index) => ( - - ))} - - - - {toastMessage ? ( - setToastMessage(null)} /> - ) : null} - - ); -} - -const styles = StyleSheet.create({ - container: { - flex: 1, - backgroundColor: "#F4F7F0", - }, - sceneContainer: { - flex: 1, - backgroundColor: "#DDE8D6", - }, - pager: { - flex: 1, - }, - page: { - flex: 1, - }, - headerSafeArea: { - position: "absolute", - top: 0, - left: 0, - right: 0, - }, - headerCard: { - marginHorizontal: 16, - marginTop: 8, - minHeight: 56, - borderRadius: 18, - backgroundColor: "rgba(255,255,255,0.96)", - flexDirection: "row", - alignItems: "center", - paddingHorizontal: 12, - shadowColor: "#000", - shadowOffset: { width: 0, height: 2 }, - shadowOpacity: 0.08, - shadowRadius: 10, - elevation: 3, - }, - headerSideButton: { - width: 56, - minHeight: 44, - justifyContent: "center", - }, - headerBackText: { - fontSize: 14, - fontWeight: "600", - color: "#374151", - }, - headerTitle: { - flex: 1, - textAlign: "center", - fontSize: 18, - fontWeight: "700", - color: "#171717", - }, - headerActionWrap: { - minWidth: 72, - alignItems: "flex-end", - }, - followButton: { - borderRadius: 12, - backgroundColor: "#E9F6EA", - paddingHorizontal: 12, - paddingVertical: 8, - }, - followButtonText: { - fontSize: 13, - fontWeight: "700", - color: "#2F7D32", - }, - selfBadgeText: { - fontSize: 13, - fontWeight: "600", - color: "#6B7280", - }, - overlaySafeArea: { - position: "absolute", - top: 0, - left: 0, - right: 0, - }, - pagination: { - marginTop: 86, - alignSelf: "center", - flexDirection: "row", - alignItems: "center", - gap: 8, - }, - dot: { - width: 8, - height: 8, - borderRadius: 999, - }, - dotActive: { - width: 22, - backgroundColor: "#FFFFFF", - }, - dotInactive: { - backgroundColor: "rgba(255,255,255,0.45)", - }, - emptyContainer: { - flex: 1, - backgroundColor: "#FFFFFF", - }, - emptyScrollSafeArea: { - flex: 1, - }, - emptyScrollContent: { - paddingTop: 104, - paddingBottom: 28, - }, - summaryRow: { - flexDirection: "row", - alignItems: "center", - paddingHorizontal: 20, - paddingVertical: 14, - gap: 10, - }, - profileImageWrap: { - width: 40, - height: 40, - borderRadius: 20, - backgroundColor: "#E5E7EB", - overflow: "hidden", - }, - profileImage: { - width: "100%", - height: "100%", - }, - nickname: { - flex: 1, - fontSize: 16, - fontWeight: "600", - color: "#171717", - }, - emptyGardenWrap: { - paddingHorizontal: 20, - paddingVertical: 28, - gap: 6, - }, - emptyGardenTitle: { - fontSize: 16, - fontWeight: "700", - color: "#171717", - }, - emptyGardenDescription: { - fontSize: 14, - lineHeight: 20, - color: "#6B7280", - }, -}); +import { useEffect, useMemo, useRef, useState } from "react"; + +import { + + Image, + + ScrollView, + + StyleSheet, + + Text, + + TouchableOpacity, + + View, + +} from "react-native"; + +import type { AxiosError } from "axios"; + +import PagerView from "react-native-pager-view"; + +import { SafeAreaView } from "react-native-safe-area-context"; + +import type { RootStackScreenProps } from "@/navigation/types"; + +import StatusView from "@/components/common/StatusView"; + +import HomeToast from "@/components/home/HomeToast"; + +import ProfileGardenScene from "@/components/profile/ProfileGardenScene"; + +import { useFriendWater, useUserProfile } from "@/hooks/profile/useProfileApi"; + +import { useFollowUser } from "@/hooks/follow/useFollowApi"; + +import useTokenStore from "@/stores/useTokenStore"; + +import { createTimingLogger, debugLog } from "@/utils/debug"; + +import { FollowStatus } from "@/types/profile/profileApi.type"; + + + +type Props = RootStackScreenProps<"Profile">; + + + +const FRIEND_WATER_ACTION_COOLDOWN_MS = 700; + + + +const getFriendWaterErrorMessage = ( + + status: number | null | undefined, + + serverMessage: string | null | undefined + +) => { + + if (serverMessage === "팔로우한 사용자만 물 주기가 가능합니다." + + || (status === 403 && serverMessage === "요청에 대한 권한이 없습니다.")) { + + return "친구 추가 후 물을 줄 수 있어요."; + + } + + + + if (serverMessage === "차단된 사용자입니다.") { + + return "차단된 사용자에게는 물을 줄 수 없어요."; + + } + + + + return serverMessage ?? "친구 물주기에 실패했습니다."; + +}; + + + +const backgrounds = [ + + require("@/assets/images/background/background1.webp"), + + require("@/assets/images/background/background2.webp"), + + require("@/assets/images/background/background3.png"), + + require("@/assets/images/background/background4.webp"), + +] as const; + + + +export default function ProfileScreen({ navigation, route }: Props) { + + const { userId: myUserId } = useTokenStore(); + + const userId = route.params.userId; + + const { data, error, isLoading, refetch } = useUserProfile(userId); + + const waterMutation = useFriendWater(userId); + + const followMutation = useFollowUser(myUserId); + + const [currentPage, setCurrentPage] = useState(0); + + const [wateringGardenId, setWateringGardenId] = useState(null); + + const [optimisticallyWateredGardenIds, setOptimisticallyWateredGardenIds] = useState([]); + + const [isFriendWaterCooldownActive, setIsFriendWaterCooldownActive] = useState(false); + + const [toastMessage, setToastMessage] = useState(null); + + const initialLoadTimingRef = useRef | null>(null); + + + + const isMe = String(userId) === myUserId; + + + + useEffect(() => { + + initialLoadTimingRef.current = createTimingLogger("ProfileScreen", "initial profile load", { userId }); + + }, [userId]); + + + + useEffect(() => { + + if (!data || !initialLoadTimingRef.current) { + + return; + + } + + + + initialLoadTimingRef.current({ gardenCount: data.userGardens.length }); + + initialLoadTimingRef.current = null; + + }, [data]); + + + + useEffect(() => { + + if (!data) { + + return; + + } + + + + setOptimisticallyWateredGardenIds(previous => + + previous.filter(gardenId => { + + const garden = data.userGardens.find(item => item.gardenId === gardenId); + + return garden?.isWateringAbleByMe ?? false; + + }) + + ); + + }, [data]); + + + + const handleBack = () => { + + if (navigation.canGoBack()) { + + navigation.goBack(); + + return; + + } + + + + navigation.navigate("Main", { screen: "Feed" }); + + }; + + + + const handleOpenGuestbook = () => { + + navigation.navigate("Guestbook", { + + userId, + + userNickname: data?.userNickname, + + }); + + }; + + + + const handleFriendWater = async (gardenId: number) => { + + if (waterMutation.isPending || isFriendWaterCooldownActive) { + + return; + + } + + + + const finishActionTiming = createTimingLogger("ProfileScreen", "friend water action", { + + userId, + + gardenId, + + }); + + + + setOptimisticallyWateredGardenIds(previous => + + previous.includes(gardenId) ? previous : [...previous, gardenId] + + ); + + setIsFriendWaterCooldownActive(true); + + setWateringGardenId(gardenId); + + setToastMessage("친구 정원에 물을 주었습니다."); + + setTimeout(() => { + + setWateringGardenId(prev => (prev === gardenId ? null : prev)); + + }, 1000); + + setTimeout(() => { + + setIsFriendWaterCooldownActive(false); + + }, FRIEND_WATER_ACTION_COOLDOWN_MS); + + + + try { + + await waterMutation.mutateAsync(gardenId); + + finishActionTiming({ startedImmediately: true }); + + } catch (error) { + + const axiosError = error as AxiosError<{ message?: string }>; + + const status = axiosError.response?.status; + + const serverMessage = axiosError.response?.data?.message; + + + + setOptimisticallyWateredGardenIds(previous => previous.filter(id => id !== gardenId)); + + setIsFriendWaterCooldownActive(false); + + setWateringGardenId(prev => (prev === gardenId ? null : prev)); + + finishActionTiming({ + + startedImmediately: true, + + rolledBack: true, + + status: status ?? null, + + }); + + debugLog("ProfileScreen", "friend water action failed", { + + userId, + + gardenId, + + status: status ?? null, + + serverMessage: serverMessage ?? null, + + }); + + setToastMessage(getFriendWaterErrorMessage(status, serverMessage)); + + } + + }; + + + + const followAction = useMemo(() => { + + if (!data || isMe) return null; + + + + switch (data.followStatus) { + + case FollowStatus.NOT_FOLLOWING: + + return { + + kind: "button" as const, + + label: "친구 추가", + + onPress: () => void followMutation.mutateAsync(userId), + + pending: followMutation.isPending, + + }; + + case FollowStatus.FOLLOW_BACK_POSSIBLE: + + return { + + kind: "button" as const, + + label: "맞팔로우", + + onPress: () => void followMutation.mutateAsync(userId), + + pending: followMutation.isPending, + + }; + + case FollowStatus.FOLLOWING: + + return { + + kind: "badge" as const, + + label: "이미 친구", + + }; + + default: + + return null; + + } + + }, [data, followMutation, userId, isMe]); + + + + if (isLoading) { + + return ( + + + + + + + + ); + + } + + + + if (error) { + + return ( + + + + void refetch()} + + /> + + + + ); + + } + + + + if (!data) { + + return ( + + + + + + + + ); + + } + + + + const scenes = data.userGardens.map((garden, index) => ({ + + key: `profile-garden-${garden.gardenId}`, + + background: backgrounds[index % backgrounds.length], + + garden, + + })); + + + + const renderProfileHeader = () => ( + + + + {/* 한글 주석: + + 프로필 화면의 상단은 방명록 화면과 톤을 맞춘 박스형 헤더로 분리해서, + + 뒤로가기/프로필/친구추가 역할이 정원 씬 위에 명확하게 보이도록 정리한다. */} + + + + + + 뒤로 + + + + + + 프로필 + + + + + + {followAction ? ( + + followAction.kind === "button" ? ( + + + + + + {followAction.pending ? "?? ?..." : followAction.label} + + + + + + ) : ( + + + + {followAction.label} + + + + ) + + ) : isMe ? ( + + ? ??? + + ) : null} + + + + + + + + ); + + + + if (scenes.length === 0) { + + return ( + + + + {renderProfileHeader()} + + + + + + + + + + {data.profileImageUrl ? ( + + + + ) : null} + + + + {data.userNickname} + + + + + + + + 정원 정보가 없습니다. + + + + 현재 API 기준으로 표시할 정원 데이터가 없어 기본 정보만 표시합니다. + + + + + + + + + + + + ); + + } + + + + return ( + + + + setCurrentPage(event.nativeEvent.position)} + + > + + {scenes.map(scene => ( + + + + {/* 한글 주석: + + 타인 프로필은 홈처럼 정원 중심 화면을 쓰되, + + 정원 개수는 해금된 userGardens 길이만큼만 페이지를 만든다. */} + + void handleFriendWater(scene.garden.gardenId)} + + onPressGuestbook={handleOpenGuestbook} + + waterDisabled={ + + waterMutation.isPending || + + isFriendWaterCooldownActive || + + optimisticallyWateredGardenIds.includes(scene.garden.gardenId) + + } + + /> + + + + ))} + + + + + + {renderProfileHeader()} + + + + + + + + {scenes.map((scene, index) => ( + + + + ))} + + + + + + + + {toastMessage ? ( + + setToastMessage(null)} /> + + ) : null} + + + + ); + +} + + + +const styles = StyleSheet.create({ + + container: { + + flex: 1, + + backgroundColor: "#F4F7F0", + + }, + + sceneContainer: { + + flex: 1, + + backgroundColor: "#DDE8D6", + + }, + + pager: { + + flex: 1, + + }, + + page: { + + flex: 1, + + }, + + headerSafeArea: { + + position: "absolute", + + top: 0, + + left: 0, + + right: 0, + + }, + + headerCard: { + + marginHorizontal: 16, + + marginTop: 8, + + minHeight: 56, + + borderRadius: 18, + + backgroundColor: "rgba(255,255,255,0.96)", + + flexDirection: "row", + + alignItems: "center", + + paddingHorizontal: 12, + + shadowColor: "#000", + + shadowOffset: { width: 0, height: 2 }, + + shadowOpacity: 0.08, + + shadowRadius: 10, + + elevation: 3, + + }, + + headerSideButton: { + + width: 56, + + minHeight: 44, + + justifyContent: "center", + + }, + + headerBackText: { + + fontSize: 14, + + fontWeight: "600", + + color: "#374151", + + }, + + headerTitle: { + + flex: 1, + + textAlign: "center", + + fontSize: 18, + + fontWeight: "700", + + color: "#171717", + + }, + + headerActionWrap: { + + minWidth: 72, + + alignItems: "flex-end", + + }, + + followButton: { + + borderRadius: 12, + + backgroundColor: "#E9F6EA", + + paddingHorizontal: 12, + + paddingVertical: 8, + + }, + + followButtonText: { + + fontSize: 13, + + fontWeight: "700", + + color: "#2F7D32", + + }, + + followBadge: { + + borderRadius: 12, + + backgroundColor: "rgba(255,255,255,0.9)", + + borderWidth: 1, + + borderColor: "#D1D5DB", + + paddingHorizontal: 12, + + paddingVertical: 8, + + }, + + followBadgeText: { + + fontSize: 13, + + fontWeight: "700", + + color: "#4B5563", + + }, + + selfBadgeText: { + + fontSize: 13, + + fontWeight: "600", + + color: "#6B7280", + + }, + + overlaySafeArea: { + + position: "absolute", + + top: 0, + + left: 0, + + right: 0, + + }, + + pagination: { + + marginTop: 86, + + alignSelf: "center", + + flexDirection: "row", + + alignItems: "center", + + gap: 8, + + }, + + dot: { + + width: 8, + + height: 8, + + borderRadius: 999, + + }, + + dotActive: { + + width: 22, + + backgroundColor: "#FFFFFF", + + }, + + dotInactive: { + + backgroundColor: "rgba(255,255,255,0.45)", + + }, + + emptyContainer: { + + flex: 1, + + backgroundColor: "#FFFFFF", + + }, + + emptyScrollSafeArea: { + + flex: 1, + + }, + + emptyScrollContent: { + + paddingTop: 104, + + paddingBottom: 28, + + }, + + summaryRow: { + + flexDirection: "row", + + alignItems: "center", + + paddingHorizontal: 20, + + paddingVertical: 14, + + gap: 10, + + }, + + profileImageWrap: { + + width: 40, + + height: 40, + + borderRadius: 20, + + backgroundColor: "#E5E7EB", + + overflow: "hidden", + + }, + + profileImage: { + + width: "100%", + + height: "100%", + + }, + + nickname: { + + flex: 1, + + fontSize: 16, + + fontWeight: "600", + + color: "#171717", + + }, + + emptyGardenWrap: { + + paddingHorizontal: 20, + + paddingVertical: 28, + + gap: 6, + + }, + + emptyGardenTitle: { + + fontSize: 16, + + fontWeight: "700", + + color: "#171717", + + }, + + emptyGardenDescription: { + + fontSize: 14, + + lineHeight: 20, + + color: "#6B7280", + + }, + +}); + From 9b36510cf3afe664ad1998b0c51bcba44fbb0aa7 Mon Sep 17 00:00:00 2001 From: lejuho Date: Tue, 17 Mar 2026 19:24:17 +0900 Subject: [PATCH 81/92] =?UTF-8?q?fix:=20=ED=94=BC=EB=93=9C=EC=99=80=20?= =?UTF-8?q?=ED=8C=94=EB=A1=9C=EC=9A=B0=20=ED=99=94=EB=A9=B4=EC=97=90=20?= =?UTF-8?q?=EC=83=88=EB=A1=9C=EA=B3=A0=EC=B9=A8=20UI=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/ScreenHeader.tsx | 40 +++++++++++---- src/pages/feed/FeedAvatarScreen.tsx | 44 +++++++++++++--- src/pages/feed/FeedDiaryScreen.tsx | 44 +++++++++++++--- src/pages/feed/FeedScreen.tsx | 70 ++++++++++++++++++++------ src/pages/follow/FollowScreen.tsx | 27 +++++++++- 5 files changed, 186 insertions(+), 39 deletions(-) diff --git a/src/components/common/ScreenHeader.tsx b/src/components/common/ScreenHeader.tsx index 0f0206f..7e5e591 100644 --- a/src/components/common/ScreenHeader.tsx +++ b/src/components/common/ScreenHeader.tsx @@ -3,9 +3,21 @@ import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; type Props = { title: string; onBack?: () => void; + rightActionLabel?: string; + onRightAction?: () => void; + rightActionDisabled?: boolean; }; -export default function ScreenHeader({ title, onBack }: Props) { +export default function ScreenHeader({ + title, + onBack, + rightActionLabel, + onRightAction, + rightActionDisabled = false, +}: Props) { + const resolvedRightAction = onRightAction ?? onBack; + const resolvedRightLabel = rightActionLabel ?? "완료"; + return ( {onBack ? ( @@ -20,13 +32,20 @@ export default function ScreenHeader({ title, onBack }: Props) { )} {title} - - 완료 - + {resolvedRightAction ? ( + + + {resolvedRightLabel} + + + ) : ( + + )} ); } @@ -58,9 +77,12 @@ const styles = StyleSheet.create({ color: "#374151", textAlign: "right", }, + disabledText: { + color: "#9CA3AF", + }, title: { fontSize: 17, fontWeight: "600", color: "#171717", }, -}); \ No newline at end of file +}); diff --git a/src/pages/feed/FeedAvatarScreen.tsx b/src/pages/feed/FeedAvatarScreen.tsx index 24990df..425162a 100644 --- a/src/pages/feed/FeedAvatarScreen.tsx +++ b/src/pages/feed/FeedAvatarScreen.tsx @@ -4,6 +4,7 @@ import { FlatList, KeyboardAvoidingView, Platform, + RefreshControl, StyleSheet, Text, View, @@ -34,7 +35,7 @@ export default function FeedAvatarScreen({ navigation, route }: Props) { const id = Number(postId); const isValidId = Number.isFinite(id) && id > 0; - const { data, error, isLoading, refetch } = useAvatarPostDetail(isValidId ? id : 0); + const { data, error, isLoading, isRefetching, refetch } = useAvatarPostDetail(isValidId ? id : 0); const [content, setContent] = useState(""); const initialLoadTimingRef = useRef | null>(null); const { mutateAsync, isPending } = usePostComment(() => refetch()); @@ -101,7 +102,13 @@ export default function FeedAvatarScreen({ navigation, route }: Props) { if (isLoading) { return ( - + void refetch()} + rightActionDisabled={isLoading || isRefetching} + /> ); @@ -110,10 +117,16 @@ export default function FeedAvatarScreen({ navigation, route }: Props) { if (error) { return ( - + void refetch()} + rightActionDisabled={isLoading || isRefetching} + /> void refetch()} /> @@ -124,7 +137,13 @@ export default function FeedAvatarScreen({ navigation, route }: Props) { if (!data) { return ( - + void refetch()} + rightActionDisabled={isLoading || isRefetching} + /> - + void refetch()} + rightActionDisabled={isLoading || isRefetching} + /> item.key} showsVerticalScrollIndicator={false} contentContainerStyle={styles.listContent} + refreshControl={ + void refetch()} + tintColor="#7DC960" + /> + } onEndReached={() => { if (hasNextPage && !isFetchingNextPage) { void fetchNextPage(); diff --git a/src/pages/feed/FeedDiaryScreen.tsx b/src/pages/feed/FeedDiaryScreen.tsx index e2cf15b..737f3d9 100644 --- a/src/pages/feed/FeedDiaryScreen.tsx +++ b/src/pages/feed/FeedDiaryScreen.tsx @@ -4,6 +4,7 @@ import { FlatList, KeyboardAvoidingView, Platform, + RefreshControl, StyleSheet, Text, View, @@ -34,7 +35,7 @@ export default function FeedDiaryScreen({ navigation, route }: Props) { const id = Number(postId); const isValidId = Number.isFinite(id) && id > 0; - const { data, error, isLoading, refetch } = useDiaryDetail(isValidId ? id : 0); + const { data, error, isLoading, isRefetching, refetch } = useDiaryDetail(isValidId ? id : 0); const [content, setContent] = useState(""); const initialLoadTimingRef = useRef | null>(null); const { mutateAsync, isPending } = usePostComment(() => refetch()); @@ -101,7 +102,13 @@ export default function FeedDiaryScreen({ navigation, route }: Props) { if (isLoading) { return ( - + void refetch()} + rightActionDisabled={isLoading || isRefetching} + /> ); @@ -110,10 +117,16 @@ export default function FeedDiaryScreen({ navigation, route }: Props) { if (error) { return ( - + void refetch()} + rightActionDisabled={isLoading || isRefetching} + /> void refetch()} /> @@ -124,7 +137,13 @@ export default function FeedDiaryScreen({ navigation, route }: Props) { if (!data) { return ( - + void refetch()} + rightActionDisabled={isLoading || isRefetching} + /> - + void refetch()} + rightActionDisabled={isLoading || isRefetching} + /> item.key} showsVerticalScrollIndicator={false} contentContainerStyle={styles.listContent} + refreshControl={ + void refetch()} + tintColor="#7DC960" + /> + } onEndReached={() => { if (hasNextPage && !isFetchingNextPage) { void fetchNextPage(); diff --git a/src/pages/feed/FeedScreen.tsx b/src/pages/feed/FeedScreen.tsx index 8343ac8..4d01a0c 100644 --- a/src/pages/feed/FeedScreen.tsx +++ b/src/pages/feed/FeedScreen.tsx @@ -1,5 +1,6 @@ import React from "react"; import { + RefreshControl, View, Text, TouchableOpacity, @@ -10,13 +11,14 @@ import { SafeAreaView } from "react-native-safe-area-context"; import type { MainTabScreenProps } from "@/navigation/types"; import { UserPlusIcon } from "@/assets/icons/CommonIcons"; +import StatusView from "@/components/common/StatusView"; import FeedList from "@/components/feed/FeedList"; import { useFeed } from "@/hooks/feed/useFeedApi"; type Props = MainTabScreenProps<"Feed">; export default function FeedScreen({ navigation }: Props) { - const { data: result, isLoading, error } = useFeed(); + const { data: result, isLoading, isRefetching, error, refetch } = useFeed(); const handleUserPlusClick = () => { navigation.navigate("Follow"); @@ -37,7 +39,16 @@ export default function FeedScreen({ navigation }: Props) { {/* Header spacing is tuned to match the centered title layout from the FE design. */} - + void refetch()} + activeOpacity={0.7} + disabled={isLoading || isRefetching} + > + + 새로고침 + + 둘러보기 - {/* Feed content remains unchanged; only the surrounding layout was tightened. */} - - void refetch()} /> - + ) : ( + void refetch()} + tintColor="#7DC960" + /> + } + > + {/* 한글 주석: + 피드 메인에서는 빈 상태와 로딩 상태를 리스트 컴포넌트가 맡고, + 네트워크 재시도는 상단 버튼과 pull-to-refresh 둘 다 열어 둔다. */} + + + )} ); } @@ -79,14 +108,23 @@ const styles = StyleSheet.create({ paddingLeft: 20, marginBottom: 12, }, - headerSpacer: { - width: 24, - }, headerTitle: { fontSize: 18, fontWeight: "700", color: "#171717", }, + headerTextButton: { + minWidth: 56, + justifyContent: "center", + }, + headerTextButtonLabel: { + fontSize: 14, + fontWeight: "600", + color: "#374151", + }, + headerTextButtonDisabled: { + color: "#9CA3AF", + }, headerButton: { width: 24, alignItems: "center", diff --git a/src/pages/follow/FollowScreen.tsx b/src/pages/follow/FollowScreen.tsx index c5a9b84..b531266 100644 --- a/src/pages/follow/FollowScreen.tsx +++ b/src/pages/follow/FollowScreen.tsx @@ -1,6 +1,7 @@ import { useState } from "react"; import { Image, + RefreshControl, ScrollView, StyleSheet, Text, @@ -30,6 +31,9 @@ export default function FollowScreen({ navigation }: Props) { const unfollowMutation = useUnfollowUser(userId); const isLoading = activeTab === "added" ? followingQuery.isLoading : followersQuery.isLoading; + const isRefetching = activeTab === "added" + ? followingQuery.isRefetching + : followersQuery.isRefetching; const error = activeTab === "added" ? followingQuery.error : followersQuery.error; const users = activeTab === "added" @@ -56,7 +60,13 @@ export default function FollowScreen({ navigation }: Props) { return ( - + {/* Tabs are renamed to match the app copy while still mapping to following/follower queries. */} @@ -98,7 +108,20 @@ export default function FollowScreen({ navigation }: Props) { description="팔로우 데이터가 준비되면 이 화면에서 바로 목록을 볼 수 있습니다." /> ) : ( - + + } + > + {/* 한글 주석: + 팔로우 탭은 활성 탭 쿼리만 다시 읽으면 되므로, + 헤더 새로고침과 pull-to-refresh 모두 같은 handleRetry로 묶는다. */} {users.map(user => ( // The custom row matches the FE design more closely than the previous generic card. From fd70acb793a96bfb73b3f68475b14dcd3d2bb811 Mon Sep 17 00:00:00 2001 From: lejuho Date: Tue, 17 Mar 2026 19:35:59 +0900 Subject: [PATCH 82/92] =?UTF-8?q?fix=20:=20=EC=9D=BC=EA=B8=B0=20=EC=93=B0?= =?UTF-8?q?=EA=B8=B0=20=EB=82=A0=EC=A7=9C=20=ED=85=8D=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=8A=A4=ED=83=80=EC=9D=BC=20=EB=94=94=EC=9E=90=EC=9D=B8=20?= =?UTF-8?q?=EB=B0=98=EC=98=81=20(13px=E2=86=9216px,=20=EC=83=89=EC=83=81?= =?UTF-8?q?=20#282828)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx b/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx index 086a131..55bd48d 100644 --- a/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx +++ b/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx @@ -210,10 +210,9 @@ const styles = StyleSheet.create({ gap: 20, }, dateText: { - fontSize: 13, - color: "#9CA3AF", + fontSize: 16, + color: "#282828", fontWeight: "400", - letterSpacing: 0.2, }, visibilityRow: { flexDirection: "row", From 7113a9cab0f3cec2778dc455d99efa19e76a7d95 Mon Sep 17 00:00:00 2001 From: lejuho Date: Tue, 17 Mar 2026 19:36:50 +0900 Subject: [PATCH 83/92] =?UTF-8?q?fix=20:=20=EC=9D=BC=EA=B8=B0=20=EC=93=B0?= =?UTF-8?q?=EA=B8=B0=20=EC=A0=9C=EB=AA=A9=20=EC=9E=85=EB=A0=A5=20=EC=98=81?= =?UTF-8?q?=EC=97=AD=20=EB=94=94=EC=9E=90=EC=9D=B8=20=EB=B0=98=EC=98=81=20?= =?UTF-8?q?(=EB=82=A0=EC=A7=9C+=EC=A0=9C=EB=AA=A9=20=EC=84=B9=EC=85=98=20?= =?UTF-8?q?=EB=AC=B6=EC=9D=8C,=2024px=20SemiBold)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- .../DailyMissionWriteDiaryScreen.tsx | 36 ++++++++++++++----- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx b/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx index 55bd48d..36ea7f5 100644 --- a/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx +++ b/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx @@ -1,5 +1,5 @@ import * as ImagePicker from "expo-image-picker"; -import { Alert, ScrollView, StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import { Alert, ScrollView, StyleSheet, Text, TextInput, TouchableOpacity, View } from "react-native"; import { useQueryClient } from "@tanstack/react-query"; import { useState } from "react"; import { SafeAreaView } from "react-native-safe-area-context"; @@ -124,14 +124,17 @@ export default function DailyMissionWriteDiaryScreen({ navigation }: Props) { - {today} - - + {/* 날짜 + 제목 섹션 (하단 구분선으로 묶음) */} + + {today} + + Date: Tue, 17 Mar 2026 19:42:46 +0900 Subject: [PATCH 84/92] =?UTF-8?q?feat=20:=20=EC=9D=BC=EA=B8=B0=20=EC=93=B0?= =?UTF-8?q?=EA=B8=B0=20=ED=99=94=EB=A9=B4=20=ED=94=BC=EA=B7=B8=EB=A7=88=20?= =?UTF-8?q?=EB=94=94=EC=9E=90=EC=9D=B8=20=EC=A0=84=EB=A9=B4=20=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 배경 흰색(#FFFFFF), 헤더 완료 버튼 이동 및 하단 footer 제거 - 본문 입력 플레인 TextInput 교체, AI 힌트 문구 하드코딩 추가 - 공개여부 텍스트 항상 검정, 아이콘 크기 24px - ScreenHeader: 높이 56px, 타이틀 18px SemiBold, 완료 Regular/#171717, 구분선 #EFEFEF - ImageAttachmentCard: 이미지 높이 353px, 텍스트 14px/#7C7C7C Co-Authored-By: Claude Sonnet 4.6 --- src/components/common/ScreenHeader.tsx | 23 ++-- .../dailyMission/ImageAttachmentCard.tsx | 32 +++-- .../DailyMissionWriteDiaryScreen.tsx | 123 +++++++++++------- 3 files changed, 108 insertions(+), 70 deletions(-) diff --git a/src/components/common/ScreenHeader.tsx b/src/components/common/ScreenHeader.tsx index 7e5e591..12f5f04 100644 --- a/src/components/common/ScreenHeader.tsx +++ b/src/components/common/ScreenHeader.tsx @@ -20,6 +20,7 @@ export default function ScreenHeader({ return ( + {/* 왼쪽: 닫기(X) 버튼 */} {onBack ? ( )} + + {/* 중앙: 화면 타이틀 */} {title} + + {/* 오른쪽: 완료 텍스트 버튼 */} {resolvedRightAction ? ( {imageUrl ? ( + // 선택된 이미지 미리보기 ) : ( + // 이미지 미선택 안내 플레이스홀더 📷 - 화분을 예쁘게 가꾸고 - - 친구들에게 멋진 식물을 자랑해보아요! - + + 화분을 예쁘게 가꾸고 + 친구들에게 멋진 식물을 자랑해보아요! + )} @@ -55,25 +57,31 @@ const styles = StyleSheet.create({ imageAreaDisabled: { opacity: 0.6, }, + // 이미지 높이 353px (피그마 기준) previewImage: { width: "100%", - height: 260, + height: 353, }, placeholderBox: { - height: 260, + height: 353, alignItems: "center", justifyContent: "center", - gap: 8, + gap: 4, }, cameraIcon: { fontSize: 32, - marginBottom: 4, opacity: 0.45, }, + // 플레이스홀더 텍스트 묶음 + placeholderTextGroup: { + alignItems: "center", + gap: 0, + }, + // 플레이스홀더 텍스트: 14px #7C7C7C placeholderText: { - fontSize: 13, - color: "#9CA3AF", - lineHeight: 20, + fontSize: 14, + color: "#7C7C7C", + lineHeight: 14 * 1.6, textAlign: "center", }, helperText: { @@ -82,4 +90,4 @@ const styles = StyleSheet.create({ color: "#92400E", paddingHorizontal: 4, }, -}); \ No newline at end of file +}); diff --git a/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx b/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx index 36ea7f5..b445b24 100644 --- a/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx +++ b/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx @@ -7,13 +7,15 @@ import ScreenHeader from "@/components/common/ScreenHeader"; import CheckIcon from "@/assets/icons/Check.svg"; import Check2Icon from "@/assets/icons/Check2.svg"; import ImageAttachmentCard from "@/components/dailyMission/ImageAttachmentCard"; -import RegistrationFooter from "@/components/registration/RegistrationFooter"; -import RegistrationTextField from "@/components/registration/RegistrationTextField"; import { useWriteDiaryImageUpload, useWriteDiarySubmit } from "@/hooks/mission/useMissionApi"; import type { RootStackScreenProps } from "@/navigation/types"; type Props = RootStackScreenProps<"DailyMissionWriteDiary">; +// 임시 하드코딩 힌트 문구 (추후 백엔드 API 연결 예정) +const HINT_KEYWORD = "내 식물의 겨울나기"; +const HINT_SUFFIX = "에 대해서\n이야기해보는 건 어때요?"; + export default function DailyMissionWriteDiaryScreen({ navigation }: Props) { const queryClient = useQueryClient(); const [title, setTitle] = useState(""); @@ -28,12 +30,14 @@ export default function DailyMissionWriteDiaryScreen({ navigation }: Props) { const uploadDiaryImage = useWriteDiaryImageUpload(); const submitDiary = useWriteDiarySubmit(); + // 홈 화면으로 초기화 이동 const goHome = () => navigation.reset({ index: 0, routes: [{ name: "Main", params: { screen: "Home" } }], }); + // 갤러리에서 이미지 선택 후 서버 업로드 const handlePickImage = async () => { if (!permissionRequested) { const permission = await ImagePicker.requestMediaLibraryPermissionsAsync(); @@ -81,6 +85,7 @@ export default function DailyMissionWriteDiaryScreen({ navigation }: Props) { } }; + // 일기 저장 후 관련 쿼리 무효화 및 홈 이동 const handleSubmit = async () => { if (!title.trim() || !content.trim()) { return; @@ -100,9 +105,6 @@ export default function DailyMissionWriteDiaryScreen({ navigation }: Props) { imageUrl: uploadedImage.imageUrl, }); - /* - * Invalidate related queries so home and log reflect the new diary immediately. - */ await queryClient.invalidateQueries({ queryKey: ["home-summary"] }); await queryClient.invalidateQueries({ queryKey: ["calendar"] }); await queryClient.invalidateQueries({ queryKey: ["diaries"] }); @@ -113,6 +115,13 @@ export default function DailyMissionWriteDiaryScreen({ navigation }: Props) { } }; + const isSubmitDisabled = + !title.trim() || + !content.trim() || + !uploadedImage || + uploadDiaryImage.isPending || + submitDiary.isPending; + const today = new Date().toLocaleDateString("ko-KR", { year: "numeric", month: "long", @@ -121,7 +130,13 @@ export default function DailyMissionWriteDiaryScreen({ navigation }: Props) { return ( - + {/* 헤더: X 닫기 + 완료 제출 버튼 */} + void handleSubmit()} + rightActionDisabled={isSubmitDisabled} + /> {/* 날짜 + 제목 섹션 (하단 구분선으로 묶음) */} @@ -136,6 +151,7 @@ export default function DailyMissionWriteDiaryScreen({ navigation }: Props) { /> + {/* 이미지 첨부 카드 */} void handlePickImage()} @@ -148,26 +164,32 @@ export default function DailyMissionWriteDiaryScreen({ navigation }: Props) { } /> - + {/* AI 글쓰기 힌트 문구 (추후 백엔드 API 연결 예정) */} + + {HINT_KEYWORD} + {HINT_SUFFIX} + + + {/* 공개 여부 선택 */} setIsPublic(false)} activeOpacity={0.7} > - - {!isPublic ? : } - - - {"나만 보기"} - + {!isPublic ? : } + 나만 보기 setIsPublic(true)} activeOpacity={0.7} > - - {isPublic ? : } - - - {"공개하기"} - + {isPublic ? : } + 공개하기 - - void handleSubmit()} - primaryDisabled={ - !title.trim() || - !content.trim() || - !uploadedImage || - uploadDiaryImage.isPending || - submitDiary.isPending - } - primaryLoading={submitDiary.isPending} - /> ); } const styles = StyleSheet.create({ + // 전체 배경 흰색 safeArea: { flex: 1, - backgroundColor: "#F7F8F4", + backgroundColor: "#FFFFFF", }, content: { paddingHorizontal: 20, - paddingTop: 20, + paddingTop: 24, paddingBottom: 32, - gap: 20, + gap: 24, }, // 날짜 + 제목 묶음 섹션 titleSection: { @@ -219,23 +225,49 @@ const styles = StyleSheet.create({ borderBottomWidth: 1, borderBottomColor: "#EFEFEF", }, + // 날짜 텍스트 dateText: { fontSize: 16, color: "#282828", fontWeight: "400", + lineHeight: 16 * 1.6, }, - // 제목 입력 필드 (박스 없이 큰 텍스트 스타일) + // 제목 입력 (박스 없이 큰 텍스트) titleInput: { fontSize: 24, fontWeight: "600", color: "#171717", + lineHeight: 24 * 1.35, + paddingVertical: 0, + paddingHorizontal: 0, + }, + // 본문 입력 (플레인 멀티라인) + contentInput: { + fontSize: 16, + fontWeight: "400", + color: "#171717", + lineHeight: 16 * 1.6, + minHeight: 80, paddingVertical: 0, paddingHorizontal: 0, }, + // AI 힌트 문구 영역 + hintText: { + fontSize: 16, + fontWeight: "400", + color: "#9B9B9B", + lineHeight: 16 * 1.6, + }, + // 힌트 키워드 강조 (SemiBold 18px) + hintKeyword: { + fontSize: 18, + fontWeight: "600", + color: "#9B9B9B", + }, + // 공개 여부 선택 행 visibilityRow: { flexDirection: "row", - gap: 24, - paddingTop: 4, + gap: 16, paddingBottom: 8, }, visibilityOption: { @@ -243,20 +275,11 @@ const styles = StyleSheet.create({ alignItems: "center", gap: 8, }, - radioCircle: { - width: 22, - height: 22, - alignItems: "center", - justifyContent: "center", - }, - radioCircleSelected: {}, + // 공개 여부 텍스트 (선택 여부 무관 검정) visibilityLabel: { fontSize: 14, - color: "#9CA3AF", fontWeight: "400", - }, - visibilityLabelSelected: { color: "#171717", - fontWeight: "500", + lineHeight: 14 * 1.6, }, }); From ee1a31bd30ce17f184149455cfa32a2bcb56ac9c Mon Sep 17 00:00:00 2001 From: lejuho Date: Fri, 27 Mar 2026 14:33:00 +0900 Subject: [PATCH 85/92] =?UTF-8?q?chore=20:=20=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=EC=A1=B0=EC=A0=95=20=EB=B0=8F=20api=20=EC=97=B0=EA=B2=B0,?= =?UTF-8?q?=EC=B5=9C=EC=A0=81=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .claude/settings.local.json | 5 +- App.tsx | 11 + app.json | 9 +- package-lock.json | 440 ++++- package.json | 2 + sometips.md | 290 +++ src/apis/block/blockApi.ts | 22 + src/apis/comments/commentApi.ts | 5 + src/apis/option/notificationApi.ts | 24 + src/apis/report/reportApi.ts | 10 + src/assets/icons/CommonIcons.tsx | 36 + src/components/common/Comment.tsx | 31 +- src/components/common/ScreenHeader.tsx | 31 +- .../dailyMission/OxQuizOptionCard.tsx | 76 + src/components/feed/FeedAvatarDetailCard.tsx | 78 +- src/components/feed/FeedDetail.tsx | 184 +- src/components/feed/FeedDiaryDetailCard.tsx | 78 +- src/components/feed/FeedSeedDetailCard.tsx | 88 +- src/components/profile/ProfileGardenScene.tsx | 59 +- src/hooks/block/useBlockApi.ts | 24 + src/hooks/comments/useCommentApi.ts | 110 +- src/hooks/follow/useFollowApi.ts | 36 +- src/hooks/home/useHomeApi.ts | 4 + src/hooks/mission/useMissionApi.ts | 31 +- src/hooks/option/useNotificationApi.ts | 39 + src/hooks/profile/useGuestbookApi.ts | 28 +- src/hooks/report/useReportApi.ts | 10 + src/navigation/RootNavigator.tsx | 14 +- src/navigation/types.ts | 39 +- .../dailyMission/DailyMissionQuizOxScreen.tsx | 210 ++- src/pages/delivery/DeliveryCompleteScreen.tsx | 125 +- src/pages/delivery/DeliveryScreen.tsx | 245 ++- src/pages/delivery/UnlockGardenScreen.tsx | 362 ++-- src/pages/feed/FeedScreen.tsx | 69 +- src/pages/follow/FollowScreen.tsx | 25 +- src/pages/home/HomeScreen.tsx | 35 +- src/pages/log/LogScreen.tsx | 20 +- src/pages/option/OptionScreen.tsx | 10 +- src/pages/profile/ProfileScreen.tsx | 1550 ++++++----------- .../registration/RegistrationAvatarScreen.tsx | 204 ++- .../RegistrationCreationCompleteScreen.tsx | 92 + .../RegistrationCreationDetailScreen.tsx | 155 +- .../RegistrationCreationPendingScreen.tsx | 122 ++ .../RegistrationPlantNicknameScreen.tsx | 236 ++- .../RegistrationSelectionDetailScreen.tsx | 15 +- src/types/comments/commentApi.type.ts | 1 + src/types/feed/avatarPostDetailApi.type.ts | 1 + src/types/feed/detail.ts | 1 + src/types/log/diaryDetailApi.type.ts | 1 + src/types/report/index.ts | 8 + src/utils/fcm.ts | 47 + 51 files changed, 3397 insertions(+), 1951 deletions(-) create mode 100644 sometips.md create mode 100644 src/apis/block/blockApi.ts create mode 100644 src/apis/option/notificationApi.ts create mode 100644 src/apis/report/reportApi.ts create mode 100644 src/components/dailyMission/OxQuizOptionCard.tsx create mode 100644 src/hooks/block/useBlockApi.ts create mode 100644 src/hooks/option/useNotificationApi.ts create mode 100644 src/hooks/report/useReportApi.ts create mode 100644 src/pages/registration/RegistrationCreationCompleteScreen.tsx create mode 100644 src/pages/registration/RegistrationCreationPendingScreen.tsx create mode 100644 src/types/report/index.ts create mode 100644 src/utils/fcm.ts diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 419f0f0..efab5a6 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -12,7 +12,10 @@ "mcp__figma-desktop__get_screenshot", "mcp__plugin_figma_figma__get_screenshot", "Bash(git add:*)", - "Bash(git commit:*)" + "Bash(git commit:*)", + "Read(//c/MainBE/**)", + "Bash(xargs grep:*)", + "Bash(head -20 grep -n \"usePostComment\\\\|useDeleteComment\\\\|refetch\\\\|comments\" c:/MainAPP/src/pages/feed/FeedAvatarScreen.tsx)" ] } } diff --git a/App.tsx b/App.tsx index 8265138..4a84780 100644 --- a/App.tsx +++ b/App.tsx @@ -16,15 +16,26 @@ import { isSupabaseConfigured, } from "@/apis/supabase"; import { debugLog } from "@/utils/debug"; +import useTokenStore from "@/stores/useTokenStore"; +import { registerDeviceFcmToken } from "@/utils/fcm"; export default function App() { const navigationRef = useNavigationContainerRef(); const currentRouteNameRef = useRef(undefined); + const { accessToken } = useTokenStore(); + const fcmRegisteredRef = useRef(false); useEffect(() => { debugLog("App", "App mounted", { isSupabaseConfigured }); }, []); + // 로그인 상태가 되면 FCM 토큰을 서버에 등록 (세션당 1회) + useEffect(() => { + if (!accessToken || fcmRegisteredRef.current) return; + fcmRegisteredRef.current = true; + void registerDeviceFcmToken(); + }, [accessToken]); + if (!isSupabaseConfigured) { return ( diff --git a/app.json b/app.json index 702577c..dd991cd 100644 --- a/app.json +++ b/app.json @@ -31,7 +31,14 @@ "plugins": [ "expo-dev-client", "expo-secure-store", - "expo-web-browser" + "expo-web-browser", + [ + "expo-notifications", + { + "icon": "./assets/icon.png", + "color": "#3AB40B" + } + ] ] } } diff --git a/package-lock.json b/package-lock.json index 2bc9c93..f01c9b7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,8 +22,10 @@ "expo-auth-session": "~7.0.10", "expo-crypto": "~15.0.8", "expo-dev-client": "~6.0.20", + "expo-device": "~8.0.10", "expo-image-picker": "~17.0.10", "expo-linking": "~8.0.11", + "expo-notifications": "~0.32.16", "expo-secure-store": "~15.0.8", "expo-status-bar": "~3.0.9", "expo-web-browser": "~15.0.10", @@ -2375,6 +2377,12 @@ "react-native": "*" } }, + "node_modules/@ide/backoff": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@ide/backoff/-/backoff-1.0.0.tgz", + "integrity": "sha512-F0YfUDjvT+Mtt/R4xdl2X0EYCHMMiJqNLdxHD++jDT5ydEFIyqbCHh51Qx2E211dgZprPKhV7sHmnXKpLuvc5g==", + "license": "MIT" + }, "node_modules/@isaacs/fs-minipass": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", @@ -3800,6 +3808,19 @@ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "license": "MIT" }, + "node_modules/assert": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", + "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "is-nan": "^1.3.2", + "object-is": "^1.1.5", + "object.assign": "^4.1.4", + "util": "^0.12.5" + } + }, "node_modules/async-limiter": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", @@ -3812,6 +3833,21 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/axios": { "version": "1.13.6", "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz", @@ -4046,6 +4082,12 @@ "@babel/core": "^7.0.0" } }, + "node_modules/badgin": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/badgin/-/badgin-1.2.3.tgz", + "integrity": "sha512-NQGA7LcfCpSzIbGRbkgjgdWkjy7HI+Th5VLxTJfW5EeaAf3fnS+xWQaQOCYiny+q6QSvxqoSO04vCx+4u++EJw==", + "license": "MIT" + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -4263,6 +4305,24 @@ "node": ">= 0.8" } }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -4276,6 +4336,22 @@ "node": ">= 0.4" } }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -4897,6 +4973,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/define-lazy-prop": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", @@ -4906,6 +4999,23 @@ "node": ">=8" } }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -5284,6 +5394,15 @@ } } }, + "node_modules/expo-application": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/expo-application/-/expo-application-7.0.8.tgz", + "integrity": "sha512-qFGyxk7VJbrNOQWBbE09XUuGuvkOgFS9QfToaK2FdagM2aQ+x3CvGV2DuVgl/l4ZxPgIf3b/MNh9xHpwSwn74Q==", + "license": "MIT", + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo-asset": { "version": "12.0.12", "resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-12.0.12.tgz", @@ -5317,15 +5436,6 @@ "react-native": "*" } }, - "node_modules/expo-auth-session/node_modules/expo-application": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/expo-application/-/expo-application-7.0.8.tgz", - "integrity": "sha512-qFGyxk7VJbrNOQWBbE09XUuGuvkOgFS9QfToaK2FdagM2aQ+x3CvGV2DuVgl/l4ZxPgIf3b/MNh9xHpwSwn74Q==", - "license": "MIT", - "peerDependencies": { - "expo": "*" - } - }, "node_modules/expo-constants": { "version": "18.0.13", "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-18.0.13.tgz", @@ -5403,6 +5513,44 @@ "expo": "*" } }, + "node_modules/expo-device": { + "version": "8.0.10", + "resolved": "https://registry.npmjs.org/expo-device/-/expo-device-8.0.10.tgz", + "integrity": "sha512-jd5BxjaF7382JkDMaC+P04aXXknB2UhWaVx5WiQKA05ugm/8GH5uaz9P9ckWdMKZGQVVEOC8MHaUADoT26KmFA==", + "license": "MIT", + "dependencies": { + "ua-parser-js": "^0.7.33" + }, + "peerDependencies": { + "expo": "*" + } + }, + "node_modules/expo-device/node_modules/ua-parser-js": { + "version": "0.7.41", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.41.tgz", + "integrity": "sha512-O3oYyCMPYgNNHuO7Jjk3uacJWZF8loBgwrfd/5LE/HyZ3lUIOdniQ7DNXJcIgZbwioZxk0fLfI4EVnetdiX5jg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "license": "MIT", + "bin": { + "ua-parser-js": "script/cli.js" + }, + "engines": { + "node": "*" + } + }, "node_modules/expo-file-system": { "version": "19.0.21", "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-19.0.21.tgz", @@ -5520,6 +5668,26 @@ "react-native": "*" } }, + "node_modules/expo-notifications": { + "version": "0.32.16", + "resolved": "https://registry.npmjs.org/expo-notifications/-/expo-notifications-0.32.16.tgz", + "integrity": "sha512-QQD/UA6v7LgvwIJ+tS7tSvqJZkdp0nCSj9MxsDk/jU1GttYdK49/5L2LvE/4U0H7sNBz1NZAyhDZozg8xgBLXw==", + "license": "MIT", + "dependencies": { + "@expo/image-utils": "^0.8.8", + "@ide/backoff": "^1.0.0", + "abort-controller": "^3.0.0", + "assert": "^2.0.0", + "badgin": "^1.1.5", + "expo-application": "~7.0.8", + "expo-constants": "~18.0.13" + }, + "peerDependencies": { + "expo": "*", + "react": "*", + "react-native": "*" + } + }, "node_modules/expo-secure-store": { "version": "15.0.8", "resolved": "https://registry.npmjs.org/expo-secure-store/-/expo-secure-store-15.0.8.tgz", @@ -6011,6 +6179,21 @@ "integrity": "sha512-6FPvD/IVyT4ZlNe7Wcn5Fb/4ChigpucKYSvD6a+0iMoLn2inpo711eyIcKjmDtE5XNcgAkSH9uN/nfAeZzHEfg==", "license": "BSD-2-Clause" }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/form-data": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", @@ -6074,6 +6257,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -6222,6 +6414,18 @@ "node": ">=8" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", @@ -6487,6 +6691,22 @@ "loose-envify": "^1.0.0" } }, + "node_modules/is-arguments": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -6506,6 +6726,18 @@ "node": ">=8" } }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-core-module": { "version": "2.16.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", @@ -6554,6 +6786,25 @@ "node": ">=8" } }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -6566,6 +6817,22 @@ "node": ">=0.10.0" } }, + "node_modules/is-nan": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -6584,6 +6851,39 @@ "node": ">=8" } }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -8056,6 +8356,51 @@ "node": ">= 6" } }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", @@ -8486,6 +8831,15 @@ "node": ">=4.0.0" } }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/postcss": { "version": "8.4.49", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", @@ -9955,6 +10309,23 @@ ], "license": "MIT" }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/sax": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/sax/-/sax-1.5.0.tgz", @@ -10081,6 +10452,23 @@ "node": ">= 0.8" } }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", @@ -10944,6 +11332,19 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -11076,6 +11477,27 @@ "node": ">= 8" } }, + "node_modules/which-typed-array": { + "version": "1.1.20", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", + "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/wonka": { "version": "6.3.5", "resolved": "https://registry.npmjs.org/wonka/-/wonka-6.3.5.tgz", diff --git a/package.json b/package.json index 07d8dc6..96eb909 100644 --- a/package.json +++ b/package.json @@ -23,8 +23,10 @@ "expo-auth-session": "~7.0.10", "expo-crypto": "~15.0.8", "expo-dev-client": "~6.0.20", + "expo-device": "~8.0.10", "expo-image-picker": "~17.0.10", "expo-linking": "~8.0.11", + "expo-notifications": "~0.32.16", "expo-secure-store": "~15.0.8", "expo-status-bar": "~3.0.9", "expo-web-browser": "~15.0.10", diff --git a/sometips.md b/sometips.md new file mode 100644 index 0000000..ee1a36e --- /dev/null +++ b/sometips.md @@ -0,0 +1,290 @@ +# Claude Code 스킬 완전 가이드 + +> 출처: unclejobs.ai — AI Threads + +--- + +## 목차 + +1. [스킬은 마크다운 파일이 아니다](#스킬은-마크다운-파일이-아니다) +2. [9가지 스킬 유형](#9가지-스킬-유형) + - [1. 라이브러리/API 레퍼런스](#1-라이브러리api-레퍼런스) + - [2. 제품 검증](#2-제품-검증-product-verification) + - [3. 데이터 패칭/분석](#3-데이터-패칭분석) + - [4. 비즈니스 프로세스/팀 자동화](#4-비즈니스-프로세스팀-자동화) + - [5. 코드 스캐폴딩/템플릿](#5-코드-스캐폴딩템플릿) + - [6. 코드 품질/리뷰](#6-코드-품질리뷰) + - [7. CI/CD/배포](#7-cicd배포) + - [8. 런북(Runbook)](#8-런북runbook) + - [9. 인프라 운영](#9-인프라-운영) +3. [잘 만드는 법 — Anthropic의 8가지 팁](#잘-만드는-법--anthropic의-8가지-팁) +4. [온디맨드 훅](#온디맨드-훅--필요할-때만-켜지는-안전장치) +5. [팀에 퍼뜨리는 방법](#팀에-어떻게-퍼뜨리나) +6. [스킬 사용량 측정](#스킬-사용량-측정) + +--- + +## 스킬은 마크다운 파일이 아니다 + +가장 먼저 깨야 할 오해가 있어요. + +> "스킬은 그냥 .md 파일 아닌가요?" + +아닙니다. 스킬은 **폴더**예요. + +마크다운 파일 하나가 아니라, 그 안에 스크립트, 예제 코드, 데이터 파일, 템플릿을 전부 담을 수 있는 폴더 구조입니다. Claude에게 "이 폴더 안에 이런 파일들이 있어"라고 알려주면, 필요한 시점에 알아서 꺼내 읽어요. + +SKILL.md 하나에 모든 걸 때려넣는 게 아니라, 폴더 전체를 하나의 지식 체계로 설계하는 거예요. 이게 Anthropic이 "가장 흥미로운 스킬들"이라고 부르는 것들의 공통점이래요. 설정 옵션과 폴더 구조를 창의적으로 쓰고 있다는 거. + +--- + +## 9가지 스킬 유형 + +좋은 스킬은 하나에 딱 속하고, 헷갈리는 스킬은 여러 개에 걸쳐 있었다고. 이건 "우리 팀에 어떤 유형이 빠졌는지" 체크하는 프레임워크로 쓰면 좋아요. + +### 1. 라이브러리/API 레퍼런스 + +"이 라이브러리는 이렇게 써야 해"를 가르치는 스킬. + +회사에 내부 빌링 라이브러리가 있다고 해봐요. 특정 메서드를 호출할 때 순서를 잘못하면 에러가 나는 함정이 있는데, Claude는 당연히 이걸 모릅니다. 이런 엣지 케이스와 "이렇게 하면 안 돼" 목록을 스킬에 담는 거예요. 레퍼런스 코드 스니펫 폴더도 같이. + +외부 라이브러리도 마찬가지. Claude가 자주 실수하는 부분이 있으면 스킬로 교정할 수 있어요. + +**예시:** +- **billing-lib** — 사내 빌링 라이브러리의 엣지 케이스, 함정 모음 +- **internal-platform-cli** — 사내 CLI의 모든 서브커맨드와 사용 시점 예시 +- **frontend-design** — Claude가 우리 디자인 시스템을 더 잘 다루게 만드는 스킬 + +--- + +### 2. 제품 검증 (Product Verification) + +"코드가 진짜 돌아가는지 테스트하는 법"을 가르치는 스킬. + +Claude가 코드를 짜주긴 하는데, 그게 실제로 맞게 작동하는지는 어떻게 확인하죠? 이 스킬은 Playwright(브라우저 자동화 도구)나 tmux 같은 외부 도구와 짝을 이뤄서, Claude가 직접 테스트를 돌리고 결과를 검증하게 만들어요. + +Anthropic이 이렇게까지 말합니다. + +> "엔지니어 한 명이 일주일을 투자해서 검증 스킬 하나를 완벽하게 만드는 것도 충분히 가치가 있다." + +Claude가 테스트 과정을 영상으로 녹화하게 해서 정확히 뭘 테스트했는지 눈으로 볼 수 있게 만들거나, 각 단계에서 프로그래밍적 검증(assertion)을 강제하는 방법도 추천해요. + +**예시:** +- **signup-flow-driver** — 회원가입 → 이메일 인증 → 온보딩을 헤드리스 브라우저에서 실행, 각 단계마다 상태 검증 +- **checkout-verifier** — Stripe 테스트 카드로 결제 UI를 구동하고 인보이스가 맞는 상태에 도달했는지 확인 +- **tmux-cli-driver** — TTY가 필요한 대화형 CLI 테스트용 + +--- + +### 3. 데이터 패칭/분석 + +"데이터를 어디서 어떻게 가져오는지"를 가르치는 스킬. + +회사의 데이터 스택, 모니터링 도구에 연결하는 거예요. 접속 정보, 대시보드 ID, 일반적인 분석 워크플로우를 스킬에 담습니다. + +"가입부터 결제까지 퍼널을 보려면 어떤 테이블의 어떤 이벤트를 조인해야 하는지" + 실제 user_id가 들어있는 캐노니컬 테이블이 뭔지. 이런 걸 스킬에 넣어두면 Claude가 매번 "그 테이블 이름이 뭐였죠?"라고 물을 필요가 없어요. + +**예시:** +- **funnel-query** — 가입 → 활성화 → 결제 퍼널의 이벤트 조인 방법 + 캐노니컬 user_id 테이블 +- **cohort-compare** — 두 코호트의 리텐션/전환율 비교, 통계적 유의성 표시 +- **grafana** — 데이터소스 UID, 클러스터 이름, "이 문제면 이 대시보드" 매핑 + +--- + +### 4. 비즈니스 프로세스/팀 자동화 + +매일 반복하는 업무를 한 커맨드로 자동화하는 스킬. + +스탠드업 포스트 스킬을 예로 들어볼게요. 티켓 트래커에서 내 할당 업무를 가져오고, GitHub에서 어제 커밋 내역을 모으고, Slack에서 관련 대화를 긁어서 포맷에 맞게 정리합니다. 이전 스탠드업과 비교해서 "어제 대비 뭐가 바뀌었는지"만 보여주는 delta-only 방식. + +팁이 하나 있어요. 이런 스킬은 이전 실행 결과를 로그 파일에 저장해두면, Claude가 "지난번에 뭘 했는지"를 읽고 일관성을 유지할 수 있대요. + +**예시:** +- **standup-post** — 티켓 + GitHub + Slack 집계 → 포맷된 스탠드업(delta-only) +- **create-ticket** — 스키마 강제(유효한 값, 필수 필드) + 생성 후 워크플로우(리뷰어 핑, Slack 링크) +- **weekly-recap** — 머지된 PR + 닫힌 티켓 + 배포 → 주간 요약 + +--- + +### 5. 코드 스캐폴딩/템플릿 + +새 기능을 만들 때 뼈대를 자동 생성하는 스킬. + +"새 API 엔드포인트 만들어줘"라고 하면, 우리 조직의 인증 방식, 로깅 설정, 배포 구성이 미리 연결된 상태로 파일 구조를 잡아주는 거예요. 순수 코드 제너레이터로는 커버 안 되는 자연어 요구사항("이 서비스는 이런 컨벤션을 따라야 해")이 있을 때 특히 유용합니다. + +**예시:** +- **new-workflow** — 조직의 어노테이션이 포함된 새 서비스/핸들러 스캐폴딩 +- **new-migration** — 마이그레이션 파일 템플릿 + 일반적인 함정 +- **create-app** — 인증, 로깅, 배포 설정이 미리 연결된 새 내부 앱 + +--- + +### 6. 코드 품질/리뷰 + +조직의 코드 품질 기준을 강제하는 스킬. + +재밌는 예가 있어요. `adversarial-review` 스킬. 서브에이전트를 하나 더 띄워서 "처음 보는 사람의 눈"으로 코드를 비판하게 합니다. 지적 사항을 수정하고, 다시 리뷰하고, 지적이 사소한 수준(nitpick)까지 내려갈 때까지 반복. + +훅이나 GitHub Action에 연결해서 자동 실행되게 할 수도 있어요. + +**예시:** +- **adversarial-review** — 서브에이전트가 비판 → 수정 → 반복, 지적이 사소해질 때까지 +- **code-style** — Claude가 기본적으로 잘 못하는 코드 스타일 강제 +- **testing-practices** — 테스트 작성법과 무엇을 테스트해야 하는지 안내 + +--- + +### 7. CI/CD/배포 + +코드를 빌드하고 테스트하고 배포하는 과정을 자동화하는 스킬. + +`babysit-pr` 스킬이 대표적이에요. PR을 올리면 CI가 돌아가잖아요. 가끔 환경 문제로 무작위 실패하는 불안정한 테스트가 있는데, 이 스킬이 알아서 재시도하고, 머지 충돌이 생기면 해결하고, 문제없으면 오토 머지까지 켜줍니다. + +배포 스킬은 더 정교해요. 빌드 → 스모크 테스트 → 트래픽 점진적 롤아웃 → 에러율 비교 → 리그레션 시 자동 롤백. 사람이 붙어서 모니터링하던 걸 스킬이 대신합니다. + +**예시:** +- **babysit-pr** — PR 모니터링 → 불안정 CI 재시도 → 머지 충돌 해결 → 오토 머지 +- **deploy-service** — 빌드 → 스모크 테스트 → 점진적 트래픽 → 에러 시 자동 롤백 +- **cherry-pick-prod** — 격리된 워크트리 → 체리픽 → 충돌 해결 → 템플릿 PR + +--- + +### 8. 런북(Runbook) + +"이런 증상이 나타나면 이렇게 조사해라"를 자동화한 스킬. + +장애가 나면 보통 이래요. Slack에서 알림 → 로그 확인 → 관련 시스템 확인 → 원인 파악 → 보고서. 런북 스킬은 이 전체를 자동화합니다. + +요청 ID 하나를 주면 그 요청이 지나간 모든 시스템에서 매칭 로그를 뽑아서 하나로 모아주는 `log-correlator` 같은 거예요. + +**예시:** +- **service-debugging** — 고트래픽 서비스의 증상 → 도구 → 쿼리 패턴 매핑 +- **oncall-runner** — 알림 → 일반적 원인 확인 → 발견 사항 포맷팅 +- **log-correlator** — 요청 ID → 모든 시스템에서 매칭 로그 추출 + +--- + +### 9. 인프라 운영 + +정기 유지보수와 운영 절차를 자동화하는 스킬. 특히 "실수하면 큰일 나는" 파괴적 작업에 가드레일을 다는 용도예요. + +고아 상태(아무도 안 쓰는) 쿠버네티스 파드나 볼륨을 찾아서 → Slack에 알리고 → 며칠 기다리고(혹시 누가 쓰는지) → 사용자가 확인하면 → 정리. 자동이되 사람의 확인을 거치는 구조. + +**예시:** +- **resource-orphans** — 고아 파드/볼륨 탐색 → Slack 알림 → 대기 → 확인 → 정리 +- **dependency-management** — 조직의 의존성 승인 워크플로우 +- **cost-investigation** — "왜 스토리지 비용이 급증했나" + 특정 버킷과 쿼리 패턴 + +--- + +## 잘 만드는 법 — Anthropic의 8가지 팁 + +### 팁 1. 당연한 걸 적지 마라 + +Claude는 코딩에 대해 이미 많이 알아요. "변수명은 의미 있게 지어라" 같은 일반 상식을 스킬에 적으면 토큰만 낭비됩니다. + +스킬에는 **Claude가 평소에 모르거나 틀리는 것만** 적어야 해요. + +`frontend-design` 스킬이 좋은 예예요. Anthropic의 한 엔지니어가 고객 피드백을 반복 반영하면서 만들었는데, Claude가 기본적으로 쓰는 Inter 폰트, 보라색 그라데이션 같은 "AI 티 나는 패턴"을 피하게 한 거예요. "일반적인 좋은 디자인"이 아니라 "Claude가 구체적으로 틀리는 부분"에 집중한 겁니다. + +### 팁 2. Gotchas 섹션이 가장 중요하다 + +모든 스킬에서 가장 가치 있는 부분이 뭐냐고 물었더니 Anthropic의 답은 **Gotchas 섹션**이래요. + +Gotchas는 "Claude가 이 스킬을 쓸 때 자주 빠지는 함정" 목록이에요. 처음에는 하나둘로 시작하지만, Claude가 새 엣지 케이스를 만날 때마다 추가합니다. + +이게 스킬의 진짜 성장 방식이에요. 완벽하게 만들어서 배포하는 게 아니라, **실패할 때마다 Gotchas에 한 줄 추가**하는 것. + +### 팁 3. 파일 시스템을 활용해라 — 점진적 공개 + +스킬은 폴더라고 했죠. 이걸 제대로 쓰면 "**점진적 공개(Progressive Disclosure)**"가 가능해요. + +모든 정보를 한꺼번에 보여주지 않고, 필요할 때만 꺼내 보는 거예요. + +- `SKILL.md` — 핵심 지침만 +- `references/api.md` — 상세한 API 사용법 +- `assets/` — 출력 템플릿 +- `examples/` — 예제 코드 + +Claude에게 "이 파일들이 있으니 필요하면 읽어"라고 알려주면 적절한 타이밍에 가져옵니다. 하나의 마크다운에 전부 때려넣으면 매번 모든 걸 읽어야 하니까 토큰이 낭비돼요. + +### 팁 4. Claude를 너무 가두지 마라 + +스킬은 재사용되는 거잖아요. 지시사항이 너무 구체적이면 상황이 조금만 달라져도 안 맞습니다. + +- **나쁜 예:** "반드시 A를 호출하고, 그 다음 B를 호출하고, 결과를 C 형식으로 저장하라" +- **좋은 예:** "이 함수들이 있고, 각각의 용도는 이렇다. 상황에 맞게 조합해서 써라" + +필요한 정보를 주되, 판단의 유연성을 남겨두라는 거예요. + +### 팁 5. 셋업을 설계해라 + +어떤 스킬은 처음에 사용자한테 물어봐야 할 게 있어요. "스탠드업을 어느 Slack 채널에 올릴까요?" 같은 거. + +좋은 패턴은 스킬 폴더 안에 `config.json`을 두는 거예요. 설정 파일이 비어있으면 Claude가 사용자에게 질문합니다. 답을 받아서 저장하면 다음부터는 묻지 않아요. + +구조화된 객관식 질문을 제시하고 싶으면 Claude에게 `AskUserQuestion` 도구를 쓰라고 지시하면 됩니다. + +### 팁 6. description은 "언제 쓸지"를 적는 곳이다 + +세션이 시작되면 Claude Code는 설치된 모든 스킬의 `description`을 스캔해서 "이 요청에 맞는 스킬이 있나?"를 판단해요. + +그러니까 description은 요약이 아닙니다. **"이 스킬을 언제 호출해야 하는지"를 적는 트리거 조건**이에요. + +- **나쁜 예:** "코드 리뷰를 도와주는 스킬입니다" +- **좋은 예:** "PR이 올라왔을 때 보안 취약점, 누락된 테스트, 동작 리그레션을 검토합니다. 사용자가 '리뷰해줘', 'PR 체크'라고 말할 때 호출." + +이 차이가 스킬이 제때 불리느냐 마느냐를 결정합니다. + +### 팁 7. 스킬에 기억을 넣어라 + +스킬 안에 데이터를 저장할 수 있어요. 단순한 텍스트 로그, JSON, 심지어 SQLite까지. + +`standup-post` 스킬이 매일 `standups.log`에 기록을 남기면, 다음에 실행할 때 Claude가 이전 기록을 읽고 "어제 대비 뭐가 바뀌었는지"를 알 수 있어요. + +> **주의:** 스킬 업그레이드 시 디렉토리가 삭제될 수 있어요. `${CLAUDE_PLUGIN_DATA}` 같은 안정적인 경로에 저장하라고 합니다. + +### 팁 8. 스크립트를 넣어라 — 코드가 가장 강력한 도구다 + +데이터 분석 스킬에 데이터 페칭 함수 라이브러리를 넣어두면, Claude는 매번 데이터를 가져오는 코드를 처음부터 쓰는 대신, 이 함수들을 조합해서 분석하는 데 집중할 수 있어요. + +"화요일에 무슨 일이 있었어?"라고 물으면 Claude가 미리 준비된 함수를 조합해서 스크립트를 즉석으로 짜고 실행합니다. 보일러플레이트에 턴을 쓰지 않으니까 토큰이 줄어요. + +--- + +## 온디맨드 훅 — 필요할 때만 켜지는 안전장치 + +스킬이 호출될 때만 활성화되고 세션 동안만 유지되는 훅을 넣을 수 있어요. 항상 켜두면 짜증나지만, 특정 상황에서는 꼭 필요한 것들. + +- **/careful** — `rm -rf`, `DROP TABLE`, `force-push`, `kubectl delete`를 전부 차단. 프로덕션 작업할 때만 켜는 거예요. 항상 켜두면 일상 작업이 불가능해집니다. +- **/freeze** — 특정 디렉토리 이외의 파일 수정을 전부 차단. 디버깅할 때 "로그만 추가하려고 했는데 실수로 다른 파일까지 고쳐버렸다"를 방지. + +--- + +## 팀에 어떻게 퍼뜨리나 + +두 가지 방법이 있어요. + +**레포에 체크인** +`.claude/skills/` 폴더에 넣어서 Git으로 관리. 팀 전원이 같은 스킬을 씁니다. 작은 팀에 적합. 단점은 스킬이 많아지면 전부 Claude 컨텍스트에 올라간다는 것. + +**사내 플러그인 마켓플레이스** +규모가 커지면 이쪽. 팀원이 필요한 스킬만 골라서 설치하는 구조. + +Anthropic의 마켓플레이스 운영 방식이 재밌어요. 중앙 팀이 결정하지 않습니다. + +1. 스킬을 만들면 GitHub 샌드박스 폴더에 올림 +2. Slack에서 "이거 써봐" 하고 공유 +3. 견인력이 생기면(스킬 오너가 판단) 마켓플레이스에 PR + +유기적으로 떠오르게 하는 거예요. 경고도 하나 남겼습니다. + +> "나쁘거나 중복된 스킬을 만드는 건 쉽다. 릴리스 전에 큐레이션 과정이 반드시 필요하다." + +--- + +## 스킬 사용량 측정 + +Anthropic은 `PreToolUse` 훅으로 사내 스킬 사용량을 로깅하고 있대요. 어떤 스킬이 많이 쓰이는지, 기대보다 호출이 적은 건 뭔지 데이터로 파악합니다. + +기대보다 안 쓰이면 `description`(트리거 조건)을 다시 쓰고, 인기 있는 스킬은 더 다듬고. diff --git a/src/apis/block/blockApi.ts b/src/apis/block/blockApi.ts new file mode 100644 index 0000000..102a729 --- /dev/null +++ b/src/apis/block/blockApi.ts @@ -0,0 +1,22 @@ +import api from "@/apis/instance"; +import type { ApiResponse } from "@/types/common/apiResponse.type"; + +type BlockUserPayload = { + userIdToBlock: number; +}; + +export const postBlockUser = async ( + userIdToBlock: number +): ApiResponse => { + const res = await api.post("/api/v1/blocks", { userIdToBlock } satisfies BlockUserPayload); + return res.data; +}; + +export const deleteBlockUser = async ( + userIdToBlock: number +): ApiResponse => { + const res = await api.delete("/api/v1/blocks", { + data: { userIdToBlock } satisfies BlockUserPayload, + }); + return res.data; +}; diff --git a/src/apis/comments/commentApi.ts b/src/apis/comments/commentApi.ts index b47bbd8..21a1aff 100644 --- a/src/apis/comments/commentApi.ts +++ b/src/apis/comments/commentApi.ts @@ -11,3 +11,8 @@ export const postComment = async ( const res = await api.post("/api/v1/comments", body); return res.data; }; + +export const deleteComment = async (commentId: number): ApiResponse => { + const res = await api.delete(`/api/v1/comments/${commentId}`); + return res.data; +}; diff --git a/src/apis/option/notificationApi.ts b/src/apis/option/notificationApi.ts new file mode 100644 index 0000000..2bb06dc --- /dev/null +++ b/src/apis/option/notificationApi.ts @@ -0,0 +1,24 @@ +import api from "@/apis/instance"; +import type { ApiResponse, NoResponse } from "@/types/common/apiResponse.type"; + +export type NotificationSettings = { + notificationEnabled: boolean; + marketingConsent: boolean; +}; + +export const getNotificationSettings = async (): ApiResponse => { + const res = await api.get("/api/v1/notifications/settings"); + return res.data; +}; + +export const patchNotificationSettings = async ( + settings: Partial +): ApiResponse => { + const res = await api.patch("/api/v1/notifications/settings", settings); + return res.data; +}; + +export const postFcmToken = async (token: string): ApiResponse => { + const res = await api.post("/api/v1/notifications/token", { token }); + return res.data; +}; diff --git a/src/apis/report/reportApi.ts b/src/apis/report/reportApi.ts new file mode 100644 index 0000000..e8bd52d --- /dev/null +++ b/src/apis/report/reportApi.ts @@ -0,0 +1,10 @@ +import api from "@/apis/instance"; +import type { ApiResponse } from "@/types/common/apiResponse.type"; +import type { CreateReportPayload } from "@/types/report"; + +export const postReport = async ( + payload: CreateReportPayload +): ApiResponse => { + const res = await api.post("/api/v1/reports", payload); + return res.data; +}; diff --git a/src/assets/icons/CommonIcons.tsx b/src/assets/icons/CommonIcons.tsx index 45ced71..7a2d4a8 100644 --- a/src/assets/icons/CommonIcons.tsx +++ b/src/assets/icons/CommonIcons.tsx @@ -181,6 +181,42 @@ export function UserPlusIcon({ size = 24, color = "#171717" }: IconProps) { ); } +// 새로고침 아이콘 +export function RefreshIcon({ size = 24, color = "#171717" }: IconProps) { + return ( + + + + + + + ); +} + // 전송 아이콘 export function SendIcon({ size = 32 }: IconProps) { return ( diff --git a/src/components/common/Comment.tsx b/src/components/common/Comment.tsx index 30c1114..b2c0618 100644 --- a/src/components/common/Comment.tsx +++ b/src/components/common/Comment.tsx @@ -1,12 +1,20 @@ import React from "react"; -import { View, Text, Image, StyleSheet } from "react-native"; +import { View, Text, Image, StyleSheet, TouchableOpacity } from "react-native"; import type { CommentItem } from "@/types/log/diary"; type Props = { comment: CommentItem; + actionLabel?: string; + onActionPress?: () => void; + actionDisabled?: boolean; }; -export default function Comment({ comment }: Props) { +export default function Comment({ + comment, + actionLabel, + onActionPress, + actionDisabled = false, +}: Props) { return ( {/* 프로필 이미지 */} @@ -28,6 +36,17 @@ export default function Comment({ comment }: Props) { {comment.writer} + {actionLabel && onActionPress ? ( + + + {actionLabel} + + + ) : null} {/* 댓글 내용 */} @@ -82,6 +101,14 @@ const styles = StyleSheet.create({ fontWeight: "600", color: "#171717", }, + reportText: { + fontSize: 12, + fontWeight: "600", + color: "#6B7280", + }, + reportTextDisabled: { + color: "#9CA3AF", + }, commentContent: { fontSize: 14, color: "#171717", diff --git a/src/components/common/ScreenHeader.tsx b/src/components/common/ScreenHeader.tsx index 12f5f04..0fd9b87 100644 --- a/src/components/common/ScreenHeader.tsx +++ b/src/components/common/ScreenHeader.tsx @@ -1,4 +1,6 @@ import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import { RefreshIcon } from "@/assets/icons/CommonIcons"; +import LeftIcon from "@/assets/icons/common/left.svg"; type Props = { title: string; @@ -15,38 +17,41 @@ export default function ScreenHeader({ onRightAction, rightActionDisabled = false, }: Props) { - const resolvedRightAction = onRightAction ?? onBack; const resolvedRightLabel = rightActionLabel ?? "완료"; + const isRefreshAction = resolvedRightLabel === "새로고침"; return ( - {/* 왼쪽: 닫기(X) 버튼 */} {onBack ? ( - + ) : ( )} - {/* 중앙: 화면 타이틀 */} {title} - {/* 오른쪽: 완료 텍스트 버튼 */} - {resolvedRightAction ? ( + {onRightAction ? ( - - {resolvedRightLabel} - + {isRefreshAction ? ( + + ) : ( + + {resolvedRightLabel} + + )} ) : ( @@ -72,11 +77,6 @@ const styles = StyleSheet.create({ justifyContent: "center", alignItems: "center", }, - closeText: { - fontSize: 18, - color: "#171717", - }, - // 완료 버튼: Regular 16px 검정 completeText: { fontSize: 16, fontWeight: "400", @@ -86,7 +86,6 @@ const styles = StyleSheet.create({ disabledText: { color: "#BFBFBF", }, - // 타이틀: SemiBold 18px title: { fontSize: 18, fontWeight: "600", diff --git a/src/components/dailyMission/OxQuizOptionCard.tsx b/src/components/dailyMission/OxQuizOptionCard.tsx new file mode 100644 index 0000000..1821a45 --- /dev/null +++ b/src/components/dailyMission/OxQuizOptionCard.tsx @@ -0,0 +1,76 @@ +import { StyleSheet, TouchableOpacity, View } from "react-native"; +import OIcon from "@/assets/icons/common/OX_O.svg"; +import XIcon from "@/assets/icons/common/OX_X.svg"; + +type OxOptionState = "idle" | "selected" | "correct" | "wrong" | "answer"; + +type Props = { + label: "O" | "X"; + state?: OxOptionState; + disabled?: boolean; + onPress: () => void; +}; + +export default function OxQuizOptionCard({ + label, + state = "idle", + disabled = false, + onPress, +}: Props) { + const Icon = label === "O" ? OIcon : XIcon; + const iconColor = + state === "correct" || state === "answer" + ? "#6FCF4A" + : state === "wrong" + ? "#FF6B6B" + : state === "selected" + ? "#4A4A4A" + : "#BFBFBF"; + + return ( + + + + + + ); +} + +const styles = StyleSheet.create({ + card: { + flex: 1, + height: 150, + borderRadius: 8, + borderWidth: 1, + borderColor: "#EFEFEF", + backgroundColor: "#FFFFFF", + alignItems: "center", + justifyContent: "center", + }, + cardSelected: { + backgroundColor: "#EFEFEF", + borderColor: "#BFBFBF", + }, + cardCorrect: { + backgroundColor: "#EFF9EA", + borderColor: "#6FCF4A", + }, + cardWrong: { + backgroundColor: "#FFF1F1", + borderColor: "#FF6B6B", + }, + iconWrap: { + alignItems: "center", + justifyContent: "center", + }, +}); diff --git a/src/components/feed/FeedAvatarDetailCard.tsx b/src/components/feed/FeedAvatarDetailCard.tsx index 0762858..5e1c138 100644 --- a/src/components/feed/FeedAvatarDetailCard.tsx +++ b/src/components/feed/FeedAvatarDetailCard.tsx @@ -1,9 +1,11 @@ +import type { AxiosError } from "axios"; import { useState } from "react"; -import { ActivityIndicator, StyleSheet, Text, View } from "react-native"; +import { ActivityIndicator, Alert, StyleSheet, Text, View } from "react-native"; import FeedDetail from "@/components/feed/FeedDetail"; -import usePostComment from "@/hooks/comments/useCommentApi"; +import usePostComment, { useDeleteComment } from "@/hooks/comments/useCommentApi"; import useFeedLikeToggle from "@/hooks/feed/useFeedLikeToggle"; import { useAvatarPostDetail } from "@/hooks/feed/useAvatarPostDetailApi"; +import { useCreateReport } from "@/hooks/report/useReportApi"; import type { FeedDetailResult } from "@/types/feed/detail"; type Props = { @@ -13,7 +15,10 @@ type Props = { export default function FeedAvatarDetailCard({ postId }: Props) { const { data, isLoading, error, refetch } = useAvatarPostDetail(postId); const [content, setContent] = useState(""); + const [isHidden, setIsHidden] = useState(false); const { mutateAsync, isPending } = usePostComment(() => void refetch()); + const deleteCommentMutation = useDeleteComment(() => void refetch()); + const reportMutation = useCreateReport(); const { liked, likeCount, toggleLike, isLikePending } = useFeedLikeToggle({ targetId: postId, targetType: "AVATAR_POST", @@ -31,10 +36,51 @@ export default function FeedAvatarDetailCard({ postId }: Props) { await mutateAsync({ content, targetId: postId, targetType: "AVATAR_POST" }); setContent(""); } catch (commentError) { - console.error( - "[FeedAvatarDetailCard] Failed to post comment:", - commentError - ); + console.error("[FeedAvatarDetailCard] Failed to post comment:", commentError); + } + }; + + const handleReportPost = async () => { + try { + await reportMutation.mutateAsync({ + targetType: "AVATAR_POST", + targetId: postId, + reason: "부적절한 콘텐츠", + additionalComment: "", + }); + setIsHidden(true); + Alert.alert("신고 완료", "신고가 접수되었습니다."); + } catch (error) { + const axiosError = error as AxiosError<{ message?: string }>; + Alert.alert("신고 실패", axiosError.response?.data?.message ?? "잠시 후 다시 시도해주세요."); + throw error; + } + }; + + const handleReportComment = async (commentId: number) => { + try { + await reportMutation.mutateAsync({ + targetType: "COMMENT", + targetId: commentId, + reason: "부적절한 댓글", + additionalComment: "", + }); + Alert.alert("신고 완료", "신고가 접수되었습니다."); + } catch (error) { + const axiosError = error as AxiosError<{ message?: string }>; + Alert.alert("신고 실패", axiosError.response?.data?.message ?? "잠시 후 다시 시도해주세요."); + throw error; + } + }; + + const handleDeleteComment = async (commentId: number) => { + try { + await deleteCommentMutation.mutateAsync({ commentId, targetType: "AVATAR_POST", targetId: postId }); + Alert.alert("삭제 완료", "댓글이 삭제되었습니다."); + } catch (error) { + const axiosError = error as AxiosError<{ message?: string }>; + Alert.alert("삭제 실패", axiosError.response?.data?.message ?? "잠시 후 다시 시도해주세요."); + throw error; } }; @@ -55,6 +101,15 @@ export default function FeedAvatarDetailCard({ postId }: Props) { ); } + if (isHidden) { + return ( + + 신고한 게시물입니다. + 이 항목은 나에게 숨김 처리되었습니다. + + ); + } + const result: FeedDetailResult = { id: data.id, writerId: data.writerId, @@ -74,6 +129,7 @@ export default function FeedAvatarDetailCard({ postId }: Props) { return ( void handleSendComment()} isCommentPending={isPending} + onPressReport={handleReportPost} + onPressCommentReport={handleReportComment} + onPressCommentDelete={handleDeleteComment} + isReportPending={reportMutation.isPending || deleteCommentMutation.isPending} /> ); } @@ -96,5 +156,11 @@ const styles = StyleSheet.create({ statusText: { fontSize: 14, color: "#6B7280", + textAlign: "center", + }, + hiddenTitle: { + fontSize: 15, + fontWeight: "700", + color: "#171717", }, }); diff --git a/src/components/feed/FeedDetail.tsx b/src/components/feed/FeedDetail.tsx index 47646b6..c52feb5 100644 --- a/src/components/feed/FeedDetail.tsx +++ b/src/components/feed/FeedDetail.tsx @@ -1,5 +1,6 @@ -import React, { useCallback, useMemo, useRef, useState } from "react"; +import React, { useCallback, useMemo, useRef, useState } from "react"; import { + Alert, FlatList, ListRenderItem, View, @@ -24,10 +25,12 @@ import type { RootStackParamList } from "@/navigation/types"; import { HeartIcon, ChatIcon } from "@/assets/icons/CommonIcons"; import Comment from "@/components/common/Comment"; import CommentComposer from "@/components/common/CommentComposer"; +import useTokenStore from "@/stores/useTokenStore"; import type { FeedDetailResult } from "@/types/feed/detail"; type Props = { result: FeedDetailResult; + reportTargetLabel?: string; liked?: boolean; likeCount?: number; onToggleLike?: () => void; @@ -36,10 +39,15 @@ type Props = { onChangeComment?: (text: string) => void; onSubmitComment?: () => void; isCommentPending?: boolean; + onPressReport?: () => Promise | void; + onPressCommentReport?: (commentId: number, writer: string) => Promise | void; + onPressCommentDelete?: (commentId: number) => Promise | void; + isReportPending?: boolean; }; export default function FeedDetail({ result, + reportTargetLabel = "게시물", liked = result.isLiked, likeCount = result.likeCount, onToggleLike, @@ -48,26 +56,116 @@ export default function FeedDetail({ onChangeComment, onSubmitComment, isCommentPending = false, + onPressReport, + onPressCommentReport, + onPressCommentDelete, + isReportPending = false, }: Props) { const navigation = useNavigation>(); + const myUserId = useTokenStore(state => state.userId); const bottomSheetModalRef = useRef(null); const snapPoints = useMemo(() => ["60%", "90%"], []); + const [hiddenCommentIds, setHiddenCommentIds] = useState([]); const comments = useMemo( () => - result.comments.map(c => ({ - id: c.commentId, - profileImageUrl: c.profileImageUrl, - writer: c.writer, - content: c.content, - })), - [result.comments] + result.comments + .filter(c => !hiddenCommentIds.includes(c.commentId)) + .map(c => ({ + id: c.commentId, + writerId: c.writerId, + profileImageUrl: c.profileImageUrl, + writer: c.writer, + content: c.content, + })), + [hiddenCommentIds, result.comments] ); + const handleCommentReportPress = async (commentId: number, writer: string) => { + if (!onPressCommentReport || isReportPending) { + return; + } + + Alert.alert("신고하기", "댓글을 신고하시겠습니까?\n신고한 댓글은 나에게 숨겨집니다.", [ + { + text: "취소", + style: "cancel", + }, + { + text: "신고하기", + style: "destructive", + onPress: () => { + Alert.alert("사용자 숨기기", "사용자의 모든 댓글을 숨기시겠습니까?\n이 작업은 취소할 수 없습니다.", [ + { + text: "취소", + style: "cancel", + }, + { + text: "숨기기", + style: "destructive", + onPress: async () => { + try { + await onPressCommentReport(commentId, writer); + setHiddenCommentIds(previous => + previous.includes(commentId) ? previous : [...previous, commentId] + ); + } catch { + // Error handling is delegated to the caller. + } + }, + }, + ]); + }, + }, + ]); + }; + const renderCommentItem: ListRenderItem<(typeof comments)[number]> = ({ item, - }) => ; + }) => { + const isOwnComment = Boolean(myUserId && String(item.writerId) === myUserId); + + return ( + { + if (!onPressCommentDelete || isReportPending) { + return; + } + + Alert.alert("삭제하기", "댓글을 삭제하시겠습니까?", [ + { + text: "취소", + style: "cancel", + }, + { + text: "삭제", + style: "destructive", + onPress: async () => { + try { + await onPressCommentDelete(item.id); + setHiddenCommentIds(previous => + previous.includes(item.id) ? previous : [...previous, item.id] + ); + } catch { + // Error handling is delegated to the caller. + } + }, + }, + ]); + } + : onPressCommentReport + ? () => void handleCommentReportPress(item.id, item.writer) + : undefined + } + actionDisabled={isReportPending} + /> + ); + }; const getCommentKey = (item: (typeof comments)[number]) => item.id.toString(); @@ -84,6 +182,46 @@ export default function FeedDetail({ bottomSheetModalRef.current?.present(); }; + const handleReportPress = () => { + if (!onPressReport || isReportPending) { + return; + } + + Alert.alert( + "신고하기", + `${reportTargetLabel}을 신고하시겠습니까?\n신고한 ${reportTargetLabel}은 나에게 숨겨집니다.`, + [ + { + text: "취소", + style: "cancel", + }, + { + text: "신고하기", + style: "destructive", + onPress: () => { + Alert.alert( + "사용자 숨기기", + `사용자의 모든 ${reportTargetLabel}을 숨기시겠습니까?\n이 작업은 취소할 수 없습니다.`, + [ + { + text: "취소", + style: "cancel", + }, + { + text: "숨기기", + style: "destructive", + onPress: () => { + void onPressReport(); + }, + }, + ] + ); + }, + }, + ] + ); + }; + const handleCloseComments = () => { bottomSheetModalRef.current?.dismiss(); }; @@ -110,9 +248,6 @@ export default function FeedDetail({ return ( - {/* 한글 주석: - 댓글 입력창은 바텀시트 본문 흐름과 분리된 footer로 렌더링해 - 댓글 수와 관계없이 항상 시트 최하단에 고정한다. */} - {/* 작성자 영역 */} {formatDate(result.createdAt)} - 신고 + + + {isReportPending ? "신고 중..." : "신고"} + + - {/* 이미지 */} - {/* 내용 */} {result.content} - {/* 액션 바 */} - {/* 공감 */} - {/* 댓글 */} - 댓글 {result.commentCount} + 댓글 {comments.length} @@ -213,7 +350,7 @@ export default function FeedDetail({ style={styles.sheetKeyboard} > - 댓글 {result.commentCount} + 댓글 {comments.length} {comments.length > 0 ? ( @@ -269,7 +406,6 @@ const styles = StyleSheet.create({ }, writerName: { fontSize: 14, - // Match the lighter author text weight from the current FE detail layout. fontWeight: "400", color: "#171717", }, @@ -283,6 +419,9 @@ const styles = StyleSheet.create({ fontWeight: "600", color: "#6B7280", }, + reportButtonDisabled: { + color: "#9CA3AF", + }, mainImage: { width: "100%", aspectRatio: 1, @@ -292,7 +431,6 @@ const styles = StyleSheet.create({ content: { fontSize: 14, color: "#171717", - // Slightly tighter line height keeps multi-line posts closer to the FE proportions. lineHeight: 20, marginBottom: 24, }, diff --git a/src/components/feed/FeedDiaryDetailCard.tsx b/src/components/feed/FeedDiaryDetailCard.tsx index b4e30f1..4a0588e 100644 --- a/src/components/feed/FeedDiaryDetailCard.tsx +++ b/src/components/feed/FeedDiaryDetailCard.tsx @@ -1,8 +1,10 @@ +import type { AxiosError } from "axios"; import { useState } from "react"; -import { ActivityIndicator, StyleSheet, Text, View } from "react-native"; +import { ActivityIndicator, Alert, StyleSheet, Text, View } from "react-native"; import FeedDetail from "@/components/feed/FeedDetail"; -import usePostComment from "@/hooks/comments/useCommentApi"; +import usePostComment, { useDeleteComment } from "@/hooks/comments/useCommentApi"; import useFeedLikeToggle from "@/hooks/feed/useFeedLikeToggle"; +import { useCreateReport } from "@/hooks/report/useReportApi"; import { useDiaryDetail } from "@/hooks/log/useDiaryDetailApi"; import type { FeedDetailResult } from "@/types/feed/detail"; @@ -13,7 +15,10 @@ type Props = { export default function FeedDiaryDetailCard({ postId }: Props) { const { data, isLoading, error, refetch } = useDiaryDetail(postId); const [content, setContent] = useState(""); + const [isHidden, setIsHidden] = useState(false); const { mutateAsync, isPending } = usePostComment(() => void refetch()); + const deleteCommentMutation = useDeleteComment(() => void refetch()); + const reportMutation = useCreateReport(); const { liked, likeCount, toggleLike, isLikePending } = useFeedLikeToggle({ targetId: postId, targetType: "DIARY", @@ -31,10 +36,51 @@ export default function FeedDiaryDetailCard({ postId }: Props) { await mutateAsync({ content, targetId: postId, targetType: "DIARY" }); setContent(""); } catch (commentError) { - console.error( - "[FeedDiaryDetailCard] Failed to post comment:", - commentError - ); + console.error("[FeedDiaryDetailCard] Failed to post comment:", commentError); + } + }; + + const handleReportPost = async () => { + try { + await reportMutation.mutateAsync({ + targetType: "DIARY", + targetId: postId, + reason: "부적절한 콘텐츠", + additionalComment: "", + }); + setIsHidden(true); + Alert.alert("신고 완료", "신고가 접수되었습니다."); + } catch (error) { + const axiosError = error as AxiosError<{ message?: string }>; + Alert.alert("신고 실패", axiosError.response?.data?.message ?? "잠시 후 다시 시도해주세요."); + throw error; + } + }; + + const handleReportComment = async (commentId: number) => { + try { + await reportMutation.mutateAsync({ + targetType: "COMMENT", + targetId: commentId, + reason: "부적절한 댓글", + additionalComment: "", + }); + Alert.alert("신고 완료", "신고가 접수되었습니다."); + } catch (error) { + const axiosError = error as AxiosError<{ message?: string }>; + Alert.alert("신고 실패", axiosError.response?.data?.message ?? "잠시 후 다시 시도해주세요."); + throw error; + } + }; + + const handleDeleteComment = async (commentId: number) => { + try { + await deleteCommentMutation.mutateAsync({ commentId, targetType: "DIARY", targetId: postId }); + Alert.alert("삭제 완료", "댓글이 삭제되었습니다."); + } catch (error) { + const axiosError = error as AxiosError<{ message?: string }>; + Alert.alert("삭제 실패", axiosError.response?.data?.message ?? "잠시 후 다시 시도해주세요."); + throw error; } }; @@ -55,6 +101,15 @@ export default function FeedDiaryDetailCard({ postId }: Props) { ); } + if (isHidden) { + return ( + + 신고한 일기입니다. + 이 항목은 나에게 숨김 처리되었습니다. + + ); + } + const result: FeedDetailResult = { id: data.id, writerId: data.writerId, @@ -74,6 +129,7 @@ export default function FeedDiaryDetailCard({ postId }: Props) { return ( void handleSendComment()} isCommentPending={isPending} + onPressReport={handleReportPost} + onPressCommentReport={handleReportComment} + onPressCommentDelete={handleDeleteComment} + isReportPending={reportMutation.isPending || deleteCommentMutation.isPending} /> ); } @@ -96,5 +156,11 @@ const styles = StyleSheet.create({ statusText: { fontSize: 14, color: "#6B7280", + textAlign: "center", + }, + hiddenTitle: { + fontSize: 15, + fontWeight: "700", + color: "#171717", }, }); diff --git a/src/components/feed/FeedSeedDetailCard.tsx b/src/components/feed/FeedSeedDetailCard.tsx index c73591f..b974728 100644 --- a/src/components/feed/FeedSeedDetailCard.tsx +++ b/src/components/feed/FeedSeedDetailCard.tsx @@ -1,6 +1,10 @@ -import { StyleSheet, View } from "react-native"; +import type { AxiosError } from "axios"; +import { Alert, StyleSheet, Text, View } from "react-native"; +import { useState } from "react"; import FeedDetail from "@/components/feed/FeedDetail"; import useFeedLikeToggle from "@/hooks/feed/useFeedLikeToggle"; +import { useDeleteComment } from "@/hooks/comments/useCommentApi"; +import { useCreateReport } from "@/hooks/report/useReportApi"; import type { FeedDetailResult } from "@/types/feed/detail"; import type { RandomFeedPostType } from "@/types/feed/randomFeedApi.type"; @@ -14,6 +18,9 @@ type Props = { isCommentPending: boolean; }; +const getReportTargetLabel = (postType: RandomFeedPostType) => + postType === "DIARY" ? "일기" : "게시물"; + export default function FeedSeedDetailCard({ result, postType, @@ -23,6 +30,9 @@ export default function FeedSeedDetailCard({ onSubmitComment, isCommentPending, }: Props) { + const reportMutation = useCreateReport(); + const deleteCommentMutation = useDeleteComment(() => void onRefetch()); + const [isHidden, setIsHidden] = useState(false); const { liked, likeCount, toggleLike, isLikePending } = useFeedLikeToggle({ targetId: result.id, targetType: postType, @@ -31,13 +41,64 @@ export default function FeedSeedDetailCard({ onSuccessRefetch: onRefetch, }); + const handleReportPost = async () => { + try { + await reportMutation.mutateAsync({ + targetType: postType, + targetId: result.id, + reason: "부적절한 콘텐츠", + additionalComment: "", + }); + setIsHidden(true); + Alert.alert("신고 완료", "신고가 접수되었습니다."); + } catch (error) { + const axiosError = error as AxiosError<{ message?: string }>; + Alert.alert("신고 실패", axiosError.response?.data?.message ?? "잠시 후 다시 시도해주세요."); + throw error; + } + }; + + const handleReportComment = async (commentId: number) => { + try { + await reportMutation.mutateAsync({ + targetType: "COMMENT", + targetId: commentId, + reason: "부적절한 댓글", + additionalComment: "", + }); + Alert.alert("신고 완료", "신고가 접수되었습니다."); + } catch (error) { + const axiosError = error as AxiosError<{ message?: string }>; + Alert.alert("신고 실패", axiosError.response?.data?.message ?? "잠시 후 다시 시도해주세요."); + throw error; + } + }; + + const handleDeleteComment = async (commentId: number) => { + try { + await deleteCommentMutation.mutateAsync({ commentId, targetType: postType, targetId: result.id }); + Alert.alert("삭제 완료", "댓글이 삭제되었습니다."); + } catch (error) { + const axiosError = error as AxiosError<{ message?: string }>; + Alert.alert("삭제 실패", axiosError.response?.data?.message ?? "잠시 후 다시 시도해주세요."); + throw error; + } + }; + + if (isHidden) { + return ( + + 신고한 {getReportTargetLabel(postType)}입니다. + 이 항목은 나에게 숨김 처리되었습니다. + + ); + } + return ( - {/* 한글 주석: - 사용자가 둘러보기에서 처음 선택한 포스트는 항상 첫 카드로 고정하고, - 기존 상세 댓글 작성 UX도 댓글 시트 안에서만 유지한다. */} ); @@ -55,4 +120,19 @@ const styles = StyleSheet.create({ container: { backgroundColor: "#FFFFFF", }, + hiddenCard: { + paddingHorizontal: 20, + paddingVertical: 32, + backgroundColor: "#FFFFFF", + gap: 6, + }, + hiddenTitle: { + fontSize: 15, + fontWeight: "700", + color: "#171717", + }, + hiddenDescription: { + fontSize: 13, + color: "#6B7280", + }, }); diff --git a/src/components/profile/ProfileGardenScene.tsx b/src/components/profile/ProfileGardenScene.tsx index 299e569..064763d 100644 --- a/src/components/profile/ProfileGardenScene.tsx +++ b/src/components/profile/ProfileGardenScene.tsx @@ -6,7 +6,9 @@ import { useSafeAreaInsets } from "react-native-safe-area-context"; const mailboxImage = require("@/assets/images/profile/letterbox.png"); const wateringImage = require("@/assets/images/background/watering.png"); +const dropImage = require("@/assets/images/profile/drop.png"); const ACTION_RAIL_BOTTOM_OFFSET = 128; +const MAX_WATER_COUNT = 3; type Props = { background: any; @@ -31,16 +33,22 @@ export default function ProfileGardenScene({ }: Props) { const insets = useSafeAreaInsets(); const canWater = !isMe && garden.isWateringAbleByMe && !waterDisabled; - const topOverlayOffset = insets.top + 92; + const topOverlayOffset = insets.top + 144; return ( + {garden.avatarInfo?.avatarName ? ( + + {garden.avatarInfo.avatarName} + + ) : null} + {!isMe ? ( - - - {leftWaterCountForOthers}회 + + + {leftWaterCountForOthers}/{MAX_WATER_COUNT} ) : null} @@ -120,6 +128,23 @@ const styles = StyleSheet.create({ gap: 4, zIndex: 3, }, + scenePlantName: { + position: "absolute", + left: 0, + right: 0, + textAlign: "center", + fontSize: 28, + fontWeight: "600", + color: "#FFFFFF", + textShadowColor: "rgba(0, 0, 0, 0.18)", + textShadowOffset: { width: 0, height: 1 }, + textShadowRadius: 4, + zIndex: 3, + }, + waterDropIcon: { + width: 18, + height: 18, + }, waterCountText: { fontSize: 16, fontWeight: "700", @@ -191,32 +216,30 @@ const styles = StyleSheet.create({ width: 64, height: 64, borderRadius: 32, - backgroundColor: "rgba(255,255,255,0.18)", + backgroundColor: "#FFFFFF", alignItems: "center", justifyContent: "center", overflow: "hidden", }, actionButtonDisabled: { - backgroundColor: "rgba(255,255,255,0.08)", + backgroundColor: "rgba(255,255,255,0.5)", }, guestbookWrap: { - paddingHorizontal: 16, + paddingHorizontal: 20, paddingTop: 8, }, guestbookButton: { - borderRadius: 18, - backgroundColor: "rgba(255,255,255,0.92)", - paddingVertical: 18, + height: 56, + borderRadius: 8, + backgroundColor: "#FFFFFF", + borderWidth: 1, + borderColor: "#7DC960", alignItems: "center", - shadowColor: "#000", - shadowOffset: { width: 0, height: 2 }, - shadowOpacity: 0.08, - shadowRadius: 8, - elevation: 3, + justifyContent: "center", }, guestbookButtonText: { - fontSize: 15, - fontWeight: "700", - color: "#4CAF50", + fontSize: 18, + fontWeight: "600", + color: "#3AB40B", }, }); diff --git a/src/hooks/block/useBlockApi.ts b/src/hooks/block/useBlockApi.ts new file mode 100644 index 0000000..d725d9c --- /dev/null +++ b/src/hooks/block/useBlockApi.ts @@ -0,0 +1,24 @@ +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { deleteBlockUser, postBlockUser } from "@/apis/block/blockApi"; + +export const useBlockUser = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: (targetUserId: number) => postBlockUser(targetUserId), + onSuccess: async () => { + await queryClient.invalidateQueries({ queryKey: ["feed"] }); + }, + }); +}; + +export const useUnblockUser = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: (targetUserId: number) => deleteBlockUser(targetUserId), + onSuccess: async () => { + await queryClient.invalidateQueries({ queryKey: ["feed"] }); + }, + }); +}; diff --git a/src/hooks/comments/useCommentApi.ts b/src/hooks/comments/useCommentApi.ts index 383522a..fa6e6a3 100644 --- a/src/hooks/comments/useCommentApi.ts +++ b/src/hooks/comments/useCommentApi.ts @@ -1,18 +1,114 @@ -import { useMutation } from "@tanstack/react-query"; - +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import type { GlobalResponse } from "@/types/common/apiResponse.type"; import type { PostCommentRequest, PostCommentResponse, } from "@/types/comments/commentApi.type"; +import type { GETDiaryDetailResponse } from "@/types/log/diaryDetailApi.type"; +import type { GETAvatarPostDetailResponse } from "@/types/feed/avatarPostDetailApi.type"; +import { deleteComment, postComment } from "@/apis/comments/commentApi"; +import useTokenStore from "@/stores/useTokenStore"; +import { useHomeSummaryStore } from "@/stores/useHomeSummaryStore"; + +export type DeleteCommentVariables = { + commentId: number; + targetType: "DIARY" | "AVATAR_POST"; + targetId: number; +}; + +type DetailCache = GlobalResponse; + +type CommentMutateContext = { + previous: DetailCache | undefined; + queryKey: (string | number)[]; +}; + +const getDetailQueryKey = (targetType: "DIARY" | "AVATAR_POST", targetId: number) => + targetType === "DIARY" + ? ["diary-detail", targetId] + : ["avatar-post-detail", targetId]; -import { postComment } from "@/apis/comments/commentApi"; +export const usePostComment = (onSuccessRefetch?: () => void) => { + const queryClient = useQueryClient(); + const { userId } = useTokenStore(); + const { user } = useHomeSummaryStore(); -export const usePostComment = (onSuccessRefetch?: () => void) => - useMutation<{ result: PostCommentResponse }, unknown, PostCommentRequest>({ + return useMutation<{ result: PostCommentResponse }, unknown, PostCommentRequest, CommentMutateContext>({ mutationFn: (body: PostCommentRequest) => postComment(body), - onSuccess: () => { + onMutate: async ({ content, targetType, targetId }) => { + const queryKey = getDetailQueryKey(targetType, targetId); + await queryClient.cancelQueries({ queryKey }); + const previous = queryClient.getQueryData(queryKey); + + // 임시 음수 ID: 서버 응답 후 onSettled 리패치로 실제 ID로 교체됨 + const optimisticComment = { + commentId: -Date.now(), + writerId: Number(userId), + profileImageUrl: null, + writer: user?.username ?? "", + content, + }; + + queryClient.setQueryData(queryKey, old => + old + ? { + ...old, + result: { + ...old.result, + comments: [...old.result.comments, optimisticComment], + commentCount: old.result.commentCount + 1, + }, + } + : old + ); + + return { previous, queryKey }; + }, + onError: (_err, _vars, context) => { + if (context?.previous) { + queryClient.setQueryData(context.queryKey, context.previous); + } + }, + onSettled: () => { + onSuccessRefetch?.(); + }, + }); +}; + +export const useDeleteComment = (onSuccessRefetch?: () => void) => { + const queryClient = useQueryClient(); + + return useMutation<{ result: void }, unknown, DeleteCommentVariables, CommentMutateContext>({ + mutationFn: ({ commentId }) => deleteComment(commentId), + onMutate: async ({ commentId, targetType, targetId }) => { + const queryKey = getDetailQueryKey(targetType, targetId); + await queryClient.cancelQueries({ queryKey }); + const previous = queryClient.getQueryData(queryKey); + + queryClient.setQueryData(queryKey, old => + old + ? { + ...old, + result: { + ...old.result, + comments: old.result.comments.filter(c => c.commentId !== commentId), + commentCount: Math.max(0, old.result.commentCount - 1), + }, + } + : old + ); + + return { previous, queryKey }; + }, + onError: (_err, _vars, context) => { + if (context?.previous) { + queryClient.setQueryData(context.queryKey, context.previous); + } + }, + onSettled: () => { onSuccessRefetch?.(); }, }); +}; -export default usePostComment; +export default usePostComment; \ No newline at end of file diff --git a/src/hooks/follow/useFollowApi.ts b/src/hooks/follow/useFollowApi.ts index a6e422b..d07aff5 100644 --- a/src/hooks/follow/useFollowApi.ts +++ b/src/hooks/follow/useFollowApi.ts @@ -6,6 +6,10 @@ import { postFollowUser, } from "@/apis/follow/followApi"; import type { FollowResponse } from "@/types/follow"; +import { FollowStatus, type GetUserProfileResponse } from "@/types/profile/profileApi.type"; + +type ProfileCache = { result: GetUserProfileResponse }; +type FollowMutateContext = { previous: ProfileCache | undefined; queryKey: string[] }; export const useFollowing = (userId: string | undefined) => useQuery< @@ -36,8 +40,22 @@ export const useFollowers = (userId: string | undefined) => export const useFollowUser = (userId: string | undefined) => { const queryClient = useQueryClient(); - return useMutation({ + return useMutation({ mutationFn: (targetUserId: string | number) => postFollowUser(targetUserId), + onMutate: async (targetUserId: string | number) => { + const queryKey = ["profile", String(targetUserId)]; + await queryClient.cancelQueries({ queryKey }); + const previous = queryClient.getQueryData(queryKey); + queryClient.setQueryData(queryKey, old => + old ? { ...old, result: { ...old.result, followStatus: FollowStatus.FOLLOWING } } : old + ); + return { previous, queryKey }; + }, + onError: (_err, _targetUserId, context) => { + if (context?.previous !== undefined) { + queryClient.setQueryData(context.queryKey, context.previous); + } + }, onSuccess: async (_, targetUserId) => { await Promise.all([ queryClient.invalidateQueries({ queryKey: ["profile", String(targetUserId)] }), @@ -51,8 +69,22 @@ export const useFollowUser = (userId: string | undefined) => { export const useUnfollowUser = (userId: string | undefined) => { const queryClient = useQueryClient(); - return useMutation({ + return useMutation({ mutationFn: (targetUserId: string | number) => deleteFollowUser(targetUserId), + onMutate: async (targetUserId: string | number) => { + const queryKey = ["profile", String(targetUserId)]; + await queryClient.cancelQueries({ queryKey }); + const previous = queryClient.getQueryData(queryKey); + queryClient.setQueryData(queryKey, old => + old ? { ...old, result: { ...old.result, followStatus: FollowStatus.NOT_FOLLOWING } } : old + ); + return { previous, queryKey }; + }, + onError: (_err, _targetUserId, context) => { + if (context?.previous !== undefined) { + queryClient.setQueryData(context.queryKey, context.previous); + } + }, onSuccess: async (_, targetUserId) => { await Promise.all([ queryClient.invalidateQueries({ queryKey: ["profile", String(targetUserId)] }), diff --git a/src/hooks/home/useHomeApi.ts b/src/hooks/home/useHomeApi.ts index 6e07919..6ae6a78 100644 --- a/src/hooks/home/useHomeApi.ts +++ b/src/hooks/home/useHomeApi.ts @@ -39,6 +39,10 @@ export const useHomePanelApi = () => queryFn: getHomePanel, select: data => data.result, refetchOnMount: "always", + // 한글 주석: + // 미션 진행률은 1분 이내 재진입 시 캐시를 그대로 사용. + // 가든 씬(home-summary)보다 덜 긴급해서 background fetch 우선순위를 낮춤. + staleTime: 60_000, }); export const useTrackingPromptStatus = () => diff --git a/src/hooks/mission/useMissionApi.ts b/src/hooks/mission/useMissionApi.ts index f4451c7..7259ba5 100644 --- a/src/hooks/mission/useMissionApi.ts +++ b/src/hooks/mission/useMissionApi.ts @@ -21,6 +21,8 @@ import type { WriteDiaryRequest, WriteDiaryResponse, } from "@/types/missions"; +import type { GlobalResponse } from "@/types/common/apiResponse.type"; +import type { HomePanelPayload } from "@/types/home/panel"; import { createTimingLogger, debugLog } from "@/utils/debug"; export const useWriteDiaryImageUpload = () => @@ -43,8 +45,31 @@ export const useMissionQuiz = (params: GetQuizRequest) => export const useAnswerQuiz = () => { const queryClient = useQueryClient(); - return useMutation({ + return useMutation< + AnswerQuizResponse, + Error, + AnswerQuizRequest, + { previous: GlobalResponse | undefined } + >({ mutationFn: payload => answerQuizApi(payload), + onMutate: async () => { + /* + * 한글 주석: + * 퀴즈 정답 제출 즉시 홈 패널 캐시의 isQuizCompleted를 true로 설정해 + * 홈으로 돌아왔을 때 완료 애니메이션이 지연 없이 표시된다. + */ + await queryClient.cancelQueries({ queryKey: ["home-panel"] }); + const previous = queryClient.getQueryData>(["home-panel"]); + queryClient.setQueryData>(["home-panel"], old => + old ? { ...old, result: { ...old.result, isQuizCompleted: true } } : old + ); + return { previous }; + }, + onError: (_err, _vars, context) => { + if (context?.previous !== undefined) { + queryClient.setQueryData(["home-panel"], context.previous); + } + }, onSuccess: async () => { /* * 한글 주석: @@ -64,6 +89,10 @@ export const useDailySurvey = () => queryKey: ["daily-survey"], queryFn: getDailySurveyApi, select: data => data.result, + // 한글 주석: + // 감정 설문은 하루 1회만 바뀌므로 5분간 캐시 유지. + // 홈 재진입 시 불필요한 재요청 없이 즉시 감정 버튼 상태 표시. + staleTime: 5 * 60_000, }); export const useAnswerDailySurvey = () => { diff --git a/src/hooks/option/useNotificationApi.ts b/src/hooks/option/useNotificationApi.ts new file mode 100644 index 0000000..3deffdf --- /dev/null +++ b/src/hooks/option/useNotificationApi.ts @@ -0,0 +1,39 @@ +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { + getNotificationSettings, + patchNotificationSettings, + type NotificationSettings, +} from "@/apis/option/notificationApi"; +import type { GlobalResponse } from "@/types/common/apiResponse.type"; + +const SETTINGS_QUERY_KEY = ["notificationSettings"]; + +export const useNotificationSettings = () => + useQuery({ + queryKey: SETTINGS_QUERY_KEY, + queryFn: getNotificationSettings, + select: data => data.result, + }); + +export const useUpdateNotificationSettings = () => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: patchNotificationSettings, + onMutate: async newSettings => { + await queryClient.cancelQueries({ queryKey: SETTINGS_QUERY_KEY }); + const previous = queryClient.getQueryData>(SETTINGS_QUERY_KEY); + queryClient.setQueryData>(SETTINGS_QUERY_KEY, old => + old ? { ...old, result: { ...old.result, ...newSettings } } : old + ); + return { previous }; + }, + onError: (_err, _vars, context) => { + if (context?.previous) { + queryClient.setQueryData(SETTINGS_QUERY_KEY, context.previous); + } + }, + onSettled: () => { + void queryClient.invalidateQueries({ queryKey: SETTINGS_QUERY_KEY }); + }, + }); +}; diff --git a/src/hooks/profile/useGuestbookApi.ts b/src/hooks/profile/useGuestbookApi.ts index c1b141b..5b9da3e 100644 --- a/src/hooks/profile/useGuestbookApi.ts +++ b/src/hooks/profile/useGuestbookApi.ts @@ -6,6 +6,7 @@ import type { GuestbookEntry, } from "@/types/profile/guestbookApi.type"; import { getGuestbookList, postGuestbook } from "@/apis/profile/guestbookApi"; +import { useHomeSummaryStore } from "@/stores/useHomeSummaryStore"; export const useGuestbookList = (userId: string | number | undefined) => useQuery, AxiosError, GuestbookEntry[]>({ @@ -18,9 +19,34 @@ export const useGuestbookList = (userId: string | number | undefined) => export const useCreateGuestbook = (userId: string | number | undefined) => { const queryClient = useQueryClient(); + const currentUsername = useHomeSummaryStore(state => state.user?.username ?? ""); - return useMutation({ + return useMutation< + unknown, + AxiosError, + CreateGuestbookRequest, + { previous: GlobalResponse | undefined; queryKey: (string | number | undefined)[] } + >({ mutationFn: (body: CreateGuestbookRequest) => postGuestbook(String(userId), body), + onMutate: async (body: CreateGuestbookRequest) => { + const queryKey = ["guestbook-list", userId]; + await queryClient.cancelQueries({ queryKey }); + const previous = queryClient.getQueryData>(queryKey); + const optimisticEntry: GuestbookEntry = { + author: currentUsername, + content: body.content, + createdAt: new Date().toISOString(), + }; + queryClient.setQueryData>(queryKey, old => + old ? { ...old, result: [optimisticEntry, ...old.result] } : old + ); + return { previous, queryKey }; + }, + onError: (_err, _body, context) => { + if (context?.previous !== undefined) { + queryClient.setQueryData(context.queryKey, context.previous); + } + }, onSuccess: async () => { /* * 한글 주석: diff --git a/src/hooks/report/useReportApi.ts b/src/hooks/report/useReportApi.ts new file mode 100644 index 0000000..203668b --- /dev/null +++ b/src/hooks/report/useReportApi.ts @@ -0,0 +1,10 @@ +import { useMutation } from "@tanstack/react-query"; +import { postReport } from "@/apis/report/reportApi"; +import type { CreateReportPayload } from "@/types/report"; + +export const useCreateReport = () => + useMutation({ + mutationFn: (payload: CreateReportPayload) => postReport(payload), + }); + +export default useCreateReport; diff --git a/src/navigation/RootNavigator.tsx b/src/navigation/RootNavigator.tsx index 55944b0..041e56b 100644 --- a/src/navigation/RootNavigator.tsx +++ b/src/navigation/RootNavigator.tsx @@ -1,4 +1,4 @@ -import { createNativeStackNavigator } from "@react-navigation/native-stack"; +import { createNativeStackNavigator } from "@react-navigation/native-stack"; import type { RootStackParamList } from "./types"; import useTokenStore from "@/stores/useTokenStore"; import Splash from "@/components/common/Splash"; @@ -25,6 +25,8 @@ import DeliveryCompleteScreen from "@/pages/delivery/DeliveryCompleteScreen"; import UnlockGardenScreen from "@/pages/delivery/UnlockGardenScreen"; import RegistrationAvatarScreen from "@/pages/registration/RegistrationAvatarScreen"; import RegistrationCreationDetailScreen from "@/pages/registration/RegistrationCreationDetailScreen"; +import RegistrationCreationPendingScreen from "@/pages/registration/RegistrationCreationPendingScreen"; +import RegistrationCreationCompleteScreen from "@/pages/registration/RegistrationCreationCompleteScreen"; import RegistrationSelectionDetailScreen from "@/pages/registration/RegistrationSelectionDetailScreen"; import RegistrationPlantNicknameScreen from "@/pages/registration/RegistrationPlantNicknameScreen"; import DailyMissionWriteDiaryScreen from "@/pages/dailyMission/DailyMissionWriteDiaryScreen"; @@ -97,6 +99,16 @@ export default function RootNavigator() { component={RegistrationCreationDetailScreen} options={{ headerShown: false }} /> + + data?.quizOptions?.length ? data.quizOptions : [ - { optionOrder: 0, optionText: "O" }, - { optionOrder: 1, optionText: "X" }, - ], + () => + data?.quizOptions?.length + ? data.quizOptions + : [ + { optionOrder: 0, optionText: "O" }, + { optionOrder: 1, optionText: "X" }, + ], [data?.quizOptions] ); @@ -33,11 +34,6 @@ export default function DailyMissionQuizOxScreen({ navigation }: Props) { } }, [data?.selectedOptionNumber]); - /* - * 한글 주석: - * OX 퀴즈도 객관식과 같은 복원 규칙을 써야 화면을 나갔다 와도 - * 사용자가 고른 답과 해설을 다시 그대로 보여줄 수 있다. - */ const persistedAnswerResult = useMemo(() => { if ( !data?.isCompleted || @@ -73,16 +69,22 @@ export default function DailyMissionQuizOxScreen({ navigation }: Props) { }); }; - const goHome = () => + const goNext = () => { + if (navigation.canGoBack()) { + navigation.goBack(); + return; + } + navigation.reset({ index: 0, routes: [{ name: "Main", params: { screen: "Home" } }], }); + }; if (isLoading) { return ( - navigation.goBack()} /> + navigation.goBack()} /> ); @@ -91,7 +93,7 @@ export default function DailyMissionQuizOxScreen({ navigation }: Props) { if (isError) { return ( - navigation.goBack()} /> + navigation.goBack()} /> - navigation.goBack()} /> + navigation.goBack()} /> ); } return ( - - navigation.goBack()} /> + + navigation.goBack()} /> - 오늘의 퀴즈 + 오늘의 퀴즈! {data.quizQuestion} - + {options.map(option => { const state = answerResult != null @@ -132,15 +134,16 @@ export default function DailyMissionQuizOxScreen({ navigation }: Props) { : option.optionOrder === answerResult.answerNumber ? "answer" : "idle" - : "idle"; + : selected === option.optionOrder + ? "selected" + : "idle"; return ( - setSelected(option.optionOrder)} /> ); @@ -148,30 +151,56 @@ export default function DailyMissionQuizOxScreen({ navigation }: Props) { {answerResult ? ( - + + + {answerResult.isCorrect ? "정답!" : "오답!"} + + + {answerResult.answerDescription} + + ) : null} {submitAnswer.isError ? ( - + 정답 제출에 실패했습니다. - - OX 퀴즈도 객관식과 같은 답안 API를 사용합니다. 서버 응답 계약을 다시 확인해야 합니다. - + 잠시 후 다시 시도해주세요. ) : null} - void handleSubmit()} - primaryDisabled={answerResult ? false : selected === null || submitAnswer.isPending} - primaryLoading={submitAnswer.isPending} - /> + + void handleSubmit()} + style={[ + styles.primaryButton, + !answerResult && selected === null ? styles.primaryButtonDisabled : null, + answerResult ? styles.primaryButtonNext : null, + ]} + > + + {answerResult ? "다음" : submitAnswer.isPending ? "확인 중..." : "정답 확인하기"} + + + ); } @@ -179,44 +208,103 @@ export default function DailyMissionQuizOxScreen({ navigation }: Props) { const styles = StyleSheet.create({ safeArea: { flex: 1, - backgroundColor: "#F7F8F4", + backgroundColor: "#FFFFFF", }, content: { - padding: 20, - gap: 18, + paddingHorizontal: 20, + paddingTop: 34, + paddingBottom: 24, }, headerBlock: { - gap: 8, + gap: 10, + marginBottom: 52, }, - eyebrow: { - fontSize: 12, - color: "#2F7D32", - fontWeight: "700", + title: { + fontSize: 20, + lineHeight: 28, + fontWeight: "600", + color: "#171717", }, question: { - fontSize: 24, - lineHeight: 32, - fontWeight: "700", + fontSize: 16, + lineHeight: 26, + fontWeight: "400", color: "#171717", }, - options: { + optionsRow: { + flexDirection: "row", + gap: 12, + marginBottom: 34, + }, + resultBlock: { gap: 12, }, - errorCard: { - borderRadius: 16, - padding: 16, - backgroundColor: "#FEF2F2", + resultTitle: { + fontSize: 16, + lineHeight: 24, + fontWeight: "700", + }, + resultTitleCorrect: { + color: "#46C02B", + }, + resultTitleWrong: { + color: "#FF6B6B", + }, + resultDescription: { + fontSize: 14, + lineHeight: 28, + fontWeight: "400", + }, + resultDescriptionCorrect: { + color: "#46C02B", + }, + resultDescriptionWrong: { + color: "#FF6B6B", + }, + errorBlock: { + marginTop: 20, gap: 6, }, errorTitle: { - fontSize: 16, + fontSize: 15, fontWeight: "700", color: "#B91C1C", }, errorDescription: { - fontSize: 14, + fontSize: 13, lineHeight: 20, color: "#7F1D1D", }, + footer: { + paddingHorizontal: 20, + paddingTop: 16, + paddingBottom: 28, + }, + primaryButton: { + minHeight: 56, + borderRadius: 8, + backgroundColor: "#6FCF4A", + alignItems: "center", + justifyContent: "center", + }, + primaryButtonDisabled: { + backgroundColor: "#EFEFEF", + }, + primaryButtonNext: { + backgroundColor: "#EFF9EA", + }, + primaryButtonText: { + fontSize: 18, + lineHeight: 27, + fontWeight: "600", + color: "#FFFFFF", + }, + primaryButtonTextDisabled: { + color: "#BFBFBF", + }, + primaryButtonTextNext: { + color: "#46C02B", + }, }); + diff --git a/src/pages/delivery/DeliveryCompleteScreen.tsx b/src/pages/delivery/DeliveryCompleteScreen.tsx index d1fd7bc..c0f2765 100644 --- a/src/pages/delivery/DeliveryCompleteScreen.tsx +++ b/src/pages/delivery/DeliveryCompleteScreen.tsx @@ -1,11 +1,13 @@ -import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import { Image, StyleSheet, Text, TouchableOpacity, View } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; import ScreenHeader from "@/components/common/ScreenHeader"; import type { RootStackScreenProps } from "@/navigation/types"; type Props = RootStackScreenProps<"DeliveryComplete">; -export default function DeliveryCompleteScreen({ navigation, route }: Props) { +const packagePlantImage = require("@/assets/images/plant.png"); + +export default function DeliveryCompleteScreen({ navigation }: Props) { const handleDone = () => { navigation.reset({ index: 0, @@ -14,37 +16,27 @@ export default function DeliveryCompleteScreen({ navigation, route }: Props) { }; return ( - - + + + + + + - - Step 3 / 3 + + 배송 요청이 완료되었어요! + 3~7일 이내 자택으로 배송될 예정이에요. + 이제 텃밭을 열고, 새로운 식물을 키울 수 있어요. - 배송 요청이 완료되었어요. - - {route.params?.seedName - ? `${route.params.seedName} 배송 요청이 접수되었습니다.` - : "선택한 식물의 배송 요청이 접수되었습니다."} - - - 웹 기준 메시지처럼 3~7일 내 배송 안내를 노출했고, 이후 홈으로 돌아가서 정원 확장 흐름을 이어갈 수 있게 구성했습니다. - - - 다음에 이어질 흐름 - - 정원 unlock 완료 처리와 배송 상태 추적은 서버 계약 확인 후 다음 단계에서 보강할 수 있습니다. - + + - - 홈으로 돌아가기 + + 다음 @@ -54,71 +46,66 @@ export default function DeliveryCompleteScreen({ navigation, route }: Props) { const styles = StyleSheet.create({ safeArea: { flex: 1, - backgroundColor: "#F7F8F4", + backgroundColor: "#FFFFFF", }, - content: { - flex: 1, - padding: 24, - justifyContent: "center", - gap: 18, + progressTrack: { + marginHorizontal: 20, + marginTop: 16, + height: 4, + borderRadius: 999, + backgroundColor: "#F1F1F1", + overflow: "hidden", }, - badge: { - alignSelf: "flex-start", + progressFill: { + height: "100%", borderRadius: 999, - backgroundColor: "#DDF3DE", - paddingHorizontal: 12, - paddingVertical: 6, + backgroundColor: "#6FCF4A", }, - badgeText: { - fontSize: 12, - fontWeight: "700", - color: "#1F5C27", + content: { + flex: 1, + paddingHorizontal: 20, + paddingTop: 48, + justifyContent: "space-between", + }, + headerBlock: { + gap: 10, }, title: { - fontSize: 28, - lineHeight: 36, + fontSize: 18, + lineHeight: 28, fontWeight: "700", color: "#171717", }, description: { - fontSize: 15, - lineHeight: 24, - color: "#4B5563", - }, - messageCard: { - borderRadius: 20, - padding: 18, - backgroundColor: "#FFFFFF", - gap: 8, - }, - cardTitle: { fontSize: 16, - fontWeight: "700", + lineHeight: 26, color: "#171717", }, - cardText: { - fontSize: 14, - lineHeight: 20, - color: "#4B5563", + imageWrap: { + alignItems: "center", + justifyContent: "center", + paddingBottom: 48, + }, + image: { + width: 260, + height: 260, }, footer: { - paddingHorizontal: 24, - paddingBottom: 20, + paddingHorizontal: 20, paddingTop: 12, - borderTopWidth: 1, - borderTopColor: "#E5E7EB", - backgroundColor: "#FFFFFF", + paddingBottom: 20, }, primaryButton: { + minHeight: 56, + borderRadius: 8, alignItems: "center", justifyContent: "center", - minHeight: 54, - borderRadius: 16, - backgroundColor: "#2F7D32", + backgroundColor: "#6FCF4A", }, primaryButtonText: { - fontSize: 15, - fontWeight: "700", + fontSize: 18, + lineHeight: 27, + fontWeight: "600", color: "#FFFFFF", }, }); diff --git a/src/pages/delivery/DeliveryScreen.tsx b/src/pages/delivery/DeliveryScreen.tsx index 1a2fb25..a2bd66d 100644 --- a/src/pages/delivery/DeliveryScreen.tsx +++ b/src/pages/delivery/DeliveryScreen.tsx @@ -1,17 +1,11 @@ -import { useMemo, useState } from "react"; -import { - ScrollView, - StyleSheet, - Text, - TouchableOpacity, - View, -} from "react-native"; +import { useMemo, useState } from "react"; +import { Alert, ScrollView, StyleSheet, Text, TouchableOpacity, View } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; import ScreenHeader from "@/components/common/ScreenHeader"; import StatusView from "@/components/common/StatusView"; import DeliveryRequestSelector from "@/components/delivery/DeliveryRequestSelector"; import DeliveryTextField from "@/components/delivery/DeliveryTextField"; -import { useCreateSeedDelivery } from "@/hooks/delivery/useDeliveryApi"; +import { useCreateSeedDelivery, useUnlockGarden } from "@/hooks/delivery/useDeliveryApi"; import type { RootStackScreenProps } from "@/navigation/types"; import { useHomeSummaryStore } from "@/stores/useHomeSummaryStore"; @@ -19,7 +13,11 @@ type Props = RootStackScreenProps<"Delivery">; export default function DeliveryScreen({ navigation, route }: Props) { const user = useHomeSummaryStore(state => state.user); + const gardens = useHomeSummaryStore(state => state.gardens); + const updateGarden = useHomeSummaryStore(state => state.updateGarden); + const setUser = useHomeSummaryStore(state => state.setUser); const createSeedDelivery = useCreateSeedDelivery(); + const unlockGarden = useUnlockGarden(); const [recipientName, setRecipientName] = useState(user?.username ?? ""); const [recipientPhone, setRecipientPhone] = useState(""); @@ -31,6 +29,12 @@ export default function DeliveryScreen({ navigation, route }: Props) { const seedType = route.params?.seedType; const seedName = route.params?.seedName; + const gardenId = route.params?.gardenId; + const gardenSlotNumber = route.params?.gardenSlotNumber; + const selectedGarden = useMemo( + () => gardens.find(garden => garden.gardenId === gardenId) ?? null, + [gardenId, gardens] + ); const resolvedMessage = message === "직접 입력" ? customMessage.trim() : message; const isFormValid = useMemo( @@ -52,11 +56,14 @@ export default function DeliveryScreen({ navigation, route }: Props) { return; } - navigation.navigate("UnlockGarden"); + navigation.navigate("UnlockGarden", { + gardenId, + gardenSlotNumber, + }); }; const handleSubmit = async () => { - if (!seedType || !isFormValid || createSeedDelivery.isPending) { + if (!seedType || !isFormValid || createSeedDelivery.isPending || unlockGarden.isPending) { return; } @@ -68,42 +75,63 @@ export default function DeliveryScreen({ navigation, route }: Props) { postalCode: postalCode.trim(), address: address.trim(), addressDetail: addressDetail.trim(), - message: resolvedMessage, + message: resolvedMessage || undefined, }); + await unlockGarden.mutateAsync(); + + if (selectedGarden) { + updateGarden(selectedGarden.gardenId, { + isLocked: false, + locked: false, + isUnlockable: false, + unlockable: false, + avatar: null, + }); + } + + if (user) { + setUser({ + ...user, + lastAccessedSlotNumber: gardenSlotNumber ?? user.lastAccessedSlotNumber, + }); + } + navigation.replace("DeliveryComplete", { seedName, - gardenId: route.params?.gardenId, + gardenId, + gardenSlotNumber, }); - } catch { - // Error state is rendered below through mutation state. + } catch (error) { + if (error instanceof Error) { + Alert.alert("진행 실패", error.message); + } } }; if (!seedType) { return ( - + navigation.replace("UnlockGarden")} + onAction={() => navigation.replace("UnlockGarden", { gardenId, gardenSlotNumber })} /> ); } return ( - - - - - Step 2 / 3 - 배송 받을 정보를 입력해주세요. - - 선택한 식물: {seedName ?? `씨앗 타입 #${seedType}`} - + + + + + + + + + 배송 정보를 입력해주세요 @@ -124,26 +152,25 @@ export default function DeliveryScreen({ navigation, route }: Props) { - 주소 정보 + 배송지 정보 @@ -153,45 +180,36 @@ export default function DeliveryScreen({ navigation, route }: Props) { onChange={setMessage} onChangeCustom={setCustomMessage} /> - - {createSeedDelivery.isError ? ( - - 배송 요청을 완료하지 못했습니다. - - `POST /api/v1/deliveries/seeds` 호출에 실패했습니다. 요청 필드 계약과 서버 상태를 다시 확인해야 합니다. - - - ) : null} - - - 현재 연결된 범위 - - 배송 신청은 MainFE에서 확인된 payload 구조만 사용합니다. 주소 검색, 배송 조회, 수정 기능은 이번 단계 범위 밖입니다. - - navigation.navigate("Main", { screen: "Home" })} style={styles.secondaryButton} - activeOpacity={0.85} - onPress={handleBack} > - 이전 + 나중에 받기 void handleSubmit()} style={[ styles.primaryButton, - !isFormValid || createSeedDelivery.isPending + !isFormValid || createSeedDelivery.isPending || unlockGarden.isPending ? styles.primaryButtonDisabled : null, ]} - activeOpacity={0.85} - disabled={!isFormValid || createSeedDelivery.isPending} - onPress={() => void handleSubmit()} > - - {createSeedDelivery.isPending ? "전송 중..." : "배송 요청 완료"} + + {createSeedDelivery.isPending || unlockGarden.isPending ? "진행 중..." : "다음"} @@ -202,109 +220,84 @@ export default function DeliveryScreen({ navigation, route }: Props) { const styles = StyleSheet.create({ safeArea: { flex: 1, - backgroundColor: "#F7F8F4", - }, - content: { - padding: 20, - gap: 20, - }, - heroCard: { - borderRadius: 22, - padding: 20, - backgroundColor: "#255137", - gap: 8, + backgroundColor: "#FFFFFF", }, - eyebrow: { - fontSize: 12, - color: "#D7E9D8", + progressTrack: { + marginHorizontal: 20, + marginTop: 16, + height: 4, + borderRadius: 999, + backgroundColor: "#F1F1F1", + overflow: "hidden", }, - heroTitle: { - fontSize: 24, - lineHeight: 32, - fontWeight: "700", - color: "#FFFFFF", + progressFill: { + height: "100%", + borderRadius: 999, + backgroundColor: "#6FCF4A", }, - heroDescription: { - fontSize: 14, - lineHeight: 20, - color: "#E5F4E5", + content: { + paddingHorizontal: 20, + paddingTop: 48, + paddingBottom: 24, + gap: 36, }, - section: { + headerBlock: { gap: 12, }, - sectionTitle: { + title: { fontSize: 18, + lineHeight: 28, fontWeight: "700", color: "#171717", }, - errorCard: { - borderRadius: 18, - padding: 16, - backgroundColor: "#FEF2F2", - gap: 6, - }, - errorTitle: { - fontSize: 16, - fontWeight: "700", - color: "#B91C1C", - }, - errorDescription: { - fontSize: 14, - lineHeight: 20, - color: "#7F1D1D", - }, - infoCard: { - borderRadius: 18, - padding: 16, - backgroundColor: "#EEF3EA", - gap: 8, + section: { + gap: 18, }, - infoTitle: { - fontSize: 16, + sectionTitle: { + fontSize: 18, + lineHeight: 27, fontWeight: "700", color: "#171717", }, - infoDescription: { - fontSize: 14, - lineHeight: 20, - color: "#4B5563", - }, footer: { flexDirection: "row", gap: 12, paddingHorizontal: 20, - paddingVertical: 16, - borderTopWidth: 1, - borderTopColor: "#E5E7EB", - backgroundColor: "#FFFFFF", + paddingTop: 12, + paddingBottom: 20, }, secondaryButton: { flex: 1, + minHeight: 56, + borderRadius: 8, alignItems: "center", justifyContent: "center", - minHeight: 52, - borderRadius: 16, - backgroundColor: "#E5E7EB", + backgroundColor: "#EFF9EA", }, secondaryButtonText: { - fontSize: 15, - fontWeight: "700", - color: "#374151", + fontSize: 18, + lineHeight: 27, + fontWeight: "600", + color: "#46C02B", }, primaryButton: { flex: 1, + minHeight: 56, + borderRadius: 8, alignItems: "center", justifyContent: "center", - minHeight: 52, - borderRadius: 16, - backgroundColor: "#2F7D32", + backgroundColor: "#6FCF4A", }, primaryButtonDisabled: { - backgroundColor: "#A7D4A5", + backgroundColor: "#EAEAEA", }, primaryButtonText: { - fontSize: 15, - fontWeight: "700", + fontSize: 18, + lineHeight: 27, + fontWeight: "600", color: "#FFFFFF", }, + primaryButtonTextDisabled: { + color: "#BFBFBF", + }, }); diff --git a/src/pages/delivery/UnlockGardenScreen.tsx b/src/pages/delivery/UnlockGardenScreen.tsx index 7e0ccdc..a0e502a 100644 --- a/src/pages/delivery/UnlockGardenScreen.tsx +++ b/src/pages/delivery/UnlockGardenScreen.tsx @@ -1,59 +1,31 @@ -import { useEffect, useMemo, useState } from "react"; -import { - Alert, - ScrollView, - StyleSheet, - Text, - TouchableOpacity, - View, -} from "react-native"; +import { useEffect, useMemo, useState } from "react"; +import { ScrollView, StyleSheet, Text, TouchableOpacity, View } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; import ScreenHeader from "@/components/common/ScreenHeader"; import StatusView from "@/components/common/StatusView"; -import GardenSlotCard from "@/components/delivery/GardenSlotCard"; import PlantOptionCard from "@/components/delivery/PlantOptionCard"; -import { useDeliverablePlants, useUnlockGarden } from "@/hooks/delivery/useDeliveryApi"; -import useHomeApi from "@/hooks/home/useHomeApi"; +import { useDeliverablePlants } from "@/hooks/delivery/useDeliveryApi"; import type { RootStackScreenProps } from "@/navigation/types"; import { useHomeSummaryStore } from "@/stores/useHomeSummaryStore"; import { getGardenLocked, getGardenUnlockable } from "@/types/home/garden"; type Props = RootStackScreenProps<"UnlockGarden">; -export default function UnlockGardenScreen({ navigation }: Props) { - const { - data: homeData, - refetch: refetchHome, - } = useHomeApi(); - const { - data: plants, - error, - isLoading, - refetch, - } = useDeliverablePlants(); - const unlockGarden = useUnlockGarden(); - const { gardens, hydrate } = useHomeSummaryStore(); +export default function UnlockGardenScreen({ navigation, route }: Props) { + const { data: plants, error, isLoading, refetch } = useDeliverablePlants(); + const gardens = useHomeSummaryStore(state => state.gardens); const [selectedSeedType, setSelectedSeedType] = useState(null); - const [selectedGardenId, setSelectedGardenId] = useState(null); - useEffect(() => { - if (homeData) { - hydrate(homeData); + const selectedGarden = useMemo(() => { + if (route.params?.gardenId) { + const routedGarden = gardens.find(garden => garden.gardenId === route.params?.gardenId); + if (routedGarden && getGardenLocked(routedGarden)) { + return routedGarden; + } } - }, [homeData, hydrate]); - - const lockedGardens = useMemo( - () => gardens.filter(garden => getGardenLocked(garden)), - [gardens] - ); - useEffect(() => { - if (!selectedGardenId && lockedGardens.length > 0) { - const initialGarden = - lockedGardens.find(garden => getGardenUnlockable(garden)) ?? lockedGardens[0]; - setSelectedGardenId(initialGarden.gardenId); - } - }, [lockedGardens, selectedGardenId]); + return gardens.find(garden => getGardenLocked(garden) && getGardenUnlockable(garden)) ?? null; + }, [gardens, route.params?.gardenId]); useEffect(() => { if (!selectedSeedType && plants && plants.length > 0) { @@ -61,11 +33,7 @@ export default function UnlockGardenScreen({ navigation }: Props) { } }, [plants, selectedSeedType]); - const selectedPlant = - plants?.find(plant => plant.seedType === selectedSeedType) ?? null; - const selectedGarden = - lockedGardens.find(garden => garden.gardenId === selectedGardenId) ?? null; - const canUnlock = Boolean(selectedGarden && getGardenUnlockable(selectedGarden)); + const selectedPlant = plants?.find(plant => plant.seedType === selectedSeedType) ?? null; const handleBack = () => { if (navigation.canGoBack()) { @@ -76,34 +44,11 @@ export default function UnlockGardenScreen({ navigation }: Props) { navigation.navigate("Main", { screen: "Home" }); }; - const handleUnlock = async () => { - if (!canUnlock || unlockGarden.isPending) { - return; - } - - try { - await unlockGarden.mutateAsync(); - await refetchHome(); - Alert.alert("정원 해금 완료", "홈에서 변경된 정원 상태를 확인할 수 있습니다.", [ - { - text: "홈으로 이동", - onPress: () => navigation.navigate("Main", { screen: "Home" }), - }, - ]); - } catch (unlockError) { - const message = - unlockError instanceof Error - ? unlockError.message - : "정원 해금 중 오류가 발생했습니다."; - Alert.alert("정원 해금 실패", message); - } - }; - if (isLoading) { return ( - + ); } @@ -114,7 +59,6 @@ export default function UnlockGardenScreen({ navigation }: Props) { void refetch()} /> @@ -122,114 +66,98 @@ export default function UnlockGardenScreen({ navigation }: Props) { ); } + if (!selectedGarden) { + return ( + + + + + ); + } + if (!plants || plants.length === 0) { return ( ); } return ( - + + + + + - - 정원 해금 - - 해금 가능한 슬롯을 선택하고 정원을 열어주세요. - - - 정원 해금은 `POST /api/v1/gardens/unlock`를 body 없이 호출하고, 성공 후 홈 데이터를 다시 조회합니다. + + 원하는 식물을 선택해주세요 + + 선택한 씨앗은 새로 열리는 텃밭 {selectedGarden.gardenSlotNumber}번으로 배송 요청됩니다. - - 잠금 슬롯 상태 - - 홈 summary에 내려온 `isLocked`, `isUnlockable` 상태를 기준으로 표시합니다. - - {lockedGardens.length > 0 ? ( - lockedGardens.map(garden => ( - setSelectedGardenId(garden.gardenId)} - /> - )) - ) : ( - - 잠금된 정원 슬롯이 없습니다. - - 홈 summary에 잠금 슬롯이 내려오면 이 화면에서 바로 확인할 수 있습니다. - - - )} - + + {plants.map(plant => ( + setSelectedSeedType(plant.seedType)} + /> + ))} + - - 배송 받을 식물 - - 배송은 정원 해금과 독립적인 흐름이라, 필요할 때만 별도로 진행합니다. - - - {plants.map(plant => ( - setSelectedSeedType(plant.seedType)} - /> - ))} - - + {selectedPlant ? {selectedPlant.name} : null} - {unlockGarden.isError ? ( - - 정원 해금에 실패했습니다. - - 서버 공통 에러 응답을 확인한 뒤 다시 시도해주세요. - - - ) : null} + + {plants.map(plant => ( + + ))} + navigation.navigate("Main", { screen: "Home" })} style={styles.secondaryButton} - activeOpacity={0.85} + > + 나중에 받기 + + navigation.navigate("Delivery", { seedType: selectedPlant?.seedType, seedName: selectedPlant?.name, - gardenId: selectedGardenId ?? undefined, + gardenId: selectedGarden.gardenId, + gardenSlotNumber: selectedGarden.gardenSlotNumber, }) } - disabled={!selectedPlant} + style={[styles.primaryButton, !selectedPlant ? styles.primaryButtonDisabled : null]} > - 배송 정보 입력 - - void handleUnlock()} - > - - {unlockGarden.isPending ? "해금 중..." : "정원 해금하기"} - + 다음 @@ -239,118 +167,106 @@ export default function UnlockGardenScreen({ navigation }: Props) { const styles = StyleSheet.create({ safeArea: { flex: 1, - backgroundColor: "#F7F8F4", - }, - content: { - padding: 20, - gap: 20, - }, - heroCard: { - borderRadius: 22, - padding: 20, - backgroundColor: "#234A2F", - gap: 8, + backgroundColor: "#FFFFFF", }, - eyebrow: { - fontSize: 12, - color: "#D7E9D8", + progressTrack: { + marginHorizontal: 20, + marginTop: 16, + height: 4, + borderRadius: 999, + backgroundColor: "#F1F1F1", + overflow: "hidden", }, - heroTitle: { - fontSize: 24, - lineHeight: 32, - fontWeight: "700", - color: "#FFFFFF", + progressFill: { + height: "100%", + borderRadius: 999, + backgroundColor: "#6FCF4A", }, - heroDescription: { - fontSize: 14, - lineHeight: 20, - color: "#E5F4E5", + content: { + paddingHorizontal: 20, + paddingTop: 48, + paddingBottom: 24, }, - section: { - gap: 10, + headerBlock: { + gap: 12, + marginBottom: 40, }, - sectionTitle: { + title: { fontSize: 18, + lineHeight: 28, fontWeight: "700", color: "#171717", }, - sectionDescription: { - fontSize: 13, - lineHeight: 18, - color: "#6B7280", - }, - horizontalList: { - gap: 12, - paddingRight: 20, + description: { + fontSize: 14, + lineHeight: 22, + color: "#171717", }, - infoCard: { - borderRadius: 18, - padding: 16, - backgroundColor: "#EEF3EA", - gap: 8, + carousel: { + gap: 18, + paddingHorizontal: 48, }, - infoTitle: { - fontSize: 16, + selectedName: { + marginTop: 18, + textAlign: "center", + fontSize: 18, + lineHeight: 27, fontWeight: "700", color: "#171717", }, - infoDescription: { - fontSize: 14, - lineHeight: 20, - color: "#4B5563", + pagination: { + marginTop: 12, + flexDirection: "row", + justifyContent: "center", + gap: 8, }, - errorCard: { - borderRadius: 18, - padding: 16, - backgroundColor: "#FEF2F2", - gap: 6, + dot: { + width: 8, + height: 8, + borderRadius: 999, }, - errorTitle: { - fontSize: 16, - fontWeight: "700", - color: "#B91C1C", + dotActive: { + backgroundColor: "#7A7A7A", }, - errorDescription: { - fontSize: 14, - lineHeight: 20, - color: "#7F1D1D", + dotInactive: { + backgroundColor: "#E2E2E2", }, footer: { flexDirection: "row", gap: 12, paddingHorizontal: 20, - paddingVertical: 16, - borderTopWidth: 1, - borderTopColor: "#E5E7EB", - backgroundColor: "#FFFFFF", + paddingTop: 12, + paddingBottom: 20, }, secondaryButton: { flex: 1, + minHeight: 56, + borderRadius: 8, alignItems: "center", justifyContent: "center", - minHeight: 52, - borderRadius: 16, - backgroundColor: "#E5E7EB", + backgroundColor: "#EFF9EA", }, secondaryButtonText: { - fontSize: 15, - fontWeight: "700", - color: "#374151", + fontSize: 18, + lineHeight: 27, + fontWeight: "600", + color: "#46C02B", }, primaryButton: { flex: 1, + minHeight: 56, + borderRadius: 8, alignItems: "center", justifyContent: "center", - minHeight: 52, - borderRadius: 16, - backgroundColor: "#2F7D32", + backgroundColor: "#6FCF4A", }, primaryButtonDisabled: { - backgroundColor: "#A7D4A5", + backgroundColor: "#EAEAEA", }, primaryButtonText: { - fontSize: 15, - fontWeight: "700", + fontSize: 18, + lineHeight: 27, + fontWeight: "600", color: "#FFFFFF", }, }); diff --git a/src/pages/feed/FeedScreen.tsx b/src/pages/feed/FeedScreen.tsx index 4d01a0c..ddb22a4 100644 --- a/src/pages/feed/FeedScreen.tsx +++ b/src/pages/feed/FeedScreen.tsx @@ -1,16 +1,19 @@ -import React from "react"; +import React, { useState, useCallback } from "react"; import { RefreshControl, View, Text, TouchableOpacity, ScrollView, + ActivityIndicator, StyleSheet, } from "react-native"; + +const FEED_PAGE_SIZE = 10; import { SafeAreaView } from "react-native-safe-area-context"; import type { MainTabScreenProps } from "@/navigation/types"; -import { UserPlusIcon } from "@/assets/icons/CommonIcons"; +import { RefreshIcon, UserPlusIcon } from "@/assets/icons/CommonIcons"; import StatusView from "@/components/common/StatusView"; import FeedList from "@/components/feed/FeedList"; import { useFeed } from "@/hooks/feed/useFeedApi"; @@ -19,6 +22,7 @@ type Props = MainTabScreenProps<"Feed">; export default function FeedScreen({ navigation }: Props) { const { data: result, isLoading, isRefetching, error, refetch } = useFeed(); + const [displayCount, setDisplayCount] = useState(FEED_PAGE_SIZE); const handleUserPlusClick = () => { navigation.navigate("Follow"); @@ -32,22 +36,38 @@ export default function FeedScreen({ navigation }: Props) { } }; - // API 결과가 null/빈 배열이면 빈 배열로 대체 - const dataForRender = result && result.length > 0 ? result : []; + const handleRefetch = useCallback(() => { + setDisplayCount(FEED_PAGE_SIZE); + void refetch(); + }, [refetch]); + + const handleScroll = useCallback( + ({ nativeEvent }: { nativeEvent: { layoutMeasurement: { height: number }; contentOffset: { y: number }; contentSize: { height: number } } }) => { + const { layoutMeasurement, contentOffset, contentSize } = nativeEvent; + const isNearBottom = layoutMeasurement.height + contentOffset.y >= contentSize.height - 200; + if (isNearBottom && displayCount < (result?.length ?? 0)) { + setDisplayCount(prev => Math.min(prev + FEED_PAGE_SIZE, result?.length ?? prev)); + } + }, + [displayCount, result?.length] + ); + + const allData = result && result.length > 0 ? result : []; + const dataForRender = allData.slice(0, displayCount); + const hasMore = displayCount < allData.length; return ( - {/* Header spacing is tuned to match the centered title layout from the FE design. */} void refetch()} + style={styles.headerIconButton} + onPress={handleRefetch} activeOpacity={0.7} disabled={isLoading || isRefetching} + accessibilityRole="button" + accessibilityLabel="새로고침" > - - 새로고침 - + 둘러보기 void refetch()} + onRefresh={handleRefetch} tintColor="#7DC960" /> } > - {/* 한글 주석: - 피드 메인에서는 빈 상태와 로딩 상태를 리스트 컴포넌트가 맡고, - 네트워크 재시도는 상단 버튼과 pull-to-refresh 둘 다 열어 둔다. */} + {hasMore && ( + + + + )} )} @@ -113,18 +137,11 @@ const styles = StyleSheet.create({ fontWeight: "700", color: "#171717", }, - headerTextButton: { - minWidth: 56, + headerIconButton: { + width: 24, + alignItems: "center", justifyContent: "center", }, - headerTextButtonLabel: { - fontSize: 14, - fontWeight: "600", - color: "#374151", - }, - headerTextButtonDisabled: { - color: "#9CA3AF", - }, headerButton: { width: 24, alignItems: "center", @@ -132,4 +149,8 @@ const styles = StyleSheet.create({ scrollView: { flex: 1, }, + loadMoreIndicator: { + paddingVertical: 16, + alignItems: "center", + }, }); diff --git a/src/pages/follow/FollowScreen.tsx b/src/pages/follow/FollowScreen.tsx index b531266..0640b36 100644 --- a/src/pages/follow/FollowScreen.tsx +++ b/src/pages/follow/FollowScreen.tsx @@ -1,5 +1,6 @@ import { useState } from "react"; import { + Alert, Image, RefreshControl, ScrollView, @@ -58,6 +59,28 @@ export default function FollowScreen({ navigation }: Props) { void followersQuery.refetch(); }; + const handleConfirmRemoveFriend = (targetUserId: number) => { + if (unfollowMutation.isPending) { + return; + } + + Alert.alert( + "친구 삭제하기", + "사용자를 친구에서 삭제하시겠습니까?\n언제든 다시 추가할 수 있습니다.", + [ + { + text: "취소", + style: "cancel", + }, + { + text: "삭제", + style: "destructive", + onPress: () => void unfollowMutation.mutateAsync(targetUserId), + }, + ] + ); + }; + return ( void unfollowMutation.mutateAsync(user.userId)} + onPress={() => handleConfirmRemoveFriend(user.userId)} style={styles.removeButton} > diff --git a/src/pages/home/HomeScreen.tsx b/src/pages/home/HomeScreen.tsx index 2bfcc34..c5c3824 100644 --- a/src/pages/home/HomeScreen.tsx +++ b/src/pages/home/HomeScreen.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { StyleSheet, View } from "react-native"; import { useQueryClient } from "@tanstack/react-query"; import { useFocusEffect } from "@react-navigation/native"; @@ -86,9 +86,6 @@ export default function HomeScreen({ navigation }: Props) { useFocusEffect( useCallback(() => { - // 한글 주석: - // 홈 복귀 시점에도 서버 기준 eligible 상태를 다시 읽어야 - // 방금 물/햇빛을 완료한 뒤 즉시 2주 리포트 팝업을 띄울 수 있다. void refetch(); void refetchTrackingPromptStatus(); }, [refetch, refetchTrackingPromptStatus]) @@ -132,11 +129,6 @@ export default function HomeScreen({ navigation }: Props) { return; } - /* - * 한글 주석: - * 서버가 eligible 을 내려줘도 같은 앱 세션 안에서 이미 연 cycleKey 라면 - * 홈 재포커스나 추가 refetch 때문에 같은 모달이 연속으로 다시 뜨지 않게 막는다. - */ if (openedTrackingCycleKeysRef.current.has(trackingPromptStatus.cycleKey)) { return; } @@ -172,11 +164,6 @@ export default function HomeScreen({ navigation }: Props) { } }, [isCurrentGardenLocked, isSheetExpanded]); - /* - * 한글 주석: - * 홈 말풍선은 서버 응답과 별개로, 홈에서 방금 답한 직후 상태도 바로 반영해야 한다. - * 로컬 24시간 완료 상태를 함께 보아야 버튼이 다시 나타나는 깜빡임을 막을 수 있다. - */ const isEmotionAnswered = (surveyQuery.data?.isAnswered ?? false) || isEmotionCooldownActive; const answeredKind = emotionAnswerKind ?? lastAnswerKind; const initialPage = Math.max(0, Math.min(3, (userInfo?.lastAccessedSlotNumber ?? 1) - 1)); @@ -191,11 +178,6 @@ export default function HomeScreen({ navigation }: Props) { } try { - /* - * 한글 주석: - * 닫기와 CTA 모두 같은 confirm API 로 모아 처리해서 - * 이번 cycle 확인 완료 여부를 서버에 한 번만 기록한다. - */ await trackingPromptConfirmMutation.mutateAsync({ cycleKey: trackingPromptStatus.cycleKey, }); @@ -252,8 +234,13 @@ export default function HomeScreen({ navigation }: Props) { onPressMap={() => setIsMapModalOpen(true)} onPressBird={() => setIsAlertsModalOpen(true)} onPressEmotion={() => setIsEmotionModalOpen(true)} - onPressUnlock={() => navigation.navigate("UnlockGarden")} - onPressEmpty={() => navigation.navigate("RegistrationAvatar")} + onPressUnlock={() => + navigation.navigate("UnlockGarden", { + gardenId: scene.garden?.gardenId, + gardenSlotNumber: scene.slotNumber, + }) + } + onPressEmpty={() => navigation.navigate("RegistrationAvatar", { entry: "garden" })} /> ))} @@ -278,11 +265,6 @@ export default function HomeScreen({ navigation }: Props) { panel={panel} currentLevel={userInfo?.level ?? 0} onPressMission={mission => { - /* - * 한글 주석: - * 완료된 일기 미션은 다시 작성 화면으로 보내지 않고, - * 오늘 방금 작성한 일기 상세로 연결해야 결과 확인 흐름이 자연스럽다. - */ if (mission.missionType === "DIARY" && mission.isCompleted && latestTodayDiaryId) { navigation.navigate("LogDetail", { id: latestTodayDiaryId }); return; @@ -382,3 +364,4 @@ const styles = StyleSheet.create({ backgroundColor: "#F4F7F0", }, }); + diff --git a/src/pages/log/LogScreen.tsx b/src/pages/log/LogScreen.tsx index b1e279d..b78e116 100644 --- a/src/pages/log/LogScreen.tsx +++ b/src/pages/log/LogScreen.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useState, useEffect } from "react"; import { View, Text, @@ -9,7 +9,9 @@ import { import { SafeAreaView } from "react-native-safe-area-context"; import { useNavigation } from "@react-navigation/native"; import type { NativeStackNavigationProp } from "@react-navigation/native-stack"; +import { useQueryClient } from "@tanstack/react-query"; import type { RootStackParamList } from "@/navigation/types"; +import { getDiaries } from "@/apis/log/diariesApi"; import LogCalendar from "@/components/log/LogCalendar"; import MyDiary from "@/components/log/MyDiary"; @@ -19,6 +21,22 @@ type NavigationProp = NativeStackNavigationProp; export default function LogScreen() { const [activeTab, setActiveTab] = useState("mission"); const navigation = useNavigation(); + const queryClient = useQueryClient(); + + useEffect(() => { + /* + * 한글 주석: + * 로그 화면 진입 시 현재 탭과 무관하게 일기 데이터를 미리 가져온다. + * 탭 전환 즉시 데이터가 준비돼 있어 로딩 지연이 없다. + */ + const now = new Date(); + const year = now.getFullYear(); + const month = now.getMonth() + 1; + void queryClient.prefetchQuery({ + queryKey: ["diaries", year, month], + queryFn: () => getDiaries(year, month), + }); + }, [queryClient]); const handleDiarySelect = (diaryId: number) => { navigation.navigate("LogDetail", { id: diaryId }); diff --git a/src/pages/option/OptionScreen.tsx b/src/pages/option/OptionScreen.tsx index 68d2ec3..8911d0a 100644 --- a/src/pages/option/OptionScreen.tsx +++ b/src/pages/option/OptionScreen.tsx @@ -10,13 +10,16 @@ import { import ScreenHeader from "@/components/common/ScreenHeader"; import useTokenStore from "@/stores/useTokenStore"; import { logout } from "@/utils/auth"; +import { useNotificationSettings, useUpdateNotificationSettings } from "@/hooks/option/useNotificationApi"; type Props = MainTabScreenProps<"Option">; export default function OptionScreen({ navigation }: Props) { - const [pushNotification, setPushNotification] = useState(true); const [isLoggingOut, setIsLoggingOut] = useState(false); const { accessToken, userId, hasHydrated } = useTokenStore(); + const { data: notificationSettings } = useNotificationSettings(); + const updateSettingsMutation = useUpdateNotificationSettings(); + const pushNotification = notificationSettings?.notificationEnabled ?? true; const handleLogout = () => { if (isLoggingOut || !accessToken) { @@ -47,8 +50,11 @@ export default function OptionScreen({ navigation }: Props) { label="푸시 알림" rightSlot={ setPushNotification(prev => !prev)} + onPress={() => + updateSettingsMutation.mutate({ notificationEnabled: !pushNotification }) + } activeOpacity={0.7} + disabled={updateSettingsMutation.isPending} accessibilityRole="switch" accessibilityState={{ checked: pushNotification }} > diff --git a/src/pages/profile/ProfileScreen.tsx b/src/pages/profile/ProfileScreen.tsx index 35cd641..df1db12 100644 --- a/src/pages/profile/ProfileScreen.tsx +++ b/src/pages/profile/ProfileScreen.tsx @@ -1,1014 +1,536 @@ -import { useEffect, useMemo, useRef, useState } from "react"; - -import { - - Image, - - ScrollView, - - StyleSheet, - - Text, - - TouchableOpacity, - - View, - -} from "react-native"; - -import type { AxiosError } from "axios"; - -import PagerView from "react-native-pager-view"; - -import { SafeAreaView } from "react-native-safe-area-context"; - -import type { RootStackScreenProps } from "@/navigation/types"; - -import StatusView from "@/components/common/StatusView"; - -import HomeToast from "@/components/home/HomeToast"; - -import ProfileGardenScene from "@/components/profile/ProfileGardenScene"; - -import { useFriendWater, useUserProfile } from "@/hooks/profile/useProfileApi"; - -import { useFollowUser } from "@/hooks/follow/useFollowApi"; - -import useTokenStore from "@/stores/useTokenStore"; - -import { createTimingLogger, debugLog } from "@/utils/debug"; - -import { FollowStatus } from "@/types/profile/profileApi.type"; - - - -type Props = RootStackScreenProps<"Profile">; - - - -const FRIEND_WATER_ACTION_COOLDOWN_MS = 700; - - - -const getFriendWaterErrorMessage = ( - - status: number | null | undefined, - - serverMessage: string | null | undefined - -) => { - - if (serverMessage === "팔로우한 사용자만 물 주기가 가능합니다." - - || (status === 403 && serverMessage === "요청에 대한 권한이 없습니다.")) { - - return "친구 추가 후 물을 줄 수 있어요."; - - } - - - - if (serverMessage === "차단된 사용자입니다.") { - - return "차단된 사용자에게는 물을 줄 수 없어요."; - - } - - - - return serverMessage ?? "친구 물주기에 실패했습니다."; - -}; - - - -const backgrounds = [ - - require("@/assets/images/background/background1.webp"), - - require("@/assets/images/background/background2.webp"), - - require("@/assets/images/background/background3.png"), - - require("@/assets/images/background/background4.webp"), - -] as const; - - - -export default function ProfileScreen({ navigation, route }: Props) { - - const { userId: myUserId } = useTokenStore(); - - const userId = route.params.userId; - - const { data, error, isLoading, refetch } = useUserProfile(userId); - - const waterMutation = useFriendWater(userId); - - const followMutation = useFollowUser(myUserId); - - const [currentPage, setCurrentPage] = useState(0); - - const [wateringGardenId, setWateringGardenId] = useState(null); - - const [optimisticallyWateredGardenIds, setOptimisticallyWateredGardenIds] = useState([]); - - const [isFriendWaterCooldownActive, setIsFriendWaterCooldownActive] = useState(false); - - const [toastMessage, setToastMessage] = useState(null); - - const initialLoadTimingRef = useRef | null>(null); - - - - const isMe = String(userId) === myUserId; - - - - useEffect(() => { - - initialLoadTimingRef.current = createTimingLogger("ProfileScreen", "initial profile load", { userId }); - - }, [userId]); - - - - useEffect(() => { - - if (!data || !initialLoadTimingRef.current) { - - return; - - } - - - - initialLoadTimingRef.current({ gardenCount: data.userGardens.length }); - - initialLoadTimingRef.current = null; - - }, [data]); - - - - useEffect(() => { - - if (!data) { - - return; - - } - - - - setOptimisticallyWateredGardenIds(previous => - - previous.filter(gardenId => { - - const garden = data.userGardens.find(item => item.gardenId === gardenId); - - return garden?.isWateringAbleByMe ?? false; - - }) - - ); - - }, [data]); - - - - const handleBack = () => { - - if (navigation.canGoBack()) { - - navigation.goBack(); - - return; - - } - - - - navigation.navigate("Main", { screen: "Feed" }); - - }; - - - - const handleOpenGuestbook = () => { - - navigation.navigate("Guestbook", { - - userId, - - userNickname: data?.userNickname, - - }); - - }; - - - - const handleFriendWater = async (gardenId: number) => { - - if (waterMutation.isPending || isFriendWaterCooldownActive) { - - return; - - } - - - - const finishActionTiming = createTimingLogger("ProfileScreen", "friend water action", { - - userId, - - gardenId, - - }); - - - - setOptimisticallyWateredGardenIds(previous => - - previous.includes(gardenId) ? previous : [...previous, gardenId] - - ); - - setIsFriendWaterCooldownActive(true); - - setWateringGardenId(gardenId); - - setToastMessage("친구 정원에 물을 주었습니다."); - - setTimeout(() => { - - setWateringGardenId(prev => (prev === gardenId ? null : prev)); - - }, 1000); - - setTimeout(() => { - - setIsFriendWaterCooldownActive(false); - - }, FRIEND_WATER_ACTION_COOLDOWN_MS); - - - - try { - - await waterMutation.mutateAsync(gardenId); - - finishActionTiming({ startedImmediately: true }); - - } catch (error) { - - const axiosError = error as AxiosError<{ message?: string }>; - - const status = axiosError.response?.status; - - const serverMessage = axiosError.response?.data?.message; - - - - setOptimisticallyWateredGardenIds(previous => previous.filter(id => id !== gardenId)); - - setIsFriendWaterCooldownActive(false); - - setWateringGardenId(prev => (prev === gardenId ? null : prev)); - - finishActionTiming({ - - startedImmediately: true, - - rolledBack: true, - - status: status ?? null, - - }); - - debugLog("ProfileScreen", "friend water action failed", { - - userId, - - gardenId, - - status: status ?? null, - - serverMessage: serverMessage ?? null, - - }); - - setToastMessage(getFriendWaterErrorMessage(status, serverMessage)); - - } - - }; - - - - const followAction = useMemo(() => { - - if (!data || isMe) return null; - - - - switch (data.followStatus) { - - case FollowStatus.NOT_FOLLOWING: - - return { - - kind: "button" as const, - - label: "친구 추가", - - onPress: () => void followMutation.mutateAsync(userId), - - pending: followMutation.isPending, - - }; - - case FollowStatus.FOLLOW_BACK_POSSIBLE: - - return { - - kind: "button" as const, - - label: "맞팔로우", - - onPress: () => void followMutation.mutateAsync(userId), - - pending: followMutation.isPending, - - }; - - case FollowStatus.FOLLOWING: - - return { - - kind: "badge" as const, - - label: "이미 친구", - - }; - - default: - - return null; - - } - - }, [data, followMutation, userId, isMe]); - - - - if (isLoading) { - - return ( - - - - - - - - ); - - } - - - - if (error) { - - return ( - - - - void refetch()} - - /> - - - - ); - - } - - - - if (!data) { - - return ( - - - - - - - - ); - - } - - - - const scenes = data.userGardens.map((garden, index) => ({ - - key: `profile-garden-${garden.gardenId}`, - - background: backgrounds[index % backgrounds.length], - - garden, - - })); - - - - const renderProfileHeader = () => ( - - - - {/* 한글 주석: - - 프로필 화면의 상단은 방명록 화면과 톤을 맞춘 박스형 헤더로 분리해서, - - 뒤로가기/프로필/친구추가 역할이 정원 씬 위에 명확하게 보이도록 정리한다. */} - - - - - - 뒤로 - - - - - - 프로필 - - - - - - {followAction ? ( - - followAction.kind === "button" ? ( - - - - - - {followAction.pending ? "?? ?..." : followAction.label} - - - - - - ) : ( - - - - {followAction.label} - - - - ) - - ) : isMe ? ( - - ? ??? - - ) : null} - - - - - - - - ); - - - - if (scenes.length === 0) { - - return ( - - - - {renderProfileHeader()} - - - - - - - - - - {data.profileImageUrl ? ( - - - - ) : null} - - - - {data.userNickname} - - - - - - - - 정원 정보가 없습니다. - - - - 현재 API 기준으로 표시할 정원 데이터가 없어 기본 정보만 표시합니다. - - - - - - - - - - - - ); - - } - - - - return ( - - - - setCurrentPage(event.nativeEvent.position)} - - > - - {scenes.map(scene => ( - - - - {/* 한글 주석: - - 타인 프로필은 홈처럼 정원 중심 화면을 쓰되, - - 정원 개수는 해금된 userGardens 길이만큼만 페이지를 만든다. */} - - void handleFriendWater(scene.garden.gardenId)} - - onPressGuestbook={handleOpenGuestbook} - - waterDisabled={ - - waterMutation.isPending || - - isFriendWaterCooldownActive || - - optimisticallyWateredGardenIds.includes(scene.garden.gardenId) - - } - - /> - - - - ))} - - - - - - {renderProfileHeader()} - - - - - - - - {scenes.map((scene, index) => ( - - - - ))} - - - - - - - - {toastMessage ? ( - - setToastMessage(null)} /> - - ) : null} - - - - ); - -} - - - -const styles = StyleSheet.create({ - - container: { - - flex: 1, - - backgroundColor: "#F4F7F0", - - }, - - sceneContainer: { - - flex: 1, - - backgroundColor: "#DDE8D6", - - }, - - pager: { - - flex: 1, - - }, - - page: { - - flex: 1, - - }, - - headerSafeArea: { - - position: "absolute", - - top: 0, - - left: 0, - - right: 0, - - }, - - headerCard: { - - marginHorizontal: 16, - - marginTop: 8, - - minHeight: 56, - - borderRadius: 18, - - backgroundColor: "rgba(255,255,255,0.96)", - - flexDirection: "row", - - alignItems: "center", - - paddingHorizontal: 12, - - shadowColor: "#000", - - shadowOffset: { width: 0, height: 2 }, - - shadowOpacity: 0.08, - - shadowRadius: 10, - - elevation: 3, - - }, - - headerSideButton: { - - width: 56, - - minHeight: 44, - - justifyContent: "center", - - }, - - headerBackText: { - - fontSize: 14, - - fontWeight: "600", - - color: "#374151", - - }, - - headerTitle: { - - flex: 1, - - textAlign: "center", - - fontSize: 18, - - fontWeight: "700", - - color: "#171717", - - }, - - headerActionWrap: { - - minWidth: 72, - - alignItems: "flex-end", - - }, - - followButton: { - - borderRadius: 12, - - backgroundColor: "#E9F6EA", - - paddingHorizontal: 12, - - paddingVertical: 8, - - }, - - followButtonText: { - - fontSize: 13, - - fontWeight: "700", - - color: "#2F7D32", - - }, - - followBadge: { - - borderRadius: 12, - - backgroundColor: "rgba(255,255,255,0.9)", - - borderWidth: 1, - - borderColor: "#D1D5DB", - - paddingHorizontal: 12, - - paddingVertical: 8, - - }, - - followBadgeText: { - - fontSize: 13, - - fontWeight: "700", - - color: "#4B5563", - - }, - - selfBadgeText: { - - fontSize: 13, - - fontWeight: "600", - - color: "#6B7280", - - }, - - overlaySafeArea: { - - position: "absolute", - - top: 0, - - left: 0, - - right: 0, - - }, - - pagination: { - - marginTop: 86, - - alignSelf: "center", - - flexDirection: "row", - - alignItems: "center", - - gap: 8, - - }, - - dot: { - - width: 8, - - height: 8, - - borderRadius: 999, - - }, - - dotActive: { - - width: 22, - - backgroundColor: "#FFFFFF", - - }, - - dotInactive: { - - backgroundColor: "rgba(255,255,255,0.45)", - - }, - - emptyContainer: { - - flex: 1, - - backgroundColor: "#FFFFFF", - - }, - - emptyScrollSafeArea: { - - flex: 1, - - }, - - emptyScrollContent: { - - paddingTop: 104, - - paddingBottom: 28, - - }, - - summaryRow: { - - flexDirection: "row", - - alignItems: "center", - - paddingHorizontal: 20, - - paddingVertical: 14, - - gap: 10, - - }, - - profileImageWrap: { - - width: 40, - - height: 40, - - borderRadius: 20, - - backgroundColor: "#E5E7EB", - - overflow: "hidden", - - }, - - profileImage: { - - width: "100%", - - height: "100%", - - }, - - nickname: { - - flex: 1, - - fontSize: 16, - - fontWeight: "600", - - color: "#171717", - - }, - - emptyGardenWrap: { - - paddingHorizontal: 20, - - paddingVertical: 28, - - gap: 6, - - }, - - emptyGardenTitle: { - - fontSize: 16, - - fontWeight: "700", - - color: "#171717", - - }, - - emptyGardenDescription: { - - fontSize: 14, - - lineHeight: 20, - - color: "#6B7280", - - }, - -}); - +import { useEffect, useMemo, useRef, useState } from "react"; +import { Alert, Image, ScrollView, StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import type { AxiosError } from "axios"; +import PagerView from "react-native-pager-view"; +import { SafeAreaView } from "react-native-safe-area-context"; +import type { RootStackScreenProps } from "@/navigation/types"; +import StatusView from "@/components/common/StatusView"; +import HomeToast from "@/components/home/HomeToast"; +import ProfileGardenScene from "@/components/profile/ProfileGardenScene"; +import ScreenHeader from "@/components/common/ScreenHeader"; +import { useFriendWater, useUserProfile } from "@/hooks/profile/useProfileApi"; +import { useFollowUser } from "@/hooks/follow/useFollowApi"; +import { useBlockUser, useUnblockUser } from "@/hooks/block/useBlockApi"; +import useTokenStore from "@/stores/useTokenStore"; +import { createTimingLogger, debugLog } from "@/utils/debug"; +import { FollowStatus } from "@/types/profile/profileApi.type"; + +type Props = RootStackScreenProps<"Profile">; + +const FRIEND_WATER_ACTION_COOLDOWN_MS = 700; + +const getFriendWaterErrorMessage = ( + status: number | null | undefined, + serverMessage: string | null | undefined +) => { + if ( + serverMessage === "팔로우한 사용자만 물 주기가 가능합니다." || + (status === 403 && serverMessage === "요청에 대한 권한이 없습니다.") + ) { + return "친구 추가 후 물을 줄 수 있어요."; + } + + if (serverMessage === "차단된 사용자입니다.") { + return "차단된 사용자에게는 물을 줄 수 없어요."; + } + + return serverMessage ?? "친구 물주기에 실패했습니다."; +}; + +const getActionErrorMessage = ( + error: unknown, + fallbackMessage: string +) => { + const axiosError = error as AxiosError<{ message?: string }>; + return axiosError.response?.data?.message ?? fallbackMessage; +}; + +const backgrounds = [ + require("@/assets/images/background/background1.webp"), + require("@/assets/images/background/background2.webp"), + require("@/assets/images/background/background3.png"), + require("@/assets/images/background/background4.webp"), +] as const; + +export default function ProfileScreen({ navigation, route }: Props) { + const { userId: myUserId } = useTokenStore(); + const userId = route.params.userId; + const { data, error, isLoading, refetch } = useUserProfile(userId); + const waterMutation = useFriendWater(userId); + const followMutation = useFollowUser(myUserId); + const blockMutation = useBlockUser(); + const unblockMutation = useUnblockUser(); + const [currentPage, setCurrentPage] = useState(0); + const [wateringGardenId, setWateringGardenId] = useState(null); + const [optimisticallyWateredGardenIds, setOptimisticallyWateredGardenIds] = useState([]); + const [isFriendWaterCooldownActive, setIsFriendWaterCooldownActive] = useState(false); + const [toastMessage, setToastMessage] = useState(null); + const [isBlockedUser, setIsBlockedUser] = useState(false); + const initialLoadTimingRef = useRef | null>(null); + + const isMe = String(userId) === myUserId; + const isBlockActionPending = blockMutation.isPending || unblockMutation.isPending; + + useEffect(() => { + initialLoadTimingRef.current = createTimingLogger("ProfileScreen", "initial profile load", { userId }); + }, [userId]); + + useEffect(() => { + if (!data || !initialLoadTimingRef.current) { + return; + } + + initialLoadTimingRef.current({ gardenCount: data.userGardens.length }); + initialLoadTimingRef.current = null; + }, [data]); + + useEffect(() => { + if (!data) { + return; + } + + setOptimisticallyWateredGardenIds(previous => + previous.filter(gardenId => { + const garden = data.userGardens.find(item => item.gardenId === gardenId); + return garden?.isWateringAbleByMe ?? false; + }) + ); + }, [data]); + + const handleBack = () => { + if (navigation.canGoBack()) { + navigation.goBack(); + return; + } + + navigation.navigate("Main", { screen: "Feed" }); + }; + + const handleOpenGuestbook = () => { + navigation.navigate("Guestbook", { + userId, + userNickname: data?.userNickname, + }); + }; + + const handleFriendWater = async (gardenId: number) => { + if (waterMutation.isPending || isFriendWaterCooldownActive || isBlockedUser) { + return; + } + + const finishActionTiming = createTimingLogger("ProfileScreen", "friend water action", { + userId, + gardenId, + }); + + setOptimisticallyWateredGardenIds(previous => + previous.includes(gardenId) ? previous : [...previous, gardenId] + ); + setIsFriendWaterCooldownActive(true); + setWateringGardenId(gardenId); + setToastMessage("친구 정원에 물을 주었습니다."); + + setTimeout(() => { + setWateringGardenId(prev => (prev === gardenId ? null : prev)); + }, 1000); + + setTimeout(() => { + setIsFriendWaterCooldownActive(false); + }, FRIEND_WATER_ACTION_COOLDOWN_MS); + + try { + await waterMutation.mutateAsync(gardenId); + finishActionTiming({ startedImmediately: true }); + } catch (error) { + const axiosError = error as AxiosError<{ message?: string }>; + const status = axiosError.response?.status; + const serverMessage = axiosError.response?.data?.message; + + setOptimisticallyWateredGardenIds(previous => previous.filter(id => id !== gardenId)); + setIsFriendWaterCooldownActive(false); + setWateringGardenId(prev => (prev === gardenId ? null : prev)); + finishActionTiming({ + startedImmediately: true, + rolledBack: true, + status: status ?? null, + }); + debugLog("ProfileScreen", "friend water action failed", { + userId, + gardenId, + status: status ?? null, + serverMessage: serverMessage ?? null, + }); + setToastMessage(getFriendWaterErrorMessage(status, serverMessage)); + } + }; + + const handleToggleBlock = () => { + if (isMe || isBlockActionPending) { + return; + } + + if (isBlockedUser) { + Alert.alert("차단 해제", "이 사용자의 차단을 해제할까요?", [ + { text: "취소", style: "cancel" }, + { + text: "차단 해제", + onPress: async () => { + try { + await unblockMutation.mutateAsync(userId); + setIsBlockedUser(false); + setToastMessage("사용자 차단을 해제했습니다."); + } catch (error) { + Alert.alert("차단 해제 실패", getActionErrorMessage(error, "잠시 후 다시 시도해주세요.")); + } + }, + }, + ]); + return; + } + + Alert.alert("차단", "이 사용자를 차단할까요? 서로 팔로우가 해제되고 콘텐츠가 숨겨집니다.", [ + { text: "취소", style: "cancel" }, + { + text: "차단", + style: "destructive", + onPress: async () => { + try { + await blockMutation.mutateAsync(userId); + setIsBlockedUser(true); + setToastMessage("사용자를 차단했습니다."); + } catch (error) { + Alert.alert("차단 실패", getActionErrorMessage(error, "잠시 후 다시 시도해주세요.")); + } + }, + }, + ]); + }; + + const followAction = useMemo(() => { + if (!data || isMe || isBlockedUser) { + return null; + } + + switch (data.followStatus) { + case FollowStatus.NOT_FOLLOWING: + return { + kind: "button" as const, + label: "친구 추가", + onPress: () => void followMutation.mutateAsync(userId), + pending: followMutation.isPending, + }; + case FollowStatus.FOLLOW_BACK_POSSIBLE: + return { + kind: "button" as const, + label: "맞팔로우", + onPress: () => void followMutation.mutateAsync(userId), + pending: followMutation.isPending, + }; + case FollowStatus.FOLLOWING: + return { + kind: "badge" as const, + label: "이미 친구", + }; + default: + return null; + } + }, [data, followMutation, userId, isMe, isBlockedUser]); + + if (isLoading) { + return ( + + + + ); + } + + if (error) { + return ( + + void refetch()} + /> + + ); + } + + if (!data) { + return ( + + + + ); + } + + const scenes = data.userGardens.map((garden, index) => ({ + key: `profile-garden-${garden.gardenId}`, + background: backgrounds[index % backgrounds.length], + garden, + })); + + const renderProfileHeader = () => ( + + + + + + {data.profileImageUrl ? ( + + ) : null} + + {data.userNickname} + + + {followAction ? ( + followAction.kind === "button" ? ( + + + {followAction.pending ? "처리 중..." : followAction.label} + + + ) : ( + {followAction.label} + ) + ) : null} + {!isMe ? ( + + + {isBlockActionPending ? "처리 중..." : isBlockedUser ? "차단 해제" : "차단"} + + + ) : null} + + + + ); + + if (scenes.length === 0) { + return ( + + {renderProfileHeader()} + + + + + {data.profileImageUrl ? ( + + ) : null} + + {data.userNickname} + + + + 정원 정보가 없습니다. + + 현재 API 기준으로 표시할 정원 데이터가 없어 기본 정보만 표시합니다. + + + + + + ); + } + + return ( + + setCurrentPage(event.nativeEvent.position)} + > + {scenes.map(scene => ( + + void handleFriendWater(scene.garden.gardenId)} + onPressGuestbook={handleOpenGuestbook} + waterDisabled={ + isBlockedUser || + waterMutation.isPending || + isFriendWaterCooldownActive || + optimisticallyWateredGardenIds.includes(scene.garden.gardenId) + } + /> + + ))} + + + {renderProfileHeader()} + + + + {scenes.map((scene, index) => ( + + ))} + + + + {toastMessage ? setToastMessage(null)} /> : null} + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: "#F4F7F0", + }, + sceneContainer: { + flex: 1, + backgroundColor: "#DDE8D6", + }, + pager: { + flex: 1, + }, + page: { + flex: 1, + }, + headerSafeArea: { + position: "absolute", + top: 0, + left: 0, + right: 0, + backgroundColor: "#FFFFFF", + }, + userInfoBar: { + backgroundColor: "#FFFFFF", + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + paddingHorizontal: 20, + paddingVertical: 16, + borderBottomWidth: 1, + borderBottomColor: "#EFEFEF", + }, + userInfoLeft: { + flexDirection: "row", + alignItems: "center", + gap: 8, + }, + userAvatarWrap: { + width: 32, + height: 32, + borderRadius: 16, + backgroundColor: "#E5E7EB", + overflow: "hidden", + }, + userAvatarImage: { + width: "100%", + height: "100%", + }, + userNickname: { + fontSize: 18, + fontWeight: "600", + color: "#171717", + }, + userInfoRight: { + flexDirection: "row", + alignItems: "center", + gap: 12, + }, + followText: { + fontSize: 14, + fontWeight: "400", + color: "#3AB40B", + }, + followedText: { + fontSize: 14, + color: "#BFBFBF", + }, + blockText: { + fontSize: 12, + color: "#9CA3AF", + }, + blockActiveText: { + color: "#6B7280", + }, + overlaySafeArea: { + position: "absolute", + bottom: 0, + left: 0, + right: 0, + }, + pagination: { + paddingBottom: 96, + alignSelf: "center", + flexDirection: "row", + alignItems: "center", + gap: 12, + }, + dot: { + width: 8, + height: 8, + borderRadius: 999, + }, + dotActive: { + backgroundColor: "#FFFFFF", + }, + dotInactive: { + backgroundColor: "rgba(255,255,255,0.45)", + }, + emptyContainer: { + flex: 1, + backgroundColor: "#FFFFFF", + }, + emptyScrollSafeArea: { + flex: 1, + }, + emptyScrollContent: { + paddingTop: 104, + paddingBottom: 28, + }, + summaryRow: { + flexDirection: "row", + alignItems: "center", + paddingHorizontal: 20, + paddingVertical: 14, + gap: 10, + }, + profileImageWrap: { + width: 40, + height: 40, + borderRadius: 20, + backgroundColor: "#E5E7EB", + overflow: "hidden", + }, + profileImage: { + width: "100%", + height: "100%", + }, + nickname: { + flex: 1, + fontSize: 16, + fontWeight: "600", + color: "#171717", + }, + emptyGardenWrap: { + paddingHorizontal: 20, + paddingVertical: 28, + gap: 6, + }, + emptyGardenTitle: { + fontSize: 16, + fontWeight: "700", + color: "#171717", + }, + emptyGardenDescription: { + fontSize: 14, + lineHeight: 20, + color: "#6B7280", + }, +}); diff --git a/src/pages/registration/RegistrationAvatarScreen.tsx b/src/pages/registration/RegistrationAvatarScreen.tsx index 1be0e8f..79ed4c9 100644 --- a/src/pages/registration/RegistrationAvatarScreen.tsx +++ b/src/pages/registration/RegistrationAvatarScreen.tsx @@ -1,73 +1,81 @@ -import { ScrollView, StyleSheet, Text, View } from "react-native"; +import { Image, ScrollView, StyleSheet, Text, TouchableOpacity, View } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; import ScreenHeader from "@/components/common/ScreenHeader"; -import RegistrationFooter from "@/components/registration/RegistrationFooter"; -import RegistrationModeCard from "@/components/registration/RegistrationModeCard"; import type { RootStackScreenProps } from "@/navigation/types"; import useRegistrationStore from "@/stores/useRegistrationStore"; type Props = RootStackScreenProps<"RegistrationAvatar">; -export default function RegistrationAvatarScreen({ navigation }: Props) { - const { mode, selectedMaster, selectedPreview, setMode } = useRegistrationStore(); +type EntryMode = "initial" | "garden"; - const goNext = () => { - if (mode === "selection") { - navigation.navigate("RegistrationSelectionDetail"); - return; - } +const selectionImage = require("@/assets/images/creationAvatar/SelectionDefultImg.png"); +const creationImage = require("@/assets/images/creationAvatar/CreationDefultImg.png"); - if (mode === "creation") { - navigation.navigate("RegistrationCreationDetail"); - } +export default function RegistrationAvatarScreen({ navigation, route }: Props) { + const { setMode } = useRegistrationStore(); + const entry: EntryMode = route.params?.entry ?? "initial"; + const isGardenEntry = entry === "garden"; + + const goSelection = () => { + setMode("selection"); + navigation.navigate("RegistrationSelectionDetail", { entry }); + }; + + const goCreation = () => { + setMode("creation"); + navigation.navigate("RegistrationCreationDetail", { entry }); }; return ( - + navigation.navigate("Main", { screen: "Home" })} + onBack={isGardenEntry ? undefined : () => navigation.navigate("Main", { screen: "Home" })} /> + - - 등록 플로우 시작 - 어떤 방식으로 식물을 데려올지 선택하세요. - - 선택형은 제공된 아바타를 고르는 방식이고, 생성형은 이미지를 업로드한 뒤 별명을 붙이는 방식입니다. - + + + 아바타 선택 + 00종의 아바타 중에서{"\n"}선택할 수 있어요 + + 선택하러 가기 + + + - setMode("selection")} - /> + - setMode("creation")} - /> + + + 나만의 아바타 + 내 식물의 생김새를{"\n"}반영한 나만의 아바타를{"\n"}만들 수 있어요 + + 만들러 가기 + + + + - - navigation.reset({ - index: 0, - routes: [{ name: "Main", params: { screen: "Home" } }], - }) - } - primaryLabel="다음" - onPrimaryPress={goNext} - primaryDisabled={!mode} - /> + + + navigation.reset({ + index: 0, + routes: [{ name: "Main", params: { screen: "Home" } }], + }) + } + > + + {isGardenEntry ? "다음" : "나중에 만들기"} + + + ); } @@ -75,31 +83,87 @@ export default function RegistrationAvatarScreen({ navigation }: Props) { const styles = StyleSheet.create({ safeArea: { flex: 1, - backgroundColor: "#F7F8F4", + backgroundColor: "#FFFFFF", }, content: { - padding: 20, - gap: 16, - }, - heroCard: { - borderRadius: 22, - padding: 20, - backgroundColor: "#234A2F", - gap: 8, - }, - eyebrow: { - fontSize: 12, - color: "#D7E9D8", - }, - heroTitle: { - fontSize: 24, - lineHeight: 32, + paddingTop: 18, + paddingBottom: 24, + }, + card: { + minHeight: 300, + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", + paddingHorizontal: 20, + gap: 12, + }, + divider: { + height: 1, + backgroundColor: "#EFEFEF", + }, + copyWrap: { + flex: 1, + gap: 12, + }, + cardTitle: { + fontSize: 40 / 2, + lineHeight: 56 / 2, fontWeight: "700", + color: "#171717", + }, + cardDescription: { + fontSize: 16, + lineHeight: 40 / 2, + color: "#171717", + }, + cardActionButton: { + marginTop: 8, + alignSelf: "flex-start", + minWidth: 146, + minHeight: 44, + borderRadius: 8, + backgroundColor: "#6FCF4A", + alignItems: "center", + justifyContent: "center", + paddingHorizontal: 18, + }, + cardActionLabel: { + fontSize: 32 / 2, + lineHeight: 54 / 2, + fontWeight: "600", color: "#FFFFFF", }, - heroDescription: { - fontSize: 14, - lineHeight: 20, - color: "#E5F4E5", + cardImage: { + width: 184, + height: 184, + opacity: 0.95, + }, + footer: { + paddingHorizontal: 20, + paddingTop: 10, + paddingBottom: 20, + }, + footerButton: { + minHeight: 56, + borderRadius: 8, + alignItems: "center", + justifyContent: "center", + }, + footerButtonSecondary: { + backgroundColor: "#EFF9EA", + }, + footerButtonDisabled: { + backgroundColor: "#EAEAEA", + }, + footerLabel: { + fontSize: 18, + lineHeight: 27, + fontWeight: "600", + }, + footerLabelSecondary: { + color: "#46C02B", + }, + footerLabelDisabled: { + color: "#BFBFBF", }, }); diff --git a/src/pages/registration/RegistrationCreationCompleteScreen.tsx b/src/pages/registration/RegistrationCreationCompleteScreen.tsx new file mode 100644 index 0000000..4062f8b --- /dev/null +++ b/src/pages/registration/RegistrationCreationCompleteScreen.tsx @@ -0,0 +1,92 @@ +import { Image, StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; +import ScreenHeader from "@/components/common/ScreenHeader"; +import type { RootStackScreenProps } from "@/navigation/types"; +import { useHomeSummaryStore } from "@/stores/useHomeSummaryStore"; + +type Props = RootStackScreenProps<"RegistrationCreationComplete">; + +export default function RegistrationCreationCompleteScreen({ navigation, route }: Props) { + const username = useHomeSummaryStore(state => state.user?.username) ?? ""; + const { imageUrl } = route.params; + + return ( + + + + + {username || "OO"}님만의{"\n"}아바타가 완성되었어요! + + + + + + + + navigation.replace("RegistrationPlantNickname")} + > + 다음 + + + + ); +} + +const styles = StyleSheet.create({ + safeArea: { + flex: 1, + backgroundColor: "#FFFFFF", + }, + content: { + flex: 1, + paddingHorizontal: 25, + paddingTop: 32, + }, + title: { + fontSize: 20, + lineHeight: 28, + fontWeight: "600", + color: "#171717", + }, + previewCard: { + width: 258, + height: 292, + marginTop: 66, + marginLeft: 43, + borderRadius: 12, + borderWidth: 2, + borderColor: "#72D14E", + backgroundColor: "#EEF9EA", + alignItems: "center", + justifyContent: "center", + paddingHorizontal: 19, + paddingVertical: 16, + }, + previewImage: { + width: 220, + height: 261, + borderRadius: 8, + }, + footer: { + paddingHorizontal: 20, + paddingTop: 12, + paddingBottom: 34, + }, + nextButton: { + minHeight: 56, + borderRadius: 8, + backgroundColor: "#72D14E", + alignItems: "center", + justifyContent: "center", + }, + nextLabel: { + fontSize: 18, + lineHeight: 27, + fontWeight: "600", + color: "#FFFFFF", + }, +}); + diff --git a/src/pages/registration/RegistrationCreationDetailScreen.tsx b/src/pages/registration/RegistrationCreationDetailScreen.tsx index c17caf4..28267e5 100644 --- a/src/pages/registration/RegistrationCreationDetailScreen.tsx +++ b/src/pages/registration/RegistrationCreationDetailScreen.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useState } from "react"; import * as ImagePicker from "expo-image-picker"; import { Alert, @@ -12,26 +12,21 @@ import { SafeAreaView } from "react-native-safe-area-context"; import ScreenHeader from "@/components/common/ScreenHeader"; import AvatarPreviewCard from "@/components/registration/AvatarPreviewCard"; import RegistrationFooter from "@/components/registration/RegistrationFooter"; -import { useUploadCreationAvatar } from "@/hooks/avatars/useAvatarApi"; import type { RootStackScreenProps } from "@/navigation/types"; import useRegistrationStore from "@/stores/useRegistrationStore"; type Props = RootStackScreenProps<"RegistrationCreationDetail">; -export default function RegistrationCreationDetailScreen({ navigation }: Props) { +export default function RegistrationCreationDetailScreen({ navigation, route }: Props) { + const entry = route.params?.entry; const [permissionRequested, setPermissionRequested] = useState(false); - const uploadCreationAvatar = useUploadCreationAvatar(); const { creationDetail, updateCreationDetail, - setMode, - setSelectedMaster, setSelectedPreview, } = useRegistrationStore(); - const previewImageUrl = - creationDetail.uploadedImageUrl || creationDetail.imageUri || null; - const canProceed = Boolean(creationDetail.uploadedImageUrl); + const previewImageUrl = creationDetail.imageUri || null; const handlePickImage = async () => { if (!permissionRequested) { @@ -57,13 +52,6 @@ export default function RegistrationCreationDetailScreen({ navigation }: Props) const asset = result.assets[0]; const fileName = asset.fileName ?? `avatar-${Date.now()}.jpg`; const fileType = asset.mimeType ?? "image/jpeg"; - const formData = new FormData(); - - formData.append("image", { - uri: asset.uri, - name: fileName, - type: fileType, - } as never); updateCreationDetail({ imageUri: asset.uri, @@ -72,104 +60,50 @@ export default function RegistrationCreationDetailScreen({ navigation }: Props) setSelectedPreview({ masterId: null, imageUrl: asset.uri, - description: "선택한 이미지를 업로드하는 중입니다.", + description: "선택한 이미지를 업로드합니다.", }); - try { - const response = await uploadCreationAvatar.mutateAsync(formData); - - updateCreationDetail({ - imageUri: asset.uri, - uploadedImageUrl: response.imageUrl, - }); - setMode("creation"); - setSelectedMaster(null); - setSelectedPreview({ - masterId: null, - imageUrl: response.imageUrl, - description: "업로드가 완료되었습니다. 이 이미지를 기반으로 식물을 등록합니다.", - }); - } catch (error) { - const message = - error instanceof Error ? error.message : "이미지 업로드에 실패했습니다."; - Alert.alert("업로드 실패", message); - } - }; - - const goNext = () => { - if (!canProceed) { - return; - } - - navigation.navigate("RegistrationPlantNickname"); + navigation.navigate("RegistrationCreationPending", { + entry, + imageUri: asset.uri, + fileName, + fileType, + }); }; return ( navigation.navigate("RegistrationAvatar")} + title="식물 데려오기" + onBack={() => navigation.navigate("RegistrationAvatar", { entry })} /> - 이미지를 업로드해주세요. - - 선택한 이미지는 `POST /api/v1/register/upload`로 업로드되고, 응답 `imageUrl`이 최종 등록 단계로 이어집니다. - + 사진을 선택해주세요 + 사진 업로드 후 아바타 생성이 시작됩니다. - void handlePickImage()} - > + void handlePickImage()}> - {uploadCreationAvatar.isPending ? "업로드 중..." : creationDetail.imageUri ? "이미지 다시 선택" : "이미지 선택"} + {creationDetail.imageUri ? "이미지 다시 선택" : "이미지 선택"} - - - 현재 상태 - - {creationDetail.uploadedImageUrl - ? "서버 업로드가 완료되었습니다. 다음 단계에서 별명을 정한 뒤 최종 등록합니다." - : "이미지를 선택하면 업로드를 먼저 수행합니다."} - - {creationDetail.uploadedImageUrl ? ( - {creationDetail.uploadedImageUrl} - ) : null} - - - {uploadCreationAvatar.isError ? ( - - 이미지 업로드에 실패했습니다. - - 같은 이미지를 다시 선택해서 재시도할 수 있습니다. - - - ) : null} navigation.navigate("RegistrationAvatar")} - primaryLabel="별명 정하러 가기" - onPrimaryPress={goNext} - primaryDisabled={!canProceed || uploadCreationAvatar.isPending} - primaryLoading={uploadCreationAvatar.isPending} + primaryLabel="나중에 만들기" + onPrimaryPress={() => + navigation.reset({ + index: 0, + routes: [{ name: "Main", params: { screen: "Home" } }], + }) + } /> ); @@ -210,41 +144,4 @@ const styles = StyleSheet.create({ fontWeight: "700", color: "#FFFFFF", }, - infoCard: { - borderRadius: 18, - padding: 16, - backgroundColor: "#EEF3EA", - gap: 8, - }, - infoTitle: { - fontSize: 16, - fontWeight: "700", - color: "#171717", - }, - infoText: { - fontSize: 14, - lineHeight: 20, - color: "#4B5563", - }, - infoUrl: { - fontSize: 12, - lineHeight: 18, - color: "#2563EB", - }, - errorCard: { - borderRadius: 18, - padding: 16, - backgroundColor: "#FEF2F2", - gap: 6, - }, - errorTitle: { - fontSize: 16, - fontWeight: "700", - color: "#B91C1C", - }, - errorDescription: { - fontSize: 14, - lineHeight: 20, - color: "#7F1D1D", - }, }); diff --git a/src/pages/registration/RegistrationCreationPendingScreen.tsx b/src/pages/registration/RegistrationCreationPendingScreen.tsx new file mode 100644 index 0000000..7d5cb90 --- /dev/null +++ b/src/pages/registration/RegistrationCreationPendingScreen.tsx @@ -0,0 +1,122 @@ +import { useEffect, useRef } from "react"; +import { Alert, StyleSheet, Text, View } from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; +import ScreenHeader from "@/components/common/ScreenHeader"; +import PendingCharacter from "@/assets/images/creationAvatar/PendingImage.svg"; +import { useUploadCreationAvatar } from "@/hooks/avatars/useAvatarApi"; +import type { RootStackScreenProps } from "@/navigation/types"; +import useRegistrationStore from "@/stores/useRegistrationStore"; + +type Props = RootStackScreenProps<"RegistrationCreationPending">; + +export default function RegistrationCreationPendingScreen({ navigation, route }: Props) { + const uploadCreationAvatar = useUploadCreationAvatar(); + const hasStartedRef = useRef(false); + const { entry, imageUri, fileName, fileType } = route.params; + const { + updateCreationDetail, + setMode, + setSelectedMaster, + setSelectedPreview, + } = useRegistrationStore(); + + useEffect(() => { + if (hasStartedRef.current) { + return; + } + hasStartedRef.current = true; + + const formData = new FormData(); + formData.append("image", { + uri: imageUri, + name: fileName, + type: fileType, + } as never); + + void uploadCreationAvatar + .mutateAsync(formData) + .then(response => { + updateCreationDetail({ + imageUri, + uploadedImageUrl: response.imageUrl, + }); + setMode("creation"); + setSelectedMaster(null); + setSelectedPreview({ + masterId: null, + imageUrl: response.imageUrl, + description: "업로드가 완료되었습니다. 이 이미지를 기반으로 식물을 등록합니다.", + }); + + navigation.replace("RegistrationCreationComplete", { + entry, + imageUrl: response.imageUrl, + }); + }) + .catch(error => { + const message = error instanceof Error ? error.message : "이미지 업로드에 실패했습니다."; + Alert.alert("업로드 실패", message, [ + { + text: "다시 선택", + onPress: () => navigation.replace("RegistrationCreationDetail", { entry }), + }, + ]); + }); + }, [ + entry, + fileName, + fileType, + imageUri, + navigation, + setMode, + setSelectedMaster, + setSelectedPreview, + updateCreationDetail, + uploadCreationAvatar, + ]); + + return ( + + + + + + + 아바타를 만들고 있어요 + 잠시만 기다려주세요... + + + + + ); +} + +const styles = StyleSheet.create({ + safeArea: { + flex: 1, + backgroundColor: "#FFFFFF", + }, + content: { + flex: 1, + alignItems: "center", + justifyContent: "center", + marginTop: -38, + }, + group: { + width: 165, + minHeight: 174, + alignItems: "center", + gap: 16, + }, + messageWrap: { + width: 165, + alignItems: "center", + }, + message: { + fontSize: 18, + lineHeight: 29, + fontWeight: "600", + color: "#7C7C7C", + textAlign: "center", + }, +}); diff --git a/src/pages/registration/RegistrationPlantNicknameScreen.tsx b/src/pages/registration/RegistrationPlantNicknameScreen.tsx index 8bab698..7619195 100644 --- a/src/pages/registration/RegistrationPlantNicknameScreen.tsx +++ b/src/pages/registration/RegistrationPlantNicknameScreen.tsx @@ -1,13 +1,12 @@ -import { ScrollView, StyleSheet, Text, View } from "react-native"; +import { Image, StyleSheet, Text, TextInput, TouchableOpacity, View } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; import ScreenHeader from "@/components/common/ScreenHeader"; -import AvatarPreviewCard from "@/components/registration/AvatarPreviewCard"; -import RegistrationFooter from "@/components/registration/RegistrationFooter"; -import RegistrationTextField from "@/components/registration/RegistrationTextField"; import { useFinalChoiceAvatar } from "@/hooks/avatars/useAvatarApi"; import type { RootStackScreenProps } from "@/navigation/types"; import useRegistrationStore from "@/stores/useRegistrationStore"; +const MAX_NICKNAME_LENGTH = 6; + type Props = RootStackScreenProps<"RegistrationPlantNickname">; export default function RegistrationPlantNicknameScreen({ navigation }: Props) { @@ -23,18 +22,18 @@ export default function RegistrationPlantNicknameScreen({ navigation }: Props) { const finalChoiceAvatar = useFinalChoiceAvatar(); const trimmedNickname = nickname.trim(); - const isInvalid = trimmedNickname.length === 0 || trimmedNickname.length > 6; + const isTooLong = trimmedNickname.length > MAX_NICKNAME_LENGTH; + const isEmpty = trimmedNickname.length === 0; + const isInvalid = isEmpty || isTooLong; const canSubmitToApi = (mode === "selection" && Boolean(selectedMaster?.id && selectedMaster.defaultImageUrl)) || (mode === "creation" && Boolean(creationDetail.uploadedImageUrl)); - const helperText = - mode === "selection" - ? "선택형은 imageUrl과 masterId를 함께 보내 최종 등록합니다." - : "생성형은 업로드된 imageUrl과 masterId:null로 최종 등록합니다."; + const previewImageUrl = + selectedPreview?.imageUrl ?? creationDetail.uploadedImageUrl ?? selectedMaster?.defaultImageUrl ?? null; const completeFlow = async () => { - if (isInvalid || !canSubmitToApi) { + if (isInvalid || !canSubmitToApi || finalChoiceAvatar.isPending) { return; } @@ -59,7 +58,7 @@ export default function RegistrationPlantNicknameScreen({ navigation }: Props) { routes: [{ name: "Main", params: { screen: "Home" } }], }); } catch { - // Error card below handles the failure case. + // Keep same visual state and allow retry. } }; @@ -73,63 +72,60 @@ export default function RegistrationPlantNicknameScreen({ navigation }: Props) { }; return ( - - - - - 식물의 별명을 지어주세요. - - 별명과 imageUrl을 함께 보내 최종 아바타 등록을 완료합니다. - - + + - - - - - - - {trimmedNickname.length > 6 - ? "최대 6자까지 입력할 수 있습니다." - : "공백을 제외한 별명을 입력해주세요."} - - {!canSubmitToApi ? ( - - {mode === "creation" - ? "생성형 이미지를 먼저 업로드해야 합니다." - : "선택한 아바타 정보를 다시 확인해주세요."} - + + 식물의 별명을 지어주세요 + + + {previewImageUrl ? ( + ) : null} - {finalChoiceAvatar.isError ? ( - - 최종 등록에 실패했습니다. - - `POST /api/v1/avatars` 호출에 실패했습니다. 같은 정보로 다시 시도할 수 있습니다. - - - ) : null} - - - void completeFlow()} - primaryDisabled={isInvalid || !canSubmitToApi || finalChoiceAvatar.isPending} - primaryLoading={finalChoiceAvatar.isPending} - /> + + + {isEmpty ? 최대 6자 : null} + + + {isTooLong ? 최대 6자 입력해주세요. : null} + + + + void completeFlow()} + style={[ + styles.primaryButton, + isInvalid || !canSubmitToApi || finalChoiceAvatar.isPending ? styles.primaryButtonDisabled : null, + ]} + > + + 내 텃밭으로 가기 + + + ); } @@ -137,51 +133,99 @@ export default function RegistrationPlantNicknameScreen({ navigation }: Props) { const styles = StyleSheet.create({ safeArea: { flex: 1, - backgroundColor: "#F7F8F4", + backgroundColor: "#FFFFFF", }, content: { - padding: 20, - gap: 18, - }, - headerBlock: { - gap: 8, + flex: 1, + paddingHorizontal: 20, + paddingTop: 32, + alignItems: "center", }, title: { - fontSize: 24, - lineHeight: 32, - fontWeight: "700", + width: "100%", + paddingHorizontal: 5, + fontSize: 20, + lineHeight: 28, + fontWeight: "600", color: "#171717", + marginBottom: 73, }, - subtitle: { - fontSize: 14, - lineHeight: 20, - color: "#6B7280", + previewCard: { + width: 258, + height: 292, + borderRadius: 12, + borderWidth: 2, + borderColor: "#72D14E", + backgroundColor: "#EEF9EA", + marginBottom: 16, + overflow: "hidden", + alignItems: "center", + justifyContent: "center", }, - captionRow: { - gap: 8, + previewImage: { + width: 220, + height: 261, }, - caption: { - fontSize: 12, - lineHeight: 18, - color: "#6B7280", + inputWrap: { + width: 353, + height: 60, + borderWidth: 1, + borderColor: "#BFBFBF", + borderRadius: 8, + paddingHorizontal: 16, + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between", }, - captionError: { - color: "#B91C1C", + inputWrapActive: { + borderColor: "#171717", }, - errorCard: { - borderRadius: 18, - padding: 16, - backgroundColor: "#FEF2F2", - gap: 6, + inputWrapError: { + borderColor: "#F76868", }, - errorTitle: { + input: { + flex: 1, fontSize: 16, - fontWeight: "700", - color: "#B91C1C", + lineHeight: 26, + color: "#171717", + paddingVertical: 0, + }, + maxCount: { + fontSize: 14, + lineHeight: 22, + color: "#7C7C7C", + marginLeft: 8, }, - errorDescription: { + errorText: { + width: "100%", + paddingLeft: 17, + marginTop: 8, fontSize: 14, - lineHeight: 20, - color: "#7F1D1D", + lineHeight: 22, + color: "#7C7C7C", + }, + footer: { + paddingHorizontal: 20, + paddingTop: 12, + paddingBottom: 20, + }, + primaryButton: { + minHeight: 56, + borderRadius: 8, + backgroundColor: "#72D14E", + alignItems: "center", + justifyContent: "center", + }, + primaryButtonDisabled: { + backgroundColor: "#EFEFEF", + }, + primaryButtonText: { + fontSize: 18, + lineHeight: 27, + fontWeight: "600", + color: "#FFFFFF", + }, + primaryButtonTextDisabled: { + color: "#BFBFBF", }, }); diff --git a/src/pages/registration/RegistrationSelectionDetailScreen.tsx b/src/pages/registration/RegistrationSelectionDetailScreen.tsx index 6c18019..5ae8045 100644 --- a/src/pages/registration/RegistrationSelectionDetailScreen.tsx +++ b/src/pages/registration/RegistrationSelectionDetailScreen.tsx @@ -1,4 +1,4 @@ -import { useEffect } from "react"; +import { useEffect } from "react"; import { ScrollView, StyleSheet, @@ -18,7 +18,9 @@ type Props = RootStackScreenProps<"RegistrationSelectionDetail">; export default function RegistrationSelectionDetailScreen({ navigation, + route, }: Props) { + const entry = route.params?.entry; const { data, isLoading, isError, refetch } = useAvatarMasters(); const { selectedMaster, @@ -57,7 +59,7 @@ export default function RegistrationSelectionDetailScreen({ navigation.navigate("RegistrationAvatar")} + onBack={() => navigation.navigate("RegistrationAvatar", { entry })} /> @@ -69,7 +71,7 @@ export default function RegistrationSelectionDetailScreen({ navigation.navigate("RegistrationAvatar")} + onBack={() => navigation.navigate("RegistrationAvatar", { entry })} /> navigation.navigate("RegistrationAvatar")} + onBack={() => navigation.navigate("RegistrationAvatar", { entry })} /> navigation.navigate("RegistrationAvatar")} + onBack={() => navigation.navigate("RegistrationAvatar", { entry })} /> @@ -123,7 +125,7 @@ export default function RegistrationSelectionDetailScreen({ navigation.navigate("RegistrationAvatar")} + onSecondaryPress={() => navigation.navigate("RegistrationAvatar", { entry })} primaryLabel="별명 정하러 가기" onPrimaryPress={goNext} primaryDisabled={!selectedMaster} @@ -162,3 +164,4 @@ const styles = StyleSheet.create({ rowGap: 12, }, }); + diff --git a/src/types/comments/commentApi.type.ts b/src/types/comments/commentApi.type.ts index 0ac8f32..adec340 100644 --- a/src/types/comments/commentApi.type.ts +++ b/src/types/comments/commentApi.type.ts @@ -6,6 +6,7 @@ export type PostCommentRequest = { export type PostCommentResponse = { id: number; + writerId: number; writer: string; content: string; targetId: number; diff --git a/src/types/feed/avatarPostDetailApi.type.ts b/src/types/feed/avatarPostDetailApi.type.ts index 6328402..c6f9edc 100644 --- a/src/types/feed/avatarPostDetailApi.type.ts +++ b/src/types/feed/avatarPostDetailApi.type.ts @@ -1,5 +1,6 @@ export type AvatarPostCommentApi = { commentId: number; + writerId: number | null; profileImageUrl: string | null; writer: string; content: string; diff --git a/src/types/feed/detail.ts b/src/types/feed/detail.ts index 84a07e2..a0516c6 100644 --- a/src/types/feed/detail.ts +++ b/src/types/feed/detail.ts @@ -1,5 +1,6 @@ export interface FeedComment { commentId: number; + writerId: number | null; profileImageUrl: string | null; writer: string; content: string; diff --git a/src/types/log/diaryDetailApi.type.ts b/src/types/log/diaryDetailApi.type.ts index e6fedaf..e747c0a 100644 --- a/src/types/log/diaryDetailApi.type.ts +++ b/src/types/log/diaryDetailApi.type.ts @@ -1,5 +1,6 @@ export type DiaryCommentApi = { commentId: number; + writerId: number | null; profileImageUrl: string | null; writer: string; content: string; diff --git a/src/types/report/index.ts b/src/types/report/index.ts new file mode 100644 index 0000000..d8f9177 --- /dev/null +++ b/src/types/report/index.ts @@ -0,0 +1,8 @@ +export type ReportTargetType = "DIARY" | "COMMENT" | "AVATAR_POST" | "USER"; + +export type CreateReportPayload = { + targetType: ReportTargetType; + targetId: number; + reason: string; + additionalComment?: string; +}; diff --git a/src/utils/fcm.ts b/src/utils/fcm.ts new file mode 100644 index 0000000..fb0c6bc --- /dev/null +++ b/src/utils/fcm.ts @@ -0,0 +1,47 @@ +import * as Notifications from "expo-notifications"; +import * as Device from "expo-device"; +import { Platform } from "react-native"; +import { postFcmToken } from "@/apis/option/notificationApi"; +import { debugLog } from "@/utils/debug"; + +export const registerDeviceFcmToken = async (): Promise => { + // 실제 기기에서만 동작 (에뮬레이터 건너뜀) + if (!Device.isDevice) { + debugLog("FCM", "skipped — not a physical device"); + return; + } + + try { + const { status: existing } = await Notifications.getPermissionsAsync(); + let finalStatus = existing; + + if (existing !== "granted") { + const { status } = await Notifications.requestPermissionsAsync(); + finalStatus = status; + } + + if (finalStatus !== "granted") { + debugLog("FCM", "notification permission denied"); + return; + } + + // Android 알림 채널 설정 + if (Platform.OS === "android") { + await Notifications.setNotificationChannelAsync("default", { + name: "나풀나풀", + importance: Notifications.AndroidImportance.MAX, + vibrationPattern: [0, 250, 250, 250], + }); + } + + // 네이티브 FCM 토큰 획득 (Expo 푸시 토큰이 아닌 실제 FCM 토큰) + const { data: token } = await Notifications.getDevicePushTokenAsync(); + debugLog("FCM", "device token acquired"); + + await postFcmToken(token); + debugLog("FCM", "token registered with server"); + } catch (error) { + // 토큰 등록 실패는 앱 동작을 막지 않음 + debugLog("FCM", "token registration failed", { error }); + } +}; From e9ece56c37151d9b77e1d755a2f7a84ef491f864 Mon Sep 17 00:00:00 2001 From: lejuho Date: Mon, 30 Mar 2026 21:34:44 +0900 Subject: [PATCH 86/92] =?UTF-8?q?chore=20:=20=EB=A1=9C=EA=B3=A0=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .claude/settings.json | 7 + .claude/settings.local.json | 3 +- App.tsx | 47 +- app.json | 7 +- assets/adaptive-icon.png | Bin 17547 -> 307233 bytes assets/favicon.png | Bin 1466 -> 307233 bytes assets/icon.png | Bin 22380 -> 307233 bytes assets/logo.png | Bin 0 -> 307233 bytes assets/refresh-icon.png | Bin 0 -> 17848 bytes assets/splash-icon.png | Bin 17547 -> 307233 bytes eas.json | 29 ++ src/apis/option/notificationApi.ts | 7 +- .../images/{char.webp => char-emotion.webp} | Bin .../images/{char2.webp => char-stage.webp} | Bin src/assets/images/flower.png | Bin 0 -> 26879 bytes src/assets/images/fruit.png | Bin 0 -> 30095 bytes src/assets/images/sprout.png | Bin 0 -> 13819 bytes src/assets/images/tree.png | Bin 0 -> 26153 bytes src/components/common/ScreenHeader.tsx | 24 +- src/components/common/Splash.tsx | 2 +- src/components/feed/FeedDetail.tsx | 11 +- src/components/feed/FeedList.tsx | 7 +- src/components/home/HomeAlertsModal.tsx | 148 +++--- src/components/home/HomeAvatarStage.tsx | 24 +- src/components/home/HomeEmotionModal.tsx | 8 +- src/components/home/HomeGardenScene.tsx | 50 +- src/components/home/WishTreeInfoModal.tsx | 35 +- src/hooks/option/useNotificationApi.ts | 14 +- src/pages/feed/FeedScreen.tsx | 51 +- src/pages/option/OptionScreen.tsx | 48 +- .../RegistrationPlantNicknameScreen.tsx | 7 +- .../RegistrationSelectionDetailScreen.tsx | 442 +++++++++++++++--- src/utils/auth.ts | 19 +- src/utils/fcm.ts | 76 +-- 34 files changed, 779 insertions(+), 287 deletions(-) create mode 100644 .claude/settings.json create mode 100644 assets/logo.png create mode 100644 assets/refresh-icon.png create mode 100644 eas.json rename src/assets/images/{char.webp => char-emotion.webp} (100%) rename src/assets/images/{char2.webp => char-stage.webp} (100%) create mode 100644 src/assets/images/flower.png create mode 100644 src/assets/images/fruit.png create mode 100644 src/assets/images/sprout.png create mode 100644 src/assets/images/tree.png diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..fb7d919 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,7 @@ +{ + "permissions": { + "allow": [ + "Read(//c//**)" + ] + } +} diff --git a/.claude/settings.local.json b/.claude/settings.local.json index efab5a6..f9dcfd9 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -15,7 +15,8 @@ "Bash(git commit:*)", "Read(//c/MainBE/**)", "Bash(xargs grep:*)", - "Bash(head -20 grep -n \"usePostComment\\\\|useDeleteComment\\\\|refetch\\\\|comments\" c:/MainAPP/src/pages/feed/FeedAvatarScreen.tsx)" + "Bash(head -20 grep -n \"usePostComment\\\\|useDeleteComment\\\\|refetch\\\\|comments\" c:/MainAPP/src/pages/feed/FeedAvatarScreen.tsx)", + "Bash(grep -r fastapi /c/MainBE --include=*.yml --include=*.yaml --include=*.properties --include=*.env)" ] } } diff --git a/App.tsx b/App.tsx index 4a84780..36f7a90 100644 --- a/App.tsx +++ b/App.tsx @@ -1,4 +1,4 @@ -import "./global.css"; +import "./global.css"; import { useEffect, useRef } from "react"; import { StatusBar } from "expo-status-bar"; import { @@ -15,27 +15,48 @@ import { SUPABASE_CONFIG_ERROR_MESSAGE, isSupabaseConfigured, } from "@/apis/supabase"; +import { useNotificationSettings } from "@/hooks/option/useNotificationApi"; import { debugLog } from "@/utils/debug"; import useTokenStore from "@/stores/useTokenStore"; -import { registerDeviceFcmToken } from "@/utils/fcm"; +import { registerDeviceFcmToken, unregisterDeviceFcmToken } from "@/utils/fcm"; + +function NotificationTokenSync() { + const { accessToken } = useTokenStore(); + const { data: notificationSettings } = useNotificationSettings(); + const lastSyncedStateRef = useRef(null); + + useEffect(() => { + if (!accessToken || !notificationSettings) { + lastSyncedStateRef.current = null; + return; + } + + const syncKey = `${accessToken}:${notificationSettings.notificationEnabled}`; + if (lastSyncedStateRef.current === syncKey) { + return; + } + + lastSyncedStateRef.current = syncKey; + + if (notificationSettings.notificationEnabled) { + void registerDeviceFcmToken(); + return; + } + + void unregisterDeviceFcmToken(); + }, [accessToken, notificationSettings]); + + return null; +} export default function App() { const navigationRef = useNavigationContainerRef(); const currentRouteNameRef = useRef(undefined); - const { accessToken } = useTokenStore(); - const fcmRegisteredRef = useRef(false); useEffect(() => { debugLog("App", "App mounted", { isSupabaseConfigured }); }, []); - // 로그인 상태가 되면 FCM 토큰을 서버에 등록 (세션당 1회) - useEffect(() => { - if (!accessToken || fcmRegisteredRef.current) return; - fcmRegisteredRef.current = true; - void registerDeviceFcmToken(); - }, [accessToken]); - if (!isSupabaseConfigured) { return ( @@ -53,9 +74,7 @@ export default function App() { - {/* 한글 주석: - BottomSheetModal을 앱 어디서든 안정적으로 열 수 있도록 - 네비게이션 루트를 모달 provider로 감싼다. */} + F0AksTp~gY0?8%qn{xva(6`Izq}Wdmm(F@6G?E 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
EU}()Q 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≷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

UkEvwXWwFdOobeXOVo#P64^+Yy_&jMo4 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

EU}()Q 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≷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

UkEvwXWwFdOobeXOVo#P64^+Yy_&jMo4 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 diff --git a/assets/icon.png b/assets/icon.png index a0b1526fc7b78680fd8d733dbc6113e1af695487..f690d82556d1ae98b560a894d60d4678af7ae11c 100644 GIT binary patch literal 307233 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

EU}()Q zaRbVoapmZu{<58&o$mD`jACKe`c&db^ELWmk^C#`uRUqLPRU;II_4%k8R86P!ZUFt zvw^G__2`M;e{Vpz8wGd=ZHr7 z@Els$99oG-%>qiwmah-hjaQ7!8nd;tJ^mFUtF=lxf&(NNZPt34-kOdMdA{_QtgMtk^caTX?d&dzm&bym z4L)Isfl#IF3DMwjc18@-dL9%}+J3{%Skv0F!e#d~|L>UkDS{nZbk=+Ia@qyAq4Q`G zR&ut8QM2`XXyg9y_w-}`w16t;#8Co4r3;M4htu^0(Y$6E}I7}>{K zW2)~-oJ}vt7bgAnto!nkd4!Y$dFr(-UDtV8%Xxd&_I5~UGJgT7SZN>!`2oBF zdbwlCZQm6gcHO!Quz<2{d^+^twcHyNXl7^#?>)KTJ_UYb(0S|({Yn6gYju4O+Deg4 zl9|Z+@1j{@NFca`+54*mCoqly8Y~b5=l(Mbo~icB*T%vovCr(pIe&Dbn*`C38MSXVv2dT#-)u=g*p# z?{3leZS`$H;4E!zn?JL=Ct?J7&Fq;IN-4B4SKz~V7&M2%!45VMIfAKZkqu+Y5y&t8 zIsFJB>i#aF*!0rea1zisypj$bG*L+6f^}!Ae%e%Qbvn~LEQ*R(U5})tex3FtkRAA= zkJ|!qzFP|yX0t?VJ2^e>nd@Upz7IuJX6`#>iVx{reia(!vZar@?W1+vY{m^)aC&VBLC2v7u>Oa4b zrBy=}>r4e_%2eO<1>??%C4O78OpQl?XUDqk=BB_G3cdu3uT?UPnutyun6RjCA5@BD zr6PPxNA6KvI3EtQ)V&M9IKcsiBgJEX%VQ@2vRJ1GYXf279g9`9W`Ry8!Ova2Yz?zT zO(OnXP_c=e#H8JtG~~2q-e~PPSK0X~IkulE?aba*5?*cVzVqkCJUGhFy)#0&f$Nc@ zW^91Z3*Z#{yUlyWc%}v#|q!tQ|Xc2pCNbyE3gtCZvZ#ORqu&1 z+A0NUkTb=cks#`Ud+(0;`!AiJmD+hk7!o?)5_aXcnqWW2Lu1=nqQ_MwsO{m4H68xy z`x(PvqJ?6f4={mXP9}d%2~a%}yy2Ft=m#EGsh5Zk{YM7*pXx~nVH#~Q^2}K>`JgsfY9e{NE3xr{6gO7yH)kjk?ibXesqA{#gXd}-VCZ7WmtM2N` z&)Y5!GpG=Wt;G;4VO@ zeHdq~o*BEh`LopI%w3biLWL8*uz=D~JsLGXY+*x3*d&4c@0SB5w9IhEwA+QD#QK;! zs_#dBR2c!(LTscFQ9fEd&1g{0IKh-B)7yo@>~5l32|VE23n}GDpHsJQ1J5jPYY+d^ zq~LRVD#zMA_VIbbYX?1(vNYxyqRGC%1qaSu*K?+Ui@(`3(>E1Tf&NM{gulhL#+Eqm z*26(yURV&f=`O>FBfc16M4u8Gp!{Vc$E+NDo;utC=@<^7t@=fx3p&?Ty#FNLZo%}0 z1B3a1BS#u*UL}mk`Os0fuO+=L^}ae1Ent-Hrg0e1j$qY8RJqz|^9>Kr03F6S&>X1& z^YZ3N*UDpHTtxrk+!MU~P8?lzBuC2UvRp@htEX4B;S-QEaWHrPiwnLj)RPPW;>(SH z1Pvl#(uoM_c?-o0N3P=oNh#z$^`<}aj1fxv`vKrR&};Z$zCQt>LUznY*<`VJ;Z989 zrargYje_=_#o$ugLBG#pT8*h;6hLqpWD4+5lq9)PeXSw{zotJ~S_d46MZ5#UhZL-E zBs6t0h8du}hz-7?`s@PxHxZ^3Y%TPHPslj=!ga4h}XVY#;XzOh4D@HY8* zG~9bs3+(i)|M|HQo@3tU2ve2>YLZRm3L#>RvlQQE{tO=!(Add<uPeQ(l)|}ynzWGE1PEV8q6)kCERJIjln6BPPohMa=@xOQ;x;QomtiJbRj@m* z0+O94zh@6&Mk_fHk+jJvEFgAmlii7wAJX%PDl8=|K_6k#l3e(~fW%GXgMhRCQAM}U zy~;XoUy^&Rqf)I3YmZ*-!^gAumv7doB2hR`3Gxq;{JT>7iPVKui)@1}ss-ir(&orG zxSqYT@m>KKu4EG~B9iQC`x6FydwUb%QBjY zqOXrJ?!_4|(Tz(vHzQ& zUSh_D#Hh(3AwgZtzqjcMz?S0r5hquftR?cLy{X={2+CsGmfzu?qOPpo0{Z+o_rACU zrxi7fX($X>ONdz=){J^{3Cf(ow(QQOhq03FZ1GqqvW@m25f>)Z{z?sktVsA&uI=)l zsj=$N%JRs5k%DN@YaRiSX^M#~5W|@qkacJ=RGDKv!xIec?p_J-CK(P;A;)<5x>)8S zdj8}C@IL?=M79(KGaqd8wdipp!ol^*`5#kq#nFspTuWcuY<_Ba@6|drSw!U zWc`hIJ1s(ZLcH|d+b(b|Ki;2)D)R4gMchM6BID;&c07K+UumnDfRxHlb~TlH6JwR) zgjig#WVeM`NFHik=k;C+3l8ldeyKDy%N4MSz96?( zez8FE9QCxL5!L6-MtS^{Hgqd-rXX|C)mC=B5E1p(nRiuJ2fK&#jNhEqW$f=-l&6d> zYLy*$_i+66gyiM zv}^0(7z30-m}TFejrt25975JW2;y+w-Waq6}Zc_PNpQ+ZrZKQ z{!58T9)NdR(4|Hfcui7<|B%M@I3@Ezv3WN-moP-LR(+N`=C`q+@{M|>4MJ+t#^Is-%C(?7%HoojV+^jfA7=`afXjp^J=cu%kR94$)w zf)|8?tK3x0>I;q9+>7-;={=^? zn^Q_NOBtVtr61Sn+(x&@kCg>(84r`ROt;+qlS<(4h5m--Zf@BmEZ`!EkXfH84?2jG zTQ`hj@8l<15EPqHct0aOf7+-;9FZSEfYg@nmD6f0Ac%TuIH#++shZB|8)j+*P3Y{o z9Pn$pdc+RgaFP-@YI0xwmx+ktFG3ETMECwq{mTwF_#1vDy^0w>yMAsoBJa%7DBIzA z6=LI**wA#CV*wEKDVw2sG0G}J3suBo#(uN>UaKqP(>W*E;-NR(-sDkRP}i}|I6f>t zPi#DT>LTbN??}XkPeG}p3$dN?Y`>4cjU#zw%NvUOQe*sj56#l2?S`isyWXp`T_gh3 zsDrV~6M|On>;vUT$P!~TR+jM9E_P@mv-6Wy*?ly#cCa!(pY4+y~Z zjt?Uq75A-Lnb%91x#ewzyH~$VYJv@&gXAO48na`Ng`Hq>Y)q195l(AE3$?{!=#*R5 zlqnC%<&F?-0v4X$b%Pt_B@n!uS0kkpnNKA2NH>v!vn77%JE0b{G8>T>6-&cW705}J zz(aH<%p^INkp*EGDORF%!DeB}$bOMI9m9DtyL&U2_r%p{zaizVpIl>G96cy(1(<;x-!{%qWPO z%7|X~W5N`%OyK!i0MxL`JXhWFRZzh!)khaE>@iFZVM5(LSk>YFuG@FPzAr+6-H7!>4-mVp-wiZBu9mgtRCZxThu?Lk78Kp z71>*i;vK&Kho?s3Z=ik>${B>>>U{b>VxM$H2}?Av5Lw=!QA&+O11X|Re4k&gLobb2 z?_BQ1tLB&q9)58>8RvP>vwaG!`AhgR`}0?+&S?*#druY(GBM0aI^A${PRvtd0j#|8 zH-Piu@E_G_n8)yjAUfnzHJ#w`jqzAj>cuC{5i~Fhya{d7z%c6rzty|i3h$jlyC3F| zQt8^pH{7l^lIw!c!^x}AV&+eor&X}~^2?@;^tG+yS;ONho`HH_CRL7?{iJ4wX&a5X zq!5Mn2H2JQG2ss-2-+MOKR_S7vH zD`9Cv0fN~R(AsoZ@poP5!m);LGsKmoo#VRf4)O{GrC=<*m%>-ceDmkKf&WiX_;qNI zO!-Z@{VP15P#^r3m0#oP≷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

UkEvwXWwFdOobeXOVo#P64^+Yy_&jMo4 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 diff --git a/assets/logo.png b/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f690d82556d1ae98b560a894d60d4678af7ae11c GIT binary patch literal 307233 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

EU}()Q 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≷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

UkEvwXWwFdOobeXOVo#P64^+Yy_&jMo4 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

EU}()Q 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≷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

UkEvwXWwFdOobeXOVo#P64^+Yy_&jMo4 zy6AD#&I#m!^61eREj2bQ zN4Ali$6WJNtg%y?G;d*=eZq5y+XMj4N7H5=<1G1u28#~$%pQzhw&aJ6Ypjv~bywwcy zMBFi;j$^&le8>P9o2d=fJ*lO`M*ed!*i8*)F=Mb^1L06$AgVXgmWkdNBe4Zma@%tl zIMYbDLHB`)e-O)&V%l{YCH1`J3h?!q2<9eRft^^uRDhDXPr;4--&=m2}wsWY?vYD@nmQl9NBHA&(rcB$=T$i2R@GZr#)f5@=*i`}?+&WIL#`Q%tJtk_c3K z-#BF9Lv1UAzRiSEuxfJqmLD>>5&B#2==NhV5NKEg=OM0uZ{k3ZN8W;D5u^bO=No3H?IigUP~N3+ z+m4-ZRXtd|wIjk=v5HaS$iv;33gGqL3+8%Zp7@BFI@0;|KCdej=oCO^Lq&qwd8UF? zgFi1xu&uRAQ)23lF-@fq1dD4QU#4$(!2~Cwc(Xb`2ef>yGKmGD{?fspH#s;2ICx7; z{KDd3r`{VpKWy8)e^3}RbC3bajX=5-GxS1*r!1qQVz}i;u-A{ycjK9!O*$oZX&nrp zpCaLqp^8u=?6jHe2_yK#SyuiV5dU_*w;QVe7zvuSbQI^tNT`GW*;=HRami~S6z^^D zRb)qY>aCB+s;}QY@4&4CXg?;2Q{N6t`!gg2<&F@e>^+|$?$FP0{u9du3&)^j09VQ> zF>cHoRJ5kRhMOmC4NB8fcVFLdk2)~(g&h|b!J-r25kc=4eC)PfGxK|3l>(c{R1d1A zV^1rFfS3k-M+C&II?WG!O9U_6%NSO^q}($KkKQcdZ-WZ#b{`@C2m<{O7L}&E!Z~t* z502Cq+bra@4gnDO8{S;JAtbUp;^+~UL@t3vF43Gin1L+qK$H?oB0K=#c>Eko-hpCn zRTPd^4fzgg89}%pQ~n1g${{qGD5tB)Y!A-kpO6Y1^*#!CF?o91=)-HS<@; z%$fy$8DNGC((imm9E0k%y=$p;nil<2ZxO|XEdL4xJ&#cA7c-j;!fHdY&G-(LuaNBp zMwWcqAn<;syK&|K=`A$~gb}io{gVyGToZMDHxeJ{Z7_KITi!mL`SywKBFiOGAAq-i zRO~@`29Im1uJ7jC5b(BN$3BkvHbQr7<5ym|F>rR{`xzzQH@H$W6k{fXQ2q}P!@i=` zj490IgS?wLbt~|W)}B#WW(sD-|KCO*Qk66Pyqv(oKf$7)&mj6RC5LI7^_&)RDS>ON z?T0N z#w8#(De0ZeXC&~@&M%O^O%*L0Tl(Za+ys7U$Zf0nuYgZ(*Kz` zDiZkrxhG$kkzhOxmn1V`Oe6jK^c2fFEx~e@y@e9YGJ$l0Ox=qk8cjl+u0Q26AZ^Se z#@RBHX(7)4DF#izGA4a)mq=bAeU|P=Ar)SK`Yv8~F*23vPcQYR7`$aV4gGoB~ok)%!zMY6D7t@Rzr-?{aOF3}A8T z1+c>l%^rhhdVGv7Q=gF6f}ARKc}LXX`kY$ZgY(z>`9R%WfY~k*o7wt7!T;@zrKSSX zRXJYR`dWBhayH?`+9)mii9O?10;E=`%MRI~-L6Qmsd58&Uyxz%AiOYn#@4;CdTItK zyxKY~Je?Tqls0Q3=}#5i^Vf|76wf zIuvq>yoYms@_wGR-tRxL(~eDpha38fR!npVAJmI-9Dhs?ye}&ApQu`M_^q(@F)3;3 z)-B^sb?jq%9~n+Norb}J0WYdn1c5qNI(z{%{+2)&d#T*Gk#UhpBmyb{zbuVUwsXa%LIEc(uiyx!gHQzmW!8K>8UIX+a#{b%aQ&(QF@c8qXevA2 z#Uj%_*5O}ld5ml23-Y)2=}t;}1i6R>h!xMgTbK=Gy1tkX3uqqV4nQ;RpVC|JCXquq zzgz$6jYl4zb-xf}`WVO0--)(XFGMQE%QBkLM>t?U{Og)u-o|zveP++xV3EXBdW@YJ z#t@g(Li{mNTN1KD7f{P5(Z59p0G<1T+_JV_Ap^oPdEWU^_QD2Z%NJ6X#`y@?EX}ek)h`_YpFAg1W6@b&xpSD>%GI;Pfh)cK6ddT&%64XiPInHL|g>!3tB2@ut zEfgFagjQvm{S@b$IDr!{lmXiC7KP5{x6`HzpR#fqUCv~X$(vlcwLMr!9M*IFEHcK3 zTL=Bv-Ofi1ZU(h8aSA&p(#$&)4AbrbY$qE6%;dkc|0J2t3G2Ux2vi6mrFHRK?x5L6 z{{vOioD!QYIbJA@;DBXUe1)c?x0@t0oJl!&+3u60)ca+fU|VLWhx~aM_}Ko$^)JiV0mli6V0x)zm`bWsOs^)_ zXSofOhNk!d0*l%45eOC;kDqvy|3=sY`v85mWc!%Z^_Ty*Cjj&g5pPi&VU{$02cs(_79;y-?M_2<8zbyZcLtE#X^ zL3MTA-+%1K|9ZqQu|lk*{_p=k%CXN{4CmuV><2~!1O20lm{dc<*Dqh%K7Vd(Zf>oq zsr&S)uA$)zpWj$jh0&@1^r>DTXsWAgZftC+umAFwk(g9L-5UhHwEawUMxdV5=IdKl9436TVl;2HG#c;&s>?qV=bZ<1G1 zGL92vWDII5F@*Q-Rgk(*nG6_q=^VO{)x0`lqq2GV~}@c!>8{Rh%N*#!Md zcK;8gf67wupJn>jNdIgNpZR|v@cIA03H<+(hK<+%dm4_({I~3;yCGk?+3uu{%&A)1 zP|cr?lT925PwRQ?kWkw`F7W*U9t!16S{OM(7PR?fkti+?J% z7t5SDGUlQrKxkX1{4X56^_wp&@p8D-UXyDn@OD!Neu1W6OE-Vp{U<+)W!P+q)zBy! z&z(NXdS(=_xBLY;#F~pon__oo^`e~z#+CbFrzoXRPOG}Nty51XiyX4#FXgyB7C9~+ zJiO_tZs0udqi(V&y>k5{-ZTz-4E1}^yLQcB{usz{%pqgzyG_r0V|yEqf`yyE$R)>* z+xu$G;G<(8ht7;~bBj=7#?I_I?L-p;lKU*@(E{93EbN=5lI zX1!nDlH@P$yx*N#<(=LojPrW6v$gn-{GG3wk1pnq240wq5w>zCpFLjjwyA1~#p9s< zV0B3aDPIliFkyvKZ0Pr2ab|n2-P{-d_~EU+tk(nym16NQ;7R?l}n==EP3XY7;&ok_M4wThw?=Qb2&IL0r zAa_W>q=IjB4!et=pWgJ$Km!5ZBoQtIu~QNcr*ea<2{!itWk|z~7Ga6;9*2=I4YnbG zXDOh~y{+b6-rN^!E?Uh7sMCeE(5b1)Y(vJ0(V|%Z+1|iAGa9U(W5Rfp-YkJ(==~F8 z4dcXe@<^=?_*UUyUlDslpO&B{T2&hdymLe-{x%w1HDxa-ER)DU(0C~@xT99v@;sM5 zGC{%ts)QA+J6*tjnmJk)fQ!Nba|zIrKJO8|%N$KG2&Z6-?Es7|UyjD6boZ~$L!fQ} z_!fV(nQ7VdVwNoANg?ob{)7Fg<`+;01YGn1eNfb_nJKrB;sLya(vT;Nm|DnCjoyTV zWG0|g2d3~Oy-D$e|w|reqyJ}4Ynk#J`ZSh$+7UESh|JJ z%E?JpXj^*PmAp-4rX?`Bh%1?y4R$^fg7A^LDl2zEqz@KfoRz*)d-&3ME4z3RecXF( z&VAj}EL`d22JTP~{^a_c`^!!rO9~#1rN``Vtu@^d~$&2DJ0 zI`*LVx=i7T@zn{|Ae&_LKU;BmoKcvu!U;XNLm?- z`9$AWwdIi*vT?H2j1QmM_$p!dZjaBkMBW#Pu*SPs+x=rj-rsZX*Uwl!jw##am$Sla z={ixqgTqq43kA2TwznpSACvKQ?_e*>7MqBphDh`@kC8vNX-atL-E9HOfm@-rwJ=!w zDy4O~H&p86Sz}lqM%YCejH?s7llrpn7o|E(7AL-qjJvf?n&W*AizC+tjmNU*K603| zOZctr603w>uzzZk8S@TPdM+BTjUhn)Om0Fx>)e6c&g69aMU3{3>0#cH)>-E7Fb4xL zE|i~fXJ!s`NKCviTy%@7TtBJv0o|VUVl}1~Xq$>`E*)f6MK}#<-u9w0g2uL2uH;F~ z;~5|aFmT)-w%2QFu6?3Cj|DS}7BVo&fGYwubm2pNG zfKnrxw>zt-xwPQgF7D3eTN17Zn8d$T!bPGbdqzU1VlKHm7aaN4sY`3%{(~59Mt>Kh zH~8zY;jeVo$CVOoIp;9%E7sP$0*Cqou8a-Ums!E502h{ZMVy|XH-E90W)USFDzSjp)b$rmB9eaA1>h zZ<`M7V|PcDSP0lL>GO^&xuaLpig7~Y3;E3E-f@>AOliK)rS6N?W!Ewu&$OpE$!k$O zaLmm(Mc^4B;87?dW}9o?nNiMKp`gG*vUHILV$rTk(~{yC4BJ4FL}qv4PKJ(FmZoN@ zf|$>xsToZq>tp$D45U%kZ{Yf>yDxT|1U6z|=Gd72{_2tfK_NV!wi$5$YHK zit#+!0%p>@;*o?ynW3w3DzmcaYj7$Ugi}A$>gcH+HY0MFwdtaa5#@JRdVzm>uSw|l3VvL-Xln~r6!H^zKLy zMW|W{Z090XJupzJv}xo0(X~6Sw%SEL44A8V}VDElH!d z>*G!)H*=2~OVBZp!LEl5RY8LHeZr1S@jirblOln1(L=0JXmj(B&(FeR9WkOlWteu+ z!X75~kC)10m8Pej+-&6T_*l|x`G(%!Dw)BrWM*0Hk-%zF{{H>1(kb7 z4)}@b!KeU2)@MzR_YE%3o4g*xJG?EcRK5kXSbz@E+m@qx9_R7a^9cb7fKr1-sL|Hx0;y;miqVzfm7z;p-)CAP(ZiJ zP1Y%M-_+4D9~cib;p}(HG??Wn1vnmg@v#rr&i#~r$Wwqk85%Axbzh6#3IZUMvhhU@ zBb%DLm(GHgt(!WkiH2z!-&2b)YU6_KW!G-9J9i_z)(0`howk{W+m9T>>TqI6;Kuqb z|3voT4@T;Gn&UNdx+g&bb`SsFzPp(G$EED)YUct=@1m(ZU8{F5ge^GUuf~;Y&sv=* ziv8_;Y3c?0@zpo_DU#(lUdOB1Khv)>OY90tw#Z*6m~Q(nw1v2@21||3i}LH~zg2&a zRK~&B2OrDXKnKp}GXpMm%ZJ^HTRWKRcroCL_|6xZoD-#3qpC`X$a{Y<{(DFR?P~WM zQQ@VwTnF!hBK3w(sjs%RMRvk>BDzO+c~_XeFvaf`)o;ylGq9&7%V_)#L?|%aFD2pF zoisAcCNS58Cjcq8wDKX22JiM0;_|1*TYpvgziQ-IT%qgY2JJ9>qg5V>?yDuVJdArVp_*M5f^p;!XL+`CZXIz z&rC=}cLo@_Z*DU{LE$PR$sXxXn1@wOg5yi(z4XV?=*+KPm8XtGOiM#Ju5zxQZ<-j- zWUgqFd9cs}49w<*_`4A`Bw*I&f|oI<xl5> zVFZ2Nj~iRjUXAa>(fXNh^l0ZvZCj}@-|mHBAfc{{giu1V*5YbZoWSQk4n50vJhk5U z(%~pjC}zxiC;H4m8q}m=m3wS(8#hGA^wk5xKEb6D;tiW=`Sq=s+BIa}|4PYKfRlyP zYrl_^WKrE&P?=hyvPG`OPl^JBy^IJP$fDS=kV$jySp_Zfo)VztEnxJtA5%{TMQ}>f z7)(c`oDc%)o70pZfU5mSJqy0NhtDg`JF1d_Q7)jK{(ULJE=`#LdopdJKEt#k4J7#7 zHOIUCTFM<46TmOC`1i`8O@L5bv&=_jYTiD>IYC~+Q+)RoebW3r;^Iehpng2|yd;de zJ5KgeWK#i0JHt%Vh8L}%06l3tR5^>%5BOp2+sz2Y<-MfS!PB1Q+#>y2%&eMwBd@3j z=bIn_S@vrd%|mYBFpKmmI7L9WK=$|y5pIxl8kb@Q#9?S5lzDIp^6t|E@mn5>h0@LX zK5t(Gk#`NN?T}O)dwhpjGXabPxSDo34&-s^4bs!=oG}g5WIH&+s$#qjWa}Qzc;|uF zjmT93Tt3wV$xyw$Q~~O)n_sRbDAq6)VeKQ<$BnQn+=~XDTd9hO;g~ILIS_U-iVNE> zP8T*%AbYt$AGdO!n3*5rLc@Me=!J(I1z=v0T1R`o5m|{)C|RTYTVNuTL!n>uc);VY zt1hK}GgHuUkg;EwmlnFSqOS2-CBtR8u0_ij`@xIE`~XqG)j!s3H>CR&{$1(jD0v2v z6LK_DWF351Q^EywA@pKn@mWuJI!C z9o+gLqgrVDv1G?Gbl2z+c>ZjT!aEb(B{_7@enEhJW20r8cE*WQ<|85nd`diS#GH21^>;;XS{9)Aw*KEZw0W{OW#6hHPovJN zjoem5<5LbVSqE%7SLA7TIMy;;N%3TEhr=W&^2TFRJUWPve86@7iEsH^$p;U=q`H!)9EwB9#Y=V-g&lcJVX;dw}$ zvE?Goc@I7bt>>~=%SafT(`sK|(8U+Z0hvZ`rKHT|)(H2{XAd;2_a?X5K#5EjWMF~@ z=Dx$iW|qOsStpJq`5mS6o{?&hDkjLH2Omg)(og-e>X->WQU8V^@vGI{=FC9ES5e{A zptfOTbCVipp$%$%4Z3!I{EpC`i1AM}X7`m)lAs2KXqp( zxS7r0jzS+aeOwl~0r4WDc$(~!?+=hpubxt&+pyJ|MT1$(WA>^N&d@0YIPh1RcUwrD zVClN;B7^C`fzofKtfG7=oGn!WXK-ng6(+_N?txi@qgah^A0zsqx??_U68mb73%o9x8I-BGbW3+qPbqD(RL3!8Is3{2QUr@pfV7s zyDvbLe)5av)u%m{PWT>milh>L)XBGX5hkYLbwus;=c-=K&e*&CVK0|4H9Is98XSS3 z?u#8@a~?u~@IWW~;+ve_(hA~~Fpp2>DDWKD-8{zTU8$j91k|r1fqwhasxVvo0@rBl8WY}*oQ9Qli~1-fda^B`uahETKe zW2a_^&5=2w7|N;ZY+Cn99syF%rJm`4_ehNznD=O)C3=B-MC=0}tSBRwzsf*r%ch2U z-|x@x9AkL*xT>L}=7IyUlfB$Wh-7}4GV?|UtBfPb|iP*S;^5@Xl4#xc-reL)N8g-aP-H;@?3A`?b4>#KAW#~2t$Lnf@L(h&flZE%(6UHif)My{j zHKntv_d94HiH`>MIeHL*46n>b$nl0U9XiixT2^=yst zTrW!v9UQnvt-ow8GyWB+Q3N?UjTr zT*VeybJ8~IEqwnvI1Z+8zpGbPQt*i4~_e?dK-4%6+$D>w61II;f zl=$T^9g&Htv*eRMTt2s^XOjYM37Mt}HRpl9vCaGZW`UOf$bn4W{Wlk*_=dx4?P?dG zc#bUGmYTaS^iXdm$hX@@-@0;Cv{8xFn0*_Crfn}XIG@HmE`rk z_0-#^aKI@cL52NhLEZr{LQq5cDvSB8q&3%qGa}t1t3Fhd+_iON`Re{;nlv=n^uo`( zn0&8)ZX$v7H0-r zBJE^dvRs$sS!1MWb2y{NIO<_huhf+KvH2^_pqq@=u{mwQM+P=4apqt>Mv*kd^v%AY z>FL~qxn5Hn>3~%y=6$CX)ZfvZt(a3}f&Gwj8@f*d?{BSvkKx-&1>jTwdR<0H-Q_{gH z(h+qS!JO~g9}y>>(0!#1RKpoU(;A+m|2df6OmoD#K6&xZXSO2=MeK49(A#1>_cSK$ zxNTS+{T1SB0)*+{nsumSHMf!pNG5HuA1`$-Wjg9T(L@gIMhp~B|Dm}cwL*0tGV+qSmExLEP?K_cA<;ea@WI{6 za6THY@lQURt`WtlVfNM*|8R28OSRM_Trp~14J z(Zzsnr9G0C2^O8T-yW7pSMI-|lgV2}v!)DmLWT+$y6?Y4yt8nJC?JpEDGwk0%`nH@ z{@YsI5Fkt(BdW!DT}M*)AT;Xn4EeZ=kmyOWLx}g_BT+b(c&wxKra^43UvaXoE8}*&NOlT4U)?L-3@=;fJx& zaGV?(r4A(EoRO!`4x5sfDGkfqDQ5ug=R+xpr=V3Gl<*vVyB4G9du)3ZA ziDzy}JA7@I6Kg;jB>IgnL+V`q%~d0KG(c5fuxODH9*a=M_KaVXzgA)8zi9;+J+nvo zkNl=-q^o~L;Z>owxJT@rd=E*8^!|~GduhQ|tU+9{BxPfkgdK6)-C#Ai*>ZbxCawR{ zL_C7c;xY(LU=X;;IMRj<#sis39%c`>|Le8OdCnNq)A- z6tK0J+l1)b(M9a<&B&1Z#Jth4%xQbdMk#d&1u)0q$nTKM5UWkt%8|YvW(#deR?fae z%)66!ej@HC_=ybH>NC04N(ylmN6wg;VonG`mD(Cfpl$nH3&z>*>n5|8ZU%gwZbU@T&zVNT;AD+*xcGGUnD4;S-eHESm;G=N^fJppiQ z*=j&7*2!U0RR2%QeBal1k5oO`4bW&xQ7V?}630?osIEr?H6d6IH03~d02>&$H&_7r z4Q{BAcwa1G-0`{`sLMgg!uey%s7i00r@+$*e80`XVtNz{`P<46o``|bzj$2@uFv^> z^X)jBG`(!J>8ts)&*9%&EHGXD2P($T^zUQQC2>s%`TdVaGA*jC2-(E&iB~C+?J7gs z$dS{OxS0@WXeDA3GkYF}T!d_dyr-kh=)tmt$V(_4leSc@rwBP=3K_|XBlxyP0_2MG zj5%u%`HKkj)byOt-9JNYA@&!xk@|2AMZ~dh`uKr0hP?>y z$Qt7a<%|=UfZJ3eRCIk7!mg|7FF(q`)VExGyLVLq)&(;SKIB48IrO5He9P!iTROJR zs0KTFhltr1o2(X2Nb3lM6bePKV`Cl;#iOxfEz5s$kDuNqz_n%XHd?BrBYo$RKW1*c z&9tu#UWeDd_C`?ASQyyaJ{KFv&i;>@n&fW5&Jmb7QYhSbLY>q9OAx+|>n0up zw2^SLO!XASLHCE4Im8)F`X1QNU}mk@ssu*!ViT@5Ep%hB2w0kS0XQbRx8B(|dSEMr zF^e0IZ1$x}$^kaa8ZGi}y=(Rn1V4}l?Tx`s=6Vr7^|9oYiiuHlWJ&7W$}3x}Agpk} zeM0Fa;wuFuzh&67?b5ElegEwyD4ctwO6z|2^Ryh;U^}gvl|f-s>9f9hL_ybM0@xG( zQ1I~tGO7&d2be|<#Cs(_l&dG8)_#H8s7G?8-|1Fi-ZN~Kf$1)`tnZ~?Ea2SPC~w!% zN5N}H_G0#jI!9Cw#D~!7Al;b%PS%DkYv#jUfx;B3nk6lv({hlhK8q$+H zSstPe5?7Eo_xBsM+SKCKh%IedpelOV3!4B6ur$i+c`Cnzb3;0t8j6jpL&VDTLWE9@ z3s=jP1Xh)8C?qKDfqDpf<<%O4BFG&7xVNe1sCq?yITF_X-6D6zE_o& zhBM=Z$ijRnhk*=f4 zCuo^l{2f@<$|23>um~C!xJQm%KW|oB|Bt#l3?A6&O@H=dslsfy@L^pVDV3D5x#PUp ze0|@LGO(FTb6f#UI7f!({D2mvw+ylGbk*;XB~C2dDKd3ufIC$IZ0%Uq%L`5wuGm}3 z#e?0n)bjvHRXGhAbPC)+GIh!(q=}cRwFBBwfc~BY4g-2{6rEbM-{m650qx z^|{n|;_zWeo2#3Y=>|Ve0(#Y)7Nywel&yjJMC1AS;p%g=3n+xHW&&@kHGo5uu=vKS z=`3?V6S|~7w%a5 z{}=htve$^OJZLo1W}!u*ZTG9|M}ecn)6-YdK>$e;PpbW+^8K8}!6N_KMOdDCdW!;} z?sFLI8mGJntXnvi29p;0^HLaV;t1fLNND@^-92U2w4$!I931qha#C`Q2sk*fIsVZS zBna`<`##i>ropjwol`Lv8)&Aq#+2uuqa5@y@ESIbAaU=4w-amDiy~LO&Kx2}oY0hb zGjdkEmn*sQy#_>m`Y<}^?qkeuXQ3nF5tT&bcWzljE#R0njPvCnS#j%!jZnsMu} zJi-)e37^AC zGZ9?eDy7|+gMy$=B#C61?=CHezhL$l(70~|4vj?)!gYJqN?=+!7E5lDP}AKdn9=du zhk#)cDB7uK#NIFXJDxce8?9sh?A$KeWNjKGjcPNdpGDHEU=>}`HxpYfgHfHh29cAa zUW2P@AB)UO>aKdfoIqg0SGRpc4E&-TfB3Y9Q%|WAj|mG4e1$IOk1CmNVl)I9Vm4wo z3(oVdo}JO$pk8E*ZwuuQ1THZ4-TXOKvqfwqg^A=8eE+D`MRVo|&eynm{Ofwwm}6xr zi-ZBSj>L9g$p$AoVv9fu6%h7%f%`)l+O2bZ@%rC3f+-_J_0ap(NLXgyPxdw$HM9~= zFABy^XplC%j6ExbJHBu#cganl#xs`^X-w*M1U9Y{Cs%L|!sU3)rK(498T1HYtO-*t zE>i}}Q^5VijVUo+a{N20QKeZ&mUB)$2x>!>nfd_<&42MzO_oU^Cuw3W1U>C8k4Z-;I)Hwz}clprW*1#cN9Eb zc+)>qHS%7}9^t&jOjsczIIrb)IhH|7_FvnJ#3iry6`pc8JS^|zdc`sIrW~1v44uAu z4cXW$3L?~kE9>1tR}nrfv_T83-xr!;EgYul%$1fy>9C%r0(M(5`Ww>Z8eY8jc)$22 z79&%(H(PfzKGg~3+n=o!mLRb+v51(qU9bb zgq44mOQDCxkf_0mCPe6MW31cl?In&&s*%%+%XbEe{59^Z=D4z^C9H>b{DB2~UamwF zuSv;}X)m89VM~{>c0?+jcoejZE9&8ah~|E{{pZCGFu4RXkTYB4C|2>y@e+&j`Bw8k-+O@%1cfIuz5?+=-ggCj*qoolI4MOO5YF&V{*r$zYEKQldnW$~DOE*= zjCNv~z^rJMo)l+4GaQ}uX*i+ZO3((%4R}J!+$z^OMmeQ@g}-0CU`Y!IT4V!T zsH%huM^)eDsvK%fc_5tS-u|u^DRCgx=wgz($x22;FrR=5B;OZXjMi_VDiYp}XUphZzWH>!3ft&F_FLqSF|@5jm9JvT11!n> z@CqC{a>@2;3KeP51s@~SKihE2k(Kjdwd01yXiR-}=DVK^@%#vBgGbQ|M-N^V9?bl; zYiRd$W5aSKGa8u$=O)v(V@!?6b~`0p<7X1Sjt{K}4ra2qvAR|bjSoFMkHzE!p!s|f zuR@#dF(OAp(es%Jcl5&UhHSs_C;X87mP(b;q0cEtzzDitS8l|V6*s)!#endR=$@lM z@zW@rnOyQ#L8v!Uy4Lf}gWp9dR=@Z^)2;d-9604An?7U4^zOHu-y$2d#C+DDwdwt6vZ)P1r zEmnfv)gMQ5Fez$I`O{_|`eoD#e|h-ho*m}aBCqU7kaYS2=ESiXipbeV2!9|DF0+)m zvFag{YuNeyhwZn-;5^V zSd2{0Oy(}~yTCmQzWXEMFy`G#&V>ypu4f&XDvubOHzbVle1bo;(7-=3fvAS1hB{r{ zK9-O65t+fFL#0b~r6L-?q<5=RcKTM}V$WkcEkv5iL&ukW?jO^a^rU=0Cen1H^wqC0 z{sv?taDA@di!}>PKt}4{dQt=zaJRlDSS3%YCQij$@El(EeS)@&@lx_+=r1t|Q3>2v zCDdxkooWqzrf(+dORYXyBnry^vm>wyd0hE~6T;p-9~f0^4m~AUeAv={cet7m*{2|~6vVAM=vpL?8r|>+7ZfuT;*FKMLJGNyc z)!M?FJlzd>mzyrCJi3SQM$eUS@xCJioofaUwqrzeQ%S|R`Aa6u$h3~pn3ge8H;U0% z+Z~w$tX*TF3?Bia(5OK1--uI#gzJ;b5uLoH{ZFw&E0w}REn0XA!4#HLjdvE}GHCBT zMj7g$9;PwAHTUKI5ZL0?jTRutws}W@-^ZQvY+I`RRUq^H(;hro2sF&qX0$Sn8yjq1 zS-XgbgdmyQukGKXhM9c#5rJ(q^!e2^A|dvfiB5oGPSLeAt5%D5*PeG3-*&*guZuuC zJBU$e7TQYCv=P5Uu*IQUHW?0y%33xDZpbd98PO};2E)HxOQVOU|UymxHgZ9B@5W$*}2MWJa*c^h+fpc9wwZ5c?$46XDvb@ z2}v~Q+LI9-eS9J4lf0KKW+gGo70QNXC1;t@eC1Od3WRDxuCWR+h{JeQTln@;u^A#0Ge4Qp1=`> zt(XIo8r+4#xfGhRFBQT(lgt$%8A30KhUoG{+ik~fuoeR8Ud~f*o zN#9})#5rW_+dgG!l}{1c%z{6AH(Tvg3|h;u2D`;{o73i$bqh7Iop3+H*fcNREDYT_ zV_$JL|Eylt9GKs|rOxX5$xtGCZEeAQKH}yQj-e(UJp}D!_2yJ@gWOA&MM>%1!demF z{DzSMQm{L!n=px(sn{+@2(U%8ziqH>-40JBY~3gL*LpzOteyy^!}jjLw(L1_o}Uk# zkKOf^Zc3kM+N-motfgs9@a}WnlbNk!W-goXTetqGjXAXc z$y3qKU$bLO7v=B~DBGp6MY8{jqh`(d-;*ilDsa5kLsG3nql?h0gTJ>LMhtReWbRU)S)mI$^JHKjp#>5BrWm#uS z&6^i@GHwk&nGLSz%FztTWa8``W>tAC{;-Vadc3icr+*5Tpg1 zb4{+jDC;o(mNXIT&m#g)lCPKSRP?zt$jhdxu=L}y*CL>gNCS=sCl`j~I9IwR0hkQC zNk0%Mc)XPszHT|{`-Hp9ZCH;eb4c<7?i;#qszYtx_-^5xDYJR3FZ*l<8yA}Xb}g`% zQvia(gm>;D3o7NQ-GgipuW{}`$MPFUGAzrbx{1i|?cuMGeLCu){I)gxeT2lY%p5>f$g;-r^p8fOaa7MlL zOB$w}<1+naU2bU$qq8(UphBVS{il1Y%H%Ot66gsPl;7oMV}Eif_WZ)$l#gYl_f z`!9^`Ih-`#inT$_!|E=KMw|AP$5OZan1c}{81&!%*f?-6`OBAih;H|eKf;SD7SvYJ zzI!=qL9#@V=6^Ed&Vox>nvRgDbxB_G?scQ-4ZOdqdj8RP9skm?jMwcFwCnt`DMh#3 zPx|w1K!Ml)Gcv<|7Q?Lj&cj$OXm*u%PCL^ivl`om5G&#SR#@4=SD~LX(^Jcxbdhw)5wf$X(QCS-?EVV-)KgU*f@rc_QJ!#&y zOnFUrTYr6Mk}Z@%Qbo3$IlJ$M@?-X_S_aKG-u<$&rk995uEm5|lZ&I?TEYt9$7B^P zh2HP!B7$3DdD#;0C|DAv-v(3*Q|JpR9rtw@KlcjR z0u>+jpcaF#*%yK3>on*QPT$n!hVmV?3Ts*6GgSv4WmL`R|5df<*oLdRtm2wssW!KC zANH}}tLuVDmi`i0E&R1Fka^c(-X?U*iL8Ni3u&xU@Cju*t3?-7mMgv#d@i~fK9iXzdGFDTymtyi!gn^Fzx1BNJP&lM zUsmCM#g|#v+_f=Bwx2VIz0a!?{k_u&wdY!H)n;5Filb}BC~Dd zleclQdsliFY_`v=OWBaLQw%{>Irf^2qsPwfC@p5@P%HZ<(=Xl}n2EvcWSC?(i?OY1 zvC~5z*DPj7bacJde*UiO7_88zd&53d@@}-WtQqfPE7fZ3pqKF*Fq#f{D`xfrsa@wU z<*UY85uCMZSrwZ8)Zjhj&4|Xa6JbcI39UBcTjM8SJm_RGI+SF6%`K{6%jaGz3>bn} z+_X**pz=y>rP<-ElPQyC5s&80wYvX>jrC9)DWiw(CWwmOALHdL;J%ZxDSOP~B6*A^ zvA9^=p}pk1%Hw;g2LAW=HZgN5 z)~zf0COD0!sIf(4tefY|r#UNQ3*Ed-xx_2&1=P{a1GYu(heIonxLsE;4z5%~5PV+G zn75(GucB<9ey_JzfqTF@|E^G{2lv&{W8A+uCNx8}!;{`fXXNVUWdk>vQT)x8#S=20 zxtV0no%fhw&@#V3{rh`fUu(DC;I3ADmQ?4kRO|GN3w_z?IEURYnw8c~?CjFGP#-#o z6gxi=DS(5ZOw^TRNj*Ya+u14%%PLH@XN&L{9qlq7QswNCL;D{qRJt{qk!YsZZMQQ& zpL9?2Be@!`V@xFODnG)ykGOt$GdusL$~Beo#G*t!R!z>WA%1S}UVPj`)8)QQEp)R? zNRlD9@_AzW1FNeC<#_Rnxwu`2rChms6a8n8-s5H)8!6wf;y=ezsBCb@2=?%+ZjD~>TkD?9{hd{mviZq&e@@syMi~U zd&=3NKjgbW%mK=%vv}3C|XwTn{657 zbb~Af2pBjxh4)hb_DyqU?}{vGa$0wA*G2sYHC$?DOmM^-6W#0b4l|R-yYDFkj_7%~ z4GR*+&k3YxnbR@Lwhi2Y$1K&)$0tR&(no+~FJ}E%z!Lfj33|sT#!5-MsBQ|fpxRI7c%fg$8dcKMWe0Kl% z5&ro-HQiOeU6N*GaPWJz@Xp;^$)vl2N`-Y+6Y>aJpuz5qRzjJ6dWpvbc+4+Vzlz!+ zMa$YdGf{^1e)cq$COm-0*!-aHVF}nYbz{GW)v>Gr)~Kp70Mb8(Y(ZihSi|qF5 z089q9BJI!Buu9C!yR2*Y2q4kcM{t?tq@|G|_%<@ea>STGXz2%?AASW~uXEq{Br=wk z;iYtbm+uz4>eazwD!eYWHz5TL$FioIQmm#<0q=S&yGv%>(jRr+j0xVP4fwW~TW!&C zW;FK}vhuHx>NIf;<_bI%=cHBC$gQaA$55KdxcRQYC}{A?n*LFZVSxOh>9RMUq!p+1 z3b+o2kA(^lme;OnzCpiD>d8gsM4FWk<_TASAE>{y?UnzI-kfutXG!&%xG*OQYE5*F zKRZ&$x^-pS>w0-i6XiYyMz`?ph1BT6l;^LoTMlfY1M1dsU~3NdWv|JT*W!B*rE?zN zL$=&u)^hz_W=Q*Hu=D)oB7Utxr|bE&BI={s8ij4!u?rlcer>!d<3W$RcL9~X;OWqh zSOiRkO`m12Srj~HGB&B)ExJ7|u50z<(mvj`L@%c-=D=^^l(TR?pzXQK52^Y;==qY< zbRwd8@ak?QQX2^_l?sygrJC<#-Opg|dNb$inQC298xt1{gp4!Wo&@1F_^@xEwSV(I0PKsI}kIF$b$=b-aygh z_b$B~T;22GMW4NvE`H-P(UguY{5O4^L-@Y)A^35c5x&<@_XlVuj^_#=jcOblZG9 zdFXYD{dweuA(en;gvv?Zj!k?tAC0ob&U7=9LnCI(7O$!wjHZbdX?2R^6+HWEZ%V9% zo*v1!(M=0%3%Va$Tnb&|yXAO!r=M81O3%#UKV2`L?dh#%H&0!C9C)}_jHl$DG`ufC zGqzclc(&4Bj`#B)7r?LJDesZEAF2vUhtdD~;y3HR z2K}eo-2b>8-t@0;kN*oyG18C= 16.0.0", + "appVersionSource": "remote" + }, + "build": { + "development": { + "developmentClient": true, + "distribution": "internal", + "android": { + "buildType": "apk" + } + }, + "preview": { + "distribution": "internal", + "android": { + "buildType": "apk" + } + }, + "production": { + "android": { + "buildType": "app-bundle" + } + } + }, + "submit": { + "production": {} + } +} diff --git a/src/apis/option/notificationApi.ts b/src/apis/option/notificationApi.ts index 2bb06dc..b758792 100644 --- a/src/apis/option/notificationApi.ts +++ b/src/apis/option/notificationApi.ts @@ -1,4 +1,4 @@ -import api from "@/apis/instance"; +import api from "@/apis/instance"; import type { ApiResponse, NoResponse } from "@/types/common/apiResponse.type"; export type NotificationSettings = { @@ -22,3 +22,8 @@ export const postFcmToken = async (token: string): ApiResponse => { const res = await api.post("/api/v1/notifications/token", { token }); return res.data; }; + +export const deleteFcmToken = async (): ApiResponse => { + const res = await api.delete("/api/v1/notifications/token"); + return res.data; +}; diff --git a/src/assets/images/char.webp b/src/assets/images/char-emotion.webp similarity index 100% rename from src/assets/images/char.webp rename to src/assets/images/char-emotion.webp diff --git a/src/assets/images/char2.webp b/src/assets/images/char-stage.webp similarity index 100% rename from src/assets/images/char2.webp rename to src/assets/images/char-stage.webp diff --git a/src/assets/images/flower.png b/src/assets/images/flower.png new file mode 100644 index 0000000000000000000000000000000000000000..da6a7d9dc0535d09504341e3d50120845e4c7ba9 GIT binary patch literal 26879 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

YaI&sHb?=+5x)YpscjiPBABnXo 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 literal 0 HcmV?d00001 diff --git a/src/assets/images/fruit.png b/src/assets/images/fruit.png new file mode 100644 index 0000000000000000000000000000000000000000..c68ff5523f5532e55b7a95dd43d9555c41208498 GIT binary patch literal 30095 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 literal 0 HcmV?d00001 diff --git a/src/assets/images/tree.png b/src/assets/images/tree.png new file mode 100644 index 0000000000000000000000000000000000000000..5c39e32ca5459ba1c697312f45265f624fb51a44 GIT binary patch literal 26153 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 E0}ON!J^%m! literal 0 HcmV?d00001 diff --git a/src/components/common/ScreenHeader.tsx b/src/components/common/ScreenHeader.tsx index 0fd9b87..1516201 100644 --- a/src/components/common/ScreenHeader.tsx +++ b/src/components/common/ScreenHeader.tsx @@ -1,7 +1,8 @@ -import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; -import { RefreshIcon } from "@/assets/icons/CommonIcons"; +import { Image, StyleSheet, Text, TouchableOpacity, View } from "react-native"; import LeftIcon from "@/assets/icons/common/left.svg"; +const refreshIcon = require("../../../assets/refresh-icon.png"); + type Props = { title: string; onBack?: () => void; @@ -23,11 +24,7 @@ export default function ScreenHeader({ return ( {onBack ? ( - + ) : ( @@ -46,7 +43,11 @@ export default function ScreenHeader({ accessibilityLabel={resolvedRightLabel} > {isRefreshAction ? ( - + ) : ( {resolvedRightLabel} @@ -77,6 +78,13 @@ const styles = StyleSheet.create({ justifyContent: "center", alignItems: "center", }, + refreshIcon: { + width: 22, + height: 22, + }, + refreshIconDisabled: { + opacity: 0.4, + }, completeText: { fontSize: 16, fontWeight: "400", diff --git a/src/components/common/Splash.tsx b/src/components/common/Splash.tsx index b20d6c4..b0f765d 100644 --- a/src/components/common/Splash.tsx +++ b/src/components/common/Splash.tsx @@ -1,4 +1,4 @@ -import { View, Text, ImageBackground, Image, StyleSheet } from "react-native"; +import { View, Text, ImageBackground, Image, StyleSheet } from "react-native"; const SplashBg = require("@/assets/images/onboarding/splash.png"); const Character = require("@/assets/images/char.png"); diff --git a/src/components/feed/FeedDetail.tsx b/src/components/feed/FeedDetail.tsx index c52feb5..7055545 100644 --- a/src/components/feed/FeedDetail.tsx +++ b/src/components/feed/FeedDetail.tsx @@ -275,7 +275,7 @@ export default function FeedDetail({ )} @@ -298,7 +298,7 @@ export default function FeedDetail({ {result.content} @@ -396,6 +396,8 @@ const styles = StyleSheet.create({ borderRadius: 16, backgroundColor: "#E5E7EB", overflow: "hidden", + alignItems: "center", + justifyContent: "center", }, profileImage: { width: "100%", @@ -427,12 +429,14 @@ const styles = StyleSheet.create({ aspectRatio: 1, borderRadius: 12, marginBottom: 24, + backgroundColor: "#F3F4F6", }, content: { fontSize: 14, color: "#171717", lineHeight: 20, marginBottom: 24, + backgroundColor: "#F3F4F6", }, actionBar: { flexDirection: "row", @@ -477,6 +481,8 @@ const styles = StyleSheet.create({ flex: 1, backgroundColor: "#FFFFFF", overflow: "hidden", + alignItems: "center", + justifyContent: "center", }, sheetHandle: { width: 44, @@ -515,3 +521,4 @@ const styles = StyleSheet.create({ backgroundColor: "#FFFFFF", }, }); + diff --git a/src/components/feed/FeedList.tsx b/src/components/feed/FeedList.tsx index 451dac7..e500a11 100644 --- a/src/components/feed/FeedList.tsx +++ b/src/components/feed/FeedList.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React from "react"; import { View, Text, @@ -70,7 +70,7 @@ export default function FeedList({ ); @@ -122,9 +122,12 @@ const styles = StyleSheet.create({ width: ITEM_SIZE, height: ITEM_SIZE, backgroundColor: "#F3F4F6", + padding: 6, }, image: { width: "100%", height: "100%", + borderRadius: 8, }, }); + diff --git a/src/components/home/HomeAlertsModal.tsx b/src/components/home/HomeAlertsModal.tsx index e1e09a9..4952535 100644 --- a/src/components/home/HomeAlertsModal.tsx +++ b/src/components/home/HomeAlertsModal.tsx @@ -1,5 +1,6 @@ -import { useEffect, useMemo, useRef, useState } from "react"; +import { useEffect, useMemo, useRef, useState } from "react"; import { + Image, Modal, Pressable, ScrollView, @@ -12,6 +13,8 @@ import { useGuestbookList, useNotifications, useReadNotifications } from "@/hook import type { GuestbookEntry, NotificationItem } from "@/types/home/alerts"; import { createTimingLogger } from "@/utils/debug"; +const birdImage = require("@/assets/images/bird.webp"); + function isNotificationRead(item: NotificationItem) { return item.isRead ?? item.read ?? false; } @@ -120,70 +123,74 @@ export default function HomeAlertsModal({ - - - - 받은 소식 - - 닫기 - - + + - - setActiveTab("GUESTBOOK")} - /> - setActiveTab("RECORD")} - /> - + + + + 받은 소식 + + 닫기 + + - - {activeState.isLoading ? ( - 불러오는 중입니다. - ) : activeState.isError ? ( - - {activeTab === "GUESTBOOK" - ? "받은 방명록을 불러오지 못했습니다." - : "알림을 불러오지 못했습니다."} - - ) : activeState.items.length === 0 ? ( - - {activeTab === "GUESTBOOK" - ? "아직 받은 방명록이 없어요." - : "아직 기록이 없어요."} - - ) : activeTab === "GUESTBOOK" ? ( - (activeState.items as GuestbookEntry[]).map((item, index) => ( - - - {item.author} - {formatDateTime(item.createdAt)} + + setActiveTab("GUESTBOOK")} + /> + setActiveTab("RECORD")} + /> + + + + {activeState.isLoading ? ( + 불러오는 중입니다. + ) : activeState.isError ? ( + + {activeTab === "GUESTBOOK" + ? "받은 방명록을 불러오지 못했습니다." + : "알림을 불러오지 못했습니다."} + + ) : activeState.items.length === 0 ? ( + + {activeTab === "GUESTBOOK" + ? "아직 받은 방명록이 없어요." + : "아직 기록이 없어요."} + + ) : activeTab === "GUESTBOOK" ? ( + (activeState.items as GuestbookEntry[]).map((item, index) => ( + + + {item.author} + {formatDateTime(item.createdAt)} + + {item.content} - {item.content} - - )) - ) : ( - (activeState.items as NotificationItem[]).map(item => ( - - - {getNotificationLabel(item.notificationType)} - {formatDateTime(item.createdAt)} + )) + ) : ( + (activeState.items as NotificationItem[]).map(item => ( + + + {getNotificationLabel(item.notificationType)} + {formatDateTime(item.createdAt)} + + {item.content} + {!isNotificationRead(item) ? : null} - {item.content} - {!isNotificationRead(item) ? : null} - - )) - )} - + )) + )} + + @@ -246,21 +253,37 @@ const styles = StyleSheet.create({ justifyContent: "center", padding: 24, }, - card: { + cardFrame: { width: "100%", maxWidth: 360, maxHeight: "80%", + position: "relative", + overflow: "visible", + }, + card: { + width: "100%", + maxHeight: "100%", borderRadius: 28, backgroundColor: "#FFFFFF", paddingHorizontal: 20, paddingTop: 22, paddingBottom: 18, + overflow: "hidden", + }, + decorativeBird: { + position: "absolute", + top: -34, + left: 8, + width: 58, + height: 58, + zIndex: 3, }, header: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", marginBottom: 12, + zIndex: 1, }, headerSpacer: { width: 44, @@ -283,6 +306,7 @@ const styles = StyleSheet.create({ flexDirection: "row", gap: 10, marginBottom: 14, + zIndex: 1, }, tabButton: { flex: 1, diff --git a/src/components/home/HomeAvatarStage.tsx b/src/components/home/HomeAvatarStage.tsx index 13760da..25df044 100644 --- a/src/components/home/HomeAvatarStage.tsx +++ b/src/components/home/HomeAvatarStage.tsx @@ -1,4 +1,4 @@ -import { Image, Pressable, StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import { Image, Pressable, StyleSheet, Text, TouchableOpacity, View } from "react-native"; import { useEffect, useState } from "react"; import { ANSWER_COPY } from "@/components/home/HomeEmotionModal"; @@ -6,7 +6,7 @@ import type { SurveyAnswerKind } from "@/types/missions"; const wateringImage = require("@/assets/images/background/watering.png"); const birdImage = require("@/assets/images/bird.webp"); -const characterImage = require("@/assets/images/char2.webp"); +const characterImage = require("@/assets/images/char-stage.webp"); const plantFallback = require("@/assets/images/plant.png"); export default function HomeAvatarStage({ @@ -118,22 +118,10 @@ const styles = StyleSheet.create({ avatarImage: { width: 320, height: 320, - - /* - * 한글 주석: - * 화분 밑단을 더 아래로 내리기 위해 하단 여백을 줄였다. - * 주변 오브젝트도 같은 기준선에서 함께 내려오도록 절대 위치 값도 맞춘다. - */ marginBottom: -96, }, wateringImage: { position: "absolute", - - /* - * 한글 주석: - * 물뿌리개와 물방울 연출은 식물 중앙이 아니라 - * 식물의 왼쪽 70% 높이 부근에서 시작하도록 고정 위치를 옮긴다. - */ left: "18%", bottom: 168, width: 118, @@ -204,13 +192,13 @@ const styles = StyleSheet.create({ marginTop: -10, }, characterImage: { - width: 82, - height: 82, + width: 120, + height: 120, }, birdButton: { position: "absolute", - right: 48, - bottom: 18, + right: 56, + bottom: 0, }, notificationBadge: { position: "absolute", diff --git a/src/components/home/HomeEmotionModal.tsx b/src/components/home/HomeEmotionModal.tsx index c363c92..0a7f4d3 100644 --- a/src/components/home/HomeEmotionModal.tsx +++ b/src/components/home/HomeEmotionModal.tsx @@ -17,7 +17,7 @@ import { } from "@/types/missions"; import { createTimingLogger, debugLog } from "@/utils/debug"; -const characterImage = require("@/assets/images/char.webp"); +const characterImage = require("@/assets/images/char-emotion.webp"); const ANSWER_COPY: Record = { YES: "좋은 기분으로 오늘 하루 계속 이어가요!", @@ -72,10 +72,6 @@ export default function HomeEmotionModal({ answer: SURVEY_ANSWER_VALUE_MAP[answer], }); - /* - * Close the modal as soon as submit succeeds. - * Home state is updated immediately and query refresh continues in the background. - */ onAnswered(answer); onClose(); finishSubmitTiming({ closedImmediately: true }); @@ -226,5 +222,3 @@ const styles = StyleSheet.create({ textAlign: "center", }, }); - - diff --git a/src/components/home/HomeGardenScene.tsx b/src/components/home/HomeGardenScene.tsx index 12ff849..574036f 100644 --- a/src/components/home/HomeGardenScene.tsx +++ b/src/components/home/HomeGardenScene.tsx @@ -28,7 +28,8 @@ const mapIcon = require("@/assets/images/map.png"); const emptyGardenImage = require("@/assets/images/null.webp"); const sunlightOverlay = require("@/assets/images/background/sunlight.png"); -const SCENE_BOTTOM_OFFSET = -16; +const SCENE_BOTTOM_OFFSET = 56; +const EMPTY_SCENE_BOTTOM_OFFSET = 124; const ACTION_RAIL_BOTTOM_OFFSET = 128; const WATER_ACTION_COOLDOWN_MS = 700; @@ -194,12 +195,12 @@ export default function HomeGardenScene({ style={styles.lockStatusIcon} /> - {isUnlockable ? "\uC9C0\uAE08 \uC5F4 \uC218 \uC788\uC5B4\uC694" : "\uD574\uAE08\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4"} + {isUnlockable ? "지금 열 수 있어요" : "해금되지 않았습니다"} {isUnlockable - ? "\uC528\uC557\uC744 \uBC1B\uC544 \uC0C8\uB85C\uC6B4 \uD143\uBC2D\uC744 \uC5F4 \uC218 \uC788\uC5B4\uC694." - : "\uC18C\uB9DD \uB098\uBB34\uAC00 \uCDA9\uBD84\uD788 \uC790\uB77C\uBA74 \uC0C8\uB85C\uC6B4 \uD143\uBC2D\uC744 \uC5F4 \uC218 \uC788\uC5B4\uC694."} + ? "씨앗을 받아 새로운 텃밭을 열 수 있어요." + : "소망 나무가 충분히 자라면 새로운 텃밭을 열 수 있어요."} @@ -218,7 +219,7 @@ export default function HomeGardenScene({ ) : ( - + {hasAvatar ? ( - - 새로운 식물을{"\n"}심어볼까요? - + + + + 새로운 식물을{"\n"}심어볼까요? + + + + @@ -335,14 +339,12 @@ const styles = StyleSheet.create({ justifyContent: "center", alignItems: "center", paddingHorizontal: 24, - - /* - * 한글 주석: - * 화분과 주변 오브젝트를 화면 하단 쪽으로 더 내리되, - * 접힌 패널에 가려지지 않도록 최소 여백을 남긴 위치로 고정한다. - */ paddingBottom: SCENE_BOTTOM_OFFSET, }, + emptySceneBody: { + justifyContent: "flex-end", + paddingBottom: EMPTY_SCENE_BOTTOM_OFFSET, + }, lockedSceneBody: { flex: 1, justifyContent: "space-between", @@ -415,16 +417,26 @@ const styles = StyleSheet.create({ width: "100%", alignItems: "center", justifyContent: "center", - paddingBottom: 12, + }, + emptyBubbleWrap: { + alignItems: "center", + marginBottom: -64, }, emptyBubble: { - marginBottom: 12, borderRadius: 24, backgroundColor: "rgba(255,255,255,0.95)", paddingHorizontal: 26, paddingVertical: 16, alignItems: "center", }, + emptyBubbleTail: { + width: 18, + height: 18, + marginTop: -9, + backgroundColor: "rgba(255,255,255,0.95)", + transform: [{ rotate: "45deg" }], + borderBottomRightRadius: 4, + }, emptyBubbleText: { fontSize: 15, lineHeight: 22, @@ -439,9 +451,7 @@ const styles = StyleSheet.create({ fontWeight: "700", }, emptyGardenImage: { - width: 300, - height: 240, + width: 360, + height: 288, }, }); - - diff --git a/src/components/home/WishTreeInfoModal.tsx b/src/components/home/WishTreeInfoModal.tsx index 7a12644..4d01900 100644 --- a/src/components/home/WishTreeInfoModal.tsx +++ b/src/components/home/WishTreeInfoModal.tsx @@ -1,4 +1,5 @@ -import { +import { + Image, Modal, Pressable, ScrollView, @@ -7,11 +8,16 @@ import { View, } from "react-native"; -function StageIcon({ label }: { label: string }) { +const sproutImage = require("@/assets/images/sprout.png"); +const flowerImage = require("@/assets/images/flower.png"); +const fruitImage = require("@/assets/images/fruit.png"); +const treeImage = require("@/assets/images/tree.png"); + +function StageIcon({ label, source }: { label: string; source: number }) { return ( - - {label[0]} + + {label} @@ -49,13 +55,13 @@ export default function WishTreeInfoModal({ visible, onClose }: Props) { - + - + - + - + @@ -126,18 +132,15 @@ const styles = StyleSheet.create({ alignItems: "center", gap: 8, }, - stageIconPlaceholder: { + stageIconFrame: { width: 52, height: 52, - borderRadius: 26, - backgroundColor: "#F0F4EC", alignItems: "center", justifyContent: "center", }, - stageIconText: { - fontSize: 20, - color: "#4CAF50", - fontWeight: "700", + stageIconImage: { + width: 52, + height: 52, }, stageLabel: { fontSize: 13, @@ -169,3 +172,5 @@ const styles = StyleSheet.create({ color: "#6B7280", }, }); + + diff --git a/src/hooks/option/useNotificationApi.ts b/src/hooks/option/useNotificationApi.ts index 3deffdf..c27e01d 100644 --- a/src/hooks/option/useNotificationApi.ts +++ b/src/hooks/option/useNotificationApi.ts @@ -1,7 +1,9 @@ -import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { + deleteFcmToken, getNotificationSettings, patchNotificationSettings, + postFcmToken, type NotificationSettings, } from "@/apis/option/notificationApi"; import type { GlobalResponse } from "@/types/common/apiResponse.type"; @@ -37,3 +39,13 @@ export const useUpdateNotificationSettings = () => { }, }); }; + +export const useRegisterNotificationToken = () => + useMutation({ + mutationFn: postFcmToken, + }); + +export const useDeleteNotificationToken = () => + useMutation({ + mutationFn: deleteFcmToken, + }); diff --git a/src/pages/feed/FeedScreen.tsx b/src/pages/feed/FeedScreen.tsx index ddb22a4..0d6c9c5 100644 --- a/src/pages/feed/FeedScreen.tsx +++ b/src/pages/feed/FeedScreen.tsx @@ -1,28 +1,27 @@ -import React, { useState, useCallback } from "react"; +import React, { useCallback } from "react"; import { RefreshControl, View, Text, TouchableOpacity, ScrollView, - ActivityIndicator, StyleSheet, + Image, } from "react-native"; - -const FEED_PAGE_SIZE = 10; import { SafeAreaView } from "react-native-safe-area-context"; import type { MainTabScreenProps } from "@/navigation/types"; -import { RefreshIcon, UserPlusIcon } from "@/assets/icons/CommonIcons"; +import { UserPlusIcon } from "@/assets/icons/CommonIcons"; import StatusView from "@/components/common/StatusView"; import FeedList from "@/components/feed/FeedList"; import { useFeed } from "@/hooks/feed/useFeedApi"; +const refreshIcon = require("../../../assets/refresh-icon.png"); + type Props = MainTabScreenProps<"Feed">; export default function FeedScreen({ navigation }: Props) { const { data: result, isLoading, isRefetching, error, refetch } = useFeed(); - const [displayCount, setDisplayCount] = useState(FEED_PAGE_SIZE); const handleUserPlusClick = () => { navigation.navigate("Follow"); @@ -37,24 +36,10 @@ export default function FeedScreen({ navigation }: Props) { }; const handleRefetch = useCallback(() => { - setDisplayCount(FEED_PAGE_SIZE); void refetch(); }, [refetch]); - const handleScroll = useCallback( - ({ nativeEvent }: { nativeEvent: { layoutMeasurement: { height: number }; contentOffset: { y: number }; contentSize: { height: number } } }) => { - const { layoutMeasurement, contentOffset, contentSize } = nativeEvent; - const isNearBottom = layoutMeasurement.height + contentOffset.y >= contentSize.height - 200; - if (isNearBottom && displayCount < (result?.length ?? 0)) { - setDisplayCount(prev => Math.min(prev + FEED_PAGE_SIZE, result?.length ?? prev)); - } - }, - [displayCount, result?.length] - ); - - const allData = result && result.length > 0 ? result : []; - const dataForRender = allData.slice(0, displayCount); - const hasMore = displayCount < allData.length; + const dataForRender = result && result.length > 0 ? result : []; return ( @@ -67,7 +52,11 @@ export default function FeedScreen({ navigation }: Props) { accessibilityRole="button" accessibilityLabel="새로고침" > - + 둘러보기 - {hasMore && ( - - - - )} )} @@ -142,6 +124,13 @@ const styles = StyleSheet.create({ alignItems: "center", justifyContent: "center", }, + refreshIcon: { + width: 22, + height: 22, + }, + refreshIconDisabled: { + opacity: 0.4, + }, headerButton: { width: 24, alignItems: "center", @@ -149,8 +138,4 @@ const styles = StyleSheet.create({ scrollView: { flex: 1, }, - loadMoreIndicator: { - paddingVertical: 16, - alignItems: "center", - }, }); diff --git a/src/pages/option/OptionScreen.tsx b/src/pages/option/OptionScreen.tsx index 8911d0a..dea2198 100644 --- a/src/pages/option/OptionScreen.tsx +++ b/src/pages/option/OptionScreen.tsx @@ -1,4 +1,4 @@ -import { useState, type ReactNode } from "react"; +import { useState, type ReactNode } from "react"; import { Alert, ScrollView, StyleSheet, Text, TouchableOpacity, View } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; import type { MainTabScreenProps } from "@/navigation/types"; @@ -8,9 +8,10 @@ import { ToggleOnIcon, } from "@/assets/icons/CommonIcons"; import ScreenHeader from "@/components/common/ScreenHeader"; +import { useNotificationSettings, useUpdateNotificationSettings } from "@/hooks/option/useNotificationApi"; import useTokenStore from "@/stores/useTokenStore"; import { logout } from "@/utils/auth"; -import { useNotificationSettings, useUpdateNotificationSettings } from "@/hooks/option/useNotificationApi"; +import { registerDeviceFcmToken, unregisterDeviceFcmToken } from "@/utils/fcm"; type Props = MainTabScreenProps<"Option">; @@ -20,6 +21,39 @@ export default function OptionScreen({ navigation }: Props) { const { data: notificationSettings } = useNotificationSettings(); const updateSettingsMutation = useUpdateNotificationSettings(); const pushNotification = notificationSettings?.notificationEnabled ?? true; + const marketingConsent = notificationSettings?.marketingConsent ?? false; + + const handleTogglePushNotification = async () => { + if (updateSettingsMutation.isPending) { + return; + } + + if (!pushNotification) { + const registered = await registerDeviceFcmToken(); + if (!registered) { + Alert.alert("알림 권한 필요", "기기 알림 권한을 허용한 뒤 다시 시도해주세요."); + return; + } + } else { + const removed = await unregisterDeviceFcmToken(); + if (!removed) { + Alert.alert("알림 설정 변경 실패", "토큰 해제에 실패했습니다. 잠시 후 다시 시도해주세요."); + return; + } + } + + updateSettingsMutation.mutate( + { + notificationEnabled: !pushNotification, + marketingConsent, + }, + { + onError: () => { + Alert.alert("알림 설정 변경 실패", "잠시 후 다시 시도해주세요."); + }, + } + ); + }; const handleLogout = () => { if (isLoggingOut || !accessToken) { @@ -45,14 +79,11 @@ export default function OptionScreen({ navigation }: Props) { - {/* Settings are rendered as a simple list so FE-style rows can expand without changing layout structure. */} - updateSettingsMutation.mutate({ notificationEnabled: !pushNotification }) - } + onPress={() => void handleTogglePushNotification()} activeOpacity={0.7} disabled={updateSettingsMutation.isPending} accessibilityRole="switch" @@ -96,7 +127,6 @@ function OptionRow({ onPress?: () => void; }) { const content = ( - // A shared row component keeps label-only, toggle, and action rows visually consistent. {content} diff --git a/src/pages/registration/RegistrationPlantNicknameScreen.tsx b/src/pages/registration/RegistrationPlantNicknameScreen.tsx index 7619195..f69a66f 100644 --- a/src/pages/registration/RegistrationPlantNicknameScreen.tsx +++ b/src/pages/registration/RegistrationPlantNicknameScreen.tsx @@ -80,7 +80,7 @@ export default function RegistrationPlantNicknameScreen({ navigation }: Props) { {previewImageUrl ? ( - + ) : null} @@ -163,8 +163,8 @@ const styles = StyleSheet.create({ justifyContent: "center", }, previewImage: { - width: 220, - height: 261, + width: 234, + height: 268, }, inputWrap: { width: 353, @@ -229,3 +229,4 @@ const styles = StyleSheet.create({ color: "#BFBFBF", }, }); + diff --git a/src/pages/registration/RegistrationSelectionDetailScreen.tsx b/src/pages/registration/RegistrationSelectionDetailScreen.tsx index 5ae8045..ba150a8 100644 --- a/src/pages/registration/RegistrationSelectionDetailScreen.tsx +++ b/src/pages/registration/RegistrationSelectionDetailScreen.tsx @@ -1,33 +1,127 @@ -import { useEffect } from "react"; +import { useEffect, useMemo, useRef, useState } from "react"; import { + Animated, + Dimensions, + Image, + NativeScrollEvent, + NativeSyntheticEvent, ScrollView, StyleSheet, Text, + TouchableOpacity, View, } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; + import ScreenHeader from "@/components/common/ScreenHeader"; import StatusView from "@/components/common/StatusView"; -import RegistrationFooter from "@/components/registration/RegistrationFooter"; -import SelectionAvatarCard from "@/components/registration/SelectionAvatarCard"; import { useAvatarMasters } from "@/hooks/avatars/useAvatarApi"; import type { RootStackScreenProps } from "@/navigation/types"; import useRegistrationStore from "@/stores/useRegistrationStore"; type Props = RootStackScreenProps<"RegistrationSelectionDetail">; +type PaginationDotTone = "active" | "default" | "edge" | "hidden"; + +const { width: screenWidth } = Dimensions.get("window"); +const CARD_WIDTH = 258; +const CARD_HEIGHT = 292; +const CARD_SPACING = 16; +const SNAP_INTERVAL = CARD_WIDTH + CARD_SPACING; +const SIDE_PADDING = Math.max((screenWidth - CARD_WIDTH) / 2, 20); +const DOT_SIZE = 8; +const DOT_SPACING = 6; + +function buildPaginationSlots(total: number, currentIndex: number): PaginationDotTone[] { + if (total <= 0) { + return ["hidden", "hidden", "hidden"]; + } + + if (total === 1) { + return ["hidden", "active", "hidden"]; + } + + if (total === 2) { + return currentIndex === 0 + ? ["hidden", "active", "default"] + : ["default", "active", "hidden"]; + } + + if (currentIndex === 0) { + return ["hidden", "active", "default"]; + } + + if (currentIndex === total - 1) { + return ["default", "active", "hidden"]; + } + + if (currentIndex === 1) { + return ["default", "active", "edge"]; + } + + if (currentIndex === total - 2) { + return ["edge", "active", "default"]; + } + + return ["edge", "active", "edge"]; +} + +function getDotColor(tone: PaginationDotTone) { + return tone === "active" ? "#7C7C7C" : "#D9D9D9"; +} + +function getDotOpacity(tone: PaginationDotTone) { + if (tone === "active" || tone === "default") { + return 1; + } + + if (tone === "edge") { + return 0.35; + } + + return 0; +} + +function getDotScale(tone: PaginationDotTone) { + if (tone === "active") { + return 1; + } + + if (tone === "default") { + return 0.92; + } + + if (tone === "edge") { + return 0.82; + } + + return 0.4; +} + +function getClampedIndex(total: number, offsetX: number) { + if (total <= 0) { + return 0; + } + + return Math.min(total - 1, Math.max(0, Math.round(offsetX / SNAP_INTERVAL))); +} + export default function RegistrationSelectionDetailScreen({ navigation, route, }: Props) { const entry = route.params?.entry; const { data, isLoading, isError, refetch } = useAvatarMasters(); - const { - selectedMaster, - setMode, - setSelectedMaster, - setSelectedPreview, - } = useRegistrationStore(); + const scrollRef = useRef(null); + const dotOpacity = useRef( + Array.from({ length: 3 }, () => new Animated.Value(0)), + ).current; + const dotScale = useRef( + Array.from({ length: 3 }, () => new Animated.Value(0.4)), + ).current; + const { selectedMaster, setMode, setSelectedMaster, setSelectedPreview } = + useRegistrationStore(); + const [indicatorIndex, setIndicatorIndex] = useState(0); useEffect(() => { if (!selectedMaster && data && data.length > 0) { @@ -37,9 +131,90 @@ export default function RegistrationSelectionDetailScreen({ description: data[0].description, imageUrl: data[0].defaultImageUrl, }); + setIndicatorIndex(0); } }, [data, selectedMaster, setSelectedMaster, setSelectedPreview]); + const selectedIndex = + data && selectedMaster + ? Math.max( + data.findIndex(avatar => avatar.id === selectedMaster.id), + 0, + ) + : 0; + + useEffect(() => { + setIndicatorIndex(selectedIndex); + }, [selectedIndex]); + + const paginationSlots = useMemo( + () => buildPaginationSlots(data?.length ?? 0, indicatorIndex), + [data?.length, indicatorIndex], + ); + + useEffect(() => { + Animated.parallel( + paginationSlots.map((tone, index) => + Animated.parallel([ + Animated.timing(dotOpacity[index], { + toValue: getDotOpacity(tone), + duration: 140, + useNativeDriver: false, + }), + Animated.timing(dotScale[index], { + toValue: getDotScale(tone), + duration: 140, + useNativeDriver: false, + }), + ]), + ), + ).start(); + }, [dotOpacity, dotScale, paginationSlots]); + + const selectAvatarAtIndex = (index: number, shouldScroll = false) => { + if (!data || index < 0 || index >= data.length) { + return; + } + + const avatar = data[index]; + setSelectedMaster(avatar); + setSelectedPreview({ + masterId: avatar.id, + description: avatar.description, + imageUrl: avatar.defaultImageUrl, + }); + setIndicatorIndex(index); + + if (shouldScroll) { + scrollRef.current?.scrollTo({ + x: index * SNAP_INTERVAL, + animated: true, + }); + } + }; + + const handleScroll = (event: NativeSyntheticEvent) => { + const nextIndex = getClampedIndex(data?.length ?? 0, event.nativeEvent.contentOffset.x); + + if (nextIndex !== indicatorIndex) { + setIndicatorIndex(nextIndex); + } + }; + + const handleMomentumScrollEnd = ( + event: NativeSyntheticEvent, + ) => { + if (!data || data.length === 0) { + return; + } + + const nextIndex = getClampedIndex(data.length, event.nativeEvent.contentOffset.x); + + if (data[nextIndex].id !== selectedMaster?.id) { + selectAvatarAtIndex(nextIndex); + } + }; + const goNext = () => { if (!selectedMaster) { return; @@ -56,9 +231,9 @@ export default function RegistrationSelectionDetailScreen({ if (isLoading) { return ( - + navigation.navigate("RegistrationAvatar", { entry })} /> @@ -68,14 +243,13 @@ export default function RegistrationSelectionDetailScreen({ if (isError) { return ( - + navigation.navigate("RegistrationAvatar", { entry })} /> void refetch()} /> @@ -85,51 +259,110 @@ export default function RegistrationSelectionDetailScreen({ if (!data || data.length === 0) { return ( - + navigation.navigate("RegistrationAvatar", { entry })} /> - + ); } return ( - + navigation.navigate("RegistrationAvatar", { entry })} /> - - - 원하는 식물 아바타를 선택해주세요. - - `GET /api/v1/avatars/masters` 응답 기준으로 목록을 보여줍니다. - - - - {data.map(avatar => ( - setSelectedMaster(avatar)} - /> - ))} + + + 원하는 아바타를 선택해주세요 + + + + {data.map((avatar, index) => { + const isSelected = selectedMaster?.id === avatar.id; + + return ( + selectAvatarAtIndex(index, true)} + > + + + + {avatar.description} + + ); + })} + + + + {paginationSlots.map((tone, index) => ( + + + + ))} + - - - navigation.navigate("RegistrationAvatar", { entry })} - primaryLabel="별명 정하러 가기" - onPrimaryPress={goNext} - primaryDisabled={!selectedMaster} - /> + + + + + + 다음 + + + ); } @@ -137,31 +370,112 @@ export default function RegistrationSelectionDetailScreen({ const styles = StyleSheet.create({ safeArea: { flex: 1, - backgroundColor: "#F7F8F4", + backgroundColor: "#FFFFFF", }, content: { - padding: 20, - gap: 18, - }, - headerBlock: { - gap: 8, + flex: 1, }, title: { - fontSize: 24, - lineHeight: 32, - fontWeight: "700", + marginTop: 32, + marginLeft: 25, + fontSize: 20, + lineHeight: 28, + fontWeight: "600", color: "#171717", }, - subtitle: { - fontSize: 14, - lineHeight: 20, - color: "#6B7280", + carouselSection: { + flex: 1, + paddingTop: 84, + position: "relative", + }, + carouselContent: { + paddingHorizontal: SIDE_PADDING, + }, + cardBlock: { + width: CARD_WIDTH, + marginRight: CARD_SPACING, + alignItems: "center", + }, + cardFrame: { + width: CARD_WIDTH, + height: CARD_HEIGHT, + borderRadius: 12, + borderWidth: 2, + borderColor: "#72D14E", + overflow: "hidden", + alignItems: "center", + justifyContent: "center", + }, + cardFrameSelected: { + backgroundColor: "#EEF9EA", + opacity: 1, + }, + cardFrameIdle: { + backgroundColor: "#FFFFFF", + opacity: 0.5, }, - grid: { + cardImage: { + width: CARD_WIDTH - 24, + height: CARD_HEIGHT - 24, + }, + cardImageSelected: { + opacity: 1, + }, + cardImageIdle: { + opacity: 0.92, + }, + cardLabel: { + marginTop: 16, + width: "100%", + paddingHorizontal: 8, + fontSize: 18, + lineHeight: 27, + fontWeight: "600", + color: "#171717", + textAlign: "center", + }, + pagination: { + position: "absolute", + left: 0, + right: 0, + bottom: 180, flexDirection: "row", - flexWrap: "wrap", - justifyContent: "space-between", - rowGap: 12, + alignItems: "center", + justifyContent: "center", + }, + paginationSlot: { + width: DOT_SIZE + DOT_SPACING * 2, + alignItems: "center", + justifyContent: "center", + }, + paginationDot: { + width: DOT_SIZE, + height: DOT_SIZE, + borderRadius: 999, + }, + footer: { + paddingHorizontal: 20, + paddingTop: 12, + paddingBottom: 18, + }, + primaryButton: { + height: 56, + borderRadius: 8, + backgroundColor: "#72D14E", + alignItems: "center", + justifyContent: "center", + }, + primaryButtonDisabled: { + backgroundColor: "#7C7C7C", + }, + primaryButtonLabel: { + fontSize: 18, + lineHeight: 27, + fontWeight: "600", + color: "#FFFFFF", + }, + primaryButtonLabelDisabled: { + color: "#BFBFBF", }, }); diff --git a/src/utils/auth.ts b/src/utils/auth.ts index d0138c0..9542258 100644 --- a/src/utils/auth.ts +++ b/src/utils/auth.ts @@ -1,7 +1,24 @@ -import { supabase } from "@/apis/supabase"; +import { supabase } from "@/apis/supabase"; import useTokenStore from "@/stores/useTokenStore"; export const logout = async () => { + const { accessToken } = useTokenStore.getState(); + + if (accessToken) { + const apiUrl = process.env.EXPO_PUBLIC_API_URL || "https://api.napulnapul.com"; + + try { + await fetch(`${apiUrl}/api/v1/notifications/token`, { + method: "DELETE", + headers: { + Authorization: `Bearer ${accessToken}`, + }, + }); + } catch (error) { + console.error("[auth] Failed to delete notification token during logout:", error); + } + } + useTokenStore.getState().clearTokens(); try { diff --git a/src/utils/fcm.ts b/src/utils/fcm.ts index fb0c6bc..fa1c76f 100644 --- a/src/utils/fcm.ts +++ b/src/utils/fcm.ts @@ -1,47 +1,71 @@ -import * as Notifications from "expo-notifications"; +import * as Notifications from "expo-notifications"; import * as Device from "expo-device"; import { Platform } from "react-native"; -import { postFcmToken } from "@/apis/option/notificationApi"; +import { deleteFcmToken, postFcmToken } from "@/apis/option/notificationApi"; import { debugLog } from "@/utils/debug"; -export const registerDeviceFcmToken = async (): Promise => { - // 실제 기기에서만 동작 (에뮬레이터 건너뜀) +const ensureNotificationPermission = async (): Promise => { if (!Device.isDevice) { - debugLog("FCM", "skipped — not a physical device"); - return; + debugLog("FCM", "skipped - not a physical device"); + return false; } - try { - const { status: existing } = await Notifications.getPermissionsAsync(); - let finalStatus = existing; + const { status: existing } = await Notifications.getPermissionsAsync(); + let finalStatus = existing; - if (existing !== "granted") { - const { status } = await Notifications.requestPermissionsAsync(); - finalStatus = status; - } + if (existing !== "granted") { + const { status } = await Notifications.requestPermissionsAsync(); + finalStatus = status; + } - if (finalStatus !== "granted") { - debugLog("FCM", "notification permission denied"); - return; - } + if (finalStatus !== "granted") { + debugLog("FCM", "notification permission denied"); + return false; + } + + return true; +}; + +const configureAndroidNotificationChannel = async () => { + if (Platform.OS !== "android") { + return; + } + + await Notifications.setNotificationChannelAsync("default", { + name: "나풀나풀", + importance: Notifications.AndroidImportance.MAX, + vibrationPattern: [0, 250, 250, 250], + }); +}; - // Android 알림 채널 설정 - if (Platform.OS === "android") { - await Notifications.setNotificationChannelAsync("default", { - name: "나풀나풀", - importance: Notifications.AndroidImportance.MAX, - vibrationPattern: [0, 250, 250, 250], - }); +export const registerDeviceFcmToken = async (): Promise => { + try { + const hasPermission = await ensureNotificationPermission(); + if (!hasPermission) { + return false; } - // 네이티브 FCM 토큰 획득 (Expo 푸시 토큰이 아닌 실제 FCM 토큰) + await configureAndroidNotificationChannel(); + const { data: token } = await Notifications.getDevicePushTokenAsync(); debugLog("FCM", "device token acquired"); await postFcmToken(token); debugLog("FCM", "token registered with server"); + return true; } catch (error) { - // 토큰 등록 실패는 앱 동작을 막지 않음 debugLog("FCM", "token registration failed", { error }); + return false; + } +}; + +export const unregisterDeviceFcmToken = async (): Promise => { + try { + await deleteFcmToken(); + debugLog("FCM", "token removed from server"); + return true; + } catch (error) { + debugLog("FCM", "token removal failed", { error }); + return false; } }; From d7da3e5b8822ec2f1eff344e0a1fdbc9c05eb867 Mon Sep 17 00:00:00 2001 From: lejuho Date: Mon, 30 Mar 2026 22:57:06 +0900 Subject: [PATCH 87/92] =?UTF-8?q?chore=20:=20=ED=81=AC=EA=B8=B0=20?= =?UTF-8?q?=EB=B0=8F=20=EA=B0=84=EA=B2=A9=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/ConfirmModal.tsx | 133 +++++++ .../dailyMission/OxQuizOptionCard.tsx | 30 +- .../dailyMission/QuizOptionCard.tsx | 82 ++-- src/components/feed/FeedDetail.tsx | 179 ++++----- src/components/home/HomeBottomSheet.tsx | 352 ++++++++---------- src/components/home/HomeGardenScene.tsx | 73 ++-- .../DailyMissionQuizMultipleChoiceScreen.tsx | 186 +++++---- .../dailyMission/DailyMissionQuizOxScreen.tsx | 78 ++-- src/pages/follow/FollowScreen.tsx | 47 +-- src/pages/home/HomeScreen.tsx | 35 +- src/pages/option/OptionScreen.tsx | 35 +- src/pages/option/ServiceGuideScreen.tsx | 43 +-- src/pages/profile/ProfileScreen.tsx | 98 +++-- 13 files changed, 790 insertions(+), 581 deletions(-) create mode 100644 src/components/common/ConfirmModal.tsx diff --git a/src/components/common/ConfirmModal.tsx b/src/components/common/ConfirmModal.tsx new file mode 100644 index 0000000..4d26248 --- /dev/null +++ b/src/components/common/ConfirmModal.tsx @@ -0,0 +1,133 @@ +import { Modal, Pressable, StyleSheet, Text, TouchableOpacity, View } from "react-native"; + +type Props = { + visible: boolean; + title: string; + description: string; + cancelLabel?: string; + confirmLabel: string; + confirmDestructive?: boolean; + confirmDisabled?: boolean; + onCancel: () => void; + onConfirm: () => void; +}; + +export default function ConfirmModal({ + visible, + title, + description, + cancelLabel = "취소", + confirmLabel, + confirmDestructive = false, + confirmDisabled = false, + onCancel, + onConfirm, +}: Props) { + return ( + + + + + + {title} + {description} + + + + + {cancelLabel} + + + {confirmLabel} + + + + + + ); +} + +const styles = StyleSheet.create({ + backdrop: { + flex: 1, + backgroundColor: "rgba(0,0,0,0.38)", + alignItems: "center", + justifyContent: "center", + paddingHorizontal: 24, + }, + card: { + width: "100%", + maxWidth: 355, + borderRadius: 12, + backgroundColor: "#FFFFFF", + paddingHorizontal: 24, + paddingTop: 28, + paddingBottom: 24, + gap: 32, + }, + copyGroup: { + width: "100%", + gap: 8, + }, + title: { + fontSize: 20, + lineHeight: 28, + fontWeight: "600", + color: "#171717", + }, + description: { + fontSize: 16, + lineHeight: 26, + color: "#171717", + }, + actions: { + flexDirection: "row", + alignItems: "center", + gap: 12, + }, + cancelButton: { + flex: 1, + height: 57, + borderRadius: 8, + backgroundColor: "#EFEFEF", + alignItems: "center", + justifyContent: "center", + }, + cancelLabel: { + fontSize: 18, + lineHeight: 27, + fontWeight: "600", + color: "#171717", + }, + confirmButton: { + flex: 1, + height: 57, + borderRadius: 8, + alignItems: "center", + justifyContent: "center", + }, + confirmButtonPrimary: { + backgroundColor: "#72D14E", + }, + confirmButtonDanger: { + backgroundColor: "#F76868", + }, + confirmButtonDisabled: { + opacity: 0.55, + }, + confirmLabel: { + fontSize: 18, + lineHeight: 27, + fontWeight: "600", + color: "#FFFFFF", + }, +}); diff --git a/src/components/dailyMission/OxQuizOptionCard.tsx b/src/components/dailyMission/OxQuizOptionCard.tsx index 1821a45..d7bff55 100644 --- a/src/components/dailyMission/OxQuizOptionCard.tsx +++ b/src/components/dailyMission/OxQuizOptionCard.tsx @@ -18,14 +18,10 @@ export default function OxQuizOptionCard({ onPress, }: Props) { const Icon = label === "O" ? OIcon : XIcon; - const iconColor = - state === "correct" || state === "answer" - ? "#6FCF4A" - : state === "wrong" - ? "#FF6B6B" - : state === "selected" - ? "#4A4A4A" - : "#BFBFBF"; + const isCorrect = state === "correct" || state === "answer"; + const isWrong = state === "wrong"; + const isSelected = state === "selected"; + const iconColor = isCorrect ? "#3AB40B" : isWrong ? "#F76868" : isSelected ? "#171717" : "#BFBFBF"; return ( - + ); @@ -49,7 +45,7 @@ export default function OxQuizOptionCard({ const styles = StyleSheet.create({ card: { flex: 1, - height: 150, + height: 160, borderRadius: 8, borderWidth: 1, borderColor: "#EFEFEF", @@ -62,12 +58,12 @@ const styles = StyleSheet.create({ borderColor: "#BFBFBF", }, cardCorrect: { - backgroundColor: "#EFF9EA", - borderColor: "#6FCF4A", + backgroundColor: "#EEF9EA", + borderColor: "#72D14E", }, cardWrong: { - backgroundColor: "#FFF1F1", - borderColor: "#FF6B6B", + backgroundColor: "#FFEFEF", + borderColor: "#F76868", }, iconWrap: { alignItems: "center", diff --git a/src/components/dailyMission/QuizOptionCard.tsx b/src/components/dailyMission/QuizOptionCard.tsx index 3cd9a07..a9cc3d6 100644 --- a/src/components/dailyMission/QuizOptionCard.tsx +++ b/src/components/dailyMission/QuizOptionCard.tsx @@ -1,4 +1,4 @@ -import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; import CheckIcon from "@/assets/icons/Check.svg"; import Check2Icon from "@/assets/icons/Check2.svg"; @@ -17,24 +17,19 @@ export default function QuizOptionCard({ state = "idle", onPress, }: Props) { - const BadgeIcon = - state === "correct" || state === "answer" || selected ? CheckIcon : Check2Icon; - const badgeText = - state === "correct" || state === "answer" - ? "\uC815\uB2F5" - : state === "wrong" - ? "\uC624\uB2F5" - : selected - ? "\uC120\uD0DD\uB428" - : null; + const isCorrect = state === "correct" || state === "answer"; + const isWrong = state === "wrong"; + const isSelected = selected && !isCorrect && !isWrong; + const BadgeIcon = isCorrect || isSelected ? CheckIcon : Check2Icon; + const badgeText = isCorrect ? "정답!" : isWrong ? "오답!" : null; return ( {label} - {badgeText ? ( - + {badgeText} - ) : null} + ) : ( + + )} ); @@ -61,10 +51,13 @@ export default function QuizOptionCard({ const styles = StyleSheet.create({ card: { - borderRadius: 14, + minHeight: 60, + borderRadius: 8, borderWidth: 1, - borderColor: "#D1D5DB", - padding: 16, + borderColor: "#EFEFEF", + paddingLeft: 24, + paddingRight: 16, + paddingVertical: 16, backgroundColor: "#FFFFFF", flexDirection: "row", alignItems: "center", @@ -72,39 +65,38 @@ const styles = StyleSheet.create({ gap: 12, }, cardSelected: { - backgroundColor: "#F3F4F6", - borderColor: "#9CA3AF", + backgroundColor: "#EFEFEF", + borderColor: "#BFBFBF", }, cardCorrect: { - backgroundColor: "#EDF7ED", - borderColor: "#2F7D32", + backgroundColor: "#EEF9EA", + borderColor: "#72D14E", }, cardWrong: { - backgroundColor: "#FEF2F2", - borderColor: "#DC2626", + backgroundColor: "#FFEFEF", + borderColor: "#F76868", }, text: { flex: 1, - fontSize: 15, - lineHeight: 22, - color: "#171717", + fontSize: 16, + lineHeight: 26, + color: "#282828", + fontWeight: "400", }, badgeWrap: { - flexDirection: "row", - alignItems: "center", - gap: 6, - minWidth: 54, - justifyContent: "flex-end", + minWidth: 60, + alignItems: "flex-end", + justifyContent: "center", }, badgeText: { - fontSize: 12, - fontWeight: "700", - color: "#4B5563", + fontSize: 18, + lineHeight: 27, + fontWeight: "600", }, badgeTextCorrect: { - color: "#2F7D32", + color: "#3AB40B", }, badgeTextWrong: { - color: "#DC2626", + color: "#F76868", }, }); diff --git a/src/components/feed/FeedDetail.tsx b/src/components/feed/FeedDetail.tsx index 7055545..ab1ae80 100644 --- a/src/components/feed/FeedDetail.tsx +++ b/src/components/feed/FeedDetail.tsx @@ -1,15 +1,14 @@ import React, { useCallback, useMemo, useRef, useState } from "react"; import { - Alert, FlatList, - ListRenderItem, - View, - Text, Image, KeyboardAvoidingView, + ListRenderItem, Platform, - TouchableOpacity, StyleSheet, + Text, + TouchableOpacity, + View, } from "react-native"; import { useNavigation } from "@react-navigation/native"; import type { NativeStackNavigationProp } from "@react-navigation/native-stack"; @@ -25,6 +24,7 @@ import type { RootStackParamList } from "@/navigation/types"; import { HeartIcon, ChatIcon } from "@/assets/icons/CommonIcons"; import Comment from "@/components/common/Comment"; import CommentComposer from "@/components/common/CommentComposer"; +import ConfirmModal from "@/components/common/ConfirmModal"; import useTokenStore from "@/stores/useTokenStore"; import type { FeedDetailResult } from "@/types/feed/detail"; @@ -45,6 +45,14 @@ type Props = { isReportPending?: boolean; }; +type ConfirmModalState = { + title: string; + description: string; + confirmLabel: string; + destructive?: boolean; + onConfirm: () => Promise | ConfirmModalState | void; +}; + export default function FeedDetail({ result, reportTargetLabel = "게시물", @@ -67,6 +75,8 @@ export default function FeedDetail({ const bottomSheetModalRef = useRef(null); const snapPoints = useMemo(() => ["60%", "90%"], []); const [hiddenCommentIds, setHiddenCommentIds] = useState([]); + const [confirmModalState, setConfirmModalState] = useState(null); + const [isConfirmPending, setIsConfirmPending] = useState(false); const comments = useMemo( () => @@ -87,38 +97,28 @@ export default function FeedDetail({ return; } - Alert.alert("신고하기", "댓글을 신고하시겠습니까?\n신고한 댓글은 나에게 숨겨집니다.", [ - { - text: "취소", - style: "cancel", - }, - { - text: "신고하기", - style: "destructive", - onPress: () => { - Alert.alert("사용자 숨기기", "사용자의 모든 댓글을 숨기시겠습니까?\n이 작업은 취소할 수 없습니다.", [ - { - text: "취소", - style: "cancel", - }, - { - text: "숨기기", - style: "destructive", - onPress: async () => { - try { - await onPressCommentReport(commentId, writer); - setHiddenCommentIds(previous => - previous.includes(commentId) ? previous : [...previous, commentId] - ); - } catch { - // Error handling is delegated to the caller. - } - }, - }, - ]); + setConfirmModalState({ + title: "신고하기", + description: "댓글을 신고하시겠습니까?\n신고한 댓글은 나에게 숨겨집니다.", + confirmLabel: "신고하기", + destructive: true, + onConfirm: () => ({ + title: "사용자 숨기기", + description: "사용자의 모든 댓글을 숨기시겠습니까?\n이 작업은 취소할 수 없습니다.", + confirmLabel: "숨기기", + destructive: true, + onConfirm: async () => { + try { + await onPressCommentReport(commentId, writer); + setHiddenCommentIds(previous => + previous.includes(commentId) ? previous : [...previous, commentId] + ); + } catch { + // Error handling is delegated to the caller. + } }, - }, - ]); + }), + }); }; const renderCommentItem: ListRenderItem<(typeof comments)[number]> = ({ @@ -137,26 +137,22 @@ export default function FeedDetail({ return; } - Alert.alert("삭제하기", "댓글을 삭제하시겠습니까?", [ - { - text: "취소", - style: "cancel", - }, - { - text: "삭제", - style: "destructive", - onPress: async () => { - try { - await onPressCommentDelete(item.id); - setHiddenCommentIds(previous => - previous.includes(item.id) ? previous : [...previous, item.id] - ); - } catch { - // Error handling is delegated to the caller. - } - }, + setConfirmModalState({ + title: "삭제하기", + description: "댓글을 삭제하시겠습니까?", + confirmLabel: "삭제", + destructive: true, + onConfirm: async () => { + try { + await onPressCommentDelete(item.id); + setHiddenCommentIds(previous => + previous.includes(item.id) ? previous : [...previous, item.id] + ); + } catch { + // Error handling is delegated to the caller. + } }, - ]); + }); } : onPressCommentReport ? () => void handleCommentReportPress(item.id, item.writer) @@ -187,39 +183,37 @@ export default function FeedDetail({ return; } - Alert.alert( - "신고하기", - `${reportTargetLabel}을 신고하시겠습니까?\n신고한 ${reportTargetLabel}은 나에게 숨겨집니다.`, - [ - { - text: "취소", - style: "cancel", + setConfirmModalState({ + title: "신고하기", + description: `${reportTargetLabel}을 신고하시겠습니까?\n신고한 ${reportTargetLabel}은 나에게 숨겨집니다.`, + confirmLabel: "신고하기", + destructive: true, + onConfirm: () => ({ + title: "사용자 숨기기", + description: `사용자의 모든 ${reportTargetLabel}을 숨기시겠습니까?\n이 작업은 취소할 수 없습니다.`, + confirmLabel: "숨기기", + destructive: true, + onConfirm: async () => { + void onPressReport(); }, - { - text: "신고하기", - style: "destructive", - onPress: () => { - Alert.alert( - "사용자 숨기기", - `사용자의 모든 ${reportTargetLabel}을 숨기시겠습니까?\n이 작업은 취소할 수 없습니다.`, - [ - { - text: "취소", - style: "cancel", - }, - { - text: "숨기기", - style: "destructive", - onPress: () => { - void onPressReport(); - }, - }, - ] - ); - }, - }, - ] - ); + }), + }); + }; + + const handleConfirmModal = async () => { + if (!confirmModalState || isConfirmPending) { + return; + } + + const activeState = confirmModalState; + setIsConfirmPending(true); + + try { + const nextState = await activeState.onConfirm(); + setConfirmModalState(nextState ?? null); + } finally { + setIsConfirmPending(false); + } }; const handleCloseComments = () => { @@ -370,6 +364,17 @@ export default function FeedDetail({ + + setConfirmModalState(null)} + onConfirm={() => void handleConfirmModal()} + /> ); } diff --git a/src/components/home/HomeBottomSheet.tsx b/src/components/home/HomeBottomSheet.tsx index 635e5a8..6e462d2 100644 --- a/src/components/home/HomeBottomSheet.tsx +++ b/src/components/home/HomeBottomSheet.tsx @@ -1,14 +1,10 @@ -import { useEffect, useRef, useState } from "react"; -import { - Animated, - PanResponder, - Pressable, - ScrollView, - StyleSheet, - Text, - TouchableOpacity, - View, -} from "react-native"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import BottomSheet, { + BottomSheetBackdrop, + BottomSheetHandleProps, + BottomSheetScrollView, +} from "@gorhom/bottom-sheet"; import CheckIcon from "@/assets/icons/Check.svg"; import Check2Icon from "@/assets/icons/Check2.svg"; import PlantBadgeIcon from "@/assets/icons/bottom-sheet/plant.svg"; @@ -16,9 +12,8 @@ import WishTreeInfoModal from "@/components/home/WishTreeInfoModal"; import { getMissionCompleted, type TodayMission } from "@/types/home/garden"; import type { HomePanelPayload } from "@/types/home/panel"; -const COLLAPSED_HEIGHT = 104; +const COLLAPSED_HEIGHT = 90; const EXPANDED_HEIGHT = 580; -const DRAG_RANGE = EXPANDED_HEIGHT - COLLAPSED_HEIGHT; export default function HomeBottomSheet({ expanded, @@ -37,57 +32,13 @@ export default function HomeBottomSheet({ onPressMission: (mission: TodayMission) => void; onPressEmotionCheck: () => void; }) { - const translateY = useRef(new Animated.Value(expanded ? 0 : DRAG_RANGE)).current; - const dragStart = useRef(DRAG_RANGE); + const bottomSheetRef = useRef(null); const [isWishInfoVisible, setIsWishInfoVisible] = useState(false); + const snapPoints = useMemo(() => [COLLAPSED_HEIGHT, EXPANDED_HEIGHT], []); useEffect(() => { - Animated.spring(translateY, { - toValue: expanded ? 0 : DRAG_RANGE, - useNativeDriver: true, - tension: 90, - friction: 12, - }).start(); - }, [expanded, translateY]); - - const panResponder = useRef( - PanResponder.create({ - onMoveShouldSetPanResponder: (_, gestureState) => Math.abs(gestureState.dy) > 4, - onPanResponderGrant: () => { - translateY.stopAnimation(value => { - dragStart.current = value; - }); - }, - onPanResponderMove: (_, gestureState) => { - const next = Math.max(0, Math.min(DRAG_RANGE, dragStart.current + gestureState.dy)); - translateY.setValue(next); - }, - onPanResponderRelease: (_, gestureState) => { - const movedUpEnough = gestureState.dy < -40; - const movedDownEnough = gestureState.dy > 40; - const flingUp = gestureState.vy < -0.45; - const flingDown = gestureState.vy > 0.45; - const nextExpanded = - movedUpEnough || flingUp - ? true - : movedDownEnough || flingDown - ? false - : expanded; - - if (!movedUpEnough && !movedDownEnough) { - translateY.stopAnimation(value => { - onExpandedChange(flingUp ? true : flingDown ? false : value < DRAG_RANGE / 2); - }); - return; - } - - onExpandedChange(nextExpanded); - }, - onPanResponderTerminate: () => { - onExpandedChange(expanded); - }, - }) - ).current; + bottomSheetRef.current?.snapToIndex(expanded ? 1 : 0); + }, [expanded]); const checkingMission = missions.find(mission => mission.missionType === "CHECKING"); const diaryMission = missions.find(mission => mission.missionType === "DIARY"); @@ -127,123 +78,142 @@ export default function HomeBottomSheet({ }, ]; - return ( - - {expanded ? onExpandedChange(false)} /> : null} + const renderBackdrop = useCallback( + (props: any) => ( + + ), + [] + ); - - - onExpandedChange(!expanded)} - style={styles.sheetDragArea} - > - - - - - 오늘의 미션 - - {missionCards.map(card => ( - - ))} - - - + const handleSheetChange = useCallback( + (index: number) => { + const nextExpanded = index > 0; + if (nextExpanded !== expanded) { + onExpandedChange(nextExpanded); + } + }, + [expanded, onExpandedChange] + ); - - {/* - * 한글 주석: - * 접힌 상태에서는 오늘의 미션 제목과 진행도만 위로 남기고, - * 실제 미션 카드와 하단 정보는 패널 안쪽으로 더 들어가 보이도록 간격을 분리한다. - */} - - {missionCards.map(card => ( - - - {card.label} - - - - ))} - + const renderHandle = useCallback( + (_props: BottomSheetHandleProps) => ( + + + + + + 오늘의 미션 + + {missionCards.map(card => ( + + ))} + + + + ), + [missionCards] + ); + + return ( + + + + + {missionCards.map(card => ( + + + {card.label} + + + + ))} + - + - - - - - - {"\uC18C\uB9DD \uB098\uBB34"} - - setIsWishInfoVisible(true)} - style={styles.wishInfoButton} - > - ? - + + + + - - {progressPercent >= 100 - ? "지금 바로 새로운 텃밭을 열 수 있어요!" - : `소망 나무 다음 성장까지 ${100 - progressPercent}%가 남았어요!`} - + 소망 나무 + + setIsWishInfoVisible(true)} + style={styles.wishInfoButton} + > + ? + + + {progressPercent >= 100 + ? "지금 바로 새로운 텃밭을 열 수 있어요!" + : `소망 나무 다음 성장까지 ${100 - progressPercent}%가 남았어요!`} + + - - {currentStage} - {nextStage} - - - + + {currentStage} + {nextStage} + + + + + + + 현재 성장 + + {currentGrowthPoints} + / {requiredGrowthPoints} + - - - 현재 성장 - - {currentGrowthPoints} - / {requiredGrowthPoints} - - - - 다음 성장까지 - - {remainingGrowthPoints} - 남음 - - + + 다음 성장까지 + + {remainingGrowthPoints} + 남음 + - - - - - - setIsWishInfoVisible(false)} - /> + + + + setIsWishInfoVisible(false)} /> ); } - function MissionStatusDot({ checked }: { checked: boolean }) { return ( - {checked ? : } + {checked ? : } ); } @@ -253,50 +223,37 @@ const styles = StyleSheet.create({ ...StyleSheet.absoluteFillObject, justifyContent: "flex-end", }, - sheetBackdrop: { - ...StyleSheet.absoluteFillObject, - backgroundColor: "rgba(12, 18, 14, 0.10)", - }, - - sheetWrap: { - height: EXPANDED_HEIGHT, - }, - sheet: { - width: "100%", - height: EXPANDED_HEIGHT, + sheetBackground: { + backgroundColor: "#FFFFFF", borderTopLeftRadius: 24, borderTopRightRadius: 24, borderTopWidth: 1, borderTopColor: "#E5E7EB", - backgroundColor: "#FFFFFF", - paddingHorizontal: 16, - paddingTop: 6, - paddingBottom: 30, - overflow: "hidden", shadowColor: "#000000", shadowOpacity: 0.12, shadowRadius: 10, shadowOffset: { width: 0, height: -4 }, elevation: 12, }, - sheetDragArea: { - paddingTop: 2, - paddingBottom: 18, - paddingHorizontal: 4, + handleWrap: { + paddingHorizontal: 20, + paddingTop: 14, + paddingBottom: 20, + backgroundColor: "#FFFFFF", + borderTopLeftRadius: 24, + borderTopRightRadius: 24, + overflow: "hidden", }, sheetHandleButton: { alignItems: "center", - paddingBottom: 12, - paddingTop: 8, + paddingTop: 4, + paddingBottom: 14, }, sheetHandle: { - width: 40, - height: 4, + width: 44, + height: 5, borderRadius: 999, - backgroundColor: "#9CA3AF", - }, - sheetContent: { - paddingHorizontal: 4, + backgroundColor: "#B8C0CC", }, sheetHeaderRow: { flexDirection: "row", @@ -313,11 +270,20 @@ const styles = StyleSheet.create({ gap: 8, }, statusDot: { - width: 24, - height: 24, + width: 28, + height: 28, alignItems: "center", justifyContent: "center", }, + sheetContent: { + backgroundColor: "#FFFFFF", + borderTopLeftRadius: 24, + borderTopRightRadius: 24, + }, + sheetContentContainer: { + paddingHorizontal: 20, + paddingBottom: 30, + }, sheetMissionList: { marginTop: 8, gap: 10, @@ -451,7 +417,7 @@ const styles = StyleSheet.create({ color: "#6B7280", fontWeight: "600", }, - }); + diff --git a/src/components/home/HomeGardenScene.tsx b/src/components/home/HomeGardenScene.tsx index 574036f..0773c8f 100644 --- a/src/components/home/HomeGardenScene.tsx +++ b/src/components/home/HomeGardenScene.tsx @@ -179,10 +179,18 @@ export default function HomeGardenScene({ - - - - {title ?? `${userName ?? "나풀나풀"}의 정원`} + {isLocked ? ( + + ) : ( + + + + )} + {!isLocked ? ( + {title ?? `${userName ?? "나풀나풀"}의 정원`} + ) : ( + + )} @@ -195,12 +203,12 @@ export default function HomeGardenScene({ style={styles.lockStatusIcon} /> - {isUnlockable ? "지금 열 수 있어요" : "해금되지 않았습니다"} + {isUnlockable ? "지금 열 수 있어요!" : "해금되지 않았습니다"} {isUnlockable - ? "씨앗을 받아 새로운 텃밭을 열 수 있어요." - : "소망 나무가 충분히 자라면 새로운 텃밭을 열 수 있어요."} + ? "아래 버튼을 눌러 씨앗을 배송받고,\n새로운 곳에서 식물을 키워보세요." + : "성장 나무가 성장한 뒤에\n새로운 식물을 키울 수 있어요."} @@ -213,8 +221,13 @@ export default function HomeGardenScene({ isUnlockable ? styles.lockedFooterButtonActive : styles.lockedFooterButtonDisabled, ]} > - - {isUnlockable ? "씨앗 받고 해금하기" : "아직 감자가 충분히 모이지 않았어요"} + + {isUnlockable ? "씨앗 받고 해금하기!" : "아직 감자가 충분히 모이지 않았어요"} @@ -330,6 +343,9 @@ const styles = StyleSheet.create({ textShadowOffset: { width: 0, height: 1 }, textShadowRadius: 4, }, + sceneTitleSpacer: { + flex: 1, + }, sceneHeaderSpacer: { width: 48, height: 48, @@ -349,7 +365,7 @@ const styles = StyleSheet.create({ flex: 1, justifyContent: "space-between", paddingHorizontal: 20, - paddingBottom: 28, + paddingBottom: 0, zIndex: 2, }, actionRail: { @@ -379,40 +395,47 @@ const styles = StyleSheet.create({ marginBottom: 6, }, lockedHeading: { - fontSize: 24, - fontWeight: "700", - color: "#D64545", + fontSize: 18, + lineHeight: 27, + fontWeight: "600", + color: "#F76868", textAlign: "center", }, unlockHeading: { - color: "#59A647", + color: "#45B01B", }, lockedBody: { - fontSize: 15, - lineHeight: 22, + fontSize: 16, + lineHeight: 26, color: "#171717", textAlign: "center", }, lockedFooterButton: { - width: "100%", - minHeight: 58, - borderRadius: 18, + alignSelf: "stretch", + marginHorizontal: -20, + height: 72, alignItems: "center", justifyContent: "center", paddingHorizontal: 20, }, lockedFooterButtonActive: { - backgroundColor: "#59A647", + backgroundColor: "#72D14E", }, lockedFooterButtonDisabled: { - backgroundColor: "#BFC6BC", + backgroundColor: "#EFEFEF", }, lockedFooterButtonText: { - fontSize: 16, - fontWeight: "700", - color: "#FFFFFF", + fontSize: 18, + lineHeight: 27, + fontWeight: "600", textAlign: "center", }, + lockedFooterButtonTextActive: { + color: "#FFFFFF", + }, + lockedFooterButtonTextDisabled: { + color: "#BFBFBF", + }, emptySlotWrap: { width: "100%", alignItems: "center", @@ -455,3 +478,5 @@ const styles = StyleSheet.create({ height: 288, }, }); + + diff --git a/src/pages/dailyMission/DailyMissionQuizMultipleChoiceScreen.tsx b/src/pages/dailyMission/DailyMissionQuizMultipleChoiceScreen.tsx index ef31e64..f0e95d9 100644 --- a/src/pages/dailyMission/DailyMissionQuizMultipleChoiceScreen.tsx +++ b/src/pages/dailyMission/DailyMissionQuizMultipleChoiceScreen.tsx @@ -1,20 +1,16 @@ -import { useEffect, useMemo, useState } from "react"; -import { ScrollView, StyleSheet, Text, View } from "react-native"; +import { useEffect, useMemo, useState } from "react"; +import { ScrollView, StyleSheet, Text, TouchableOpacity, View } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; import ScreenHeader from "@/components/common/ScreenHeader"; import StatusView from "@/components/common/StatusView"; import QuizOptionCard from "@/components/dailyMission/QuizOptionCard"; -import QuizResultCard from "@/components/dailyMission/QuizResultCard"; -import RegistrationFooter from "@/components/registration/RegistrationFooter"; import { useAnswerQuiz, useMissionQuiz } from "@/hooks/mission/useMissionApi"; import type { RootStackScreenProps } from "@/navigation/types"; import type { AnswerQuizResult } from "@/types/missions"; type Props = RootStackScreenProps<"DailyMissionQuizMultipleChoice">; -export default function DailyMissionQuizMultipleChoiceScreen({ - navigation, -}: Props) { +export default function DailyMissionQuizMultipleChoiceScreen({ navigation }: Props) { const [selected, setSelected] = useState(null); const { data, isLoading, isError, refetch } = useMissionQuiz({ quizType: "MULTI_CHOICE", @@ -27,11 +23,6 @@ export default function DailyMissionQuizMultipleChoiceScreen({ } }, [data?.selectedOptionNumber]); - /* - * 한글 주석: - * 이미 푼 퀴즈에 다시 진입했을 때도 선택한 선지와 해설을 복원해야 하므로 - * 조회 응답에 포함된 완료 상태를 제출 응답과 같은 형태로 맞춰서 사용한다. - */ const persistedAnswerResult = useMemo(() => { if ( !data?.isCompleted || @@ -76,7 +67,7 @@ export default function DailyMissionQuizMultipleChoiceScreen({ if (isLoading) { return ( - navigation.goBack()} /> + navigation.goBack()} /> ); @@ -85,7 +76,7 @@ export default function DailyMissionQuizMultipleChoiceScreen({ if (isError) { return ( - navigation.goBack()} /> + navigation.goBack()} /> - navigation.goBack()} /> + navigation.goBack()} /> ); } return ( - - navigation.goBack()} /> - + + navigation.goBack()} /> + - 오늘의 퀴즈 + 오늘의 퀴즈! {data.quizQuestion} {data.quizOptions?.map(option => { - const state = - answerResult != null - ? answerResult.isCorrect - ? option.optionOrder === answerResult.answerNumber - ? "correct" - : "idle" - : option.optionOrder === answerResult.selectedOptionNumber - ? "wrong" - : option.optionOrder === answerResult.answerNumber - ? "answer" - : "idle" - : "idle"; + const isSelected = selected === option.optionOrder; + const isCorrectAnswer = option.optionOrder === answerResult?.answerNumber; + const isWrongSelected = option.optionOrder === answerResult?.selectedOptionNumber && answerResult && !answerResult.isCorrect; + + const state = answerResult + ? isWrongSelected + ? "wrong" + : isCorrectAnswer + ? "correct" + : "idle" + : "idle"; + + const shouldShowExplanation = Boolean(answerResult && isCorrectAnswer); return ( - setSelected(option.optionOrder)} - /> + + setSelected(option.optionOrder)} + /> + {shouldShowExplanation ? ( + {answerResult?.answerDescription ?? ""} + ) : null} + ); })} - {answerResult ? ( - - ) : null} - {submitAnswer.isError ? ( 정답 제출에 실패했습니다. - - `POST /api/v1/realQuiz/{'{quizId}'}/answer` 응답을 다시 확인해야 합니다. - + 잠시 후 다시 시도해주세요. ) : null} - void handleSubmit()} - primaryDisabled={answerResult ? false : selected === null || submitAnswer.isPending} - primaryLoading={submitAnswer.isPending} - /> + + void handleSubmit()} + disabled={answerResult ? false : selected === null || submitAnswer.isPending} + style={[ + styles.primaryButton, + !answerResult && (selected === null || submitAnswer.isPending) ? styles.primaryButtonDisabled : null, + answerResult ? styles.primaryButtonResult : null, + ]} + > + + {answerResult ? "다음" : submitAnswer.isPending ? "확인 중..." : "정답 확인하기"} + + + ); } @@ -173,33 +174,45 @@ export default function DailyMissionQuizMultipleChoiceScreen({ const styles = StyleSheet.create({ safeArea: { flex: 1, - backgroundColor: "#F7F8F4", + backgroundColor: "#FFFFFF", }, content: { - padding: 20, - gap: 18, + paddingHorizontal: 20, + paddingTop: 34, + paddingBottom: 24, }, headerBlock: { gap: 8, + marginBottom: 32, }, - eyebrow: { - fontSize: 12, - color: "#2F7D32", - fontWeight: "700", + title: { + fontSize: 20, + lineHeight: 28, + fontWeight: "600", + color: "#171717", }, question: { - fontSize: 24, - lineHeight: 32, - fontWeight: "700", + fontSize: 16, + lineHeight: 26, + fontWeight: "400", color: "#171717", }, options: { - gap: 12, + gap: 8, + }, + optionBlock: { + gap: 8, + }, + explanation: { + fontSize: 14, + lineHeight: 22, + color: "#3AB40B", }, errorCard: { + marginTop: 20, borderRadius: 16, padding: 16, - backgroundColor: "#FEF2F2", + backgroundColor: "#FFF4F4", gap: 6, }, errorTitle: { @@ -212,5 +225,40 @@ const styles = StyleSheet.create({ lineHeight: 20, color: "#7F1D1D", }, + footer: { + paddingHorizontal: 20, + paddingTop: 12, + paddingBottom: 16, + backgroundColor: "#FFFFFF", + }, + primaryButton: { + minHeight: 56, + borderRadius: 8, + backgroundColor: "#72D14E", + alignItems: "center", + justifyContent: "center", + borderWidth: 1, + borderColor: "#72D14E", + }, + primaryButtonDisabled: { + backgroundColor: "#EFEFEF", + borderColor: "#EFEFEF", + }, + primaryButtonResult: { + backgroundColor: "#FFFFFF", + borderColor: "#72D14E", + }, + primaryButtonText: { + fontSize: 18, + lineHeight: 27, + fontWeight: "600", + color: "#FFFFFF", + }, + primaryButtonTextDisabled: { + color: "#BFBFBF", + }, + primaryButtonTextResult: { + color: "#3AB40B", + }, }); diff --git a/src/pages/dailyMission/DailyMissionQuizOxScreen.tsx b/src/pages/dailyMission/DailyMissionQuizOxScreen.tsx index 34a1e5e..ae64508 100644 --- a/src/pages/dailyMission/DailyMissionQuizOxScreen.tsx +++ b/src/pages/dailyMission/DailyMissionQuizOxScreen.tsx @@ -115,7 +115,7 @@ export default function DailyMissionQuizOxScreen({ navigation }: Props) { return ( navigation.goBack()} /> - + 오늘의 퀴즈! {data.quizQuestion} @@ -123,20 +123,21 @@ export default function DailyMissionQuizOxScreen({ navigation }: Props) { {options.map(option => { - const state = - answerResult != null - ? answerResult.isCorrect - ? option.optionOrder === answerResult.answerNumber - ? "correct" - : "idle" - : option.optionOrder === answerResult.selectedOptionNumber - ? "wrong" - : option.optionOrder === answerResult.answerNumber - ? "answer" - : "idle" - : selected === option.optionOrder - ? "selected" - : "idle"; + const isCorrectAnswer = option.optionOrder === answerResult?.answerNumber; + const isWrongSelected = + option.optionOrder === answerResult?.selectedOptionNumber && + answerResult != null && + !answerResult.isCorrect; + + const state = answerResult + ? isWrongSelected + ? "wrong" + : isCorrectAnswer + ? "correct" + : "idle" + : selected === option.optionOrder + ? "selected" + : "idle"; return ( void handleSubmit()} style={[ styles.primaryButton, - !answerResult && selected === null ? styles.primaryButtonDisabled : null, - answerResult ? styles.primaryButtonNext : null, + !answerResult && (selected === null || submitAnswer.isPending) ? styles.primaryButtonDisabled : null, + answerResult ? styles.primaryButtonResult : null, ]} > {answerResult ? "다음" : submitAnswer.isPending ? "확인 중..." : "정답 확인하기"} @@ -216,7 +217,7 @@ const styles = StyleSheet.create({ paddingBottom: 24, }, headerBlock: { - gap: 10, + gap: 8, marginBottom: 52, }, title: { @@ -234,32 +235,32 @@ const styles = StyleSheet.create({ optionsRow: { flexDirection: "row", gap: 12, - marginBottom: 34, + marginBottom: 32, }, resultBlock: { - gap: 12, + gap: 8, }, resultTitle: { - fontSize: 16, - lineHeight: 24, - fontWeight: "700", + fontSize: 18, + lineHeight: 27, + fontWeight: "600", }, resultTitleCorrect: { - color: "#46C02B", + color: "#3AB40B", }, resultTitleWrong: { - color: "#FF6B6B", + color: "#F76868", }, resultDescription: { fontSize: 14, - lineHeight: 28, + lineHeight: 22, fontWeight: "400", }, resultDescriptionCorrect: { - color: "#46C02B", + color: "#3AB40B", }, resultDescriptionWrong: { - color: "#FF6B6B", + color: "#F76868", }, errorBlock: { marginTop: 20, @@ -277,21 +278,22 @@ const styles = StyleSheet.create({ }, footer: { paddingHorizontal: 20, - paddingTop: 16, - paddingBottom: 28, + paddingTop: 12, + paddingBottom: 16, + backgroundColor: "#FFFFFF", }, primaryButton: { minHeight: 56, borderRadius: 8, - backgroundColor: "#6FCF4A", + backgroundColor: "#72D14E", alignItems: "center", justifyContent: "center", }, primaryButtonDisabled: { backgroundColor: "#EFEFEF", }, - primaryButtonNext: { - backgroundColor: "#EFF9EA", + primaryButtonResult: { + backgroundColor: "#EEF9EA", }, primaryButtonText: { fontSize: 18, @@ -302,9 +304,7 @@ const styles = StyleSheet.create({ primaryButtonTextDisabled: { color: "#BFBFBF", }, - primaryButtonTextNext: { - color: "#46C02B", + primaryButtonTextResult: { + color: "#3AB40B", }, }); - - diff --git a/src/pages/follow/FollowScreen.tsx b/src/pages/follow/FollowScreen.tsx index 0640b36..95c59ac 100644 --- a/src/pages/follow/FollowScreen.tsx +++ b/src/pages/follow/FollowScreen.tsx @@ -1,6 +1,5 @@ -import { useState } from "react"; +import { useState } from "react"; import { - Alert, Image, RefreshControl, ScrollView, @@ -12,6 +11,7 @@ import { import { SafeAreaView } from "react-native-safe-area-context"; import type { RootStackScreenProps } from "@/navigation/types"; import { XmarkIcon } from "@/assets/icons/CommonIcons"; +import ConfirmModal from "@/components/common/ConfirmModal"; import ScreenHeader from "@/components/common/ScreenHeader"; import StatusView from "@/components/common/StatusView"; import { @@ -26,6 +26,7 @@ type Tab = "added" | "followed"; export default function FollowScreen({ navigation }: Props) { const [activeTab, setActiveTab] = useState("added"); + const [pendingRemoveUserId, setPendingRemoveUserId] = useState(null); const userId = useTokenStore(state => state.userId); const followingQuery = useFollowing(userId); const followersQuery = useFollowers(userId); @@ -64,21 +65,17 @@ export default function FollowScreen({ navigation }: Props) { return; } - Alert.alert( - "친구 삭제하기", - "사용자를 친구에서 삭제하시겠습니까?\n언제든 다시 추가할 수 있습니다.", - [ - { - text: "취소", - style: "cancel", - }, - { - text: "삭제", - style: "destructive", - onPress: () => void unfollowMutation.mutateAsync(targetUserId), - }, - ] - ); + setPendingRemoveUserId(targetUserId); + }; + + const handleRemoveFriend = async () => { + if (pendingRemoveUserId === null || unfollowMutation.isPending) { + return; + } + + const targetUserId = pendingRemoveUserId; + setPendingRemoveUserId(null); + await unfollowMutation.mutateAsync(targetUserId); }; return ( @@ -91,7 +88,6 @@ export default function FollowScreen({ navigation }: Props) { rightActionDisabled={isLoading || isRefetching} /> - {/* Tabs are renamed to match the app copy while still mapping to following/follower queries. */} } > - {/* 한글 주석: - 팔로우 탭은 활성 탭 쿼리만 다시 읽으면 되므로, - 헤더 새로고침과 pull-to-refresh 모두 같은 handleRetry로 묶는다. */} {users.map(user => ( - // The custom row matches the FE design more closely than the previous generic card. )} + + setPendingRemoveUserId(null)} + onConfirm={() => void handleRemoveFriend()} + /> ); } diff --git a/src/pages/home/HomeScreen.tsx b/src/pages/home/HomeScreen.tsx index c5c3824..f9877a6 100644 --- a/src/pages/home/HomeScreen.tsx +++ b/src/pages/home/HomeScreen.tsx @@ -246,16 +246,18 @@ export default function HomeScreen({ navigation }: Props) { ))} - - - {scenes.map((scene, index) => ( - - ))} + {!isCurrentGardenLocked ? ( + + + {scenes.map((scene, index) => ( + + ))} + - + ) : null} {!isCurrentGardenLocked ? ( ; export default function OptionScreen({ navigation }: Props) { const [isLoggingOut, setIsLoggingOut] = useState(false); + const [isLogoutConfirmVisible, setIsLogoutConfirmVisible] = useState(false); const { accessToken, userId, hasHydrated } = useTokenStore(); const { data: notificationSettings } = useNotificationSettings(); const updateSettingsMutation = useUpdateNotificationSettings(); @@ -60,17 +62,17 @@ export default function OptionScreen({ navigation }: Props) { return; } - Alert.alert("로그아웃", "현재 계정에서 로그아웃할까요?", [ - { text: "취소", style: "cancel" }, - { - text: "로그아웃", - style: "destructive", - onPress: async () => { - setIsLoggingOut(true); - await logout(); - }, - }, - ]); + setIsLogoutConfirmVisible(true); + }; + + const handleConfirmLogout = async () => { + if (isLoggingOut || !accessToken) { + return; + } + + setIsLogoutConfirmVisible(false); + setIsLoggingOut(true); + await logout(); }; const loginStatus = !hasHydrated ? "세션 확인 중" : accessToken ? "로그인 상태" : "로그아웃 상태"; @@ -109,6 +111,17 @@ export default function OptionScreen({ navigation }: Props) { {userId ? `사용자 ID ${userId}` : "사용자 ID 없음"} + + setIsLogoutConfirmVisible(false)} + onConfirm={() => void handleConfirmLogout()} + /> ); } diff --git a/src/pages/option/ServiceGuideScreen.tsx b/src/pages/option/ServiceGuideScreen.tsx index d1f3799..374db3d 100644 --- a/src/pages/option/ServiceGuideScreen.tsx +++ b/src/pages/option/ServiceGuideScreen.tsx @@ -1,5 +1,6 @@ -import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; +import LeftIcon from "@/assets/icons/common/left.svg"; import type { RootStackScreenProps } from "@/navigation/types"; import OnboardingCarousel from "@/components/onboarding/OnboardingCarousel"; @@ -8,22 +9,19 @@ type Props = RootStackScreenProps<"ServiceGuide">; export default function ServiceGuideScreen({ navigation }: Props) { return ( - + navigation.goBack()} activeOpacity={0.7} style={styles.headerSideButton} > - 뒤로 + 서비스 안내 - {/* 한글 주석: - 서비스 안내는 별도 API 없이 온보딩의 4장 소개 슬라이드를 그대로 재사용하되, - 설정 화면 진입 문맥에 맞게 상단 헤더만 박스형으로 따로 얹는다. */} @@ -35,37 +33,28 @@ const styles = StyleSheet.create({ flex: 1, backgroundColor: "#FFFFFF", }, - headerCard: { - marginHorizontal: 16, - marginTop: 8, - marginBottom: 8, - minHeight: 56, - borderRadius: 18, - backgroundColor: "rgba(255,255,255,0.96)", + headerBar: { + height: 56, flexDirection: "row", alignItems: "center", - paddingHorizontal: 12, - shadowColor: "#000", - shadowOffset: { width: 0, height: 2 }, - shadowOpacity: 0.08, - shadowRadius: 10, - elevation: 3, + justifyContent: "space-between", + paddingHorizontal: 13, + backgroundColor: "#FFFFFF", + borderBottomWidth: 1, + borderBottomColor: "#EFEFEF", }, headerSideButton: { - width: 56, - minHeight: 44, + width: 24, + height: 24, justifyContent: "center", - }, - backText: { - fontSize: 14, - fontWeight: "600", - color: "#374151", + alignItems: "center", }, headerTitle: { flex: 1, textAlign: "center", fontSize: 18, - fontWeight: "700", + lineHeight: 27, + fontWeight: "600", color: "#171717", }, carouselWrap: { diff --git a/src/pages/profile/ProfileScreen.tsx b/src/pages/profile/ProfileScreen.tsx index df1db12..5abcf78 100644 --- a/src/pages/profile/ProfileScreen.tsx +++ b/src/pages/profile/ProfileScreen.tsx @@ -4,6 +4,7 @@ import type { AxiosError } from "axios"; import PagerView from "react-native-pager-view"; import { SafeAreaView } from "react-native-safe-area-context"; import type { RootStackScreenProps } from "@/navigation/types"; +import ConfirmModal from "@/components/common/ConfirmModal"; import StatusView from "@/components/common/StatusView"; import HomeToast from "@/components/home/HomeToast"; import ProfileGardenScene from "@/components/profile/ProfileGardenScene"; @@ -17,6 +18,14 @@ import { FollowStatus } from "@/types/profile/profileApi.type"; type Props = RootStackScreenProps<"Profile">; +type BlockConfirmState = { + title: string; + description: string; + confirmLabel: string; + destructive?: boolean; + onConfirm: () => Promise | void; +} | null; + const FRIEND_WATER_ACTION_COOLDOWN_MS = 700; const getFriendWaterErrorMessage = ( @@ -66,6 +75,7 @@ export default function ProfileScreen({ navigation, route }: Props) { const [isFriendWaterCooldownActive, setIsFriendWaterCooldownActive] = useState(false); const [toastMessage, setToastMessage] = useState(null); const [isBlockedUser, setIsBlockedUser] = useState(false); + const [blockConfirmState, setBlockConfirmState] = useState(null); const initialLoadTimingRef = useRef | null>(null); const isMe = String(userId) === myUserId; @@ -170,40 +180,48 @@ export default function ProfileScreen({ navigation, route }: Props) { } if (isBlockedUser) { - Alert.alert("차단 해제", "이 사용자의 차단을 해제할까요?", [ - { text: "취소", style: "cancel" }, - { - text: "차단 해제", - onPress: async () => { - try { - await unblockMutation.mutateAsync(userId); - setIsBlockedUser(false); - setToastMessage("사용자 차단을 해제했습니다."); - } catch (error) { - Alert.alert("차단 해제 실패", getActionErrorMessage(error, "잠시 후 다시 시도해주세요.")); - } - }, - }, - ]); - return; - } - - Alert.alert("차단", "이 사용자를 차단할까요? 서로 팔로우가 해제되고 콘텐츠가 숨겨집니다.", [ - { text: "취소", style: "cancel" }, - { - text: "차단", - style: "destructive", - onPress: async () => { + setBlockConfirmState({ + title: "차단 해제", + description: "이 사용자의 차단을 해제할까요?", + confirmLabel: "차단 해제", + onConfirm: async () => { try { - await blockMutation.mutateAsync(userId); - setIsBlockedUser(true); - setToastMessage("사용자를 차단했습니다."); + await unblockMutation.mutateAsync(userId); + setIsBlockedUser(false); + setToastMessage("사용자 차단을 해제했습니다."); } catch (error) { - Alert.alert("차단 실패", getActionErrorMessage(error, "잠시 후 다시 시도해주세요.")); + Alert.alert("차단 해제 실패", getActionErrorMessage(error, "잠시 후 다시 시도해주세요.")); } }, + }); + return; + } + + setBlockConfirmState({ + title: "차단", + description: "이 사용자를 차단할까요?\n서로 팔로우가 해제되고 콘텐츠가 숨겨집니다.", + confirmLabel: "차단", + destructive: true, + onConfirm: async () => { + try { + await blockMutation.mutateAsync(userId); + setIsBlockedUser(true); + setToastMessage("사용자를 차단했습니다."); + } catch (error) { + Alert.alert("차단 실패", getActionErrorMessage(error, "잠시 후 다시 시도해주세요.")); + } }, - ]); + }); + }; + + const handleConfirmBlock = async () => { + if (!blockConfirmState || isBlockActionPending) { + return; + } + + const currentConfirm = blockConfirmState; + setBlockConfirmState(null); + await currentConfirm.onConfirm(); }; const followAction = useMemo(() => { @@ -335,6 +353,17 @@ export default function ProfileScreen({ navigation, route }: Props) { + + setBlockConfirmState(null)} + onConfirm={() => void handleConfirmBlock()} + /> ); } @@ -381,6 +410,17 @@ export default function ProfileScreen({ navigation, route }: Props) { {toastMessage ? setToastMessage(null)} /> : null} + + setBlockConfirmState(null)} + onConfirm={() => void handleConfirmBlock()} + /> ); } From a9daed18644305dc4d113d4a2d7dd10ae52fe731 Mon Sep 17 00:00:00 2001 From: lejuho Date: Sat, 25 Apr 2026 13:17:59 +0900 Subject: [PATCH 88/92] =?UTF-8?q?chore=20:=20=EC=97=90=EC=9D=B4=EC=A0=84?= =?UTF-8?q?=ED=8A=B8=20=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .claude/CLAUDE.md | 70 +++ .claude/hooks/force-advisor-check.sh | 34 ++ .claude/hooks/track-failures.sh | 30 ++ .claude/settings.json | 57 ++- .claude/skills/advisor/SKILL.md | 26 ++ .claude/skills/backend-spring/SKILL.md | 507 ++++++++++++++++++++++ .claude/skills/design-principles/SKILL.md | 244 +++++++++++ .claude/skills/frontend-react/SKILL.md | 189 ++++++++ .githooks/pre-commit | 35 ++ .github/workflows/cross-review.yml | 25 ++ .vscode/settings.json | 3 + AGENTS.md | 50 +++ 12 files changed, 1269 insertions(+), 1 deletion(-) create mode 100644 .claude/CLAUDE.md create mode 100644 .claude/hooks/force-advisor-check.sh create mode 100644 .claude/hooks/track-failures.sh create mode 100644 .claude/skills/advisor/SKILL.md create mode 100644 .claude/skills/backend-spring/SKILL.md create mode 100644 .claude/skills/design-principles/SKILL.md create mode 100644 .claude/skills/frontend-react/SKILL.md create mode 100644 .githooks/pre-commit create mode 100644 .github/workflows/cross-review.yml create mode 100644 .vscode/settings.json create mode 100644 AGENTS.md diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md new file mode 100644 index 0000000..b0c6455 --- /dev/null +++ b/.claude/CLAUDE.md @@ -0,0 +1,70 @@ +# Architecture +Web2, java spring backend - JDK 17, expo,react native frontend,r2 storage,supabase +# Conventions + +# Commands + +# prohibited pattern + +## 금지 - basic +- critical한 파일 임의 수정 금지 + +## 금지 — Backend +- req.body 직접 DB, userId from body +- any 타입, 에러 raw throw + +## 금지 — Frontend +- useEffect 안 fetch, 인라인 스타일 + +# Testing & Verify + +# Past Failures -> Rules +- 실패/의도와 다른 에러 발생 시 여기에 한줄씩 추가 + +# Workflow Rules + +- 새 모듈/기능 작업 시작 전, 첫 코드 작성 직전에 advisor 호출. + 형식: "Approach check: [모듈명], [핵심 판단 지점 2-3개]" + → Skill("advisor") 로드 후 Agent(model: "opus")로 위임. 응답은 100단어 이내, 단계 나열로만. + +- "작업 완료" 선언 직전 advisor 재호출. + 형식: "Completion check: [변경된 파일], [회귀 우려 지점]" + → Skill("advisor") 로드 후 Agent(model: "opus")로 위임. 응답은 100단어 이내. + +- Plan 문서(plan.md) 없이 Generate 단계 진입 금지. + plan.md는 Codex가 작성, Claude Code가 비판적 리뷰 후 v2 확정한 것만 유효. + +# Cross-Review Loop +- 작업 완료 advisor 호출 후, Codex 세션에 review.md 작성 요청. +- review.md에 issue 1건 이상이면 Claude Code 세션 재개하여 수정. +- 수정 완료 후 같은 review.md에 "RESOLVED: [항목]" 추가하고 Codex 재검증 요청. +- review.md v2도 issue 0건이어야 PR 가능. +- 3회 사이클 후에도 미해결 시 사용자 에스컬레이션. 자동 진행 금지. + +# Cross-Review Loop (필수) + +작업 완료 선언 직전 advisor 호출 후, 다음 2-pass 교차 검증을 거쳐야 PR 가능: + +## Pass 1 — Codex 검증 +- Claude Code 세션 종료 +- 별도 Codex 세션에서 review.md 작성 +- review.md는 다음 3가지를 명시: + 1. plan.md Sprint Contract 미충족 항목 (있으면 모두 나열) + 2. 자동 체크(test/lint/slither/build) 실패 항목 + 3. plan.md에 없던 변경사항 (scope creep 식별) +- review.md에 issue 0건이면 Pass 1 완료, 1건 이상이면 Claude Code 세션 재개 + +## Pass 2 — Claude Code 수정 + 자체 재검증 +- Codex review.md 읽고 수정 작업 수행 +- 수정 후 자체 테스트/lint 재실행 +- 수정 완료 시 review.md에 "RESOLVED: [항목]" 한 줄씩 추가 +- 모든 issue가 RESOLVED 되면 작업 완료 advisor 재호출 + +## Pass 3 — Codex 재검증 +- 별도 Codex 세션에서 review.md v2 작성 +- v2에서도 issue 발견되면 Pass 2로 복귀 +- v2 issue 0건이면 PR 생성 가능 + +## 최대 반복 횟수 +- Pass 1 → Pass 2 → Pass 3 사이클은 최대 3회. +- 3회 후에도 issue 잔존 시 사용자에게 에스컬레이션. 자동 머지 절대 금지. \ No newline at end of file diff --git a/.claude/hooks/force-advisor-check.sh b/.claude/hooks/force-advisor-check.sh new file mode 100644 index 0000000..1f2aaa6 --- /dev/null +++ b/.claude/hooks/force-advisor-check.sh @@ -0,0 +1,34 @@ +#!/bin/bash +# Stop hook — fail-open 원칙: 훅 자체가 실패하면 차단하지 않고 통과 + +INPUT=$(cat) + +# jq 없으면 즉시 통과 (block 안 함) +if ! command -v jq >/dev/null 2>&1; then + exit 0 +fi + +# JSON 파싱 실패 시 통과 +TRANSCRIPT=$(echo "$INPUT" | jq -r '.transcript_path // empty' 2>/dev/null) +STOP_HOOK_ACTIVE=$(echo "$INPUT" | jq -r '.stop_hook_active // false' 2>/dev/null) + +# 무한루프 방지 — 한 번 block 한 적 있으면 무조건 통과 +[ "$STOP_HOOK_ACTIVE" = "true" ] && exit 0 + +# transcript 경로가 비었거나 파일이 없으면 통과 +[ -z "$TRANSCRIPT" ] && exit 0 +[ ! -f "$TRANSCRIPT" ] && exit 0 + +# transcript 끝부분 읽기 실패 시 통과 +RECENT=$(tail -c 20000 "$TRANSCRIPT" 2>/dev/null) || exit 0 + +# Completion check 이미 했으면 통과 +echo "$RECENT" | grep -q "Completion check" && exit 0 + +# 여기까지 와야 block 발동 +cat <<'EOF' +{ + "decision": "block", + "reason": "종료 전 강제 advisor 호출 누락. 형식: 'Completion check: [변경 파일 리스트], [회귀 우려 지점 2-3개]'. 100단어 이내 응답을 받은 후 종료할 것." +} +EOF \ No newline at end of file diff --git a/.claude/hooks/track-failures.sh b/.claude/hooks/track-failures.sh new file mode 100644 index 0000000..3772e87 --- /dev/null +++ b/.claude/hooks/track-failures.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# .claude/hooks/track-failures.sh +# PostToolUse(Bash) — Bash 출력에서 실패 패턴 추적 + +INPUT=$(cat) +TOOL_OUTPUT=$(echo "$INPUT" | jq -r '.tool_response.stdout // ""') +TOOL_STDERR=$(echo "$INPUT" | jq -r '.tool_response.stderr // ""') + +# 실패 시그니처 추출 (테스트명/에러 첫 줄) +SIGNATURE=$(echo "$TOOL_STDERR$TOOL_OUTPUT" \ + | grep -E "FAIL|Error:|revert|✗" \ + | head -1 \ + | sha256sum | cut -c1-16) + +[ -z "$SIGNATURE" ] && exit 0 # 실패 없으면 종료 + +# 카운터 파일에 누적 +COUNTER_FILE="/tmp/claude-failures-$$.log" +COUNT=$(grep -c "^$SIGNATURE$" "$COUNTER_FILE" 2>/dev/null || echo 0) +echo "$SIGNATURE" >> "$COUNTER_FILE" + +if [ "$COUNT" -ge 1 ]; then + # 2회째 — advisor 호출 강제 + cat <" +}) +``` + +## 응답 형식 (Opus에게 전달할 프롬프트에 포함) + +- 100단어 이내 +- 단계 나열로만 (산문 금지) +- Approach check: 접근 순서 + 핵심 판단 지점만 +- Completion check: 회귀 위험 항목 + 검증 필요 포인트만 diff --git a/.claude/skills/backend-spring/SKILL.md b/.claude/skills/backend-spring/SKILL.md new file mode 100644 index 0000000..3ea4309 --- /dev/null +++ b/.claude/skills/backend-spring/SKILL.md @@ -0,0 +1,507 @@ +--- +name: backend-spring +description: "Use this skill when writing or reviewing Spring Boot REST controllers, services, JPA repositories, or Java backend code. Covers DTO separation, Bean Validation, security context auth, standard response formats with @RestControllerAdvice, @Transactional placement, N+1 query prevention, and constructor injection. Triggers on Spring, Spring Boot, Java backend, JPA, Hibernate, REST controller keywords." +--- + +# Spring Boot Backend 규칙 + +## 절대 쓰지 말 것 + +``` +- Entity를 Controller에서 직접 받거나 반환 (반드시 DTO 분리) +- @Autowired 필드 주입 (생성자 주입만, Lombok @RequiredArgsConstructor 권장) +- @Transactional을 Controller에 붙이기 (Service 계층에만) +- @Data on JPA Entity (equals/hashCode/toString 무한루프 + 영속성 깨짐) +- Optional를 필드 / 파라미터 / Entity 필드에 사용 (반환 타입에만) +- userId / tenantId를 RequestBody에서 받기 (반드시 SecurityContext에서 추출) +- findAll() 후 N+1 쿼리 발생 (fetch join 또는 EntityGraph 명시) +- 트랜잭션 내에서 외부 API 호출 (커넥션 점유 + 롤백 일관성 깨짐) +- Native query에서 SELECT * (컬럼 명시) +- Setter 남발 (Builder, record, with-style 메서드 사용) +- Open Session In View true (application.yml에 false 명시) +- 예외를 그냥 throw new RuntimeException (도메인 예외 클래스 사용) +- Lombok @Value 또는 @Getter on Entity (record / explicit accessor 사용) +``` + +--- + +## DTO + Bean Validation + +모든 RequestBody는 DTO로 받고 `@Valid` 적용: + +```java +// dto//CreateRequest.java +package .dto.; + +import jakarta.validation.constraints.*; +import java.util.UUID; + +public record CreateRequest( + @NotNull + UUID , + + @NotBlank + @Size(min = 1, max = 100) + String title +) {} + +public record CreateRequest( + @NotBlank + String content, + + String context, // optional은 그대로 둠 + + UUID linkedId // optional은 그대로 둠 +) {} + +public record Request( + @NotNull + Method method, // enum + + UUID presetId, + + @Pattern(regexp = "^https?://.*") + String destination +) {} +``` + +UUID 검증은 타입 자체로 처리됨(파싱 실패 시 400). 추가 검증이 필요하면 커스텀 validator. + +사용법: + +```java +@PostMapping("/api/") +public ResponseEntityResponse>> create( + @Valid @RequestBody CreateRequest request +) { + // 파싱/검증 실패 시 자동 400 + ... +} +``` + +--- + +## userId는 SecurityContext에서만 + +```java +// 잘못된 것 +@PostMapping("/api/") +public ResponseEntity create(@RequestBody CreateRequest req) { + UUID userId = req.userId(); // ← 클라이언트 조작 가능 + ... +} + +// 올바른 것 — @AuthenticationPrincipal 사용 +@PostMapping("/api/") +public ResponseEntityResponse>> create( + @AuthenticationPrincipal CustomUserDetails principal, + @Valid @RequestBody CreateRequest request +) { + if (principal == null) throw new ForbiddenException(); + UUID userId = principal.getUserId(); // ← 서버가 검증한 값 + ... +} +``` + +`SecurityContextHolder.getContext().getAuthentication()` 직접 호출은 테스트성·결합도 때문에 비권장. 컨트롤러 시그니처에 `@AuthenticationPrincipal`로 박는 게 표준. + +--- + +## 표준 응답 포맷 — `ApiResponse` + `@RestControllerAdvice` + +공통 응답 클래스: + +```java +// common/ApiResponse.java +public record ApiResponse( + boolean ok, + T data, + String error +) { + public static ApiResponse ok(T data) { + return new ApiResponse<>(true, data, null); + } + public static ApiResponse error(String message) { + return new ApiResponse<>(false, null, message); + } +} +``` + +도메인 예외: + +```java +// common/exception/DomainException.java +public abstract class DomainException extends RuntimeException { + public abstract HttpStatus status(); + protected DomainException(String message) { super(message); } +} + +public class BadRequestException extends DomainException { + public BadRequestException(String message) { super(message); } + public HttpStatus status() { return HttpStatus.BAD_REQUEST; } +} + +public class ForbiddenException extends DomainException { + public ForbiddenException() { super("forbidden"); } + public HttpStatus status() { return HttpStatus.FORBIDDEN; } +} + +public class NotFoundException extends DomainException { + public NotFoundException(String resource) { super("not_found: " + resource); } + public HttpStatus status() { return HttpStatus.NOT_FOUND; } +} +``` + +전역 핸들러: + +```java +// common/GlobalExceptionHandler.java +@RestControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler(DomainException.class) + public ResponseEntity> handleDomain(DomainException e) { + return ResponseEntity.status(e.status()) + .body(ApiResponse.error(e.getMessage())); + } + + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseEntity> handleValidation( + MethodArgumentNotValidException e + ) { + String message = e.getBindingResult().getFieldErrors().stream() + .map(err -> err.getField() + ": " + err.getDefaultMessage()) + .collect(Collectors.joining(", ")); + return ResponseEntity.badRequest().body(ApiResponse.error(message)); + } + + @ExceptionHandler(Exception.class) + public ResponseEntity> handleUnknown(Exception e) { + log.error("Unhandled", e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.error("server_error")); + } +} +``` + +Controller에서는 정상 응답만 신경 쓰면 됨. `try/catch` 금지 — 전역 핸들러가 잡음. + +--- + +## 상태 전환 — 중앙 함수 통과 필수 + +Entity 안에 도메인 로직으로 박는 게 정석: + +```java +// domain/.java +@Entity +@Table(name = "") +public class { + + @Id + private UUID id; + + @Enumerated(EnumType.STRING) + private Status status; + + private static final Map<Status, Set<Status>> VALID_TRANSITIONS = Map.of( + Status.DRAFT, Set.of(Status.IN_REVIEW), + Status.IN_REVIEW, Set.of(Status.APPROVED, Status.REJECTED, Status.DRAFT), + Status.APPROVED, Set.of(), + Status.REJECTED, Set.of(Status.DRAFT) + ); + + public void changeStatus(Status to) { + Set<Status> allowed = VALID_TRANSITIONS.get(this.status); + if (allowed == null || !allowed.contains(to)) { + throw new BadRequestException( + "invalid transition: " + this.status + " → " + to + ); + } + this.status = to; + } +} +``` + +Service에서는 `entity.changeStatus(...)`만 호출. Setter 직접 호출 금지. + +--- + +## Controller 기본 구조 + +```java +// controller/Controller.java +@RestController +@RequestMapping("/api/") +@RequiredArgsConstructor // 생성자 주입 (Lombok) +public class Controller { + + private final Service Service; + + @PostMapping + public ResponseEntityResponse>> create( + @AuthenticationPrincipal CustomUserDetails principal, + @Valid @RequestBody CreateRequest request + ) { + if (principal == null) throw new ForbiddenException(); + + Response response = Service.create( + request, + principal.getUserId() + ); + + return ResponseEntity + .status(HttpStatus.CREATED) + .body(ApiResponse.ok(response)); + } + + @GetMapping("/{}") + public ResponseEntityResponse>> get( + @AuthenticationPrincipal CustomUserDetails principal, + @PathVariable UUID + ) { + if (principal == null) throw new ForbiddenException(); + + Response response = Service.findById( + , + principal.getUserId() + ); + + return ResponseEntity.ok(ApiResponse.ok(response)); + } +} +``` + +Controller는 **얇게**. 검증·인증·라우팅만. 비즈니스 로직 전부 Service. + +--- + +## Service 계층 규칙 + +```java +// service/Service.java +@Service +@RequiredArgsConstructor +public class Service { + + private final Repository Repository; + private final Repository Repository; + + @Transactional // ← 쓰기는 트랜잭션 명시 + public Response create(CreateRequest request, UUID userId) { + // 1. 사전 조건 확인 + parent = Repository + .findById(request.()) + .orElseThrow(() -> new NotFoundException("")); + + if (!parent.isAccessibleBy(userId)) { + throw new ForbiddenException(); + } + + // 2. 도메인 객체 생성 + entity = .create(parent, request.title(), userId); + + // 3. 저장 + Repository.save(entity); + + // 4. 응답 변환 + return Response.from(entity); + } + + @Transactional(readOnly = true) // ← 읽기는 readOnly 명시 + public Response findById(UUID , UUID userId) { + entity = Repository + .findByIdWithParent() // fetch join 메서드 + .orElseThrow(() -> new NotFoundException("")); + + if (!entity.isAccessibleBy(userId)) { + throw new ForbiddenException(); + } + + return Response.from(entity); + } +} +``` + +규칙: +- 쓰기 메서드: `@Transactional` +- 읽기 메서드: `@Transactional(readOnly = true)` — 1차 캐시 정리 + 성능 +- 트랜잭션 안에서 외부 HTTP 호출 / 메시지 발행 금지 — 트랜잭션 커밋 후 발행하려면 `ApplicationEventPublisher` + `@TransactionalEventListener(phase = AFTER_COMMIT)` + +--- + +## Repository — N+1 명시적 회피 + +```java +// repository/Repository.java +public interface Repository extends JpaRepository<, UUID> { + + // 잘못된 것 — findAll() 호출 후 entity.getParent() 접근하면 N+1 + // 올바른 것 — fetch join 명시 + @Query(""" + SELECT e FROM e + JOIN FETCH e. + WHERE e.id = :id + """) + Optional<> findByIdWithParent(@Param("id") UUID id); + + // 또는 @EntityGraph + @EntityGraph(attributePaths = {"", ""}) + Optional<> findById(UUID id); + + // 페이징 + fetch join은 주의 — Hibernate가 in-memory paging으로 fallback + // 페이징이 필요하면 ID만 먼저 가져온 뒤 별도 쿼리로 fetch +} +``` + +Native query 사용 시: + +```java +@Query(value = """ + SELECT id, title, status, created_at + FROM + WHERE _id = : +""", nativeQuery = true) +List<Projection> findProjectionsByParent( + @Param("") UUID +); +``` + +`SELECT *` 금지. 필요한 컬럼만. + +--- + +## Entity vs DTO 분리 + +```java +// domain/.java — 영속 객체 +@Entity +@Table(name = "") +@Access(AccessType.FIELD) +public class { + + @Id + private UUID id; + + @ManyToOne(fetch = FetchType.LAZY) // ← LAZY가 기본 + @JoinColumn(name = "_id") + private ; + + private String title; + + @Enumerated(EnumType.STRING) + private Status status; + + private UUID createdBy; + + private Instant createdAt; + + protected () {} // JPA 요구사항, protected로 외부 접근 차단 + + public static create( parent, String title, UUID userId) { + e = new (); + e.id = UUID.randomUUID(); + e. = parent; + e.title = title; + e.status = Status.DRAFT; + e.createdBy = userId; + e.createdAt = Instant.now(); + return e; + } + + public boolean isAccessibleBy(UUID userId) { + return this..isMember(userId); + } + + // Setter 없음. 상태 변경은 도메인 메서드(changeStatus 등)로만 +} +``` + +```java +// dto//Response.java — 외부 응답 +public record Response( + UUID id, + UUID , + String title, + String status, + UUID createdBy, + Instant createdAt +) { + public static Response from( entity) { + return new Response( + entity.getId(), + entity.get().getId(), + entity.getTitle(), + entity.getStatus().name(), + entity.getCreatedBy(), + entity.getCreatedAt() + ); + } +} +``` + +규칙: **Entity는 절대로 Controller 시그니처에 등장하지 않음**. + +--- + +## application.yml 기본 설정 + +```yaml +spring: + jpa: + open-in-view: false # ← 반드시 false + hibernate: + ddl-auto: validate # 운영은 validate, 개발도 가급적 update만 + properties: + hibernate: + jdbc.batch_size: 50 + order_inserts: true + order_updates: true + default_batch_fetch_size: 100 # N+1 완화 안전망 + +logging: + level: + org.hibernate.SQL: DEBUG # 개발 환경에서만 + org.hibernate.orm.jdbc.bind: TRACE # 바인드 파라미터 확인 +``` + +`open-in-view: true`(Spring 기본값)는 컨트롤러까지 영속성 컨텍스트가 유지돼서 **숨겨진 N+1 쿼리의 주범**. 무조건 `false`. + +--- + +## API 완성 기준 + +``` +□ 모든 @RequestBody에 DTO + @Valid 적용됨 +□ Entity가 Controller 시그니처에 노출되지 않음 +□ userId는 @AuthenticationPrincipal에서만 추출 +□ Controller에 try/catch 없음 (GlobalExceptionHandler가 처리) +□ Service 메서드에 @Transactional 또는 @Transactional(readOnly=true) 명시 +□ 트랜잭션 내부에 외부 HTTP 호출 / 메시지 발행 없음 +□ 상태 전환은 Entity의 도메인 메서드 통과 (Setter 직접 호출 없음) +□ findById가 fetch join 또는 EntityGraph 명시 (관련 객체 접근 시) +□ Native query에 SELECT * 없음 +□ Optional가 필드 / 파라미터에 사용되지 않음 +□ open-in-view: false 적용됨 +□ 생성자 주입 (필드 주입 @Autowired 없음) +□ Entity에 @Data, @Setter 없음 +``` + +--- + +## Placeholder 치환 가이드 + +| 플레이스홀더 | 의미 | 치환 예시 | +|---|---|---| +| `` | 베이스 패키지 | `com.example.app` | +| `` | 핵심 도메인 객체 (PascalCase) | `Order`, `Asset`, `Bundle` | +| `` | 변수/파일명 (camelCase) | `order`, `asset`, `bundle` | +| `` | URL 경로 / 테이블명 | `orders`, `assets`, `bundles` | +| `` | ID 변수명 | `orderId`, `assetId` | +| `` | 상위 엔티티 | `Project`, `Workspace`, `Task` | +| `` | 상위 엔티티 변수명 | `project`, `workspace` | +| `` | 상위 엔티티 ID | `projectId`, `taskId` | +| `` | 하위 엔티티 | `Revision`, `Comment`, `Item` | +| `` | 하위 컬렉션 필드명 | `revisions`, `comments` | +| `` | 연결 엔티티 | `Intent`, `Source`, `Tag` | +| `` | 액션 이름 | `Dispatch`, `Approve`, `Submit` | \ No newline at end of file diff --git a/.claude/skills/design-principles/SKILL.md b/.claude/skills/design-principles/SKILL.md new file mode 100644 index 0000000..963e6cf --- /dev/null +++ b/.claude/skills/design-principles/SKILL.md @@ -0,0 +1,244 @@ +--- +name: design-principles +description: "Use this skill when designing class structures, refactoring code for maintainability, evaluating coupling and cohesion, or applying SOLID principles. Triggers on SOLID, refactoring, design pattern, coupling, cohesion, single responsibility, dependency injection, interface segregation keywords." +--- + +# 설계 원칙 — SOLID & 결합도/응집도 + +## 핵심 방향 + +``` +결합도는 낮게 (모듈 간 의존 최소화) +응집도는 높게 (하나의 모듈 = 하나의 책임) +``` + +--- + +## 절대 쓰지 말 것 + +``` +- 전역 변수로 모듈 간 상태 공유 (공통 결합) +- public 필드 직접 접근 (내용 결합) +- boolean 플래그를 함수 인자로 넘겨 내부 분기 제어 (제어 결합) +- 하나의 클래스에서 저장 + 출력 + 계산 동시 처리 (단일책임 위반) +- 부모 클래스 메서드를 자식이 throw로 막기 (리스코프 위반) +- 쓰지 않는 인터페이스 메서드를 구현 강제 (인터페이스 분리 위반) +- 고수준 모듈 안에서 저수준 구현체 직접 new (의존역전 위반) +- 새 기능 추가 시 기존 함수 내부 수정 (개방폐쇄 위반) +``` + +--- + +## 결합도 — 나쁜 것부터 좋은 것 순서 + +| 등급 | 이름 | 특징 | 대처 | +|---|---|---|---| +| 최악 | 내용 결합 | 다른 모듈 내부 필드 직접 수정 | private + getter/setter | +| 나쁨 | 공통 결합 | 전역 변수 공유 | 생성자 주입으로 교체 | +| 나쁨 | 제어 결합 | boolean 플래그로 흐름 제어 | 함수 분리 또는 전략 패턴 | +| 보통 | 외부 결합 | 외부 자료구조 직접 참조 | 자료 결합으로 낮추기 | +| 보통 | 스탬프 결합 | 객체 전체를 넘김 | 필요한 필드만 추출해서 넘기기 | +| 좋음 | 자료 결합 | 기본 자료형만 주고받기 | 목표 상태 | + +--- + +## 제어 결합 — 가장 자주 실수하는 패턴 + +**잘못된 것:** + +```java +// boolean 플래그가 함수 내부 흐름을 결정 +.(, true); // true가 뭔지 호출부에서 알 수 없음 + +public void ([] , boolean ) { + if () { System.out.println("started"); } + // ... + if () { System.out.println("done"); } +} +``` + +**올바른 것:** + +```java +// 부가 책임은 별도 클래스가 담당 +public class { + public void ([] ) { /* 순수 처리만 */ } +} + +public class WithLogging { + private ; + public void ([] ) { + System.out.println("started"); + .(); + System.out.println("done"); + } +} +``` + +→ **함수에 boolean 인자가 있으면 제어 결합 의심**. 함수를 두 개로 나누거나 래퍼 클래스를 만들 것. + +--- + +## 응집도 — 낮은 것부터 높은 것 순서 + +| 등급 | 이름 | 특징 | +|---|---|---| +| 최악 | 우연적 | 연관 없는 기능들이 한 클래스에 | +| 나쁨 | 논리적 | switch/if로 유사한 기능 묶음 | +| 보통 | 시간적 | 초기화처럼 "같은 시점"에 실행 | +| 보통 | 절차적 | 순서대로 여러 기능 호출 | +| 좋음 | 교환적 | 같은 입력을 다른 방식으로 처리 | +| 좋음 | 순차적 | 이전 출력이 다음 입력으로 연결 | +| 최고 | 기능적 | 단 하나의 목적만 | + +--- + +## 논리적 응집도 — switch/if가 신호 + +**잘못된 것:** + +```java +// 새 타입 추가마다 이 함수를 수정해야 함 → 개방폐쇄 원칙 위반 +public void ( type, payload) { + switch (type) { + case : (payload); break; + case : (payload); break; + case : (payload); break; + } +} +``` + +**올바른 것:** + +```java +// 타입 추가 시 새 클래스만 추가, 기존 코드 수정 없음 +interface { void handle( payload); } + +class implements { ... } +class implements { ... } +class implements { ... } + +// 호출부 + handler = registry.resolve(type); +handler.handle(payload); +``` + +→ **switch/if로 타입 분기 중이면 인터페이스 분리 + 전략 패턴 적용** 검토. + +--- + +## SOLID — 위반 신호와 대처 + +### S — 단일 책임 + +``` +위반 신호: 하나의 클래스가 계산도 하고, 출력도 하고, DB 저장도 함 +대처: 역할별로 클래스 분리 + ( / / ) +``` + +### O — 개방 폐쇄 + +``` +위반 신호: 새 기능 추가할 때 기존 함수 내부를 열어서 else if 추가 +대처: 인터페이스 하나 만들고 새 클래스로 확장 (기존 코드 수정 없이) +``` + +### L — 리스코프 대체 + +``` +위반 신호: 자식 클래스의 오버라이드 메서드가 throw 던짐 +대처: 인터페이스를 분리, 불가능한 동작은 처음부터 계약에 넣지 않기 +``` + +```java +// 잘못된 것 +class extends { + @Override + public void () { throw new UnsupportedOperationException(); } +} + +// 올바른 것 +interface { void (); } +interface extends { void (); } +class implements { ... } +class implements { ... } +``` + +### I — 인터페이스 분리 + +``` +위반 신호: implements 후 일부 메서드를 빈 구현이나 throw로 채움 +대처: 인터페이스를 쪼갬. 클라이언트가 쓰는 메서드만 계약에 포함 +``` + +```java +// 잘못된 것 +class implements { + public void () { + throw new UnsupportedOperationException(); + } +} + +// 올바른 것 +interface { void (); } +interface { void (); } +class implements { ... } // 강제 없음 +class implements , { ... } +``` + +### D — 의존 역전 + +``` +위반 신호: 고수준 클래스 생성자 안에서 new <저수준구현체>() 직접 생성 +대처: 인터페이스에 의존, 구현체는 생성자 주입으로 외부에서 받기 +``` + +```java +// 잘못된 것 +class { + private = new (); +} + +// 올바른 것 +class { + private ; + public ( ) { + this. = ; + } +} +``` + +--- + +## 설계 완성 기준 + +``` +□ 함수 인자에 boolean 플래그가 없음 (제어 결합 없음) +□ public 필드가 없음, 모든 접근은 메서드 경유 (내용 결합 없음) +□ 전역 변수 없음, 상태는 생성자 주입으로 전달 (공통 결합 없음) +□ 하나의 클래스 = 하나의 책임 (계산/출력/저장 분리됨) +□ 새 타입 추가 시 기존 함수를 수정하지 않아도 됨 (switch 분기 없음) +□ 자식 클래스 메서드가 throw를 던지지 않음 +□ implements한 인터페이스의 모든 메서드를 실제로 구현함 +□ 고수준 클래스 안에서 new <저수준구현체>() 없음 +``` + +--- + +## Placeholder 치환 가이드 + +| 플레이스홀더 | 의미 | 치환 예시 | +|---|---|---| +| `` | 처리 클래스 | `OrderProcessor`, `Validator` | +| `` | 처리 메서드 | `process`, `validate`, `compute` | +| `` | 데이터 타입 | `int`, `Order`, `Record` | +| `` | 핸들러 인터페이스 | `MessageSender`, `EventHandler` | +| `` | 분기 enum | `MessageType`, `EventType` | +| `` | enum 멤버 | `EMAIL/SMS/PUSH` | +| `` | 베이스 인터페이스 | `Bird`, `Worker`, `Vehicle` | +| `` | 능력 추가 인터페이스 | `FlyingBird`, `EatableWorker` | +| `` | 구현 클래스 | `Sparrow`, `RobotWorker` | +| `` | 의존하는 쪽 | `Computer`, `App` | +| `` | 의존받는 인터페이스 | `InputDevice`, `Logger` | +| `` | 구체 구현체 | `Keyboard`, `FileLogger` | \ No newline at end of file diff --git a/.claude/skills/frontend-react/SKILL.md b/.claude/skills/frontend-react/SKILL.md new file mode 100644 index 0000000..86651c6 --- /dev/null +++ b/.claude/skills/frontend-react/SKILL.md @@ -0,0 +1,189 @@ +--- +name: frontend-react +description: "Use this skill when writing or reviewing React components, Next.js pages, or TypeScript frontend code. Covers component composition rules, props discipline, event handler naming, loading/error states, mock data patterns, and styling conventions. Triggers on React, Next.js, TSX, JSX, component, frontend, Tailwind keywords." +--- + +# React 컴포넌트 규칙 + +## 5개 핵심 규칙 + +``` +1. 컴포넌트 하나당 파일 하나 +2. 데이터를 직접 fetch하지 말 것 — props로만 받기 +3. 버튼 onClick은 반드시 props로 받기 (내부에서 API 호출 금지) +4. useState는 최대한 위로 올리기 (페이지 레벨에서 관리) +5. 파일명 = 컴포넌트명 (Card.tsx, Panel.tsx) +``` + +--- + +## 절대 쓰지 말 것 + +``` +- any 타입 +- useEffect 안에서 fetch +- 컴포넌트 안에서 router.push 직접 호출 +- console.log (디버깅 후 반드시 제거) +- 인라인 스타일 (style={{ }}) — Tailwind 클래스만 +- 파일 안에 타입 직접 선언 (types/index.ts에서 import) +``` + +--- + +## 올바른 컴포넌트 패턴 + +**잘못된 것:** + +```tsx +// Card.tsx +export function Card({ }) { + const [, set] = useState(null); + + useEffect(() => { + fetch(`/api//${}`) // ← API 직접 호출 금지 + .then(r => r.json()) + .then(set); + }, []); + + return ( +

+ ); +} +``` + +**올바른 것:** + +```tsx +// Card.tsx — 데이터는 props, 액션은 콜백 +import { } from '@/types'; + +type Props = { + name: string; + status: ['status']; + revision: string; + isLoading: boolean; + error: string | null; + onClick: () => void; // 내부에서 뭘 할지 모름, 위에서 결정 +}; + +export function Card({ name, status, revision, isLoading, error, onClick }: Props) { + if (isLoading) return
로딩 중...
; + if (error) return
{error}
; + + return ( +
+ {name} + + {revision} +
+ ); +} +``` + +API 연결은 페이지 레벨에서만: + +```tsx +// app//page.tsx — API는 여기서만 +const = await fetchList(); + +<Card + name={.name} + status={.status} + revision={`v${.version}`} + isLoading={isLoading} + error={error} + onClick={() => router.push(`//${.id}`)} +/> +``` + +--- + +## 이벤트 핸들러 네이밍 + +``` +컨벤션: on + 명사 + 동사 + +onClick ← 클릭 +onApprove ← 승인 버튼 +onRequestChanges ← 변경 요청 +onCopy ← 복사 버튼 +onResolve ← 댓글 resolve +``` + +--- + +## 로딩/에러 슬롯 — 반드시 포함 + +모든 컴포넌트 props에 아래 두 개 포함: + +```tsx +type Props = { + isLoading: boolean; + error: string | null; + // ... 나머지 +}; + +if (isLoading) return
로딩 중...
; +if (error) return
{error}
; +``` + +--- + +## 목업 데이터 — 파일 하나로 통일 + +```tsx +// mocks/index.ts +import { , , } from '@/types'; + +export const mock: = { + id: '-001', + : '-001', + title: '<예시 제목>', + status: 'in_review', + createdBy: 'user-001', + createdAt: '2026-04-14T10:00:00Z', +}; + +export const mock: = { + id: '-001', + projectId: 'project-001', + title: '<예시 제목>', + assigneeId: 'user-001', + startDate: '2026-04-14', + endDate: '2026-04-27', + status: 'in_progress', +}; +``` + +컴포넌트 안에 하드코딩 금지. 무조건 이 파일에서 import. + +--- + +## 컴포넌트 완성 기준 + +아래 네 개 체크 후 개발자에게 알릴 것: + +``` +□ props 타입 정의됨 (types/index.ts에서 import) +□ 로딩/에러 상태 처리됨 +□ 목업 데이터로 렌더링 확인됨 +□ lint/형식 위반 없음 (any 타입, 인라인 스타일 등) +``` + +--- + +## Placeholder 치환 가이드 + +| 플레이스홀더 | 의미 | 치환 예시 | +|---|---|---| +| `` | 컴포넌트 대상 (PascalCase) | `Order`, `Asset`, `Post` | +| `` | 변수/파일명 (camelCase) | `order`, `asset`, `post` | +| `` | 라우트 경로 (복수형) | `orders`, `assets`, `posts` | +| `` | ID prop 이름 | `orderId`, `assetId` | +| `` | 상위 엔티티 | `Project`, `Workspace` | +| `` | 상위 엔티티 ID | `projectId`, `workspaceId` | +| `` | 연관 엔티티 | `Comment`, `Tag`, `Review` | +| `` | 하위 엔티티 (네이밍용) | `Comment`, `Item` | +| `` | 액션 동사 (PascalCase) | `Submit`, `Cancel`, `Share` | \ No newline at end of file diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100644 index 0000000..d2bf137 --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +# Cross-Review Loop pre-commit hook +# fail-open 원칙: 의존성 없거나 파일 없으면 통과 + +set -uo pipefail + +# 1. .review 디렉토리 없으면 통과 (초기 커밋 / 사이클 시작 전) +[ ! -d ".review" ] && exit 0 + +# 2. 가장 최근 사이클 찾기 +CURRENT_CYCLE=$(ls .review/ 2>/dev/null | sort -V | tail -1) +[ -z "$CURRENT_CYCLE" ] && exit 0 + +# 3. 사이클 횟수 검증 (3회 초과 차단) +CYCLE_COUNT=$(ls .review/ 2>/dev/null | wc -l) +if [ "$CYCLE_COUNT" -gt 3 ]; then + echo "❌ Cross-review 사이클 $CYCLE_COUNT 회 — 한도 초과" + echo " 사용자 결정 필요. 강제 커밋: git commit --no-verify" + exit 1 +fi + +# 4. status.txt 확인 +STATUS_FILE=".review/$CURRENT_CYCLE/status.txt" +[ ! -f "$STATUS_FILE" ] && exit 0 # 파일 없으면 통과 + +STATUS=$(cat "$STATUS_FILE" 2>/dev/null | tr -d '[:space:]') +if [ "$STATUS" != "ready_to_merge" ]; then + echo "❌ 사이클 $CURRENT_CYCLE 상태: '$STATUS'" + echo " 교차 검증 미완료. 'ready_to_merge' 상태에서만 커밋 가능." + echo " 강제 커밋: git commit --no-verify" + exit 1 +fi + +echo "✅ Cross-review 통과 (cycle: $CURRENT_CYCLE)" +exit 0 \ No newline at end of file diff --git a/.github/workflows/cross-review.yml b/.github/workflows/cross-review.yml new file mode 100644 index 0000000..3ba5cea --- /dev/null +++ b/.github/workflows/cross-review.yml @@ -0,0 +1,25 @@ +name: Cross-Model Review +on: + pull_request: + types: [opened, synchronize] + +jobs: + codex-review: + if: contains(github.event.pull_request.labels.*.name, 'claude-generated') + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Run Codex review against plan.md + run: | + codex review \ + --plan plan.md \ + --diff "$(git diff origin/main)" \ + --output review.md \ + --criteria "Sprint Contract 만족 / 자동 체크 통과 / plan.md 외 변경사항" + - name: Block merge if issues found + run: | + if grep -q "ISSUE FOUND" review.md; then + gh pr comment ${{ github.event.pull_request.number }} \ + --body-file review.md + exit 1 + fi \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7b016a8 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.compile.nullAnalysis.mode": "automatic" +} \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..6981540 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,50 @@ +# Architecture +Web2, java spring backend - JDK 17, expo,react native frontend,r2 storage,supabase +# Conventions + +# Commands + +# prohibited pattern + +## 금지 - basic +- critical한 파일 임의 수정 금지 + +## 금지 — Backend +- req.body 직접 DB, userId from body +- any 타입, 에러 raw throw + +## 금지 — Frontend +- useEffect 안 fetch, 인라인 스타일 + +# Testing & Verify + +# Past Failures -> Rules +- 실패/의도와 다른 에러 발생 시 여기에 한줄씩 추가 + +## Review Protocol + +- plan.md 작성 시 다음 항목 필수 포함: + 1. 입력/출력 명세 + 2. Sprint Contract — 통과 기준 (테스트 케이스, gas 한도, slither 통과) + 3. 누락된 엣지 케이스 후보 3개 + 4. 더 단순한 대안 1개 + +- Generate 완료 후 별도 세션에서 호출됨. 검증 항목: + 1. plan.md Sprint Contract 만족 여부 (의미 수준) + 2. 자동 체크(test/lint/slither) 통과 여부 + 3. plan.md에 없던 변경사항 식별 + +- issue 발견 시 PR 머지 차단, Claude Code 세션 재개 트리거. + +# Re-review Protocol + +review.md 작성 시 버전 표기 필수: +- 첫 검증: review.md (Pass 1) +- 재검증: review.md에 "## Re-review" 섹션 append (Pass 3) + +재검증 항목: +1. 이전 issue가 RESOLVED 표기되어 있고 실제로 수정됐는지 확인 +2. 수정 과정에서 새로 도입된 회귀 이슈 식별 +3. plan.md Sprint Contract 만족 여부 재확인 + +재검증에서 issue 발견 시 "REGRESSION" 또는 "UNRESOLVED" 라벨 명시. \ No newline at end of file From b6946fbc8ff00f93922181ff6c534bd787614ee9 Mon Sep 17 00:00:00 2001 From: lejuho Date: Sat, 25 Apr 2026 14:56:33 +0900 Subject: [PATCH 89/92] chore : review out of git tracking --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index d914c32..7e96104 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,6 @@ yarn-error.* # generated native folders /ios /android + + +.review/ From 4b31e2da7db874640c7b1c18b3b6f8f9b7e52684 Mon Sep 17 00:00:00 2001 From: lejuho Date: Sat, 25 Apr 2026 15:54:31 +0900 Subject: [PATCH 90/92] refactor : notification read method modify --- src/apis/home/homeApi.ts | 5 ++ src/apis/missions/missionApi.ts | 6 ++ src/components/home/HomeAlertsModal.tsx | 31 +++---- src/hooks/home/useHomeApi.ts | 81 ++++++++++--------- src/hooks/mission/useMissionApi.ts | 11 +++ .../DailyMissionWriteDiaryScreen.tsx | 37 +++------ src/pages/profile/ProfileScreen.tsx | 15 ++++ src/types/missions/index.ts | 11 +++ 8 files changed, 114 insertions(+), 83 deletions(-) diff --git a/src/apis/home/homeApi.ts b/src/apis/home/homeApi.ts index 2d4c5e4..a986788 100644 --- a/src/apis/home/homeApi.ts +++ b/src/apis/home/homeApi.ts @@ -52,6 +52,11 @@ export const patchNotificationRead = async (notificationId: number) => { return res.data; }; +export const patchAllNotificationsRead = async () => { + const res = await api.patch("/api/v1/notifications/read-all"); + return res.data; +}; + export const getGuestbookList = async ( userId: number ): ApiResponse => { diff --git a/src/apis/missions/missionApi.ts b/src/apis/missions/missionApi.ts index 3f3a9ab..b5f926c 100644 --- a/src/apis/missions/missionApi.ts +++ b/src/apis/missions/missionApi.ts @@ -8,6 +8,7 @@ import type { GetDailySurveyResponse, GetQuizRequest, GetQuizResponse, + GetTodayKeywordResponse, WriteDiaryRequest, WriteDiaryResponse, } from "@/types/missions"; @@ -31,6 +32,11 @@ export const writeDiaryApi = async ( return res.data; }; +export const getTodayKeywordApi = async (): Promise => { + const res = await api.get("/api/v1/keywords/today"); + return res.data; +}; + export const getQuizApi = async ( params: GetQuizRequest ): Promise => { diff --git a/src/components/home/HomeAlertsModal.tsx b/src/components/home/HomeAlertsModal.tsx index 4952535..a138d42 100644 --- a/src/components/home/HomeAlertsModal.tsx +++ b/src/components/home/HomeAlertsModal.tsx @@ -31,7 +31,10 @@ export default function HomeAlertsModal({ onClose: () => void; }) { const [activeTab, setActiveTab] = useState("GUESTBOOK"); - const [hasMarkedRecordAsReadThisOpen, setHasMarkedRecordAsReadThisOpen] = useState(false); + const [ + hasMarkedNotificationsAsReadThisOpen, + setHasMarkedNotificationsAsReadThisOpen, + ] = useState(false); const openTimingRef = useRef | null>(null); const notificationsQuery = useNotifications(visible); const guestbookQuery = useGuestbookList(userId, visible); @@ -63,35 +66,19 @@ export default function HomeAlertsModal({ useEffect(() => { if (!visible) { - setHasMarkedRecordAsReadThisOpen(false); + setHasMarkedNotificationsAsReadThisOpen(false); openTimingRef.current = null; return; } - if (activeTab !== "RECORD" || hasMarkedRecordAsReadThisOpen) { + if (hasMarkedNotificationsAsReadThisOpen) { return; } - if (notificationsQuery.isLoading || !notificationsQuery.data) { - return; - } - - const unreadNotificationIds = notificationsQuery.data - .filter(item => !isNotificationRead(item)) - .map(item => item.id); - - setHasMarkedRecordAsReadThisOpen(true); - - if (unreadNotificationIds.length === 0) { - return; - } - - void readNotificationsMutation.mutateAsync(unreadNotificationIds); + setHasMarkedNotificationsAsReadThisOpen(true); + void readNotificationsMutation.mutateAsync(); }, [ - activeTab, - hasMarkedRecordAsReadThisOpen, - notificationsQuery.data, - notificationsQuery.isLoading, + hasMarkedNotificationsAsReadThisOpen, readNotificationsMutation, visible, ]); diff --git a/src/hooks/home/useHomeApi.ts b/src/hooks/home/useHomeApi.ts index 6ae6a78..4d90d2f 100644 --- a/src/hooks/home/useHomeApi.ts +++ b/src/hooks/home/useHomeApi.ts @@ -6,7 +6,7 @@ import { getHomeSummary, getNotifications, getTrackingPromptStatus, - patchNotificationRead, + patchAllNotificationsRead, postGardenMyWater, postGardenSunlight, postTrackingPromptConfirm, @@ -81,55 +81,64 @@ export const useReadNotifications = () => { const queryClient = useQueryClient(); return useMutation({ - mutationFn: async (notificationIds: number[]) => { - await Promise.all( - notificationIds.map(notificationId => patchNotificationRead(notificationId)) - ); - }, - onSuccess: async (_, notificationIds) => { + mutationFn: patchAllNotificationsRead, + onMutate: async () => { + await Promise.all([ + queryClient.cancelQueries({ queryKey: ["notifications"] }), + queryClient.cancelQueries({ queryKey: ["home-summary"] }), + ]); + + const previousNotifications = + queryClient.getQueryData>(["notifications"]); + const previousHomeSummary = + queryClient.getQueryData>(["home-summary"]); + queryClient.setQueryData>( ["notifications"], previous => previous ? { ...previous, - result: previous.result.map(item => - notificationIds.includes(item.id) - ? { ...item, isRead: true, read: true } - : item - ), + result: previous.result.map(item => ({ + ...item, + isRead: true, + read: true, + })), } : previous ); queryClient.setQueryData>( ["home-summary"], - previous => { - if (!previous) { - return previous; - } - - const unreadDelta = previous.result.userInfo.unreadNotificationCount; - const nextUnreadCount = Math.max( - 0, - unreadDelta - notificationIds.length - ); - - return { - ...previous, - result: { - ...previous.result, - userInfo: { - ...previous.result.userInfo, - unreadNotificationCount: nextUnreadCount, - }, - }, - }; - } + previous => + previous + ? { + ...previous, + result: { + ...previous.result, + userInfo: { + ...previous.result.userInfo, + unreadNotificationCount: 0, + }, + }, + } + : previous ); - await queryClient.invalidateQueries({ queryKey: ["notifications"] }); - await queryClient.invalidateQueries({ queryKey: ["home-summary"] }); + return { previousNotifications, previousHomeSummary }; + }, + onError: (_error, _variables, context) => { + if (context?.previousNotifications) { + queryClient.setQueryData(["notifications"], context.previousNotifications); + } + + if (context?.previousHomeSummary) { + queryClient.setQueryData(["home-summary"], context.previousHomeSummary); + } + }, + onSettled: () => { + void queryClient.invalidateQueries({ queryKey: ["notifications"] }); + void queryClient.invalidateQueries({ queryKey: ["home-summary"] }); }, }); }; diff --git a/src/hooks/mission/useMissionApi.ts b/src/hooks/mission/useMissionApi.ts index 7259ba5..2b71567 100644 --- a/src/hooks/mission/useMissionApi.ts +++ b/src/hooks/mission/useMissionApi.ts @@ -4,6 +4,7 @@ import { answerQuizApi, getDailySurveyApi, getQuizApi, + getTodayKeywordApi, uploadDiaryImageApi, writeDiaryApi, } from "@/apis/missions/missionApi"; @@ -17,7 +18,9 @@ import type { GetDailySurveyResponse, GetQuizRequest, GetQuizResponse, + GetTodayKeywordResponse, MissionQuiz, + TodayKeyword, WriteDiaryRequest, WriteDiaryResponse, } from "@/types/missions"; @@ -35,6 +38,14 @@ export const useWriteDiarySubmit = () => mutationFn: payload => writeDiaryApi(payload), }); +export const useTodayKeyword = () => + useQuery({ + queryKey: ["today-keyword"], + queryFn: getTodayKeywordApi, + select: data => data.result, + staleTime: 5 * 60_000, + }); + export const useMissionQuiz = (params: GetQuizRequest) => useQuery({ queryKey: ["mission-quiz", params.quizType], diff --git a/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx b/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx index b445b24..9a35d38 100644 --- a/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx +++ b/src/pages/dailyMission/DailyMissionWriteDiaryScreen.tsx @@ -7,17 +7,18 @@ import ScreenHeader from "@/components/common/ScreenHeader"; import CheckIcon from "@/assets/icons/Check.svg"; import Check2Icon from "@/assets/icons/Check2.svg"; import ImageAttachmentCard from "@/components/dailyMission/ImageAttachmentCard"; -import { useWriteDiaryImageUpload, useWriteDiarySubmit } from "@/hooks/mission/useMissionApi"; +import { + useTodayKeyword, + useWriteDiaryImageUpload, + useWriteDiarySubmit, +} from "@/hooks/mission/useMissionApi"; import type { RootStackScreenProps } from "@/navigation/types"; type Props = RootStackScreenProps<"DailyMissionWriteDiary">; -// 임시 하드코딩 힌트 문구 (추후 백엔드 API 연결 예정) -const HINT_KEYWORD = "내 식물의 겨울나기"; -const HINT_SUFFIX = "에 대해서\n이야기해보는 건 어때요?"; - export default function DailyMissionWriteDiaryScreen({ navigation }: Props) { const queryClient = useQueryClient(); + const { data: todayKeyword } = useTodayKeyword(); const [title, setTitle] = useState(""); const [content, setContent] = useState(""); const [isPublic, setIsPublic] = useState(false); @@ -127,6 +128,11 @@ export default function DailyMissionWriteDiaryScreen({ navigation }: Props) { month: "long", day: "numeric", }); + const keyword = todayKeyword?.keyword.trim(); + const contentPlaceholder = + keyword && !keyword.includes("없습니다") && !keyword.includes("실패") + ? `${keyword}에 대해 이야기 해보는 건 어때요?` + : "오늘 식물에게 있었던 일을 적어주세요"; return ( @@ -168,19 +174,13 @@ export default function DailyMissionWriteDiaryScreen({ navigation }: Props) { - {/* AI 글쓰기 힌트 문구 (추후 백엔드 API 연결 예정) */} - - {HINT_KEYWORD} - {HINT_SUFFIX} - - {/* 공개 여부 선택 */} garden.gardenId === gardenId); + if (!targetGarden?.isWateringAbleByMe) { + setToastMessage( + data.leftWaterCountForOthers <= 0 + ? "오늘 줄 수 있는 친구 물주기를 모두 사용했어요." + : "오늘은 이미 물을 주었습니다." + ); + return; + } + const finishActionTiming = createTimingLogger("ProfileScreen", "friend water action", { userId, gardenId, diff --git a/src/types/missions/index.ts b/src/types/missions/index.ts index 333aa65..828907f 100644 --- a/src/types/missions/index.ts +++ b/src/types/missions/index.ts @@ -35,6 +35,17 @@ export interface WriteDiaryResponse { result: string; } +export interface TodayKeyword { + keyword: string; +} + +export interface GetTodayKeywordResponse { + isSuccess: boolean; + code: string; + message: string; + result: TodayKeyword; +} + export interface QuizOption { optionOrder: number; optionText: string; From 9b418acf65e1c7eadc5679d5b65a91037bc9963e Mon Sep 17 00:00:00 2001 From: lejuho Date: Sun, 26 Apr 2026 03:22:32 +0900 Subject: [PATCH 91/92] =?UTF-8?q?feat=20:=20=ED=83=88=ED=87=B4=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/option/userApi.ts | 7 +++++ src/hooks/option/useDeleteAccount.ts | 15 +++++++++++ src/pages/option/OptionScreen.tsx | 40 ++++++++++++++++++++++++++++ src/utils/auth.ts | 18 ++++++++----- 4 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 src/apis/option/userApi.ts create mode 100644 src/hooks/option/useDeleteAccount.ts diff --git a/src/apis/option/userApi.ts b/src/apis/option/userApi.ts new file mode 100644 index 0000000..5194831 --- /dev/null +++ b/src/apis/option/userApi.ts @@ -0,0 +1,7 @@ +import api from "@/apis/instance"; +import type { ApiResponse, NoResponse } from "@/types/common/apiResponse.type"; + +export const deleteMeApi = async (): ApiResponse => { + const res = await api.delete("/api/v1/users/me"); + return res.data; +}; diff --git a/src/hooks/option/useDeleteAccount.ts b/src/hooks/option/useDeleteAccount.ts new file mode 100644 index 0000000..efdb1d0 --- /dev/null +++ b/src/hooks/option/useDeleteAccount.ts @@ -0,0 +1,15 @@ +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { deleteMeApi } from "@/apis/option/userApi"; +import { clearLocalSession } from "@/utils/auth"; + +export const useDeleteAccount = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: deleteMeApi, + onSuccess: async () => { + await clearLocalSession(); + queryClient.clear(); + }, + }); +}; diff --git a/src/pages/option/OptionScreen.tsx b/src/pages/option/OptionScreen.tsx index f3f4485..ff19f60 100644 --- a/src/pages/option/OptionScreen.tsx +++ b/src/pages/option/OptionScreen.tsx @@ -10,6 +10,7 @@ import { import ConfirmModal from "@/components/common/ConfirmModal"; import ScreenHeader from "@/components/common/ScreenHeader"; import { useNotificationSettings, useUpdateNotificationSettings } from "@/hooks/option/useNotificationApi"; +import { useDeleteAccount } from "@/hooks/option/useDeleteAccount"; import useTokenStore from "@/stores/useTokenStore"; import { logout } from "@/utils/auth"; import { registerDeviceFcmToken, unregisterDeviceFcmToken } from "@/utils/fcm"; @@ -19,9 +20,11 @@ type Props = MainTabScreenProps<"Option">; export default function OptionScreen({ navigation }: Props) { const [isLoggingOut, setIsLoggingOut] = useState(false); const [isLogoutConfirmVisible, setIsLogoutConfirmVisible] = useState(false); + const [isDeleteConfirmVisible, setIsDeleteConfirmVisible] = useState(false); const { accessToken, userId, hasHydrated } = useTokenStore(); const { data: notificationSettings } = useNotificationSettings(); const updateSettingsMutation = useUpdateNotificationSettings(); + const deleteAccountMutation = useDeleteAccount(); const pushNotification = notificationSettings?.notificationEnabled ?? true; const marketingConsent = notificationSettings?.marketingConsent ?? false; @@ -65,6 +68,27 @@ export default function OptionScreen({ navigation }: Props) { setIsLogoutConfirmVisible(true); }; + const handleDeleteAccount = () => { + if (deleteAccountMutation.isPending || !accessToken) { + return; + } + + setIsDeleteConfirmVisible(true); + }; + + const handleConfirmDeleteAccount = () => { + if (deleteAccountMutation.isPending || !accessToken) { + return; + } + + setIsDeleteConfirmVisible(false); + deleteAccountMutation.mutate(undefined, { + onError: () => { + Alert.alert("회원 탈퇴 실패", "회원 탈퇴에 실패했습니다. 잠시 후 다시 시도해주세요."); + }, + }); + }; + const handleConfirmLogout = async () => { if (isLoggingOut || !accessToken) { return; @@ -105,6 +129,12 @@ export default function OptionScreen({ navigation }: Props) { disabled={!hasHydrated || !accessToken || isLoggingOut} onPress={handleLogout} /> + {loginStatus} @@ -122,6 +152,16 @@ export default function OptionScreen({ navigation }: Props) { onCancel={() => setIsLogoutConfirmVisible(false)} onConfirm={() => void handleConfirmLogout()} /> + setIsDeleteConfirmVisible(false)} + onConfirm={handleConfirmDeleteAccount} + /> ); } diff --git a/src/utils/auth.ts b/src/utils/auth.ts index 9542258..86feaa8 100644 --- a/src/utils/auth.ts +++ b/src/utils/auth.ts @@ -1,6 +1,16 @@ import { supabase } from "@/apis/supabase"; import useTokenStore from "@/stores/useTokenStore"; +export const clearLocalSession = async () => { + useTokenStore.getState().clearTokens(); + + try { + await supabase.auth.signOut(); + } catch (error) { + console.error("[auth] Failed to clear Supabase session:", error); + } +}; + export const logout = async () => { const { accessToken } = useTokenStore.getState(); @@ -19,11 +29,5 @@ export const logout = async () => { } } - useTokenStore.getState().clearTokens(); - - try { - await supabase.auth.signOut(); - } catch (error) { - console.error("[auth] Failed to clear Supabase session:", error); - } + await clearLocalSession(); }; From 22d3218ef5bdf04583a80a8861c67ee5f13b6fea Mon Sep 17 00:00:00 2001 From: lejuho Date: Mon, 27 Apr 2026 21:08:10 +0900 Subject: [PATCH 92/92] fix : expo sdk rollback --- README.md | 26 +- app.json | 4 +- package-lock.json | 1137 +++++++++++++++++++++++++++++---------------- package.json | 6 +- src/utils/fcm.ts | 12 +- 5 files changed, 764 insertions(+), 421 deletions(-) diff --git a/README.md b/README.md index 892fe40..a7918d4 100644 --- a/README.md +++ b/README.md @@ -19,14 +19,14 @@ React Native (Expo) 기반 모바일 애플리케이션 ### 1. 사전 요구사항 ```bash -# Node.js 버전 확인 (18.x 이상 권장) +# Node.js 버전 확인 (20.19.x 이상 권장) node -v # npm 버전 확인 npm -v ``` -Node.js가 설치되어 있지 않다면 [nodejs.org](https://nodejs.org)에서 LTS 버전을 설치하세요. +Node.js 20.19.x 이상을 권장합니다. [nodejs.org](https://nodejs.org)에서 LTS 버전(20 또는 22)을 설치하세요. --- @@ -45,31 +45,37 @@ npm install ### 3. 개발 서버 실행 -이거 권장 -> WIFI 같지 않아도 됨. (규영) -npx expo start --clear --tunnel - +#### Expo Go 경로 (Apple Developer 계정 불필요) ```bash -npx expo start +# 터널 모드: PC와 iPhone이 같은 Wi-Fi가 아니어도 연결됩니다 +npx expo start --tunnel --clear ``` -실행 후 터미널에 QR 코드가 표시됩니다. +#### Development Build 경로 (native 모듈 개발 시) + +`expo-dev-client` 가 제거된 상태입니다. `expo run:android / expo run:ios` 개발 빌드가 필요한 경우 +`npx expo install expo-dev-client` 후 `app.json` plugins에 `"expo-dev-client"` 를 다시 추가하세요. --- ### 4. 앱 실행 방법 -#### 방법 A: 실제 기기 (권장) +#### 방법 A: 실제 기기 — Expo Go (권장, 계정 불필요) 1. **Expo Go 앱 설치** - Android: [Play Store](https://play.google.com/store/apps/details?id=host.exp.exponent) - iOS: [App Store](https://apps.apple.com/app/expo-go/id982107779) -2. **QR 코드 스캔** +2. **서버 실행 후 QR 코드 스캔** + ```bash + npx expo start --tunnel --clear + ``` - Android: Expo Go 앱 내에서 직접 스캔 - iOS: 기본 카메라 앱으로 스캔 후 링크 터치 -> **주의**: PC와 휴대폰이 **같은 Wi-Fi 네트워크**에 연결되어 있어야 합니다. +> **터널 모드**: PC와 iPhone이 **같은 Wi-Fi가 아니어도** 연결됩니다. +> Expo Go에서 `Project is incompatible`가 뜨면 프로젝트 SDK와 스토어 Expo Go 지원 SDK가 맞는지 확인하세요. #### 방법 B: 에뮬레이터 (선택사항) diff --git a/app.json b/app.json index 1cd0832..5a2a2b9 100644 --- a/app.json +++ b/app.json @@ -29,7 +29,6 @@ "favicon": "./assets/favicon.png" }, "plugins": [ - "expo-dev-client", "expo-secure-store", "expo-web-browser", [ @@ -38,7 +37,8 @@ "icon": "./assets/icon.png", "color": "#3AB40B" } - ] + ], + "expo-font" ], "extra": { "eas": { diff --git a/package-lock.json b/package-lock.json index f01c9b7..648c610 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,8 +21,8 @@ "expo": "~54.0.33", "expo-auth-session": "~7.0.10", "expo-crypto": "~15.0.8", - "expo-dev-client": "~6.0.20", "expo-device": "~8.0.10", + "expo-font": "~14.0.11", "expo-image-picker": "~17.0.10", "expo-linking": "~8.0.11", "expo-notifications": "~0.32.16", @@ -35,16 +35,18 @@ "react-native": "0.81.5", "react-native-gesture-handler": "~2.28.0", "react-native-pager-view": "6.9.1", - "react-native-reanimated": "~4.2.1", + "react-native-reanimated": "~4.1.1", "react-native-safe-area-context": "~5.6.0", "react-native-screens": "~4.16.0", "react-native-svg": "15.12.1", "react-native-url-polyfill": "^3.0.0", "react-native-web": "^0.21.0", + "react-native-worklets": "0.5.1", "tailwindcss": "^3.4.17", "zustand": "^5.0.10" }, "devDependencies": { + "@expo/ngrok": "^4.1.3", "@types/react": "~19.1.0", "babel-plugin-module-resolver": "^5.0.2", "react-native-svg-transformer": "^1.5.3", @@ -213,9 +215,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.7", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.7.tgz", - "integrity": "sha512-6Fqi8MtQ/PweQ9xvux65emkLQ83uB+qAVtfHkC9UodyHMIZdxNI01HjLCLUtybElp2KY2XNE0nOgyP1E1vXw9w==", + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.8.tgz", + "integrity": "sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==", "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.28.6", @@ -1397,7 +1399,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1629,9 +1630,9 @@ } }, "node_modules/@expo/config-plugins/node_modules/brace-expansion": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", - "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" @@ -1658,21 +1659,21 @@ } }, "node_modules/@expo/config-plugins/node_modules/lru-cache": { - "version": "11.2.6", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", - "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", "license": "BlueOak-1.0.0", "engines": { "node": "20 || >=22" } }, "node_modules/@expo/config-plugins/node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.5" }, "engines": { "node": "18 || 20 || >=22" @@ -1743,9 +1744,9 @@ } }, "node_modules/@expo/config/node_modules/brace-expansion": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", - "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" @@ -1772,21 +1773,21 @@ } }, "node_modules/@expo/config/node_modules/lru-cache": { - "version": "11.2.6", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", - "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", "license": "BlueOak-1.0.0", "engines": { "node": "20 || >=22" } }, "node_modules/@expo/config/node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.5" }, "engines": { "node": "18 || 20 || >=22" @@ -1917,9 +1918,9 @@ } }, "node_modules/@expo/fingerprint/node_modules/brace-expansion": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", - "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" @@ -1946,12 +1947,12 @@ } }, "node_modules/@expo/fingerprint/node_modules/glob/node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.5" }, "engines": { "node": "18 || 20 || >=22" @@ -1961,9 +1962,9 @@ } }, "node_modules/@expo/fingerprint/node_modules/lru-cache": { - "version": "11.2.6", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", - "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", "license": "BlueOak-1.0.0", "engines": { "node": "20 || >=22" @@ -2007,17 +2008,17 @@ } }, "node_modules/@expo/image-utils": { - "version": "0.8.12", - "resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.8.12.tgz", - "integrity": "sha512-3KguH7kyKqq7pNwLb9j6BBdD/bjmNwXZG/HPWT6GWIXbwrvAJt2JNyYTP5agWJ8jbbuys1yuCzmkX+TU6rmI7A==", + "version": "0.8.13", + "resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.8.13.tgz", + "integrity": "sha512-1I//yBQeTY6p0u1ihqGNDAr35EbSG8uFEupFrIF0jd++h9EWH33521yZJU1yE+mwGlzCb61g3ehu78siMhXBlA==", "license": "MIT", "dependencies": { + "@expo/require-utils": "^55.0.4", "@expo/spawn-async": "^1.7.2", "chalk": "^4.0.0", "getenv": "^2.0.0", "jimp-compact": "0.16.1", "parse-png": "^2.1.0", - "resolve-from": "^5.0.0", "semver": "^7.6.0" } }, @@ -2034,9 +2035,9 @@ } }, "node_modules/@expo/json-file": { - "version": "10.0.12", - "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-10.0.12.tgz", - "integrity": "sha512-inbDycp1rMAelAofg7h/mMzIe+Owx6F7pur3XdQ3EPTy00tme+4P6FWgHKUcjN8dBSrnbRNpSyh5/shzHyVCyQ==", + "version": "10.0.13", + "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-10.0.13.tgz", + "integrity": "sha512-pX/XjQn7tgNw6zuuV2ikmegmwe/S7uiwhrs2wXrANMkq7ozrA+JcZwgW9Q/8WZgciBzfAhNp5hnackHcrmapQA==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.20.0", @@ -2112,9 +2113,9 @@ } }, "node_modules/@expo/metro-config/node_modules/brace-expansion": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", - "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" @@ -2141,12 +2142,12 @@ } }, "node_modules/@expo/metro-config/node_modules/glob/node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.5" }, "engines": { "node": "18 || 20 || >=22" @@ -2156,9 +2157,9 @@ } }, "node_modules/@expo/metro-config/node_modules/lru-cache": { - "version": "11.2.6", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", - "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", "license": "BlueOak-1.0.0", "engines": { "node": "20 || >=22" @@ -2189,6 +2190,208 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@expo/ngrok": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@expo/ngrok/-/ngrok-4.1.3.tgz", + "integrity": "sha512-AESYaROGIGKWwWmUyQoUXcbvaUZjmpecC5buArXxYou+RID813F8T0Y5jQ2HUY49mZpYfJiy9oh4VSN37GgrXA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@expo/ngrok-bin": "2.3.42", + "got": "^11.5.1", + "uuid": "^3.3.2", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/@expo/ngrok-bin": { + "version": "2.3.42", + "resolved": "https://registry.npmjs.org/@expo/ngrok-bin/-/ngrok-bin-2.3.42.tgz", + "integrity": "sha512-kyhORGwv9XpbPeNIrX6QZ9wDVCDOScyTwxeS+ScNmUqYoZqD9LRmEqF7bpDh5VonTsrXgWrGl7wD2++oSHcaTQ==", + "dev": true, + "bin": { + "ngrok": "bin/ngrok.js" + }, + "optionalDependencies": { + "@expo/ngrok-bin-darwin-arm64": "2.3.41", + "@expo/ngrok-bin-darwin-x64": "2.3.41", + "@expo/ngrok-bin-freebsd-ia32": "2.3.41", + "@expo/ngrok-bin-freebsd-x64": "2.3.41", + "@expo/ngrok-bin-linux-arm": "2.3.41", + "@expo/ngrok-bin-linux-arm64": "2.3.41", + "@expo/ngrok-bin-linux-ia32": "2.3.41", + "@expo/ngrok-bin-linux-x64": "2.3.41", + "@expo/ngrok-bin-sunos-x64": "2.3.41", + "@expo/ngrok-bin-win32-ia32": "2.3.41", + "@expo/ngrok-bin-win32-x64": "2.3.41" + } + }, + "node_modules/@expo/ngrok-bin-darwin-arm64": { + "version": "2.3.41", + "resolved": "https://registry.npmjs.org/@expo/ngrok-bin-darwin-arm64/-/ngrok-bin-darwin-arm64-2.3.41.tgz", + "integrity": "sha512-TPf95xp6SkvbRONZjltTOFcCJbmzAH7lrQ36Dv+djrOckWGPVq4HCur48YAeiGDqspmFEmqZ7ykD5c/bDfRFOA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@expo/ngrok-bin-darwin-x64": { + "version": "2.3.41", + "resolved": "https://registry.npmjs.org/@expo/ngrok-bin-darwin-x64/-/ngrok-bin-darwin-x64-2.3.41.tgz", + "integrity": "sha512-29QZHfX4Ec0p0pQF5UrqiP2/Qe7t2rI96o+5b8045VCEl9AEAKHceGuyo+jfUDR4FSQBGFLSDb06xy8ghL3ZYA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@expo/ngrok-bin-freebsd-ia32": { + "version": "2.3.41", + "resolved": "https://registry.npmjs.org/@expo/ngrok-bin-freebsd-ia32/-/ngrok-bin-freebsd-ia32-2.3.41.tgz", + "integrity": "sha512-YYXgwNZ+p0aIrwgb+1/RxJbsWhGEzBDBhZulKg1VB7tKDAd2C8uGnbK1rOCuZy013iOUsJDXaj9U5QKc13iIXw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@expo/ngrok-bin-freebsd-x64": { + "version": "2.3.41", + "resolved": "https://registry.npmjs.org/@expo/ngrok-bin-freebsd-x64/-/ngrok-bin-freebsd-x64-2.3.41.tgz", + "integrity": "sha512-1Ei6K8BB+3etmmBT0tXYC4dyVkJMigT4ELbRTF5jKfw1pblqeXM9Qpf3p8851PTlH142S3bockCeO39rSkOnkg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@expo/ngrok-bin-linux-arm": { + "version": "2.3.41", + "resolved": "https://registry.npmjs.org/@expo/ngrok-bin-linux-arm/-/ngrok-bin-linux-arm-2.3.41.tgz", + "integrity": "sha512-B6+rW/+tEi7ZrKWQGkRzlwmKo7c1WJhNODFBSgkF/Sj9PmmNhBz67mer91S2+6nNt5pfcwLLd61CjtWfR1LUHQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@expo/ngrok-bin-linux-arm64": { + "version": "2.3.41", + "resolved": "https://registry.npmjs.org/@expo/ngrok-bin-linux-arm64/-/ngrok-bin-linux-arm64-2.3.41.tgz", + "integrity": "sha512-eC8GA/xPcmQJy4h+g2FlkuQB3lf5DjITy8Y6GyydmPYMByjUYAGEXe0brOcP893aalAzRqbNOAjSuAw1lcCLSQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@expo/ngrok-bin-linux-ia32": { + "version": "2.3.41", + "resolved": "https://registry.npmjs.org/@expo/ngrok-bin-linux-ia32/-/ngrok-bin-linux-ia32-2.3.41.tgz", + "integrity": "sha512-w5Cy31wSz4jYnygEHS7eRizR1yt8s9TX6kHlkjzayIiRTFRb2E1qD2l0/4T2w0LJpBjM5ZFPaaKqsNWgCUIEow==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@expo/ngrok-bin-linux-x64": { + "version": "2.3.41", + "resolved": "https://registry.npmjs.org/@expo/ngrok-bin-linux-x64/-/ngrok-bin-linux-x64-2.3.41.tgz", + "integrity": "sha512-LcU3MbYHv7Sn2eFz8Yzo2rXduufOvX1/hILSirwCkH+9G8PYzpwp2TeGqVWuO+EmvtBe6NEYwgdQjJjN6I4L1A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@expo/ngrok-bin-sunos-x64": { + "version": "2.3.41", + "resolved": "https://registry.npmjs.org/@expo/ngrok-bin-sunos-x64/-/ngrok-bin-sunos-x64-2.3.41.tgz", + "integrity": "sha512-bcOj45BLhiV2PayNmLmEVZlFMhEiiGpOr36BXC0XSL+cHUZHd6uNaS28AaZdz95lrRzGpeb0hAF8cuJjo6nq4g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ] + }, + "node_modules/@expo/ngrok-bin-win32-ia32": { + "version": "2.3.41", + "resolved": "https://registry.npmjs.org/@expo/ngrok-bin-win32-ia32/-/ngrok-bin-win32-ia32-2.3.41.tgz", + "integrity": "sha512-0+vPbKvUA+a9ERgiAknmZCiWA3AnM5c6beI+51LqmjKEM4iAAlDmfXNJ89aAbvZMUtBNwEPHzJHnaM4s2SeBhA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@expo/ngrok-bin-win32-x64": { + "version": "2.3.41", + "resolved": "https://registry.npmjs.org/@expo/ngrok-bin-win32-x64/-/ngrok-bin-win32-x64-2.3.41.tgz", + "integrity": "sha512-mncsPRaG462LiYrM8mQT8OYe3/i44m3N/NzUeieYpGi8+pCOo8TIC23kR9P93CVkbM9mmXsy3X6hq91a8FWBdA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@expo/ngrok/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/@expo/ngrok/node_modules/yaml": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.3.tgz", + "integrity": "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, "node_modules/@expo/osascript": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.4.2.tgz", @@ -2202,12 +2405,12 @@ } }, "node_modules/@expo/package-manager": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.10.3.tgz", - "integrity": "sha512-ZuXiK/9fCrIuLjPSe1VYmfp0Sa85kCMwd8QQpgyi5ufppYKRtLBg14QOgUqj8ZMbJTxE0xqzd0XR7kOs3vAK9A==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.10.4.tgz", + "integrity": "sha512-y9Mr4Kmpk4abAVZrNNPCdzOZr8nLLyi18p1SXr0RCVA8IfzqZX/eY4H+50a0HTmXqIsPZrQdcdb4I3ekMS9GvQ==", "license": "MIT", "dependencies": { - "@expo/json-file": "^10.0.12", + "@expo/json-file": "^10.0.13", "@expo/spawn-async": "^1.7.2", "chalk": "^4.0.0", "npm-package-arg": "^11.0.0", @@ -2259,6 +2462,25 @@ "node": ">=10" } }, + "node_modules/@expo/require-utils": { + "version": "55.0.4", + "resolved": "https://registry.npmjs.org/@expo/require-utils/-/require-utils-55.0.4.tgz", + "integrity": "sha512-JAANvXqV7MOysWeVWgaiDzikoyDjJWOV/ulOW60Zb3kXJfrx2oZOtGtDXDFKD1mXuahQgoM5QOjuZhF7gFRNjA==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.20.0", + "@babel/core": "^7.25.2", + "@babel/plugin-transform-modules-commonjs": "^7.24.8" + }, + "peerDependencies": { + "typescript": "^5.0.0 || ^5.0.0-0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/@expo/schema-utils": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/@expo/schema-utils/-/schema-utils-0.1.8.tgz", @@ -2307,9 +2529,9 @@ "license": "MIT" }, "node_modules/@expo/xcpretty": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@expo/xcpretty/-/xcpretty-4.4.1.tgz", - "integrity": "sha512-KZNxZvnGCtiM2aYYZ6Wz0Ix5r47dAvpNLApFtZWnSoERzAdOMzVBOPysBoM0JlF6FKWZ8GPqgn6qt3dV/8Zlpg==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@expo/xcpretty/-/xcpretty-4.4.3.tgz", + "integrity": "sha512-wC562eD3gS6vO2tWHToFhlFnmHKfKHgF1oyvojeSkLK/ZYop1bMU+7cOMiF9Sq70CzcsLy/EMRy/uRc76QmNRw==", "license": "BSD-3-Clause", "dependencies": { "@babel/code-frame": "^7.20.0", @@ -2821,9 +3043,9 @@ } }, "node_modules/@react-native/codegen/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -2988,9 +3210,9 @@ } }, "node_modules/@react-navigation/core": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-7.16.1.tgz", - "integrity": "sha512-xhquoyhKdqDfiL7LuupbwYnmauUGfVFGDEJO34m26k8zSN1eDjQ2stBZcHN8ILOI1PrG9885nf8ZmfaQxPS0ww==", + "version": "7.17.2", + "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-7.17.2.tgz", + "integrity": "sha512-Rt2OZwcgOmjv401uLGAKaRM6xo0fiBce/A7LfRHI1oe5FV+KooWcgAoZ2XOtgKj6UzVMuQWt3b2e6rxo/mDJRA==", "license": "MIT", "dependencies": { "@react-navigation/routers": "^7.5.3", @@ -3007,9 +3229,9 @@ } }, "node_modules/@react-navigation/elements": { - "version": "2.9.10", - "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-2.9.10.tgz", - "integrity": "sha512-N8tuBekzTRb0pkMHFJGvmC6Q5OisSbt6gzvw7RHMnp4NDo5auVllT12sWFaTXf8mTduaLKNSrD/NZNaOqThCBg==", + "version": "2.9.15", + "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-2.9.15.tgz", + "integrity": "sha512-cyz/pPiyyC6gaTVLsGFc1g0MYgrmuCFqklAWGXMWPscr5YU3ui94vPI4vnZwcsEy0T758TQWLzmS5XudZeRKcA==", "license": "MIT", "dependencies": { "color": "^4.2.3", @@ -3018,7 +3240,7 @@ }, "peerDependencies": { "@react-native-masked-view/masked-view": ">= 0.2.0", - "@react-navigation/native": "^7.1.33", + "@react-navigation/native": "^7.2.2", "react": ">= 18.2.0", "react-native": "*", "react-native-safe-area-context": ">= 4.0.0" @@ -3030,12 +3252,12 @@ } }, "node_modules/@react-navigation/native": { - "version": "7.1.33", - "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-7.1.33.tgz", - "integrity": "sha512-DpFdWGcgLajKZ1TuIvDNQsblN2QaUFWpTQaB8v7WRP9Mix8H/6TFoIrZd93pbymI2hybd6UYrD+lI408eWVcfw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-7.2.2.tgz", + "integrity": "sha512-kem1Ko2BcbAjmbQIv66dNmr6EtfDut3QU0qjsVhMnLLhktwyXb6FzZYp8gTrUb6AvkAbaJoi+BF5Pl55pAUa5w==", "license": "MIT", "dependencies": { - "@react-navigation/core": "^7.16.1", + "@react-navigation/core": "^7.17.2", "escape-string-regexp": "^4.0.0", "fast-deep-equal": "^3.1.3", "nanoid": "^3.3.11", @@ -3099,6 +3321,19 @@ "integrity": "sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==", "license": "MIT" }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, "node_modules/@sinonjs/commons": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", @@ -3444,6 +3679,19 @@ "@svgr/core": "*" } }, + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dev": true, + "license": "MIT", + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@tanstack/query-core": { "version": "5.90.20", "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.20.tgz", @@ -3511,6 +3759,19 @@ "@babel/types": "^7.28.2" } }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, "node_modules/@types/graceful-fs": { "version": "4.1.9", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", @@ -3526,6 +3787,13 @@ "integrity": "sha512-ynRvcq6wvqexJ9brDMS4BnBLzmr0e14d6ZJTEShTBWKymQiHwlAyGu0ZPEFI2Fh1U53F7tN9ufClWM5KvqkKOw==", "license": "MIT" }, + "node_modules/@types/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -3550,6 +3818,16 @@ "@types/istanbul-lib-report": "*" } }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/node": { "version": "25.5.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.0.tgz", @@ -3575,6 +3853,16 @@ "csstype": "^3.0.2" } }, + "node_modules/@types/responselike": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", @@ -3635,9 +3923,9 @@ } }, "node_modules/@xmldom/xmldom": { - "version": "0.8.11", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.11.tgz", - "integrity": "sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==", + "version": "0.8.13", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.13.tgz", + "integrity": "sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -3689,22 +3977,6 @@ "node": ">= 14" } }, - "node_modules/ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, "node_modules/anser": { "version": "1.4.10", "resolved": "https://registry.npmjs.org/anser/-/anser-1.4.10.tgz", @@ -3926,13 +4198,13 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.16", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.16.tgz", - "integrity": "sha512-xaVwwSfebXf0ooE11BJovZYKhFjIvQo7TsyVpETuIeH2JHv0k/T6Y5j22pPTvqYqmpkxdlPAJlyJ0tfOJAoMxw==", + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.17.tgz", + "integrity": "sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==", "license": "MIT", "dependencies": { "@babel/compat-data": "^7.28.6", - "@babel/helper-define-polyfill-provider": "^0.6.7", + "@babel/helper-define-polyfill-provider": "^0.6.8", "semver": "^6.3.1" }, "peerDependencies": { @@ -3953,12 +4225,12 @@ } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.7", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.7.tgz", - "integrity": "sha512-OTYbUlSwXhNgr4g6efMZgsO8//jA61P7ZbRX3iTT53VON8l+WQS8IAUEVo4a4cWknrg2W8Cj4gQhRYNCJ8GkAA==", + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.8.tgz", + "integrity": "sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==", "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.7" + "@babel/helper-define-polyfill-provider": "^0.6.8" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -4305,15 +4577,44 @@ "node": ">= 0.8" } }, + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/call-bind": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", - "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", + "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.0", - "es-define-property": "^1.0.0", - "get-intrinsic": "^1.2.4", + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "get-intrinsic": "^1.3.0", "set-function-length": "^1.2.2" }, "engines": { @@ -4549,6 +4850,19 @@ "node": ">=0.8" } }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/color": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", @@ -4721,9 +5035,9 @@ "license": "MIT" }, "node_modules/core-js-compat": { - "version": "3.48.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.48.0.tgz", - "integrity": "sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q==", + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.49.0.tgz", + "integrity": "sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==", "license": "MIT", "dependencies": { "browserslist": "^4.28.1" @@ -4943,6 +5257,35 @@ "node": ">=0.10" } }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", @@ -4973,6 +5316,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -5199,6 +5552,16 @@ "node": ">= 0.8" } }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -5436,79 +5799,28 @@ "react-native": "*" } }, - "node_modules/expo-constants": { - "version": "18.0.13", - "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-18.0.13.tgz", - "integrity": "sha512-FnZn12E1dRYKDHlAdIyNFhBurKTS3F9CrfrBDJI5m3D7U17KBHMQ6JEfYlSj7LG7t+Ulr+IKaj58L1k5gBwTcQ==", - "license": "MIT", - "dependencies": { - "@expo/config": "~12.0.13", - "@expo/env": "~2.0.8" - }, - "peerDependencies": { - "expo": "*", - "react-native": "*" - } - }, - "node_modules/expo-crypto": { - "version": "15.0.8", - "resolved": "https://registry.npmjs.org/expo-crypto/-/expo-crypto-15.0.8.tgz", - "integrity": "sha512-aF7A914TB66WIlTJvl5J6/itejfY78O7dq3ibvFltL9vnTALJ/7LYHvLT4fwmx9yUNS6ekLBtDGWivFWnj2Fcw==", - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.0" - }, - "peerDependencies": { - "expo": "*" - } - }, - "node_modules/expo-dev-client": { - "version": "6.0.20", - "resolved": "https://registry.npmjs.org/expo-dev-client/-/expo-dev-client-6.0.20.tgz", - "integrity": "sha512-5XjoVlj1OxakNxy55j/AUaGPrDOlQlB6XdHLLWAw61w5ffSpUDHDnuZzKzs9xY1eIaogOqTOQaAzZ2ddBkdXLA==", - "license": "MIT", - "dependencies": { - "expo-dev-launcher": "6.0.20", - "expo-dev-menu": "7.0.18", - "expo-dev-menu-interface": "2.0.0", - "expo-manifests": "~1.0.10", - "expo-updates-interface": "~2.0.0" - }, - "peerDependencies": { - "expo": "*" - } - }, - "node_modules/expo-dev-launcher": { - "version": "6.0.20", - "resolved": "https://registry.npmjs.org/expo-dev-launcher/-/expo-dev-launcher-6.0.20.tgz", - "integrity": "sha512-a04zHEeT9sB0L5EB38fz7sNnUKJ2Ar1pXpcyl60Ki8bXPNCs9rjY7NuYrDkP/irM8+1DklMBqHpyHiLyJ/R+EA==", - "license": "MIT", - "dependencies": { - "ajv": "^8.11.0", - "expo-dev-menu": "7.0.18", - "expo-manifests": "~1.0.10" - }, - "peerDependencies": { - "expo": "*" - } - }, - "node_modules/expo-dev-menu": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/expo-dev-menu/-/expo-dev-menu-7.0.18.tgz", - "integrity": "sha512-4kTdlHrnZCAWCT6tZRQHSSjZ7vECFisL4T+nsG/GJDo/jcHNaOVGV5qPV9wzlTxyMk3YOPggRw4+g7Ownrg5eA==", + "node_modules/expo-constants": { + "version": "18.0.13", + "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-18.0.13.tgz", + "integrity": "sha512-FnZn12E1dRYKDHlAdIyNFhBurKTS3F9CrfrBDJI5m3D7U17KBHMQ6JEfYlSj7LG7t+Ulr+IKaj58L1k5gBwTcQ==", "license": "MIT", "dependencies": { - "expo-dev-menu-interface": "2.0.0" + "@expo/config": "~12.0.13", + "@expo/env": "~2.0.8" }, "peerDependencies": { - "expo": "*" + "expo": "*", + "react-native": "*" } }, - "node_modules/expo-dev-menu-interface": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/expo-dev-menu-interface/-/expo-dev-menu-interface-2.0.0.tgz", - "integrity": "sha512-BvAMPt6x+vyXpThsyjjOYyjwfjREV4OOpQkZ0tNl+nGpsPfcY9mc6DRACoWnH9KpLzyIt3BOgh3cuy/h/OxQjw==", + "node_modules/expo-crypto": { + "version": "15.0.8", + "resolved": "https://registry.npmjs.org/expo-crypto/-/expo-crypto-15.0.8.tgz", + "integrity": "sha512-aF7A914TB66WIlTJvl5J6/itejfY78O7dq3ibvFltL9vnTALJ/7LYHvLT4fwmx9yUNS6ekLBtDGWivFWnj2Fcw==", "license": "MIT", + "dependencies": { + "base64-js": "^1.3.0" + }, "peerDependencies": { "expo": "*" } @@ -5596,12 +5908,6 @@ "expo": "*" } }, - "node_modules/expo-json-utils": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/expo-json-utils/-/expo-json-utils-0.15.0.tgz", - "integrity": "sha512-duRT6oGl80IDzH2LD2yEFWNwGIC2WkozsB6HF3cDYNoNNdUvFk6uN3YiwsTsqVM/D0z6LEAQ01/SlYvN+Fw0JQ==", - "license": "MIT" - }, "node_modules/expo-keep-awake": { "version": "15.0.8", "resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-15.0.8.tgz", @@ -5626,19 +5932,6 @@ "react-native": "*" } }, - "node_modules/expo-manifests": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/expo-manifests/-/expo-manifests-1.0.10.tgz", - "integrity": "sha512-oxDUnURPcL4ZsOBY6X1DGWGuoZgVAFzp6PISWV7lPP2J0r8u1/ucuChBgpK7u1eLGFp6sDIPwXyEUCkI386XSQ==", - "license": "MIT", - "dependencies": { - "@expo/config": "~12.0.11", - "expo-json-utils": "~0.15.0" - }, - "peerDependencies": { - "expo": "*" - } - }, "node_modules/expo-modules-autolinking": { "version": "3.0.24", "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-3.0.24.tgz", @@ -5719,15 +6012,6 @@ "react-native": "*" } }, - "node_modules/expo-updates-interface": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/expo-updates-interface/-/expo-updates-interface-2.0.0.tgz", - "integrity": "sha512-pTzAIufEZdVPKql6iMi5ylVSPqV1qbEopz9G6TSECQmnNde2nwq42PxdFBaUEd8IZJ/fdJLQnOT3m6+XJ5s7jg==", - "license": "MIT", - "peerDependencies": { - "expo": "*" - } - }, "node_modules/expo-web-browser": { "version": "15.0.10", "resolved": "https://registry.npmjs.org/expo-web-browser/-/expo-web-browser-15.0.10.tgz", @@ -5835,9 +6119,9 @@ } }, "node_modules/expo/node_modules/brace-expansion": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", - "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" @@ -5879,12 +6163,12 @@ } }, "node_modules/expo/node_modules/glob/node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.5" }, "engines": { "node": "18 || 20 || >=22" @@ -5894,9 +6178,9 @@ } }, "node_modules/expo/node_modules/lru-cache": { - "version": "11.2.6", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", - "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", "license": "BlueOak-1.0.0", "engines": { "node": "20 || >=22" @@ -5928,9 +6212,9 @@ } }, "node_modules/expo/node_modules/picomatch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-3.0.1.tgz", - "integrity": "sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-3.0.2.tgz", + "integrity": "sha512-cfDHL6LStTEKlNilboNtobT/kEa30PtAf2Q1OgszfrG/rpVl1xaFWT9ktfkS306GmHgmnad1Sw4wabhlvFtsTw==", "license": "MIT", "engines": { "node": ">=10" @@ -6006,22 +6290,6 @@ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "license": "MIT" }, - "node_modules/fast-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, "node_modules/fastq": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", @@ -6330,6 +6598,22 @@ "node": ">= 0.4" } }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/getenv": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/getenv/-/getenv-2.0.0.tgz", @@ -6399,6 +6683,32 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -6513,6 +6823,13 @@ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "license": "ISC" }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "dev": true, + "license": "BSD-2-Clause" + }, "node_modules/http-errors": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", @@ -6542,6 +6859,20 @@ "node": ">= 0.8" } }, + "node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, "node_modules/https-proxy-agent": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", @@ -7152,6 +7483,13 @@ "node": ">=6" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -7159,12 +7497,6 @@ "dev": true, "license": "MIT" }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -7177,6 +7509,16 @@ "node": ">=6" } }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -7639,6 +7981,16 @@ "tslib": "^2.0.3" } }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -8086,6 +8438,16 @@ "node": ">=4" } }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/minimatch": { "version": "9.0.9", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", @@ -8252,9 +8614,9 @@ } }, "node_modules/node-forge": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.3.tgz", - "integrity": "sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.4.0.tgz", + "integrity": "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==", "license": "(BSD-3-Clause OR GPL-2.0)", "engines": { "node": ">= 6.13.0" @@ -8281,6 +8643,19 @@ "node": ">=0.10.0" } }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/npm-package-arg": { "version": "11.0.3", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.3.tgz", @@ -8568,6 +8943,16 @@ "node": ">=4" } }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -8809,12 +9194,12 @@ } }, "node_modules/plist": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", - "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.1.tgz", + "integrity": "sha512-ZIfcLJC+7E7FBFnDxm9MPmt7D+DidyQ26lewieO75AdhA2ayMtsJSES0iWzqJQbcVRSrTufQoy0DR94xHue0oA==", "license": "MIT", "dependencies": { - "@xmldom/xmldom": "^0.8.8", + "@xmldom/xmldom": "^0.9.10", "base64-js": "^1.5.1", "xmlbuilder": "^15.1.1" }, @@ -8822,6 +9207,15 @@ "node": ">=10.4.0" } }, + "node_modules/plist/node_modules/@xmldom/xmldom": { + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.10.tgz", + "integrity": "sha512-A9gOqLdi6cV4ibazAjcQufGj0B1y/vDqYrcuP6d/6x8P27gRS8643Dj9o1dEKtB6O7fwxb2FgBmJS2mX7gpvdw==", + "license": "MIT", + "engines": { + "node": ">=14.6" + } + }, "node_modules/pngjs": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", @@ -9086,6 +9480,17 @@ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "license": "MIT" }, + "node_modules/pump": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", + "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -9150,6 +9555,19 @@ ], "license": "MIT" }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -9239,9 +9657,9 @@ } }, "node_modules/react-is": { - "version": "19.2.4", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.4.tgz", - "integrity": "sha512-W+EWGn2v0ApPKgKKCy/7s7WHXkboGcsrXE+2joLyVxkbyVQfO3MUEaUQDHoSmb8TFFrSKYa9mw64WZHNHSDzYA==", + "version": "19.2.5", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.5.tgz", + "integrity": "sha512-Dn0t8IQhCmeIT3wu+Apm1/YVsJXsGWi6k4sPdnBIdqMVtHtv0IGi6dcpNpNkNac0zB2uUAqNX3MHzN8c+z2rwQ==", "license": "MIT" }, "node_modules/react-native": { @@ -9632,28 +10050,18 @@ } }, "node_modules/react-native-reanimated": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-4.2.2.tgz", - "integrity": "sha512-o3kKvdD8cVlg12Z4u3jv0MFAt53QV4k7gD9OLwQqU8eZLyd8QvaOjVZIghMZhC2pjP93uUU44PlO5JgF8S4Vxw==", + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-4.1.7.tgz", + "integrity": "sha512-Q4H6xA3Tn7QL0/E/KjI86I1KK4tcf+ErRE04LH34Etka2oVQhW6oXQ+Q8ZcDCVxiWp5vgbBH6XcH8BOo4w/Rhg==", "license": "MIT", "dependencies": { - "react-native-is-edge-to-edge": "1.2.1", - "semver": "7.7.3" + "react-native-is-edge-to-edge": "^1.2.1", + "semver": "^7.7.2" }, "peerDependencies": { "react": "*", - "react-native": "*", - "react-native-worklets": ">=0.7.0" - } - }, - "node_modules/react-native-reanimated/node_modules/react-native-is-edge-to-edge": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/react-native-is-edge-to-edge/-/react-native-is-edge-to-edge-1.2.1.tgz", - "integrity": "sha512-FLbPWl/MyYQWz+KwqOZsSyj2JmLKglHatd3xLZWskXOpRaio4LfEDEz8E/A6uD8QoTHW6Aobw1jbEwK7KMgR7Q==", - "license": "MIT", - "peerDependencies": { - "react": "*", - "react-native": "*" + "react-native": "0.78 - 0.82", + "react-native-worklets": "0.5 - 0.8" } }, "node_modules/react-native-reanimated/node_modules/semver": { @@ -9770,127 +10178,34 @@ "license": "MIT" }, "node_modules/react-native-worklets": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/react-native-worklets/-/react-native-worklets-0.7.4.tgz", - "integrity": "sha512-NYOdM1MwBb3n+AtMqy1tFy3Mn8DliQtd8sbzAVRf9Gc+uvQ0zRfxN7dS8ZzoyX7t6cyQL5THuGhlnX+iFlQTag==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/plugin-transform-arrow-functions": "7.27.1", - "@babel/plugin-transform-class-properties": "7.27.1", - "@babel/plugin-transform-classes": "7.28.4", - "@babel/plugin-transform-nullish-coalescing-operator": "7.27.1", - "@babel/plugin-transform-optional-chaining": "7.27.1", - "@babel/plugin-transform-shorthand-properties": "7.27.1", - "@babel/plugin-transform-template-literals": "7.27.1", - "@babel/plugin-transform-unicode-regex": "7.27.1", - "@babel/preset-typescript": "7.27.1", - "convert-source-map": "2.0.0", - "semver": "7.7.3" + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/react-native-worklets/-/react-native-worklets-0.5.1.tgz", + "integrity": "sha512-lJG6Uk9YuojjEX/tQrCbcbmpdLCSFxDK1rJlkDhgqkVi1KZzG7cdcBFQRqyNOOzR9Y0CXNuldmtWTGOyM0k0+w==", + "license": "MIT", + "dependencies": { + "@babel/plugin-transform-arrow-functions": "^7.0.0-0", + "@babel/plugin-transform-class-properties": "^7.0.0-0", + "@babel/plugin-transform-classes": "^7.0.0-0", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.0.0-0", + "@babel/plugin-transform-optional-chaining": "^7.0.0-0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0-0", + "@babel/plugin-transform-template-literals": "^7.0.0-0", + "@babel/plugin-transform-unicode-regex": "^7.0.0-0", + "@babel/preset-typescript": "^7.16.7", + "convert-source-map": "^2.0.0", + "semver": "7.7.2" }, "peerDependencies": { - "@babel/core": "*", + "@babel/core": "^7.0.0-0", "react": "*", "react-native": "*" } }, - "node_modules/react-native-worklets/node_modules/@babel/plugin-transform-class-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", - "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/react-native-worklets/node_modules/@babel/plugin-transform-classes": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz", - "integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-globals": "^7.28.0", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1", - "@babel/traverse": "^7.28.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/react-native-worklets/node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", - "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/react-native-worklets/node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz", - "integrity": "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/react-native-worklets/node_modules/@babel/preset-typescript": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.27.1.tgz", - "integrity": "sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-validator-option": "^7.27.1", - "@babel/plugin-syntax-jsx": "^7.27.1", - "@babel/plugin-transform-modules-commonjs": "^7.27.1", - "@babel/plugin-transform-typescript": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/react-native-worklets/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "license": "ISC", - "peer": true, "bin": { "semver": "bin/semver.js" }, @@ -10082,9 +10397,9 @@ "license": "MIT" }, "node_modules/regjsparser": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz", - "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==", + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.1.tgz", + "integrity": "sha512-dLsljMd9sqwRkby8zhO1gSg3PnJIBFid8f4CQj/sXx+7cKx+E7u0PKhZ+U4wmhx7EfmtvnA318oVaIkAB1lRJw==", "license": "BSD-2-Clause", "dependencies": { "jsesc": "~3.1.0" @@ -10160,6 +10475,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true, + "license": "MIT" + }, "node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -10184,6 +10506,19 @@ "node": ">=10" } }, + "node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/restore-cursor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", @@ -10224,9 +10559,9 @@ } }, "node_modules/rimraf/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -10571,9 +10906,9 @@ } }, "node_modules/slugify": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz", - "integrity": "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==", + "version": "1.6.9", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.9.tgz", + "integrity": "sha512-vZ7rfeehZui7wQs438JXBckYLkIIdfHOXsaVEUMyS5fHo1483l1bMdo0EDSWYclY0yZKFOipDy4KHuKs6ssvdg==", "license": "MIT", "engines": { "node": ">=8.0.0" @@ -10915,9 +11250,9 @@ } }, "node_modules/tar": { - "version": "7.5.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.11.tgz", - "integrity": "sha512-ChjMH33/KetonMTAtpYdgUFr0tbz69Fp2v7zWxQfYZX4g5ZN2nOBXm1R2xyA+lMIKrLKIoKAwFj93jE/avX9cQ==", + "version": "7.5.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.13.tgz", + "integrity": "sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==", "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/fs-minipass": "^4.0.0", @@ -10965,9 +11300,9 @@ } }, "node_modules/terser": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", - "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", + "version": "5.46.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.2.tgz", + "integrity": "sha512-uxfo9fPcSgLDYob/w1FuL0c99MWiJDnv+5qXSQc5+Ki5NjVNsYi66INnMFBjf6uFz6OnX12piJQPF4IpjJTNTw==", "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -11184,7 +11519,7 @@ "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -11221,9 +11556,9 @@ } }, "node_modules/undici": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz", - "integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==", + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.25.0.tgz", + "integrity": "sha512-ZgpWDC5gmNiuY9CnLVXEH8rl50xhRCuLNA97fAUnKi8RRuV4E6KG31pDTsLVUKnohJE0I3XDrTeEydAXRw47xg==", "license": "MIT", "engines": { "node": ">=18.17" @@ -11499,9 +11834,9 @@ } }, "node_modules/wonka": { - "version": "6.3.5", - "resolved": "https://registry.npmjs.org/wonka/-/wonka-6.3.5.tgz", - "integrity": "sha512-SSil+ecw6B4/Dm7Pf2sAshKQ5hWFvfyGlfPbEd6A14dOH6VDjrmbY86u6nZvy9omGwwIPFR8V41+of1EezgoUw==", + "version": "6.3.6", + "resolved": "https://registry.npmjs.org/wonka/-/wonka-6.3.6.tgz", + "integrity": "sha512-MXH+6mDHAZ2GuMpgKS055FR6v0xVP3XwquxIMYXgiW+FejHQlMGlvVRZT4qMCxR+bEo/FCtIdKxwej9WV3YQag==", "license": "MIT" }, "node_modules/wrap-ansi": { diff --git a/package.json b/package.json index 96eb909..013e368 100644 --- a/package.json +++ b/package.json @@ -22,8 +22,8 @@ "expo": "~54.0.33", "expo-auth-session": "~7.0.10", "expo-crypto": "~15.0.8", - "expo-dev-client": "~6.0.20", "expo-device": "~8.0.10", + "expo-font": "~14.0.11", "expo-image-picker": "~17.0.10", "expo-linking": "~8.0.11", "expo-notifications": "~0.32.16", @@ -36,16 +36,18 @@ "react-native": "0.81.5", "react-native-gesture-handler": "~2.28.0", "react-native-pager-view": "6.9.1", - "react-native-reanimated": "~4.2.1", + "react-native-reanimated": "~4.1.1", "react-native-safe-area-context": "~5.6.0", "react-native-screens": "~4.16.0", "react-native-svg": "15.12.1", "react-native-url-polyfill": "^3.0.0", "react-native-web": "^0.21.0", + "react-native-worklets": "0.5.1", "tailwindcss": "^3.4.17", "zustand": "^5.0.10" }, "devDependencies": { + "@expo/ngrok": "^4.1.3", "@types/react": "~19.1.0", "babel-plugin-module-resolver": "^5.0.2", "react-native-svg-transformer": "^1.5.3", diff --git a/src/utils/fcm.ts b/src/utils/fcm.ts index fa1c76f..3d3a8b6 100644 --- a/src/utils/fcm.ts +++ b/src/utils/fcm.ts @@ -10,15 +10,15 @@ const ensureNotificationPermission = async (): Promise => { return false; } - const { status: existing } = await Notifications.getPermissionsAsync(); - let finalStatus = existing; + const { granted: existing } = await Notifications.getPermissionsAsync(); - if (existing !== "granted") { - const { status } = await Notifications.requestPermissionsAsync(); - finalStatus = status; + if (existing) { + return true; } - if (finalStatus !== "granted") { + const { granted } = await Notifications.requestPermissionsAsync(); + + if (!granted) { debugLog("FCM", "notification permission denied"); return false; }

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