This commit is contained in:
2026-05-29 19:24:40 +02:00
parent 5ad3e12b1f
commit 9bace01b93
7 changed files with 375 additions and 430 deletions

View File

@@ -11,40 +11,105 @@ import 'package:get_it/get_it.dart';
part 'task_form_state.dart';
class TaskFormCubit extends Cubit<TaskFormState> {
final TaskRepository _repository = GetIt.I.get<TaskRepository>();
final TasksRepository _repository = GetIt.I.get<TasksRepository>();
final SettingsRepository _settingsRepository = GetIt.I
.get<SettingsRepository>();
final SessionCubit _sessionCubit = GetIt.I.get<SessionCubit>();
TaskFormCubit({TaskModel? existingTask})
: super(
TaskFormState(
id: existingTask?.id,
title: existingTask?.title ?? '',
description: existingTask?.description ?? '',
dueDate: existingTask?.dueDate,
isGlobal: existingTask?.isGlobal ?? false,
selectedStaffIds: existingTask?.assignedToIds ?? [],
),
) {
if (existingTask == null) {
_initializeNewTaskReminders();
} else {
_loadExistingTaskReminders(existingTask.id!);
}
TaskFormCubit({
String? initialTaskId, // <-- RIPRISTINATO PER DEEP LINK
TaskModel? existingTask,
}) : super(const TaskFormState()) {
// Avviamo l'inizializzazione centralizzata (gestisce sia mem, sia deep link, sia nuovo)
initForm(initialTaskId: initialTaskId, existingTask: existingTask);
}
String get _companyId => _sessionCubit.state.company!.id!;
String get _currentUserId => _sessionCubit.state.currentStaffMember!.id!;
String? get _currentStoreId => _sessionCubit.state.currentStore?.id;
// --- INIT REMINDER NUOVO TASK ---
// --- ARMED INITIALIZATION (Nuovo, Esistente o Deep Link) ---
Future<void> initForm({
String? initialTaskId,
TaskModel? existingTask,
}) async {
emit(state.copyWith(status: TaskFormStatus.loading));
try {
TaskModel? task = existingTask;
// 1. Se arriviamo da Deep Link col solo ID, lo scarichiamo dal DB
if (initialTaskId != null && task == null) {
task = await _repository.fetchTaskById(initialTaskId);
}
if (task != null) {
// CASO: TASK ESISTENTE (Modifica o Deep Link pronto)
emit(
state.copyWith(
id: task.id,
title: task.title,
description: task.description,
dueDate: task.dueDate,
isGlobal: task.isGlobal, // Sfrutta il tuo getter storeId == null
selectedStaffIds: task.assignedToIds,
),
);
await _loadExistingTaskReminders(task.id!);
} else {
// CASO: NUOVO TASK
await _initializeNewTaskReminders();
}
// 2. Carichiamo e raggruppiamo il personale (Global o Store)
await _loadAndGroupStaff();
// Mandiamo lo status a 'initial' così il FormScreen sincronizza i controller di testo!
emit(state.copyWith(status: TaskFormStatus.initial));
} catch (e) {
emit(
state.copyWith(
status: TaskFormStatus.failure,
errorMessage: e.toString(),
),
);
}
}
// --- 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,
);
// 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);
}
emit(state.copyWith(groupedAvailableStaff: grouped));
}
// Se l'utente switcha su "Globale Aziendale", ricarichiamo lo staff di conseguenza
void toggleGlobalScope(bool g) async {
emit(state.copyWith(isGlobal: g, status: TaskFormStatus.loading));
await _loadAndGroupStaff();
emit(
state.copyWith(status: TaskFormStatus.initial),
); // Ri-notifichiamo la UI
}
// --- INIT REMINDER ---
Future<void> _initializeNewTaskReminders() async {
try {
final defaults = await _settingsRepository.getMyReminderDefaults(
companyId: _companyId,
staffId: _currentUserId,
);
final initialReminders = defaults
.map(
(d) => TaskReminderConfig(
@@ -53,10 +118,8 @@ class TaskFormCubit extends Cubit<TaskFormState> {
),
)
.toList();
emit(state.copyWith(reminders: initialReminders));
} catch (e) {
// Fallback in caso di errore
emit(
state.copyWith(
reminders: const [
@@ -67,10 +130,8 @@ class TaskFormCubit extends Cubit<TaskFormState> {
}
}
// --- INIT REMINDER TASK ESISTENTE ---
Future<void> _loadExistingTaskReminders(String taskId) async {
try {
// Recuperiamo SOLO i reminder non forzati dell'utente loggato per popolare il form
final existingConfigs = await _repository.fetchPersonalReminders(
taskId: taskId,
staffId: _currentUserId,
@@ -81,11 +142,10 @@ class TaskFormCubit extends Cubit<TaskFormState> {
}
}
// --- UPDATE CAMPI BASE ---
// --- AGGIORNAMENTO CAMPI ---
void updateTitle(String t) => emit(state.copyWith(title: t));
void updateDescription(String d) => emit(state.copyWith(description: d));
void updateDueDate(DateTime? d) => emit(state.copyWith(dueDate: d));
void toggleGlobalScope(bool g) => emit(state.copyWith(isGlobal: g));
void toggleStaffSelection(String staffId) {
final updated = List<String>.from(state.selectedStaffIds);
@@ -93,7 +153,22 @@ class TaskFormCubit extends Cubit<TaskFormState> {
emit(state.copyWith(selectedStaffIds: updated));
}
// --- GESTIONE REMINDER NEL FORM ---
void toggleStoreSelection(String storeName, bool selectAll) {
final updated = List<String>.from(state.selectedStaffIds);
final storeStaff = state.groupedAvailableStaff[storeName] ?? [];
for (var staff in storeStaff) {
if (staff.id == null) continue;
if (selectAll) {
if (!updated.contains(staff.id)) updated.add(staff.id!);
} else {
updated.remove(staff.id);
}
}
emit(state.copyWith(selectedStaffIds: updated));
}
// --- AZIONI REMINDER ---
void addReminderRule(int minutesBefore, String channel) {
final updated = List<TaskReminderConfig>.from(state.reminders);
final newConfig = TaskReminderConfig(
@@ -114,7 +189,7 @@ class TaskFormCubit extends Cubit<TaskFormState> {
emit(state.copyWith(reminders: updated));
}
// --- SALVATAGGIO FINALE ---
// --- SALVATAGGIO ---
Future<void> saveTask() async {
if (!state.isFormValid) return;
emit(state.copyWith(status: TaskFormStatus.submitting));
@@ -122,18 +197,18 @@ class TaskFormCubit extends Cubit<TaskFormState> {
final taskToSave = TaskModel(
id: state.id,
companyId: _companyId,
createdBy: _currentUserId,
createdById: _currentUserId,
title: state.title.trim(),
description: state.description.trim(),
dueDate: state.dueDate,
isGlobal: state.isGlobal,
storeId: state.isGlobal
? null
: _currentStoreId, // Gestione nativa basata sulla tua logica
assignedToIds: state.selectedStaffIds,
);
try {
if (state.id == null) {
// NUOVO TASK -> CREATE
// Qui potresti passare un managerForcedOverride se implementi la UI per quello
await _repository.createTask(
task: taskToSave,
assignedStaffIds: state.selectedStaffIds,
@@ -141,7 +216,6 @@ class TaskFormCubit extends Cubit<TaskFormState> {
currentUserCustomReminders: state.reminders,
);
} else {
// VECCHIO TASK -> UPDATE
await _repository.updateTask(
task: taskToSave,
assignedStaffIds: state.selectedStaffIds,

View File

@@ -10,8 +10,9 @@ class TaskFormState extends Equatable {
final DateTime? dueDate;
final bool isGlobal;
final List<String> selectedStaffIds;
final List<TaskReminderConfig>
reminders; // I promemoria (solo dell'utente loggato)
final List<TaskReminderConfig> reminders;
final Map<String, List<StaffMemberModel>>
groupedAvailableStaff; // <-- RIPRISTINATO
final String? errorMessage;
const TaskFormState({
@@ -23,6 +24,7 @@ class TaskFormState extends Equatable {
this.isGlobal = false,
this.selectedStaffIds = const [],
this.reminders = const [],
this.groupedAvailableStaff = const {},
this.errorMessage,
});
@@ -37,6 +39,7 @@ class TaskFormState extends Equatable {
bool? isGlobal,
List<String>? selectedStaffIds,
List<TaskReminderConfig>? reminders,
Map<String, List<StaffMemberModel>>? groupedAvailableStaff,
String? errorMessage,
}) {
return TaskFormState(
@@ -48,6 +51,8 @@ class TaskFormState extends Equatable {
isGlobal: isGlobal ?? this.isGlobal,
selectedStaffIds: selectedStaffIds ?? this.selectedStaffIds,
reminders: reminders ?? this.reminders,
groupedAvailableStaff:
groupedAvailableStaff ?? this.groupedAvailableStaff,
errorMessage: errorMessage,
);
}
@@ -62,6 +67,7 @@ class TaskFormState extends Equatable {
isGlobal,
selectedStaffIds,
reminders,
groupedAvailableStaff,
errorMessage,
];
}

View File

@@ -8,7 +8,7 @@ import 'package:get_it/get_it.dart';
part 'task_list_state.dart';
class TaskListCubit extends Cubit<TaskListState> {
final TaskRepository _repository = GetIt.I.get<TaskRepository>();
final TasksRepository _repository = GetIt.I.get<TasksRepository>();
final String currentCompanyId;
final String? currentStoreId;