sparkbooth anbindung optimiert
This commit is contained in:
@@ -1,16 +1 @@
|
|||||||
{
|
{"mcpServers":{"laravel-boost":{"command":"php","args":["artisan","boost:mcp"],"transport":"stdio","alwaysAllow":["application-info","search-docs"],"disabled":false}}}
|
||||||
"mcpServers": {
|
|
||||||
"laravel-boost": {
|
|
||||||
"command": "php",
|
|
||||||
"args": [
|
|
||||||
"artisan",
|
|
||||||
"boost:mcp"
|
|
||||||
],
|
|
||||||
"transport": "stdio",
|
|
||||||
"alwaysAllow": [
|
|
||||||
"application-info"
|
|
||||||
],
|
|
||||||
"disabled": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
88
app/Filament/Pages/SparkboothConnections.php
Normal file
88
app/Filament/Pages/SparkboothConnections.php
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Pages;
|
||||||
|
|
||||||
|
use App\Models\Gallery;
|
||||||
|
use BackedEnum;
|
||||||
|
use Filament\Notifications\Notification;
|
||||||
|
use Filament\Pages\Page;
|
||||||
|
use Filament\Actions\Action;
|
||||||
|
use Filament\Tables\Columns\TextColumn;
|
||||||
|
use Filament\Tables\Concerns\InteractsWithTable;
|
||||||
|
use Filament\Tables\Contracts\HasTable;
|
||||||
|
use Filament\Tables\Table;
|
||||||
|
use UnitEnum;
|
||||||
|
|
||||||
|
class SparkboothConnections extends Page implements HasTable
|
||||||
|
{
|
||||||
|
use InteractsWithTable;
|
||||||
|
|
||||||
|
protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-link';
|
||||||
|
|
||||||
|
protected static string|UnitEnum|null $navigationGroup = 'Admin';
|
||||||
|
|
||||||
|
protected static ?int $navigationSort = 11;
|
||||||
|
|
||||||
|
protected static ?string $title = 'Sparkbooth Verbindungen';
|
||||||
|
|
||||||
|
protected ?string $heading = 'Sparkbooth Verbindungen';
|
||||||
|
|
||||||
|
protected string $view = 'filament.pages.sparkbooth-connections';
|
||||||
|
|
||||||
|
public function table(Table $table): Table
|
||||||
|
{
|
||||||
|
return $table
|
||||||
|
->heading('Vorhandene Sparkbooth-Verbindungen')
|
||||||
|
->query(
|
||||||
|
Gallery::query()
|
||||||
|
->whereNotNull('upload_token_hash')
|
||||||
|
->orderByDesc('created_at')
|
||||||
|
)
|
||||||
|
->columns([
|
||||||
|
TextColumn::make('name')
|
||||||
|
->label('Name')
|
||||||
|
->searchable(),
|
||||||
|
TextColumn::make('slug')
|
||||||
|
->label('Slug')
|
||||||
|
->copyable()
|
||||||
|
->toggleable(),
|
||||||
|
TextColumn::make('images_path')
|
||||||
|
->label('Upload-Pfad')
|
||||||
|
->copyable()
|
||||||
|
->toggleable(),
|
||||||
|
TextColumn::make('created_at')
|
||||||
|
->label('Angelegt')
|
||||||
|
->since()
|
||||||
|
->sortable(),
|
||||||
|
])
|
||||||
|
->actions([
|
||||||
|
Action::make('show')
|
||||||
|
->label('Zugangsdaten anzeigen')
|
||||||
|
->icon('heroicon-o-key')
|
||||||
|
->color('primary')
|
||||||
|
->modalHeading('Upload-Zugangsdaten')
|
||||||
|
->modalSubmitAction(false)
|
||||||
|
->modalCancelActionLabel('Schließen')
|
||||||
|
->modalContent(function (Gallery $record) {
|
||||||
|
$plainToken = $record->regenerateUploadToken();
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'gallery' => $record->only(['id', 'name', 'slug', 'images_path']),
|
||||||
|
'upload_token' => $plainToken,
|
||||||
|
'upload_url' => route('api.sparkbooth.upload'),
|
||||||
|
'gallery_url' => route('gallery.show', $record),
|
||||||
|
];
|
||||||
|
|
||||||
|
Notification::make()
|
||||||
|
->title('Upload-Token wurde erneuert.')
|
||||||
|
->body('Bitte verwende den neuen Token in Sparkbooth.')
|
||||||
|
->success()
|
||||||
|
->send();
|
||||||
|
|
||||||
|
return view('filament.pages.partials.sparkbooth-token', $data);
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
->emptyStateHeading('Keine Sparkbooth-Verbindungen')
|
||||||
|
->emptyStateDescription('Lege eine neue Verbindung an oder aktiviere Uploads für eine Galerie.');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -49,7 +49,10 @@ class SparkboothSetup extends Page implements HasForms
|
|||||||
->label('Upload-Pfad')
|
->label('Upload-Pfad')
|
||||||
->helperText('Relativ zu public/storage, z.B. uploads/event-xyz')
|
->helperText('Relativ zu public/storage, z.B. uploads/event-xyz')
|
||||||
->default(fn () => 'uploads/'.Str::slug('event-'.Str::random(4)))
|
->default(fn () => 'uploads/'.Str::slug('event-'.Str::random(4)))
|
||||||
->required(),
|
->required()
|
||||||
|
->rule('regex:/^[A-Za-z0-9._\\/-]+$/')
|
||||||
|
->unique(table: Gallery::class, column: 'images_path')
|
||||||
|
->dehydrateStateUsing(fn (string $state): string => trim($state, '/')),
|
||||||
Toggle::make('allow_print')
|
Toggle::make('allow_print')
|
||||||
->label('Drucken erlauben')
|
->label('Drucken erlauben')
|
||||||
->default(true),
|
->default(true),
|
||||||
@@ -100,8 +103,15 @@ class SparkboothSetup extends Page implements HasForms
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
\Filament\Actions\Action::make('save')
|
\Filament\Actions\Action::make('save')
|
||||||
->label('Setup erstellen')
|
->label('Speichern')
|
||||||
|
->icon('heroicon-m-check')
|
||||||
|
->color('primary')
|
||||||
->submit('save'),
|
->submit('save'),
|
||||||
|
\Filament\Actions\Action::make('cancel')
|
||||||
|
->label('Abbrechen')
|
||||||
|
->icon('heroicon-m-x-mark')
|
||||||
|
->color('gray')
|
||||||
|
->url(route('filament.admin.pages.dashboard')),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('galleries', function (Blueprint $table) {
|
||||||
|
if (! Schema::hasColumn('galleries', 'images_path')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$duplicates = DB::table('galleries')
|
||||||
|
->select('images_path', DB::raw('COUNT(*) as aggregate'))
|
||||||
|
->whereNotNull('images_path')
|
||||||
|
->groupBy('images_path')
|
||||||
|
->having('aggregate', '>', 1)
|
||||||
|
->pluck('images_path')
|
||||||
|
->all();
|
||||||
|
|
||||||
|
if (! empty($duplicates)) {
|
||||||
|
foreach ($duplicates as $path) {
|
||||||
|
$idsToKeep = DB::table('galleries')
|
||||||
|
->where('images_path', $path)
|
||||||
|
->orderBy('id')
|
||||||
|
->limit(1)
|
||||||
|
->pluck('id');
|
||||||
|
|
||||||
|
DB::table('galleries')
|
||||||
|
->where('images_path', $path)
|
||||||
|
->whereNotIn('id', $idsToKeep)
|
||||||
|
->delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$table->unique('images_path');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('galleries', function (Blueprint $table) {
|
||||||
|
if (! Schema::hasColumn('galleries', 'images_path')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$table->dropUnique('galleries_images_path_unique');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<div class="space-y-4">
|
||||||
|
<div class="rounded-xl border border-gray-200 bg-white p-4 shadow-sm dark:border-white/10 dark:bg-white/5">
|
||||||
|
<p class="text-xs uppercase tracking-[0.3em] text-gray-500 dark:text-gray-300">Upload Endpoint</p>
|
||||||
|
<p class="mt-1 break-all font-semibold text-gray-900 dark:text-white">{{ $upload_url }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid gap-4 md:grid-cols-2">
|
||||||
|
<div class="rounded-xl border border-gray-200 bg-white p-4 shadow-sm dark:border-white/10 dark:bg-white/5">
|
||||||
|
<p class="text-xs uppercase tracking-[0.3em] text-gray-500 dark:text-gray-300">Upload Token</p>
|
||||||
|
<p class="mt-1 break-all font-mono text-sm text-gray-900 dark:text-white">{{ $upload_token }}</p>
|
||||||
|
<p class="mt-2 text-xs text-gray-500 dark:text-gray-300">Trage diesen Token in Sparkbooth unter „Upload Secret“ ein.</p>
|
||||||
|
</div>
|
||||||
|
<div class="rounded-xl border border-gray-200 bg-white p-4 shadow-sm dark:border-white/10 dark:bg-white/5">
|
||||||
|
<p class="text-xs uppercase tracking-[0.3em] text-gray-500 dark:text-gray-300">Galerie-Link</p>
|
||||||
|
<p class="mt-1 break-all font-semibold text-gray-900 dark:text-white">{{ $gallery_url }}</p>
|
||||||
|
<p class="mt-2 text-xs text-gray-500 dark:text-gray-300">Slug: {{ $gallery['slug'] }}, Pfad: storage/{{ $gallery['images_path'] }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid gap-4 md:grid-cols-2">
|
||||||
|
<div class="rounded-xl border border-gray-200 bg-white p-4 shadow-sm dark:border-white/10 dark:bg-white/5">
|
||||||
|
<p class="text-xs uppercase tracking-[0.3em] text-gray-500 dark:text-gray-300">QR Code (Galerie)</p>
|
||||||
|
<div class="mt-2 rounded-lg border border-gray-200 bg-white p-2 shadow-sm dark:border-white/20 dark:bg-white/5">
|
||||||
|
{!! \SimpleSoftwareIO\QrCode\Facades\QrCode::size(200)->margin(1)->generate($gallery_url) !!}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="rounded-xl border border-gray-200 bg-white p-4 shadow-sm dark:border-white/10 dark:bg-white/5">
|
||||||
|
<p class="text-xs uppercase tracking-[0.3em] text-gray-500 dark:text-gray-300">QR Code (Upload)</p>
|
||||||
|
<div class="mt-2 rounded-lg border border-gray-200 bg-white p-2 shadow-sm dark:border-white/20 dark:bg-white/5">
|
||||||
|
{!! \SimpleSoftwareIO\QrCode\Facades\QrCode::size(200)->margin(1)->generate($upload_url.'?token='.$upload_token) !!}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<x-filament-panels::page>
|
||||||
|
{{ $this->table }}
|
||||||
|
</x-filament-panels::page>
|
||||||
@@ -1,6 +1,12 @@
|
|||||||
<x-filament-panels::page>
|
<x-filament-panels::page>
|
||||||
<div class="space-y-6">
|
<div class="space-y-6">
|
||||||
{{ $this->form }}
|
<form wire:submit="save" class="space-y-4">
|
||||||
|
{{ $this->form }}
|
||||||
|
|
||||||
|
<div class="fi-form-actions">
|
||||||
|
<x-filament::actions :actions="$this->getFormActions()" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
@if ($result)
|
@if ($result)
|
||||||
<div class="rounded-2xl border border-gray-200/80 bg-white/70 p-6 shadow-sm ring-1 ring-black/5 dark:border-white/10 dark:bg-white/5">
|
<div class="rounded-2xl border border-gray-200/80 bg-white/70 p-6 shadow-sm ring-1 ring-black/5 dark:border-white/10 dark:bg-white/5">
|
||||||
|
|||||||
Reference in New Issue
Block a user