From 6d874f91f26ba7c2a7b9c34891442bbf6113f875 Mon Sep 17 00:00:00 2001 From: Varadraj75 Date: Sun, 19 Apr 2026 17:13:33 +0530 Subject: [PATCH] fix: add submission guard and loading state to therapy save, deduplicate regression reports --- .../supabase_patient_repository.dart | 7 ++- .../therapy_goals/therapy_goals_screen.dart | 1 + .../widgets/save_therapy_button.dart | 49 ++++++++++++------- therapist/lib/provider/therapy_provider.dart | 45 ++++++++++------- 4 files changed, 64 insertions(+), 38 deletions(-) diff --git a/patient/lib/repository/supabase_patient_repository.dart b/patient/lib/repository/supabase_patient_repository.dart index 698a065..1f0e0b5 100644 --- a/patient/lib/repository/supabase_patient_repository.dart +++ b/patient/lib/repository/supabase_patient_repository.dart @@ -238,13 +238,16 @@ class SupabasePatientRepository implements PatientRepository { .gte('performed_on', startDate.toIso8601String()) .lte('performed_on', endDate.toIso8601String()); + final Set seenRegressions = {}; List regressions = []; for(var i = 0; i < regresstionResponse.length; i++) { final regression = regresstionResponse[i]['regressions']; for(var j = 0; j < regression.length; j++) { final regressionItem = regression[j] is String ? jsonDecode(regression[j]) : regression[j]; - - regressions.add(regressionItem['name']); + final String regressionName = regressionItem['name']; + if (seenRegressions.add(regressionName)) { + regressions.add(regressionName); + } } } diff --git a/therapist/lib/presentation/therapy_goals/therapy_goals_screen.dart b/therapist/lib/presentation/therapy_goals/therapy_goals_screen.dart index 470bd71..ed32eef 100644 --- a/therapist/lib/presentation/therapy_goals/therapy_goals_screen.dart +++ b/therapist/lib/presentation/therapy_goals/therapy_goals_screen.dart @@ -115,6 +115,7 @@ class _TherapyGoalsScreenState extends State { padding: const EdgeInsets.symmetric(horizontal: 22, vertical: 25), child: SaveTherapyButton( text: 'Save Therapy Details', + isLoading: therapyProvider.saveTherapyStatus.isLoading, onPressed: _onSaveTherapyDetails, ), ), diff --git a/therapist/lib/presentation/therapy_goals/widgets/save_therapy_button.dart b/therapist/lib/presentation/therapy_goals/widgets/save_therapy_button.dart index 168d274..2f7fbf2 100644 --- a/therapist/lib/presentation/therapy_goals/widgets/save_therapy_button.dart +++ b/therapist/lib/presentation/therapy_goals/widgets/save_therapy_button.dart @@ -6,31 +6,44 @@ class SaveTherapyButton extends StatelessWidget { super.key, required this.text, required this.onPressed, + this.isLoading = false, }); final String text; - final VoidCallback onPressed; - + final VoidCallback? onPressed; + final bool isLoading; @override Widget build(BuildContext context) { return GestureDetector( - onTap: onPressed, - child: Container( - width: double.infinity, - height: 50, - decoration: BoxDecoration( - color: AppTheme.primaryColor, - borderRadius: BorderRadius.circular(10), - ), - child: Center( - child: Text( - text, - style: const TextStyle( - color: Colors.white, - fontSize: 16, - fontWeight: FontWeight.w700, - ), + onTap: isLoading ? null : onPressed, + child: Opacity( + opacity: isLoading ? 0.6 : 1.0, + child: Container( + width: double.infinity, + height: 50, + decoration: BoxDecoration( + color: AppTheme.primaryColor, + borderRadius: BorderRadius.circular(10), + ), + child: Center( + child: isLoading + ? const SizedBox( + height: 24, + width: 24, + child: CircularProgressIndicator( + color: Colors.white, + strokeWidth: 2.5, + ), + ) + : Text( + text, + style: const TextStyle( + color: Colors.white, + fontSize: 16, + fontWeight: FontWeight.w700, + ), + ), ), ), ), diff --git a/therapist/lib/provider/therapy_provider.dart b/therapist/lib/provider/therapy_provider.dart index be16686..2e5986b 100644 --- a/therapist/lib/provider/therapy_provider.dart +++ b/therapist/lib/provider/therapy_provider.dart @@ -219,27 +219,36 @@ class TherapyProvider extends ChangeNotifier { notifyListeners(); } - void saveTherapyDetails() async { + Future saveTherapyDetails() async { + if (_saveTherapyStatus.isLoading) return; + _saveTherapyStatus = SaveTherapyStatus.loading; - final therapyGoalModel = TherapyGoalModel( - performedOn: _selectedDateTime ?? DateTime.now(), - therapyTypeId: _getTherapyIdFromSelectedTherapy(), - goals: _selectedTherapyGoals, - observations: _selectedTherapyObservations, - regressions: _selectedTherapyRegressions, - activities: _selectedTherapyActivities, - patientId: _patientId, - ); - - final ActionResult result = await _therapyRepository.saveTherapyGoals(therapyGoalModel.toEntity()); + notifyListeners(); - if(result is ActionResultSuccess) { - _saveTherapyStatus = SaveTherapyStatus.success; - _saveTherapyErrorMessage = ''; - notifyListeners(); - } else { + try { + final therapyGoalModel = TherapyGoalModel( + performedOn: _selectedDateTime ?? DateTime.now(), + therapyTypeId: _getTherapyIdFromSelectedTherapy(), + goals: _selectedTherapyGoals, + observations: _selectedTherapyObservations, + regressions: _selectedTherapyRegressions, + activities: _selectedTherapyActivities, + patientId: _patientId, + ); + + final ActionResult result = await _therapyRepository.saveTherapyGoals(therapyGoalModel.toEntity()); + + if (result is ActionResultSuccess) { + _saveTherapyStatus = SaveTherapyStatus.success; + _saveTherapyErrorMessage = ''; + } else { + _saveTherapyStatus = SaveTherapyStatus.failure; + _saveTherapyErrorMessage = result.errorMessage.toString(); + } + } catch (e) { _saveTherapyStatus = SaveTherapyStatus.failure; - _saveTherapyErrorMessage = result.errorMessage.toString(); + _saveTherapyErrorMessage = e.toString(); + } finally { notifyListeners(); } }