feat: enhance UI, branding assets, onboarding flow, and screen layouts
This commit is contained in:
@@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:lucide_icons_flutter/lucide_icons.dart';
|
||||
|
||||
import '../core/permissions.dart';
|
||||
import '../core/theme.dart';
|
||||
import '../state/profile_controller.dart';
|
||||
import '../state/seed.dart';
|
||||
@@ -11,13 +12,41 @@ import '../state/shifts_controller.dart';
|
||||
import '../state/timecards_controller.dart';
|
||||
import '../widgets/common.dart';
|
||||
|
||||
class SettingsScreen extends ConsumerWidget {
|
||||
class SettingsScreen extends ConsumerStatefulWidget {
|
||||
const SettingsScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final session = ref.watch(sessionProvider);
|
||||
ConsumerState<SettingsScreen> createState() => _SettingsScreenState();
|
||||
}
|
||||
|
||||
class _SettingsScreenState extends ConsumerState<SettingsScreen> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
// A permission can be revoked in system settings while the app is closed,
|
||||
// so the switches are re-read from the OS rather than trusted from cache.
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
ref.read(sessionProvider.notifier).refresh();
|
||||
});
|
||||
}
|
||||
|
||||
/// The OS has no API to revoke a permission, and re-requesting a granted one
|
||||
/// does nothing — so the switch hands off to the system settings page for
|
||||
/// anything it cannot do itself.
|
||||
Future<void> _toggle(AppPermission permission, bool value) async {
|
||||
final notifier = ref.read(sessionProvider.notifier);
|
||||
if (!value) {
|
||||
await ref.read(permissionServiceProvider).openSettings();
|
||||
return;
|
||||
}
|
||||
final granted = await notifier.request(permission);
|
||||
if (granted || !mounted) return;
|
||||
await ref.read(permissionServiceProvider).openSettings();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final session = ref.watch(sessionProvider);
|
||||
final profile = ref.watch(profileProvider);
|
||||
final reviewCount = ref.watch(timecardsNeedingReviewProvider).length;
|
||||
|
||||
@@ -44,7 +73,7 @@ class SettingsScreen extends ConsumerWidget {
|
||||
title: 'Location',
|
||||
subtitle: 'Needed to clock in at the venue',
|
||||
value: session.locationGranted,
|
||||
onChanged: (v) => v ? notifier.grantLocation() : null,
|
||||
onChanged: (v) => _toggle(AppPermission.location, v),
|
||||
),
|
||||
const Divider(height: 1),
|
||||
_SwitchRow(
|
||||
@@ -52,7 +81,7 @@ class SettingsScreen extends ConsumerWidget {
|
||||
title: 'Notifications',
|
||||
subtitle: 'Shift offers, reminders and pay alerts',
|
||||
value: session.notificationsGranted,
|
||||
onChanged: (v) => v ? notifier.grantNotifications() : null,
|
||||
onChanged: (v) => _toggle(AppPermission.notifications, v),
|
||||
),
|
||||
const Divider(height: 1),
|
||||
_SwitchRow(
|
||||
@@ -60,7 +89,7 @@ class SettingsScreen extends ConsumerWidget {
|
||||
title: 'Camera',
|
||||
subtitle: 'Photograph documents and attire',
|
||||
value: session.cameraGranted,
|
||||
onChanged: (v) => v ? notifier.grantCamera() : null,
|
||||
onChanged: (v) => _toggle(AppPermission.camera, v),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user