change routes with names
This commit is contained in:
@@ -42,10 +42,26 @@ import 'package:flux/features/tickets/ui/ticket_list_screen.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
// Nota: Dovrai creare questi placeholder o file per non avere errori di compilazione
|
||||
// import 'package:flux/features/master_data/master_data_hub_screen.dart';
|
||||
// import 'package:flux/features/master_data/staff/ui/staff_screen.dart';
|
||||
// import 'package:flux/features/master_data/store/ui/stores_screen.dart';
|
||||
const String loginRoute = 'login';
|
||||
const String setPasswordRoute = 'set-password';
|
||||
const String onboardingRoute = 'onboarding';
|
||||
const String homeRoute = 'home';
|
||||
const String masterDataRoute = 'master-data';
|
||||
const String productsRoute = 'products';
|
||||
const String companySettingsRoute = 'company-settings';
|
||||
const String staffRoute = 'staff';
|
||||
const String storesRoute = 'stores';
|
||||
const String providersRoute = 'providers';
|
||||
const String settingsRoute = 'settings';
|
||||
const String themeRoute = 'theme';
|
||||
const String operationsRoute = 'operations';
|
||||
const String customersRoute = 'customers';
|
||||
const String ticketsRoute = 'tickets';
|
||||
const String ticketFormRoute = 'ticket-form';
|
||||
const String operationFormRoute = 'operation-form';
|
||||
const String uploadSuccessRoute = 'upload-success';
|
||||
const String customerFormRoute = 'customer-form';
|
||||
const String uploadRoute = 'upload';
|
||||
|
||||
class AppRouter {
|
||||
static GoRouter createRouter(SessionCubit sessionCubit) {
|
||||
@@ -97,14 +113,17 @@ class AppRouter {
|
||||
// --- ROTTE DI SERVIZIO (FUORI DALLA SHELL) ---
|
||||
GoRoute(
|
||||
path: '/login',
|
||||
name: 'login',
|
||||
builder: (context, state) => const AuthScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/set-password',
|
||||
name: 'set-password',
|
||||
builder: (context, state) => const SetPasswordScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/onboarding',
|
||||
name: 'onboarding',
|
||||
builder: (context, state) => BlocProvider(
|
||||
create: (context) => OnboardingCubit(
|
||||
GetIt.I.get<SessionCubit>(),
|
||||
@@ -119,15 +138,21 @@ class AppRouter {
|
||||
builder: (context, state, child) => AppShell(child: child),
|
||||
routes: [
|
||||
// 1. DASHBOARD
|
||||
GoRoute(path: '/', builder: (context, state) => const HomeScreen()),
|
||||
GoRoute(
|
||||
path: '/',
|
||||
name: homeRoute,
|
||||
builder: (context, state) => const HomeScreen(),
|
||||
),
|
||||
|
||||
// 2. HUB ANAGRAFICHE E SOTTO-ROTTE
|
||||
GoRoute(
|
||||
path: '/master-data',
|
||||
name: masterDataRoute,
|
||||
builder: (context, state) => const MasterDataHubScreen(),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'products', // Diventa /master-data/products
|
||||
name: 'products',
|
||||
builder: (context, state) {
|
||||
context.read<ProductsCubit>().refreshCubit();
|
||||
|
||||
@@ -136,21 +161,25 @@ class AppRouter {
|
||||
),
|
||||
GoRoute(
|
||||
path: 'company-settings',
|
||||
name: companySettingsRoute,
|
||||
builder: (context, state) => BlocProvider(
|
||||
create: (context) => CompanySettingsCubit(),
|
||||
child: const CompanySettingsScreen(),
|
||||
),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'staff', // Diventa /master-data/staff
|
||||
path: 'staff',
|
||||
name: staffRoute, // Diventa /master-data/staff
|
||||
builder: (context, state) => const StaffScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'stores', // Diventa /master-data/stores
|
||||
path: storesRoute,
|
||||
name: 'stores', // Diventa /master-data/stores
|
||||
builder: (context, state) => const StoresScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'providers', // Diventa /master-data/providers
|
||||
path: 'providers',
|
||||
name: providersRoute, // Diventa /master-data/providers
|
||||
builder: (context, state) =>
|
||||
const ProvidersMasterDataScreen(),
|
||||
),
|
||||
@@ -160,16 +189,19 @@ class AppRouter {
|
||||
// 3. IMPOSTAZIONI
|
||||
GoRoute(
|
||||
path: '/settings',
|
||||
name: settingsRoute,
|
||||
builder: (context, state) => const SettingsView(),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'theme',
|
||||
name: themeRoute,
|
||||
builder: (context, state) => const ThemeSettingsView(),
|
||||
),
|
||||
],
|
||||
),
|
||||
GoRoute(
|
||||
path: '/operations',
|
||||
name: operationsRoute,
|
||||
builder: (context, state) => BlocProvider(
|
||||
create: (context) => OperationListCubit(),
|
||||
child: const OperationListScreen(),
|
||||
@@ -177,11 +209,13 @@ class AppRouter {
|
||||
),
|
||||
GoRoute(
|
||||
path: '/customers',
|
||||
name: customersRoute,
|
||||
builder: (context, state) =>
|
||||
const CustomersContent(), // O come si chiama il tuo widget della lista!
|
||||
),
|
||||
GoRoute(
|
||||
path: '/tickets',
|
||||
name: ticketsRoute,
|
||||
builder: (context, state) => BlocProvider(
|
||||
create: (context) => TicketListCubit(),
|
||||
child: const TicketListScreen(),
|
||||
@@ -194,6 +228,7 @@ class AppRouter {
|
||||
GoRoute(
|
||||
// Il path sarà es. /tickets/form/123 oppure /tickets/form/new
|
||||
path: '/tickets/form/:id',
|
||||
name: ticketFormRoute,
|
||||
builder: (context, state) {
|
||||
// 1. Leggiamo l'ID dall'URL
|
||||
final String pathId = state.pathParameters['id'] ?? 'new';
|
||||
@@ -230,10 +265,12 @@ class AppRouter {
|
||||
),
|
||||
GoRoute(
|
||||
path: '/upload-success',
|
||||
name: uploadSuccessRoute,
|
||||
builder: (context, state) => const UploadSuccessScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/customer/:id',
|
||||
path: '/customer/form/:id',
|
||||
name: 'customer-form',
|
||||
builder: (context, state) {
|
||||
final customer = state.extra as CustomerModel;
|
||||
return BlocProvider(
|
||||
@@ -248,6 +285,7 @@ class AppRouter {
|
||||
|
||||
GoRoute(
|
||||
path: '/operations/form/:id',
|
||||
name: operationFormRoute,
|
||||
builder: (context, state) {
|
||||
final String pathId = state.pathParameters['id'] ?? 'new';
|
||||
final OperationModel? operationFromExtra =
|
||||
@@ -286,6 +324,7 @@ class AppRouter {
|
||||
|
||||
GoRoute(
|
||||
path: '/upload/:type/:id',
|
||||
name: uploadRoute,
|
||||
builder: (context, state) {
|
||||
final typeString = state.pathParameters['type']!;
|
||||
final id = state.pathParameters['id']!;
|
||||
|
||||
@@ -21,11 +21,10 @@ class QrUploadDialog extends StatelessWidget {
|
||||
|
||||
return BlocListener<AttachmentsBloc, AttachmentsState>(
|
||||
listener: (context, state) {
|
||||
if (state.status == AttachmentsStatus.success) {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
},
|
||||
listenWhen: (previous, current) => previous.status != current.status,
|
||||
listenWhen: (previous, current) =>
|
||||
previous.allFiles.length < current.allFiles.length,
|
||||
child: AlertDialog(
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
|
||||
backgroundColor: theme.colorScheme.surface,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flux/core/blocs/session/session_cubit.dart';
|
||||
import 'package:flux/core/routes/app_router.dart';
|
||||
import 'package:flux/core/theme/theme.dart';
|
||||
import 'package:flux/features/customers/blocs/customers_cubit.dart';
|
||||
import 'package:flux/features/customers/models/customer_model.dart';
|
||||
@@ -109,8 +110,9 @@ class _CustomersContentState extends State<CustomersContent> {
|
||||
final customer = state.customers[index];
|
||||
return _CustomerTile(
|
||||
customer: customer,
|
||||
onTap: () => context.push(
|
||||
'/customer/${customer.id}',
|
||||
onTap: () => context.pushNamed(
|
||||
customerFormRoute,
|
||||
pathParameters: {'id': customer.id!},
|
||||
extra: customer,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flux/core/blocs/session/session_cubit.dart';
|
||||
import 'package:flux/core/routes/app_router.dart';
|
||||
import 'package:flux/core/theme/theme.dart';
|
||||
import 'package:flux/core/utils/extensions.dart';
|
||||
import 'package:flux/features/home/latest_store_operations/bloc/latest_store_operations_bloc.dart';
|
||||
@@ -48,7 +49,7 @@ class _LatestOperationsCardContent extends StatelessWidget {
|
||||
side: BorderSide(color: theme.dividerColor.withValues(alpha: 0.5)),
|
||||
),
|
||||
child: InkWell(
|
||||
onTap: () => context.push('/operations'),
|
||||
onTap: () => context.pushNamed(operationsRoute),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
@@ -134,8 +135,9 @@ class _LatestOperationsCardContent extends StatelessWidget {
|
||||
itemBuilder: (context, index) {
|
||||
final operation = state.operations[index];
|
||||
return InkWell(
|
||||
onTap: () => context.push(
|
||||
'/operations/form/id=${operation.id}',
|
||||
onTap: () => context.pushNamed(
|
||||
operationFormRoute,
|
||||
pathParameters: {'id': operation.id!},
|
||||
extra: operation,
|
||||
),
|
||||
child: Padding(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flux/core/blocs/session/session_cubit.dart';
|
||||
import 'package:flux/core/routes/app_router.dart';
|
||||
import 'package:flux/core/theme/theme.dart';
|
||||
import 'package:flux/core/utils/extensions.dart';
|
||||
import 'package:flux/features/home/latest_store_operations/ui/latest_store_operations_card.dart';
|
||||
@@ -83,7 +84,7 @@ class HomeScreen extends StatelessWidget {
|
||||
color: Colors.purple,
|
||||
context: context,
|
||||
onTap: () =>
|
||||
context.push('/tickets'), // <-- Aggiunto!
|
||||
context.pushNamed(ticketsRoute), // <-- Aggiunto!
|
||||
),
|
||||
]),
|
||||
),
|
||||
@@ -186,7 +187,10 @@ class HomeScreen extends StatelessWidget {
|
||||
color: Colors.blue,
|
||||
onTap: () {
|
||||
// Entriamo nel form! Nessun parametro extra = Nuovo Servizio
|
||||
context.push('/operations/form/new');
|
||||
context.pushNamed(
|
||||
operationFormRoute,
|
||||
pathParameters: {'id': 'New'},
|
||||
);
|
||||
},
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
@@ -196,7 +200,7 @@ class HomeScreen extends StatelessWidget {
|
||||
color: Colors.redAccent,
|
||||
onTap: () {
|
||||
// Andiamo alla lista! (Da lì poi aggiungeremo il tasto "+" per il form)
|
||||
context.push('/tickets/form/new');
|
||||
context.pushNamed(ticketFormRoute, pathParameters: {'id': 'New'});
|
||||
},
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flux/core/routes/app_router.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
// Mantieni i tuoi import per il tema se usi le estensioni (es. context.accent)
|
||||
// import 'package:flux/core/theme/theme.dart';
|
||||
@@ -65,7 +66,7 @@ class MasterDataHubScreen extends StatelessWidget {
|
||||
color: Colors.orange,
|
||||
// Usiamo .push() perché avevamo detto che i clienti
|
||||
// stanno FUORI dalla Shell (niente BottomBar)
|
||||
onTap: () => context.push('/customers'),
|
||||
onTap: () => context.pushNamed(customersRoute),
|
||||
),
|
||||
_buildHubCard(
|
||||
context,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flux/core/blocs/session/session_cubit.dart';
|
||||
import 'package:flux/core/routes/app_router.dart';
|
||||
import 'package:flux/core/theme/theme.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
@@ -28,7 +29,7 @@ class SettingsView extends StatelessWidget {
|
||||
icon: Icons.business,
|
||||
subtitle: 'Configura i dati aziendali',
|
||||
context: context,
|
||||
onTap: () => context.push('/master-data/company-settings'),
|
||||
onTap: () => context.pushNamed(companySettingsRoute),
|
||||
),
|
||||
]),
|
||||
const SizedBox(height: 16),
|
||||
@@ -38,7 +39,7 @@ class SettingsView extends StatelessWidget {
|
||||
title: 'Tema (FLUX Dark)',
|
||||
subtitle: 'Configurazione visiva',
|
||||
context: context,
|
||||
onTap: () => context.push('/settings/theme'),
|
||||
onTap: () => context.pushNamed(themeRoute),
|
||||
),
|
||||
]),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flux/core/routes/app_router.dart';
|
||||
import 'package:flux/features/tickets/blocs/ticket_list_cubit.dart';
|
||||
import 'package:flux/features/tickets/blocs/ticket_list_state.dart';
|
||||
import 'package:flux/features/tickets/models/ticket_model.dart';
|
||||
import 'package:flux/features/tickets/models/ticket_status_extension.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class TicketListScreen extends StatefulWidget {
|
||||
const TicketListScreen({super.key});
|
||||
@@ -147,7 +149,7 @@ class _TicketListScreenState extends State<TicketListScreen> {
|
||||
),
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
onPressed: () {
|
||||
// TODO: Navigare alla creazione di un nuovo ticket
|
||||
context.pushNamed(ticketFormRoute, pathParameters: {'id': 'New'});
|
||||
},
|
||||
icon: const Icon(Icons.add),
|
||||
label: const Text('Nuovo Ticket'),
|
||||
@@ -279,7 +281,14 @@ class _TicketCard extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
onTap: () {
|
||||
// TODO: Aprire il dettaglio del ticket!
|
||||
context.pushNamed(
|
||||
'ticket-form',
|
||||
pathParameters: {'id': ticket.id!},
|
||||
extra:
|
||||
ticket, // <-- LA MAGIA È QUI: Passa l'oggetto intero!
|
||||
|
||||
// Teniamo anche il parametro URL per coerenza di routing
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user