feat: enhance UI, branding assets, onboarding flow, and screen layouts

This commit is contained in:
R-Bharathraj
2026-09-18 15:23:30 +05:30
parent cafffd27e0
commit 5122eebc11
68 changed files with 1661 additions and 470 deletions

View File

@@ -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),
),
],
),