// File: add_new_shift.dart (Shift Name Changed back to Dropdown) import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:mobile_pos/Screens/hrm/shift/Model/shift_list_model.dart'; import 'package:mobile_pos/Screens/hrm/shift/repo/shift_repo.dart'; import 'package:mobile_pos/generated/l10n.dart' as l; import 'package:icons_plus/icons_plus.dart'; import '../../../constant.dart'; import '../widgets/set_time.dart'; import 'package:intl/intl.dart'; class AddNewShift extends ConsumerStatefulWidget { const AddNewShift({super.key, this.isEdit = false, this.shift}); final bool isEdit; final ShiftData? shift; @override ConsumerState createState() => _AddNewShiftState(); } class _AddNewShiftState extends ConsumerState { final GlobalKey _key = GlobalKey(); // *** CHANGED: Shift Name is now managed by selectedShift String? *** String? selectedShift; // shiftNameController is now unnecessary for dropdown, but kept for cleanup clarity final TextEditingController shiftNameController = TextEditingController(); String? selectedBreakStatus; String? _selectedStatus; final startTimeController = TextEditingController(); final endTimeController = TextEditingController(); final startBreakTimeController = TextEditingController(); final endBreakTimeController = TextEditingController(); final List _statusOptions = ['Active', 'Inactive']; final List _shiftNameOptions = ['Morning', "Day", "Evening", 'Night']; // Fixed list for dropdown String formatTime(String time24) { try { DateTime parsedTime = DateFormat("HH:mm:ss").parse(time24); return DateFormat("h:mm a").format(parsedTime); } catch (e) { return time24; } } @override void initState() { super.initState(); if (widget.isEdit && widget.shift != null) { final data = widget.shift!; // *** FIX: Use Shift Name from data for selectedShift state *** selectedShift = data.name; selectedBreakStatus = data.breakStatus == 'yes' ? "Yes" : "No"; _selectedStatus = data.status == 1 ? 'Active' : 'Inactive'; startTimeController.text = formatTime(data.startTime ?? ''); endTimeController.text = formatTime(data.endTime ?? ''); startBreakTimeController.text = formatTime(data.startBreakTime ?? ''); endBreakTimeController.text = formatTime(data.endBreakTime ?? ''); } else { _selectedStatus = 'Active'; selectedBreakStatus = 'No'; } } @override void dispose() { // shiftNameController.dispose(); // No longer needed if using dropdown startTimeController.dispose(); endTimeController.dispose(); startBreakTimeController.dispose(); endBreakTimeController.dispose(); super.dispose(); } Future _saveOrUpdateShift(BuildContext context) async { if (!_key.currentState!.validate()) return; // Check if the required state variables are set by the dropdowns if (selectedShift == null) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Please select Shift Name')), ); return; } final repo = ShiftRepo(); final int apiStatus = _selectedStatus == 'Active' ? 1 : 0; // Ensure times are in HH:mm format before sending (setTime uses HH:mm a, // but the repo needs to handle conversion to HH:mm:ss if necessary) if (widget.isEdit) { await repo.updateShift( ref: ref, context: context, id: widget.shift!.id!.round(), shiftName: selectedShift!, breakStatus: selectedBreakStatus!, startTime: startTimeController.text, endTime: endTimeController.text, breakStartTime: startBreakTimeController.text.isEmpty ? null : startBreakTimeController.text, breakEndTime: endBreakTimeController.text.isEmpty ? null : endBreakTimeController.text, status: apiStatus.toString(), ); } else { await repo.createShift( ref: ref, context: context, shiftName: selectedShift!, breakStatus: selectedBreakStatus ?? "No", startTime: startTimeController.text, endTime: endTimeController.text, breakStartTime: startBreakTimeController.text.isEmpty ? null : startBreakTimeController.text, breakEndTime: endBreakTimeController.text.isEmpty ? null : endBreakTimeController.text, status: apiStatus.toString(), ); } } void _resetForm() { _key.currentState?.reset(); setState(() { selectedShift = null; // Reset dropdown selection selectedBreakStatus = 'No'; _selectedStatus = 'Active'; // Reset time controllers startTimeController.clear(); endTimeController.clear(); startBreakTimeController.clear(); endBreakTimeController.clear(); }); } @override Widget build(BuildContext context) { final _lang = l.S.of(context); return Scaffold( backgroundColor: kWhite, appBar: AppBar( centerTitle: true, title: Text( widget.isEdit ? _lang.editShift : _lang.addNewShift, ), bottom: PreferredSize( preferredSize: const Size.fromHeight(1), child: Divider(height: 2, color: kBackgroundColor), ), ), body: SingleChildScrollView( padding: const EdgeInsets.all(16), child: Form( key: _key, child: Column( children: [ // 1. Shift Name (FIXED: Changed back to Dropdown) DropdownButtonFormField( value: selectedShift, icon: const Icon(Icons.keyboard_arrow_down, color: kNeutral800), decoration: InputDecoration(labelText: _lang.shiftName, hintText: _lang.selectOne), items: _shiftNameOptions .map((String value) => DropdownMenuItem(value: value, child: Text(value))) .toList(), onChanged: (String? newValue) => setState(() => selectedShift = newValue), validator: (value) => value == null ? _lang.pleaseSelectAShift : null, ), const SizedBox(height: 20), // 2. Break Status Dropdown DropdownButtonFormField( value: selectedBreakStatus, icon: const Icon(Icons.keyboard_arrow_down, color: kNeutral800), decoration: InputDecoration( labelText: _lang.breakStatus, hintText: _lang.selectOne, ), items: const ['Yes', 'No'] .map((String value) => DropdownMenuItem(value: value, child: Text(value))) .toList(), onChanged: (String? newValue) => setState(() => selectedBreakStatus = newValue), validator: (value) => value == null ? _lang.pleaseSelectBreakStatus : null, ), const SizedBox(height: 20), // 3. Status Dropdown DropdownButtonFormField( value: _selectedStatus, icon: const Icon(Icons.keyboard_arrow_down, color: kNeutral800), decoration: InputDecoration( labelText: _lang.status, hintText: _lang.selectOne, ), items: _statusOptions.map((String value) => DropdownMenuItem(value: value, child: Text(value))).toList(), onChanged: (String? newValue) => setState(() => _selectedStatus = newValue), validator: (value) => value == null ? _lang.pleaseSelectAStatus : null, ), const SizedBox(height: 20), // 4. Start Time & End Time Row( children: [ Expanded( child: TextFormField( onTap: () => setTime(startTimeController, context), readOnly: true, controller: startTimeController, validator: (value) => value.isNullOrEmpty() ? _lang.startTimeIsRequired : null, decoration: InputDecoration( labelText: _lang.startTime, hintText: _lang.enterStartTime, suffixIcon: Icon( AntDesign.clock_circle_outline, size: 18, color: kNeutral800, ), ), ), ), const SizedBox(width: 16), Expanded( child: TextFormField( readOnly: true, controller: endTimeController, onTap: () => setTime(endTimeController, context), validator: (value) => value.isNullOrEmpty() ? _lang.endTimeIsRequired : null, decoration: InputDecoration( labelText: _lang.endTime, hintText: _lang.enterEndTime, suffixIcon: Icon( AntDesign.clock_circle_outline, size: 18, color: kNeutral800, ), ), ), ), ], ), const SizedBox(height: 20), // 5. Break Time (Conditional) if (selectedBreakStatus == 'Yes') Row( children: [ Expanded( child: TextFormField( onTap: () => setTime(startBreakTimeController, context), readOnly: true, controller: startBreakTimeController, decoration: InputDecoration( labelText: _lang.startBreakTime, hintText: _lang.enterBreakTime, suffixIcon: Icon( AntDesign.clock_circle_outline, size: 18, color: kNeutral800, ), ), ), ), const SizedBox(width: 16), Expanded( child: TextFormField( readOnly: true, controller: endBreakTimeController, onTap: () => setTime(endBreakTimeController, context), decoration: InputDecoration( labelText: _lang.endBreakTime, hintText: _lang.enterBreakTime, suffixIcon: Icon( AntDesign.clock_circle_outline, size: 18, color: kNeutral800, ), ), ), ), ], ), const SizedBox(height: 20), // 6. Action Buttons Row( children: [ Expanded( child: OutlinedButton(onPressed: _resetForm, child: Text(_lang.resets)), ), const SizedBox(width: 16), Expanded( child: ElevatedButton( onPressed: () => _saveOrUpdateShift(context), child: Text(widget.isEdit ? _lang.update : _lang.save)), ), ], ), ], ), ), ), ); } } // Extension to help with simple validation checks extension on String? { bool isNullOrEmpty() => this == null || this!.isEmpty; }