This commit is contained in:
2026-05-30 12:12:14 +02:00
parent 9bace01b93
commit bd81173559
30 changed files with 1020 additions and 51 deletions

View File

@@ -1,12 +1,13 @@
import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flux/core/blocs/session/session_cubit.dart';
import 'package:flux/features/master_data/staff/data/staff_repository.dart';
import 'package:flux/features/master_data/staff/models/staff_member_model.dart';
import 'package:flux/features/settings/data/settings_repository.dart';
import 'package:flux/features/tasks/data/task_repository.dart';
import 'package:flux/features/tasks/models/task_model.dart';
import 'package:flux/features/tasks/models/task_reminder_config.dart';
import 'package:flux/features/tasks/models/task_status.dart';
import 'package:get_it/get_it.dart';
part 'task_form_state.dart';
@@ -14,12 +15,16 @@ class TaskFormCubit extends Cubit<TaskFormState> {
final TasksRepository _repository = GetIt.I.get<TasksRepository>();
final SettingsRepository _settingsRepository = GetIt.I
.get<SettingsRepository>();
final _staffRepository = GetIt.I.get<StaffRepository>();
final SessionCubit _sessionCubit = GetIt.I.get<SessionCubit>();
final List<StaffMemberModel>? _preloadedStaff;
TaskFormCubit({
String? initialTaskId, // <-- RIPRISTINATO PER DEEP LINK
TaskModel? existingTask,
}) : super(const TaskFormState()) {
List<StaffMemberModel>? allStaff,
}) : _preloadedStaff = allStaff,
super(const TaskFormState()) {
// Avviamo l'inizializzazione centralizzata (gestisce sia mem, sia deep link, sia nuovo)
initForm(initialTaskId: initialTaskId, existingTask: existingTask);
}
@@ -77,18 +82,34 @@ class TaskFormCubit extends Cubit<TaskFormState> {
// --- LOGICA GESTIONE STAFF (GLOBAL STAFF / STORE STAFF) ---
Future<void> _loadAndGroupStaff() async {
// Se isGlobal è true, passiamo null come storeId al repo per tirare giù tutta l'azienda
final List<StaffMemberModel> staffList = await _repository
.fetchAvailableStaff(
companyId: _companyId,
storeId: state.isGlobal ? null : _currentStoreId,
);
final List<StaffMemberModel> staffList;
// SE C'È LO STAFF PASCIUTO DALL'APP USA QUELLO, ALTRIMENTI CHIAMA IL REPO
if (_preloadedStaff != null && _preloadedStaff.isNotEmpty) {
staffList = _preloadedStaff;
} else {
staffList = await _staffRepository.getStaffMembers(_companyId);
}
// Raggruppamento per nome del negozio (Mappa { "Nome Negozio": [Membri] })
final Map<String, List<StaffMemberModel>> grouped = {};
for (var staff in staffList) {
final storeName = staff.storeName ?? 'Senza Sede';
grouped.putIfAbsent(storeName, () => []).add(staff);
if (!state.isGlobal) {
final belongsToCurrentStore = staff.assignedStores.any(
(store) => store.id == _currentStoreId,
);
if (!belongsToCurrentStore) continue;
}
if (staff.assignedStores.isEmpty) {
grouped.putIfAbsent('Direzione / Senza Sede', () => []).add(staff);
} else {
for (var store in staff.assignedStores) {
if (!state.isGlobal && store.id != _currentStoreId) continue;
final storeName = store.name;
grouped.putIfAbsent(storeName, () => []).add(staff);
}
}
}
emit(state.copyWith(groupedAvailableStaff: grouped));
@@ -138,7 +159,7 @@ class TaskFormCubit extends Cubit<TaskFormState> {
);
emit(state.copyWith(reminders: existingConfigs));
} catch (e) {
print('Errore caricamento reminder: $e');
debugPrint('Errore caricamento reminder: $e');
}
}

View File

@@ -39,6 +39,7 @@ class TasksRepository {
)
.toList();
} catch (e) {
debugPrint('Errore fetch personal reminders: $e');
throw Exception('Errore fetch personal reminders: $e');
}
}
@@ -98,6 +99,26 @@ class TasksRepository {
}
}
Future<TaskModel?> fetchTaskById(String taskId) async {
try {
final response = await _supabase
.from(Tables.tasks)
.select('''
*,
task_assignments:${Tables.taskAssignments} (
${Tables.staffMembers} (*)
)
''')
.eq('id', taskId)
.single();
return TaskModel.fromMap(response);
} catch (e) {
debugPrint('Errore fetch task by id: $e');
throw Exception('Errore fetch task by id: $e');
}
}
// =========================================================================
// REALTIME STREAM (La sentinella per la bacheca)
// =========================================================================

View File

@@ -1,8 +1,6 @@
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/tasks/blocs/task_form_cubit.dart';
import 'package:get_it/get_it.dart';
import 'package:go_router/go_router.dart';
class TaskFormScreen extends StatefulWidget {
@@ -136,15 +134,7 @@ class _TaskFormScreenState extends State<TaskFormScreen> {
)
else
TextButton.icon(
onPressed: state.isFormValid
? () => cubit.saveTask(
currentUserId: GetIt.I
.get<SessionCubit>()
.state
.currentStaffMember!
.id!,
)
: null,
onPressed: state.isFormValid ? () => cubit.saveTask() : null,
icon: const Icon(Icons.save),
label: const Text('Salva'),
style: TextButton.styleFrom(