fcm
This commit is contained in:
@@ -232,7 +232,7 @@ class HomeScreen extends StatelessWidget {
|
||||
QuickActionButton(
|
||||
icon: Icons.task_alt,
|
||||
label: context.l10n.commonTask,
|
||||
color: Colors.teal,
|
||||
color: Colors.orange,
|
||||
onTap: () {
|
||||
context.pushNamed(Routes.taskForm, pathParameters: {'id': 'new'});
|
||||
},
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flux/core/enums_and_consts/consts.dart';
|
||||
import 'package:flux/features/master_data/staff/models/staff_member_model.dart';
|
||||
import 'package:flux/features/master_data/store/models/store_model.dart';
|
||||
@@ -10,19 +11,38 @@ class StaffRepository {
|
||||
// --- ANAGRAFICA PURA ---
|
||||
|
||||
// Prende tutto lo staff della Company (per l'Hub Anagrafiche)
|
||||
Future<List<StaffMemberModel>> getStaffMembers(String companyId) async {
|
||||
final response = await _supabase
|
||||
.from(Tables.staffMembers)
|
||||
.select('''
|
||||
*,
|
||||
store_assignments:${Tables.staffInStores} (
|
||||
${Tables.stores}(*)
|
||||
)
|
||||
''')
|
||||
.eq('company_id', companyId)
|
||||
.order('name', ascending: true);
|
||||
Future<List<StaffMemberModel>> getStaffMembers(
|
||||
String companyId, {
|
||||
String? storeId,
|
||||
}) async {
|
||||
try {
|
||||
var filterBuilder = _supabase
|
||||
.from(Tables.staffMembers)
|
||||
.select('''
|
||||
*,
|
||||
store_assignments:${Tables.staffInStores} (
|
||||
${Tables.stores}(*)
|
||||
)
|
||||
''')
|
||||
.eq('company_id', companyId);
|
||||
|
||||
return (response as List).map((s) => StaffMemberModel.fromMap(s)).toList();
|
||||
if (storeId != null) {
|
||||
filterBuilder = filterBuilder.or(
|
||||
'store_id.eq.$storeId,store_id.is.null',
|
||||
);
|
||||
}
|
||||
|
||||
var transformBuilder = filterBuilder.order('name', ascending: true);
|
||||
|
||||
final response = await transformBuilder;
|
||||
|
||||
return (response as List)
|
||||
.map((s) => StaffMemberModel.fromMap(s))
|
||||
.toList();
|
||||
} on Exception catch (e) {
|
||||
debugPrint('Errore nel recupero della lista di staff: $e');
|
||||
throw Exception('Errore nel recupero della lista di staff: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<StaffMemberModel?> getStaffMemberById(String staffId) async {
|
||||
|
||||
@@ -18,6 +18,7 @@ class _ReminderSettingsScreenState extends State<ReminderSettingsScreen> {
|
||||
}
|
||||
|
||||
void _showAddReminderBottomSheet(BuildContext context) {
|
||||
final cubit = context.read<ReminderDefaultsCubit>();
|
||||
// Valori preselezionati
|
||||
int selectedMinutes = 15;
|
||||
String selectedChannel = 'push';
|
||||
@@ -73,8 +74,9 @@ class _ReminderSettingsScreenState extends State<ReminderSettingsScreen> {
|
||||
),
|
||||
],
|
||||
onChanged: (val) {
|
||||
if (val != null)
|
||||
if (val != null) {
|
||||
setModalState(() => selectedMinutes = val);
|
||||
}
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
@@ -113,8 +115,9 @@ class _ReminderSettingsScreenState extends State<ReminderSettingsScreen> {
|
||||
),
|
||||
],
|
||||
onChanged: (val) {
|
||||
if (val != null)
|
||||
if (val != null) {
|
||||
setModalState(() => selectedChannel = val);
|
||||
}
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 32),
|
||||
@@ -125,7 +128,7 @@ class _ReminderSettingsScreenState extends State<ReminderSettingsScreen> {
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
),
|
||||
onPressed: () {
|
||||
context.read<ReminderDefaultsCubit>().addReminder(
|
||||
cubit.addReminder(
|
||||
minutesBefore: selectedMinutes,
|
||||
channel: selectedChannel,
|
||||
);
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
// =========================================================================
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user