* 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
+17 -1
View File
@@ -1,5 +1,5 @@
import 'dart:async';
import 'package:flutter/foundation.dart' show debugPrint;
import 'package:flutter/foundation.dart' show debugPrint, kIsWeb;
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:http/http.dart' as http;
@@ -46,6 +46,22 @@ final connectivityMonitorProvider = Provider.autoDispose<void>((ref) {
/// Pings the app's own backend to determine online status.
class ConnectivityMonitor {
static Future<bool> check() async {
if (kIsWeb) {
// On web the browser enforces CORS: a HEAD request to an external domain
// (tasq.crmc.ph) is blocked even when online, making it look permanently
// offline. Instead probe the Supabase REST endpoint, which is already
// CORS-configured for this app's origin. Any HTTP response (including
// 401 without auth headers) proves the network is reachable.
try {
final restUrl = Supabase.instance.client.rest.url;
final res = await http
.head(Uri.parse(restUrl))
.timeout(const Duration(seconds: 5));
return res.statusCode < 500;
} catch (_) {
return false;
}
}
try {
final res = await http
.head(Uri.parse('https://tasq.crmc.ph'))