Implement husband-wife connection dialogue and theme support for learn articles

This commit is contained in:
2026-01-05 17:09:15 -06:00
parent 02d25d0cc7
commit 96655f9a74
36 changed files with 3849 additions and 819 deletions

View File

@@ -10,6 +10,7 @@ import '../../services/mock_data_service.dart'; // Import mock service
import '../calendar/calendar_screen.dart'; // Import calendar
import 'husband_notes_screen.dart'; // Import notes screen
import 'learn_article_screen.dart'; // Import learn article screen
import 'husband_devotional_screen.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
/// Husband's companion app main screen
@@ -34,7 +35,7 @@ class _HusbandHomeScreenState extends ConsumerState<HusbandHomeScreen> {
children: [
const _HusbandDashboard(),
const CalendarScreen(readOnly: true), // Reused Calendar
const HusbandNotesScreen(), // Notes Screen
const HusbandDevotionalScreen(), // Devotional & Planning
const _HusbandTipsScreen(),
const _HusbandLearnScreen(),
const _HusbandSettingsScreen(),
@@ -70,9 +71,9 @@ class _HusbandHomeScreenState extends ConsumerState<HusbandHomeScreen> {
label: 'Calendar',
),
BottomNavigationBarItem(
icon: Icon(Icons.note_alt_outlined),
activeIcon: Icon(Icons.note_alt),
label: 'Notes',
icon: Icon(Icons.menu_book_outlined),
activeIcon: Icon(Icons.menu_book),
label: 'Devotion',
),
BottomNavigationBarItem(
icon: Icon(Icons.lightbulb_outline),
@@ -1253,10 +1254,12 @@ class _HusbandSettingsScreen extends ConsumerWidget {
void _showConnectDialog(BuildContext context, WidgetRef ref) {
final codeController = TextEditingController();
bool shareDevotional = true;
showDialog(
context: context,
builder: (context) => AlertDialog(
builder: (context) => StatefulBuilder(
builder: (context, setState) => AlertDialog(
title: Row(
children: [
const Icon(Icons.link, color: AppColors.navyBlue),
@@ -1286,6 +1289,37 @@ class _HusbandSettingsScreen extends ConsumerWidget {
'Your wife can find this code in her Settings under "Share with Husband".',
style: GoogleFonts.outfit(fontSize: 12, color: AppColors.warmGray),
),
const SizedBox(height: 24),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 24,
width: 24,
child: Checkbox(
value: shareDevotional,
onChanged: (val) => setState(() => shareDevotional = val ?? true),
activeColor: AppColors.navyBlue,
),
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Share Devotional Plans',
style: GoogleFonts.outfit(fontWeight: FontWeight.bold, fontSize: 14, color: AppColors.charcoal),
),
Text(
'Allow her to see the teaching plans you create.',
style: GoogleFonts.outfit(fontSize: 12, color: AppColors.warmGray),
),
],
),
),
],
),
],
),
actions: [
@@ -1296,36 +1330,44 @@ class _HusbandSettingsScreen extends ConsumerWidget {
ElevatedButton(
onPressed: () async {
final code = codeController.text.trim();
if (code.isEmpty) return;
// In a real app, this would validate the code against a backend
// For now, we'll just show a success message and simulate pairing
Navigator.pop(context);
// Update preference
final user = ref.read(userProfileProvider);
if (user != null) {
await ref.read(userProfileProvider.notifier).updateProfile(
user.copyWith(isDataShared: shareDevotional)
);
}
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Connected! Loading wife\'s data...'),
content: Text('Settings updated & Connected!'),
backgroundColor: AppColors.sageGreen,
),
);
// Load demo data as simulation of pairing
final mockService = MockDataService();
final entries = mockService.generateMockCycleEntries();
for (var entry in entries) {
await ref.read(cycleEntriesProvider.notifier).addEntry(entry);
}
final mockWife = mockService.generateMockWifeProfile();
final currentProfile = ref.read(userProfileProvider);
if (currentProfile != null) {
final updatedProfile = currentProfile.copyWith(
partnerName: mockWife.name,
averageCycleLength: mockWife.averageCycleLength,
averagePeriodLength: mockWife.averagePeriodLength,
lastPeriodStartDate: mockWife.lastPeriodStartDate,
favoriteFoods: mockWife.favoriteFoods,
);
await ref.read(userProfileProvider.notifier).updateProfile(updatedProfile);
if (code.isNotEmpty) {
// Load demo data as simulation
final mockService = MockDataService();
final entries = mockService.generateMockCycleEntries();
for (var entry in entries) {
await ref.read(cycleEntriesProvider.notifier).addEntry(entry);
}
final mockWife = mockService.generateMockWifeProfile();
final currentProfile = ref.read(userProfileProvider);
if (currentProfile != null) {
final updatedProfile = currentProfile.copyWith(
isDataShared: shareDevotional,
partnerName: mockWife.name,
averageCycleLength: mockWife.averageCycleLength,
averagePeriodLength: mockWife.averagePeriodLength,
lastPeriodStartDate: mockWife.lastPeriodStartDate,
favoriteFoods: mockWife.favoriteFoods,
);
await ref.read(userProfileProvider.notifier).updateProfile(updatedProfile);
}
}
},
style: ElevatedButton.styleFrom(
@@ -1336,6 +1378,7 @@ class _HusbandSettingsScreen extends ConsumerWidget {
),
],
),
),
);
}