Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,4 @@ app.*.map.json
/android/fastlane/build/outputs/
/android/fastlane/report.xml
/lib/version.dart
/.env
21 changes: 20 additions & 1 deletion lib/l10n/app_de.arb
Original file line number Diff line number Diff line change
Expand Up @@ -480,5 +480,24 @@
"type": "int"
}
}
}
},
"@_SURVEY": {},
"survey_card_title": "Nutzerumfrage",
"survey_card_subtitle": "Studienarbeit MoveTopia",
"survey_card_description": "Wir möchten gerne deine Meinung zu MoveTopia erfahren. Deine Teilnahme hilft uns, die App zu verbessern.",
"survey_card_remind_later": "Später erinnern",
"survey_card_take_survey": "Teilnehmen",
"survey_dialog_title": "Umfrage öffnen",
"survey_dialog_content": "Wie möchtest du die Umfrage öffnen?",
"survey_dialog_not_interested": "Nicht teilnehmen",
"survey_dialog_open_in_app": "In App öffnen",
"survey_dialog_open_externally": "Im Browser öffnen",
"survey_dialog_already_completed": "Bereits abgeschlossen",
"survey_webview_title": "Nutzerumfrage",
"survey_error_opening_url": "Konnte die URL nicht öffnen",
"survey_completed_question": "Hast du die Umfrage abgeschlossen?",
"survey_completed_yes": "Ja, habe ich",
"survey_completed_no": "Nein, später",
"common_back": "Zurück",
"common_refresh": "Aktualisieren"
}
22 changes: 21 additions & 1 deletion lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -499,5 +499,25 @@
"type": "int"
}
}
}
},

"@_SURVEY": {},
"survey_card_title": "User Survey",
"survey_card_subtitle": "MoveTopia Study Project",
"survey_card_description": "We would like to hear your opinion about MoveTopia. Your participation helps us improve the app.",
"survey_card_remind_later": "Remind me later",
"survey_card_take_survey": "Participate",
"survey_dialog_title": "Open Survey",
"survey_dialog_content": "How would you like to open the survey?",
"survey_dialog_not_interested": "Not interested",
"survey_dialog_open_in_app": "Open in app",
"survey_dialog_open_externally": "Open in browser",
"survey_dialog_already_completed": "Already completed",
"survey_webview_title": "User Survey",
"survey_error_opening_url": "Could not open the URL",
"survey_completed_question": "Did you complete the survey?",
"survey_completed_yes": "Yes, I did",
"survey_completed_no": "No, later",
"common_back": "Back",
"common_refresh": "Refresh"
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import '../widgets/app_dates_section.dart';
import '../widgets/badge_debug_section.dart';
import '../widgets/cache_debug_section.dart';
import '../widgets/streak_debug_section.dart';
import '../widgets/survey_debug_section.dart';

class DebugSettingsScreen extends HookConsumerWidget {
const DebugSettingsScreen({super.key});
Expand Down Expand Up @@ -59,6 +60,9 @@ class DebugSettingsScreen extends HookConsumerWidget {
// Badge Debugging Sektion
BadgeDebugSection(isLoading: isLoading),

// Survey Debugging Sektion
SurveyDebugSection(isLoading: isLoading),

// Cache Debuggin Sektion
CacheDebugSection(isLoading: isLoading)
],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:movetopia/presentation/today/widgets/survey_card.dart';
import 'package:shared_preferences/shared_preferences.dart';

/// Debug Sektion for User Survey
class SurveyDebugSection extends ConsumerWidget {
final ValueNotifier<bool> isLoading;

const SurveyDebugSection({super.key, required this.isLoading});

@override
Widget build(BuildContext context, WidgetRef ref) {
final l10n = AppLocalizations.of(context)!;
final theme = Theme.of(context);

return Card(
margin: const EdgeInsets.symmetric(vertical: 8),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Survey Debug',
style: theme.textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.bold,
color: theme.colorScheme.primary,
),
),
const SizedBox(height: 16),
FutureBuilder<Map<String, bool>>(
future: _getSurveyStatus(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
}

final status =
snapshot.data ?? {'dismissed': false, 'completed': false};
final dismissed = status['dismissed'] ?? false;
final completed = status['completed'] ?? false;

return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Aktueller Status:',
style: theme.textTheme.titleMedium),
const SizedBox(height: 8),
_buildStatusChip(context, 'Dismissed', dismissed,
theme.colorScheme.error),
const SizedBox(height: 4),
_buildStatusChip(context, 'Completed', completed,
theme.colorScheme.primary),
const SizedBox(height: 24),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton.icon(
icon: const Icon(Icons.refresh),
label: const Text('Reset Status'),
onPressed: () => _resetSurveyStatus(context),
style: ElevatedButton.styleFrom(
backgroundColor: theme.colorScheme.primary,
foregroundColor: theme.colorScheme.onPrimary,
),
),
ElevatedButton.icon(
icon: const Icon(Icons.check_circle),
label: const Text('Mark Completed'),
onPressed: () => _markSurveyCompleted(context),
style: ElevatedButton.styleFrom(
backgroundColor: theme.colorScheme.secondary,
foregroundColor: theme.colorScheme.onSecondary,
),
),
],
),
const SizedBox(height: 12),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton.icon(
icon: const Icon(Icons.close),
label: const Text('Mark Dismissed'),
onPressed: () => _markSurveyDismissed(context),
style: ElevatedButton.styleFrom(
backgroundColor: theme.colorScheme.error,
foregroundColor: theme.colorScheme.onError,
),
),
ElevatedButton.icon(
icon: const Icon(Icons.date_range),
label: const Text('Set to Today'),
onPressed: () => _setStartDateToToday(context),
style: ElevatedButton.styleFrom(
backgroundColor: theme.colorScheme.tertiary,
foregroundColor: theme.colorScheme.onTertiary,
),
),
],
),
],
);
},
),
],
),
),
);
}

/// Creates a status chip with a label and value
Widget _buildStatusChip(
BuildContext context, String label, bool value, Color color) {
return Row(
children: [
Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
decoration: BoxDecoration(
color: value ? color : Colors.grey.shade300,
borderRadius: BorderRadius.circular(16),
),
child: Text(
label,
style: TextStyle(
color: value ? Colors.white : Colors.black54,
fontWeight: FontWeight.bold,
),
),
),
const SizedBox(width: 8),
Text(value ? 'Ja' : 'Nein'),
],
);
}

/// Reads the survey status from SharedPreferences
Future<Map<String, bool>> _getSurveyStatus() async {
final prefs = await SharedPreferences.getInstance();
final dismissed =
prefs.getBool(SurveyConstants.prefKeySurveyDismissed) ?? false;
final completed =
prefs.getBool(SurveyConstants.prefKeySurveyCompleted) ?? false;

return {
'dismissed': dismissed,
'completed': completed,
};
}

/// Resets the survey status in SharedPreferences
Future<void> _resetSurveyStatus(BuildContext context) async {
isLoading.value = true;

try {
final prefs = await SharedPreferences.getInstance();
await prefs.remove(SurveyConstants.prefKeySurveyDismissed);
await prefs.remove(SurveyConstants.prefKeySurveyCompleted);

if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Survey-Status zurückgesetzt')),
);
}
} finally {
isLoading.value = false;
}
}

/// Marks the survey as completed
Future<void> _markSurveyCompleted(BuildContext context) async {
isLoading.value = true;

try {
final prefs = await SharedPreferences.getInstance();
await prefs.setBool(SurveyConstants.prefKeySurveyCompleted, true);

if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Umfrage als abgeschlossen markiert')),
);
}
} finally {
isLoading.value = false;
}
}

/// Marks the survey as dismissed
Future<void> _markSurveyDismissed(BuildContext context) async {
isLoading.value = true;

try {
final prefs = await SharedPreferences.getInstance();
await prefs.setBool(SurveyConstants.prefKeySurveyDismissed, true);

if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Umfrage als verworfen markiert')),
);
}
} finally {
isLoading.value = false;
}
}

/// Set the start date to today
Future<void> _setStartDateToToday(BuildContext context) async {
isLoading.value = true;

try {
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text(
'StartDate ist ein static final Feld und kann zur Laufzeit nicht geändert werden. Bitte ändere den Code direkt.')),
);
}
} finally {
isLoading.value = false;
}
}
}
14 changes: 13 additions & 1 deletion lib/presentation/today/routes.dart
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:movetopia/presentation/today/screen/survey_webview_screen.dart';
import 'package:movetopia/presentation/today/screen/today_screen.dart';

const todayPath = '/today';

const String surveyWebViewPath = 'survey-webview';
const String fullSurveyWebViewPath = '$todayPath/$surveyWebViewPath';

class TodayRoutes {
static final navigatorKey = GlobalKey<NavigatorState>();

static List<RouteBase> routes = [
GoRoute(
path: todayPath,
builder: (context, state) => const TodayScreen(),
)
routes: [
GoRoute(
path: surveyWebViewPath,
builder: (context, state) => SurveyWebViewScreen(
surveyUrl: state.extra as String,
),
),
],
),
];
}
Loading
Loading