Files
fotospiel-app/app/Filament/Resources/TaskResource/Pages/ImportTasks.php
SEB Fotografie - soeren fc1e64fea3 feat(profile): add username + preferred_locale; wire to Inertia + middleware
- DB: users.username (unique), users.preferred_locale (default from app.locale)
- Backend: validation, model fillable; share supportedLocales; SetLocaleFromUser
- Frontend: profile page fields + types
- Filament: SuperAdmin profile page with username/language

feat(admin-nav): move Tasks to Bibliothek and add menu labels

fix(tasks-table): show localized title/emotion/event type; add translated headers

feat(l10n): add missing table headers for emotions and event types; normalize en/de files

refactor: tidy translations for tasks/emotions/event types
2025-09-11 21:17:19 +02:00

131 lines
4.5 KiB
PHP

<?php
namespace App\Filament\Resources\TaskResource\Pages;
use App\Filament\Resources\TaskResource;
use App\Models\Task;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Form;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\Page;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
class ImportTasks extends Page
{
protected static string $resource = TaskResource::class;
protected string $view = 'filament.resources.task-resource.pages.import-tasks';
protected ?string $heading = null;
public ?string $file = null;
public function form(Form $form): Form
{
return $form->schema([
FileUpload::make('file')
->label(__('admin.common.csv_file'))
->acceptedFileTypes(['text/csv', 'text/plain'])
->directory('imports')
->required(),
]);
}
public function doImport(): void
{
$this->validate();
$path = $this->form->getState()['file'] ?? null;
if (!$path || !Storage::disk('public')->exists($path)) {
Notification::make()->danger()->title(__('admin.notifications.file_not_found'))->send();
return;
}
$fullPath = Storage::disk('public')->path($path);
[$ok, $fail] = $this->importTasksCsv($fullPath);
Notification::make()
->success()
->title(__('admin.notifications.imported_rows', ['count' => $ok]))
->body($fail ? __('admin.notifications.failed_count', ['count' => $fail]) : null)
->send();
}
public function getHeading(): string
{
return __('admin.tasks.import.heading');
}
private function importTasksCsv(string $file): array
{
$handle = fopen($file, 'r');
if (!$handle) {
return [0, 0];
}
$ok = 0;
$fail = 0;
$headers = fgetcsv($handle, 0, ',');
if (!$headers) {
return [0, 0];
}
$map = array_flip($headers);
while (($row = fgetcsv($handle, 0, ',')) !== false) {
try {
DB::transaction(function () use ($row, $map, &$ok) {
$emotionName = trim($row[$map['emotion_name']] ?? '');
$emotionNameDe = trim($row[$map['emotion_name_de']] ?? '');
$emotionNameEn = trim($row[$map['emotion_name_en']] ?? '');
$emotionId = null;
if ($emotionName) {
$emotionId = DB::table('emotions')->where('name', $emotionName)->value('id');
} elseif ($emotionNameDe) {
$emotionId = DB::table('emotions')->where('name->de', $emotionNameDe)->value('id');
} elseif ($emotionNameEn) {
$emotionId = DB::table('emotions')->where('name->en', $emotionNameEn)->value('id');
}
if (!$emotionId) {
throw new \Exception('Emotion not found.');
}
$eventTypeId = null;
$eventTypeSlug = trim($row[$map['event_type_slug']] ?? '');
if ($eventTypeSlug) {
$eventTypeId = DB::table('event_types')->where('slug', $eventTypeSlug)->value('id');
}
Task::create([
'emotion_id' => $emotionId,
'event_type_id' => $eventTypeId,
'title' => [
'de' => $row[$map['title_de']] ?? null,
'en' => $row[$map['title_en']] ?? null,
],
'description' => [
'de' => $row[$map['description_de']] ?? null,
'en' => $row[$map['description_en']] ?? null,
],
'difficulty' => $row[$map['difficulty']] ?? 'easy',
'example_text' => [
'de' => $row[$map['example_text_de']] ?? null,
'en' => $row[$map['example_text_en']] ?? null,
],
'sort_order' => (int)($row[$map['sort_order']] ?? 0),
'is_active' => (int)($row[$map['is_active']] ?? 1) ? 1 : 0,
]);
$ok++;
});
} catch (\Throwable $e) {
$fail++;
}
}
fclose($handle);
return [$ok, $fail];
}
}