adding multilingual support
This commit is contained in:
@@ -7,6 +7,15 @@
|
|||||||
|
|
||||||
# The following line activates a set of recommended lints for Flutter apps,
|
# The following line activates a set of recommended lints for Flutter apps,
|
||||||
# packages, and plugins designed to encourage good coding practices.
|
# packages, and plugins designed to encourage good coding practices.
|
||||||
|
analyzer:
|
||||||
|
exclude:
|
||||||
|
- build/**
|
||||||
|
- android/**
|
||||||
|
- ios/**
|
||||||
|
- web/**
|
||||||
|
- windows/**
|
||||||
|
- macos/**
|
||||||
|
- linux/**
|
||||||
include: package:flutter_lints/flutter.yaml
|
include: package:flutter_lints/flutter.yaml
|
||||||
|
|
||||||
linter:
|
linter:
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"student": "Student",
|
||||||
|
"create_student": "Create Student",
|
||||||
|
"update_student": "Update Student",
|
||||||
|
"name": "Name",
|
||||||
|
"phone_number": "Phone Number",
|
||||||
|
"email": "Email"
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"student": "छात्र",
|
||||||
|
"create_student": "छात्र बनाएँ",
|
||||||
|
"update_student": "छात्र अपडेट करें",
|
||||||
|
"name": "नाम",
|
||||||
|
"phone_number": "फ़ोन नंबर",
|
||||||
|
"email": "ईमेल"
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
arb-dir: lib/l10n
|
||||||
|
template-arb-file: app_en.arb
|
||||||
|
output-localization-file: app_localizations.dart
|
||||||
|
output-dir: lib/l10n
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import '../../../l10n/app_localizations.dart';
|
||||||
import 'package:file_picker/file_picker.dart';
|
import 'package:file_picker/file_picker.dart';
|
||||||
import 'base_field.dart';
|
import 'base_field.dart';
|
||||||
import '../utils/entity_field_store.dart';
|
import '../utils/entity_field_store.dart';
|
||||||
@@ -63,7 +64,9 @@ class AudioUploadField extends BaseField {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.audiotrack_rounded),
|
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 'package:flutter/material.dart';
|
||||||
|
import '../../../l10n/app_localizations.dart';
|
||||||
import 'base_field.dart';
|
import 'base_field.dart';
|
||||||
import '../../../shared/widgets/inputs/modern_text_field.dart';
|
import '../../../shared/widgets/inputs/modern_text_field.dart';
|
||||||
|
|
||||||
@@ -255,7 +256,7 @@ class _AutocompleteMultiSelectWidgetState
|
|||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
'No results',
|
AppLocalizations.of(context)!.noResults,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color:
|
color:
|
||||||
widget.colorScheme.onSurfaceVariant),
|
widget.colorScheme.onSurfaceVariant),
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import '../../../l10n/app_localizations.dart';
|
||||||
import 'package:barcode_widget/barcode_widget.dart';
|
import 'package:barcode_widget/barcode_widget.dart';
|
||||||
import 'base_field.dart';
|
import 'base_field.dart';
|
||||||
|
|
||||||
@@ -73,8 +74,10 @@ class BarcodeField extends BaseField {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
IconButton(
|
Builder(
|
||||||
tooltip: 'Scan Barcode',
|
builder: (ctx) => IconButton(
|
||||||
|
tooltip:
|
||||||
|
AppLocalizations.of(ctx)!.scanBarcode,
|
||||||
icon: Icon(Icons.document_scanner_rounded,
|
icon: Icon(Icons.document_scanner_rounded,
|
||||||
color: colorScheme.primary),
|
color: colorScheme.primary),
|
||||||
onPressed: scanner == null
|
onPressed: scanner == null
|
||||||
@@ -87,6 +90,7 @@ class BarcodeField extends BaseField {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import '../../../l10n/app_localizations.dart';
|
||||||
import 'base_field.dart';
|
import 'base_field.dart';
|
||||||
|
|
||||||
/// Read-only Data Grid field
|
/// Read-only Data Grid field
|
||||||
@@ -96,7 +97,7 @@ class _DataGridFieldWidgetState extends State<_DataGridFieldWidget> {
|
|||||||
}
|
}
|
||||||
final data = snapshot.data ?? const <Map<String, dynamic>>[];
|
final data = snapshot.data ?? const <Map<String, dynamic>>[];
|
||||||
if (data.isEmpty) {
|
if (data.isEmpty) {
|
||||||
return Text('No data available',
|
return Text(AppLocalizations.of(context)!.noDataAvailable,
|
||||||
style: TextStyle(color: colorScheme.onSurfaceVariant));
|
style: TextStyle(color: colorScheme.onSurfaceVariant));
|
||||||
}
|
}
|
||||||
final columns = data.first.keys.toList();
|
final columns = data.first.keys.toList();
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import '../../../l10n/app_localizations.dart';
|
||||||
import 'base_field.dart';
|
import 'base_field.dart';
|
||||||
import '../../../shared/widgets/inputs/modern_text_field.dart';
|
import '../../../shared/widgets/inputs/modern_text_field.dart';
|
||||||
|
|
||||||
@@ -152,7 +153,8 @@ class _DynamicDropdownWidgetState extends State<_DynamicDropdownWidget> {
|
|||||||
children: [
|
children: [
|
||||||
TextField(
|
TextField(
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: 'Search ${widget.label.toLowerCase()}',
|
hintText: AppLocalizations.of(context)!
|
||||||
|
.searchEntity(widget.label),
|
||||||
prefixIcon: const Icon(Icons.search),
|
prefixIcon: const Icon(Icons.search),
|
||||||
border: const OutlineInputBorder(),
|
border: const OutlineInputBorder(),
|
||||||
),
|
),
|
||||||
@@ -162,7 +164,8 @@ class _DynamicDropdownWidgetState extends State<_DynamicDropdownWidget> {
|
|||||||
Flexible(
|
Flexible(
|
||||||
child: filtered.isEmpty
|
child: filtered.isEmpty
|
||||||
? Center(
|
? Center(
|
||||||
child: Text('No results',
|
child: Text(
|
||||||
|
AppLocalizations.of(context)!.noResults,
|
||||||
style: TextStyle(color: cs.onSurfaceVariant)),
|
style: TextStyle(color: cs.onSurfaceVariant)),
|
||||||
)
|
)
|
||||||
: ListView.separated(
|
: ListView.separated(
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import '../../../l10n/app_localizations.dart';
|
||||||
import 'base_field.dart';
|
import 'base_field.dart';
|
||||||
import '../../../shared/widgets/inputs/modern_text_field.dart';
|
import '../../../shared/widgets/inputs/modern_text_field.dart';
|
||||||
|
|
||||||
@@ -146,7 +147,8 @@ class _DynamicMultiSelectWidgetState extends State<_DynamicMultiSelectWidget> {
|
|||||||
children: [
|
children: [
|
||||||
TextField(
|
TextField(
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: 'Search ${widget.label.toLowerCase()}',
|
hintText: AppLocalizations.of(context)!
|
||||||
|
.searchEntity(widget.label),
|
||||||
prefixIcon: const Icon(Icons.search),
|
prefixIcon: const Icon(Icons.search),
|
||||||
border: const OutlineInputBorder(),
|
border: const OutlineInputBorder(),
|
||||||
),
|
),
|
||||||
@@ -156,7 +158,8 @@ class _DynamicMultiSelectWidgetState extends State<_DynamicMultiSelectWidget> {
|
|||||||
Flexible(
|
Flexible(
|
||||||
child: filtered.isEmpty
|
child: filtered.isEmpty
|
||||||
? Center(
|
? Center(
|
||||||
child: Text('No results',
|
child: Text(
|
||||||
|
AppLocalizations.of(context)!.noResults,
|
||||||
style: TextStyle(color: cs.onSurfaceVariant)),
|
style: TextStyle(color: cs.onSurfaceVariant)),
|
||||||
)
|
)
|
||||||
: ListView.separated(
|
: ListView.separated(
|
||||||
@@ -188,7 +191,8 @@ class _DynamicMultiSelectWidgetState extends State<_DynamicMultiSelectWidget> {
|
|||||||
widget.onChanged?.call();
|
widget.onChanged?.call();
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: const Text('Clear'),
|
child: Text(
|
||||||
|
AppLocalizations.of(context)!.clearBtn),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
@@ -199,7 +203,8 @@ class _DynamicMultiSelectWidgetState extends State<_DynamicMultiSelectWidget> {
|
|||||||
widget.onChanged?.call();
|
widget.onChanged?.call();
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: const Text('Done'),
|
child: Text(
|
||||||
|
AppLocalizations.of(context)!.doneBtn),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:file_picker/file_picker.dart';
|
import 'package:file_picker/file_picker.dart';
|
||||||
|
import '../../../l10n/app_localizations.dart';
|
||||||
import 'base_field.dart';
|
import 'base_field.dart';
|
||||||
import '../utils/entity_field_store.dart';
|
import '../utils/entity_field_store.dart';
|
||||||
|
|
||||||
@@ -62,7 +63,9 @@ class FileUploadField extends BaseField {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.attach_file_rounded),
|
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 'dart:typed_data';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
|
import '../../../l10n/app_localizations.dart';
|
||||||
import 'base_field.dart';
|
import 'base_field.dart';
|
||||||
import '../utils/entity_field_store.dart';
|
import '../utils/entity_field_store.dart';
|
||||||
|
|
||||||
@@ -57,7 +58,9 @@ class ImageUploadField extends BaseField {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.image_rounded),
|
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 'package:flutter/material.dart';
|
||||||
|
import '../../../l10n/app_localizations.dart';
|
||||||
import 'base_field.dart';
|
import 'base_field.dart';
|
||||||
import '../ui/entity_form.dart';
|
import '../ui/entity_form.dart';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
@@ -553,7 +554,9 @@ class _OneToManyWidgetState extends State<_OneToManyWidget> {
|
|||||||
child: ElevatedButton.icon(
|
child: ElevatedButton.icon(
|
||||||
onPressed: () => _addRow(),
|
onPressed: () => _addRow(),
|
||||||
icon: Icon(Icons.add, color: cs.onPrimary),
|
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: TextStyle(color: cs.onPrimary)),
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor: cs.primary,
|
backgroundColor: cs.primary,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import '../../../l10n/app_localizations.dart';
|
||||||
import '../../../core/constants/ui_constants.dart';
|
import '../../../core/constants/ui_constants.dart';
|
||||||
import '../../../core/providers/dynamic_theme_provider.dart';
|
import '../../../core/providers/dynamic_theme_provider.dart';
|
||||||
import '../ui/entity_form.dart';
|
import '../ui/entity_form.dart';
|
||||||
@@ -147,7 +147,8 @@ class RelatedEntityInsertField extends BaseField {
|
|||||||
setLocal(() => isSubmitting = false);
|
setLocal(() => isSubmitting = false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
submitButtonText: 'Create',
|
submitButtonText: AppLocalizations.of(context)!
|
||||||
|
.createEntity(relationTitle),
|
||||||
isLoading: isSubmitting,
|
isLoading: isSubmitting,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -156,7 +157,8 @@ class RelatedEntityInsertField extends BaseField {
|
|||||||
onPressed: isSubmitting
|
onPressed: isSubmitting
|
||||||
? null
|
? null
|
||||||
: () => Navigator.of(dialogContext).pop(),
|
: () => Navigator.of(dialogContext).pop(),
|
||||||
child: const Text('Cancel'),
|
child: Text(
|
||||||
|
AppLocalizations.of(dialogContext)!.cancel),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@@ -402,7 +404,8 @@ class _RelatedEntityInsertWidgetState
|
|||||||
ElevatedButton.icon(
|
ElevatedButton.icon(
|
||||||
onPressed: _creating ? null : _openInsertDialog,
|
onPressed: _creating ? null : _openInsertDialog,
|
||||||
icon: Icon(Icons.add_rounded, color: cs.onPrimary, size: 18),
|
icon: Icon(Icons.add_rounded, color: cs.onPrimary, size: 18),
|
||||||
label: Text('Insert',
|
label: Text(
|
||||||
|
AppLocalizations.of(context)!.insertBtn,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: cs.onPrimary, fontWeight: FontWeight.w600)),
|
color: cs.onPrimary, fontWeight: FontWeight.w600)),
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
@@ -491,7 +494,8 @@ class _RelatedEntityInsertWidgetState
|
|||||||
TextButton(
|
TextButton(
|
||||||
onPressed:
|
onPressed:
|
||||||
isSubmitting ? null : () => Navigator.of(context).pop(),
|
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 'package:flutter/material.dart';
|
||||||
|
import '../../../l10n/app_localizations.dart';
|
||||||
import 'base_field.dart';
|
import 'base_field.dart';
|
||||||
import '../ui/entity_form.dart';
|
import '../ui/entity_form.dart';
|
||||||
|
|
||||||
@@ -143,7 +144,8 @@ class _ValueListPickerWidgetState extends State<_ValueListPickerWidget> {
|
|||||||
strokeWidth: 2, color: cs.primary),
|
strokeWidth: 2, color: cs.primary),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
Text('Loading...',
|
Text(
|
||||||
|
AppLocalizations.of(context)!.loading,
|
||||||
style: TextStyle(color: cs.onSurfaceVariant)),
|
style: TextStyle(color: cs.onSurfaceVariant)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -152,7 +154,7 @@ class _ValueListPickerWidgetState extends State<_ValueListPickerWidget> {
|
|||||||
if (snapshot.hasError || _loadError != null) {
|
if (snapshot.hasError || _loadError != null) {
|
||||||
final String msg = snapshot.error?.toString() ??
|
final String msg = snapshot.error?.toString() ??
|
||||||
_loadError ??
|
_loadError ??
|
||||||
'Failed to load';
|
AppLocalizations.of(context)!.errorLoadingData;
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16),
|
||||||
child: Container(
|
child: Container(
|
||||||
@@ -186,13 +188,15 @@ class _ValueListPickerWidgetState extends State<_ValueListPickerWidget> {
|
|||||||
Icon(Icons.inbox_rounded,
|
Icon(Icons.inbox_rounded,
|
||||||
color: cs.onSurfaceVariant, size: 36),
|
color: cs.onSurfaceVariant, size: 36),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
Text('No data found',
|
Text(
|
||||||
|
AppLocalizations.of(context)!.noDataFound,
|
||||||
style: TextStyle(color: cs.onSurfaceVariant)),
|
style: TextStyle(color: cs.onSurfaceVariant)),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
ElevatedButton.icon(
|
ElevatedButton.icon(
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
icon: const Icon(Icons.close_rounded),
|
icon: const Icon(Icons.close_rounded),
|
||||||
label: const Text('Close'),
|
label: Text(
|
||||||
|
AppLocalizations.of(context)!.close),
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor: cs.primary,
|
backgroundColor: cs.primary,
|
||||||
foregroundColor: cs.onPrimary,
|
foregroundColor: cs.onPrimary,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import 'dart:typed_data';
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:file_picker/file_picker.dart';
|
import 'package:file_picker/file_picker.dart';
|
||||||
|
import '../../../l10n/app_localizations.dart';
|
||||||
import 'base_field.dart';
|
import 'base_field.dart';
|
||||||
import '../utils/entity_field_store.dart';
|
import '../utils/entity_field_store.dart';
|
||||||
|
|
||||||
@@ -63,7 +64,9 @@ class VideoUploadField extends BaseField {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.video_library_rounded),
|
icon: const Icon(Icons.video_library_rounded),
|
||||||
label: const Text('Add Video'),
|
label: Builder(
|
||||||
|
builder: (ctx) =>
|
||||||
|
Text(AppLocalizations.of(ctx)!.addVideo)),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import '../../../l10n/app_localizations.dart';
|
||||||
import '../../../core/providers/dynamic_theme_provider.dart';
|
import '../../../core/providers/dynamic_theme_provider.dart';
|
||||||
import '../../../core/constants/ui_constants.dart';
|
import '../../../core/constants/ui_constants.dart';
|
||||||
import '../../../shared/widgets/app_bar/modern_app_bar.dart';
|
import '../../../shared/widgets/app_bar/modern_app_bar.dart';
|
||||||
@@ -408,7 +409,7 @@ class _EntityDetailsState extends State<EntityDetails>
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ModernButton(
|
child: ModernButton(
|
||||||
text: 'Edit',
|
text: AppLocalizations.of(context)!.edit,
|
||||||
type: ModernButtonType.secondary,
|
type: ModernButtonType.secondary,
|
||||||
size: ModernButtonSize.large,
|
size: ModernButtonSize.large,
|
||||||
onPressed: () => widget.onEdit(widget.entity),
|
onPressed: () => widget.onEdit(widget.entity),
|
||||||
@@ -418,7 +419,7 @@ class _EntityDetailsState extends State<EntityDetails>
|
|||||||
const SizedBox(width: UIConstants.spacing16),
|
const SizedBox(width: UIConstants.spacing16),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ModernButton(
|
child: ModernButton(
|
||||||
text: 'Delete',
|
text: AppLocalizations.of(context)!.delete,
|
||||||
type: ModernButtonType.danger,
|
type: ModernButtonType.danger,
|
||||||
size: ModernButtonSize.large,
|
size: ModernButtonSize.large,
|
||||||
onPressed: () => _showDeleteDialog(colorScheme),
|
onPressed: () => _showDeleteDialog(colorScheme),
|
||||||
|
|||||||
@@ -386,6 +386,7 @@
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import '../../../l10n/app_localizations.dart';
|
||||||
import '../../../core/providers/dynamic_theme_provider.dart';
|
import '../../../core/providers/dynamic_theme_provider.dart';
|
||||||
import '../fields/base_field.dart';
|
import '../fields/base_field.dart';
|
||||||
import '../fields/dependent_dropdown_field.dart';
|
import '../fields/dependent_dropdown_field.dart';
|
||||||
@@ -562,7 +563,9 @@ class _EntityFormState extends State<EntityForm> {
|
|||||||
final pass = passwordByGroup[gid] ?? '';
|
final pass = passwordByGroup[gid] ?? '';
|
||||||
if (confirm.isNotEmpty && confirm != pass) {
|
if (confirm.isNotEmpty && confirm != pass) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
const SnackBar(content: Text('Passwords do not match')),
|
SnackBar(
|
||||||
|
content: Text(AppLocalizations.of(context)!
|
||||||
|
.passwordsDoNotMatch)),
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import '../../../core/providers/dynamic_theme_provider.dart';
|
import '../../../core/providers/dynamic_theme_provider.dart';
|
||||||
import '../../../core/constants/ui_constants.dart';
|
import '../../../core/constants/ui_constants.dart';
|
||||||
|
import '../../../l10n/app_localizations.dart';
|
||||||
import '../../../shared/widgets/app_bar/modern_app_bar.dart';
|
import '../../../shared/widgets/app_bar/modern_app_bar.dart';
|
||||||
import 'entity_card.dart';
|
import 'entity_card.dart';
|
||||||
|
|
||||||
@@ -106,7 +107,7 @@ class _EntityListState extends State<EntityList> with TickerProviderStateMixin {
|
|||||||
TextButton(
|
TextButton(
|
||||||
onPressed: widget.onInsertAction,
|
onPressed: widget.onInsertAction,
|
||||||
child: Text(
|
child: Text(
|
||||||
widget.insertActionLabel ?? 'Unknown',
|
widget.insertActionLabel ?? AppLocalizations.of(context)!.unknown,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: colorScheme.primary,
|
color: colorScheme.primary,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@@ -117,7 +118,7 @@ class _EntityListState extends State<EntityList> with TickerProviderStateMixin {
|
|||||||
IconButton(
|
IconButton(
|
||||||
onPressed: widget.onAddNew,
|
onPressed: widget.onAddNew,
|
||||||
icon: Icon(Icons.add_rounded, color: colorScheme.primary),
|
icon: Icon(Icons.add_rounded, color: colorScheme.primary),
|
||||||
tooltip: 'Add New',
|
tooltip: AppLocalizations.of(context)!.addNew,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -175,7 +176,8 @@ class _EntityListState extends State<EntityList> with TickerProviderStateMixin {
|
|||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: 'Search ${widget.title.toLowerCase()}...',
|
hintText: AppLocalizations.of(context)!
|
||||||
|
.searchEntity(widget.title.toLowerCase()),
|
||||||
hintStyle: TextStyle(
|
hintStyle: TextStyle(
|
||||||
color: colorScheme.onSurface.withOpacity(0.6),
|
color: colorScheme.onSurface.withOpacity(0.6),
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
@@ -214,7 +216,7 @@ class _EntityListState extends State<EntityList> with TickerProviderStateMixin {
|
|||||||
color: colorScheme.onSurface.withOpacity(0.8),
|
color: colorScheme.onSurface.withOpacity(0.8),
|
||||||
size: 22,
|
size: 22,
|
||||||
),
|
),
|
||||||
tooltip: 'Refresh',
|
tooltip: AppLocalizations.of(context)!.refresh,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -245,7 +247,7 @@ class _EntityListState extends State<EntityList> with TickerProviderStateMixin {
|
|||||||
CircularProgressIndicator(color: colorScheme.primary, strokeWidth: 3),
|
CircularProgressIndicator(color: colorScheme.primary, strokeWidth: 3),
|
||||||
const SizedBox(height: UIConstants.spacing16),
|
const SizedBox(height: UIConstants.spacing16),
|
||||||
Text(
|
Text(
|
||||||
'Loading ${widget.title.toLowerCase()}...',
|
AppLocalizations.of(context)!.loadingEntity(widget.title.toLowerCase()),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: colorScheme.onSurface.withOpacity(0.7),
|
color: colorScheme.onSurface.withOpacity(0.7),
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
@@ -277,7 +279,7 @@ class _EntityListState extends State<EntityList> with TickerProviderStateMixin {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: UIConstants.spacing16),
|
const SizedBox(height: UIConstants.spacing16),
|
||||||
Text(
|
Text(
|
||||||
'Error Loading Data',
|
AppLocalizations.of(context)!.errorLoadingData,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: colorScheme.onSurface,
|
color: colorScheme.onSurface,
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
@@ -286,7 +288,7 @@ class _EntityListState extends State<EntityList> with TickerProviderStateMixin {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: UIConstants.spacing8),
|
const SizedBox(height: UIConstants.spacing8),
|
||||||
Text(
|
Text(
|
||||||
widget.errorMessage ?? 'Something went wrong',
|
widget.errorMessage ?? AppLocalizations.of(context)!.somethingWentWrong,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: colorScheme.onSurface.withOpacity(0.7),
|
color: colorScheme.onSurface.withOpacity(0.7),
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
@@ -299,7 +301,7 @@ class _EntityListState extends State<EntityList> with TickerProviderStateMixin {
|
|||||||
onPressed: widget.onRefresh,
|
onPressed: widget.onRefresh,
|
||||||
icon: Icon(Icons.refresh_rounded, color: colorScheme.onPrimary),
|
icon: Icon(Icons.refresh_rounded, color: colorScheme.onPrimary),
|
||||||
label: Text(
|
label: Text(
|
||||||
'Retry',
|
AppLocalizations.of(context)!.retry,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: colorScheme.onPrimary,
|
color: colorScheme.onPrimary,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@@ -344,7 +346,7 @@ class _EntityListState extends State<EntityList> with TickerProviderStateMixin {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: UIConstants.spacing16),
|
const SizedBox(height: UIConstants.spacing16),
|
||||||
Text(
|
Text(
|
||||||
'No ${widget.title.toLowerCase()} found',
|
AppLocalizations.of(context)!.noEntityFound(widget.title.toLowerCase()),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: colorScheme.onSurface,
|
color: colorScheme.onSurface,
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
@@ -354,8 +356,9 @@ class _EntityListState extends State<EntityList> with TickerProviderStateMixin {
|
|||||||
const SizedBox(height: UIConstants.spacing8),
|
const SizedBox(height: UIConstants.spacing8),
|
||||||
Text(
|
Text(
|
||||||
widget.searchQuery.isNotEmpty
|
widget.searchQuery.isNotEmpty
|
||||||
? 'Try adjusting your search terms'
|
? AppLocalizations.of(context)!.adjustSearchTerms
|
||||||
: 'Start by adding your first ${widget.title.toLowerCase()}',
|
: AppLocalizations.of(context)!
|
||||||
|
.startByAdding(widget.title.toLowerCase()),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: colorScheme.onSurface.withOpacity(0.7),
|
color: colorScheme.onSurface.withOpacity(0.7),
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
@@ -369,7 +372,7 @@ class _EntityListState extends State<EntityList> with TickerProviderStateMixin {
|
|||||||
onPressed: widget.onAddNew,
|
onPressed: widget.onAddNew,
|
||||||
icon: Icon(Icons.add_rounded, color: colorScheme.onPrimary),
|
icon: Icon(Icons.add_rounded, color: colorScheme.onPrimary),
|
||||||
label: Text(
|
label: Text(
|
||||||
'Add ${widget.title}',
|
AppLocalizations.of(context)!.addEntity(widget.title),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: colorScheme.onPrimary,
|
color: colorScheme.onPrimary,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:base_project/l10n/app_localizations.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class ReusableDropdownField extends StatelessWidget {
|
class ReusableDropdownField extends StatelessWidget {
|
||||||
@@ -46,9 +47,10 @@ class ReusableDropdownField extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
value: (value != null && value!.isNotEmpty) ? value : null,
|
value: (value != null && value!.isNotEmpty) ? value : null,
|
||||||
items: [
|
items: [
|
||||||
const DropdownMenuItem<String>(
|
DropdownMenuItem<String>(
|
||||||
value: '',
|
value: '',
|
||||||
child: Text('Select an option'),
|
child: Text(
|
||||||
|
AppLocalizations.of(context)!.selectOption),
|
||||||
),
|
),
|
||||||
...options.map<DropdownMenuItem<String>>(
|
...options.map<DropdownMenuItem<String>>(
|
||||||
(item) => DropdownMenuItem<String>(
|
(item) => DropdownMenuItem<String>(
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import '../../Entity/angulardatatype/Basicp1/Basicp1_viewModel/Basicp1_view_mode
|
|||||||
|
|
||||||
import 'package:base_project/utils/image_constant.dart';
|
import 'package:base_project/utils/image_constant.dart';
|
||||||
import 'package:base_project/commans/widgets/custome_drawe_item.dart';
|
import 'package:base_project/commans/widgets/custome_drawe_item.dart';
|
||||||
|
import 'package:base_project/l10n/app_localizations.dart';
|
||||||
import 'package:base_project/resources/app_colors.dart';
|
import 'package:base_project/resources/app_colors.dart';
|
||||||
import 'package:base_project/routes/route_names.dart';
|
import 'package:base_project/routes/route_names.dart';
|
||||||
import 'package:base_project/utils/managers/user_manager.dart';
|
import 'package:base_project/utils/managers/user_manager.dart';
|
||||||
@@ -76,13 +77,14 @@ class MyCustomDrawer extends StatelessWidget {
|
|||||||
height: 60,
|
height: 60,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
accountName: Text("Hello, $userName"),
|
accountName: Text(
|
||||||
|
AppLocalizations.of(context)!.helloUser(userName)),
|
||||||
accountEmail: Text(email.toString()),
|
accountEmail: Text(email.toString()),
|
||||||
),
|
),
|
||||||
DrawerItem(
|
DrawerItem(
|
||||||
color: AppColors.primary,
|
color: AppColors.primary,
|
||||||
icon: Icons.person,
|
icon: Icons.person,
|
||||||
title: 'Profile',
|
title: AppLocalizations.of(context)!.profile,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.pushNamed(context, RouteNames.profileView);
|
Navigator.pushNamed(context, RouteNames.profileView);
|
||||||
},
|
},
|
||||||
@@ -90,7 +92,7 @@ class MyCustomDrawer extends StatelessWidget {
|
|||||||
DrawerItem(
|
DrawerItem(
|
||||||
color: AppColors.primary,
|
color: AppColors.primary,
|
||||||
icon: Icons.system_security_update,
|
icon: Icons.system_security_update,
|
||||||
title: 'System Parameters',
|
title: AppLocalizations.of(context)!.systemParameters,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
// Add navigation or other logic here
|
// Add navigation or other logic here
|
||||||
Navigator.pushNamed(context, RouteNames.systemParamsView);
|
Navigator.pushNamed(context, RouteNames.systemParamsView);
|
||||||
@@ -99,7 +101,7 @@ class MyCustomDrawer extends StatelessWidget {
|
|||||||
DrawerItem(
|
DrawerItem(
|
||||||
color: AppColors.primary,
|
color: AppColors.primary,
|
||||||
icon: Icons.password,
|
icon: Icons.password,
|
||||||
title: 'change password',
|
title: AppLocalizations.of(context)!.changePassword,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.pushNamed(context, RouteNames.changePasswordView);
|
Navigator.pushNamed(context, RouteNames.changePasswordView);
|
||||||
},
|
},
|
||||||
@@ -314,7 +316,7 @@ class MyCustomDrawer extends StatelessWidget {
|
|||||||
DrawerItem(
|
DrawerItem(
|
||||||
icon: Icons.logout,
|
icon: Icons.logout,
|
||||||
color: Colors.red,
|
color: Colors.red,
|
||||||
title: 'Logout',
|
title: AppLocalizations.of(context)!.logout,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await UserManager().clearUser();
|
await UserManager().clearUser();
|
||||||
Navigator.pushReplacementNamed(context, RouteNames.splashView);
|
Navigator.pushReplacementNamed(context, RouteNames.splashView);
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
import '../providers/locale_provider.dart';
|
||||||
|
|
||||||
|
/// Translates stable, server/form-builder keys with a safe English fallback.
|
||||||
|
extension DynamicStrings on BuildContext {
|
||||||
|
String trDynamic(String key) => watch<LocaleProvider>().dynamicText(key);
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
class LocaleProvider extends ChangeNotifier {
|
||||||
|
static const preferenceKey = 'app_locale_code';
|
||||||
|
static const supportedCodes = <String>['en', 'hi'];
|
||||||
|
|
||||||
|
Locale _locale = const Locale('en');
|
||||||
|
Locale get locale => _locale;
|
||||||
|
final Map<String, Map<String, String>> _dynamicTables = {};
|
||||||
|
|
||||||
|
Future<void> initialize() async {
|
||||||
|
final preferences = await SharedPreferences.getInstance();
|
||||||
|
final savedCode = preferences.getString(preferenceKey);
|
||||||
|
if (savedCode != null && supportedCodes.contains(savedCode)) {
|
||||||
|
_locale = Locale(savedCode);
|
||||||
|
}
|
||||||
|
await _loadDynamicTables();
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _loadDynamicTables() async {
|
||||||
|
for (final code in supportedCodes) {
|
||||||
|
try {
|
||||||
|
final raw = await rootBundle.loadString('assets/translations_dynamic/$code.json');
|
||||||
|
final decoded = jsonDecode(raw) as Map<String, dynamic>;
|
||||||
|
_dynamicTables[code] = decoded.map(
|
||||||
|
(key, value) => MapEntry(_normalizeKey(key), value.toString()),
|
||||||
|
);
|
||||||
|
} catch (_) {
|
||||||
|
_dynamicTables[code] = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> setLocale(String code) async {
|
||||||
|
if (!supportedCodes.contains(code) || code == _locale.languageCode) return;
|
||||||
|
_locale = Locale(code);
|
||||||
|
notifyListeners();
|
||||||
|
final preferences = await SharedPreferences.getInstance();
|
||||||
|
await preferences.setString(preferenceKey, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
String dynamicText(String key) {
|
||||||
|
final normalized = _normalizeKey(key);
|
||||||
|
return _dynamicTables[_locale.languageCode]?[normalized] ??
|
||||||
|
_dynamicTables['en']?[normalized] ??
|
||||||
|
key.replaceAll('_', ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
String _normalizeKey(String key) =>
|
||||||
|
key.trim().toLowerCase().replaceAll(RegExp(r'\s+'), '_');
|
||||||
|
}
|
||||||
@@ -0,0 +1,177 @@
|
|||||||
|
{
|
||||||
|
"@@locale": "en",
|
||||||
|
"appTitle": "AuthSec Flutter",
|
||||||
|
"language": "Language",
|
||||||
|
"english": "English",
|
||||||
|
"hindi": "Hindi",
|
||||||
|
"helloUser": "Hello, {name}",
|
||||||
|
"@helloUser": {"placeholders": {"name": {"type": "String"}}},
|
||||||
|
"user": "User",
|
||||||
|
"logout": "Logout",
|
||||||
|
"cancel": "Cancel",
|
||||||
|
"confirm": "Confirm",
|
||||||
|
"retry": "Retry",
|
||||||
|
"refresh": "Refresh",
|
||||||
|
"addNew": "Add new",
|
||||||
|
"searchEntity": "Search {entity}...",
|
||||||
|
"@searchEntity": {"placeholders": {"entity": {"type": "String"}}},
|
||||||
|
"loadingEntity": "Loading {entity}...",
|
||||||
|
"@loadingEntity": {"placeholders": {"entity": {"type": "String"}}},
|
||||||
|
"noEntityFound": "No {entity} found",
|
||||||
|
"@noEntityFound": {"placeholders": {"entity": {"type": "String"}}},
|
||||||
|
"addEntity": "Add {entity}",
|
||||||
|
"@addEntity": {"placeholders": {"entity": {"type": "String"}}},
|
||||||
|
"createEntity": "Create {entity}",
|
||||||
|
"@createEntity": {"placeholders": {"entity": {"type": "String"}}},
|
||||||
|
"updateEntity": "Update {entity}",
|
||||||
|
"@updateEntity": {"placeholders": {"entity": {"type": "String"}}},
|
||||||
|
"entityRequired": "{field} is required",
|
||||||
|
"@entityRequired": {"placeholders": {"field": {"type": "String"}}},
|
||||||
|
"errorLoadingData": "Error loading data",
|
||||||
|
"somethingWentWrong": "Something went wrong",
|
||||||
|
"adjustSearchTerms": "Try adjusting your search terms",
|
||||||
|
"startByAdding": "Start by adding your first {entity}",
|
||||||
|
"@startByAdding": {"placeholders": {"entity": {"type": "String"}}},
|
||||||
|
"unknown": "Unknown",
|
||||||
|
"scanBarcode": "Scan barcode",
|
||||||
|
"enterOrScanBarcode": "Enter or scan barcode",
|
||||||
|
"addAudio": "Add audio",
|
||||||
|
"selectAudioFile": "Select audio file",
|
||||||
|
"pickColor": "Pick a color",
|
||||||
|
"systemParameters": "System Parameters",
|
||||||
|
"editSystemParameters": "Edit System Parameters",
|
||||||
|
"goBack": "Go back",
|
||||||
|
"profile": "Profile",
|
||||||
|
"editProfile": "Edit profile",
|
||||||
|
"accountUpdate": "Account update",
|
||||||
|
"changePassword": "Change password",
|
||||||
|
"confirmLogout": "Confirm logout",
|
||||||
|
"confirmLogoutBody": "Are you sure you want to log out?",
|
||||||
|
"logoutAction": "Log out",
|
||||||
|
"passwordsDoNotMatch": "Passwords do not match",
|
||||||
|
"requiredField": "This field is required",
|
||||||
|
"email": "Email",
|
||||||
|
"password": "Password",
|
||||||
|
"signIn": "Sign in",
|
||||||
|
"signUp": "Sign up",
|
||||||
|
"forgotPassword": "Forgot password?",
|
||||||
|
"loading": "Loading...",
|
||||||
|
"save": "Save",
|
||||||
|
"delete": "Delete",
|
||||||
|
"edit": "Edit",
|
||||||
|
"close": "Close"
|
||||||
|
,"welcomeBack": "Welcome back!"
|
||||||
|
,"signInToContinue": "Sign in to continue to your account"
|
||||||
|
,"emailAddress": "Email address"
|
||||||
|
,"enterYourEmail": "Enter your email"
|
||||||
|
,"emailRequired": "Email is required"
|
||||||
|
,"validEmail": "Please enter a valid email"
|
||||||
|
,"enterYourPassword": "Enter your password"
|
||||||
|
,"passwordRequired": "Password is required"
|
||||||
|
,"passwordMinLength": "Password must be at least 6 characters"
|
||||||
|
,"noAccount": "Don't have an account?"
|
||||||
|
,"orContinueWith": "Or continue with"
|
||||||
|
,"verifyOtp": "Verify OTP"
|
||||||
|
,"otpSentTo": "Enter the 6-digit code sent to"
|
||||||
|
,"yourEmail": "your email"
|
||||||
|
,"enterOtp": "Enter 6-digit OTP"
|
||||||
|
,"didNotReceiveCode": "Didn't receive code?"
|
||||||
|
,"resendIn": "Resend in {seconds}s"
|
||||||
|
,"@resendIn": {"placeholders": {"seconds": {"type": "int"}}}
|
||||||
|
,"resend": "Resend"
|
||||||
|
,"dashboard": "Dashboard"
|
||||||
|
,"settings": "Settings"
|
||||||
|
,"security": "Security"
|
||||||
|
,"reports": "Reports"
|
||||||
|
,"manageAccount": "Manage your account"
|
||||||
|
,"configureSystemSettings": "Configure system settings"
|
||||||
|
,"updateYourPassword": "Update your password"
|
||||||
|
,"getOtp": "Get OTP"
|
||||||
|
,"otpEmailPrompt": "Enter your email to receive a one-time password"
|
||||||
|
,"enterEmailAddress": "Enter your email address"
|
||||||
|
,"sendOtp": "Send OTP"
|
||||||
|
,"sendingOtp": "Sending OTP..."
|
||||||
|
,"alreadyHaveAccount": "Already have an account?"
|
||||||
|
,"backToLogin": "Back to login"
|
||||||
|
,"emailLooksGood": "Email looks good"
|
||||||
|
,"invalidEmailAddress": "Invalid email address"
|
||||||
|
,"noDataAvailable": "No data available"
|
||||||
|
,"noResults": "No results"
|
||||||
|
,"clearBtn": "Clear"
|
||||||
|
,"doneBtn": "Done"
|
||||||
|
,"addFiles": "Add Files"
|
||||||
|
,"addImage": "Add Image"
|
||||||
|
,"addVideo": "Add Video"
|
||||||
|
,"insertBtn": "Insert"
|
||||||
|
,"noDataFound": "No data found"
|
||||||
|
,"sysConfigTitle": "System Configuration"
|
||||||
|
,"sysConfigSubtitle": "Configure system-wide parameters and settings"
|
||||||
|
,"generatingTheme": "Generating dynamic theme..."
|
||||||
|
,"themeApplied": "Dynamic theme applied! Colors extracted from logo."
|
||||||
|
,"themeImmediateNote": "Theme is applied immediately! Click \"Upload Logo\" to save the logo permanently to the database. The dynamic theme will work even if upload fails."
|
||||||
|
,"uploadNewLogo": "Upload New Logo"
|
||||||
|
,"removeLogo": "Remove Logo"
|
||||||
|
,"logoAlreadyUploaded": "Company logo is already uploaded and saved in the system. You can upload a new one or remove the existing logo."
|
||||||
|
,"manualOverride": "Enable Manual Override"
|
||||||
|
,"colorPrimary": "Primary"
|
||||||
|
,"colorSecondary": "Secondary"
|
||||||
|
,"colorTertiary": "Tertiary"
|
||||||
|
,"resetLogoColors": "Reset to Logo Colors"
|
||||||
|
,"resetDefault": "Reset to Default"
|
||||||
|
,"userRegistration": "User Registration"
|
||||||
|
,"allowUserRegistration": "Allow new users to register accounts"
|
||||||
|
,"themeGenerated": "Dynamic Theme Generated"
|
||||||
|
,"resetThemeTooltip": "Reset to Default Theme"
|
||||||
|
,"colorPalette": "Color Palette"
|
||||||
|
,"colorAccent1": "Accent 1"
|
||||||
|
,"colorAccent2": "Accent 2"
|
||||||
|
,"colorN": "Color {n}"
|
||||||
|
,"@colorN": {"placeholders": {"n": {"type": "String"}}}
|
||||||
|
,"themeInfo": "Theme Information"
|
||||||
|
,"totalColors": "Total Colors"
|
||||||
|
,"themeDescription": "Description"
|
||||||
|
,"warmColors": "Warm Colors"
|
||||||
|
,"coolColors": "Cool Colors"
|
||||||
|
,"neutralColors": "Neutral Colors"
|
||||||
|
,"yes": "Yes"
|
||||||
|
,"no": "No"
|
||||||
|
,"primaryButton": "Primary Button"
|
||||||
|
,"secondaryButton": "Secondary Button"
|
||||||
|
,"uploadLogo": "Upload Logo"
|
||||||
|
,"clearLogo": "Clear Logo"
|
||||||
|
,"saveConfiguration": "Save Configuration"
|
||||||
|
,"drawerHome": "Home"
|
||||||
|
,"drawerUsers": "Users"
|
||||||
|
,"drawerRoles": "Roles"
|
||||||
|
,"drawerDepartments": "Departments"
|
||||||
|
,"drawerPositions": "Positions"
|
||||||
|
,"drawerCharges": "Charges"
|
||||||
|
,"drawerWeeks": "Weeks"
|
||||||
|
,"drawerShifts": "Shifts"
|
||||||
|
,"drawerBilling": "Billing"
|
||||||
|
,"drawerEdi": "EDI Settings"
|
||||||
|
,"drawerCompany": "Company"
|
||||||
|
,"drawerLogo": "Logo"
|
||||||
|
,"registerCompany": "Register Company"
|
||||||
|
,"accCompanyName": "Company Name"
|
||||||
|
,"accCompanyHint": "Enter company name"
|
||||||
|
,"accWorkspace": "Workspace"
|
||||||
|
,"accWorkspaceHint": "Enter workspace"
|
||||||
|
,"accGst": "GST Number"
|
||||||
|
,"accGstHint": "Enter GST number"
|
||||||
|
,"accMobile": "Mobile"
|
||||||
|
,"accMobileHint": "Enter mobile number"
|
||||||
|
,"accEmailReadonly": "Email (read-only)"
|
||||||
|
,"accPan": "PAN Card"
|
||||||
|
,"accPanHint": "Enter PAN"
|
||||||
|
,"accWorking": "Working"
|
||||||
|
,"accWorkingHint": "Working status"
|
||||||
|
,"requiredVal": "Required"
|
||||||
|
,"nActive": "Active"
|
||||||
|
,"saveChanges": "Save Changes"
|
||||||
|
,"selectOption": "Select an option"
|
||||||
|
,"removeBtn": "Remove"
|
||||||
|
,"ohSnap": "Oh Snap!"
|
||||||
|
,"alertTitle": "Alert"
|
||||||
|
,"successTitle": "Success"
|
||||||
|
}
|
||||||
@@ -0,0 +1,176 @@
|
|||||||
|
{
|
||||||
|
"@@locale": "hi",
|
||||||
|
"appTitle": "ऑथसेक फ्लटर",
|
||||||
|
"language": "भाषा",
|
||||||
|
"english": "अंग्रेज़ी",
|
||||||
|
"hindi": "हिन्दी",
|
||||||
|
"helloUser": "नमस्ते, {name}",
|
||||||
|
"@helloUser": {"placeholders": {"name": {"type": "String"}}},
|
||||||
|
"user": "उपयोगकर्ता",
|
||||||
|
"logout": "लॉग आउट",
|
||||||
|
"cancel": "रद्द करें",
|
||||||
|
"confirm": "पुष्टि करें",
|
||||||
|
"retry": "पुनः प्रयास करें",
|
||||||
|
"refresh": "रीफ़्रेश",
|
||||||
|
"addNew": "नया जोड़ें",
|
||||||
|
"searchEntity": "{entity} खोजें...",
|
||||||
|
"@searchEntity": {"placeholders": {"entity": {"type": "String"}}},
|
||||||
|
"loadingEntity": "{entity} लोड हो रहा है...",
|
||||||
|
"@loadingEntity": {"placeholders": {"entity": {"type": "String"}}},
|
||||||
|
"noEntityFound": "कोई {entity} नहीं मिला",
|
||||||
|
"@noEntityFound": {"placeholders": {"entity": {"type": "String"}}},
|
||||||
|
"addEntity": "{entity} जोड़ें",
|
||||||
|
"@addEntity": {"placeholders": {"entity": {"type": "String"}}},
|
||||||
|
"createEntity": "{entity} बनाएँ",
|
||||||
|
"@createEntity": {"placeholders": {"entity": {"type": "String"}}},
|
||||||
|
"updateEntity": "{entity} अपडेट करें",
|
||||||
|
"@updateEntity": {"placeholders": {"entity": {"type": "String"}}},
|
||||||
|
"entityRequired": "{field} आवश्यक है",
|
||||||
|
"@entityRequired": {"placeholders": {"field": {"type": "String"}}},
|
||||||
|
"errorLoadingData": "डेटा लोड करने में त्रुटि",
|
||||||
|
"somethingWentWrong": "कुछ गलत हो गया",
|
||||||
|
"adjustSearchTerms": "अपने खोज शब्द बदलें",
|
||||||
|
"startByAdding": "अपना पहला {entity} जोड़कर शुरू करें",
|
||||||
|
"@startByAdding": {"placeholders": {"entity": {"type": "String"}}},
|
||||||
|
"unknown": "अज्ञात",
|
||||||
|
"scanBarcode": "बारकोड स्कैन करें",
|
||||||
|
"enterOrScanBarcode": "बारकोड दर्ज करें या स्कैन करें",
|
||||||
|
"addAudio": "ऑडियो जोड़ें",
|
||||||
|
"selectAudioFile": "ऑडियो फ़ाइल चुनें",
|
||||||
|
"pickColor": "रंग चुनें",
|
||||||
|
"systemParameters": "सिस्टम पैरामीटर",
|
||||||
|
"editSystemParameters": "सिस्टम पैरामीटर संपादित करें",
|
||||||
|
"goBack": "वापस जाएँ",
|
||||||
|
"profile": "प्रोफ़ाइल",
|
||||||
|
"editProfile": "प्रोफ़ाइल संपादित करें",
|
||||||
|
"accountUpdate": "खाता अपडेट",
|
||||||
|
"changePassword": "पासवर्ड बदलें",
|
||||||
|
"confirmLogout": "लॉग आउट की पुष्टि करें",
|
||||||
|
"confirmLogoutBody": "क्या आप वाकई लॉग आउट करना चाहते हैं?",
|
||||||
|
"logoutAction": "लॉग आउट",
|
||||||
|
"passwordsDoNotMatch": "पासवर्ड मेल नहीं खाते",
|
||||||
|
"requiredField": "यह फ़ील्ड आवश्यक है",
|
||||||
|
"email": "ईमेल",
|
||||||
|
"password": "पासवर्ड",
|
||||||
|
"signIn": "साइन इन",
|
||||||
|
"signUp": "साइन अप",
|
||||||
|
"forgotPassword": "पासवर्ड भूल गए?",
|
||||||
|
"loading": "लोड हो रहा है...",
|
||||||
|
"save": "सहेजें",
|
||||||
|
"delete": "हटाएँ",
|
||||||
|
"edit": "संपादित करें",
|
||||||
|
"close": "बंद करें"
|
||||||
|
,"welcomeBack": "वापस स्वागत है!"
|
||||||
|
,"signInToContinue": "अपने खाते में जारी रखने के लिए साइन इन करें"
|
||||||
|
,"emailAddress": "ईमेल पता"
|
||||||
|
,"enterYourEmail": "अपना ईमेल दर्ज करें"
|
||||||
|
,"emailRequired": "ईमेल आवश्यक है"
|
||||||
|
,"validEmail": "कृपया मान्य ईमेल दर्ज करें"
|
||||||
|
,"enterYourPassword": "अपना पासवर्ड दर्ज करें"
|
||||||
|
,"passwordRequired": "पासवर्ड आवश्यक है"
|
||||||
|
,"passwordMinLength": "पासवर्ड कम से कम 6 वर्ण का होना चाहिए"
|
||||||
|
,"noAccount": "क्या आपका खाता नहीं है?"
|
||||||
|
,"orContinueWith": "या इसके साथ जारी रखें"
|
||||||
|
,"verifyOtp": "ओटीपी सत्यापित करें"
|
||||||
|
,"otpSentTo": "भेजा गया 6 अंकों का कोड दर्ज करें"
|
||||||
|
,"yourEmail": "आपका ईमेल"
|
||||||
|
,"enterOtp": "6 अंकों का ओटीपी दर्ज करें"
|
||||||
|
,"didNotReceiveCode": "कोड नहीं मिला?"
|
||||||
|
,"resendIn": "{seconds} सेकंड में पुनः भेजें"
|
||||||
|
,"@resendIn": {"placeholders": {"seconds": {"type": "int"}}}
|
||||||
|
,"resend": "पुनः भेजें"
|
||||||
|
,"dashboard": "डैशबोर्ड"
|
||||||
|
,"settings": "सेटिंग्स"
|
||||||
|
,"security": "सुरक्षा"
|
||||||
|
,"reports": "रिपोर्ट"
|
||||||
|
,"manageAccount": "अपने खाते का प्रबंधन करें"
|
||||||
|
,"configureSystemSettings": "सिस्टम सेटिंग्स कॉन्फ़िगर करें"
|
||||||
|
,"updateYourPassword": "अपना पासवर्ड अपडेट करें"
|
||||||
|
,"getOtp": "ओटीपी प्राप्त करें"
|
||||||
|
,"otpEmailPrompt": "वन-टाइम पासवर्ड पाने के लिए अपना ईमेल दर्ज करें"
|
||||||
|
,"enterEmailAddress": "अपना ईमेल पता दर्ज करें"
|
||||||
|
,"sendOtp": "ओटीपी भेजें"
|
||||||
|
,"sendingOtp": "ओटीपी भेजा जा रहा है..."
|
||||||
|
,"alreadyHaveAccount": "क्या आपका पहले से खाता है?"
|
||||||
|
,"backToLogin": "लॉगिन पर वापस जाएँ"
|
||||||
|
,"emailLooksGood": "ईमेल सही है"
|
||||||
|
,"invalidEmailAddress": "अमान्य ईमेल पता"
|
||||||
|
,"noDataAvailable": "कोई डेटा उपलब्ध नहीं"
|
||||||
|
,"noResults": "कोई परिणाम नहीं"
|
||||||
|
,"clearBtn": "साफ़ करें"
|
||||||
|
,"doneBtn": "हो गया"
|
||||||
|
,"addFiles": "फ़ाइलें जोड़ें"
|
||||||
|
,"addImage": "छवि जोड़ें"
|
||||||
|
,"addVideo": "वीडियो जोड़ें"
|
||||||
|
,"insertBtn": "डालें"
|
||||||
|
,"noDataFound": "कोई डेटा नहीं मिला"
|
||||||
|
,"sysConfigTitle": "सिस्टम कॉन्फ़िगरेशन"
|
||||||
|
,"sysConfigSubtitle": "सिस्टम-व्यापी पैरामीटर और सेटिंग्स कॉन्फ़िगर करें"
|
||||||
|
,"generatingTheme": "डायनामिक थीम बनाई जा रही है..."
|
||||||
|
,"themeApplied": "डायनामिक थीम लागू! लोगो से रंग निकाले गए।"
|
||||||
|
,"themeImmediateNote": "थीम तुरंत लागू होती है! लोगो को डेटाबेस में स्थायी रूप से सहेजने के लिए अपलोड लोगो पर क्लिक करें। अपलोड विफल होने पर भी डायनामिक थीम काम करेगी।"
|
||||||
|
,"uploadNewLogo": "नया लोगो अपलोड करें"
|
||||||
|
,"removeLogo": "लोगो हटाएं"
|
||||||
|
,"logoAlreadyUploaded": "कंपनी का लोगो पहले से अपलोड है और सिस्टम में सहेजा गया है। आप नया अपलोड कर सकते हैं या मौजूदा लोगो हटा सकते हैं।"
|
||||||
|
,"manualOverride": "मैन्युअल ओवरराइड सक्षम करें"
|
||||||
|
,"colorPrimary": "प्राथमिक"
|
||||||
|
,"colorSecondary": "द्वितीयक"
|
||||||
|
,"colorTertiary": "तृतीयक"
|
||||||
|
,"resetLogoColors": "लोगो रंगों पर रीसेट करें"
|
||||||
|
,"resetDefault": "डिफ़ॉल्ट पर रीसेट करें"
|
||||||
|
,"userRegistration": "उपयोगकर्ता पंजीकरण"
|
||||||
|
,"allowUserRegistration": "नए उपयोगकर्ताओं को खाते पंजीकृत करने दें"
|
||||||
|
,"themeGenerated": "डायनामिक थीम बनाई गई"
|
||||||
|
,"resetThemeTooltip": "डिफ़ॉल्ट थीम पर रीसेट करें"
|
||||||
|
,"colorPalette": "रंग पट्टिका"
|
||||||
|
,"colorAccent1": "एक्सेंट 1"
|
||||||
|
,"colorAccent2": "एक्सेंट 2"
|
||||||
|
,"colorN": "रंग {n}"
|
||||||
|
,"themeInfo": "थीम जानकारी"
|
||||||
|
,"totalColors": "कुल रंग"
|
||||||
|
,"themeDescription": "विवरण"
|
||||||
|
,"warmColors": "गर्म रंग"
|
||||||
|
,"coolColors": "ठंडे रंग"
|
||||||
|
,"neutralColors": "तटस्थ रंग"
|
||||||
|
,"yes": "हां"
|
||||||
|
,"no": "नहीं"
|
||||||
|
,"primaryButton": "प्राथमिक बटन"
|
||||||
|
,"secondaryButton": "द्वितीयक बटन"
|
||||||
|
,"uploadLogo": "लोगो अपलोड करें"
|
||||||
|
,"clearLogo": "लोगो साफ़ करें"
|
||||||
|
,"saveConfiguration": "कॉन्फ़िगरेशन सहेजें"
|
||||||
|
,"drawerHome": "होम"
|
||||||
|
,"drawerUsers": "उपयोगकर्ता"
|
||||||
|
,"drawerRoles": "भूमिकाएं"
|
||||||
|
,"drawerDepartments": "विभाग"
|
||||||
|
,"drawerPositions": "पद"
|
||||||
|
,"drawerCharges": "शुल्क"
|
||||||
|
,"drawerWeeks": "सप्ताह"
|
||||||
|
,"drawerShifts": "पारियां"
|
||||||
|
,"drawerBilling": "बिलिंग"
|
||||||
|
,"drawerEdi": "EDI सेटिंग्स"
|
||||||
|
,"drawerCompany": "कंपनी"
|
||||||
|
,"drawerLogo": "लोगो"
|
||||||
|
,"registerCompany": "कंपनी पंजीकृत करें"
|
||||||
|
,"accCompanyName": "कंपनी का नाम"
|
||||||
|
,"accCompanyHint": "कंपनी का नाम दर्ज करें"
|
||||||
|
,"accWorkspace": "कार्यक्षेत्र"
|
||||||
|
,"accWorkspaceHint": "कार्यक्षेत्र दर्ज करें"
|
||||||
|
,"accGst": "जीएसटी नंबर"
|
||||||
|
,"accGstHint": "जीएसटी नंबर दर्ज करें"
|
||||||
|
,"accMobile": "मोबाइल"
|
||||||
|
,"accMobileHint": "मोबाइल नंबर दर्ज करें"
|
||||||
|
,"accEmailReadonly": "ईमेल (केवल-पठन)"
|
||||||
|
,"accPan": "पैन कार्ड"
|
||||||
|
,"accPanHint": "पैन दर्ज करें"
|
||||||
|
,"accWorking": "कार्य"
|
||||||
|
,"accWorkingHint": "कार्य स्थिति"
|
||||||
|
,"requiredVal": "आवश्यक"
|
||||||
|
,"nActive": "सक्रिय"
|
||||||
|
,"saveChanges": "परिवर्तन सहेजें"
|
||||||
|
,"selectOption": "एक विकल्प चुनें"
|
||||||
|
,"removeBtn": "हटाएं"
|
||||||
|
,"ohSnap": "ओह स्नैप!"
|
||||||
|
,"alertTitle": "चेतावनी"
|
||||||
|
,"successTitle": "सफलता"
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,526 @@
|
|||||||
|
// 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 get appTitle => 'AuthSec Flutter';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get language => 'Language';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get english => 'English';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get hindi => 'Hindi';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String helloUser(String name) {
|
||||||
|
return 'Hello, $name';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get user => 'User';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get logout => 'Logout';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get cancel => 'Cancel';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get confirm => 'Confirm';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get retry => 'Retry';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get refresh => 'Refresh';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get addNew => 'Add new';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String searchEntity(String entity) {
|
||||||
|
return 'Search $entity...';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String loadingEntity(String entity) {
|
||||||
|
return 'Loading $entity...';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String noEntityFound(String entity) {
|
||||||
|
return 'No $entity found';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String addEntity(String entity) {
|
||||||
|
return 'Add $entity';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String createEntity(String entity) {
|
||||||
|
return 'Create $entity';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String updateEntity(String entity) {
|
||||||
|
return 'Update $entity';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String entityRequired(String field) {
|
||||||
|
return '$field is required';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get errorLoadingData => 'Error loading data';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get somethingWentWrong => 'Something went wrong';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get adjustSearchTerms => 'Try adjusting your search terms';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String startByAdding(String entity) {
|
||||||
|
return 'Start by adding your first $entity';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get unknown => 'Unknown';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get scanBarcode => 'Scan barcode';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get enterOrScanBarcode => 'Enter or scan barcode';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get addAudio => 'Add audio';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get selectAudioFile => 'Select audio file';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get pickColor => 'Pick a color';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get systemParameters => 'System Parameters';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get editSystemParameters => 'Edit System Parameters';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get goBack => 'Go back';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get profile => 'Profile';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get editProfile => 'Edit profile';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accountUpdate => 'Account update';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get changePassword => 'Change password';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get confirmLogout => 'Confirm logout';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get confirmLogoutBody => 'Are you sure you want to log out?';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get logoutAction => 'Log out';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get passwordsDoNotMatch => 'Passwords do not match';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get requiredField => 'This field is required';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get email => 'Email';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get password => 'Password';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get signIn => 'Sign in';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get signUp => 'Sign up';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get forgotPassword => 'Forgot password?';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get loading => 'Loading...';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get save => 'Save';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get delete => 'Delete';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get edit => 'Edit';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get close => 'Close';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get welcomeBack => 'Welcome back!';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get signInToContinue => 'Sign in to continue to your account';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get emailAddress => 'Email address';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get enterYourEmail => 'Enter your email';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get emailRequired => 'Email is required';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get validEmail => 'Please enter a valid email';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get enterYourPassword => 'Enter your password';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get passwordRequired => 'Password is required';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get passwordMinLength => 'Password must be at least 6 characters';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get noAccount => 'Don\'t have an account?';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get orContinueWith => 'Or continue with';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get verifyOtp => 'Verify OTP';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get otpSentTo => 'Enter the 6-digit code sent to';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get yourEmail => 'your email';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get enterOtp => 'Enter 6-digit OTP';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get didNotReceiveCode => 'Didn\'t receive code?';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String resendIn(int seconds) {
|
||||||
|
return 'Resend in ${seconds}s';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get resend => 'Resend';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get dashboard => 'Dashboard';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get settings => 'Settings';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get security => 'Security';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get reports => 'Reports';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get manageAccount => 'Manage your account';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get configureSystemSettings => 'Configure system settings';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get updateYourPassword => 'Update your password';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get getOtp => 'Get OTP';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get otpEmailPrompt =>
|
||||||
|
'Enter your email to receive a one-time password';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get enterEmailAddress => 'Enter your email address';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get sendOtp => 'Send OTP';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get sendingOtp => 'Sending OTP...';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get alreadyHaveAccount => 'Already have an account?';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get backToLogin => 'Back to login';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get emailLooksGood => 'Email looks good';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get invalidEmailAddress => 'Invalid email address';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get noDataAvailable => 'No data available';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get noResults => 'No results';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get clearBtn => 'Clear';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get doneBtn => 'Done';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get addFiles => 'Add Files';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get addImage => 'Add Image';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get addVideo => 'Add Video';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get insertBtn => 'Insert';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get noDataFound => 'No data found';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get sysConfigTitle => 'System Configuration';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get sysConfigSubtitle =>
|
||||||
|
'Configure system-wide parameters and settings';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get generatingTheme => 'Generating dynamic theme...';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get themeApplied =>
|
||||||
|
'Dynamic theme applied! Colors extracted from logo.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get themeImmediateNote =>
|
||||||
|
'Theme is applied immediately! Click \"Upload Logo\" to save the logo permanently to the database. The dynamic theme will work even if upload fails.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get uploadNewLogo => 'Upload New Logo';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get removeLogo => 'Remove Logo';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get logoAlreadyUploaded =>
|
||||||
|
'Company logo is already uploaded and saved in the system. You can upload a new one or remove the existing logo.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get manualOverride => 'Enable Manual Override';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get colorPrimary => 'Primary';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get colorSecondary => 'Secondary';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get colorTertiary => 'Tertiary';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get resetLogoColors => 'Reset to Logo Colors';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get resetDefault => 'Reset to Default';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get userRegistration => 'User Registration';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get allowUserRegistration => 'Allow new users to register accounts';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get themeGenerated => 'Dynamic Theme Generated';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get resetThemeTooltip => 'Reset to Default Theme';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get colorPalette => 'Color Palette';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get colorAccent1 => 'Accent 1';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get colorAccent2 => 'Accent 2';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String colorN(String n) {
|
||||||
|
return 'Color $n';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get themeInfo => 'Theme Information';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get totalColors => 'Total Colors';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get themeDescription => 'Description';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get warmColors => 'Warm Colors';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get coolColors => 'Cool Colors';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get neutralColors => 'Neutral Colors';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get yes => 'Yes';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get no => 'No';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get primaryButton => 'Primary Button';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get secondaryButton => 'Secondary Button';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get uploadLogo => 'Upload Logo';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get clearLogo => 'Clear Logo';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get saveConfiguration => 'Save Configuration';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get drawerHome => 'Home';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get drawerUsers => 'Users';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get drawerRoles => 'Roles';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get drawerDepartments => 'Departments';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get drawerPositions => 'Positions';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get drawerCharges => 'Charges';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get drawerWeeks => 'Weeks';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get drawerShifts => 'Shifts';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get drawerBilling => 'Billing';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get drawerEdi => 'EDI Settings';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get drawerCompany => 'Company';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get drawerLogo => 'Logo';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get registerCompany => 'Register Company';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accCompanyName => 'Company Name';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accCompanyHint => 'Enter company name';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accWorkspace => 'Workspace';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accWorkspaceHint => 'Enter workspace';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accGst => 'GST Number';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accGstHint => 'Enter GST number';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accMobile => 'Mobile';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accMobileHint => 'Enter mobile number';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accEmailReadonly => 'Email (read-only)';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accPan => 'PAN Card';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accPanHint => 'Enter PAN';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accWorking => 'Working';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accWorkingHint => 'Working status';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get requiredVal => 'Required';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get nActive => 'Active';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get saveChanges => 'Save Changes';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get selectOption => 'Select an option';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get removeBtn => 'Remove';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get ohSnap => 'Oh Snap!';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get alertTitle => 'Alert';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get successTitle => 'Success';
|
||||||
|
}
|
||||||
@@ -0,0 +1,526 @@
|
|||||||
|
// ignore: unused_import
|
||||||
|
import 'package:intl/intl.dart' as intl;
|
||||||
|
import 'app_localizations.dart';
|
||||||
|
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
|
||||||
|
/// The translations for Hindi (`hi`).
|
||||||
|
class AppLocalizationsHi extends AppLocalizations {
|
||||||
|
AppLocalizationsHi([String locale = 'hi']) : super(locale);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get appTitle => 'ऑथसेक फ्लटर';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get language => 'भाषा';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get english => 'अंग्रेज़ी';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get hindi => 'हिन्दी';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String helloUser(String name) {
|
||||||
|
return 'नमस्ते, $name';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get user => 'उपयोगकर्ता';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get logout => 'लॉग आउट';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get cancel => 'रद्द करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get confirm => 'पुष्टि करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get retry => 'पुनः प्रयास करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get refresh => 'रीफ़्रेश';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get addNew => 'नया जोड़ें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String searchEntity(String entity) {
|
||||||
|
return '$entity खोजें...';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String loadingEntity(String entity) {
|
||||||
|
return '$entity लोड हो रहा है...';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String noEntityFound(String entity) {
|
||||||
|
return 'कोई $entity नहीं मिला';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String addEntity(String entity) {
|
||||||
|
return '$entity जोड़ें';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String createEntity(String entity) {
|
||||||
|
return '$entity बनाएँ';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String updateEntity(String entity) {
|
||||||
|
return '$entity अपडेट करें';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String entityRequired(String field) {
|
||||||
|
return '$field आवश्यक है';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get errorLoadingData => 'डेटा लोड करने में त्रुटि';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get somethingWentWrong => 'कुछ गलत हो गया';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get adjustSearchTerms => 'अपने खोज शब्द बदलें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String startByAdding(String entity) {
|
||||||
|
return 'अपना पहला $entity जोड़कर शुरू करें';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get unknown => 'अज्ञात';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get scanBarcode => 'बारकोड स्कैन करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get enterOrScanBarcode => 'बारकोड दर्ज करें या स्कैन करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get addAudio => 'ऑडियो जोड़ें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get selectAudioFile => 'ऑडियो फ़ाइल चुनें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get pickColor => 'रंग चुनें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get systemParameters => 'सिस्टम पैरामीटर';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get editSystemParameters => 'सिस्टम पैरामीटर संपादित करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get goBack => 'वापस जाएँ';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get profile => 'प्रोफ़ाइल';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get editProfile => 'प्रोफ़ाइल संपादित करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accountUpdate => 'खाता अपडेट';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get changePassword => 'पासवर्ड बदलें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get confirmLogout => 'लॉग आउट की पुष्टि करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get confirmLogoutBody => 'क्या आप वाकई लॉग आउट करना चाहते हैं?';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get logoutAction => 'लॉग आउट';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get passwordsDoNotMatch => 'पासवर्ड मेल नहीं खाते';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get requiredField => 'यह फ़ील्ड आवश्यक है';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get email => 'ईमेल';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get password => 'पासवर्ड';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get signIn => 'साइन इन';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get signUp => 'साइन अप';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get forgotPassword => 'पासवर्ड भूल गए?';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get loading => 'लोड हो रहा है...';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get save => 'सहेजें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get delete => 'हटाएँ';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get edit => 'संपादित करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get close => 'बंद करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get welcomeBack => 'वापस स्वागत है!';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get signInToContinue => 'अपने खाते में जारी रखने के लिए साइन इन करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get emailAddress => 'ईमेल पता';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get enterYourEmail => 'अपना ईमेल दर्ज करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get emailRequired => 'ईमेल आवश्यक है';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get validEmail => 'कृपया मान्य ईमेल दर्ज करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get enterYourPassword => 'अपना पासवर्ड दर्ज करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get passwordRequired => 'पासवर्ड आवश्यक है';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get passwordMinLength => 'पासवर्ड कम से कम 6 वर्ण का होना चाहिए';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get noAccount => 'क्या आपका खाता नहीं है?';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get orContinueWith => 'या इसके साथ जारी रखें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get verifyOtp => 'ओटीपी सत्यापित करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get otpSentTo => 'भेजा गया 6 अंकों का कोड दर्ज करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get yourEmail => 'आपका ईमेल';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get enterOtp => '6 अंकों का ओटीपी दर्ज करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get didNotReceiveCode => 'कोड नहीं मिला?';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String resendIn(int seconds) {
|
||||||
|
return '$seconds सेकंड में पुनः भेजें';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get resend => 'पुनः भेजें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get dashboard => 'डैशबोर्ड';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get settings => 'सेटिंग्स';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get security => 'सुरक्षा';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get reports => 'रिपोर्ट';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get manageAccount => 'अपने खाते का प्रबंधन करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get configureSystemSettings => 'सिस्टम सेटिंग्स कॉन्फ़िगर करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get updateYourPassword => 'अपना पासवर्ड अपडेट करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get getOtp => 'ओटीपी प्राप्त करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get otpEmailPrompt =>
|
||||||
|
'वन-टाइम पासवर्ड पाने के लिए अपना ईमेल दर्ज करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get enterEmailAddress => 'अपना ईमेल पता दर्ज करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get sendOtp => 'ओटीपी भेजें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get sendingOtp => 'ओटीपी भेजा जा रहा है...';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get alreadyHaveAccount => 'क्या आपका पहले से खाता है?';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get backToLogin => 'लॉगिन पर वापस जाएँ';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get emailLooksGood => 'ईमेल सही है';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get invalidEmailAddress => 'अमान्य ईमेल पता';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get noDataAvailable => 'कोई डेटा उपलब्ध नहीं';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get noResults => 'कोई परिणाम नहीं';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get clearBtn => 'साफ़ करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get doneBtn => 'हो गया';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get addFiles => 'फ़ाइलें जोड़ें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get addImage => 'छवि जोड़ें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get addVideo => 'वीडियो जोड़ें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get insertBtn => 'डालें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get noDataFound => 'कोई डेटा नहीं मिला';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get sysConfigTitle => 'सिस्टम कॉन्फ़िगरेशन';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get sysConfigSubtitle =>
|
||||||
|
'सिस्टम-व्यापी पैरामीटर और सेटिंग्स कॉन्फ़िगर करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get generatingTheme => 'डायनामिक थीम बनाई जा रही है...';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get themeApplied => 'डायनामिक थीम लागू! लोगो से रंग निकाले गए।';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get themeImmediateNote =>
|
||||||
|
'थीम तुरंत लागू होती है! लोगो को डेटाबेस में स्थायी रूप से सहेजने के लिए अपलोड लोगो पर क्लिक करें। अपलोड विफल होने पर भी डायनामिक थीम काम करेगी।';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get uploadNewLogo => 'नया लोगो अपलोड करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get removeLogo => 'लोगो हटाएं';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get logoAlreadyUploaded =>
|
||||||
|
'कंपनी का लोगो पहले से अपलोड है और सिस्टम में सहेजा गया है। आप नया अपलोड कर सकते हैं या मौजूदा लोगो हटा सकते हैं।';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get manualOverride => 'मैन्युअल ओवरराइड सक्षम करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get colorPrimary => 'प्राथमिक';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get colorSecondary => 'द्वितीयक';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get colorTertiary => 'तृतीयक';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get resetLogoColors => 'लोगो रंगों पर रीसेट करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get resetDefault => 'डिफ़ॉल्ट पर रीसेट करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get userRegistration => 'उपयोगकर्ता पंजीकरण';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get allowUserRegistration =>
|
||||||
|
'नए उपयोगकर्ताओं को खाते पंजीकृत करने दें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get themeGenerated => 'डायनामिक थीम बनाई गई';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get resetThemeTooltip => 'डिफ़ॉल्ट थीम पर रीसेट करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get colorPalette => 'रंग पट्टिका';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get colorAccent1 => 'एक्सेंट 1';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get colorAccent2 => 'एक्सेंट 2';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String colorN(String n) {
|
||||||
|
return 'रंग $n';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get themeInfo => 'थीम जानकारी';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get totalColors => 'कुल रंग';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get themeDescription => 'विवरण';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get warmColors => 'गर्म रंग';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get coolColors => 'ठंडे रंग';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get neutralColors => 'तटस्थ रंग';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get yes => 'हां';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get no => 'नहीं';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get primaryButton => 'प्राथमिक बटन';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get secondaryButton => 'द्वितीयक बटन';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get uploadLogo => 'लोगो अपलोड करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get clearLogo => 'लोगो साफ़ करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get saveConfiguration => 'कॉन्फ़िगरेशन सहेजें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get drawerHome => 'होम';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get drawerUsers => 'उपयोगकर्ता';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get drawerRoles => 'भूमिकाएं';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get drawerDepartments => 'विभाग';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get drawerPositions => 'पद';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get drawerCharges => 'शुल्क';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get drawerWeeks => 'सप्ताह';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get drawerShifts => 'पारियां';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get drawerBilling => 'बिलिंग';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get drawerEdi => 'EDI सेटिंग्स';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get drawerCompany => 'कंपनी';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get drawerLogo => 'लोगो';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get registerCompany => 'कंपनी पंजीकृत करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accCompanyName => 'कंपनी का नाम';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accCompanyHint => 'कंपनी का नाम दर्ज करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accWorkspace => 'कार्यक्षेत्र';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accWorkspaceHint => 'कार्यक्षेत्र दर्ज करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accGst => 'जीएसटी नंबर';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accGstHint => 'जीएसटी नंबर दर्ज करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accMobile => 'मोबाइल';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accMobileHint => 'मोबाइल नंबर दर्ज करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accEmailReadonly => 'ईमेल (केवल-पठन)';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accPan => 'पैन कार्ड';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accPanHint => 'पैन दर्ज करें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accWorking => 'कार्य';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get accWorkingHint => 'कार्य स्थिति';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get requiredVal => 'आवश्यक';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get nActive => 'सक्रिय';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get saveChanges => 'परिवर्तन सहेजें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get selectOption => 'एक विकल्प चुनें';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get removeBtn => 'हटाएं';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get ohSnap => 'ओह स्नैप!';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get alertTitle => 'चेतावनी';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get successTitle => 'सफलता';
|
||||||
|
}
|
||||||
@@ -7,14 +7,18 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'core/providers/dynamic_theme_provider.dart';
|
import 'core/providers/dynamic_theme_provider.dart';
|
||||||
|
import 'core/providers/locale_provider.dart';
|
||||||
import 'core/providers/theme_provider.dart';
|
import 'core/providers/theme_provider.dart';
|
||||||
import 'core/theme/app_theme.dart';
|
import 'core/theme/app_theme.dart';
|
||||||
|
import 'l10n/app_localizations.dart';
|
||||||
import 'routes/app_routes.dart';
|
import 'routes/app_routes.dart';
|
||||||
import 'utils/managers/user_manager.dart';
|
import 'utils/managers/user_manager.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
await UserManager().initialize();
|
await UserManager().initialize();
|
||||||
|
final localeProvider = LocaleProvider();
|
||||||
|
await localeProvider.initialize();
|
||||||
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
||||||
|
|
||||||
runApp(MultiProvider(
|
runApp(MultiProvider(
|
||||||
@@ -24,6 +28,7 @@ void main() async {
|
|||||||
ChangeNotifierProvider(create: (context) => SystemParamsViewModel()),
|
ChangeNotifierProvider(create: (context) => SystemParamsViewModel()),
|
||||||
ChangeNotifierProvider(create: (context) => ThemeProvider()),
|
ChangeNotifierProvider(create: (context) => ThemeProvider()),
|
||||||
ChangeNotifierProvider(create: (context) => DynamicThemeProvider()),
|
ChangeNotifierProvider(create: (context) => DynamicThemeProvider()),
|
||||||
|
ChangeNotifierProvider.value(value: localeProvider),
|
||||||
],
|
],
|
||||||
child: const MyApp(),
|
child: const MyApp(),
|
||||||
));
|
));
|
||||||
@@ -63,8 +68,8 @@ class MyApp extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Consumer2<ThemeProvider, DynamicThemeProvider>(
|
return Consumer3<ThemeProvider, DynamicThemeProvider, LocaleProvider>(
|
||||||
builder: (context, themeProvider, dynamicThemeProvider, child) {
|
builder: (context, themeProvider, dynamicThemeProvider, localeProvider, child) {
|
||||||
final theme = AppTheme.getTheme(context);
|
final theme = AppTheme.getTheme(context);
|
||||||
// Set system UI overlay style
|
// Set system UI overlay style
|
||||||
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
|
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
|
||||||
@@ -86,6 +91,9 @@ class MyApp extends StatelessWidget {
|
|||||||
initialRoute: RouteNames.splashView,
|
initialRoute: RouteNames.splashView,
|
||||||
onGenerateRoute: AppRoutes.generateRoutes,
|
onGenerateRoute: AppRoutes.generateRoutes,
|
||||||
navigatorKey: navigatorKey,
|
navigatorKey: navigatorKey,
|
||||||
|
locale: localeProvider.locale,
|
||||||
|
supportedLocales: AppLocalizations.supportedLocales,
|
||||||
|
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||||
builder: (context, child) {
|
builder: (context, child) {
|
||||||
return MediaQuery(
|
return MediaQuery(
|
||||||
data: MediaQuery.of(context).copyWith(
|
data: MediaQuery.of(context).copyWith(
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
import 'package:base_project/l10n/app_localizations.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import '../../../core/constants/ui_constants.dart';
|
import '../../../core/constants/ui_constants.dart';
|
||||||
import '../buttons/modern_button.dart';
|
import '../buttons/modern_button.dart';
|
||||||
@@ -208,7 +209,7 @@ class _ModernImagePickerState extends State<ModernImagePicker>
|
|||||||
if (hasImage && widget.onRemoveImage != null) ...[
|
if (hasImage && widget.onRemoveImage != null) ...[
|
||||||
const SizedBox(width: UIConstants.spacing12),
|
const SizedBox(width: UIConstants.spacing12),
|
||||||
ModernButton(
|
ModernButton(
|
||||||
text: 'Remove',
|
text: AppLocalizations.of(context)!.removeBtn,
|
||||||
type: ModernButtonType.danger,
|
type: ModernButtonType.danger,
|
||||||
size: ModernButtonSize.medium,
|
size: ModernButtonSize.medium,
|
||||||
icon: Icon(Icons.delete_outline),
|
icon: Icon(Icons.delete_outline),
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
import '../../core/providers/locale_provider.dart';
|
||||||
|
import '../../l10n/app_localizations.dart';
|
||||||
|
|
||||||
|
class LanguageSwitcher extends StatelessWidget {
|
||||||
|
const LanguageSwitcher({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final locale = context.watch<LocaleProvider>().locale.languageCode;
|
||||||
|
final strings = AppLocalizations.of(context)!;
|
||||||
|
return DropdownButtonHideUnderline(
|
||||||
|
child: DropdownButton<String>(
|
||||||
|
value: locale,
|
||||||
|
icon: const Icon(Icons.language),
|
||||||
|
onChanged: (code) {
|
||||||
|
if (code != null) context.read<LocaleProvider>().setLocale(code);
|
||||||
|
},
|
||||||
|
items: [
|
||||||
|
DropdownMenuItem(value: 'en', child: Text(strings.english)),
|
||||||
|
DropdownMenuItem(value: 'hi', child: Text(strings.hindi)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import '../../../core/constants/ui_constants.dart';
|
import '../../../core/constants/ui_constants.dart';
|
||||||
|
import '../../../l10n/app_localizations.dart';
|
||||||
import '../../../utils/managers/user_manager.dart';
|
import '../../../utils/managers/user_manager.dart';
|
||||||
import '../../../view_model/profile/profile_view_model.dart';
|
import '../../../view_model/profile/profile_view_model.dart';
|
||||||
import '../buttons/modern_button.dart';
|
import '../buttons/modern_button.dart';
|
||||||
|
import '../language_switcher.dart';
|
||||||
|
|
||||||
class ModernDrawer extends StatelessWidget {
|
class ModernDrawer extends StatelessWidget {
|
||||||
final List<DrawerItem> items;
|
final List<DrawerItem> items;
|
||||||
@@ -52,6 +54,17 @@ class ModernDrawer extends StatelessWidget {
|
|||||||
// Footer
|
// Footer
|
||||||
if (footer != null) footer!,
|
if (footer != null) footer!,
|
||||||
|
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: UIConstants.spacing24),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(AppLocalizations.of(context)!.language),
|
||||||
|
const LanguageSwitcher(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
// Logout Section
|
// Logout Section
|
||||||
_buildLogoutSection(context, theme, colorScheme),
|
_buildLogoutSection(context, theme, colorScheme),
|
||||||
],
|
],
|
||||||
@@ -122,7 +135,8 @@ class ModernDrawer extends StatelessWidget {
|
|||||||
|
|
||||||
// User Name
|
// User Name
|
||||||
Text(
|
Text(
|
||||||
"Hello, ${userName ?? 'User'}",
|
AppLocalizations.of(context)!
|
||||||
|
.helloUser(userName ?? AppLocalizations.of(context)!.user),
|
||||||
style: theme.textTheme.titleLarge?.copyWith(
|
style: theme.textTheme.titleLarge?.copyWith(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@@ -216,7 +230,7 @@ class ModernDrawer extends StatelessWidget {
|
|||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.all(UIConstants.spacing24),
|
padding: const EdgeInsets.all(UIConstants.spacing24),
|
||||||
child: ModernButton(
|
child: ModernButton(
|
||||||
text: 'Logout',
|
text: AppLocalizations.of(context)!.logout,
|
||||||
type: ModernButtonType.danger,
|
type: ModernButtonType.danger,
|
||||||
size: ModernButtonSize.medium,
|
size: ModernButtonSize.medium,
|
||||||
icon: Icon(Icons.logout),
|
icon: Icon(Icons.logout),
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import '../../core/constants/ui_constants.dart';
|
import '../../core/constants/ui_constants.dart';
|
||||||
import '../../core/providers/dynamic_theme_provider.dart';
|
import '../../core/providers/dynamic_theme_provider.dart';
|
||||||
|
import '../../l10n/app_localizations.dart';
|
||||||
|
|
||||||
class ThemePreview extends StatelessWidget {
|
class ThemePreview extends StatelessWidget {
|
||||||
const ThemePreview({super.key});
|
const ThemePreview({super.key});
|
||||||
@@ -56,7 +57,7 @@ class ThemePreview extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Dynamic Theme Generated',
|
AppLocalizations.of(context)!.themeGenerated,
|
||||||
style:
|
style:
|
||||||
Theme.of(context).textTheme.titleLarge?.copyWith(
|
Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||||
color: colorScheme.onSurface,
|
color: colorScheme.onSurface,
|
||||||
@@ -79,7 +80,8 @@ class ThemePreview extends StatelessWidget {
|
|||||||
Icons.refresh,
|
Icons.refresh,
|
||||||
color: colorScheme.primary,
|
color: colorScheme.primary,
|
||||||
),
|
),
|
||||||
tooltip: 'Reset to Default Theme',
|
tooltip: AppLocalizations.of(context)!
|
||||||
|
.resetThemeTooltip,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -88,7 +90,7 @@ class ThemePreview extends StatelessWidget {
|
|||||||
|
|
||||||
// Color Palette
|
// Color Palette
|
||||||
Text(
|
Text(
|
||||||
'Color Palette',
|
AppLocalizations.of(context)!.colorPalette,
|
||||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||||
color: colorScheme.onSurface,
|
color: colorScheme.onSurface,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@@ -103,11 +105,11 @@ class ThemePreview extends StatelessWidget {
|
|||||||
children: logoColors.take(5).map((color) {
|
children: logoColors.take(5).map((color) {
|
||||||
final index = logoColors.indexOf(color);
|
final index = logoColors.indexOf(color);
|
||||||
final labels = [
|
final labels = [
|
||||||
'Primary',
|
AppLocalizations.of(context)!.colorPrimary,
|
||||||
'Secondary',
|
AppLocalizations.of(context)!.colorSecondary,
|
||||||
'Tertiary',
|
AppLocalizations.of(context)!.colorTertiary,
|
||||||
'Accent 1',
|
AppLocalizations.of(context)!.colorAccent1,
|
||||||
'Accent 2'
|
AppLocalizations.of(context)!.colorAccent2
|
||||||
];
|
];
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
@@ -142,7 +144,8 @@ class ThemePreview extends StatelessWidget {
|
|||||||
Text(
|
Text(
|
||||||
index < labels.length
|
index < labels.length
|
||||||
? labels[index]
|
? labels[index]
|
||||||
: 'Color ${index + 1}',
|
: AppLocalizations.of(context)!
|
||||||
|
.colorN((index + 1).toString()),
|
||||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||||
color: colorScheme.onSurfaceVariant,
|
color: colorScheme.onSurfaceVariant,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@@ -169,7 +172,7 @@ class ThemePreview extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Theme Information',
|
AppLocalizations.of(context)!.themeInfo,
|
||||||
style: Theme.of(context).textTheme.titleSmall?.copyWith(
|
style: Theme.of(context).textTheme.titleSmall?.copyWith(
|
||||||
color: colorScheme.onSurface,
|
color: colorScheme.onSurface,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@@ -177,24 +180,27 @@ class ThemePreview extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: UIConstants.spacing8),
|
const SizedBox(height: UIConstants.spacing8),
|
||||||
_buildInfoRow(
|
_buildInfoRow(
|
||||||
'Total Colors', '${paletteInfo['totalColors']}'),
|
AppLocalizations.of(context)!.totalColors,
|
||||||
_buildInfoRow('Description', paletteInfo['description']),
|
'${paletteInfo['totalColors']}'),
|
||||||
|
_buildInfoRow(
|
||||||
|
AppLocalizations.of(context)!.themeDescription,
|
||||||
|
paletteInfo['description']),
|
||||||
if (paletteInfo['characteristics'] != null) ...[
|
if (paletteInfo['characteristics'] != null) ...[
|
||||||
_buildInfoRow(
|
_buildInfoRow(
|
||||||
'Warm Colors',
|
AppLocalizations.of(context)!.warmColors,
|
||||||
paletteInfo['characteristics']['warm']
|
paletteInfo['characteristics']['warm']
|
||||||
? 'Yes'
|
? AppLocalizations.of(context)!.yes
|
||||||
: 'No'),
|
: AppLocalizations.of(context)!.no),
|
||||||
_buildInfoRow(
|
_buildInfoRow(
|
||||||
'Cool Colors',
|
AppLocalizations.of(context)!.coolColors,
|
||||||
paletteInfo['characteristics']['cool']
|
paletteInfo['characteristics']['cool']
|
||||||
? 'Yes'
|
? AppLocalizations.of(context)!.yes
|
||||||
: 'No'),
|
: AppLocalizations.of(context)!.no),
|
||||||
_buildInfoRow(
|
_buildInfoRow(
|
||||||
'Neutral Colors',
|
AppLocalizations.of(context)!.neutralColors,
|
||||||
paletteInfo['characteristics']['neutral']
|
paletteInfo['characteristics']['neutral']
|
||||||
? 'Yes'
|
? AppLocalizations.of(context)!.yes
|
||||||
: 'No'),
|
: AppLocalizations.of(context)!.no),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -216,7 +222,8 @@ class ThemePreview extends StatelessWidget {
|
|||||||
BorderRadius.circular(UIConstants.radius12),
|
BorderRadius.circular(UIConstants.radius12),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: const Text('Primary Button'),
|
child: Text(AppLocalizations.of(context)!
|
||||||
|
.primaryButton),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: UIConstants.spacing12),
|
const SizedBox(width: UIConstants.spacing12),
|
||||||
@@ -231,7 +238,8 @@ class ThemePreview extends StatelessWidget {
|
|||||||
BorderRadius.circular(UIConstants.radius12),
|
BorderRadius.circular(UIConstants.radius12),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: const Text('Secondary Button'),
|
child: Text(AppLocalizations.of(context)!
|
||||||
|
.secondaryButton),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import 'package:base_project/commans/widgets/custom_textform_field.dart';
|
|||||||
import 'package:base_project/commans/widgets/custome_elevated_button.dart';
|
import 'package:base_project/commans/widgets/custome_elevated_button.dart';
|
||||||
import 'package:base_project/core/constants/ui_constants.dart';
|
import 'package:base_project/core/constants/ui_constants.dart';
|
||||||
import 'package:base_project/core/providers/dynamic_theme_provider.dart';
|
import 'package:base_project/core/providers/dynamic_theme_provider.dart';
|
||||||
|
import 'package:base_project/l10n/app_localizations.dart';
|
||||||
import 'package:base_project/utils/validator/text_feild_validator.dart';
|
import 'package:base_project/utils/validator/text_feild_validator.dart';
|
||||||
import 'package:base_project/view/auth/sign_up_view.dart';
|
import 'package:base_project/view/auth/sign_up_view.dart';
|
||||||
import 'package:base_project/view_model/auth/auth_view_model.dart';
|
import 'package:base_project/view_model/auth/auth_view_model.dart';
|
||||||
@@ -231,7 +232,8 @@ class _AdminRegViewState extends State<AdminRegView>
|
|||||||
builder: (context, provider, child) {
|
builder: (context, provider, child) {
|
||||||
return MyCustomElevatedButton(
|
return MyCustomElevatedButton(
|
||||||
isLoading: provider.isLoading,
|
isLoading: provider.isLoading,
|
||||||
child: const Text("Register Company"),
|
child: Text(AppLocalizations.of(context)!
|
||||||
|
.registerCompany),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
if (_formKey.currentState!.validate()) {
|
if (_formKey.currentState!.validate()) {
|
||||||
final Map<String, dynamic> signUpData = {
|
final Map<String, dynamic> signUpData = {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
import '../../l10n/app_localizations.dart';
|
||||||
|
|
||||||
class GetOtpView extends StatefulWidget {
|
class GetOtpView extends StatefulWidget {
|
||||||
const GetOtpView({super.key});
|
const GetOtpView({super.key});
|
||||||
@@ -483,7 +484,7 @@ class _GetOtpViewState extends State<GetOtpView> with TickerProviderStateMixin {
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Get OTP',
|
AppLocalizations.of(context)!.getOtp,
|
||||||
style: Theme.of(context).textTheme.headlineMedium?.copyWith(
|
style: Theme.of(context).textTheme.headlineMedium?.copyWith(
|
||||||
color: colorScheme.primary,
|
color: colorScheme.primary,
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
@@ -493,7 +494,7 @@ class _GetOtpViewState extends State<GetOtpView> with TickerProviderStateMixin {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: UIConstants.spacing12),
|
const SizedBox(height: UIConstants.spacing12),
|
||||||
Text(
|
Text(
|
||||||
'Enter your email to receive a one-time password',
|
AppLocalizations.of(context)!.otpEmailPrompt,
|
||||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||||
color: colorScheme.onSurface.withOpacity(0.8),
|
color: colorScheme.onSurface.withOpacity(0.8),
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
@@ -543,8 +544,8 @@ class _GetOtpViewState extends State<GetOtpView> with TickerProviderStateMixin {
|
|||||||
children: [
|
children: [
|
||||||
// Email Field
|
// Email Field
|
||||||
_buildEnhancedTextField(
|
_buildEnhancedTextField(
|
||||||
label: 'Email Address',
|
label: AppLocalizations.of(context)!.emailAddress,
|
||||||
hint: 'Enter your email address',
|
hint: AppLocalizations.of(context)!.enterEmailAddress,
|
||||||
controller: _emailController,
|
controller: _emailController,
|
||||||
focusNode: _emailFocusNode,
|
focusNode: _emailFocusNode,
|
||||||
keyboardType: TextInputType.emailAddress,
|
keyboardType: TextInputType.emailAddress,
|
||||||
@@ -554,12 +555,12 @@ class _GetOtpViewState extends State<GetOtpView> with TickerProviderStateMixin {
|
|||||||
textInputAction: TextInputAction.done,
|
textInputAction: TextInputAction.done,
|
||||||
validator: (value) {
|
validator: (value) {
|
||||||
if (value == null || value.isEmpty) {
|
if (value == null || value.isEmpty) {
|
||||||
return 'Email is required';
|
return AppLocalizations.of(context)!.emailRequired;
|
||||||
}
|
}
|
||||||
if (!RegExp(
|
if (!RegExp(
|
||||||
r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$')
|
r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$')
|
||||||
.hasMatch(value)) {
|
.hasMatch(value)) {
|
||||||
return 'Please enter a valid email';
|
return AppLocalizations.of(context)!.validEmail;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
@@ -847,7 +848,9 @@ class _GetOtpViewState extends State<GetOtpView> with TickerProviderStateMixin {
|
|||||||
) ??
|
) ??
|
||||||
const TextStyle(),
|
const TextStyle(),
|
||||||
child: Text(
|
child: Text(
|
||||||
isLoading ? 'Sending OTP...' : 'Send OTP',
|
isLoading
|
||||||
|
? AppLocalizations.of(context)!.sendingOtp
|
||||||
|
: AppLocalizations.of(context)!.sendOtp,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -919,7 +922,7 @@ class _GetOtpViewState extends State<GetOtpView> with TickerProviderStateMixin {
|
|||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Already have an account? ",
|
'${AppLocalizations.of(context)!.alreadyHaveAccount} ',
|
||||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||||
color: Colors.grey.shade700,
|
color: Colors.grey.shade700,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@@ -928,7 +931,7 @@ class _GetOtpViewState extends State<GetOtpView> with TickerProviderStateMixin {
|
|||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context),
|
onPressed: () => Navigator.pop(context),
|
||||||
child: Text(
|
child: Text(
|
||||||
'Back to Login',
|
AppLocalizations.of(context)!.backToLogin,
|
||||||
style: Theme.of(context).textTheme.labelLarge?.copyWith(
|
style: Theme.of(context).textTheme.labelLarge?.copyWith(
|
||||||
color: colorScheme.primary,
|
color: colorScheme.primary,
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
@@ -982,8 +985,10 @@ class _GetOtpViewState extends State<GetOtpView> with TickerProviderStateMixin {
|
|||||||
? Icons.info_outline
|
? Icons.info_outline
|
||||||
: (_isEmailValid ? Icons.check_circle : Icons.error_outline);
|
: (_isEmailValid ? Icons.check_circle : Icons.error_outline);
|
||||||
final msg = _emailController.text.isEmpty
|
final msg = _emailController.text.isEmpty
|
||||||
? 'Enter your email address'
|
? AppLocalizations.of(context)!.enterEmailAddress
|
||||||
: (_isEmailValid ? 'Email looks good' : 'Invalid email address');
|
: (_isEmailValid
|
||||||
|
? AppLocalizations.of(context)!.emailLooksGood
|
||||||
|
: AppLocalizations.of(context)!.invalidEmailAddress);
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
width: UIConstants.getResponsiveValue(
|
width: UIConstants.getResponsiveValue(
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import 'package:base_project/routes/route_names.dart';
|
|||||||
import 'package:base_project/view_model/auth/auth_view_model.dart';
|
import 'package:base_project/view_model/auth/auth_view_model.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import '../../l10n/app_localizations.dart';
|
||||||
|
|
||||||
import '../../core/providers/dynamic_theme_provider.dart';
|
import '../../core/providers/dynamic_theme_provider.dart';
|
||||||
import '../../core/providers/theme_provider.dart';
|
import '../../core/providers/theme_provider.dart';
|
||||||
@@ -497,7 +498,7 @@ class _LoginViewState extends State<LoginView> with TickerProviderStateMixin {
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Welcome Back!',
|
AppLocalizations.of(context)!.welcomeBack,
|
||||||
style: Theme.of(context).textTheme.headlineMedium?.copyWith(
|
style: Theme.of(context).textTheme.headlineMedium?.copyWith(
|
||||||
color: colorScheme.primary,
|
color: colorScheme.primary,
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
@@ -507,7 +508,7 @@ class _LoginViewState extends State<LoginView> with TickerProviderStateMixin {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: UIConstants.spacing12),
|
const SizedBox(height: UIConstants.spacing12),
|
||||||
Text(
|
Text(
|
||||||
'Sign in to continue to your account',
|
AppLocalizations.of(context)!.signInToContinue,
|
||||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||||
color: colorScheme.onSurface.withOpacity(0.8),
|
color: colorScheme.onSurface.withOpacity(0.8),
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
@@ -557,8 +558,8 @@ class _LoginViewState extends State<LoginView> with TickerProviderStateMixin {
|
|||||||
children: [
|
children: [
|
||||||
// Email Field
|
// Email Field
|
||||||
_buildEnhancedTextField(
|
_buildEnhancedTextField(
|
||||||
label: 'Email Address',
|
label: AppLocalizations.of(context)!.emailAddress,
|
||||||
hint: 'Enter your email',
|
hint: AppLocalizations.of(context)!.enterYourEmail,
|
||||||
controller: _emailController,
|
controller: _emailController,
|
||||||
focusNode: _emailFocusNode,
|
focusNode: _emailFocusNode,
|
||||||
keyboardType: TextInputType.emailAddress,
|
keyboardType: TextInputType.emailAddress,
|
||||||
@@ -569,11 +570,11 @@ class _LoginViewState extends State<LoginView> with TickerProviderStateMixin {
|
|||||||
onSubmitted: (_) => _passwordFocusNode.requestFocus(),
|
onSubmitted: (_) => _passwordFocusNode.requestFocus(),
|
||||||
validator: (value) {
|
validator: (value) {
|
||||||
if (value == null || value.isEmpty) {
|
if (value == null || value.isEmpty) {
|
||||||
return 'Email is required';
|
return AppLocalizations.of(context)!.emailRequired;
|
||||||
}
|
}
|
||||||
if (!RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$')
|
if (!RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$')
|
||||||
.hasMatch(value)) {
|
.hasMatch(value)) {
|
||||||
return 'Please enter a valid email';
|
return AppLocalizations.of(context)!.validEmail;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
@@ -583,8 +584,8 @@ class _LoginViewState extends State<LoginView> with TickerProviderStateMixin {
|
|||||||
|
|
||||||
// Password Field
|
// Password Field
|
||||||
_buildEnhancedTextField(
|
_buildEnhancedTextField(
|
||||||
label: 'Password',
|
label: AppLocalizations.of(context)!.password,
|
||||||
hint: 'Enter your password',
|
hint: AppLocalizations.of(context)!.enterYourPassword,
|
||||||
controller: _passwordController,
|
controller: _passwordController,
|
||||||
focusNode: _passwordFocusNode,
|
focusNode: _passwordFocusNode,
|
||||||
obscureText: !_isPasswordVisible,
|
obscureText: !_isPasswordVisible,
|
||||||
@@ -607,10 +608,10 @@ class _LoginViewState extends State<LoginView> with TickerProviderStateMixin {
|
|||||||
textInputAction: TextInputAction.done,
|
textInputAction: TextInputAction.done,
|
||||||
validator: (value) {
|
validator: (value) {
|
||||||
if (value == null || value.isEmpty) {
|
if (value == null || value.isEmpty) {
|
||||||
return 'Password is required';
|
return AppLocalizations.of(context)!.passwordRequired;
|
||||||
}
|
}
|
||||||
if (value.length < 6) {
|
if (value.length < 6) {
|
||||||
return 'Password must be at least 6 characters';
|
return AppLocalizations.of(context)!.passwordMinLength;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
@@ -727,7 +728,7 @@ class _LoginViewState extends State<LoginView> with TickerProviderStateMixin {
|
|||||||
),
|
),
|
||||||
const SizedBox(width: UIConstants.spacing6),
|
const SizedBox(width: UIConstants.spacing6),
|
||||||
Text(
|
Text(
|
||||||
'Forgot Password?',
|
AppLocalizations.of(context)!.forgotPassword,
|
||||||
style: Theme.of(context).textTheme.labelSmall?.copyWith(
|
style: Theme.of(context).textTheme.labelSmall?.copyWith(
|
||||||
color: colorScheme.primary,
|
color: colorScheme.primary,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@@ -771,7 +772,7 @@ class _LoginViewState extends State<LoginView> with TickerProviderStateMixin {
|
|||||||
child: Consumer<AuthViewModel>(
|
child: Consumer<AuthViewModel>(
|
||||||
builder: (context, provider, child) {
|
builder: (context, provider, child) {
|
||||||
return ModernButton(
|
return ModernButton(
|
||||||
text: 'Sign In',
|
text: AppLocalizations.of(context)!.signIn,
|
||||||
type: ModernButtonType.primary,
|
type: ModernButtonType.primary,
|
||||||
size: ModernButtonSize.large,
|
size: ModernButtonSize.large,
|
||||||
isLoading: provider.isLoading,
|
isLoading: provider.isLoading,
|
||||||
@@ -823,7 +824,7 @@ class _LoginViewState extends State<LoginView> with TickerProviderStateMixin {
|
|||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Don't have an account? ",
|
'${AppLocalizations.of(context)!.noAccount} ',
|
||||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||||
color: Colors.grey.shade700,
|
color: Colors.grey.shade700,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@@ -834,7 +835,7 @@ class _LoginViewState extends State<LoginView> with TickerProviderStateMixin {
|
|||||||
Navigator.pushNamed(context, RouteNames.getOtpView);
|
Navigator.pushNamed(context, RouteNames.getOtpView);
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
'Sign Up',
|
AppLocalizations.of(context)!.signUp,
|
||||||
style: Theme.of(context).textTheme.labelLarge?.copyWith(
|
style: Theme.of(context).textTheme.labelLarge?.copyWith(
|
||||||
color: colorScheme.primary,
|
color: colorScheme.primary,
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
@@ -870,7 +871,7 @@ class _LoginViewState extends State<LoginView> with TickerProviderStateMixin {
|
|||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
horizontal: UIConstants.spacing16),
|
horizontal: UIConstants.spacing16),
|
||||||
child: Text(
|
child: Text(
|
||||||
'Or continue with',
|
AppLocalizations.of(context)!.orContinueWith,
|
||||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||||
color: Colors.white.withOpacity(0.9),
|
color: Colors.white.withOpacity(0.9),
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'package:base_project/core/constants/ui_constants.dart';
|
import 'package:base_project/core/constants/ui_constants.dart';
|
||||||
import 'package:base_project/core/providers/dynamic_theme_provider.dart';
|
import 'package:base_project/core/providers/dynamic_theme_provider.dart';
|
||||||
|
import 'package:base_project/l10n/app_localizations.dart';
|
||||||
import 'package:base_project/routes/route_names.dart';
|
import 'package:base_project/routes/route_names.dart';
|
||||||
import 'package:base_project/shared/widgets/app_bar/modern_app_bar.dart';
|
import 'package:base_project/shared/widgets/app_bar/modern_app_bar.dart';
|
||||||
import 'package:base_project/shared/widgets/buttons/modern_button.dart';
|
import 'package:base_project/shared/widgets/buttons/modern_button.dart';
|
||||||
@@ -322,7 +323,7 @@ class _SignUpViewState extends State<SignUpView> with TickerProviderStateMixin {
|
|||||||
Consumer<AuthViewModel>(
|
Consumer<AuthViewModel>(
|
||||||
builder: (context, provider, child) {
|
builder: (context, provider, child) {
|
||||||
return ModernButton(
|
return ModernButton(
|
||||||
text: 'Sign Up',
|
text: AppLocalizations.of(context)!.signUp,
|
||||||
type: ModernButtonType.primary,
|
type: ModernButtonType.primary,
|
||||||
size: ModernButtonSize.large,
|
size: ModernButtonSize.large,
|
||||||
isLoading: provider.isLoading,
|
isLoading: provider.isLoading,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:base_project/l10n/app_localizations.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class SignupView extends StatelessWidget {
|
class SignupView extends StatelessWidget {
|
||||||
@@ -14,7 +15,7 @@ class SignupView extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
icon: Icon(Icons.adaptive.arrow_back),
|
icon: Icon(Icons.adaptive.arrow_back),
|
||||||
),
|
),
|
||||||
title: const Text("SignUp"),
|
title: Text(AppLocalizations.of(context)!.signUp),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:pinput/pinput.dart';
|
import 'package:pinput/pinput.dart';
|
||||||
import 'package:base_project/commans/widgets/custome_elevated_button.dart';
|
import 'package:base_project/commans/widgets/custome_elevated_button.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import '../../l10n/app_localizations.dart';
|
||||||
import 'package:base_project/core/constants/ui_constants.dart';
|
import 'package:base_project/core/constants/ui_constants.dart';
|
||||||
import 'package:base_project/core/providers/dynamic_theme_provider.dart';
|
import 'package:base_project/core/providers/dynamic_theme_provider.dart';
|
||||||
|
|
||||||
@@ -83,7 +84,7 @@ class _VerifyOtpViewState extends State<VerifyOtpView>
|
|||||||
color: colorScheme.primary,
|
color: colorScheme.primary,
|
||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
'Verify OTP',
|
AppLocalizations.of(context)!.verifyOtp,
|
||||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||||
color: colorScheme.primary,
|
color: colorScheme.primary,
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
@@ -147,7 +148,7 @@ class _VerifyOtpViewState extends State<VerifyOtpView>
|
|||||||
),
|
),
|
||||||
const SizedBox(height: UIConstants.spacing16),
|
const SizedBox(height: UIConstants.spacing16),
|
||||||
Text(
|
Text(
|
||||||
'Enter the 6-digit code sent to',
|
AppLocalizations.of(context)!.otpSentTo,
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.textTheme
|
.textTheme
|
||||||
.bodyMedium
|
.bodyMedium
|
||||||
@@ -157,7 +158,7 @@ class _VerifyOtpViewState extends State<VerifyOtpView>
|
|||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
widget.email ?? 'your email',
|
widget.email ?? AppLocalizations.of(context)!.yourEmail,
|
||||||
style:
|
style:
|
||||||
Theme.of(context).textTheme.titleMedium?.copyWith(
|
Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||||
color: colorScheme.primary,
|
color: colorScheme.primary,
|
||||||
@@ -233,7 +234,7 @@ class _VerifyOtpViewState extends State<VerifyOtpView>
|
|||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
if (_otpController.text.length < 6) {
|
if (_otpController.text.length < 6) {
|
||||||
ToastMessageUtil.showToast(
|
ToastMessageUtil.showToast(
|
||||||
message: 'Enter 6-digit OTP',
|
message: AppLocalizations.of(context)!.enterOtp,
|
||||||
toastType: ToastType.error,
|
toastType: ToastType.error,
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
@@ -268,7 +269,7 @@ class _VerifyOtpViewState extends State<VerifyOtpView>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: const Text('Verify OTP'),
|
child: Text(AppLocalizations.of(context)!.verifyOtp),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@@ -285,8 +286,9 @@ class _VerifyOtpViewState extends State<VerifyOtpView>
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
provider.isResendEnabled
|
provider.isResendEnabled
|
||||||
? "Didn't receive code?"
|
? AppLocalizations.of(context)!.didNotReceiveCode
|
||||||
: 'Resend in ${provider.start}s',
|
: AppLocalizations.of(context)!
|
||||||
|
.resendIn(provider.start),
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.textTheme
|
.textTheme
|
||||||
.bodyMedium
|
.bodyMedium
|
||||||
@@ -304,7 +306,7 @@ class _VerifyOtpViewState extends State<VerifyOtpView>
|
|||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
child: Text(
|
child: Text(
|
||||||
'Resend',
|
AppLocalizations.of(context)!.resend,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: provider.isResendEnabled
|
color: provider.isResendEnabled
|
||||||
? colorScheme.primary
|
? colorScheme.primary
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import 'package:base_project/utils/managers/user_manager.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:base_project/view_model/system_params/system_params_view_model.dart';
|
import 'package:base_project/view_model/system_params/system_params_view_model.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import '../../l10n/app_localizations.dart';
|
||||||
|
|
||||||
class HomeView extends StatefulWidget {
|
class HomeView extends StatefulWidget {
|
||||||
const HomeView({super.key});
|
const HomeView({super.key});
|
||||||
@@ -32,54 +33,54 @@ class _HomeViewState extends State<HomeView> with TickerProviderStateMixin {
|
|||||||
// Dashboard stats (replace with real API data)
|
// Dashboard stats (replace with real API data)
|
||||||
List<Map<String, dynamic>> _dashboardStats = [];
|
List<Map<String, dynamic>> _dashboardStats = [];
|
||||||
|
|
||||||
final List<Map<String, dynamic>> _quickActions = [
|
List<Map<String, dynamic>> _quickActions(BuildContext context) => [
|
||||||
{
|
{
|
||||||
'label': 'Profile',
|
'label': AppLocalizations.of(context)!.profile,
|
||||||
'icon': Icons.person,
|
'icon': Icons.person,
|
||||||
'onTap': () {},
|
'onTap': () {},
|
||||||
'backgroundColor': null, // Use theme default
|
'backgroundColor': null, // Use theme default
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'label': 'Settings',
|
'label': AppLocalizations.of(context)!.settings,
|
||||||
'icon': Icons.settings,
|
'icon': Icons.settings,
|
||||||
'onTap': () {},
|
'onTap': () {},
|
||||||
'backgroundColor': null,
|
'backgroundColor': null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'label': 'Security',
|
'label': AppLocalizations.of(context)!.security,
|
||||||
'icon': Icons.security,
|
'icon': Icons.security,
|
||||||
'onTap': () {},
|
'onTap': () {},
|
||||||
'backgroundColor': null,
|
'backgroundColor': null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'label': 'Reports',
|
'label': AppLocalizations.of(context)!.reports,
|
||||||
'icon': Icons.analytics,
|
'icon': Icons.analytics,
|
||||||
'onTap': () {},
|
'onTap': () {},
|
||||||
'backgroundColor': null,
|
'backgroundColor': null,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
final List<DrawerItem> _drawerItems = [
|
List<DrawerItem> _drawerItems(BuildContext context) => [
|
||||||
DrawerItem(
|
DrawerItem(
|
||||||
icon: Icons.person,
|
icon: Icons.person,
|
||||||
title: 'Profile',
|
title: AppLocalizations.of(context)!.profile,
|
||||||
subtitle: 'Manage your account',
|
subtitle: AppLocalizations.of(context)!.manageAccount,
|
||||||
onTap: (context) {
|
onTap: (context) {
|
||||||
Navigator.pushNamed(context, RouteNames.profileView);
|
Navigator.pushNamed(context, RouteNames.profileView);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
DrawerItem(
|
DrawerItem(
|
||||||
icon: Icons.system_security_update,
|
icon: Icons.system_security_update,
|
||||||
title: 'System Parameters',
|
title: AppLocalizations.of(context)!.systemParameters,
|
||||||
subtitle: 'Configure system settings',
|
subtitle: AppLocalizations.of(context)!.configureSystemSettings,
|
||||||
onTap: (context) {
|
onTap: (context) {
|
||||||
Navigator.pushNamed(context, RouteNames.systemParamsView);
|
Navigator.pushNamed(context, RouteNames.systemParamsView);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
DrawerItem(
|
DrawerItem(
|
||||||
icon: Icons.password,
|
icon: Icons.password,
|
||||||
title: 'Change Password',
|
title: AppLocalizations.of(context)!.changePassword,
|
||||||
subtitle: 'Update your password',
|
subtitle: AppLocalizations.of(context)!.updateYourPassword,
|
||||||
onTap: (context) {
|
onTap: (context) {
|
||||||
Navigator.pushNamed(context, RouteNames.changePasswordView);
|
Navigator.pushNamed(context, RouteNames.changePasswordView);
|
||||||
},
|
},
|
||||||
@@ -226,7 +227,7 @@ class _HomeViewState extends State<HomeView> with TickerProviderStateMixin {
|
|||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: colorScheme.background,
|
backgroundColor: colorScheme.background,
|
||||||
appBar: ModernAppBar(
|
appBar: ModernAppBar(
|
||||||
title: 'Dashboard',
|
title: AppLocalizations.of(context)!.dashboard,
|
||||||
centerTitle: false,
|
centerTitle: false,
|
||||||
showLogoInTitle: true,
|
showLogoInTitle: true,
|
||||||
logoImage: _getDashboardLogoImage(colorScheme),
|
logoImage: _getDashboardLogoImage(colorScheme),
|
||||||
@@ -237,7 +238,7 @@ class _HomeViewState extends State<HomeView> with TickerProviderStateMixin {
|
|||||||
Navigator.pushNamed(context, RouteNames.profileView);
|
Navigator.pushNamed(context, RouteNames.profileView);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
drawer: ModernDrawer(items: _drawerItems),
|
drawer: ModernDrawer(items: _drawerItems(context)),
|
||||||
body: Container(
|
body: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
@@ -339,7 +340,8 @@ class _HomeViewState extends State<HomeView> with TickerProviderStateMixin {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Welcome back, ${userName ?? 'User'}! ð',
|
AppLocalizations.of(context)!
|
||||||
|
.helloUser(userName ?? AppLocalizations.of(context)!.user),
|
||||||
style: theme.textTheme.headlineMedium?.copyWith(
|
style: theme.textTheme.headlineMedium?.copyWith(
|
||||||
color: colorScheme.onBackground,
|
color: colorScheme.onBackground,
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
@@ -468,9 +470,9 @@ class _HomeViewState extends State<HomeView> with TickerProviderStateMixin {
|
|||||||
mainAxisSpacing: UIConstants.spacing16,
|
mainAxisSpacing: UIConstants.spacing16,
|
||||||
childAspectRatio: 1.0,
|
childAspectRatio: 1.0,
|
||||||
),
|
),
|
||||||
itemCount: _quickActions.length,
|
itemCount: _quickActions(context).length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final action = _quickActions[index];
|
final action = _quickActions(context)[index];
|
||||||
return QuickActionButton(
|
return QuickActionButton(
|
||||||
label: action['label'],
|
label: action['label'],
|
||||||
icon: action['icon'],
|
icon: action['icon'],
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'package:base_project/core/constants/ui_constants.dart';
|
import 'package:base_project/core/constants/ui_constants.dart';
|
||||||
import 'package:base_project/core/providers/dynamic_theme_provider.dart';
|
import 'package:base_project/core/providers/dynamic_theme_provider.dart';
|
||||||
|
import 'package:base_project/l10n/app_localizations.dart';
|
||||||
import 'package:base_project/shared/widgets/app_bar/modern_app_bar.dart';
|
import 'package:base_project/shared/widgets/app_bar/modern_app_bar.dart';
|
||||||
import 'package:base_project/shared/widgets/inputs/modern_text_field.dart';
|
import 'package:base_project/shared/widgets/inputs/modern_text_field.dart';
|
||||||
import 'package:base_project/shared/widgets/buttons/modern_button.dart';
|
import 'package:base_project/shared/widgets/buttons/modern_button.dart';
|
||||||
@@ -160,33 +161,37 @@ class _AccountUpdateViewState extends State<AccountUpdateView>
|
|||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
ModernTextField(
|
ModernTextField(
|
||||||
label: 'Company Name',
|
label: AppLocalizations.of(context)!.accCompanyName,
|
||||||
hint: 'Enter company name',
|
hint: AppLocalizations.of(context)!.accCompanyHint,
|
||||||
controller: _companyName,
|
controller: _companyName,
|
||||||
prefixIcon: const Icon(Icons.business),
|
prefixIcon: const Icon(Icons.business),
|
||||||
validator: (v) =>
|
validator: (v) =>
|
||||||
(v == null || v.isEmpty) ? 'Required' : null,
|
(v == null || v.isEmpty)
|
||||||
|
? AppLocalizations.of(context)!.requiredVal
|
||||||
|
: null,
|
||||||
),
|
),
|
||||||
SizedBox(height: UIConstants.spacing20),
|
SizedBox(height: UIConstants.spacing20),
|
||||||
ModernTextField(
|
ModernTextField(
|
||||||
label: 'Workspace',
|
label: AppLocalizations.of(context)!.accWorkspace,
|
||||||
hint: 'Enter workspace',
|
hint: AppLocalizations.of(context)!.accWorkspaceHint,
|
||||||
controller: _workspace,
|
controller: _workspace,
|
||||||
prefixIcon: const Icon(Icons.apartment_outlined),
|
prefixIcon: const Icon(Icons.apartment_outlined),
|
||||||
validator: (v) =>
|
validator: (v) =>
|
||||||
(v == null || v.isEmpty) ? 'Required' : null,
|
(v == null || v.isEmpty)
|
||||||
|
? AppLocalizations.of(context)!.requiredVal
|
||||||
|
: null,
|
||||||
),
|
),
|
||||||
SizedBox(height: UIConstants.spacing20),
|
SizedBox(height: UIConstants.spacing20),
|
||||||
ModernTextField(
|
ModernTextField(
|
||||||
label: 'GST Number',
|
label: AppLocalizations.of(context)!.accGst,
|
||||||
hint: 'Enter GST number',
|
hint: AppLocalizations.of(context)!.accGstHint,
|
||||||
controller: _gstNumber,
|
controller: _gstNumber,
|
||||||
prefixIcon: const Icon(Icons.confirmation_number_outlined),
|
prefixIcon: const Icon(Icons.confirmation_number_outlined),
|
||||||
),
|
),
|
||||||
SizedBox(height: UIConstants.spacing20),
|
SizedBox(height: UIConstants.spacing20),
|
||||||
ModernTextField(
|
ModernTextField(
|
||||||
label: 'Mobile',
|
label: AppLocalizations.of(context)!.accMobile,
|
||||||
hint: 'Enter mobile number',
|
hint: AppLocalizations.of(context)!.accMobileHint,
|
||||||
controller: _mobile,
|
controller: _mobile,
|
||||||
keyboardType: TextInputType.phone,
|
keyboardType: TextInputType.phone,
|
||||||
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
|
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
|
||||||
@@ -195,23 +200,23 @@ class _AccountUpdateViewState extends State<AccountUpdateView>
|
|||||||
SizedBox(height: UIConstants.spacing20),
|
SizedBox(height: UIConstants.spacing20),
|
||||||
AbsorbPointer(
|
AbsorbPointer(
|
||||||
child: ModernTextField(
|
child: ModernTextField(
|
||||||
label: 'Email (read-only)',
|
label: AppLocalizations.of(context)!.accEmailReadonly,
|
||||||
hint: 'Email',
|
hint: AppLocalizations.of(context)!.email,
|
||||||
controller: _email,
|
controller: _email,
|
||||||
prefixIcon: const Icon(Icons.email_outlined),
|
prefixIcon: const Icon(Icons.email_outlined),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: UIConstants.spacing20),
|
SizedBox(height: UIConstants.spacing20),
|
||||||
ModernTextField(
|
ModernTextField(
|
||||||
label: 'PAN Card',
|
label: AppLocalizations.of(context)!.accPan,
|
||||||
hint: 'Enter PAN',
|
hint: AppLocalizations.of(context)!.accPanHint,
|
||||||
controller: _pancard,
|
controller: _pancard,
|
||||||
prefixIcon: const Icon(Icons.badge_outlined),
|
prefixIcon: const Icon(Icons.badge_outlined),
|
||||||
),
|
),
|
||||||
SizedBox(height: UIConstants.spacing20),
|
SizedBox(height: UIConstants.spacing20),
|
||||||
ModernTextField(
|
ModernTextField(
|
||||||
label: 'Working',
|
label: AppLocalizations.of(context)!.accWorking,
|
||||||
hint: 'Working status',
|
hint: AppLocalizations.of(context)!.accWorkingHint,
|
||||||
controller: _working,
|
controller: _working,
|
||||||
prefixIcon: const Icon(Icons.work_outline),
|
prefixIcon: const Icon(Icons.work_outline),
|
||||||
),
|
),
|
||||||
@@ -223,7 +228,7 @@ class _AccountUpdateViewState extends State<AccountUpdateView>
|
|||||||
onChanged: (v) => setState(() => _active = v),
|
onChanged: (v) => setState(() => _active = v),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
const Text('Active')
|
Text(AppLocalizations.of(context)!.nActive)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
@@ -234,7 +239,7 @@ class _AccountUpdateViewState extends State<AccountUpdateView>
|
|||||||
desktop: UIConstants.spacing48,
|
desktop: UIConstants.spacing48,
|
||||||
)),
|
)),
|
||||||
ModernButton(
|
ModernButton(
|
||||||
text: 'Update Account',
|
text: AppLocalizations.of(context)!.accountUpdate,
|
||||||
type: ModernButtonType.primary,
|
type: ModernButtonType.primary,
|
||||||
size: ModernButtonSize.large,
|
size: ModernButtonSize.large,
|
||||||
isLoading: vm.isUpdating,
|
isLoading: vm.isUpdating,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'package:base_project/commans/widgets/custom_textform_field.dart';
|
import 'package:base_project/commans/widgets/custom_textform_field.dart';
|
||||||
import 'package:base_project/commans/widgets/custome_elevated_button.dart';
|
import 'package:base_project/commans/widgets/custome_elevated_button.dart';
|
||||||
|
import 'package:base_project/l10n/app_localizations.dart';
|
||||||
import 'package:base_project/resources/app_colors.dart';
|
import 'package:base_project/resources/app_colors.dart';
|
||||||
import 'package:base_project/utils/managers/user_manager.dart';
|
import 'package:base_project/utils/managers/user_manager.dart';
|
||||||
import 'package:base_project/utils/validator/text_feild_validator.dart';
|
import 'package:base_project/utils/validator/text_feild_validator.dart';
|
||||||
@@ -372,7 +373,7 @@ class _ChangePasswordState extends State<ChangePassword>
|
|||||||
Consumer<ProfileViewModel>(
|
Consumer<ProfileViewModel>(
|
||||||
builder: (context, provider, _) {
|
builder: (context, provider, _) {
|
||||||
return ModernButton(
|
return ModernButton(
|
||||||
text: 'Change Password',
|
text: AppLocalizations.of(context)!.changePassword,
|
||||||
type: ModernButtonType.primary,
|
type: ModernButtonType.primary,
|
||||||
size: ModernButtonSize.large,
|
size: ModernButtonSize.large,
|
||||||
isLoading: provider.isUpdating,
|
isLoading: provider.isUpdating,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'package:base_project/commans/widgets/custom_textform_field.dart';
|
import 'package:base_project/commans/widgets/custom_textform_field.dart';
|
||||||
import 'package:base_project/commans/widgets/custome_elevated_button.dart';
|
import 'package:base_project/commans/widgets/custome_elevated_button.dart';
|
||||||
|
import 'package:base_project/l10n/app_localizations.dart';
|
||||||
import 'package:base_project/model/user/user_profile.dart';
|
import 'package:base_project/model/user/user_profile.dart';
|
||||||
import 'package:base_project/resources/app_colors.dart';
|
import 'package:base_project/resources/app_colors.dart';
|
||||||
import 'package:base_project/view_model/profile/profile_view_model.dart';
|
import 'package:base_project/view_model/profile/profile_view_model.dart';
|
||||||
@@ -396,7 +397,7 @@ class _EditProfileState extends State<EditProfile>
|
|||||||
Consumer<ProfileViewModel>(
|
Consumer<ProfileViewModel>(
|
||||||
builder: (context, provider, _) {
|
builder: (context, provider, _) {
|
||||||
return ModernButton(
|
return ModernButton(
|
||||||
text: 'Save Changes',
|
text: AppLocalizations.of(context)!.saveChanges,
|
||||||
type: ModernButtonType.primary,
|
type: ModernButtonType.primary,
|
||||||
size: ModernButtonSize.large,
|
size: ModernButtonSize.large,
|
||||||
isLoading: provider.isUpdating,
|
isLoading: provider.isUpdating,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import 'package:base_project/utils/managers/user_manager.dart';
|
|||||||
import 'package:base_project/view/dashboard/profile/edit_profile.dart';
|
import 'package:base_project/view/dashboard/profile/edit_profile.dart';
|
||||||
import 'package:base_project/view_model/profile/profile_view_model.dart';
|
import 'package:base_project/view_model/profile/profile_view_model.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import '../../../l10n/app_localizations.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:base_project/core/providers/dynamic_theme_provider.dart';
|
import 'package:base_project/core/providers/dynamic_theme_provider.dart';
|
||||||
@@ -77,7 +78,7 @@ class _ProfileViewState extends State<ProfileView>
|
|||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: ModernAppBar(
|
appBar: ModernAppBar(
|
||||||
title: 'Profile',
|
title: AppLocalizations.of(context)!.profile,
|
||||||
automaticallyImplyLeading: true,
|
automaticallyImplyLeading: true,
|
||||||
leading: IconButton(
|
leading: IconButton(
|
||||||
icon: Icon(Icons.arrow_back),
|
icon: Icon(Icons.arrow_back),
|
||||||
@@ -393,7 +394,7 @@ class _ProfileViewState extends State<ProfileView>
|
|||||||
context,
|
context,
|
||||||
colorScheme: colorScheme,
|
colorScheme: colorScheme,
|
||||||
icon: Icons.edit_outlined,
|
icon: Icons.edit_outlined,
|
||||||
title: 'Edit Profile',
|
title: AppLocalizations.of(context)!.editProfile,
|
||||||
subtitle: 'Update your personal information',
|
subtitle: 'Update your personal information',
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
@@ -411,7 +412,7 @@ class _ProfileViewState extends State<ProfileView>
|
|||||||
context,
|
context,
|
||||||
colorScheme: colorScheme,
|
colorScheme: colorScheme,
|
||||||
icon: Icons.manage_accounts_outlined,
|
icon: Icons.manage_accounts_outlined,
|
||||||
title: 'Account Update',
|
title: AppLocalizations.of(context)!.accountUpdate,
|
||||||
subtitle: 'Update company/workspace details',
|
subtitle: 'Update company/workspace details',
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
@@ -427,7 +428,7 @@ class _ProfileViewState extends State<ProfileView>
|
|||||||
context,
|
context,
|
||||||
colorScheme: colorScheme,
|
colorScheme: colorScheme,
|
||||||
icon: Icons.lock_outline,
|
icon: Icons.lock_outline,
|
||||||
title: 'Change Password',
|
title: AppLocalizations.of(context)!.changePassword,
|
||||||
subtitle: 'Update your account security',
|
subtitle: 'Update your account security',
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.pushNamed(context, RouteNames.changePasswordView);
|
Navigator.pushNamed(context, RouteNames.changePasswordView);
|
||||||
@@ -438,7 +439,7 @@ class _ProfileViewState extends State<ProfileView>
|
|||||||
context,
|
context,
|
||||||
colorScheme: colorScheme,
|
colorScheme: colorScheme,
|
||||||
icon: Icons.logout,
|
icon: Icons.logout,
|
||||||
title: 'Logout',
|
title: AppLocalizations.of(context)!.logout,
|
||||||
subtitle: 'Sign out of your account',
|
subtitle: 'Sign out of your account',
|
||||||
iconColor: colorScheme.error,
|
iconColor: colorScheme.error,
|
||||||
onTap: () => _showLogoutDialog(context, colorScheme),
|
onTap: () => _showLogoutDialog(context, colorScheme),
|
||||||
@@ -541,10 +542,10 @@ class _ProfileViewState extends State<ProfileView>
|
|||||||
size: UIConstants.iconSizeMedium,
|
size: UIConstants.iconSizeMedium,
|
||||||
),
|
),
|
||||||
const SizedBox(width: UIConstants.spacing12),
|
const SizedBox(width: UIConstants.spacing12),
|
||||||
const Text("Confirm Logout"),
|
Text(AppLocalizations.of(context)!.confirmLogout),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
content: const Text("Are you sure you want to log out?"),
|
content: Text(AppLocalizations.of(context)!.confirmLogoutBody),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
@@ -563,7 +564,7 @@ class _ProfileViewState extends State<ProfileView>
|
|||||||
backgroundColor: colorScheme.error,
|
backgroundColor: colorScheme.error,
|
||||||
foregroundColor: colorScheme.onError,
|
foregroundColor: colorScheme.onError,
|
||||||
),
|
),
|
||||||
child: const Text("Log Out"),
|
child: Text(AppLocalizations.of(context)!.logoutAction),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import '../../l10n/app_localizations.dart';
|
||||||
|
|
||||||
class EditSystemParams extends StatelessWidget {
|
class EditSystemParams extends StatelessWidget {
|
||||||
const EditSystemParams({super.key});
|
const EditSystemParams({super.key});
|
||||||
@@ -13,7 +14,7 @@ class EditSystemParams extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
icon: Icon(Icons.adaptive.arrow_back),
|
icon: Icon(Icons.adaptive.arrow_back),
|
||||||
),
|
),
|
||||||
title: const Text("Edit System Parameters"),
|
title: Text(AppLocalizations.of(context)!.editSystemParameters),
|
||||||
),
|
),
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import 'package:base_project/shared/widgets/theme_preview.dart';
|
|||||||
import 'package:base_project/utils/managers/user_manager.dart';
|
import 'package:base_project/utils/managers/user_manager.dart';
|
||||||
import 'package:base_project/view_model/system_params/system_params_view_model.dart';
|
import 'package:base_project/view_model/system_params/system_params_view_model.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import '../../l10n/app_localizations.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:base_project/core/providers/dynamic_theme_provider.dart';
|
import 'package:base_project/core/providers/dynamic_theme_provider.dart';
|
||||||
|
|
||||||
@@ -235,7 +236,7 @@ class _SystemParametersViewState extends State<SystemParametersView>
|
|||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: colorScheme.background,
|
backgroundColor: colorScheme.background,
|
||||||
appBar: ModernAppBar(
|
appBar: ModernAppBar(
|
||||||
title: 'System Parameters',
|
title: AppLocalizations.of(context)!.systemParameters,
|
||||||
userAvatar: null,
|
userAvatar: null,
|
||||||
userName: userName,
|
userName: userName,
|
||||||
onProfilePressed: () {},
|
onProfilePressed: () {},
|
||||||
@@ -409,7 +410,7 @@ class _SystemParametersViewState extends State<SystemParametersView>
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'System Configuration',
|
AppLocalizations.of(context)!.sysConfigTitle,
|
||||||
style: theme.textTheme.headlineMedium?.copyWith(
|
style: theme.textTheme.headlineMedium?.copyWith(
|
||||||
color: colorScheme.onBackground,
|
color: colorScheme.onBackground,
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
@@ -417,7 +418,7 @@ class _SystemParametersViewState extends State<SystemParametersView>
|
|||||||
),
|
),
|
||||||
const SizedBox(height: UIConstants.spacing8),
|
const SizedBox(height: UIConstants.spacing8),
|
||||||
Text(
|
Text(
|
||||||
'Configure system-wide parameters and settings',
|
AppLocalizations.of(context)!.sysConfigSubtitle,
|
||||||
style: theme.textTheme.bodyLarge?.copyWith(
|
style: theme.textTheme.bodyLarge?.copyWith(
|
||||||
color: colorScheme.onSurfaceVariant,
|
color: colorScheme.onSurfaceVariant,
|
||||||
),
|
),
|
||||||
@@ -691,7 +692,8 @@ class _SystemParametersViewState extends State<SystemParametersView>
|
|||||||
),
|
),
|
||||||
const SizedBox(width: UIConstants.spacing8),
|
const SizedBox(width: UIConstants.spacing8),
|
||||||
Text(
|
Text(
|
||||||
'Generating dynamic theme...',
|
AppLocalizations.of(context)!
|
||||||
|
.generatingTheme,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.blue,
|
color: Colors.blue,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
@@ -720,7 +722,8 @@ class _SystemParametersViewState extends State<SystemParametersView>
|
|||||||
),
|
),
|
||||||
const SizedBox(width: UIConstants.spacing8),
|
const SizedBox(width: UIConstants.spacing8),
|
||||||
Text(
|
Text(
|
||||||
'Dynamic theme applied! Colors extracted from logo.',
|
AppLocalizations.of(context)!
|
||||||
|
.themeApplied,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.green,
|
color: Colors.green,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
@@ -742,7 +745,7 @@ class _SystemParametersViewState extends State<SystemParametersView>
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: ModernButton(
|
child: ModernButton(
|
||||||
text: 'Upload Logo',
|
text: AppLocalizations.of(context)!.uploadLogo,
|
||||||
type: ModernButtonType.primary,
|
type: ModernButtonType.primary,
|
||||||
size: ModernButtonSize.medium,
|
size: ModernButtonSize.medium,
|
||||||
icon: Icon(Icons.upload),
|
icon: Icon(Icons.upload),
|
||||||
@@ -757,7 +760,7 @@ class _SystemParametersViewState extends State<SystemParametersView>
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: ModernButton(
|
child: ModernButton(
|
||||||
text: 'Clear Logo',
|
text: AppLocalizations.of(context)!.clearLogo,
|
||||||
type: ModernButtonType.outline,
|
type: ModernButtonType.outline,
|
||||||
size: ModernButtonSize.medium,
|
size: ModernButtonSize.medium,
|
||||||
icon: Icon(Icons.delete_outline),
|
icon: Icon(Icons.delete_outline),
|
||||||
@@ -788,7 +791,8 @@ class _SystemParametersViewState extends State<SystemParametersView>
|
|||||||
const SizedBox(width: UIConstants.spacing8),
|
const SizedBox(width: UIConstants.spacing8),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
'Theme is applied immediately! Click "Upload Logo" to save the logo permanently to the database. The dynamic theme will work even if upload fails.',
|
AppLocalizations.of(context)!
|
||||||
|
.themeImmediateNote,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: AppColorScheme.info,
|
color: AppColorScheme.info,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
@@ -806,7 +810,7 @@ class _SystemParametersViewState extends State<SystemParametersView>
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: ModernButton(
|
child: ModernButton(
|
||||||
text: 'Upload New Logo',
|
text: AppLocalizations.of(context)!.uploadNewLogo,
|
||||||
type: ModernButtonType.primary,
|
type: ModernButtonType.primary,
|
||||||
size: ModernButtonSize.medium,
|
size: ModernButtonSize.medium,
|
||||||
icon: Icon(Icons.upload),
|
icon: Icon(Icons.upload),
|
||||||
@@ -821,7 +825,8 @@ class _SystemParametersViewState extends State<SystemParametersView>
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: ModernButton(
|
child: ModernButton(
|
||||||
text: 'Remove Logo',
|
text:
|
||||||
|
AppLocalizations.of(context)!.removeLogo,
|
||||||
type: ModernButtonType.danger,
|
type: ModernButtonType.danger,
|
||||||
size: ModernButtonSize.medium,
|
size: ModernButtonSize.medium,
|
||||||
icon: Icon(Icons.delete_outline),
|
icon: Icon(Icons.delete_outline),
|
||||||
@@ -852,7 +857,8 @@ class _SystemParametersViewState extends State<SystemParametersView>
|
|||||||
const SizedBox(width: UIConstants.spacing8),
|
const SizedBox(width: UIConstants.spacing8),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
'Company logo is already uploaded and saved in the system. You can upload a new one or remove the existing logo.',
|
AppLocalizations.of(context)!
|
||||||
|
.logoAlreadyUploaded,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: AppColorScheme.success,
|
color: AppColorScheme.success,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
@@ -913,7 +919,7 @@ class _SystemParametersViewState extends State<SystemParametersView>
|
|||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Enable Manual Override',
|
AppLocalizations.of(context)!.manualOverride,
|
||||||
style: theme.textTheme.titleMedium?.copyWith(
|
style: theme.textTheme.titleMedium?.copyWith(
|
||||||
color: cs.onSurface,
|
color: cs.onSurface,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@@ -938,7 +944,7 @@ class _SystemParametersViewState extends State<SystemParametersView>
|
|||||||
),
|
),
|
||||||
const SizedBox(height: UIConstants.spacing12),
|
const SizedBox(height: UIConstants.spacing12),
|
||||||
_buildColorRow(
|
_buildColorRow(
|
||||||
label: 'Primary',
|
label: AppLocalizations.of(context)!.colorPrimary,
|
||||||
color: effectivePrimary,
|
color: effectivePrimary,
|
||||||
onPick: () async {
|
onPick: () async {
|
||||||
final picked = await _pickColor(context, effectivePrimary);
|
final picked = await _pickColor(context, effectivePrimary);
|
||||||
@@ -949,7 +955,7 @@ class _SystemParametersViewState extends State<SystemParametersView>
|
|||||||
),
|
),
|
||||||
const SizedBox(height: UIConstants.spacing12),
|
const SizedBox(height: UIConstants.spacing12),
|
||||||
_buildColorRow(
|
_buildColorRow(
|
||||||
label: 'Secondary',
|
label: AppLocalizations.of(context)!.colorSecondary,
|
||||||
color: effectiveSecondary,
|
color: effectiveSecondary,
|
||||||
onPick: () async {
|
onPick: () async {
|
||||||
final picked =
|
final picked =
|
||||||
@@ -961,7 +967,7 @@ class _SystemParametersViewState extends State<SystemParametersView>
|
|||||||
),
|
),
|
||||||
const SizedBox(height: UIConstants.spacing12),
|
const SizedBox(height: UIConstants.spacing12),
|
||||||
_buildColorRow(
|
_buildColorRow(
|
||||||
label: 'Tertiary',
|
label: AppLocalizations.of(context)!.colorTertiary,
|
||||||
color: effectiveTertiary,
|
color: effectiveTertiary,
|
||||||
onPick: () async {
|
onPick: () async {
|
||||||
final picked = await _pickColor(context, effectiveTertiary);
|
final picked = await _pickColor(context, effectiveTertiary);
|
||||||
@@ -975,7 +981,8 @@ class _SystemParametersViewState extends State<SystemParametersView>
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ModernButton(
|
child: ModernButton(
|
||||||
text: 'Reset to Logo Colors',
|
text: AppLocalizations.of(context)!
|
||||||
|
.resetLogoColors,
|
||||||
type: ModernButtonType.outline,
|
type: ModernButtonType.outline,
|
||||||
size: ModernButtonSize.medium,
|
size: ModernButtonSize.medium,
|
||||||
icon: Icon(Icons.refresh),
|
icon: Icon(Icons.refresh),
|
||||||
@@ -987,7 +994,8 @@ class _SystemParametersViewState extends State<SystemParametersView>
|
|||||||
const SizedBox(width: UIConstants.spacing12),
|
const SizedBox(width: UIConstants.spacing12),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ModernButton(
|
child: ModernButton(
|
||||||
text: 'Reset to Default',
|
text: AppLocalizations.of(context)!
|
||||||
|
.resetDefault,
|
||||||
type: ModernButtonType.danger,
|
type: ModernButtonType.danger,
|
||||||
size: ModernButtonSize.medium,
|
size: ModernButtonSize.medium,
|
||||||
icon: Icon(Icons.settings_backup_restore),
|
icon: Icon(Icons.settings_backup_restore),
|
||||||
@@ -1041,7 +1049,7 @@ class _SystemParametersViewState extends State<SystemParametersView>
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
ModernButton(
|
ModernButton(
|
||||||
text: 'Edit',
|
text: AppLocalizations.of(context)!.edit,
|
||||||
type: ModernButtonType.text,
|
type: ModernButtonType.text,
|
||||||
size: ModernButtonSize.small,
|
size: ModernButtonSize.small,
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
@@ -1073,7 +1081,7 @@ class _SystemParametersViewState extends State<SystemParametersView>
|
|||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
title: const Text('Pick a color'),
|
title: Text(AppLocalizations.of(context)!.pickColor),
|
||||||
content: SizedBox(
|
content: SizedBox(
|
||||||
width: 320,
|
width: 320,
|
||||||
child: GridView.builder(
|
child: GridView.builder(
|
||||||
@@ -1105,7 +1113,7 @@ class _SystemParametersViewState extends State<SystemParametersView>
|
|||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
child: const Text('Cancel'),
|
child: Text(AppLocalizations.of(context)!.cancel),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@@ -1156,7 +1164,7 @@ class _SystemParametersViewState extends State<SystemParametersView>
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'User Registration',
|
AppLocalizations.of(context)!.userRegistration,
|
||||||
style: theme.textTheme.titleMedium?.copyWith(
|
style: theme.textTheme.titleMedium?.copyWith(
|
||||||
color: colorScheme.onSurface,
|
color: colorScheme.onSurface,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@@ -1164,7 +1172,7 @@ class _SystemParametersViewState extends State<SystemParametersView>
|
|||||||
),
|
),
|
||||||
const SizedBox(height: UIConstants.spacing4),
|
const SizedBox(height: UIConstants.spacing4),
|
||||||
Text(
|
Text(
|
||||||
'Allow new users to register accounts',
|
AppLocalizations.of(context)!.allowUserRegistration,
|
||||||
style: theme.textTheme.bodySmall?.copyWith(
|
style: theme.textTheme.bodySmall?.copyWith(
|
||||||
color: colorScheme.onSurfaceVariant,
|
color: colorScheme.onSurfaceVariant,
|
||||||
),
|
),
|
||||||
@@ -1194,7 +1202,7 @@ class _SystemParametersViewState extends State<SystemParametersView>
|
|||||||
return SizedBox(
|
return SizedBox(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: ModernButton(
|
child: ModernButton(
|
||||||
text: 'Save Configuration',
|
text: AppLocalizations.of(context)!.saveConfiguration,
|
||||||
type: ModernButtonType.primary,
|
type: ModernButtonType.primary,
|
||||||
size: ModernButtonSize.large,
|
size: ModernButtonSize.large,
|
||||||
icon: Icon(Icons.save),
|
icon: Icon(Icons.save),
|
||||||
@@ -1266,16 +1274,18 @@ class _SystemParametersViewState extends State<SystemParametersView>
|
|||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
children: [
|
children: [
|
||||||
_buildDrawerItem(
|
_buildDrawerItem(
|
||||||
context, theme, colorScheme, Icons.home, 'Home', () {
|
context, theme, colorScheme, Icons.home,
|
||||||
|
AppLocalizations.of(context)!.drawerHome, () {
|
||||||
Navigator.of(context).pushReplacementNamed('/');
|
Navigator.of(context).pushReplacementNamed('/');
|
||||||
}),
|
}),
|
||||||
_buildDrawerItem(context, theme, colorScheme, Icons.settings,
|
_buildDrawerItem(context, theme, colorScheme, Icons.settings,
|
||||||
'System Parameters', () {
|
AppLocalizations.of(context)!.systemParameters, () {
|
||||||
Navigator.of(context)
|
Navigator.of(context)
|
||||||
.pushReplacementNamed('/system_parameters');
|
.pushReplacementNamed('/system_parameters');
|
||||||
}, isSelected: true),
|
}, isSelected: true),
|
||||||
_buildDrawerItem(
|
_buildDrawerItem(
|
||||||
context, theme, colorScheme, Icons.people, 'Users', () {
|
context, theme, colorScheme, Icons.people,
|
||||||
|
AppLocalizations.of(context)!.drawerUsers, () {
|
||||||
Navigator.of(context).pushReplacementNamed('/users');
|
Navigator.of(context).pushReplacementNamed('/users');
|
||||||
}),
|
}),
|
||||||
_buildDrawerItem(
|
_buildDrawerItem(
|
||||||
@@ -1283,41 +1293,49 @@ class _SystemParametersViewState extends State<SystemParametersView>
|
|||||||
Navigator.of(context).pushReplacementNamed('/roles');
|
Navigator.of(context).pushReplacementNamed('/roles');
|
||||||
}),
|
}),
|
||||||
_buildDrawerItem(
|
_buildDrawerItem(
|
||||||
context, theme, colorScheme, Icons.business, 'Departments',
|
context, theme, colorScheme, Icons.business,
|
||||||
|
AppLocalizations.of(context)!.drawerDepartments,
|
||||||
() {
|
() {
|
||||||
Navigator.of(context).pushReplacementNamed('/departments');
|
Navigator.of(context).pushReplacementNamed('/departments');
|
||||||
}),
|
}),
|
||||||
_buildDrawerItem(
|
_buildDrawerItem(
|
||||||
context, theme, colorScheme, Icons.work, 'Positions', () {
|
context, theme, colorScheme, Icons.work,
|
||||||
|
AppLocalizations.of(context)!.drawerPositions, () {
|
||||||
Navigator.of(context).pushReplacementNamed('/positions');
|
Navigator.of(context).pushReplacementNamed('/positions');
|
||||||
}),
|
}),
|
||||||
_buildDrawerItem(context, theme, colorScheme,
|
_buildDrawerItem(context, theme, colorScheme,
|
||||||
Icons.monetization_on, 'Charges', () {
|
Icons.monetization_on,
|
||||||
|
AppLocalizations.of(context)!.drawerCharges, () {
|
||||||
Navigator.of(context).pushReplacementNamed('/charges');
|
Navigator.of(context).pushReplacementNamed('/charges');
|
||||||
}),
|
}),
|
||||||
_buildDrawerItem(
|
_buildDrawerItem(
|
||||||
context, theme, colorScheme, Icons.calendar_today, 'Weeks',
|
context, theme, colorScheme, Icons.calendar_today,
|
||||||
|
AppLocalizations.of(context)!.drawerWeeks,
|
||||||
() {
|
() {
|
||||||
Navigator.of(context).pushReplacementNamed('/weeks');
|
Navigator.of(context).pushReplacementNamed('/weeks');
|
||||||
}),
|
}),
|
||||||
_buildDrawerItem(
|
_buildDrawerItem(
|
||||||
context, theme, colorScheme, Icons.schedule, 'Shifts', () {
|
context, theme, colorScheme, Icons.schedule,
|
||||||
|
AppLocalizations.of(context)!.drawerShifts, () {
|
||||||
Navigator.of(context).pushReplacementNamed('/shifts');
|
Navigator.of(context).pushReplacementNamed('/shifts');
|
||||||
}),
|
}),
|
||||||
_buildDrawerItem(
|
_buildDrawerItem(
|
||||||
context, theme, colorScheme, Icons.payment, 'Billing', () {
|
context, theme, colorScheme, Icons.payment,
|
||||||
|
AppLocalizations.of(context)!.drawerBilling, () {
|
||||||
Navigator.of(context).pushReplacementNamed('/billing');
|
Navigator.of(context).pushReplacementNamed('/billing');
|
||||||
}),
|
}),
|
||||||
_buildDrawerItem(context, theme, colorScheme, Icons.swap_horiz,
|
_buildDrawerItem(context, theme, colorScheme, Icons.swap_horiz,
|
||||||
'EDI Settings', () {
|
AppLocalizations.of(context)!.drawerEdi, () {
|
||||||
Navigator.of(context).pushReplacementNamed('/edi_settings');
|
Navigator.of(context).pushReplacementNamed('/edi_settings');
|
||||||
}),
|
}),
|
||||||
_buildDrawerItem(context, theme, colorScheme,
|
_buildDrawerItem(context, theme, colorScheme,
|
||||||
Icons.business_center, 'Company', () {
|
Icons.business_center,
|
||||||
|
AppLocalizations.of(context)!.drawerCompany, () {
|
||||||
Navigator.of(context).pushReplacementNamed('/company');
|
Navigator.of(context).pushReplacementNamed('/company');
|
||||||
}),
|
}),
|
||||||
_buildDrawerItem(
|
_buildDrawerItem(
|
||||||
context, theme, colorScheme, Icons.image, 'Logo', () {
|
context, theme, colorScheme, Icons.image,
|
||||||
|
AppLocalizations.of(context)!.drawerLogo, () {
|
||||||
Navigator.of(context).pushReplacementNamed('/logo');
|
Navigator.of(context).pushReplacementNamed('/logo');
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
@@ -1328,7 +1346,7 @@ class _SystemParametersViewState extends State<SystemParametersView>
|
|||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.all(UIConstants.spacing24),
|
padding: const EdgeInsets.all(UIConstants.spacing24),
|
||||||
child: ModernButton(
|
child: ModernButton(
|
||||||
text: 'Logout',
|
text: AppLocalizations.of(context)!.logoutAction,
|
||||||
type: ModernButtonType.danger,
|
type: ModernButtonType.danger,
|
||||||
size: ModernButtonSize.medium,
|
size: ModernButtonSize.medium,
|
||||||
icon: Icon(Icons.logout),
|
icon: Icon(Icons.logout),
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:base_project/l10n/app_localizations.dart';
|
||||||
import 'package:base_project/utils/image_constant.dart';
|
import 'package:base_project/utils/image_constant.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
@@ -27,16 +28,16 @@ class ShowSnackAlert {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
if (color1 == Colors.red.shade400)
|
if (color1 == Colors.red.shade400)
|
||||||
const Text(
|
Text(
|
||||||
'Oh Snap!',
|
AppLocalizations.of(context)!.ohSnap,
|
||||||
style: TextStyle(fontSize: 18, color: Colors.white),
|
style: TextStyle(fontSize: 18, color: Colors.white),
|
||||||
),
|
),
|
||||||
if (color1 == Colors.orange.shade400)
|
if (color1 == Colors.orange.shade400)
|
||||||
const Text('Alert',
|
Text(AppLocalizations.of(context)!.alertTitle,
|
||||||
style:
|
style:
|
||||||
TextStyle(fontSize: 18, color: Colors.white)),
|
TextStyle(fontSize: 18, color: Colors.white)),
|
||||||
if (color1 == Colors.green.shade600)
|
if (color1 == Colors.green.shade600)
|
||||||
const Text('Success',
|
Text(AppLocalizations.of(context)!.successTitle,
|
||||||
style:
|
style:
|
||||||
TextStyle(fontSize: 18, color: Colors.white)),
|
TextStyle(fontSize: 18, color: Colors.white)),
|
||||||
Text(
|
Text(
|
||||||
|
|||||||
+16
-11
@@ -446,6 +446,11 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.0.0"
|
version: "5.0.0"
|
||||||
|
flutter_localizations:
|
||||||
|
dependency: "direct main"
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
flutter_plugin_android_lifecycle:
|
flutter_plugin_android_lifecycle:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -692,10 +697,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: intl
|
name: intl
|
||||||
sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5"
|
sha256: "1ca20c894b1717686a2319b8548763d812bc0aabdac580420a44c5178c57a867"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.20.2"
|
version: "0.20.3"
|
||||||
intl_phone_number_input:
|
intl_phone_number_input:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -844,10 +849,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: matcher
|
name: matcher
|
||||||
sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6"
|
sha256: "31bd099b47c10cd1aeb55146a2d46ce0277630ecef3f7dae54ad7873f36696cd"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.18"
|
version: "0.12.20"
|
||||||
material_color_utilities:
|
material_color_utilities:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -860,10 +865,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
|
sha256: "307249ce4ff29d58a18e97f6345f539382eb9c9c29ecda628900f31de0443dd9"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.17.0"
|
version: "1.19.0"
|
||||||
mime:
|
mime:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1353,10 +1358,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
sha256: "93167629bfc610f71560ab9312acdda4959de4df6fac7492c89ff0d3886f6636"
|
sha256: "2a122cbe059f8b610d3a5415f42e255b6c17b1f21eee1d960f31080237fb4f11"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.9"
|
version: "0.7.12"
|
||||||
typed_data:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1473,10 +1478,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vector_math
|
name: vector_math
|
||||||
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
|
sha256: "92b9910f66ed1057fd4da7b040ae7c74cafacf885bdc81be496928d5049b032d"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.0"
|
version: "2.4.3"
|
||||||
video_player:
|
video_player:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -1590,5 +1595,5 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.3"
|
version: "3.1.3"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.9.0 <4.0.0"
|
dart: ">=3.11.0-0 <4.0.0"
|
||||||
flutter: ">=3.35.0"
|
flutter: ">=3.35.0"
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ environment:
|
|||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
flutter_localizations:
|
||||||
|
sdk: flutter
|
||||||
another_flushbar: ^1.12.30
|
another_flushbar: ^1.12.30
|
||||||
cupertino_icons: ^1.0.8
|
cupertino_icons: ^1.0.8
|
||||||
path_provider: ^2.1.5
|
path_provider: ^2.1.5
|
||||||
@@ -100,6 +102,7 @@ dev_dependencies:
|
|||||||
|
|
||||||
# The following section is specific to Flutter packages.
|
# The following section is specific to Flutter packages.
|
||||||
flutter:
|
flutter:
|
||||||
|
generate: true
|
||||||
# The following line ensures that the Material Icons font is
|
# The following line ensures that the Material Icons font is
|
||||||
# included with your application, so that you can use the icons in
|
# included with your application, so that you can use the icons in
|
||||||
# the material Icons class.
|
# the material Icons class.
|
||||||
@@ -110,6 +113,7 @@ flutter:
|
|||||||
- assets/
|
- assets/
|
||||||
- assets/images/
|
- assets/images/
|
||||||
- assets/icon/
|
- assets/icon/
|
||||||
|
- assets/translations_dynamic/
|
||||||
|
|
||||||
# assets:
|
# assets:
|
||||||
# - images/a_dot_burr.jpeg
|
# - images/a_dot_burr.jpeg
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import 'package:base_project/l10n/app_localizations.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
test('English and Hindi catalogs expose the same essential messages', () {
|
||||||
|
final english = AppLocalizations(const Locale('en'));
|
||||||
|
final hindi = AppLocalizations(const Locale('hi'));
|
||||||
|
|
||||||
|
expect(english.searchEntity('student'), 'Search student...');
|
||||||
|
expect(hindi.searchEntity('छात्र'), 'छात्र खोजें...');
|
||||||
|
expect(english.entityRequired('Email'), 'Email is required');
|
||||||
|
expect(hindi.entityRequired('ईमेल'), 'ईमेल आवश्यक है');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('only configured locales are supported', () {
|
||||||
|
expect(AppLocalizations.supportedLocales, contains(const Locale('en')));
|
||||||
|
expect(AppLocalizations.supportedLocales, contains(const Locale('hi')));
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
// This is a basic Flutter widget test.
|
|
||||||
//
|
|
||||||
// To perform an interaction with a widget in your test, use the WidgetTester
|
|
||||||
// utility in the flutter_test package. For example, you can send tap and scroll
|
|
||||||
// gestures. You can also use WidgetTester to find child widgets in the widget
|
|
||||||
// tree, read text, and verify that the values of widget properties are correct.
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
|
||||||
|
|
||||||
import 'package:base_project/main.dart';
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
|
||||||
// Build our app and trigger a frame.
|
|
||||||
await tester.pumpWidget(const MyApp());
|
|
||||||
|
|
||||||
// Verify that our counter starts at 0.
|
|
||||||
expect(find.text('0'), findsOneWidget);
|
|
||||||
expect(find.text('1'), findsNothing);
|
|
||||||
|
|
||||||
// Tap the '+' icon and trigger a frame.
|
|
||||||
await tester.tap(find.byIcon(Icons.add));
|
|
||||||
await tester.pump();
|
|
||||||
|
|
||||||
// Verify that our counter has incremented.
|
|
||||||
expect(find.text('0'), findsNothing);
|
|
||||||
expect(find.text('1'), findsOneWidget);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user