adding multilingual support

This commit is contained in:
Azmat-7860
2026-10-03 15:04:48 +05:30
parent 3785ea1e45
commit 0d7785b242
51 changed files with 3007 additions and 250 deletions
@@ -1,6 +1,7 @@
import 'dart:typed_data';
import 'dart:io';
import 'package:flutter/material.dart';
import '../../../l10n/app_localizations.dart';
import 'package:file_picker/file_picker.dart';
import 'base_field.dart';
import '../utils/entity_field_store.dart';
@@ -63,7 +64,9 @@ class AudioUploadField extends BaseField {
}
},
icon: const Icon(Icons.audiotrack_rounded),
label: const Text('Add Audio'),
label: Builder(
builder: (ctx) =>
Text(AppLocalizations.of(ctx)!.addAudio)),
),
],
),
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import '../../../l10n/app_localizations.dart';
import 'base_field.dart';
import '../../../shared/widgets/inputs/modern_text_field.dart';
@@ -255,7 +256,7 @@ class _AutocompleteMultiSelectWidgetState
const SizedBox(width: 8),
Expanded(
child: Text(
'No results',
AppLocalizations.of(context)!.noResults,
style: TextStyle(
color:
widget.colorScheme.onSurfaceVariant),
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import '../../../l10n/app_localizations.dart';
import 'package:barcode_widget/barcode_widget.dart';
import 'base_field.dart';
@@ -73,19 +74,22 @@ class BarcodeField extends BaseField {
),
),
const SizedBox(width: 8),
IconButton(
tooltip: 'Scan Barcode',
icon: Icon(Icons.document_scanner_rounded,
color: colorScheme.primary),
onPressed: scanner == null
? null
: () async {
final val = await scanner!.call();
if (val != null) {
controller.text = val;
onChanged?.call();
}
},
Builder(
builder: (ctx) => IconButton(
tooltip:
AppLocalizations.of(ctx)!.scanBarcode,
icon: Icon(Icons.document_scanner_rounded,
color: colorScheme.primary),
onPressed: scanner == null
? null
: () async {
final val = await scanner!.call();
if (val != null) {
controller.text = val;
onChanged?.call();
}
},
),
),
],
),
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import '../../../l10n/app_localizations.dart';
import 'base_field.dart';
/// Read-only Data Grid field
@@ -96,7 +97,7 @@ class _DataGridFieldWidgetState extends State<_DataGridFieldWidget> {
}
final data = snapshot.data ?? const <Map<String, dynamic>>[];
if (data.isEmpty) {
return Text('No data available',
return Text(AppLocalizations.of(context)!.noDataAvailable,
style: TextStyle(color: colorScheme.onSurfaceVariant));
}
final columns = data.first.keys.toList();
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import '../../../l10n/app_localizations.dart';
import 'base_field.dart';
import '../../../shared/widgets/inputs/modern_text_field.dart';
@@ -152,7 +153,8 @@ class _DynamicDropdownWidgetState extends State<_DynamicDropdownWidget> {
children: [
TextField(
decoration: InputDecoration(
hintText: 'Search ${widget.label.toLowerCase()}',
hintText: AppLocalizations.of(context)!
.searchEntity(widget.label),
prefixIcon: const Icon(Icons.search),
border: const OutlineInputBorder(),
),
@@ -162,7 +164,8 @@ class _DynamicDropdownWidgetState extends State<_DynamicDropdownWidget> {
Flexible(
child: filtered.isEmpty
? Center(
child: Text('No results',
child: Text(
AppLocalizations.of(context)!.noResults,
style: TextStyle(color: cs.onSurfaceVariant)),
)
: ListView.separated(
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import '../../../l10n/app_localizations.dart';
import 'base_field.dart';
import '../../../shared/widgets/inputs/modern_text_field.dart';
@@ -146,7 +147,8 @@ class _DynamicMultiSelectWidgetState extends State<_DynamicMultiSelectWidget> {
children: [
TextField(
decoration: InputDecoration(
hintText: 'Search ${widget.label.toLowerCase()}',
hintText: AppLocalizations.of(context)!
.searchEntity(widget.label),
prefixIcon: const Icon(Icons.search),
border: const OutlineInputBorder(),
),
@@ -156,7 +158,8 @@ class _DynamicMultiSelectWidgetState extends State<_DynamicMultiSelectWidget> {
Flexible(
child: filtered.isEmpty
? Center(
child: Text('No results',
child: Text(
AppLocalizations.of(context)!.noResults,
style: TextStyle(color: cs.onSurfaceVariant)),
)
: ListView.separated(
@@ -188,7 +191,8 @@ class _DynamicMultiSelectWidgetState extends State<_DynamicMultiSelectWidget> {
widget.onChanged?.call();
Navigator.of(context).pop();
},
child: const Text('Clear'),
child: Text(
AppLocalizations.of(context)!.clearBtn),
),
const Spacer(),
ElevatedButton(
@@ -199,7 +203,8 @@ class _DynamicMultiSelectWidgetState extends State<_DynamicMultiSelectWidget> {
widget.onChanged?.call();
Navigator.of(context).pop();
},
child: const Text('Done'),
child: Text(
AppLocalizations.of(context)!.doneBtn),
),
],
),
@@ -1,6 +1,7 @@
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
import '../../../l10n/app_localizations.dart';
import 'base_field.dart';
import '../utils/entity_field_store.dart';
@@ -62,7 +63,9 @@ class FileUploadField extends BaseField {
}
},
icon: const Icon(Icons.attach_file_rounded),
label: const Text('Add Files'),
label: Builder(
builder: (ctx) =>
Text(AppLocalizations.of(ctx)!.addFiles)),
),
],
),
@@ -1,6 +1,7 @@
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import '../../../l10n/app_localizations.dart';
import 'base_field.dart';
import '../utils/entity_field_store.dart';
@@ -57,7 +58,9 @@ class ImageUploadField extends BaseField {
}
},
icon: const Icon(Icons.image_rounded),
label: const Text('Add Image'),
label: Builder(
builder: (ctx) =>
Text(AppLocalizations.of(ctx)!.addImage)),
),
],
),
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import '../../../l10n/app_localizations.dart';
import 'base_field.dart';
import '../ui/entity_form.dart';
import 'dart:convert';
@@ -553,7 +554,9 @@ class _OneToManyWidgetState extends State<_OneToManyWidget> {
child: ElevatedButton.icon(
onPressed: () => _addRow(),
icon: Icon(Icons.add, color: cs.onPrimary),
label: Text('Add ${widget.label}',
label: Text(
AppLocalizations.of(context)!
.addEntity(widget.label),
style: TextStyle(color: cs.onPrimary)),
style: ElevatedButton.styleFrom(
backgroundColor: cs.primary,
@@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../../../l10n/app_localizations.dart';
import '../../../core/constants/ui_constants.dart';
import '../../../core/providers/dynamic_theme_provider.dart';
import '../ui/entity_form.dart';
@@ -147,7 +147,8 @@ class RelatedEntityInsertField extends BaseField {
setLocal(() => isSubmitting = false);
}
},
submitButtonText: 'Create',
submitButtonText: AppLocalizations.of(context)!
.createEntity(relationTitle),
isLoading: isSubmitting,
),
),
@@ -156,7 +157,8 @@ class RelatedEntityInsertField extends BaseField {
onPressed: isSubmitting
? null
: () => Navigator.of(dialogContext).pop(),
child: const Text('Cancel'),
child: Text(
AppLocalizations.of(dialogContext)!.cancel),
),
],
);
@@ -402,7 +404,8 @@ class _RelatedEntityInsertWidgetState
ElevatedButton.icon(
onPressed: _creating ? null : _openInsertDialog,
icon: Icon(Icons.add_rounded, color: cs.onPrimary, size: 18),
label: Text('Insert',
label: Text(
AppLocalizations.of(context)!.insertBtn,
style: TextStyle(
color: cs.onPrimary, fontWeight: FontWeight.w600)),
style: ElevatedButton.styleFrom(
@@ -491,7 +494,8 @@ class _RelatedEntityInsertWidgetState
TextButton(
onPressed:
isSubmitting ? null : () => Navigator.of(context).pop(),
child: const Text('Cancel'),
child: Text(
AppLocalizations.of(context)!.cancel),
),
],
);
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import '../../../l10n/app_localizations.dart';
import 'base_field.dart';
import '../ui/entity_form.dart';
@@ -143,7 +144,8 @@ class _ValueListPickerWidgetState extends State<_ValueListPickerWidget> {
strokeWidth: 2, color: cs.primary),
),
const SizedBox(width: 12),
Text('Loading...',
Text(
AppLocalizations.of(context)!.loading,
style: TextStyle(color: cs.onSurfaceVariant)),
],
),
@@ -152,7 +154,7 @@ class _ValueListPickerWidgetState extends State<_ValueListPickerWidget> {
if (snapshot.hasError || _loadError != null) {
final String msg = snapshot.error?.toString() ??
_loadError ??
'Failed to load';
AppLocalizations.of(context)!.errorLoadingData;
return Padding(
padding: const EdgeInsets.all(16),
child: Container(
@@ -186,13 +188,15 @@ class _ValueListPickerWidgetState extends State<_ValueListPickerWidget> {
Icon(Icons.inbox_rounded,
color: cs.onSurfaceVariant, size: 36),
const SizedBox(height: 8),
Text('No data found',
Text(
AppLocalizations.of(context)!.noDataFound,
style: TextStyle(color: cs.onSurfaceVariant)),
const SizedBox(height: 12),
ElevatedButton.icon(
onPressed: () => Navigator.of(context).pop(),
icon: const Icon(Icons.close_rounded),
label: const Text('Close'),
label: Text(
AppLocalizations.of(context)!.close),
style: ElevatedButton.styleFrom(
backgroundColor: cs.primary,
foregroundColor: cs.onPrimary,
@@ -2,6 +2,7 @@ import 'dart:typed_data';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
import '../../../l10n/app_localizations.dart';
import 'base_field.dart';
import '../utils/entity_field_store.dart';
@@ -63,7 +64,9 @@ class VideoUploadField extends BaseField {
}
},
icon: const Icon(Icons.video_library_rounded),
label: const Text('Add Video'),
label: Builder(
builder: (ctx) =>
Text(AppLocalizations.of(ctx)!.addVideo)),
),
],
),