Fix stuck loading after save on profile and schedule views

- Remove fp.clear() from profile initState: if profesional is already
  loaded (e.g. navigating from schedule page) the form renders instantly
  without a spinner; if null the Consumer already shows the spinner.
- Add .catchError() so the spinner always resolves even on API failure.
- Remove redundant GET /professionals/me reload inside updateProfesionalProfileInfo:
  data is already correct from copyProfesionalWith, so the save button
  no longer waits for an extra round-trip after the PATCH.
- Wrap save button in try/finally so _saving always resets to false.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-07-12 19:44:52 -05:00
co-authored by Claude Sonnet 4.6
parent fd7b57fd35
commit 4698454cfc
2 changed files with 19 additions and 17 deletions
@@ -97,11 +97,6 @@ class ProfessionalFormProvider with ChangeNotifier {
NotificationsService.showSnackbar('Error al guardar: $e');
return false;
}
try {
final data = await _api.get('/professionals/me');
profesional = Profesional.fromDocument(data as Map<String, dynamic>);
notifyListeners();
} catch (_) {}
NotificationsService.showSnackbar('Información actualizada');
return true;
}
+19 -12
View File
@@ -1,6 +1,7 @@
import 'dart:typed_data';
import 'package:file_picker/file_picker.dart';
import 'package:prosapp_web_app/models/location_preferences.dart';
import 'package:prosapp_web_app/models/profesional.dart';
import 'package:prosapp_web_app/models/schedules_entity.dart';
import 'package:prosapp_web_app/models/usuario.dart';
import 'package:prosapp_web_app/providers/auth_provider.dart';
@@ -49,10 +50,13 @@ class _ProfessionalProfileViewState extends State<ProfessionalProfileView> {
final pfp = Provider.of<ProfileFormProvider>(context, listen: false);
final fp = Provider.of<ProfessionalFormProvider>(context, listen: false);
pfp.user = auth.user;
fp.clear(); // force spinner so TextFormField initialValue applies to fresh data
// Don't clear fp.profesional — if it's already loaded (e.g. navigating from
// schedule page) the form renders immediately with no spinner. If it's null
// the Consumer already shows the spinner until the future resolves.
Provider.of<ProfessionalProvider>(context, listen: false)
.getProfessional(auth.user!.id)
.then(fp.setProfesional);
.then(fp.setProfesional)
.catchError((_) => fp.setProfesional(Profesional.empty()));
}
@override
@@ -383,17 +387,20 @@ class _ProfileFormState extends State<_ProfileForm> {
child: ElevatedButton(
onPressed: _saving ? null : () async {
setState(() => _saving = true);
LocationPreferences lp;
if (_delivery && _office) {
lp = LocationPreferences.both;
} else if (_delivery) {
lp = LocationPreferences.delivery;
} else {
lp = LocationPreferences.office;
try {
LocationPreferences lp;
if (_delivery && _office) {
lp = LocationPreferences.both;
} else if (_delivery) {
lp = LocationPreferences.delivery;
} else {
lp = LocationPreferences.office;
}
fp.copyProfesionalWith(locationPreferences: lp, ratePreferences: _rateEnabled);
await fp.updateProfesionalProfileInfo(user.id);
} finally {
if (mounted) setState(() => _saving = false);
}
fp.copyProfesionalWith(locationPreferences: lp, ratePreferences: _rateEnabled);
await fp.updateProfesionalProfileInfo(user.id);
if (mounted) setState(() => _saving = false);
},
style: ElevatedButton.styleFrom(
backgroundColor: _kPrimary,