feat: allow editing old sessions via popup dialog

This commit is contained in:
Rohitdhall987
2025-04-25 22:55:56 +05:30
parent 07f38a8d60
commit f45ed540b3

View File

@@ -18,13 +18,16 @@
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:wger/helpers/colors.dart';
import 'package:wger/helpers/json.dart';
import 'package:wger/helpers/misc.dart';
import 'package:wger/helpers/ui.dart';
import 'package:wger/l10n/generated/app_localizations.dart';
import 'package:wger/models/workouts/log.dart';
import 'package:wger/models/workouts/routine.dart';
import 'package:wger/models/workouts/session.dart';
import 'package:wger/providers/routines.dart';
import 'package:wger/widgets/measurements/charts.dart';
import 'package:wger/widgets/routines/charts.dart';
@@ -37,44 +40,51 @@ class SessionInfo extends StatelessWidget {
Widget build(BuildContext context) {
final i18n = AppLocalizations.of(context);
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Text(
i18n.workoutSession,
style: Theme.of(context).textTheme.headlineSmall,
),
Text(
DateFormat.yMd(Localizations.localeOf(context).languageCode).format(_session.date),
style: Theme.of(context).textTheme.headlineSmall,
),
const SizedBox(height: 8.0),
_buildInfoRow(
context,
i18n.timeStart,
_session.timeStart != null
? MaterialLocalizations.of(context).formatTimeOfDay(_session.timeStart!)
: '-/-',
),
_buildInfoRow(
context,
i18n.timeEnd,
_session.timeEnd != null
? MaterialLocalizations.of(context).formatTimeOfDay(_session.timeEnd!)
: '-/-',
),
_buildInfoRow(
context,
i18n.impression,
_session.impressionAsString,
),
_buildInfoRow(
context,
i18n.notes,
_session.notes.isNotEmpty ? _session.notes : '-/-',
),
],
return GestureDetector(
onTap: (){
final routinesProvider = context.read<RoutinesProvider>();
showEditSessionDialog(context, _session, routinesProvider);
},
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Text(
i18n.workoutSession,
style: Theme.of(context).textTheme.headlineSmall,
),
Text(
DateFormat.yMd(Localizations.localeOf(context).languageCode).format(_session.date),
style: Theme.of(context).textTheme.headlineSmall,
),
const SizedBox(height: 8.0),
_buildInfoRow(
context,
i18n.timeStart,
_session.timeStart != null
? MaterialLocalizations.of(context).formatTimeOfDay(_session.timeStart!)
: '-/-',
),
_buildInfoRow(
context,
i18n.timeEnd,
_session.timeEnd != null
? MaterialLocalizations.of(context).formatTimeOfDay(_session.timeEnd!)
: '-/-',
),
_buildInfoRow(
context,
i18n.impression,
_session.impressionAsString,
),
_buildInfoRow(
context,
i18n.notes,
_session.notes.isNotEmpty ? _session.notes : '-/-',
),
],
),
),
);
}
@@ -197,3 +207,114 @@ class DayLogWidget extends StatelessWidget {
);
}
}
void showEditSessionDialog(BuildContext context, WorkoutSession session, RoutinesProvider routinesProvider) {
final _formKey = GlobalKey<FormState>();
final notesController = TextEditingController(text: session.notes);
final timeStartController = TextEditingController(text: timeToString(session.timeStart ?? TimeOfDay.now())!);
final timeEndController = TextEditingController(text: timeToString(session.timeEnd ?? TimeOfDay.now())!);
List<bool> selectedImpression = [false, false, false];
selectedImpression[session.impression - 1] = true;
showDialog(
context: context,
builder: (ctx) {
return AlertDialog(
title: Text('Edit Session (${session.date.toLocal().toString().split(' ')[0]})'),
content: Form(
key: _formKey,
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ToggleButtons(
renderBorder: false,
isSelected: selectedImpression,
onPressed: (index) {
for (int i = 0; i < selectedImpression.length; i++) {
selectedImpression[i] = (i == index);
}
session.impression = index + 1;
},
children: const [
Icon(Icons.sentiment_very_dissatisfied),
Icon(Icons.sentiment_neutral),
Icon(Icons.sentiment_very_satisfied),
],
),
const SizedBox(height: 10),
TextFormField(
decoration: const InputDecoration(labelText: 'Notes'),
controller: notesController,
maxLines: 3,
onSaved: (value) => session.notes = value ?? '',
),
const SizedBox(height: 10),
TextFormField(
decoration: const InputDecoration(labelText: 'Start Time'),
controller: timeStartController,
onTap: () async {
FocusScope.of(ctx).requestFocus(FocusNode());
final picked = await showTimePicker(
context: ctx,
initialTime: session.timeStart ?? TimeOfDay.now(),
);
if (picked != null) {
timeStartController.text = timeToString(picked)!;
session.timeStart = picked;
}
},
validator: (_) {
final start = stringToTime(timeStartController.text);
final end = stringToTime(timeEndController.text);
if (start.isAfter(end)) {
return 'Start time cannot be after end time.';
}
return null;
},
onSaved: (val) => session.timeStart = stringToTime(val),
),
TextFormField(
decoration: const InputDecoration(labelText: 'End Time'),
controller: timeEndController,
onTap: () async {
FocusScope.of(ctx).requestFocus(FocusNode());
final picked = await showTimePicker(
context: ctx,
initialTime: session.timeEnd ?? TimeOfDay.now(),
);
if (picked != null) {
timeEndController.text = timeToString(picked)!;
session.timeEnd = picked;
}
},
onSaved: (val) => session.timeEnd = stringToTime(val),
),
],
),
),
),
actions: [
TextButton(
onPressed: () => Navigator.of(ctx).pop(),
child: const Text('Cancel'),
),
ElevatedButton(
onPressed: () async {
if (_formKey.currentState?.validate() ?? false) {
_formKey.currentState?.save();
try {
await routinesProvider.editSession(session);
Navigator.of(ctx).pop();
} catch (e) {
showErrorDialog(e, context);
}
}
},
child: const Text('Save'),
),
],
);
},
);
}