basta localizzazioni per ora

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
2026-04-30 10:25:52 +02:00
parent 8d3ca62304
commit 11c1e28aaa
23 changed files with 720 additions and 213 deletions

View File

@@ -24,7 +24,7 @@ class CoreRepository {
return CompanyModel.fromMap(response); return CompanyModel.fromMap(response);
} catch (e) { } catch (e) {
debugPrint('Errore recupero azienda: $e'); debugPrint('Errore recupero azienda: $e');
throw Exception('Errore recupero azienda: $e'); throw Exception('$e');
} }
} }
@@ -38,7 +38,7 @@ class CoreRepository {
if (response == null) return null; if (response == null) return null;
return CompanyModel.fromMap(response); return CompanyModel.fromMap(response);
} catch (e) { } catch (e) {
debugPrint('Errore recupero azienda per ID: $e'); debugPrint('$e');
return null; return null;
} }
} }
@@ -55,7 +55,7 @@ class CoreRepository {
return (response as List).map((s) => StoreModel.fromMap(s)).toList(); return (response as List).map((s) => StoreModel.fromMap(s)).toList();
} catch (e) { } catch (e) {
debugPrint('Errore recupero negozi: $e'); debugPrint('Errore recupero negozi: $e');
throw Exception('Errore recupero negozi: $e'); throw Exception('$e');
} }
} }
@@ -71,7 +71,7 @@ class CoreRepository {
return StaffMemberModel.fromMap(response); return StaffMemberModel.fromMap(response);
} catch (e) { } catch (e) {
debugPrint('Errore recupero profilo staff: $e'); debugPrint('Errore recupero profilo staff: $e');
throw Exception('Errore recupero profilo staff: $e'); throw Exception('$e');
} }
} }
@@ -87,7 +87,7 @@ class CoreRepository {
return CompanyModel.fromMap(response); return CompanyModel.fromMap(response);
} catch (e) { } catch (e) {
debugPrint('Creazione azienda fallita: $e'); debugPrint('Creazione azienda fallita: $e');
throw Exception('Creazione azienda fallita: $e'); throw Exception('$e');
} }
} }
@@ -101,7 +101,7 @@ class CoreRepository {
return StoreModel.fromMap(response); return StoreModel.fromMap(response);
} catch (e) { } catch (e) {
debugPrint('Creazione negozio fallita: $e'); debugPrint('Creazione negozio fallita: $e');
throw Exception('Creazione negozio fallita: $e'); throw Exception('$e');
} }
} }
@@ -120,7 +120,7 @@ class CoreRepository {
return StaffMemberModel.fromMap(response); return StaffMemberModel.fromMap(response);
} catch (e) { } catch (e) {
debugPrint('Creazione profilo staff fallita: $e'); debugPrint('Creazione profilo staff fallita: $e');
throw Exception('Creazione profilo staff fallita: $e'); throw Exception('$e');
} }
} }

View File

@@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flux/core/utils/extensions.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
class AppShell extends StatelessWidget { class AppShell extends StatelessWidget {
@@ -43,21 +44,21 @@ class AppShell extends StatelessWidget {
onDestinationSelected: (index) => onDestinationSelected: (index) =>
_onItemTapped(index, context), _onItemTapped(index, context),
labelType: NavigationRailLabelType.all, labelType: NavigationRailLabelType.all,
destinations: const [ destinations: [
NavigationRailDestination( NavigationRailDestination(
icon: Icon(Icons.dashboard_outlined), icon: Icon(Icons.dashboard_outlined),
selectedIcon: Icon(Icons.dashboard), selectedIcon: Icon(Icons.dashboard),
label: Text('Dashboard'), label: Text(context.l10n.commonDashboard),
), ),
NavigationRailDestination( NavigationRailDestination(
icon: Icon(Icons.folder_special_outlined), icon: Icon(Icons.folder_special_outlined),
selectedIcon: Icon(Icons.folder_special), selectedIcon: Icon(Icons.folder_special),
label: Text('Anagrafiche'), label: Text(context.l10n.commonMasterData),
), ),
NavigationRailDestination( NavigationRailDestination(
icon: Icon(Icons.settings_outlined), icon: Icon(Icons.settings_outlined),
selectedIcon: Icon(Icons.settings), selectedIcon: Icon(Icons.settings),
label: Text('Impostazioni'), label: Text(context.l10n.commonSettings),
), ),
], ],
), ),
@@ -73,21 +74,21 @@ class AppShell extends StatelessWidget {
: NavigationBar( : NavigationBar(
selectedIndex: currentIndex, selectedIndex: currentIndex,
onDestinationSelected: (index) => _onItemTapped(index, context), onDestinationSelected: (index) => _onItemTapped(index, context),
destinations: const [ destinations: [
NavigationDestination( NavigationDestination(
icon: Icon(Icons.dashboard_outlined), icon: Icon(Icons.dashboard_outlined),
selectedIcon: Icon(Icons.dashboard), selectedIcon: Icon(Icons.dashboard),
label: 'Dashboard', label: context.l10n.commonDashboard,
), ),
NavigationDestination( NavigationDestination(
icon: Icon(Icons.folder_special_outlined), icon: Icon(Icons.folder_special_outlined),
selectedIcon: Icon(Icons.folder_special), selectedIcon: Icon(Icons.folder_special),
label: 'Anagrafiche', label: context.l10n.commonMasterData,
), ),
NavigationDestination( NavigationDestination(
icon: Icon(Icons.settings_outlined), icon: Icon(Icons.settings_outlined),
selectedIcon: Icon(Icons.settings), selectedIcon: Icon(Icons.settings),
label: 'Impostazioni', label: context.l10n.commonSettings,
), ),
], ],
), ),

View File

@@ -4,6 +4,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flux/core/blocs/session/session_cubit.dart'; import 'package:flux/core/blocs/session/session_cubit.dart';
import 'package:flux/core/data/core_repository.dart'; import 'package:flux/core/data/core_repository.dart';
import 'package:flux/core/layout/app_shell.dart'; import 'package:flux/core/layout/app_shell.dart';
import 'package:flux/core/utils/extensions.dart';
import 'package:flux/core/widgets/set_password_screen.dart'; import 'package:flux/core/widgets/set_password_screen.dart';
import 'package:flux/features/auth/ui/auth_screen.dart'; import 'package:flux/features/auth/ui/auth_screen.dart';
import 'package:flux/features/customers/blocs/customer_files_bloc.dart'; import 'package:flux/features/customers/blocs/customer_files_bloc.dart';
@@ -14,6 +15,9 @@ import 'package:flux/features/customers/ui/customers_content.dart';
import 'package:flux/features/home/ui/home_screen.dart'; import 'package:flux/features/home/ui/home_screen.dart';
import 'package:flux/features/master_data/master_data_hub_content.dart'; import 'package:flux/features/master_data/master_data_hub_content.dart';
import 'package:flux/features/master_data/products/ui/products_screen.dart'; import 'package:flux/features/master_data/products/ui/products_screen.dart';
import 'package:flux/features/master_data/providers/ui/providers_master_data_screen.dart';
import 'package:flux/features/master_data/staff/ui/staff_screen.dart';
import 'package:flux/features/master_data/store/ui/stores_screen.dart';
import 'package:flux/features/onboarding/blocs/onboarding_cubit.dart'; import 'package:flux/features/onboarding/blocs/onboarding_cubit.dart';
import 'package:flux/features/onboarding/ui/onboarding_screen.dart'; import 'package:flux/features/onboarding/ui/onboarding_screen.dart';
import 'package:flux/features/services/blocs/service_files_bloc.dart'; import 'package:flux/features/services/blocs/service_files_bloc.dart';
@@ -96,19 +100,16 @@ class AppRouter {
), ),
GoRoute( GoRoute(
path: 'staff', // Diventa /master-data/staff path: 'staff', // Diventa /master-data/staff
builder: (context, state) => builder: (context, state) => const StaffScreen(),
const Scaffold(body: Center(child: Text("Lista Staff"))),
), ),
GoRoute( GoRoute(
path: 'stores', // Diventa /master-data/stores path: 'stores', // Diventa /master-data/stores
builder: (context, state) => builder: (context, state) => const StoresScreen(),
const Scaffold(body: Center(child: Text("Lista Negozi"))),
), ),
GoRoute( GoRoute(
path: 'providers', // Diventa /master-data/providers path: 'providers', // Diventa /master-data/providers
builder: (context, state) => const Scaffold( builder: (context, state) =>
body: Center(child: Text("Lista Fornitori")), const ProvidersMasterDataScreen(),
),
), ),
], ],
), ),
@@ -117,7 +118,7 @@ class AppRouter {
GoRoute( GoRoute(
path: '/settings', path: '/settings',
builder: (context, state) => Scaffold( builder: (context, state) => Scaffold(
appBar: AppBar(title: const Text("Impostazioni")), appBar: AppBar(title: Text(context.l10n.commonSettings)),
body: Center( body: Center(
child: ElevatedButton.icon( child: ElevatedButton.icon(
onPressed: () => context.read<SessionCubit>().signOut(), onPressed: () => context.read<SessionCubit>().signOut(),

View File

@@ -0,0 +1,20 @@
import 'package:flutter/material.dart';
import 'package:flux/core/utils/extensions.dart';
class AppMessage {
final String key;
final String? argument;
const AppMessage({required this.key, this.argument});
String translatedMessage(BuildContext context) {
switch (key) {
case 'authCubitCheckEmailToConfirmAccount':
return context.l10n.authCubitCheckEmailToConfirmAccount;
case 'authCubitResetPasswordEmailSentTo':
return context.l10n.authCubitResetPasswordEmailSentTo(argument!);
default:
return 'empty message';
}
}
}

View File

@@ -1,5 +1,6 @@
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flux/core/utils/extensions.dart';
import 'package:flux/core/utils/functions.dart'; import 'package:flux/core/utils/functions.dart';
class ImageViewerWidget extends StatelessWidget { class ImageViewerWidget extends StatelessWidget {
@@ -36,8 +37,8 @@ class ImageViewerWidget extends StatelessWidget {
return const CircularProgressIndicator(); return const CircularProgressIndicator();
} }
if (snapshot.hasError) { if (snapshot.hasError) {
return const Text( return Text(
"Errore caricamento immagine (Permessi negati?)", context.l10n.imageViewerWidgetErrorOpening,
style: TextStyle(color: Colors.red), style: TextStyle(color: Colors.red),
); );
} }

View File

@@ -1,5 +1,6 @@
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flux/core/utils/extensions.dart';
import 'package:flux/core/utils/functions.dart'; import 'package:flux/core/utils/functions.dart';
import 'package:pdfx/pdfx.dart'; import 'package:pdfx/pdfx.dart';
import 'package:internet_file/internet_file.dart'; import 'package:internet_file/internet_file.dart';
@@ -74,13 +75,13 @@ class _PdfViewerWidgetState extends State<PdfViewerWidget> {
if (_errorMessage != null) { if (_errorMessage != null) {
return Scaffold( return Scaffold(
appBar: AppBar(leading: const CloseButton()), appBar: AppBar(leading: const CloseButton()),
body: Center(child: Text("Errore: $_errorMessage")), body: Center(child: Text(context.l10n.commonError(_errorMessage!))),
); );
} }
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: const Text("Anteprima PDF"), title: Text(context.l10n.pdfViewerAnteprimaPdf),
leading: IconButton( leading: IconButton(
icon: const Icon(Icons.close), icon: const Icon(Icons.close),
onPressed: () => Navigator.pop(context), onPressed: () => Navigator.pop(context),

View File

@@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flux/core/utils/extensions.dart';
import 'package:qr_flutter/qr_flutter.dart'; import 'package:qr_flutter/qr_flutter.dart';
class QrUploadDialog extends StatelessWidget { class QrUploadDialog extends StatelessWidget {
@@ -84,7 +85,7 @@ class QrUploadDialog extends StatelessWidget {
actions: [ actions: [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
child: const Text("CHIUDI"), child: Text(context.l10n.commonClose),
), ),
], ],
actionsAlignment: MainAxisAlignment.center, actionsAlignment: MainAxisAlignment.center,

View File

@@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flux/core/utils/extensions.dart';
import 'package:flux/core/widgets/flux_text_field.dart'; import 'package:flux/core/widgets/flux_text_field.dart';
import 'package:get_it/get_it.dart'; import 'package:get_it/get_it.dart';
import 'package:supabase_flutter/supabase_flutter.dart'; import 'package:supabase_flutter/supabase_flutter.dart';
@@ -25,9 +26,7 @@ class _SetPasswordScreenState extends State<SetPasswordScreen> {
final newPassword = _passwordCtrl.text.trim(); final newPassword = _passwordCtrl.text.trim();
if (newPassword.length < 6) { if (newPassword.length < 6) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( SnackBar(content: Text(context.l10n.setPasswordScreenAtLeast6Chars)),
content: Text("La password deve avere almeno 6 caratteri"),
),
); );
return; return;
} }
@@ -43,23 +42,23 @@ class _SetPasswordScreenState extends State<SetPasswordScreen> {
// 2. Finito! Lo mandiamo alla home o facciamo ricaricare la sessione al SessionCubit // 2. Finito! Lo mandiamo alla home o facciamo ricaricare la sessione al SessionCubit
if (mounted) { if (mounted) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( SnackBar(
content: Text("Password impostata! Benvenuto a bordo 🚀"), content: Text(context.l10n.setPasswordScreenPasswordSetWelcome),
), ),
); );
context.go('/'); // Rimandiamo al router principale context.go('/'); // Rimandiamo al router principale
} }
} on AuthException catch (e) { } on AuthException catch (e) {
if (mounted) { if (mounted) {
ScaffoldMessenger.of( ScaffoldMessenger.of(context).showSnackBar(
context, SnackBar(content: Text(context.l10n.authError(e.message))),
).showSnackBar(SnackBar(content: Text("Errore Auth: ${e.message}"))); );
} }
} catch (e) { } catch (e) {
if (mounted) { if (mounted) {
ScaffoldMessenger.of( ScaffoldMessenger.of(context).showSnackBar(
context, SnackBar(content: Text(context.l10n.commonError(e.toString()))),
).showSnackBar(SnackBar(content: Text("Errore: $e"))); );
} }
} finally { } finally {
if (mounted) setState(() => _isLoading = false); if (mounted) setState(() => _isLoading = false);
@@ -70,7 +69,7 @@ class _SetPasswordScreenState extends State<SetPasswordScreen> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: const Text("Benvenuto in FLUX!"), title: Text(context.l10n.setPasswordScreenWelcomeInFlux),
automaticallyImplyLeading: automaticallyImplyLeading:
false, // Non può tornare indietro, deve mettere la password! false, // Non può tornare indietro, deve mettere la password!
), ),
@@ -82,21 +81,21 @@ class _SetPasswordScreenState extends State<SetPasswordScreen> {
children: [ children: [
const Icon(Icons.lock_reset, size: 80, color: Colors.blueAccent), const Icon(Icons.lock_reset, size: 80, color: Colors.blueAccent),
const SizedBox(height: 24), const SizedBox(height: 24),
const Text( Text(
"Imposta la tua Password", context.l10n.setPasswordScreenSetPassword,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
const Text( Text(
"Hai accettato l'invito. Scegli una password sicura per accedere in futuro.", context.l10n.setPasswordInviteAcceptedChoosePassword,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle(color: Colors.grey), style: TextStyle(color: Colors.grey),
), ),
const SizedBox(height: 32), const SizedBox(height: 32),
FluxTextField( FluxTextField(
controller: _passwordCtrl, controller: _passwordCtrl,
label: "Nuova Password", label: context.l10n.commonNewPassword,
icon: Icons.lock, icon: Icons.lock,
isPassword: true, isPassword: true,
), ),
@@ -108,8 +107,8 @@ class _SetPasswordScreenState extends State<SetPasswordScreen> {
), ),
child: _isLoading child: _isLoading
? const CircularProgressIndicator(color: Colors.white) ? const CircularProgressIndicator(color: Colors.white)
: const Text( : Text(
"SALVA E INIZIA", context.l10n.setPasswordScreenSaveAndStart,
style: TextStyle(fontSize: 16), style: TextStyle(fontSize: 16),
), ),
), ),

View File

@@ -2,6 +2,7 @@ import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flux/core/blocs/session/session_cubit.dart'; import 'package:flux/core/blocs/session/session_cubit.dart';
import 'package:flux/core/data/constants.dart'; import 'package:flux/core/data/constants.dart';
import 'package:flux/core/utils/app_message.dart';
import 'package:get_it/get_it.dart'; import 'package:get_it/get_it.dart';
import 'package:supabase_flutter/supabase_flutter.dart'; import 'package:supabase_flutter/supabase_flutter.dart';
part 'auth_state.dart'; part 'auth_state.dart';
@@ -41,7 +42,9 @@ class AuthCubit extends Cubit<AuthState> {
emit( emit(
state.copyWith( state.copyWith(
status: AuthStatus.initial, status: AuthStatus.initial,
infoMessage: "Controlla la tua email per confermare l'account!", infoMessage: AppMessage(
key: 'authCubitCheckEmailToConfirmAccount',
),
), ),
); );
} else { } else {
@@ -82,7 +85,10 @@ class AuthCubit extends Cubit<AuthState> {
emit( emit(
state.copyWith( state.copyWith(
status: AuthStatus.pwResetSent, status: AuthStatus.pwResetSent,
infoMessage: "Email per reset password inviata a $email!", infoMessage: AppMessage(
key: 'authCubitResetPasswordEmailSentTo',
argument: email,
),
), ),
); );
} }

View File

@@ -6,7 +6,7 @@ class AuthState extends Equatable {
final AuthStatus status; final AuthStatus status;
final bool isLoginMode; final bool isLoginMode;
final String? errorMessage; final String? errorMessage;
final String? infoMessage; final AppMessage? infoMessage;
const AuthState({ const AuthState({
this.status = AuthStatus.initial, this.status = AuthStatus.initial,
@@ -19,7 +19,7 @@ class AuthState extends Equatable {
AuthStatus? status, AuthStatus? status,
bool? isLoginMode, bool? isLoginMode,
String? errorMessage, String? errorMessage,
String? infoMessage, AppMessage? infoMessage,
}) { }) {
return AuthState( return AuthState(
status: status ?? this.status, status: status ?? this.status,

View File

@@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flux/core/theme/theme.dart'; import 'package:flux/core/theme/theme.dart';
import 'package:flux/core/utils/extensions.dart';
import 'package:flux/core/widgets/flux_logo.dart'; import 'package:flux/core/widgets/flux_logo.dart';
import 'package:flux/core/widgets/flux_text_field.dart'; import 'package:flux/core/widgets/flux_text_field.dart';
import 'package:flux/features/auth/bloc/auth_cubit.dart'; import 'package:flux/features/auth/bloc/auth_cubit.dart';
@@ -55,7 +56,7 @@ class _AuthScreenState extends State<AuthScreen> {
if (state.infoMessage != null) { if (state.infoMessage != null) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text(state.infoMessage!), content: Text(state.infoMessage!.translatedMessage(context)),
backgroundColor: Colors.blueAccent, // O context.accent backgroundColor: Colors.blueAccent, // O context.accent
), ),
); );
@@ -77,7 +78,9 @@ class _AuthScreenState extends State<AuthScreen> {
// --- TITOLO DINAMICO --- // --- TITOLO DINAMICO ---
Text( Text(
state.isLoginMode ? 'BENTORNATO' : 'CREA ACCOUNT', state.isLoginMode
? context.l10n.authScreenWelcomeBack
: context.l10n.authScreenCreateAccount,
style: TextStyle( style: TextStyle(
color: context.primaryText, color: context.primaryText,
fontSize: 24, fontSize: 24,
@@ -88,8 +91,10 @@ class _AuthScreenState extends State<AuthScreen> {
const SizedBox(height: 8), const SizedBox(height: 8),
Text( Text(
state.isLoginMode state.isLoginMode
? 'Accedi per gestire il tuo business' ? context.l10n.authScreenLoginToManageYourBusiness
: 'Inizia oggi a digitalizzare il tuo negozio', : context
.l10n
.authScreenStartTodayToDigitalizeYourStore,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle(color: context.secondaryText), style: TextStyle(color: context.secondaryText),
), ),
@@ -97,7 +102,7 @@ class _AuthScreenState extends State<AuthScreen> {
// --- CAMPI INPUT --- // --- CAMPI INPUT ---
FluxTextField( FluxTextField(
label: 'Email Aziendale', label: context.l10n.authScreenBusinessEmail,
icon: Icons.email_outlined, icon: Icons.email_outlined,
controller: _emailController, controller: _emailController,
keyboardType: TextInputType.emailAddress, keyboardType: TextInputType.emailAddress,
@@ -130,7 +135,9 @@ class _AuthScreenState extends State<AuthScreen> {
), ),
) )
: Text( : Text(
state.isLoginMode ? 'ACCEDI' : 'REGISTRATI', state.isLoginMode
? context.l10n.authScreenLogin
: context.l10n.authScreenSignUp,
style: const TextStyle( style: const TextStyle(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
@@ -147,12 +154,15 @@ class _AuthScreenState extends State<AuthScreen> {
child: RichText( child: RichText(
text: TextSpan( text: TextSpan(
text: state.isLoginMode text: state.isLoginMode
? "Non hai un account? " ? context.l10n.authScreenDontHaveAccount
: "Hai già un account? ", : context.l10n.authScreenAlreadyHaveAccount,
style: TextStyle(color: context.secondaryText), style: TextStyle(color: context.secondaryText),
children: [ children: [
TextSpan( TextSpan(
text: state.isLoginMode ? "Registrati" : "Accedi", text: state.isLoginMode
? context.l10n.authScreenSignUp
: context.l10n.authScreenLogin,
style: TextStyle( style: TextStyle(
color: context.accent, color: context.accent,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
@@ -169,7 +179,7 @@ class _AuthScreenState extends State<AuthScreen> {
.read<AuthCubit>() .read<AuthCubit>()
.requestPasswordReset(_emailController.text.trim()), .requestPasswordReset(_emailController.text.trim()),
child: Text( child: Text(
'Pw dimenticata/Invito scaduto?', context.l10n.authScreenForgotPassword,
style: TextStyle( style: TextStyle(
color: context.accent, color: context.accent,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,

View File

@@ -22,5 +22,5 @@ class CompanyState extends Equatable {
} }
@override @override
List<Object?> get props => [status, errorMessage]; List<Object?> get props => [status, errorMessage, company];
} }

View File

@@ -17,7 +17,7 @@ class CompanyRepository {
} on PostgrestException catch (e) { } on PostgrestException catch (e) {
throw e.message; throw e.message;
} catch (e) { } catch (e) {
throw 'Errore imprevisto durante la creazione dell\'azienda'; throw e.toString();
} }
} }

View File

@@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flux/core/utils/extensions.dart';
import 'package:flux/features/company/bloc/company_bloc.dart'; import 'package:flux/features/company/bloc/company_bloc.dart';
import 'package:flux/core/blocs/session/session_cubit.dart'; import 'package:flux/core/blocs/session/session_cubit.dart';
import 'package:flux/core/theme/theme.dart'; import 'package:flux/core/theme/theme.dart';
@@ -69,7 +70,7 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: const Text('Configurazione Azienda'), title: Text(context.l10n.createCompanyScreenCompanyConfiguration),
actions: [ actions: [
IconButton( IconButton(
icon: const Icon(Icons.logout_rounded), icon: const Icon(Icons.logout_rounded),
@@ -98,7 +99,7 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text( content: Text(
state.errorMessage ?? 'Errore durante il salvataggio', state.errorMessage ?? context.l10n.commonSavingError,
), ),
backgroundColor: Colors.redAccent, backgroundColor: Colors.redAccent,
), ),
@@ -118,10 +119,12 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
const SizedBox(height: 32), const SizedBox(height: 32),
// --- SEZIONE 1: IDENTITÀ FISCALE --- // --- SEZIONE 1: IDENTITÀ FISCALE ---
_SectionTitle(title: 'DATI FISCALI'), _SectionTitle(
title: context.l10n.createCompanyScreenFiscalData,
),
const SizedBox(height: 16), const SizedBox(height: 16),
FluxTextField( FluxTextField(
label: 'Ragione Sociale', label: context.l10n.createCompanyScreenCompanyName,
icon: Icons.business, icon: Icons.business,
controller: _ragioneSocialeController, controller: _ragioneSocialeController,
), ),
@@ -130,7 +133,7 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
children: [ children: [
Expanded( Expanded(
child: FluxTextField( child: FluxTextField(
label: 'Partita IVA', label: context.l10n.createCompanyScreenVatId,
icon: Icons.numbers, icon: Icons.numbers,
controller: _pIvaController, controller: _pIvaController,
), ),
@@ -138,7 +141,7 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
const SizedBox(width: 12), const SizedBox(width: 12),
Expanded( Expanded(
child: FluxTextField( child: FluxTextField(
label: 'Codice Fiscale', label: context.l10n.createCompanyScreenFiscalCode,
icon: Icons.badge_outlined, icon: Icons.badge_outlined,
controller: _cfController, controller: _cfController,
), ),
@@ -147,7 +150,7 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
FluxTextField( FluxTextField(
label: 'Codice Univoco (SDI) / PEC', label: context.l10n.createCompanyScreenSdiPec,
icon: Icons.send_and_archive_outlined, icon: Icons.send_and_archive_outlined,
controller: _univocoController, controller: _univocoController,
), ),
@@ -155,10 +158,13 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
const SizedBox(height: 32), const SizedBox(height: 32),
// --- SEZIONE 2: SEDE LEGALE --- // --- SEZIONE 2: SEDE LEGALE ---
_SectionTitle(title: 'SEDE LEGALE'), _SectionTitle(
title:
context.l10n.createCompanyScreenCompanyLegalAddress,
),
const SizedBox(height: 16), const SizedBox(height: 16),
FluxTextField( FluxTextField(
label: 'Indirizzo e n. civico', label: context.l10n.commonAddress,
icon: Icons.home_work_outlined, icon: Icons.home_work_outlined,
controller: _indirizzoController, controller: _indirizzoController,
), ),
@@ -168,7 +174,7 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
Expanded( Expanded(
flex: 2, flex: 2,
child: FluxTextField( child: FluxTextField(
label: 'Città', label: context.l10n.commonCity,
icon: Icons.location_city, icon: Icons.location_city,
controller: _cittaController, controller: _cittaController,
), ),
@@ -176,7 +182,7 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
const SizedBox(width: 12), const SizedBox(width: 12),
Expanded( Expanded(
child: FluxTextField( child: FluxTextField(
label: 'CAP', label: context.l10n.commonZipCode,
icon: Icons.map_outlined, icon: Icons.map_outlined,
controller: _capController, controller: _capController,
), ),
@@ -184,7 +190,7 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
const SizedBox(width: 12), const SizedBox(width: 12),
Expanded( Expanded(
child: FluxTextField( child: FluxTextField(
label: 'Prov', label: context.l10n.commonProvince,
icon: Icons.explore_outlined, icon: Icons.explore_outlined,
controller: _provinciaController, controller: _provinciaController,
), ),
@@ -232,7 +238,7 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
Icon(Icons.cloud_upload_outlined, color: context.accent, size: 32), Icon(Icons.cloud_upload_outlined, color: context.accent, size: 32),
const SizedBox(height: 12), const SizedBox(height: 12),
Text( Text(
'Carica Logo Aziendale', context.l10n.createCompanyScreenUploadLogo,
style: TextStyle( style: TextStyle(
color: context.primaryText, color: context.primaryText,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
@@ -240,7 +246,7 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
), ),
const SizedBox(height: 4), const SizedBox(height: 4),
Text( Text(
'Verrà usato per le tue stampe e ricevute', context.l10n.createCompanyScreenWillBeUsedForReceipts,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle(color: context.secondaryText, fontSize: 12), style: TextStyle(color: context.secondaryText, fontSize: 12),
), ),
@@ -259,7 +265,7 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
: () => _onSave(), : () => _onSave(),
child: state.status == CompanyStatus.loading child: state.status == CompanyStatus.loading
? const CircularProgressIndicator() ? const CircularProgressIndicator()
: const Text('SALVA AZIENDA'), : Text(context.l10n.createCompanyScreenSaveCompany),
), ),
); );
} }
@@ -282,7 +288,7 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
), ),
const SizedBox(height: 24), const SizedBox(height: 24),
Text( Text(
'Configura la tua Azienda', context.l10n.createCompanyScreenSetupYourCompany,
style: Theme.of(context).textTheme.headlineMedium?.copyWith( style: Theme.of(context).textTheme.headlineMedium?.copyWith(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: context.primaryText, color: context.primaryText,
@@ -290,7 +296,7 @@ class _CreateCompanyScreenState extends State<CreateCompanyScreen> {
), ),
const SizedBox(height: 12), const SizedBox(height: 12),
Text( Text(
'FLUX ha bisogno dei tuoi dati fiscali per gestire correttamente le fatturazioni e le attivazioni dei tuoi negozi.', context.l10n.createCompanyScreenFluxNeedsYourFiscalData,
style: TextStyle( style: TextStyle(
color: context.secondaryText, color: context.secondaryText,
fontSize: 15, fontSize: 15,

View File

@@ -21,7 +21,7 @@ class CustomerRepository {
.single(); .single();
return CustomerModel.fromMap(response); return CustomerModel.fromMap(response);
} catch (e) { } catch (e) {
throw 'Errore durante il salvataggio del cliente: $e'; throw '$e';
} }
} }
@@ -35,7 +35,7 @@ class CustomerRepository {
.single(); .single();
return CustomerModel.fromMap(response); return CustomerModel.fromMap(response);
} catch (e) { } catch (e) {
throw 'Errore durante la modifica del cliente: $e'; throw '$e';
} }
} }
@@ -54,7 +54,7 @@ class CustomerRepository {
return (response as List).map((c) => CustomerModel.fromMap(c)).toList(); return (response as List).map((c) => CustomerModel.fromMap(c)).toList();
} catch (e) { } catch (e) {
throw 'Errore nel recupero clienti'; throw '$e';
} }
} }
@@ -102,7 +102,7 @@ class CustomerRepository {
.map((f) => CustomerFileModel.fromMap(f)) .map((f) => CustomerFileModel.fromMap(f))
.toList(); .toList();
} catch (e) { } catch (e) {
throw 'Errore recupero file: $e'; throw '$e';
} }
} }
@@ -131,7 +131,7 @@ class CustomerRepository {
try { try {
// Usiamo bytes invece del path per massima compatibilità // Usiamo bytes invece del path per massima compatibilità
if (pickedFile.bytes == null && pickedFile.path == null) { if (pickedFile.bytes == null && pickedFile.path == null) {
throw 'Impossibile leggere il contenuto del file'; throw 'File read error';
} }
// Se siamo su desktop/mobile abbiamo il path, su web abbiamo i bytes // Se siamo su desktop/mobile abbiamo il path, su web abbiamo i bytes
@@ -153,7 +153,7 @@ class CustomerRepository {
return CustomerFileModel.fromMap(response); return CustomerFileModel.fromMap(response);
} catch (e) { } catch (e) {
throw 'Errore durante l\'upload: $e'; throw '$e';
} }
} }
@@ -186,14 +186,10 @@ class CustomerRepository {
// 3. Cancellazione MASSIVA dallo Storage // 3. Cancellazione MASSIVA dallo Storage
await _supabase.storage.from('documents').remove(storagePaths); await _supabase.storage.from('documents').remove(storagePaths);
debugPrint("Eliminati con successo ${files.length} file.");
} on PostgrestException catch (e) { } on PostgrestException catch (e) {
debugPrint("Errore DB: ${e.message}"); throw e.message;
throw 'Errore database: ${e.message}';
} catch (e) { } catch (e) {
debugPrint("Errore generico: $e"); throw '$e';
throw 'Errore durante l\'eliminazione dei file: $e';
} }
} }
} }

View File

@@ -58,31 +58,31 @@ class HomeScreen extends StatelessWidget {
), ),
delegate: SliverChildListDelegate([ delegate: SliverChildListDelegate([
_buildDashboardWidget( _buildDashboardWidget(
title: context.l10n.expiring_contracts, title: context.l10n.homeExpiringContracts,
icon: Icons.assignment_late_outlined, icon: Icons.assignment_late_outlined,
color: Colors.orange, color: Colors.orange,
context: context, context: context,
), ),
_buildDashboardWidget( _buildDashboardWidget(
title: context.l10n.sticky_notes, title: context.l10n.commonStickyNotes,
icon: Icons.sticky_note_2_outlined, icon: Icons.sticky_note_2_outlined,
color: Colors.yellow.shade700, color: Colors.yellow.shade700,
context: context, context: context,
), ),
_buildDashboardWidget( _buildDashboardWidget(
title: context.l10n.my_tasks, title: context.l10n.homeMyTasks,
icon: Icons.check_box_outlined, icon: Icons.check_box_outlined,
color: Colors.green, color: Colors.green,
context: context, context: context,
), ),
_buildDashboardWidget( _buildDashboardWidget(
title: context.l10n.latestServices, title: context.l10n.homeLatestServices,
icon: Icons.design_services_outlined, icon: Icons.design_services_outlined,
color: Colors.blue, color: Colors.blue,
context: context, context: context,
), ),
_buildDashboardWidget( _buildDashboardWidget(
title: 'Ultime Assistenze', title: context.l10n.homeLatestServiceTickets,
icon: Icons.support_agent_outlined, icon: Icons.support_agent_outlined,
color: Colors.purple, color: Colors.purple,
context: context, context: context,
@@ -118,7 +118,7 @@ class HomeScreen extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
"Bentornato, ${user!.name}! 👋", context.l10n.homeWelcomeBack(user?.name ?? "Utente"),
style: theme.textTheme.headlineMedium?.copyWith( style: theme.textTheme.headlineMedium?.copyWith(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
letterSpacing: -0.5, letterSpacing: -0.5,
@@ -152,7 +152,7 @@ class HomeScreen extends StatelessWidget {
Icon(Icons.storefront, size: 16, color: context.primary), Icon(Icons.storefront, size: 16, color: context.primary),
const SizedBox(width: 8), const SizedBox(width: 8),
Text( Text(
currentStore?.nome ?? "Nessun negozio", currentStore?.nome ?? context.l10n.homeNoStoreFound,
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: context.primary, color: context.primary,
@@ -184,7 +184,7 @@ class HomeScreen extends StatelessWidget {
children: [ children: [
QuickActionButton( QuickActionButton(
icon: Icons.add, icon: Icons.add,
label: "Servizio", label: context.l10n.commonService,
color: Colors.blue, color: Colors.blue,
onTap: () { onTap: () {
// Entriamo nel form! Nessun parametro extra = Nuovo Servizio // Entriamo nel form! Nessun parametro extra = Nuovo Servizio
@@ -194,7 +194,7 @@ class HomeScreen extends StatelessWidget {
const SizedBox(width: 12), const SizedBox(width: 12),
QuickActionButton( QuickActionButton(
icon: Icons.handyman, icon: Icons.handyman,
label: "Assistenza", label: context.l10n.homeNewServiceTicket,
color: Colors.redAccent, color: Colors.redAccent,
onTap: () { onTap: () {
// TODO: Quando avrai la rotta per la nuova assistenza // TODO: Quando avrai la rotta per la nuova assistenza
@@ -204,7 +204,7 @@ class HomeScreen extends StatelessWidget {
const SizedBox(width: 12), const SizedBox(width: 12),
QuickActionButton( QuickActionButton(
icon: Icons.note_add, icon: Icons.note_add,
label: "Nota", label: context.l10n.commonNote,
color: Colors.amber, color: Colors.amber,
onTap: () { onTap: () {
// TODO: Quando faremo il modale/pagina delle note // TODO: Quando faremo il modale/pagina delle note
@@ -213,7 +213,7 @@ class HomeScreen extends StatelessWidget {
const SizedBox(width: 12), const SizedBox(width: 12),
QuickActionButton( QuickActionButton(
icon: Icons.task_alt, icon: Icons.task_alt,
label: "Task", label: context.l10n.commonTask,
color: Colors.teal, color: Colors.teal,
onTap: () { onTap: () {
// TODO: Quando faremo i task // TODO: Quando faremo i task
@@ -281,7 +281,7 @@ class HomeScreen extends StatelessWidget {
const Spacer(), const Spacer(),
Center( Center(
child: Text( child: Text(
"(Coming Soon)", context.l10n.commonComingSoon,
style: TextStyle( style: TextStyle(
color: context.secondaryText.withValues(alpha: 0.7), color: context.secondaryText.withValues(alpha: 0.7),
fontStyle: FontStyle.italic, fontStyle: FontStyle.italic,

View File

@@ -1,13 +0,0 @@
{
"@@locale": "en",
"welcomeBack": "Welcome back, {name}! 👋",
"latestServices": "Latest Services",
"masterData": "Master Data",
"settings": "Settings",
"newService": "Service",
"expiring_contracts": "Expiring Contracts",
"sticky_notes": "Sticky Notes",
"my_tasks": "My Tasks",
"latest_service_tickets": "Latest service tickets"
}

View File

@@ -1,20 +1,90 @@
{ {
"@@locale": "it", "@@locale": "it",
"welcomeBack": "Bentornato, {name}! 👋", "@authCubitResetPasswordEmailSentTo": {
"@welcomeBack": { "placeholders": {
"email": {
"type": "String"
}
}
},
"@authError": {
"placeholders": {
"message": {
"type": "String"
}
}
},
"@commonComingSoon": {},
"@commonError": {
"placeholders": {
"error": {
"type": "String"
}
}
},
"@homeWelcomeBack": {
"placeholders": { "placeholders": {
"name": { "name": {
"type": "String" "type": "String"
} }
} }
}, },
"latestServices": "Ultimi Servizi", "authCubitCheckEmailToConfirmAccount": "Controlla la tua email per confermare l'account!",
"masterData": "Anagrafiche", "authCubitResetPasswordEmailSentTo": "Email per reset password inviata a {email}!",
"settings": "Impostazioni", "authError": "Errore di autenticazione: {message}",
"newService": "Servizio", "authScreenAlreadyHaveAccount": "Hai già un account?",
"expiring_contracts": "Contratti in scadenza", "authScreenBusinessEmail": "Email aziendale",
"sticky_notes": "Sticky Notes", "authScreenCreateAccount": "CREA ACCOUNT",
"my_tasks": "Mie Attività", "authScreenDontHaveAccount": "Non hai un account?",
"latest_service_tickets": "Ultime assistenze" "authScreenForgotPassword": "Password dimenticata/Invito scaduto?",
"authScreenLogin": "LOGIN",
"authScreenLoginToManageYourBusiness": "Accedi per gestire il tuo business",
"authScreenSignUp": "REGISTRATI",
"authScreenStartTodayToDigitalizeYourStore": "Inizia oggi a digitalizzare il tuo negozio",
"authScreenWelcomeBack": "BENTORNATO",
"commonClose": "Chiudi",
"commonComingSoon": "Coming soon",
"commonDashboard": "Panoramica",
"commonError": "Si è verificato un errore: {error}",
"commonMasterData": "Anagrafiche",
"commonNewPassword": "Nuova Password",
"commonNote": "Nota",
"commonSave": "Salva",
"commonService": "Servizio",
"commonSettings": "Impostazioni",
"commonStickyNotes": "Sticky Notes",
"commonTask": "Attività",
"homeExpiringContracts": "Contratti in scadenza",
"homeLatestServiceTickets": "Ultime assistenze",
"homeLatestServices": "Ultimi Servizi",
"homeMyTasks": "Mie Attività",
"homeNewServiceTicket": "Nuova assistenza",
"homeNoStoreFound": "Nessun negozio trovato",
"homeWelcomeBack": "Bentornato, {name}! 👋",
"imageViewerWidgetErrorOpening": "Errore durante l'apertura dell'immagine",
"pdfViewerAnteprimaPdf": "Anteprima PDF",
"setPasswordInviteAcceptedChoosePassword": "Hai accettato l'invito. Scegli una password sicura per accedere in futuro.",
"setPasswordScreenAtLeast6Chars": "La password deve avere almeno 6 caratteri",
"setPasswordScreenPasswordSetWelcome": "Password impostata! Benvenuto a bordo 🚀",
"setPasswordScreenSaveAndStart": "SALVA E INIZIA",
"setPasswordScreenSetPassword": "Imposta una nuova Password",
"setPasswordScreenWelcomeInFlux": "Benvenuto in FLUX!",
"createCompanyScreenCompanyConfiguration": "Configurazione Azienda",
"commonSavingError": "Errore durante il salvataggio",
"createCompanyScreenFiscalData": "DATI FISCALI",
"createCompanyScreenCompanyName": "Ragione Sociale",
"createCompanyScreenVatId": "Partita IVA",
"createCompanyScreenFiscalCode": "Codice Fiscale",
"createCompanyScreenSdiPec": "Codice Univoco (SDI) / PEC",
"createCompanyScreenCompanyLegalAddress": "SEDE LEGALE",
"commonAddress": "Indirizzo e n. civico",
"commonCity": "Città",
"commonZipCode": "CAP",
"commonProvince": "Prov",
"commonCountry": "Paese",
"createCompanyScreenUploadLogo": "Carica Logo Aziendale",
"createCompanyScreenWillBeUsedForReceipts": "Verrà utilizzato per le tue stampe e ricevute",
"createCompanyScreenSaveCompany": "SALVA AZIENDA",
"createCompanyScreenSetupYourCompany": "Configura la tua Azienda",
"createCompanyScreenFluxNeedsYourFiscalData": "FLUX ha bisogno dei tuoi dati fiscali per gestire correttamente le fatturazioni e le attivazioni dei tuoi negozi."
} }

View File

@@ -5,7 +5,6 @@ import 'package:flutter/widgets.dart';
import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart' as intl; import 'package:intl/intl.dart' as intl;
import 'app_localizations_en.dart';
import 'app_localizations_it.dart'; import 'app_localizations_it.dart';
// ignore_for_file: type=lint // ignore_for_file: type=lint
@@ -93,64 +92,355 @@ abstract class AppLocalizations {
]; ];
/// A list of this localizations delegate's supported locales. /// A list of this localizations delegate's supported locales.
static const List<Locale> supportedLocales = <Locale>[ static const List<Locale> supportedLocales = <Locale>[Locale('it')];
Locale('en'),
Locale('it'),
];
/// No description provided for @welcomeBack. /// No description provided for @authCubitCheckEmailToConfirmAccount.
/// ///
/// In it, this message translates to: /// In it, this message translates to:
/// **'Bentornato, {name}! 👋'** /// **'Controlla la tua email per confermare l\'account!'**
String welcomeBack(String name); String get authCubitCheckEmailToConfirmAccount;
/// No description provided for @latestServices. /// No description provided for @authCubitResetPasswordEmailSentTo.
/// ///
/// In it, this message translates to: /// In it, this message translates to:
/// **'Ultimi Servizi'** /// **'Email per reset password inviata a {email}!'**
String get latestServices; String authCubitResetPasswordEmailSentTo(String email);
/// No description provided for @masterData. /// No description provided for @authError.
///
/// In it, this message translates to:
/// **'Errore di autenticazione: {message}'**
String authError(String message);
/// No description provided for @authScreenAlreadyHaveAccount.
///
/// In it, this message translates to:
/// **'Hai già un account?'**
String get authScreenAlreadyHaveAccount;
/// No description provided for @authScreenBusinessEmail.
///
/// In it, this message translates to:
/// **'Email aziendale'**
String get authScreenBusinessEmail;
/// No description provided for @authScreenCreateAccount.
///
/// In it, this message translates to:
/// **'CREA ACCOUNT'**
String get authScreenCreateAccount;
/// No description provided for @authScreenDontHaveAccount.
///
/// In it, this message translates to:
/// **'Non hai un account?'**
String get authScreenDontHaveAccount;
/// No description provided for @authScreenForgotPassword.
///
/// In it, this message translates to:
/// **'Password dimenticata/Invito scaduto?'**
String get authScreenForgotPassword;
/// No description provided for @authScreenLogin.
///
/// In it, this message translates to:
/// **'LOGIN'**
String get authScreenLogin;
/// No description provided for @authScreenLoginToManageYourBusiness.
///
/// In it, this message translates to:
/// **'Accedi per gestire il tuo business'**
String get authScreenLoginToManageYourBusiness;
/// No description provided for @authScreenSignUp.
///
/// In it, this message translates to:
/// **'REGISTRATI'**
String get authScreenSignUp;
/// No description provided for @authScreenStartTodayToDigitalizeYourStore.
///
/// In it, this message translates to:
/// **'Inizia oggi a digitalizzare il tuo negozio'**
String get authScreenStartTodayToDigitalizeYourStore;
/// No description provided for @authScreenWelcomeBack.
///
/// In it, this message translates to:
/// **'BENTORNATO'**
String get authScreenWelcomeBack;
/// No description provided for @commonClose.
///
/// In it, this message translates to:
/// **'Chiudi'**
String get commonClose;
/// No description provided for @commonComingSoon.
///
/// In it, this message translates to:
/// **'Coming soon'**
String get commonComingSoon;
/// No description provided for @commonDashboard.
///
/// In it, this message translates to:
/// **'Panoramica'**
String get commonDashboard;
/// No description provided for @commonError.
///
/// In it, this message translates to:
/// **'Si è verificato un errore: {error}'**
String commonError(String error);
/// No description provided for @commonMasterData.
/// ///
/// In it, this message translates to: /// In it, this message translates to:
/// **'Anagrafiche'** /// **'Anagrafiche'**
String get masterData; String get commonMasterData;
/// No description provided for @settings. /// No description provided for @commonNewPassword.
/// ///
/// In it, this message translates to: /// In it, this message translates to:
/// **'Impostazioni'** /// **'Nuova Password'**
String get settings; String get commonNewPassword;
/// No description provided for @newService. /// No description provided for @commonNote.
///
/// In it, this message translates to:
/// **'Nota'**
String get commonNote;
/// No description provided for @commonSave.
///
/// In it, this message translates to:
/// **'Salva'**
String get commonSave;
/// No description provided for @commonService.
/// ///
/// In it, this message translates to: /// In it, this message translates to:
/// **'Servizio'** /// **'Servizio'**
String get newService; String get commonService;
/// No description provided for @expiring_contracts. /// No description provided for @commonSettings.
/// ///
/// In it, this message translates to: /// In it, this message translates to:
/// **'Contratti in scadenza'** /// **'Impostazioni'**
String get expiring_contracts; String get commonSettings;
/// No description provided for @sticky_notes. /// No description provided for @commonStickyNotes.
/// ///
/// In it, this message translates to: /// In it, this message translates to:
/// **'Sticky Notes'** /// **'Sticky Notes'**
String get sticky_notes; String get commonStickyNotes;
/// No description provided for @my_tasks. /// No description provided for @commonTask.
/// ///
/// In it, this message translates to: /// In it, this message translates to:
/// **'Mie Attività'** /// **'Attività'**
String get my_tasks; String get commonTask;
/// No description provided for @latest_service_tickets. /// No description provided for @homeExpiringContracts.
///
/// In it, this message translates to:
/// **'Contratti in scadenza'**
String get homeExpiringContracts;
/// No description provided for @homeLatestServiceTickets.
/// ///
/// In it, this message translates to: /// In it, this message translates to:
/// **'Ultime assistenze'** /// **'Ultime assistenze'**
String get latest_service_tickets; String get homeLatestServiceTickets;
/// No description provided for @homeLatestServices.
///
/// In it, this message translates to:
/// **'Ultimi Servizi'**
String get homeLatestServices;
/// No description provided for @homeMyTasks.
///
/// In it, this message translates to:
/// **'Mie Attività'**
String get homeMyTasks;
/// No description provided for @homeNewServiceTicket.
///
/// In it, this message translates to:
/// **'Nuova assistenza'**
String get homeNewServiceTicket;
/// No description provided for @homeNoStoreFound.
///
/// In it, this message translates to:
/// **'Nessun negozio trovato'**
String get homeNoStoreFound;
/// No description provided for @homeWelcomeBack.
///
/// In it, this message translates to:
/// **'Bentornato, {name}! 👋'**
String homeWelcomeBack(String name);
/// No description provided for @imageViewerWidgetErrorOpening.
///
/// In it, this message translates to:
/// **'Errore durante l\'apertura dell\'immagine'**
String get imageViewerWidgetErrorOpening;
/// No description provided for @pdfViewerAnteprimaPdf.
///
/// In it, this message translates to:
/// **'Anteprima PDF'**
String get pdfViewerAnteprimaPdf;
/// No description provided for @setPasswordInviteAcceptedChoosePassword.
///
/// In it, this message translates to:
/// **'Hai accettato l\'invito. Scegli una password sicura per accedere in futuro.'**
String get setPasswordInviteAcceptedChoosePassword;
/// No description provided for @setPasswordScreenAtLeast6Chars.
///
/// In it, this message translates to:
/// **'La password deve avere almeno 6 caratteri'**
String get setPasswordScreenAtLeast6Chars;
/// No description provided for @setPasswordScreenPasswordSetWelcome.
///
/// In it, this message translates to:
/// **'Password impostata! Benvenuto a bordo 🚀'**
String get setPasswordScreenPasswordSetWelcome;
/// No description provided for @setPasswordScreenSaveAndStart.
///
/// In it, this message translates to:
/// **'SALVA E INIZIA'**
String get setPasswordScreenSaveAndStart;
/// No description provided for @setPasswordScreenSetPassword.
///
/// In it, this message translates to:
/// **'Imposta una nuova Password'**
String get setPasswordScreenSetPassword;
/// No description provided for @setPasswordScreenWelcomeInFlux.
///
/// In it, this message translates to:
/// **'Benvenuto in FLUX!'**
String get setPasswordScreenWelcomeInFlux;
/// No description provided for @createCompanyScreenCompanyConfiguration.
///
/// In it, this message translates to:
/// **'Configurazione Azienda'**
String get createCompanyScreenCompanyConfiguration;
/// No description provided for @commonSavingError.
///
/// In it, this message translates to:
/// **'Errore durante il salvataggio'**
String get commonSavingError;
/// No description provided for @createCompanyScreenFiscalData.
///
/// In it, this message translates to:
/// **'DATI FISCALI'**
String get createCompanyScreenFiscalData;
/// No description provided for @createCompanyScreenCompanyName.
///
/// In it, this message translates to:
/// **'Ragione Sociale'**
String get createCompanyScreenCompanyName;
/// No description provided for @createCompanyScreenVatId.
///
/// In it, this message translates to:
/// **'Partita IVA'**
String get createCompanyScreenVatId;
/// No description provided for @createCompanyScreenFiscalCode.
///
/// In it, this message translates to:
/// **'Codice Fiscale'**
String get createCompanyScreenFiscalCode;
/// No description provided for @createCompanyScreenSdiPec.
///
/// In it, this message translates to:
/// **'Codice Univoco (SDI) / PEC'**
String get createCompanyScreenSdiPec;
/// No description provided for @createCompanyScreenCompanyLegalAddress.
///
/// In it, this message translates to:
/// **'SEDE LEGALE'**
String get createCompanyScreenCompanyLegalAddress;
/// No description provided for @commonAddress.
///
/// In it, this message translates to:
/// **'Indirizzo e n. civico'**
String get commonAddress;
/// No description provided for @commonCity.
///
/// In it, this message translates to:
/// **'Città'**
String get commonCity;
/// No description provided for @commonZipCode.
///
/// In it, this message translates to:
/// **'CAP'**
String get commonZipCode;
/// No description provided for @commonProvince.
///
/// In it, this message translates to:
/// **'Prov'**
String get commonProvince;
/// No description provided for @commonCountry.
///
/// In it, this message translates to:
/// **'Paese'**
String get commonCountry;
/// No description provided for @createCompanyScreenUploadLogo.
///
/// In it, this message translates to:
/// **'Carica Logo Aziendale'**
String get createCompanyScreenUploadLogo;
/// No description provided for @createCompanyScreenWillBeUsedForReceipts.
///
/// In it, this message translates to:
/// **'Verrà utilizzato per le tue stampe e ricevute'**
String get createCompanyScreenWillBeUsedForReceipts;
/// No description provided for @createCompanyScreenSaveCompany.
///
/// In it, this message translates to:
/// **'SALVA AZIENDA'**
String get createCompanyScreenSaveCompany;
/// No description provided for @createCompanyScreenSetupYourCompany.
///
/// In it, this message translates to:
/// **'Configura la tua Azienda'**
String get createCompanyScreenSetupYourCompany;
/// No description provided for @createCompanyScreenFluxNeedsYourFiscalData.
///
/// In it, this message translates to:
/// **'FLUX ha bisogno dei tuoi dati fiscali per gestire correttamente le fatturazioni e le attivazioni dei tuoi negozi.'**
String get createCompanyScreenFluxNeedsYourFiscalData;
} }
class _AppLocalizationsDelegate class _AppLocalizationsDelegate
@@ -164,7 +454,7 @@ class _AppLocalizationsDelegate
@override @override
bool isSupported(Locale locale) => bool isSupported(Locale locale) =>
<String>['en', 'it'].contains(locale.languageCode); <String>['it'].contains(locale.languageCode);
@override @override
bool shouldReload(_AppLocalizationsDelegate old) => false; bool shouldReload(_AppLocalizationsDelegate old) => false;
@@ -173,8 +463,6 @@ class _AppLocalizationsDelegate
AppLocalizations lookupAppLocalizations(Locale locale) { AppLocalizations lookupAppLocalizations(Locale locale) {
// Lookup logic when only language code is specified. // Lookup logic when only language code is specified.
switch (locale.languageCode) { switch (locale.languageCode) {
case 'en':
return AppLocalizationsEn();
case 'it': case 'it':
return AppLocalizationsIt(); return AppLocalizationsIt();
} }

View File

@@ -1,39 +0,0 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for English (`en`).
class AppLocalizationsEn extends AppLocalizations {
AppLocalizationsEn([String locale = 'en']) : super(locale);
@override
String welcomeBack(String name) {
return 'Welcome back, $name! 👋';
}
@override
String get latestServices => 'Latest Services';
@override
String get masterData => 'Master Data';
@override
String get settings => 'Settings';
@override
String get newService => 'Service';
@override
String get expiring_contracts => 'Expiring Contracts';
@override
String get sticky_notes => 'Sticky Notes';
@override
String get my_tasks => 'My Tasks';
@override
String get latest_service_tickets => 'Latest service tickets';
}

View File

@@ -9,31 +9,194 @@ class AppLocalizationsIt extends AppLocalizations {
AppLocalizationsIt([String locale = 'it']) : super(locale); AppLocalizationsIt([String locale = 'it']) : super(locale);
@override @override
String welcomeBack(String name) { String get authCubitCheckEmailToConfirmAccount =>
'Controlla la tua email per confermare l\'account!';
@override
String authCubitResetPasswordEmailSentTo(String email) {
return 'Email per reset password inviata a $email!';
}
@override
String authError(String message) {
return 'Errore di autenticazione: $message';
}
@override
String get authScreenAlreadyHaveAccount => 'Hai già un account?';
@override
String get authScreenBusinessEmail => 'Email aziendale';
@override
String get authScreenCreateAccount => 'CREA ACCOUNT';
@override
String get authScreenDontHaveAccount => 'Non hai un account?';
@override
String get authScreenForgotPassword => 'Password dimenticata/Invito scaduto?';
@override
String get authScreenLogin => 'LOGIN';
@override
String get authScreenLoginToManageYourBusiness =>
'Accedi per gestire il tuo business';
@override
String get authScreenSignUp => 'REGISTRATI';
@override
String get authScreenStartTodayToDigitalizeYourStore =>
'Inizia oggi a digitalizzare il tuo negozio';
@override
String get authScreenWelcomeBack => 'BENTORNATO';
@override
String get commonClose => 'Chiudi';
@override
String get commonComingSoon => 'Coming soon';
@override
String get commonDashboard => 'Panoramica';
@override
String commonError(String error) {
return 'Si è verificato un errore: $error';
}
@override
String get commonMasterData => 'Anagrafiche';
@override
String get commonNewPassword => 'Nuova Password';
@override
String get commonNote => 'Nota';
@override
String get commonSave => 'Salva';
@override
String get commonService => 'Servizio';
@override
String get commonSettings => 'Impostazioni';
@override
String get commonStickyNotes => 'Sticky Notes';
@override
String get commonTask => 'Attività';
@override
String get homeExpiringContracts => 'Contratti in scadenza';
@override
String get homeLatestServiceTickets => 'Ultime assistenze';
@override
String get homeLatestServices => 'Ultimi Servizi';
@override
String get homeMyTasks => 'Mie Attività';
@override
String get homeNewServiceTicket => 'Nuova assistenza';
@override
String get homeNoStoreFound => 'Nessun negozio trovato';
@override
String homeWelcomeBack(String name) {
return 'Bentornato, $name! 👋'; return 'Bentornato, $name! 👋';
} }
@override @override
String get latestServices => 'Ultimi Servizi'; String get imageViewerWidgetErrorOpening =>
'Errore durante l\'apertura dell\'immagine';
@override @override
String get masterData => 'Anagrafiche'; String get pdfViewerAnteprimaPdf => 'Anteprima PDF';
@override @override
String get settings => 'Impostazioni'; String get setPasswordInviteAcceptedChoosePassword =>
'Hai accettato l\'invito. Scegli una password sicura per accedere in futuro.';
@override @override
String get newService => 'Servizio'; String get setPasswordScreenAtLeast6Chars =>
'La password deve avere almeno 6 caratteri';
@override @override
String get expiring_contracts => 'Contratti in scadenza'; String get setPasswordScreenPasswordSetWelcome =>
'Password impostata! Benvenuto a bordo 🚀';
@override @override
String get sticky_notes => 'Sticky Notes'; String get setPasswordScreenSaveAndStart => 'SALVA E INIZIA';
@override @override
String get my_tasks => 'Mie Attività'; String get setPasswordScreenSetPassword => 'Imposta una nuova Password';
@override @override
String get latest_service_tickets => 'Ultime assistenze'; String get setPasswordScreenWelcomeInFlux => 'Benvenuto in FLUX!';
@override
String get createCompanyScreenCompanyConfiguration =>
'Configurazione Azienda';
@override
String get commonSavingError => 'Errore durante il salvataggio';
@override
String get createCompanyScreenFiscalData => 'DATI FISCALI';
@override
String get createCompanyScreenCompanyName => 'Ragione Sociale';
@override
String get createCompanyScreenVatId => 'Partita IVA';
@override
String get createCompanyScreenFiscalCode => 'Codice Fiscale';
@override
String get createCompanyScreenSdiPec => 'Codice Univoco (SDI) / PEC';
@override
String get createCompanyScreenCompanyLegalAddress => 'SEDE LEGALE';
@override
String get commonAddress => 'Indirizzo e n. civico';
@override
String get commonCity => 'Città';
@override
String get commonZipCode => 'CAP';
@override
String get commonProvince => 'Prov';
@override
String get commonCountry => 'Paese';
@override
String get createCompanyScreenUploadLogo => 'Carica Logo Aziendale';
@override
String get createCompanyScreenWillBeUsedForReceipts =>
'Verrà utilizzato per le tue stampe e ricevute';
@override
String get createCompanyScreenSaveCompany => 'SALVA AZIENDA';
@override
String get createCompanyScreenSetupYourCompany => 'Configura la tua Azienda';
@override
String get createCompanyScreenFluxNeedsYourFiscalData =>
'FLUX ha bisogno dei tuoi dati fiscali per gestire correttamente le fatturazioni e le attivazioni dei tuoi negozi.';
} }

View File

@@ -155,9 +155,7 @@ class _FluxAppState extends State<FluxApp> {
routerConfig: _router, routerConfig: _router,
localizationsDelegates: AppLocalizations.localizationsDelegates, localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales, supportedLocales: AppLocalizations.supportedLocales,
locale: const Locale( locale: const Locale('it'),
'it',
), // Per ora forziamo l'italiano, poi lo renderemo dinamico!
); );
}, },
); );

View File

@@ -28,8 +28,6 @@ dependencies:
qr_flutter: ^4.1.0 qr_flutter: ^4.1.0
shared_preferences: ^2.5.5 shared_preferences: ^2.5.5
supabase_flutter: ^2.12.2 supabase_flutter: ^2.12.2
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
@@ -43,4 +41,4 @@ flutter:
assets: assets:
- assets/images/ - assets/images/
- assets/svg/ - assets/svg/
- .env - .env