Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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