From eb66a707cc89dbd7c78c64509a6a74e59a006c35 Mon Sep 17 00:00:00 2001 From: Mark M2 Macbook Date: Sun, 3 May 2026 12:44:51 +0200 Subject: [PATCH] s Co-authored-by: Copilot --- .../operations/blocs/operations_cubit.dart | 6 + .../operations/ui/operation_form_screen.dart | 25 +++- .../operations/ui/widgets/staff_section.dart | 136 ++++++++++++++++++ 3 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 lib/features/operations/ui/widgets/staff_section.dart diff --git a/lib/features/operations/blocs/operations_cubit.dart b/lib/features/operations/blocs/operations_cubit.dart index be48feb..b148b8a 100644 --- a/lib/features/operations/blocs/operations_cubit.dart +++ b/lib/features/operations/blocs/operations_cubit.dart @@ -89,6 +89,8 @@ class OperationsCubit extends Cubit { void initOperationForm({ OperationModel? existingOperation, String? operationId, + String? staffId, + String? staffDisplayName, }) async { if (existingOperation != null) { emit( @@ -219,6 +221,8 @@ class OperationsCubit extends Cubit { int? quantity, String? modelId, String? modelDisplayName, + String? staffId, + String? staffDisplayName, // Aggiungiamo questi flag per forzare la pulizia dei campi quando cambi tipo bool clearProvider = false, bool clearType = false, @@ -262,6 +266,8 @@ class OperationsCubit extends Cubit { modelDisplayName: clearModel ? null : (modelDisplayName ?? current.modelDisplayName), + staffId: staffId ?? current.staffId, + staffDisplayName: staffDisplayName ?? current.staffDisplayName, ); emit(state.copyWith(currentOperation: updated)); diff --git a/lib/features/operations/ui/operation_form_screen.dart b/lib/features/operations/ui/operation_form_screen.dart index ca9b24b..ed6f233 100644 --- a/lib/features/operations/ui/operation_form_screen.dart +++ b/lib/features/operations/ui/operation_form_screen.dart @@ -1,9 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flux/core/blocs/session/session_cubit.dart'; import 'package:flux/features/operations/blocs/operations_cubit.dart'; import 'package:flux/features/operations/models/operation_model.dart'; import 'package:flux/features/operations/ui/widgets/customer_section.dart'; -import 'package:flux/features/operations/ui/widgets/details_section.dart'; // ASSICURATI DEL PATH +import 'package:flux/features/operations/ui/widgets/details_section.dart'; +import 'package:flux/features/operations/ui/widgets/staff_section.dart'; +import 'package:get_it/get_it.dart'; // ASSICURATI DEL PATH // import 'package:flux/features/attachments/ui/operation_files_section.dart'; class OperationFormScreen extends StatefulWidget { @@ -44,10 +47,26 @@ class _OperationFormScreenState extends State { @override void initState() { super.initState(); - context.read().initOperationForm( + final cubit = context.read(); + final currentLoggedStaff = GetIt.I + .get() + .state + .currentStaffMember!; + + // 1. Diciamo al Cubit di prepararsi + cubit.initOperationForm( existingOperation: widget.existingOperation, operationId: widget.operationId, + staffId: currentLoggedStaff.id, + staffDisplayName: currentLoggedStaff.name, ); + + // 2. IL TRUCCO MAGICO: + // Se abbiamo passato existingOperation, il Cubit si è appena aggiornato. + // Lo stato è già pronto, quindi sincronizziamo i controller SUBITO! + if (cubit.state.currentOperation != null) { + _syncTextControllers(cubit.state.currentOperation!); + } } @override @@ -240,6 +259,8 @@ class _OperationFormScreenState extends State { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + StaffSection(currentOp: currentOp), + const Divider(height: 50), _buildSectionTitle('Cliente & Riferimento'), CustomerSection(currentOp: currentOp), const SizedBox(height: 16), diff --git a/lib/features/operations/ui/widgets/staff_section.dart b/lib/features/operations/ui/widgets/staff_section.dart new file mode 100644 index 0000000..7c41e07 --- /dev/null +++ b/lib/features/operations/ui/widgets/staff_section.dart @@ -0,0 +1,136 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flux/features/operations/blocs/operations_cubit.dart'; +import 'package:flux/features/operations/models/operation_model.dart'; +// IMPORTA IL TUO CUBIT DELLO STAFF +// import 'package:flux/features/staff/blocs/staff_cubit.dart'; + +class StaffSection extends StatelessWidget { + final OperationModel? currentOp; + + const StaffSection({super.key, required this.currentOp}); + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + final selectedStaffId = currentOp?.staffId; + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(bottom: 12.0), + child: Text( + 'Operatore', + style: theme.textTheme.titleLarge?.copyWith( + fontWeight: FontWeight.bold, + ), + ), + ), + + // Ascoltiamo il Cubit che contiene la lista dei membri dello staff del negozio + // BlocBuilder( + // builder: (context, state) { + // final staffMembers = state.storeStaff; + + // Sostituisci questo blocco 'simulato' con i dati veri del tuo BlocBuilder + Builder( + builder: (context) { + // Dati finti per farti vedere la UI, piallali quando attacchi il BlocBuilder! + final staffMembers = [ + {'id': '1', 'name': 'Tu (Admin)'}, + {'id': '2', 'name': 'Marco'}, + {'id': '3', 'name': 'Giulia'}, + ]; + + return SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + children: staffMembers.map((staff) { + final staffId = staff['id'] as String; + final staffName = staff['name'] as String; + + final isSelected = staffId == selectedStaffId; + + return GestureDetector( + onTap: () { + // Aggiorniamo la form con un solo tap! + context.read().updateOperationFields( + staffId: staffId, + staffDisplayName: staffName, + ); + }, + child: AnimatedContainer( + duration: const Duration(milliseconds: 200), + margin: const EdgeInsets.only(right: 12.0), + padding: const EdgeInsets.symmetric( + horizontal: 16.0, + vertical: 10.0, + ), + decoration: BoxDecoration( + color: isSelected + ? theme.colorScheme.primary + : theme.colorScheme.surface, + borderRadius: BorderRadius.circular(30), + border: Border.all( + color: isSelected + ? theme.colorScheme.primary + : theme.dividerColor, + width: 1.5, + ), + boxShadow: isSelected + ? [ + BoxShadow( + color: theme.colorScheme.primary.withValues( + alpha: 0.3, + ), + blurRadius: 8, + offset: const Offset(0, 2), + ), + ] + : null, + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + CircleAvatar( + radius: 12, + backgroundColor: isSelected + ? Colors.white + : theme.colorScheme.primaryContainer, + child: Text( + staffName.substring(0, 1).toUpperCase(), + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.bold, + color: isSelected + ? theme.colorScheme.primary + : theme.colorScheme.onPrimaryContainer, + ), + ), + ), + const SizedBox(width: 8), + Text( + staffName, + style: TextStyle( + fontWeight: isSelected + ? FontWeight.bold + : FontWeight.w500, + color: isSelected + ? Colors.white + : theme.colorScheme.onSurface, + ), + ), + ], + ), + ), + ); + }).toList(), + ), + ); + }, + ), + ], + ); + } +}