translate base

This commit is contained in:
Mekan1206
2026-07-31 18:08:08 +05:00
parent a794dacd39
commit 581cb8241c
413 changed files with 9087 additions and 428 deletions

View File

@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace App\Filament\Pages;
use App\Enums\ImportType;
use App\Enums\NavigationGroup;
use App\Jobs\ProcessImportJob;
use App\Services\Import\ImportService;
use BackedEnum;
@@ -32,14 +33,10 @@ class ImportWizard extends Page
{
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedArrowUpTray;
protected static string|UnitEnum|null $navigationGroup = 'System';
protected static ?string $navigationLabel = 'Import Wizard';
protected static string|UnitEnum|null $navigationGroup = NavigationGroup::System;
protected static ?int $navigationSort = 2;
protected static ?string $title = 'Import Wizard';
protected static ?string $slug = 'import-wizard';
/**
@@ -55,6 +52,16 @@ class ImportWizard extends Page
/** @var array<string, mixed>|null */
public ?array $importResult = null;
public static function getNavigationLabel(): string
{
return __('hr.resources.import_wizard');
}
public function getTitle(): string|Htmlable
{
return __('hr.import.title');
}
public function mount(): void
{
$this->form->fill([
@@ -76,17 +83,17 @@ class ImportWizard extends Page
{
return $schema->components([
Wizard::make([
Step::make('Upload')
->description('Select import type and upload an Excel file')
Step::make(__('hr.import.upload'))
->description(__('hr.import.upload_description'))
->schema([
Select::make('import_type')
->label('Import Type')
->label(__('hr.import.import_type'))
->options(ImportType::class)
->required()
->live()
->afterStateUpdated(fn () => $this->resetColumnMapping()),
FileUpload::make('file')
->label('Excel File')
->label(__('hr.import.excel_file'))
->disk(config('hr.file_uploads.disk'))
->directory(config('hr.file_uploads.directory') . '/imports')
->acceptedFileTypes([
@@ -97,29 +104,29 @@ class ImportWizard extends Page
->required()
->afterStateUpdated(fn () => $this->loadHeaders()),
]),
Step::make('Map Columns')
->description('Match spreadsheet columns to system fields')
Step::make(__('hr.import.map_columns'))
->description(__('hr.import.map_columns_description'))
->schema([
Section::make('Column Mapping')
Section::make(__('hr.import.column_mapping'))
->schema(fn (): array => $this->getColumnMappingFields()),
]),
Step::make('Preview')
->description('Review the first 10 rows with validation')
Step::make(__('hr.import.preview_step'))
->description(__('hr.import.preview_description'))
->schema([
Placeholder::make('preview_table')
->label('Preview')
->label(__('hr.import.preview'))
->content(fn (): HtmlString => new HtmlString($this->getPreviewHtml())),
]),
Step::make('Import')
->description('Run the import and review results')
Step::make(__('hr.import.import_step'))
->description(__('hr.import.import_description'))
->schema([
Placeholder::make('import_results')
->label('Import Results')
->label(__('hr.import.import_results'))
->content(fn (): HtmlString => new HtmlString($this->getResultsHtml())),
]),
])
->alpineSubmitHandler('$wire.runImport()')
->submitAction(new HtmlString('<button type="submit" class="fi-btn fi-btn-primary">Start Import</button>'))
->submitAction(new HtmlString('<button type="submit" class="fi-btn fi-btn-primary">' . e(__('hr.import.start_import')) . '</button>'))
->skippable(false),
]);
}
@@ -146,8 +153,8 @@ class ImportWizard extends Page
if ($filePath === null) {
Notification::make()
->title('Upload required')
->body('Please upload an Excel file before importing.')
->title(__('hr.import.upload_required_title'))
->body(__('hr.import.upload_required_body'))
->danger()
->send();
@@ -165,8 +172,8 @@ class ImportWizard extends Page
);
Notification::make()
->title('Import queued')
->body('Your import has been queued and will be processed shortly.')
->title(__('hr.import.import_queued_title'))
->body(__('hr.import.import_queued_body'))
->success()
->send();
}
@@ -197,14 +204,14 @@ class ImportWizard extends Page
}
/**
* @return array<int, Select>
* @return array<int, Select|Placeholder>
*/
protected function getColumnMappingFields(): array
{
if ($this->headers === []) {
return [
Placeholder::make('mapping_hint')
->content('Upload a file in step 1 to load column headers.'),
->content(__('hr.import.mapping_hint')),
];
}
@@ -228,7 +235,7 @@ class ImportWizard extends Page
$path = $this->resolveStoredFilePath();
if ($path === null) {
return '<p class="text-sm text-gray-500">Upload a file to preview rows.</p>';
return '<p class="text-sm text-gray-500">' . e(__('hr.import.upload_to_preview')) . '</p>';
}
$importType = ImportType::from($this->data['import_type'] ?? ImportType::Employees->value);
@@ -238,18 +245,18 @@ class ImportWizard extends Page
$validation = $importService->validatePreview($importType, $mappedRows);
if ($mappedRows === []) {
return '<p class="text-sm text-gray-500">No rows found in the uploaded file.</p>';
return '<p class="text-sm text-gray-500">' . e(__('hr.import.no_rows')) . '</p>';
}
$fields = array_keys($importType->fields());
$html = '<div class="overflow-x-auto"><table class="fi-ta-table w-full text-sm"><thead><tr>';
$html .= '<th class="px-3 py-2 text-left">Row</th>';
$html .= '<th class="px-3 py-2 text-left">' . e(__('hr.import.row')) . '</th>';
foreach ($fields as $field) {
$html .= '<th class="px-3 py-2 text-left">' . e($importType->fields()[$field]) . '</th>';
}
$html .= '<th class="px-3 py-2 text-left">Validation</th></tr></thead><tbody>';
$html .= '<th class="px-3 py-2 text-left">' . e(__('hr.import.validation')) . '</th></tr></thead><tbody>';
foreach ($mappedRows as $index => $row) {
$errors = $validation[$index]['errors'] ?? [];
@@ -263,7 +270,7 @@ class ImportWizard extends Page
$html .= '<td class="px-3 py-2">';
if ($errors === []) {
$html .= '<span class="text-success-600">Valid</span>';
$html .= '<span class="text-success-600">' . e(__('hr.import.valid')) . '</span>';
} else {
$html .= '<span class="text-danger-600">' . e(implode(' ', $errors)) . '</span>';
}
@@ -281,17 +288,17 @@ class ImportWizard extends Page
$this->refreshImportResult();
if ($this->importResult === null) {
return '<p class="text-sm text-gray-500">Submit the import to see results here after processing completes.</p>';
return '<p class="text-sm text-gray-500">' . e(__('hr.import.submit_to_see_results')) . '</p>';
}
$html = '<div class="space-y-2 text-sm">';
$html .= '<p><strong>Total rows:</strong> ' . $this->importResult['total'] . '</p>';
$html .= '<p><strong>Imported:</strong> ' . $this->importResult['imported'] . '</p>';
$html .= '<p><strong>Skipped (duplicates):</strong> ' . $this->importResult['skipped'] . '</p>';
$html .= '<p><strong>Failed:</strong> ' . $this->importResult['failed'] . '</p>';
$html .= '<p><strong>' . e(__('hr.import.total_rows')) . ':</strong> ' . $this->importResult['total'] . '</p>';
$html .= '<p><strong>' . e(__('hr.import.imported')) . ':</strong> ' . $this->importResult['imported'] . '</p>';
$html .= '<p><strong>' . e(__('hr.import.skipped_duplicates')) . ':</strong> ' . $this->importResult['skipped'] . '</p>';
$html .= '<p><strong>' . e(__('hr.import.failed')) . ':</strong> ' . $this->importResult['failed'] . '</p>';
if (($this->importResult['errors'] ?? []) !== []) {
$html .= '<div class="mt-3"><strong>Errors:</strong><ul class="list-disc ps-5">';
$html .= '<div class="mt-3"><strong>' . e(__('hr.import.errors')) . ':</strong><ul class="list-disc ps-5">';
foreach ($this->importResult['errors'] as $error) {
$html .= '<li>' . e($error) . '</li>';
@@ -324,9 +331,4 @@ class ImportWizard extends Page
return $this->storedFilePath;
}
public function getTitle(): string|Htmlable
{
return 'Import Wizard';
}
}