localization

This commit is contained in:
2026-04-29 19:25:48 +02:00
parent b1c1866b4b
commit 8d3ca62304
20 changed files with 361 additions and 20 deletions

View File

@@ -1,3 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flux/l10n/app_localizations.dart';
extension MyStringExtensions on String? {
// Gestiamo anche il nullable per sicurezza
String myFormat() {
@@ -40,3 +43,7 @@ extension MyStringExtensions on String? {
.join('.'); // Ritorna tutto tranne l'ultima parte
}
}
extension LocalizationExtension on BuildContext {
AppLocalizations get l10n => AppLocalizations.of(this)!;
}

View File

@@ -1,7 +1,7 @@
import 'package:file_picker/file_picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:flux/core/blocs/session/session_cubit.dart';
import 'package:flux/core/utils/string_extensions.dart';
import 'package:flux/core/utils/extensions.dart';
import 'package:flux/features/customers/models/customer_file_model.dart';
import 'package:get_it/get_it.dart';
import 'package:supabase_flutter/supabase_flutter.dart';

View File

@@ -1,5 +1,5 @@
import 'package:equatable/equatable.dart';
import 'package:flux/core/utils/string_extensions.dart';
import 'package:flux/core/utils/extensions.dart';
import 'package:flux/features/customers/models/customer_file_model.dart';
class CustomerModel extends Equatable {

View File

@@ -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/theme/theme.dart';
import 'package:flux/core/utils/extensions.dart';
import 'package:flux/features/home/ui/quick_actions_widget.dart';
import 'package:flux/features/master_data/staff/blocs/staff_cubit.dart';
import 'package:go_router/go_router.dart';
@@ -57,25 +58,25 @@ class HomeScreen extends StatelessWidget {
),
delegate: SliverChildListDelegate([
_buildDashboardWidget(
title: 'Contratti in Scadenza',
title: context.l10n.expiring_contracts,
icon: Icons.assignment_late_outlined,
color: Colors.orange,
context: context,
),
_buildDashboardWidget(
title: 'Sticky Notes',
title: context.l10n.sticky_notes,
icon: Icons.sticky_note_2_outlined,
color: Colors.yellow.shade700,
context: context,
),
_buildDashboardWidget(
title: 'I miei Task',
title: context.l10n.my_tasks,
icon: Icons.check_box_outlined,
color: Colors.green,
context: context,
),
_buildDashboardWidget(
title: 'Ultimi Servizi',
title: context.l10n.latestServices,
icon: Icons.design_services_outlined,
color: Colors.blue,
context: context,

View File

@@ -1,5 +1,5 @@
import 'package:equatable/equatable.dart';
import 'package:flux/core/utils/string_extensions.dart';
import 'package:flux/core/utils/extensions.dart';
class BrandModel extends Equatable {
final String? id;

View File

@@ -1,5 +1,5 @@
import 'package:equatable/equatable.dart';
import 'package:flux/core/utils/string_extensions.dart';
import 'package:flux/core/utils/extensions.dart';
class ModelModel extends Equatable {
final String? id;

View File

@@ -4,7 +4,7 @@ import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flux/core/utils/string_extensions.dart';
import 'package:flux/core/utils/extensions.dart';
import 'package:flux/features/services/data/services_repository.dart';
import 'package:flux/features/services/models/service_file_model.dart';
import 'package:flux/features/services/models/service_model.dart';

View File

@@ -3,7 +3,7 @@ import 'package:file_picker/file_picker.dart';
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/utils/string_extensions.dart';
import 'package:flux/core/utils/extensions.dart';
import 'package:flux/features/services/data/services_repository.dart';
import 'package:flux/features/services/models/energy_service_model.dart';
import 'package:flux/features/services/models/entertainment_service_model.dart';

View File

@@ -1,7 +1,7 @@
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flux/core/blocs/session/session_cubit.dart';
import 'package:flux/core/utils/string_extensions.dart';
import 'package:flux/core/utils/extensions.dart';
import 'package:flux/features/customers/data/customer_repository.dart';
import 'package:flux/features/customers/models/customer_file_model.dart';
import 'package:flux/features/services/models/service_file_model.dart';

View File

@@ -1,5 +1,5 @@
import 'package:equatable/equatable.dart';
import 'package:flux/core/utils/string_extensions.dart';
import 'package:flux/core/utils/extensions.dart';
import 'package:flux/features/services/models/energy_service_model.dart';
import 'package:flux/features/services/models/entertainment_service_model.dart';
import 'package:flux/features/services/models/fin_service_model.dart';

13
lib/l10n/app_en.arb Normal file
View File

@@ -0,0 +1,13 @@
{
"@@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"
}

20
lib/l10n/app_it.arb Normal file
View File

@@ -0,0 +1,20 @@
{
"@@locale": "it",
"welcomeBack": "Bentornato, {name}! 👋",
"@welcomeBack": {
"placeholders": {
"name": {
"type": "String"
}
}
},
"latestServices": "Ultimi Servizi",
"masterData": "Anagrafiche",
"settings": "Impostazioni",
"newService": "Servizio",
"expiring_contracts": "Contratti in scadenza",
"sticky_notes": "Sticky Notes",
"my_tasks": "Mie Attività",
"latest_service_tickets": "Ultime assistenze"
}

View File

@@ -0,0 +1,188 @@
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart' as intl;
import 'app_localizations_en.dart';
import 'app_localizations_it.dart';
// ignore_for_file: type=lint
/// Callers can lookup localized strings with an instance of AppLocalizations
/// returned by `AppLocalizations.of(context)`.
///
/// Applications need to include `AppLocalizations.delegate()` in their app's
/// `localizationDelegates` list, and the locales they support in the app's
/// `supportedLocales` list. For example:
///
/// ```dart
/// import 'l10n/app_localizations.dart';
///
/// return MaterialApp(
/// localizationsDelegates: AppLocalizations.localizationsDelegates,
/// supportedLocales: AppLocalizations.supportedLocales,
/// home: MyApplicationHome(),
/// );
/// ```
///
/// ## Update pubspec.yaml
///
/// Please make sure to update your pubspec.yaml to include the following
/// packages:
///
/// ```yaml
/// dependencies:
/// # Internationalization support.
/// flutter_localizations:
/// sdk: flutter
/// intl: any # Use the pinned version from flutter_localizations
///
/// # Rest of dependencies
/// ```
///
/// ## iOS Applications
///
/// iOS applications define key application metadata, including supported
/// locales, in an Info.plist file that is built into the application bundle.
/// To configure the locales supported by your app, youll need to edit this
/// file.
///
/// First, open your projects ios/Runner.xcworkspace Xcode workspace file.
/// Then, in the Project Navigator, open the Info.plist file under the Runner
/// projects Runner folder.
///
/// Next, select the Information Property List item, select Add Item from the
/// Editor menu, then select Localizations from the pop-up menu.
///
/// Select and expand the newly-created Localizations item then, for each
/// locale your application supports, add a new item and select the locale
/// you wish to add from the pop-up menu in the Value field. This list should
/// be consistent with the languages listed in the AppLocalizations.supportedLocales
/// property.
abstract class AppLocalizations {
AppLocalizations(String locale)
: localeName = intl.Intl.canonicalizedLocale(locale.toString());
final String localeName;
static AppLocalizations? of(BuildContext context) {
return Localizations.of<AppLocalizations>(context, AppLocalizations);
}
static const LocalizationsDelegate<AppLocalizations> delegate =
_AppLocalizationsDelegate();
/// A list of this localizations delegate along with the default localizations
/// delegates.
///
/// Returns a list of localizations delegates containing this delegate along with
/// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate,
/// and GlobalWidgetsLocalizations.delegate.
///
/// Additional delegates can be added by appending to this list in
/// MaterialApp. This list does not have to be used at all if a custom list
/// of delegates is preferred or required.
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates =
<LocalizationsDelegate<dynamic>>[
delegate,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
];
/// A list of this localizations delegate's supported locales.
static const List<Locale> supportedLocales = <Locale>[
Locale('en'),
Locale('it'),
];
/// No description provided for @welcomeBack.
///
/// In it, this message translates to:
/// **'Bentornato, {name}! 👋'**
String welcomeBack(String name);
/// No description provided for @latestServices.
///
/// In it, this message translates to:
/// **'Ultimi Servizi'**
String get latestServices;
/// No description provided for @masterData.
///
/// In it, this message translates to:
/// **'Anagrafiche'**
String get masterData;
/// No description provided for @settings.
///
/// In it, this message translates to:
/// **'Impostazioni'**
String get settings;
/// No description provided for @newService.
///
/// In it, this message translates to:
/// **'Servizio'**
String get newService;
/// No description provided for @expiring_contracts.
///
/// In it, this message translates to:
/// **'Contratti in scadenza'**
String get expiring_contracts;
/// No description provided for @sticky_notes.
///
/// In it, this message translates to:
/// **'Sticky Notes'**
String get sticky_notes;
/// No description provided for @my_tasks.
///
/// In it, this message translates to:
/// **'Mie Attività'**
String get my_tasks;
/// No description provided for @latest_service_tickets.
///
/// In it, this message translates to:
/// **'Ultime assistenze'**
String get latest_service_tickets;
}
class _AppLocalizationsDelegate
extends LocalizationsDelegate<AppLocalizations> {
const _AppLocalizationsDelegate();
@override
Future<AppLocalizations> load(Locale locale) {
return SynchronousFuture<AppLocalizations>(lookupAppLocalizations(locale));
}
@override
bool isSupported(Locale locale) =>
<String>['en', 'it'].contains(locale.languageCode);
@override
bool shouldReload(_AppLocalizationsDelegate old) => false;
}
AppLocalizations lookupAppLocalizations(Locale locale) {
// Lookup logic when only language code is specified.
switch (locale.languageCode) {
case 'en':
return AppLocalizationsEn();
case 'it':
return AppLocalizationsIt();
}
throw FlutterError(
'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
'an issue with the localizations generation tool. Please file an issue '
'on GitHub with a reproducible sample app and the gen-l10n configuration '
'that was used.',
);
}

View File

@@ -0,0 +1,39 @@
// 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

@@ -0,0 +1,39 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for Italian (`it`).
class AppLocalizationsIt extends AppLocalizations {
AppLocalizationsIt([String locale = 'it']) : super(locale);
@override
String welcomeBack(String name) {
return 'Bentornato, $name! 👋';
}
@override
String get latestServices => 'Ultimi Servizi';
@override
String get masterData => 'Anagrafiche';
@override
String get settings => 'Impostazioni';
@override
String get newService => 'Servizio';
@override
String get expiring_contracts => 'Contratti in scadenza';
@override
String get sticky_notes => 'Sticky Notes';
@override
String get my_tasks => 'Mie Attività';
@override
String get latest_service_tickets => 'Ultime assistenze';
}

View File

@@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flux/features/auth/bloc/auth_cubit.dart';
import 'package:flux/l10n/app_localizations.dart';
import 'package:get_it/get_it.dart';
import 'package:go_router/go_router.dart';
import 'package:shared_preferences/shared_preferences.dart';
@@ -152,6 +153,11 @@ class _FluxAppState extends State<FluxApp> {
darkTheme: fluxDarkTheme,
themeMode: themeState.currentTheme.themeMode,
routerConfig: _router,
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
locale: const Locale(
'it',
), // Per ora forziamo l'italiano, poi lo renderemo dinamico!
);
},
);