diff --git a/.expo/types/router.d.ts b/.expo/types/router.d.ts index 8492b24..dd3ef99 100644 --- a/.expo/types/router.d.ts +++ b/.expo/types/router.d.ts @@ -6,9 +6,9 @@ export * from 'expo-router'; declare module 'expo-router' { export namespace ExpoRouter { export interface __routes { - hrefInputParams: { pathname: Router.RelativePathString, params?: Router.UnknownInputParams } | { pathname: Router.ExternalPathString, params?: Router.UnknownInputParams } | { pathname: `/analytics`; params?: Router.UnknownInputParams; } | { pathname: `/emergency`; params?: Router.UnknownInputParams; } | { pathname: `/onboarding`; params?: Router.UnknownInputParams; } | { pathname: `/_sitemap`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/advanced-analytics` | `/advanced-analytics`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/advanced-therapy` | `/advanced-therapy`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/ai-chat` | `/ai-chat`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/ai-coach` | `/ai-coach`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/analytics` | `/analytics`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/articles` | `/articles`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/community` | `/community`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/courses` | `/courses`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/enhanced-exercises` | `/enhanced-exercises`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/enhanced-settings` | `/enhanced-settings`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/exercises` | `/exercises`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/gamification` | `/gamification`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}` | `/`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/journal` | `/journal`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/micro-courses` | `/micro-courses`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/mini-games` | `/mini-games`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/personalized-recommendations` | `/personalized-recommendations`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/profile` | `/profile`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/psychology` | `/psychology`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/sounds` | `/sounds`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/therapy` | `/therapy`; params?: Router.UnknownInputParams; } | { pathname: `/i18n`; params?: Router.UnknownInputParams; } | { pathname: `/+not-found`, params: Router.UnknownInputParams & { } }; - hrefOutputParams: { pathname: Router.RelativePathString, params?: Router.UnknownOutputParams } | { pathname: Router.ExternalPathString, params?: Router.UnknownOutputParams } | { pathname: `/analytics`; params?: Router.UnknownOutputParams; } | { pathname: `/emergency`; params?: Router.UnknownOutputParams; } | { pathname: `/onboarding`; params?: Router.UnknownOutputParams; } | { pathname: `/_sitemap`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/advanced-analytics` | `/advanced-analytics`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/advanced-therapy` | `/advanced-therapy`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/ai-chat` | `/ai-chat`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/ai-coach` | `/ai-coach`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/analytics` | `/analytics`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/articles` | `/articles`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/community` | `/community`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/courses` | `/courses`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/enhanced-exercises` | `/enhanced-exercises`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/enhanced-settings` | `/enhanced-settings`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/exercises` | `/exercises`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/gamification` | `/gamification`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}` | `/`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/journal` | `/journal`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/micro-courses` | `/micro-courses`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/mini-games` | `/mini-games`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/personalized-recommendations` | `/personalized-recommendations`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/profile` | `/profile`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/psychology` | `/psychology`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/sounds` | `/sounds`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/therapy` | `/therapy`; params?: Router.UnknownOutputParams; } | { pathname: `/i18n`; params?: Router.UnknownOutputParams; } | { pathname: `/+not-found`, params: Router.UnknownOutputParams & { } }; - href: Router.RelativePathString | Router.ExternalPathString | `/analytics${`?${string}` | `#${string}` | ''}` | `/emergency${`?${string}` | `#${string}` | ''}` | `/onboarding${`?${string}` | `#${string}` | ''}` | `/_sitemap${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/advanced-analytics${`?${string}` | `#${string}` | ''}` | `/advanced-analytics${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/advanced-therapy${`?${string}` | `#${string}` | ''}` | `/advanced-therapy${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/ai-chat${`?${string}` | `#${string}` | ''}` | `/ai-chat${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/ai-coach${`?${string}` | `#${string}` | ''}` | `/ai-coach${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/analytics${`?${string}` | `#${string}` | ''}` | `/analytics${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/articles${`?${string}` | `#${string}` | ''}` | `/articles${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/community${`?${string}` | `#${string}` | ''}` | `/community${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/courses${`?${string}` | `#${string}` | ''}` | `/courses${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/enhanced-exercises${`?${string}` | `#${string}` | ''}` | `/enhanced-exercises${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/enhanced-settings${`?${string}` | `#${string}` | ''}` | `/enhanced-settings${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/exercises${`?${string}` | `#${string}` | ''}` | `/exercises${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/gamification${`?${string}` | `#${string}` | ''}` | `/gamification${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}${`?${string}` | `#${string}` | ''}` | `/${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/journal${`?${string}` | `#${string}` | ''}` | `/journal${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/micro-courses${`?${string}` | `#${string}` | ''}` | `/micro-courses${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/mini-games${`?${string}` | `#${string}` | ''}` | `/mini-games${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/personalized-recommendations${`?${string}` | `#${string}` | ''}` | `/personalized-recommendations${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/profile${`?${string}` | `#${string}` | ''}` | `/profile${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/psychology${`?${string}` | `#${string}` | ''}` | `/psychology${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/sounds${`?${string}` | `#${string}` | ''}` | `/sounds${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/therapy${`?${string}` | `#${string}` | ''}` | `/therapy${`?${string}` | `#${string}` | ''}` | `/i18n${`?${string}` | `#${string}` | ''}` | { pathname: Router.RelativePathString, params?: Router.UnknownInputParams } | { pathname: Router.ExternalPathString, params?: Router.UnknownInputParams } | { pathname: `/analytics`; params?: Router.UnknownInputParams; } | { pathname: `/emergency`; params?: Router.UnknownInputParams; } | { pathname: `/onboarding`; params?: Router.UnknownInputParams; } | { pathname: `/_sitemap`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/advanced-analytics` | `/advanced-analytics`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/advanced-therapy` | `/advanced-therapy`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/ai-chat` | `/ai-chat`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/ai-coach` | `/ai-coach`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/analytics` | `/analytics`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/articles` | `/articles`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/community` | `/community`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/courses` | `/courses`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/enhanced-exercises` | `/enhanced-exercises`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/enhanced-settings` | `/enhanced-settings`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/exercises` | `/exercises`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/gamification` | `/gamification`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}` | `/`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/journal` | `/journal`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/micro-courses` | `/micro-courses`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/mini-games` | `/mini-games`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/personalized-recommendations` | `/personalized-recommendations`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/profile` | `/profile`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/psychology` | `/psychology`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/sounds` | `/sounds`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/therapy` | `/therapy`; params?: Router.UnknownInputParams; } | { pathname: `/i18n`; params?: Router.UnknownInputParams; } | `/+not-found${`?${string}` | `#${string}` | ''}` | { pathname: `/+not-found`, params: Router.UnknownInputParams & { } }; + hrefInputParams: { pathname: Router.RelativePathString, params?: Router.UnknownInputParams } | { pathname: Router.ExternalPathString, params?: Router.UnknownInputParams } | { pathname: `/analytics`; params?: Router.UnknownInputParams; } | { pathname: `/emergency`; params?: Router.UnknownInputParams; } | { pathname: `/onboarding`; params?: Router.UnknownInputParams; } | { pathname: `/_sitemap`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/advanced-analytics` | `/advanced-analytics`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/advanced-therapy` | `/advanced-therapy`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/ai-chat` | `/ai-chat`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/ai-coach` | `/ai-coach`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/analytics` | `/analytics`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/articles` | `/articles`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/community` | `/community`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/courses` | `/courses`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/enhanced-settings` | `/enhanced-settings`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/exercises` | `/exercises`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/gamification` | `/gamification`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}` | `/`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/journal` | `/journal`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/micro-courses` | `/micro-courses`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/mini-games` | `/mini-games`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/personalized-recommendations` | `/personalized-recommendations`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/profile` | `/profile`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/psychology` | `/psychology`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/sounds` | `/sounds`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/therapy` | `/therapy`; params?: Router.UnknownInputParams; } | { pathname: `/i18n`; params?: Router.UnknownInputParams; } | { pathname: `/+not-found`, params: Router.UnknownInputParams & { } }; + hrefOutputParams: { pathname: Router.RelativePathString, params?: Router.UnknownOutputParams } | { pathname: Router.ExternalPathString, params?: Router.UnknownOutputParams } | { pathname: `/analytics`; params?: Router.UnknownOutputParams; } | { pathname: `/emergency`; params?: Router.UnknownOutputParams; } | { pathname: `/onboarding`; params?: Router.UnknownOutputParams; } | { pathname: `/_sitemap`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/advanced-analytics` | `/advanced-analytics`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/advanced-therapy` | `/advanced-therapy`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/ai-chat` | `/ai-chat`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/ai-coach` | `/ai-coach`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/analytics` | `/analytics`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/articles` | `/articles`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/community` | `/community`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/courses` | `/courses`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/enhanced-settings` | `/enhanced-settings`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/exercises` | `/exercises`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/gamification` | `/gamification`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}` | `/`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/journal` | `/journal`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/micro-courses` | `/micro-courses`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/mini-games` | `/mini-games`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/personalized-recommendations` | `/personalized-recommendations`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/profile` | `/profile`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/psychology` | `/psychology`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/sounds` | `/sounds`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(tabs)'}/therapy` | `/therapy`; params?: Router.UnknownOutputParams; } | { pathname: `/i18n`; params?: Router.UnknownOutputParams; } | { pathname: `/+not-found`, params: Router.UnknownOutputParams & { } }; + href: Router.RelativePathString | Router.ExternalPathString | `/analytics${`?${string}` | `#${string}` | ''}` | `/emergency${`?${string}` | `#${string}` | ''}` | `/onboarding${`?${string}` | `#${string}` | ''}` | `/_sitemap${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/advanced-analytics${`?${string}` | `#${string}` | ''}` | `/advanced-analytics${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/advanced-therapy${`?${string}` | `#${string}` | ''}` | `/advanced-therapy${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/ai-chat${`?${string}` | `#${string}` | ''}` | `/ai-chat${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/ai-coach${`?${string}` | `#${string}` | ''}` | `/ai-coach${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/analytics${`?${string}` | `#${string}` | ''}` | `/analytics${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/articles${`?${string}` | `#${string}` | ''}` | `/articles${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/community${`?${string}` | `#${string}` | ''}` | `/community${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/courses${`?${string}` | `#${string}` | ''}` | `/courses${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/enhanced-settings${`?${string}` | `#${string}` | ''}` | `/enhanced-settings${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/exercises${`?${string}` | `#${string}` | ''}` | `/exercises${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/gamification${`?${string}` | `#${string}` | ''}` | `/gamification${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}${`?${string}` | `#${string}` | ''}` | `/${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/journal${`?${string}` | `#${string}` | ''}` | `/journal${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/micro-courses${`?${string}` | `#${string}` | ''}` | `/micro-courses${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/mini-games${`?${string}` | `#${string}` | ''}` | `/mini-games${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/personalized-recommendations${`?${string}` | `#${string}` | ''}` | `/personalized-recommendations${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/profile${`?${string}` | `#${string}` | ''}` | `/profile${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/psychology${`?${string}` | `#${string}` | ''}` | `/psychology${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/sounds${`?${string}` | `#${string}` | ''}` | `/sounds${`?${string}` | `#${string}` | ''}` | `${'/(tabs)'}/therapy${`?${string}` | `#${string}` | ''}` | `/therapy${`?${string}` | `#${string}` | ''}` | `/i18n${`?${string}` | `#${string}` | ''}` | { pathname: Router.RelativePathString, params?: Router.UnknownInputParams } | { pathname: Router.ExternalPathString, params?: Router.UnknownInputParams } | { pathname: `/analytics`; params?: Router.UnknownInputParams; } | { pathname: `/emergency`; params?: Router.UnknownInputParams; } | { pathname: `/onboarding`; params?: Router.UnknownInputParams; } | { pathname: `/_sitemap`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/advanced-analytics` | `/advanced-analytics`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/advanced-therapy` | `/advanced-therapy`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/ai-chat` | `/ai-chat`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/ai-coach` | `/ai-coach`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/analytics` | `/analytics`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/articles` | `/articles`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/community` | `/community`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/courses` | `/courses`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/enhanced-settings` | `/enhanced-settings`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/exercises` | `/exercises`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/gamification` | `/gamification`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}` | `/`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/journal` | `/journal`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/micro-courses` | `/micro-courses`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/mini-games` | `/mini-games`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/personalized-recommendations` | `/personalized-recommendations`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/profile` | `/profile`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/psychology` | `/psychology`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/sounds` | `/sounds`; params?: Router.UnknownInputParams; } | { pathname: `${'/(tabs)'}/therapy` | `/therapy`; params?: Router.UnknownInputParams; } | { pathname: `/i18n`; params?: Router.UnknownInputParams; } | `/+not-found${`?${string}` | `#${string}` | ''}` | { pathname: `/+not-found`, params: Router.UnknownInputParams & { } }; } } } diff --git a/TASKS.md b/TASKS.md index b9d493b..7e1783b 100644 --- a/TASKS.md +++ b/TASKS.md @@ -316,7 +316,22 @@ - [x] Оптимизировать отображение психологического профиля в ИИ-Чате. - [x] Подготовить релиз v1.17.0 и обновить скриншоты. -# Список задач по улучшению приложения (Цикл 18) - ПЛАНИРОВАНИЕ 📅 +# Список задач по улучшению приложения (Цикл 18) - ВЫПОЛНЕНО ✅ + +## 💬 Геймификация Сообщества +- [x] Внедрить функцию "Трезвый напарник" (поиск бадди) с постоянным сохранением через AsyncStorage. +- [x] Реализовать ежедневный импульс поддержки напарника с вознаграждением +15 очков Кармы. +- [x] Добавить тактильную отдачу (Haptics) при отправке импульса и выборе напарника. + +## 🤖 AI-Ассистент и Исправления +- [x] Исправить критический ReferenceError в методе `AICoachService.getUserInsights` при интеграции ИИ-анализа сна. +- [x] Объединить и починить специализированные тесты анализа сна в `__tests__/AICoachSleepAnalysis.test.ts`. + +## 🎨 Интерфейс и UX +- [x] Создать интуитивно понятную карточку "Трезвый напарник" с индикаторами статуса и прогресса на вкладке общения. +- [x] Подготовить и выпустить релиз v1.18.0. + +# Список задач по улучшению приложения (Цикл 19) - ПЛАНИРОВАНИЕ 📅 ## 🤖 AI-Персонализация - [ ] Добавить ИИ-анализ физической активности (шаги) на основе данных здоровья. @@ -326,7 +341,6 @@ ## 💬 Геймификация Сообщества - [ ] Реализовать еженедельные турниры между группами поддержки. - [ ] Добавить систему "Коллективных наград" за общие достижения. -- [ ] Внедрить функцию "Трезвый напарник" (поиск бадди). ## 📚 Контент и Обучение - [ ] Разработать курс "Биохакинг трезвости: как восстановить тело". diff --git a/__tests__/AICoachSleepAnalysis.test.ts b/__tests__/AICoachSleepAnalysis.test.ts index 868ee10..d7a4f52 100644 --- a/__tests__/AICoachSleepAnalysis.test.ts +++ b/__tests__/AICoachSleepAnalysis.test.ts @@ -1,4 +1,7 @@ import { AICoachService } from '../services/AICoachService'; +import { JournalService } from '../services/journalService'; + +jest.mock('../services/journalService'); describe('AICoachService Sleep Quality Analysis', () => { it('should handle empty or missing entries gracefully', () => { @@ -42,11 +45,10 @@ describe('AICoachService Sleep Quality Analysis', () => { const result = AICoachService.analyzeSleepFromJournal(entries); expect(result.sleepQuality).toBe(3); // (5 + 1) / 2 = 3 expect(result.feedback).toContain('на среднем уровне'); -import { JournalService } from '../services/journalService'; - -jest.mock('../services/journalService'); + }); +}); -describe('AICoachService Sleep Analysis', () => { +describe('AICoachService Sleep Analysis from journalService', () => { beforeEach(() => { jest.clearAllMocks(); }); diff --git a/__tests__/CommunityBuddy.test.ts b/__tests__/CommunityBuddy.test.ts new file mode 100644 index 0000000..9d4eadb --- /dev/null +++ b/__tests__/CommunityBuddy.test.ts @@ -0,0 +1,71 @@ +import { CommunityService, SoberBuddy } from '../services/communityService'; +import AsyncStorage from '@react-native-async-storage/async-storage'; + +describe('CommunityService Sober Buddy ("Трезвый напарник") ', () => { + beforeEach(async () => { + jest.clearAllMocks(); + await AsyncStorage.clear(); + }); + + it('should return a non-empty list of potential buddies', () => { + const list = CommunityService.getPotentialBuddies(); + expect(list.length).toBeGreaterThan(0); + expect(list[0]).toHaveProperty('name'); + expect(list[0]).toHaveProperty('daysSober'); + expect(list[0]).toHaveProperty('avatar'); + expect(list[0]).toHaveProperty('status'); + }); + + it('should manage buddy selection and unpairing correctly', async () => { + // 1. Initial should be null + let buddy = await CommunityService.getSelectedBuddy(); + expect(buddy).toBeNull(); + + // 2. Select a buddy + const potential = CommunityService.getPotentialBuddies()[0]; + await CommunityService.selectBuddy(potential); + + // 3. Get selected buddy + buddy = await CommunityService.getSelectedBuddy(); + expect(buddy).not.toBeNull(); + expect(buddy!.id).toBe(potential.id); + + // 4. Remove buddy + await CommunityService.removeBuddy(); + buddy = await CommunityService.getSelectedBuddy(); + expect(buddy).toBeNull(); + }); + + it('should send daily support pulse and award +15 Karma', async () => { + const potential = CommunityService.getPotentialBuddies()[0]; + await CommunityService.selectBuddy(potential); + + // Initial karma should be 0 (or default) + let karma = await CommunityService.getUserKarma(); + expect(karma).toBe(0); + + // Send support pulse + const success = await CommunityService.sendBuddyPulse(); + expect(success).toBe(true); + + // Karma should increase by 15 + karma = await CommunityService.getUserKarma(); + expect(karma).toBe(15); + + // Buddy lastPulseSent should be set to today + const buddy = await CommunityService.getSelectedBuddy(); + expect(buddy!.lastPulseSent).toBe(new Date().toDateString()); + + // Try sending again today - should fail and not award karma + const secondTry = await CommunityService.sendBuddyPulse(); + expect(secondTry).toBe(false); + + karma = await CommunityService.getUserKarma(); + expect(karma).toBe(15); // Stays at 15 + }); + + it('should return false when sending pulse with no selected buddy', async () => { + const success = await CommunityService.sendBuddyPulse(); + expect(success).toBe(false); + }); +}); diff --git a/app/(tabs)/articles.tsx b/app/(tabs)/articles.tsx index 9d152f7..83c2a46 100644 --- a/app/(tabs)/articles.tsx +++ b/app/(tabs)/articles.tsx @@ -27,19 +27,7 @@ import { useRecovery } from '../../hooks/useRecovery'; const { width: screenWidth } = Dimensions.get('window'); -interface Article { - id: string; - title: string; - category: string; - readTime: number; - preview: string; - content: string; - tags: string[]; - icon: string; - color: string; -} - -import { articlesDatabase } from '../../services/articlesDatabase'; +import { articlesDatabase, Article } from '../../services/articlesDatabase'; import { ArticleQuiz } from '../../components/ArticleQuiz'; const articles: Article[] = articlesDatabase; diff --git a/app/(tabs)/community.tsx b/app/(tabs)/community.tsx index 49e9590..f19ad27 100644 --- a/app/(tabs)/community.tsx +++ b/app/(tabs)/community.tsx @@ -8,7 +8,7 @@ import { MaterialIcons } from '@expo/vector-icons'; import * as Haptics from 'expo-haptics'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { LinearGradient } from 'expo-linear-gradient'; -import { CommunityService, SuccessStory, SupportPost, ExpertQA, ReactionType, CommunityGoal, GroupChallenge, PulseActivity } from '../../services/communityService'; +import { CommunityService, SuccessStory, SupportPost, ExpertQA, ReactionType, CommunityGoal, GroupChallenge, PulseActivity, SoberBuddy } from '../../services/communityService'; import Animated, { FadeInUp, FadeInRight, useSharedValue, useAnimatedStyle, withSpring, withSequence, withTiming } from 'react-native-reanimated'; import { Skeleton } from '../../components/Skeleton'; @@ -18,7 +18,7 @@ const KarmaBadge = ({ userName }: { userName: string }) => { const [karma, setKarma] = useState(0); useEffect(() => { - CommunityService.getUserKarma(userName).then(setKarma); + CommunityService.getOtherUserKarma(userName).then(setKarma); }, [userName]); if (userName === 'Вы' || userName === 'Sober Path Bot') return null; @@ -280,12 +280,12 @@ const CommunityPulse = () => { }, []); return ( - + - - + + - {activeUsers} участников сейчас онлайн и поддерживают друг друга + {activeUsers} участников сейчас онлайн и поддерживают друг друга ); }; @@ -311,6 +311,12 @@ export default function CommunityPage() { const [isLoading, setIsLoading] = useState(true); const [userKarma, setUserKarma] = useState(0); + // Sober Buddy (Трезвый напарник) State + const [selectedBuddy, setSelectedBuddy] = useState(null); + const [potentialBuddies, setPotentialBuddies] = useState([]); + const [isBuddyModalVisible, setIsBuddyModalVisible] = useState(false); + const [hasSentPulseToday, setHasSentPulseToday] = useState(false); + useEffect(() => { const loadData = async () => { setIsLoading(true); @@ -318,6 +324,15 @@ export default function CommunityPage() { const karma = await CommunityService.getUserKarma(); setUserKarma(karma); + // Load buddy info + const buddy = await CommunityService.getSelectedBuddy(); + setSelectedBuddy(buddy); + setPotentialBuddies(CommunityService.getPotentialBuddies()); + if (buddy) { + const todayStr = new Date().toDateString(); + setHasSentPulseToday(buddy.lastPulseSent === todayStr); + } + // Simulate network delay await new Promise(resolve => setTimeout(resolve, 1500)); setStories(CommunityService.getSuccessStories()); @@ -449,6 +464,50 @@ export default function CommunityPage() { Alert.alert('Успех', 'Ваша история опубликована!'); }; + const handleSendBuddyPulse = async () => { + if (!selectedBuddy) return; + const success = await CommunityService.sendBuddyPulse(); + if (success) { + setHasSentPulseToday(true); + const updatedKarma = await CommunityService.getUserKarma(); + setUserKarma(updatedKarma); + Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success); + Alert.alert('Импульс отправлен! ⚡', 'Вы поддержали своего напарника и получили +15 очков Кармы!'); + } else { + Alert.alert('Уже отправлено', 'Вы уже отправляли импульс поддержки сегодня. Попробуйте завтра!'); + } + }; + + const handleSelectBuddy = async (buddy: SoberBuddy) => { + await CommunityService.selectBuddy(buddy); + setSelectedBuddy(buddy); + const todayStr = new Date().toDateString(); + setHasSentPulseToday(buddy.lastPulseSent === todayStr); + setIsBuddyModalVisible(false); + Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success); + Alert.alert('Напарник выбран! 🤝', `Теперь вашим напарником является ${buddy.name}. Поддерживайте друг друга каждый день!`); + }; + + const handleRemoveBuddy = async () => { + Alert.alert( + 'Разорвать связь?', + 'Вы действительно хотите отказаться от текущего напарника? Вы сможете выбрать нового в любой момент.', + [ + { text: 'Отмена', style: 'cancel' }, + { + text: 'Да, разорвать', + style: 'destructive', + onPress: async () => { + await CommunityService.removeBuddy(); + setSelectedBuddy(null); + setHasSentPulseToday(false); + Haptics.notificationAsync(Haptics.NotificationFeedbackType.Warning); + } + } + ] + ); + }; + const handleToggleChallenge = async (challengeId: string) => { const joined = await CommunityService.toggleChallengeParticipation(challengeId); const updatedChallenges = await CommunityService.getGroupChallenges(); @@ -495,6 +554,52 @@ export default function CommunityPage() { )} + {/* Трезвый напарник Widget */} + {!isLoading && ( + + + + ТРЕЗВЫЙ НАПАРНИК + + {selectedBuddy ? ( + + + + {selectedBuddy.name} + {selectedBuddy.daysSober} дней трезвости + + + {selectedBuddy.status} + + + + + + + {hasSentPulseToday ? 'Импульс отправлен' : 'Отправить импульс'} + + + + + + + + ) : ( + + У вас пока нет трезвого напарника. Вместе идти к трезвости легче и надежнее! + setIsBuddyModalVisible(true)}> + + Найти напарника + + + )} + + )} + Групповые челленджи @@ -884,6 +989,47 @@ export default function CommunityPage() { + + setIsBuddyModalVisible(false)} + > + + + + Выбор напарника + setIsBuddyModalVisible(false)}> + + + + + Выберите напарника (бадди), чтобы делиться поддержкой каждый день и зарабатывать очки Кармы. + + + {potentialBuddies.map(buddy => ( + handleSelectBuddy(buddy)} + > + + + {buddy.name} + {buddy.daysSober} дней трезвости + Статус: {buddy.status} + + + Выбрать + + + + ))} + + + + ); } @@ -1424,7 +1570,7 @@ const styles = StyleSheet.create({ borderRadius: 8, gap: 2, }, - mentorBadge: { + mentorBadgeLight: { backgroundColor: '#FFF8E1', borderWidth: 1, borderColor: '#FFD54F', @@ -1589,7 +1735,7 @@ const styles = StyleSheet.create({ marginBottom: 15, lineHeight: 20 }, - pulseContainer: { + bottomPulseContainer: { flexDirection: 'row', alignItems: 'center', marginHorizontal: 20, @@ -1610,7 +1756,7 @@ const styles = StyleSheet.create({ alignItems: 'center', marginRight: 10, }, - pulseDot: { + bottomPulseDot: { width: 8, height: 8, borderRadius: 4, @@ -1624,7 +1770,7 @@ const styles = StyleSheet.create({ backgroundColor: '#4CAF50', opacity: 0.4, }, - pulseText: { + bottomPulseText: { fontSize: 13, color: '#666', fontWeight: '500', @@ -1696,5 +1842,160 @@ const styles = StyleSheet.create({ color: '#999', textAlign: 'right', marginTop: 4, + }, + buddyWidgetContainer: { + marginHorizontal: 20, + backgroundColor: 'white', + borderRadius: 16, + padding: 16, + marginBottom: 20, + elevation: 2, + shadowColor: '#000', + shadowOffset: { width: 0, height: 1 }, + shadowOpacity: 0.1, + shadowRadius: 2, + }, + buddyWidgetHeader: { + flexDirection: 'row', + alignItems: 'center', + gap: 6, + marginBottom: 12, + }, + buddyWidgetTitle: { + fontSize: 12, + fontWeight: 'bold', + color: '#2E7D4A', + letterSpacing: 1, + }, + buddyCard: { + flexDirection: 'row', + alignItems: 'center', + }, + buddyAvatar: { + width: 50, + height: 50, + borderRadius: 25, + marginRight: 12, + }, + buddyInfo: { + flex: 1, + }, + buddyName: { + fontSize: 16, + fontWeight: 'bold', + color: '#333', + }, + buddyDays: { + fontSize: 12, + color: '#2E7D4A', + fontWeight: '600', + marginTop: 2, + }, + buddyStatusRow: { + flexDirection: 'row', + alignItems: 'center', + gap: 4, + marginTop: 4, + }, + buddyStatusDot: { + width: 6, + height: 6, + borderRadius: 3, + backgroundColor: '#4CAF50', + }, + buddyStatusText: { + fontSize: 11, + color: '#666', + }, + buddyActions: { + alignItems: 'flex-end', + gap: 8, + }, + pulseButton: { + flexDirection: 'row', + alignItems: 'center', + backgroundColor: '#FF9800', + paddingHorizontal: 12, + paddingVertical: 8, + borderRadius: 20, + gap: 4, + }, + pulseButtonSent: { + backgroundColor: '#9E9E9E', + }, + pulseButtonText: { + color: 'white', + fontSize: 11, + fontWeight: 'bold', + }, + unpairButton: { + padding: 4, + }, + noBuddyCard: { + alignItems: 'center', + paddingVertical: 10, + }, + noBuddyText: { + fontSize: 13, + color: '#666', + textAlign: 'center', + lineHeight: 18, + marginBottom: 12, + }, + findBuddyButton: { + flexDirection: 'row', + alignItems: 'center', + backgroundColor: '#2E7D4A', + paddingHorizontal: 16, + paddingVertical: 10, + borderRadius: 20, + gap: 6, + }, + findBuddyButtonText: { + color: 'white', + fontSize: 13, + fontWeight: 'bold', + }, + buddyListScroll: { + maxHeight: 300, + }, + buddySelectionItem: { + flexDirection: 'row', + alignItems: 'center', + paddingVertical: 12, + borderBottomWidth: 1, + borderBottomColor: '#F0F0F0', + }, + buddySelectAvatar: { + width: 44, + height: 44, + borderRadius: 22, + marginRight: 12, + }, + buddySelectName: { + fontSize: 14, + fontWeight: 'bold', + color: '#333', + }, + buddySelectDays: { + fontSize: 12, + color: '#2E7D4A', + fontWeight: '600', + marginTop: 2, + }, + buddySelectStatus: { + fontSize: 11, + color: '#888', + marginTop: 2, + }, + buddySelectAction: { + flexDirection: 'row', + alignItems: 'center', + gap: 4, + }, + buddySelectActionText: { + fontSize: 12, + color: '#2E7D4A', + fontWeight: 'bold', } }); diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx index 5b60bb3..f9f52fa 100644 --- a/app/(tabs)/index.tsx +++ b/app/(tabs)/index.tsx @@ -398,7 +398,7 @@ function HomePage() { {weeklyRoadmap.focus ? ( - + {weeklyRoadmap.focus} ) : null} @@ -1451,6 +1451,47 @@ const styles = StyleSheet.create({ color: 'white', fontWeight: 'bold', fontSize: 16 + }, + briefingFocus: { + fontSize: 16, + fontWeight: 'bold', + color: '#2E7D4A', + marginBottom: 15, + textAlign: 'center' + }, + briefingSectionTitle: { + fontSize: 15, + fontWeight: 'bold', + color: '#333', + marginTop: 15, + marginBottom: 8 + }, + briefingItem: { + flexDirection: 'row', + alignItems: 'center', + gap: 8, + marginBottom: 6, + paddingLeft: 4 + }, + briefingText: { + fontSize: 14, + color: '#555', + flex: 1 + }, + motivationQuoteBox: { + backgroundColor: '#E8F5E8', + borderRadius: 10, + padding: 12, + marginTop: 15, + borderLeftWidth: 4, + borderLeftColor: '#2E7D4A' + }, + briefingMotivation: { + fontSize: 14, + fontStyle: 'italic', + color: '#1B4D2E', + textAlign: 'center', + lineHeight: 20 } }); diff --git a/assets/screenshots/buddy_paired.png b/assets/screenshots/buddy_paired.png new file mode 100644 index 0000000..db35dcd Binary files /dev/null and b/assets/screenshots/buddy_paired.png differ diff --git a/assets/screenshots/buddy_selection_modal.png b/assets/screenshots/buddy_selection_modal.png new file mode 100644 index 0000000..ee02661 Binary files /dev/null and b/assets/screenshots/buddy_selection_modal.png differ diff --git a/assets/screenshots/verification_direct_community.png b/assets/screenshots/verification_direct_community.png new file mode 100644 index 0000000..aaf0a15 Binary files /dev/null and b/assets/screenshots/verification_direct_community.png differ diff --git a/package-lock.json b/package-lock.json index fcfd9a7..5032482 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "sober-path", - "version": "1.16.0", + "version": "1.17.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "sober-path", - "version": "1.16.0", + "version": "1.17.0", "dependencies": { "@expo-google-fonts/inter": "^0.4.1", "@expo/metro-runtime": "~5.0.5", diff --git a/services/AICoachService.ts b/services/AICoachService.ts index 0c11103..0343f7c 100644 --- a/services/AICoachService.ts +++ b/services/AICoachService.ts @@ -636,7 +636,7 @@ export class AICoachService { ? 'Ваше состояние улучшается.' : 'Мы продолжаем работу.', profile, - sleepAnalysis + sleepAnalysis: sleepData }; } @@ -1011,7 +1011,7 @@ export class AICoachService { // Интеграция анализа сна в брифинг const sleepData = await this.analyzeSleepPatterns(); if (sleepData.averageScore < 60) { - briefing.quickTips.push('Уделите внимание сну: плохой сон — частый триггер срыва.'); + quickTips.push('Уделите внимание сну: плохой сон — частый триггер срыва.'); } if (soberDays > 30 && !briefing.plan.includes("Поделиться опытом в сообществе")) { diff --git a/services/communityService.ts b/services/communityService.ts index 9d794cf..81bb967 100644 --- a/services/communityService.ts +++ b/services/communityService.ts @@ -74,13 +74,92 @@ export interface GroupChallenge { category: string; } +export interface SoberBuddy { + id: string; + name: string; + daysSober: number; + avatar: string; + status: string; + lastPulseSent?: string; // Date string to track daily pulse +} + const POSTS_STORAGE_KEY = 'sober_path_community_posts'; const CHALLENGES_STORAGE_KEY = 'sober_path_community_challenges'; const KARMA_STORAGE_KEY = 'sober_path_community_karma'; +const BUDDY_STORAGE_KEY = 'sober_path_community_buddy'; export class CommunityService { private static userPosts: SupportPost[] = []; + /** + * Получить список потенциальных напарников для выбора. + */ + static getPotentialBuddies(): SoberBuddy[] { + return [ + { id: 'b1', name: 'Дмитрий К.', daysSober: 125, avatar: 'https://i.pravatar.cc/150?u=dmitry', status: 'Мотивирован' }, + { id: 'b2', name: 'Мария П.', daysSober: 42, avatar: 'https://i.pravatar.cc/150?u=maria', status: 'Нужна поддержка' }, + { id: 'b3', name: 'Елена В.', daysSober: 88, avatar: 'https://i.pravatar.cc/150?u=elena', status: 'В сети' }, + { id: 'b4', name: 'Игорь С.', daysSober: 215, avatar: 'https://i.pravatar.cc/150?u=igor', status: 'Мотивирован' }, + { id: 'b5', name: 'Ольга М.', daysSober: 31, avatar: 'https://i.pravatar.cc/150?u=olga', status: 'В сети' } + ]; + } + + /** + * Получить выбранного напарника из AsyncStorage. + */ + static async getSelectedBuddy(): Promise { + try { + const stored = await AsyncStorage.getItem(BUDDY_STORAGE_KEY); + return stored ? JSON.parse(stored) : null; + } catch (e) { + return null; + } + } + + /** + * Сохранить выбранного напарника в AsyncStorage. + */ + static async selectBuddy(buddy: SoberBuddy): Promise { + try { + await AsyncStorage.setItem(BUDDY_STORAGE_KEY, JSON.stringify(buddy)); + } catch (e) { + console.error('Failed to select buddy', e); + } + } + + /** + * Удалить выбранного напарника (разрушить пару). + */ + static async removeBuddy(): Promise { + try { + await AsyncStorage.removeItem(BUDDY_STORAGE_KEY); + } catch (e) { + console.error('Failed to remove buddy', e); + } + } + + /** + * Отправить импульс поддержки напарнику (+15 Кармы, раз в день). + */ + static async sendBuddyPulse(): Promise { + try { + const buddy = await this.getSelectedBuddy(); + if (!buddy) return false; + + const todayStr = new Date().toDateString(); + if (buddy.lastPulseSent === todayStr) { + return false; + } + + await this.addKarmaPoints(15); + buddy.lastPulseSent = todayStr; + await this.selectBuddy(buddy); + return true; + } catch (e) { + return false; + } + } + /** * Получить текущее количество очков Кармы (Очков поддержки) пользователя. */ @@ -713,7 +792,7 @@ export class CommunityService { } } - static async getUserKarma(userName: string): Promise { + static async getOtherUserKarma(userName: string): Promise { try { const stored = await AsyncStorage.getItem(KARMA_STORAGE_KEY); const karmaMap = stored ? JSON.parse(stored) : {};