* Task/Ticket desktop dialogs — widened from 520 → 600dp, and tasks now uses SizedBox(width: 600) instead of ConstrainedBox(maxWidth:) which was the root cause of the "still small" issue (max-only never forced expansion)

* Pass Slip + Leave — both dialogs gained an isSheet flag; callers now branch on AppBreakpoints.tablet: bottom sheet on mobile, dialog on desktop
This commit is contained in:
2026-04-30 06:45:51 +08:00
parent 48cd3bcd60
commit 783c5eb0be
19 changed files with 1224 additions and 887 deletions
+31 -8
View File
@@ -1,6 +1,8 @@
import 'dart:async';
import 'dart:convert';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import '../brick/cache_helpers.dart';
@@ -12,16 +14,37 @@ import 'supabase_provider.dart';
import 'stream_recovery.dart';
import 'realtime_controller.dart';
const _kGeofenceCacheKey = 'geofence_cache_v1';
final geofenceProvider = FutureProvider<GeofenceConfig?>((ref) async {
final client = ref.watch(supabaseClientProvider);
final data = await client
.from('app_settings')
.select()
.eq('key', 'geofence')
.maybeSingle();
if (data == null) return null;
final setting = AppSetting.fromMap(data);
return GeofenceConfig.fromJson(setting.value);
try {
final data = await client
.from('app_settings')
.select()
.eq('key', 'geofence')
.maybeSingle();
final prefs = await SharedPreferences.getInstance();
if (data == null) {
await prefs.setString(_kGeofenceCacheKey, 'null');
return null;
}
final setting = AppSetting.fromMap(data);
await prefs.setString(_kGeofenceCacheKey, jsonEncode(setting.value));
return GeofenceConfig.fromJson(setting.value);
} catch (_) {
// Offline / network failure — fall back to cached config so geofence
// validation still runs during offline check-in.
try {
final prefs = await SharedPreferences.getInstance();
final raw = prefs.getString(_kGeofenceCacheKey);
if (raw == null || raw == 'null') return null;
final json = jsonDecode(raw) as Map<String, dynamic>;
return GeofenceConfig.fromJson(json);
} catch (_) {
return null;
}
}
});
/// Toggle to show/hide past schedules. Defaults to false (hide past).