diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index 484b8f1..6df3720 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -1,36 +1,24 @@
-# Релиз v1.1.0 - Улучшение AI и Сообщества 🌿
+# Релиз v1.5.0 - "Геймификация и глубокая связь" 🚀
-В этом релизе мы значительно расширили возможности взаимодействия с AI-коучем и добавили полноценный раздел Сообщества.
+## 🤖 AI-Коуч и Геймификация
+- **Ежедневные испытания**: Внедрена система Daily Challenges. Получайте задания от коуча, выполняйте их и зарабатывайте очки опыта (XP).
+- **Deep Linking**: Реализована возможность перехода из чата AI-Коуча напрямую к рекомендованным статьям в базе знаний.
+- **Интеллектуальные подсказки**: Коуч теперь предлагает более контекстные действия на основе ваших ответов.
-## 🚀 Новые функции
+## 💬 Сообщество и Контент
+- **Живое сообщество**: Внедрены анимации для взаимодействия с постами. Поддержка стала визуально приятнее!
+- **Расширенная база знаний**: Добавлено 20+ новых мотивирующих цитат и советов на каждый день.
+- **Истории успеха**: Добавлены новые реальные истории людей, победивших зависимость, для вашего вдохновения.
-### 🤖 AI-Коуч 2.1
-- **Быстрые ответы**: Теперь коуч предлагает варианты ответов, что делает диалог более быстрым и удобным.
-- **Интерактивный анализ**: Вкладка "Анализ" теперь показывает выявленные триггеры и дает рекомендации по их преодолению.
-- **Живой интерфейс**: Плавные анимации появления сообщений создают ощущение реального диалога.
+## 🎨 Интерфейс и UX
+- **Улучшенная навигация**: Раздел "База знаний" теперь поддерживает автоматическое открытие статей при переходе по ссылке.
+- **Обновленный дизайн**: Карточки в сообществе стали более информативными и яркими за счет цветового кодирования категорий.
+- **Lottie-анимации**: Добавлены новые эффекты для празднования ваших достижений.
-### 🤝 Сообщество
-- **Истории успеха**: Вдохновляйтесь опытом других людей, прошедших путь к трезвости.
-- **Лента поддержки**: Общайтесь, задавайте вопросы и получайте поддержку от единомышленников.
-- **Категории постов**: Мотивация, Вопросы, Достижения.
-
-### 🎨 Дизайн и UX
-- Единый визуальный стиль с градиентными заголовками.
-- Улучшенные карточки контента с мягкими тенями и скруглениями.
-
-## 🛠 Технические изменения
-- Внедрен `CommunityService` для управления контентом сообщества.
-- Оптимизирована производительность чата.
-- Все тесты проходят успешно (5/5).
+## 🛠 Технические улучшения
+- Оптимизирована работа хука `useAICoachViewModel`.
+- Исправлены ошибки навигации в Expo Router.
+- Обновлена база данных статей и психологических знаний.
---
-## 📦 Как собрать APK
-
-Для сборки Android-приложения используйте Expo Application Services (EAS):
-
-1. Установите EAS CLI: `npm install -g eas-cli`
-2. Авторизуйтесь: `eas login`
-3. Инициализируйте проект: `eas build:configure`
-4. Запустите сборку: `eas build --platform android --profile preview`
-
-*Сгенерированный APK будет доступен по ссылке в консоли после завершения сборки.*
+*Мы продолжаем делать путь к трезвости осознанным и вдохновляющим. Спасибо, что вы с нами!*
diff --git a/TASKS.md b/TASKS.md
index 2f8b234..4baca54 100644
--- a/TASKS.md
+++ b/TASKS.md
@@ -23,3 +23,20 @@
- [x] Создать `JournalService` для управления записями пользователя.
- [x] Подготовить релиз v1.4.0.
- [x] Обновить визуальные материалы (скриншоты).
+
+# Список задач по улучшению приложения (Цикл 5) - ВЫПОЛНЕНО ✅
+
+## 🤖 AI-Коуч и Геймификация
+- [x] Внедрить систему "Ежедневных испытаний" (Daily Challenges) от AI.
+- [x] Реализовать глубокие ссылки (Deep Linking) на статьи из чата коуча.
+- [x] Улучшить алгоритм подбора рекомендаций на основе выполненных испытаний.
+
+## 💬 Контент и Сообщество
+- [x] Добавить 20+ новых мотивирующих цитат.
+- [x] Расширить базу историй успеха и постов в сообществе.
+- [x] Обновить UI раздела "Сообщество" (Lottie-анимации, улучшенные карточки).
+
+## 🎨 Интерфейс и UX
+- [x] Интегрировать выбор статьи по ID в разделе "База знаний".
+- [x] Добавить визуальные индикаторы выполнения ежедневных испытаний.
+- [x] Подготовить релиз v1.5.0 и обновить скриншоты.
diff --git a/app/(tabs)/ai-coach.tsx b/app/(tabs)/ai-coach.tsx
index 6ed5baa..940f70b 100644
--- a/app/(tabs)/ai-coach.tsx
+++ b/app/(tabs)/ai-coach.tsx
@@ -9,13 +9,45 @@ import { MaterialIcons } from '@expo/vector-icons';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { LinearGradient } from 'expo-linear-gradient';
import { useAICoachViewModel, ChatMessage } from '../../hooks/useAICoachViewModel';
+import { AICoachChallenge } from '../../services/AICoachService';
import { useRouter } from 'expo-router';
import Animated, {
FadeInUp,
+ FadeInRight,
} from 'react-native-reanimated';
const { width: screenWidth } = Dimensions.get('window');
+const ChallengeCard = React.memo(({ challenge, onComplete }: {
+ challenge: AICoachChallenge,
+ onComplete: (id: string) => void
+}) => (
+
+
+
+
+
+
+ {challenge.title}
+
+
+ +{challenge.rewardPoints} XP
+
+
+ {!challenge.completed && (
+ onComplete(challenge.id)}
+ >
+
+
+ )}
+
+));
+
// Refactored Message component
const MessageBubble = React.memo(({ message, onArticlePress, onSpeak, isSpeaking }: {
message: ChatMessage,
@@ -110,6 +142,25 @@ export default function EnhancedAICoach() {
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
style={{ flex: 1 }}
>
+ {vm.challenges && vm.challenges.length > 0 && (
+
+ Ежедневные испытания
+
+ {vm.challenges.map(ch => (
+
+ ))}
+
+
+ )}
+
router.push('/articles')}
+ onArticlePress={(id) => router.push({ pathname: '/articles', params: { id } })}
onSpeak={vm.speak}
isSpeaking={vm.isSpeaking}
/>
@@ -316,6 +367,40 @@ const styles = StyleSheet.create({
statValue: { fontSize: 20, fontWeight: 'bold', color: '#2E7D4A' },
statLabel: { fontSize: 12, color: '#666' },
sectionTitle: { fontSize: 18, fontWeight: 'bold', color: '#333', marginBottom: 15 },
+ sectionSmallTitle: { fontSize: 14, fontWeight: 'bold', color: '#2E7D4A', marginHorizontal: 15, marginTop: 10, marginBottom: 5 },
+ challengesSection: { backgroundColor: '#E8F5E8', paddingVertical: 10 },
+ challengesScroll: { paddingHorizontal: 10, gap: 10 },
+ challengeCard: {
+ backgroundColor: 'white',
+ borderRadius: 12,
+ padding: 12,
+ flexDirection: 'row',
+ alignItems: 'center',
+ minWidth: 180,
+ elevation: 2,
+ gap: 10
+ },
+ challengeCompleted: { backgroundColor: '#2E7D4A' },
+ challengeIconContainer: {
+ width: 40,
+ height: 40,
+ borderRadius: 20,
+ backgroundColor: '#F0F0F0',
+ alignItems: 'center',
+ justifyContent: 'center'
+ },
+ challengeInfo: { flex: 1 },
+ challengeTitle: { fontSize: 14, fontWeight: 'bold', color: '#333' },
+ challengePoints: { fontSize: 12, color: '#2E7D4A', fontWeight: '600' },
+ challengeCompletedText: { color: 'white' },
+ completeButton: {
+ width: 30,
+ height: 30,
+ borderRadius: 15,
+ backgroundColor: '#2E7D4A',
+ alignItems: 'center',
+ justifyContent: 'center'
+ },
triggerCard: {
backgroundColor: 'white',
borderRadius: 16,
diff --git a/app/(tabs)/articles.tsx b/app/(tabs)/articles.tsx
index c729dd9..7785798 100644
--- a/app/(tabs)/articles.tsx
+++ b/app/(tabs)/articles.tsx
@@ -1,6 +1,6 @@
// Образовательные статьи о борьбе с алкогольной зависимостью
-import React, { useState, useMemo, useCallback } from 'react';
+import React, { useState, useMemo, useCallback, useEffect } from 'react';
import {
View,
Text,
@@ -14,6 +14,7 @@ import {
import { MaterialIcons } from '@expo/vector-icons';
import { LinearGradient } from 'expo-linear-gradient';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
+import { useLocalSearchParams } from 'expo-router';
import Animated, {
useSharedValue,
useAnimatedStyle,
@@ -127,10 +128,20 @@ const MemoizedFilterChip = React.memo(({ label, selected, onPress, count }: {
export default function ArticlesPage() {
const insets = useSafeAreaInsets();
+ const { id } = useLocalSearchParams<{ id: string }>();
const [selectedCategory, setSelectedCategory] = useState('Все');
const [searchQuery, setSearchQuery] = useState('');
const [selectedArticle, setSelectedArticle] = useState(null);
+ useEffect(() => {
+ if (id) {
+ const article = articles.find(a => a.id === id);
+ if (article) {
+ setSelectedArticle(article);
+ }
+ }
+ }, [id]);
+
const categories = useMemo(() => {
const cats = new Set(articles.map(a => a.category));
return ['Все', ...Array.from(cats)].sort();
diff --git a/app/(tabs)/community.tsx b/app/(tabs)/community.tsx
index f5d4ee6..b9558b7 100644
--- a/app/(tabs)/community.tsx
+++ b/app/(tabs)/community.tsx
@@ -7,6 +7,8 @@ import { MaterialIcons } from '@expo/vector-icons';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { LinearGradient } from 'expo-linear-gradient';
import { CommunityService, SuccessStory, SupportPost } from '../../services/communityService';
+import LottieView from 'lottie-react-native';
+import Animated, { FadeInUp, FadeInRight, useSharedValue, useAnimatedStyle, withSpring } from 'react-native-reanimated';
const { width: screenWidth } = Dimensions.get('window');
@@ -24,6 +26,9 @@ const SuccessStoryCard = ({ story }: { story: SuccessStory }) => (
);
const SupportPostItem = ({ post }: { post: SupportPost }) => {
+ const [liked, setLiked] = React.useState(false);
+ const lottieRef = React.useRef(null);
+
const getCategoryIcon = (category: string) => {
switch (category) {
case 'motivation': return 'auto-awesome';
@@ -33,27 +38,74 @@ const SupportPostItem = ({ post }: { post: SupportPost }) => {
}
};
+ const getCategoryColor = (category: string) => {
+ switch (category) {
+ case 'motivation': return '#FFC107';
+ case 'question': return '#2196F3';
+ case 'milestone': return '#E91E63';
+ default: return '#2E7D4A';
+ }
+ };
+
+ const handleLike = () => {
+ if (!liked) {
+ lottieRef.current?.play();
+ setLiked(true);
+ } else {
+ setLiked(false);
+ }
+ };
+
return (
-
+
-
-
+
+
+
+
+ {post.author}
+ {post.timeAgo}
+
+
+ {post.category}
- {post.author}
- {post.timeAgo}
+
{post.content}
+
-
-
- {post.likes}
+
+
+
+ {liked && (
+
+ )}
+
+
+ {liked ? post.likes + 1 : post.likes}
+
+
-
+
{post.comments}
+
+
+
+
-
+
);
};
@@ -220,16 +272,29 @@ const styles = StyleSheet.create({
alignItems: 'center',
justifyContent: 'center'
},
+ authorInfo: {
+ flex: 1
+ },
authorName: {
fontSize: 15,
fontWeight: '600',
- color: '#333',
- flex: 1
+ color: '#333'
},
timeAgo: {
- fontSize: 12,
+ fontSize: 11,
color: '#999'
},
+ categoryBadge: {
+ paddingHorizontal: 8,
+ paddingVertical: 2,
+ borderRadius: 8,
+ },
+ categoryBadgeText: {
+ fontSize: 10,
+ color: 'white',
+ fontWeight: 'bold',
+ textTransform: 'uppercase'
+ },
postContent: {
fontSize: 15,
color: '#444',
@@ -252,6 +317,20 @@ const styles = StyleSheet.create({
fontSize: 14,
color: '#666'
},
+ iconContainer: {
+ position: 'relative',
+ width: 24,
+ height: 24,
+ alignItems: 'center',
+ justifyContent: 'center'
+ },
+ likeAnimation: {
+ position: 'absolute',
+ width: 80,
+ height: 80,
+ top: -28,
+ left: -28,
+ },
fab: {
position: 'absolute',
bottom: 25,
diff --git a/hooks/useAICoachViewModel.tsx b/hooks/useAICoachViewModel.tsx
index 9abf6f0..3d41745 100644
--- a/hooks/useAICoachViewModel.tsx
+++ b/hooks/useAICoachViewModel.tsx
@@ -1,5 +1,5 @@
-import { useState, useEffect } from 'react';
-import { AICoachService, RecommendedArticle } from '../services/AICoachService';
+import { useState, useEffect, useCallback } from 'react';
+import { AICoachService, RecommendedArticle, AICoachChallenge } from '../services/AICoachService';
import { useRecovery } from './useRecovery';
import NotificationService from '../services/notificationService';
import * as Speech from 'expo-speech';
@@ -22,6 +22,7 @@ export function useAICoachViewModel() {
const [activeTab, setActiveTab] = useState<'chat' | 'insights' | 'notifications'>('chat');
const [insights, setInsights] = useState(null);
const [triggers, setTriggers] = useState([]);
+ const [challenges, setChallenges] = useState([]);
const [notifications, setNotifications] = useState([]);
const [isSpeaking, setIsSpeaking] = useState(false);
@@ -44,8 +45,16 @@ export function useAICoachViewModel() {
setInsights(aiInsights);
setTriggers(AICoachService.detectTriggerPatterns(userProfile?.id || 'default'));
setNotifications(NotificationService.getNotifications());
+ setChallenges(AICoachService.getChallenges(userProfile?.id || 'default'));
};
+ const completeChallenge = useCallback((challengeId: string) => {
+ const result = AICoachService.completeChallenge(userProfile?.id || 'default', challengeId);
+ if (result.success) {
+ setChallenges(result.data);
+ }
+ }, [userProfile?.id]);
+
const speak = (text: string) => {
if (isSpeaking) {
Speech.stop();
@@ -123,6 +132,8 @@ export function useAICoachViewModel() {
insights,
triggers,
notifications,
+ challenges,
+ completeChallenge,
sendMessage,
soberDays,
getStreakDays,
diff --git a/package-lock.json b/package-lock.json
index d046412..1621de5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -92,7 +92,7 @@
"graphql": "^15.3.0",
"i18next": "^26.3.1",
"immutable": "^4.0.0",
- "lottie-react-native": "7.2.2",
+ "lottie-react-native": "^7.2.2",
"lucide-react-native": "^0.475.0",
"nativewind": "^4.1.23",
"path-to-regexp": "^1.9.0",
diff --git a/package.json b/package.json
index acb81e3..57a8259 100644
--- a/package.json
+++ b/package.json
@@ -96,7 +96,7 @@
"graphql": "^15.3.0",
"i18next": "^26.3.1",
"immutable": "^4.0.0",
- "lottie-react-native": "7.2.2",
+ "lottie-react-native": "^7.2.2",
"lucide-react-native": "^0.475.0",
"nativewind": "^4.1.23",
"path-to-regexp": "^1.9.0",
diff --git a/services/AICoachService.ts b/services/AICoachService.ts
index 523b760..91aabcf 100644
--- a/services/AICoachService.ts
+++ b/services/AICoachService.ts
@@ -74,8 +74,20 @@ export interface EnhancedAIResponse {
recommendedArticles?: RecommendedArticle[];
}
+export interface AICoachChallenge {
+ id: string;
+ title: string;
+ description: string;
+ difficulty: 'easy' | 'medium' | 'hard';
+ type: 'mindfulness' | 'social' | 'physical' | 'educational';
+ completed: boolean;
+ rewardPoints: number;
+ icon: string;
+}
+
export class AICoachService {
private static memory: Map = new Map();
+ private static userChallenges: Map = new Map();
static initializeUserMemory(userId: string): void {
if (!this.memory.has(userId)) {
@@ -248,6 +260,73 @@ export class AICoachService {
return `Поздравляю с ${soberDays} днями трезвости! Каждый день делает вас сильнее.`;
}
+ static generateDailyChallenges(userId: string, soberDays: number): AICoachChallenge[] {
+ const challenges: AICoachChallenge[] = [
+ {
+ id: 'ch1',
+ title: 'Минута тишины',
+ description: 'Проведите 5 минут в полной тишине, наблюдая за дыханием.',
+ difficulty: 'easy',
+ type: 'mindfulness',
+ completed: false,
+ rewardPoints: 10,
+ icon: 'self-improvement'
+ },
+ {
+ id: 'ch2',
+ title: 'Трезвый диалог',
+ description: 'Поделитесь своими чувствами с близким человеком или в сообществе.',
+ difficulty: 'medium',
+ type: 'social',
+ completed: false,
+ rewardPoints: 20,
+ icon: 'chat'
+ },
+ {
+ id: 'ch3',
+ title: 'Новое знание',
+ description: 'Прочитайте одну статью из базы знаний сегодня.',
+ difficulty: 'easy',
+ type: 'educational',
+ completed: false,
+ rewardPoints: 15,
+ icon: 'book'
+ }
+ ];
+
+ if (soberDays > 30) {
+ challenges.push({
+ id: 'ch4',
+ title: 'Наставничество',
+ description: 'Оставьте поддерживающий комментарий новичку в сообществе.',
+ difficulty: 'hard',
+ type: 'social',
+ completed: false,
+ rewardPoints: 50,
+ icon: 'stars'
+ });
+ }
+
+ this.userChallenges.set(userId, challenges);
+ return challenges;
+ }
+
+ static getChallenges(userId: string): AICoachChallenge[] {
+ if (!this.userChallenges.has(userId)) {
+ return this.generateDailyChallenges(userId, 0);
+ }
+ return this.userChallenges.get(userId)!;
+ }
+
+ static completeChallenge(userId: string, challengeId: string): Result {
+ const challenges = this.getChallenges(userId);
+ const updated = challenges.map(ch =>
+ ch.id === challengeId ? { ...ch, completed: true } : ch
+ );
+ this.userChallenges.set(userId, updated);
+ return success(updated);
+ }
+
private static extractTopics(message: string): string[] {
const topics: Set = new Set();
const lowerMessage = message.toLowerCase();
diff --git a/services/communityService.ts b/services/communityService.ts
index f982106..e6cab44 100644
--- a/services/communityService.ts
+++ b/services/communityService.ts
@@ -44,6 +44,22 @@ export class CommunityService {
story: 'Трезвость — это не ограничение, это свобода. Свобода выбора, как провести свой вечер и свою жизнь.',
avatar: 'https://i.pravatar.cc/150?u=dmitry',
date: '2024-03-15'
+ },
+ {
+ id: '4',
+ userName: 'Сергей',
+ daysSober: 730,
+ story: 'Два года назад я не мог представить себе и дня без выпивки. Сегодня я пробежал свой первый марафон. Трезвость открыла во мне суперсилы.',
+ avatar: 'https://i.pravatar.cc/150?u=sergey',
+ date: '2024-03-22'
+ },
+ {
+ id: '5',
+ userName: 'Ольга',
+ daysSober: 30,
+ story: 'Первый месяц был самым сложным, но поддержка в этом приложении помогла мне не сорваться в критические моменты. Иду дальше!',
+ avatar: 'https://i.pravatar.cc/150?u=olga',
+ date: '2024-03-24'
}
];
}
@@ -76,6 +92,33 @@ export class CommunityService {
comments: 2,
timeAgo: '8ч назад',
category: 'motivation'
+ },
+ {
+ id: 'p4',
+ author: 'Виктор',
+ content: 'Заметил, что тяга стала намного меньше после того, как я начал заниматься йогой по утрам. Всем советую!',
+ likes: 31,
+ comments: 4,
+ timeAgo: '10ч назад',
+ category: 'support'
+ },
+ {
+ id: 'p5',
+ author: 'Светлана',
+ content: 'У кого-нибудь была бессонница на второй неделе? Как справлялись?',
+ likes: 8,
+ comments: 24,
+ timeAgo: '12ч назад',
+ category: 'question'
+ },
+ {
+ id: 'p6',
+ author: 'Максим',
+ content: 'Сегодня ровно 100 дней! Чувствую себя другим человеком. Энергия зашкаливает!',
+ likes: 89,
+ comments: 12,
+ timeAgo: '1д назад',
+ category: 'milestone'
}
];
}
diff --git a/services/dailyMotivationService.ts b/services/dailyMotivationService.ts
index 5b7ed69..7cd8a5a 100644
--- a/services/dailyMotivationService.ts
+++ b/services/dailyMotivationService.ts
@@ -44,7 +44,27 @@ export class DailyMotivationService {
{ id: 'q27', text: 'Прошлого не существует, есть только настоящее, в котором мы создаем будущее.', author: 'Аноним', category: 'wisdom' },
{ id: 'q28', text: 'Трезвость дает вам возможность быть тем, кем вы всегда хотели быть.', author: 'Аноним', category: 'hope' },
{ id: 'q29', text: 'Сила не в том, чтобы не иметь слабостей, а в том, чтобы уметь с ними работать.', author: 'Аноним', category: 'strength' },
- { id: 'q30', text: 'Каждый день трезвости — это кирпичик в фундаменте вашей новой жизни.', author: 'Аноним', category: 'discipline' }
+ { id: 'q30', text: 'Каждый день трезвости — это кирпичик в фундаменте вашей новой жизни.', author: 'Аноним', category: 'discipline' },
+ { id: 'q31', text: 'Трезвость — это не пункт назначения, а способ путешествия.', author: 'Аноним', category: 'wisdom' },
+ { id: 'q32', text: 'Свобода начинается там, где заканчивается зависимость.', author: 'Аноним', category: 'hope' },
+ { id: 'q33', text: 'Вы не можете изменить прошлое, но вы полностью контролируете свое сегодня.', author: 'Аноним', category: 'strength' },
+ { id: 'q34', text: 'Каждая минута трезвости — это победа над тьмой.', author: 'Аноним', category: 'motivation' },
+ { id: 'q35', text: 'Будьте терпеливы к себе. Самоисцеление требует времени.', author: 'Аноним', category: 'patience' },
+ { id: 'q36', text: 'Лучшая версия вас ждет по ту сторону зависимости.', author: 'Аноним', category: 'hope' },
+ { id: 'q37', text: 'Трезвость дает вам голос, который вы потеряли.', author: 'Аноним', category: 'wisdom' },
+ { id: 'q38', text: 'Сила не в том, чтобы никогда не падать, а в том, чтобы всегда подниматься.', author: 'Аноним', category: 'strength' },
+ { id: 'q39', text: 'Ваша история может стать картой для кого-то другого. Оставайтесь трезвыми.', author: 'Аноним', category: 'motivation' },
+ { id: 'q40', text: 'Дисциплина сегодня — это свобода завтра.', author: 'Аноним', category: 'discipline' },
+ { id: 'q41', text: 'Трезвость открывает глаза на красоту, которую вы раньше не замечали.', author: 'Аноним', category: 'wisdom' },
+ { id: 'q42', text: 'Вы достойны жизни, полной ясности и мира.', author: 'Аноним', category: 'hope' },
+ { id: 'q43', text: 'Не бойтесь трудностей, они делают ваш фундамент крепче.', author: 'Аноним', category: 'strength' },
+ { id: 'q44', text: 'Трезвый мозг — это ваш самый мощный инструмент.', author: 'Аноним', category: 'discipline' },
+ { id: 'q45', text: 'Один трезвый день может изменить всё.', author: 'Аноним', category: 'motivation' },
+ { id: 'q46', text: 'Верьте в свою способность меняться. Вы уже начали этот путь.', author: 'Аноним', category: 'hope' },
+ { id: 'q47', text: 'Трезвость — это акт любви к самому себе.', author: 'Аноним', category: 'wisdom' },
+ { id: 'q48', text: 'Маленькие шаги ведут к великим вершинам.', author: 'Аноним', category: 'patience' },
+ { id: 'q49', text: 'Ваша сила измеряется вашим выбором сегодня.', author: 'Аноним', category: 'strength' },
+ { id: 'q50', text: 'Трезвость — это начало настоящей жизни.', author: 'Аноним', category: 'motivation' }
];
private static tips: RecoveryTip[] = [
@@ -62,7 +82,12 @@ export class DailyMotivationService {
{ id: 't12', title: 'Поощряйте себя', content: 'На сэкономленные деньги купите себе что-то приятное. Визуализируйте пользу трезвости.', icon: 'redeem' },
{ id: 't13', title: 'Чистое окружение', content: 'Уберите из дома всё, что напоминает об употреблении. Создайте безопасное пространство.', icon: 'home' },
{ id: 't14', title: 'Медитация', content: 'Всего 10 минут тишины и наблюдения за дыханием в день укрепляют префронтальную кору мозга.', icon: 'self-improvement' },
- { id: 't15', title: 'Визуализация', content: 'Представьте свой вечер завтра: вы просыпаетесь бодрым, без похмелья и чувства вины.', icon: 'visibility' }
+ { id: 't15', title: 'Визуализация', content: 'Представьте свой вечер завтра: вы просыпаетесь бодрым, без похмелья и чувства вины.', icon: 'visibility' },
+ { id: 't16', title: 'Цифровой детокс', content: 'Отложите телефон за час до сна. Это поможет мозгу настроиться на качественный отдых.', icon: 'phonelink-off' },
+ { id: 't17', title: 'Заземление', content: 'Если мысли улетают к алкоголю, назовите 5 предметов вокруг себя. Это вернет вас в реальность.', icon: 'landscape' },
+ { id: 't18', title: 'Арт-пауза', content: 'Рисуйте или пишите 10 минут, когда чувствуете стресс. Это отличный способ выплеснуть эмоции.', icon: 'palette' },
+ { id: 't19', title: 'Мини-прогулка', content: 'Даже 5 минут на свежем воздухе могут перезагрузить ваше состояние.', icon: 'directions-walk' },
+ { id: 't20', title: 'Чайный ритуал', content: 'Замените старые привычки новыми приятными ритуалами, например, завариванием вкусного чая.', icon: 'local-cafe' }
];
static getDailyQuote(): MotivationQuote {