language files combined, settings fixed, "new" badge integrated
This commit is contained in:
@@ -5,6 +5,8 @@ namespace App\Filament\Resources\AiModelResource\Pages;
|
||||
use App\Filament\Resources\AiModelResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
use Illuminate\Contracts\Pagination\Paginator;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class ListAiModels extends ListRecords
|
||||
{
|
||||
@@ -16,4 +18,35 @@ class ListAiModels extends ListRecords
|
||||
Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
|
||||
protected function shouldPersistTableFiltersInSession(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function shouldPersistTableSortInSession(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function shouldPersistTableSearchInSession(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function paginateTableQuery(Builder $query): Paginator
|
||||
{
|
||||
$paginator = parent::paginateTableQuery($query);
|
||||
return $paginator;
|
||||
}
|
||||
|
||||
public function updatedTablePage($page)
|
||||
{
|
||||
$this->dispatch('table-pagination-updated', ['tableId' => $this->id, 'page' => $page]);
|
||||
}
|
||||
|
||||
protected function getTableQueryStringIdentifier(): ?string
|
||||
{
|
||||
return 'ai-models-table';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ namespace App\Filament\Resources\ApiProviderResource\Pages;
|
||||
use App\Filament\Resources\ApiProviderResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
use Illuminate\Contracts\Pagination\Paginator;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class ListApiProviders extends ListRecords
|
||||
{
|
||||
@@ -16,4 +18,35 @@ class ListApiProviders extends ListRecords
|
||||
Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
|
||||
protected function shouldPersistTableFiltersInSession(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function shouldPersistTableSortInSession(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function shouldPersistTableSearchInSession(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function paginateTableQuery(Builder $query): Paginator
|
||||
{
|
||||
$paginator = parent::paginateTableQuery($query);
|
||||
return $paginator;
|
||||
}
|
||||
|
||||
public function updatedTablePage($page)
|
||||
{
|
||||
$this->dispatch('table-pagination-updated', ['tableId' => $this->id, 'page' => $page]);
|
||||
}
|
||||
|
||||
protected function getTableQueryStringIdentifier(): ?string
|
||||
{
|
||||
return 'api-providers-table';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,9 @@ class ImageResource extends Resource
|
||||
->required()
|
||||
->image()
|
||||
->directory('uploads'),
|
||||
Forms\Components\Toggle::make('is_public')
|
||||
->label(__('Publicly Visible'))
|
||||
->default(false),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@ namespace App\Filament\Resources\ImageResource\Pages;
|
||||
use App\Filament\Resources\ImageResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
use Illuminate\Contracts\Pagination\Paginator;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class ListImages extends ListRecords
|
||||
{
|
||||
@@ -16,4 +18,35 @@ class ListImages extends ListRecords
|
||||
Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
|
||||
protected function shouldPersistTableFiltersInSession(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function shouldPersistTableSortInSession(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function shouldPersistTableSearchInSession(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function paginateTableQuery(Builder $query): Paginator
|
||||
{
|
||||
$paginator = parent::paginateTableQuery($query);
|
||||
return $paginator;
|
||||
}
|
||||
|
||||
public function updatedTablePage($page)
|
||||
{
|
||||
$this->dispatch('table-pagination-updated', ['tableId' => $this->id, 'page' => $page]);
|
||||
}
|
||||
|
||||
protected function getTableQueryStringIdentifier(): ?string
|
||||
{
|
||||
return 'images-table';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,18 +12,31 @@ use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Fieldset;
|
||||
|
||||
class SettingResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Setting::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
|
||||
protected static ?string $navigationIcon = 'heroicon-o-cog';
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
//
|
||||
Forms\Components\TextInput::make('key')
|
||||
->label(__('Key'))
|
||||
->required()
|
||||
->maxLength(255)
|
||||
->hiddenOn('edit'),
|
||||
Forms\Components\Fieldset::make()
|
||||
->label(fn (?Setting $record) => $record ? $record->key : __('New Setting'))
|
||||
->schema([
|
||||
TextInput::make('value')
|
||||
->label(__('Value'))
|
||||
->disableLabel()
|
||||
])
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -31,7 +44,8 @@ class SettingResource extends Resource
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
//
|
||||
Tables\Columns\TextColumn::make('key')->label(__('Key'))->searchable()->sortable(),
|
||||
Tables\Columns\TextColumn::make('value')->label(__('Value'))->searchable()->sortable(),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
@@ -39,6 +53,7 @@ class SettingResource extends Resource
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make(),
|
||||
])
|
||||
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\SettingResource\Pages;
|
||||
|
||||
use App\Filament\Resources\SettingResource;
|
||||
use App\Models\Setting;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Concerns\InteractsWithForms;
|
||||
use Filament\Forms\Contracts\HasForms;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Pages\Page;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Settings extends Page implements HasForms
|
||||
{
|
||||
use InteractsWithForms;
|
||||
|
||||
protected static string $resource = SettingResource::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-cog';
|
||||
|
||||
protected static ?string $navigationGroup = 'Settings';
|
||||
|
||||
protected static ?string $navigationLabel = 'Global Settings';
|
||||
|
||||
protected static ?string $slug = 'global-settings';
|
||||
|
||||
protected static string $view = 'filament.resources.setting-resource.pages.settings';
|
||||
|
||||
public ?array $data = [];
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
$this->form->fill(
|
||||
collect(Setting::all())
|
||||
->mapWithKeys(fn (Setting $setting) => [$setting->key => $setting->value])
|
||||
->all()
|
||||
);
|
||||
}
|
||||
|
||||
public function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
TextInput::make('gallery_heading')
|
||||
->label(__('settings.gallery_heading')),
|
||||
])
|
||||
->statePath('data')
|
||||
->model(Setting::class);
|
||||
}
|
||||
|
||||
public function submit(): void
|
||||
{
|
||||
foreach ($this->form->getState() as $key => $value) {
|
||||
Setting::updateOrCreate(['key' => $key], ['value' => $value]);
|
||||
}
|
||||
|
||||
Notification::make()
|
||||
->title(__('settings.saved_successfully'))
|
||||
->success()
|
||||
->send();
|
||||
}
|
||||
}
|
||||
@@ -110,9 +110,7 @@ class StyleResource extends Resource
|
||||
])
|
||||
->emptyStateActions([
|
||||
Tables\Actions\CreateAction::make(),
|
||||
])
|
||||
->persistFiltersInSession()
|
||||
->persistSortInSession();
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
|
||||
@@ -5,6 +5,8 @@ namespace App\Filament\Resources\StyleResource\Pages;
|
||||
use App\Filament\Resources\StyleResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
use Illuminate\Contracts\Pagination\Paginator;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class ListStyles extends ListRecords
|
||||
{
|
||||
@@ -16,4 +18,35 @@ class ListStyles extends ListRecords
|
||||
Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
|
||||
protected function shouldPersistTableFiltersInSession(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function shouldPersistTableSortInSession(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function shouldPersistTableSearchInSession(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function paginateTableQuery(Builder $query): Paginator
|
||||
{
|
||||
$paginator = parent::paginateTableQuery($query);
|
||||
return $paginator;
|
||||
}
|
||||
|
||||
public function updatedTablePage($page)
|
||||
{
|
||||
$this->dispatch('table-pagination-updated', ['tableId' => $this->id, 'page' => $page]);
|
||||
}
|
||||
|
||||
protected function getTableQueryStringIdentifier(): ?string
|
||||
{
|
||||
return 'styles-table';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,24 +27,50 @@ class UserResource extends Resource
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
TextInput::make('name')
|
||||
->label(__('filament.resource.user.form.name'))
|
||||
->required()
|
||||
->maxLength(255),
|
||||
TextInput::make('email')
|
||||
->label(__('filament.resource.user.form.email'))
|
||||
->email()
|
||||
->required()
|
||||
->maxLength(255),
|
||||
TextInput::make('password')
|
||||
->label(__('filament.resource.user.form.password'))
|
||||
->password()
|
||||
->required()
|
||||
->maxLength(255),
|
||||
Select::make('role_id')
|
||||
->relationship('role', 'name')
|
||||
->label(__('filament.resource.user.form.role'))
|
||||
->required(),
|
||||
Forms\Components\Section::make('User Details')
|
||||
->schema([
|
||||
TextInput::make('name')
|
||||
->label(__('filament.resource.user.form.name'))
|
||||
->required()
|
||||
->maxLength(255),
|
||||
TextInput::make('email')
|
||||
->label(__('filament.resource.user.form.email'))
|
||||
->email()
|
||||
->required()
|
||||
->maxLength(255),
|
||||
TextInput::make('password')
|
||||
->label(__('filament.resource.user.form.password'))
|
||||
->password()
|
||||
->dehydrateStateUsing(fn (string $state): string => bcrypt($state))
|
||||
->dehydrated(fn (?string $state): bool => filled($state))
|
||||
->required(fn (string $operation): bool => $operation === 'create')
|
||||
->maxLength(255),
|
||||
Select::make('role_id')
|
||||
->relationship('role', 'name')
|
||||
->label(__('filament.resource.user.form.role'))
|
||||
->required(),
|
||||
])->columns(2),
|
||||
|
||||
Forms\Components\Section::make('Preferences')
|
||||
->schema([
|
||||
Forms\Components\Toggle::make('email_notifications_enabled')
|
||||
->label(__('Email Notifications'))
|
||||
->default(true),
|
||||
Select::make('theme_preference')
|
||||
->label(__('Theme'))
|
||||
->options([
|
||||
'light' => 'Light',
|
||||
'dark' => 'Dark',
|
||||
])
|
||||
->default('light'),
|
||||
Select::make('locale')
|
||||
->label(__('Language'))
|
||||
->options([
|
||||
'en' => 'English',
|
||||
'de' => 'Deutsch',
|
||||
])
|
||||
->default('en'),
|
||||
])->columns(2),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@ namespace App\Filament\Resources\UserResource\Pages;
|
||||
use App\Filament\Resources\UserResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
use Illuminate\Contracts\Pagination\Paginator;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class ListUsers extends ListRecords
|
||||
{
|
||||
@@ -16,4 +18,35 @@ class ListUsers extends ListRecords
|
||||
Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
|
||||
protected function shouldPersistTableFiltersInSession(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function shouldPersistTableSortInSession(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function shouldPersistTableSearchInSession(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function paginateTableQuery(Builder $query): Paginator
|
||||
{
|
||||
$paginator = parent::paginateTableQuery($query);
|
||||
return $paginator;
|
||||
}
|
||||
|
||||
public function updatedTablePage($page)
|
||||
{
|
||||
$this->dispatch('table-pagination-updated', ['tableId' => $this->id, 'page' => $page]);
|
||||
}
|
||||
|
||||
protected function getTableQueryStringIdentifier(): ?string
|
||||
{
|
||||
return 'users-table';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,10 +9,12 @@ use App\Models\ApiProvider;
|
||||
use App\Models\Style;
|
||||
use App\Models\Image;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Carbon\Carbon;
|
||||
use App\Models\Setting;
|
||||
|
||||
class ImageController extends Controller
|
||||
{
|
||||
public function index()
|
||||
public function index(Request $request)
|
||||
{
|
||||
$publicUploadsPath = public_path('storage/uploads');
|
||||
|
||||
@@ -34,15 +36,28 @@ class ImageController extends Controller
|
||||
// Add images from disk that are not in the database
|
||||
$imagesToAdd = array_diff($diskImagePaths, $dbImagePaths);
|
||||
foreach ($imagesToAdd as $path) {
|
||||
Image::create(['path' => $path]);
|
||||
Image::create(['path' => $path, 'is_public' => true]);
|
||||
}
|
||||
|
||||
// Remove images from database that are not on disk
|
||||
$imagesToRemove = array_diff($dbImagePaths, $diskImagePaths);
|
||||
Image::whereIn('path', $imagesToRemove)->delete();
|
||||
|
||||
// Fetch all images from the database after synchronization
|
||||
$images = Image::orderBy('updated_at', 'desc')->get();
|
||||
// Fetch images from the database after synchronization
|
||||
$query = Image::orderBy('updated_at', 'desc');
|
||||
|
||||
// If user is not authenticated, filter by is_public
|
||||
if (!auth()->check()) {
|
||||
$query->where('is_public', true);
|
||||
}
|
||||
|
||||
$newImageTimespanMinutes = Setting::where('key', 'new_image_timespan_minutes')->first()->value ?? 60; // Default to 60 minutes
|
||||
|
||||
$images = $query->get()->map(function ($image) use ($newImageTimespanMinutes) {
|
||||
$image->is_new = Carbon::parse($image->created_at)->diffInMinutes(Carbon::now()) <= $newImageTimespanMinutes;
|
||||
return $image;
|
||||
});
|
||||
|
||||
$formattedImages = [];
|
||||
foreach ($images as $image) {
|
||||
$formattedImages[] = [
|
||||
@@ -50,6 +65,8 @@ class ImageController extends Controller
|
||||
'path' => asset('storage/' . $image->path),
|
||||
'name' => basename($image->path),
|
||||
'is_temp' => (bool) $image->is_temp,
|
||||
'is_public' => (bool) $image->is_public,
|
||||
'is_new' => (bool) $image->is_new,
|
||||
];
|
||||
}
|
||||
return response()->json($formattedImages);
|
||||
@@ -75,6 +92,7 @@ class ImageController extends Controller
|
||||
|
||||
$image = Image::create([
|
||||
'path' => $relativePath,
|
||||
'is_public' => true,
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
@@ -96,15 +114,29 @@ class ImageController extends Controller
|
||||
|
||||
$request->validate([
|
||||
'image_id' => 'required|exists:images,id',
|
||||
'style_id' => 'required|exists:styles,id',
|
||||
'style_id' => 'nullable|exists:styles,id',
|
||||
]);
|
||||
|
||||
$image = Image::find($request->image_id);
|
||||
$style = Style::with(['aiModel' => function ($query) {
|
||||
$query->where('enabled', true)->with(['apiProviders' => function ($query) {
|
||||
$query->where('enabled', true);
|
||||
}]);
|
||||
}])->find($request->style_id);
|
||||
$style = null;
|
||||
|
||||
if ($request->style_id) {
|
||||
$style = Style::with(['aiModel' => function ($query) {
|
||||
$query->where('enabled', true)->with(['apiProviders' => function ($query) {
|
||||
$query->where('enabled', true);
|
||||
}]);
|
||||
}])->find($request->style_id);
|
||||
} else {
|
||||
// Attempt to get default style from settings
|
||||
$defaultStyleSetting = \App\Models\Setting::where('key', 'default_style_id')->first();
|
||||
if ($defaultStyleSetting && $defaultStyleSetting->value) {
|
||||
$style = Style::with(['aiModel' => function ($query) {
|
||||
$query->where('enabled', true)->with(['apiProviders' => function ($query) {
|
||||
$query->where('enabled', true);
|
||||
}]);
|
||||
}])->find($defaultStyleSetting->value);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$style || !$style->aiModel || $style->aiModel->apiProviders->isEmpty()) {
|
||||
return response()->json(['error' => __('api.style_or_provider_not_found')], 404);
|
||||
|
||||
@@ -4,20 +4,33 @@ namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Image;
|
||||
use Inertia\Inertia;
|
||||
use Illuminate\Support\Facades\Lang;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$locale = app()->getLocale();
|
||||
$translations = Lang::get('messages', [], $locale);
|
||||
$translations = array_merge(
|
||||
Lang::get('api', [], $locale),
|
||||
Lang::get('settings', [], $locale)
|
||||
);
|
||||
$galleryHeading = Setting::where('key', 'gallery_heading')->first()->value ?? 'Style Gallery';
|
||||
$newImageTimespanMinutes = Setting::where('key', 'new_image_timespan_minutes')->first()->value ?? 60; // Default to 60 minutes
|
||||
|
||||
$images = Image::all()->map(function ($image) use ($newImageTimespanMinutes) {
|
||||
$image->is_new = Carbon::parse($image->created_at)->diffInMinutes(Carbon::now()) <= $newImageTimespanMinutes;
|
||||
$image->path = 'storage/' . $image->path;
|
||||
return $image;
|
||||
});
|
||||
|
||||
return Inertia::render('Home', [
|
||||
'translations' => $translations,
|
||||
'galleryHeading' => $galleryHeading,
|
||||
'images' => $images,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -35,14 +35,21 @@ class HandleInertiaRequests extends Middleware
|
||||
'user' => $request->user(),
|
||||
],
|
||||
'locale' => app()->getLocale(),
|
||||
'lang' => function () {
|
||||
'translations' => function () use ($request) {
|
||||
$currentLocale = app()->getLocale(); // Store current locale
|
||||
$requestedLocale = $request->input('locale', $currentLocale);
|
||||
app()->setLocale($requestedLocale); // Set locale based on request or current
|
||||
|
||||
$lang = [
|
||||
'filament' => trans('filament'),
|
||||
'api' => trans('api'),
|
||||
'settings' => trans('settings'),
|
||||
'messages' => trans('messages'),
|
||||
// Add other translation files as needed
|
||||
];
|
||||
|
||||
dd($lang); // <-- ADDED FOR DEBUGGING
|
||||
|
||||
app()->setLocale($currentLocale); // Revert to original locale
|
||||
return $lang;
|
||||
},
|
||||
];
|
||||
|
||||
@@ -15,12 +15,16 @@ class SetLocale
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
$locale = substr($request->server('HTTP_ACCEPT_LANGUAGE'), 0, 2);
|
||||
|
||||
if (in_array($locale, ['de'])) {
|
||||
app()->setLocale($locale);
|
||||
if (auth()->check() && auth()->user()->locale) {
|
||||
app()->setLocale(auth()->user()->locale);
|
||||
} else {
|
||||
app()->setLocale('en');
|
||||
$locale = substr($request->server('HTTP_ACCEPT_LANGUAGE'), 0, 2);
|
||||
|
||||
if (in_array($locale, ['de'])) {
|
||||
app()->setLocale($locale);
|
||||
} else {
|
||||
app()->setLocale('en');
|
||||
}
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
|
||||
@@ -16,5 +16,6 @@ class Image extends Model
|
||||
'original_image_id',
|
||||
'style_id',
|
||||
'is_temp',
|
||||
'is_public',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -22,6 +22,9 @@ class User extends Authenticatable
|
||||
'email',
|
||||
'password',
|
||||
'role_id',
|
||||
'email_notifications_enabled',
|
||||
'theme_preference',
|
||||
'locale',
|
||||
];
|
||||
|
||||
public function role()
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Filament\Support\Facades\FilamentAsset;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
@@ -19,6 +20,10 @@ class AppServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
FilamentAsset::register([
|
||||
\Filament\Support\Assets\Js::make('custom-navigation-state', __DIR__ . '/../../resources/js/custom/navigation-state.js'),
|
||||
]);
|
||||
|
||||
$locale = substr(request()->server('HTTP_ACCEPT_LANGUAGE'), 0, 2);
|
||||
|
||||
if (in_array($locale, ['de'])) {
|
||||
|
||||
@@ -19,12 +19,13 @@ use Illuminate\Session\Middleware\StartSession;
|
||||
use Illuminate\View\Middleware\ShareErrorsFromSession;
|
||||
use App\Filament\Resources\StyleResource;
|
||||
use App\Filament\Resources\SettingResource\Pages\Settings;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class AdminPanelProvider extends PanelProvider
|
||||
{
|
||||
public function panel(Panel $panel): Panel
|
||||
{
|
||||
return $panel
|
||||
$panel = $panel
|
||||
->default()
|
||||
->id('admin')
|
||||
->path('admin')
|
||||
@@ -37,7 +38,7 @@ class AdminPanelProvider extends PanelProvider
|
||||
->pages([
|
||||
Pages\Dashboard::class,
|
||||
\App\Filament\Pages\InstallPluginPage::class,
|
||||
Settings::class,
|
||||
|
||||
])
|
||||
->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\\Filament\\Widgets')
|
||||
->widgets([
|
||||
@@ -60,6 +61,19 @@ class AdminPanelProvider extends PanelProvider
|
||||
])
|
||||
->plugins([
|
||||
|
||||
]);
|
||||
])
|
||||
->profile();
|
||||
|
||||
if (Auth::check()) {
|
||||
$user = Auth::user();
|
||||
if ($user->theme_preference === 'dark') {
|
||||
$panel->darkMode();
|
||||
} else {
|
||||
$panel->lightMode();
|
||||
}
|
||||
}
|
||||
|
||||
return $panel;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^8.1",
|
||||
|
||||
"filament/filament": "3.0",
|
||||
"guzzlehttp/guzzle": "^7.2",
|
||||
"inertiajs/inertia-laravel": "^0.6.8",
|
||||
|
||||
253
composer.lock
generated
253
composer.lock
generated
@@ -4918,16 +4918,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v6.4.23",
|
||||
"version": "v6.4.24",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "9056771b8eca08d026cd3280deeec3cfd99c4d93"
|
||||
"reference": "59266a5bf6a596e3e0844fd95e6ad7ea3c1d3350"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/9056771b8eca08d026cd3280deeec3cfd99c4d93",
|
||||
"reference": "9056771b8eca08d026cd3280deeec3cfd99c4d93",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/59266a5bf6a596e3e0844fd95e6ad7ea3c1d3350",
|
||||
"reference": "59266a5bf6a596e3e0844fd95e6ad7ea3c1d3350",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4992,7 +4992,7 @@
|
||||
"terminal"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/console/tree/v6.4.23"
|
||||
"source": "https://github.com/symfony/console/tree/v6.4.24"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -5003,12 +5003,16 @@
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-06-27T19:37:22+00:00"
|
||||
"time": "2025-07-30T10:38:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/css-selector",
|
||||
@@ -5144,16 +5148,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/error-handler",
|
||||
"version": "v6.4.23",
|
||||
"version": "v6.4.24",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/error-handler.git",
|
||||
"reference": "b088e0b175c30b4e06d8085200fa465b586f44fa"
|
||||
"reference": "30fd0b3cf0e972e82636038ce4db0e4fe777112c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/error-handler/zipball/b088e0b175c30b4e06d8085200fa465b586f44fa",
|
||||
"reference": "b088e0b175c30b4e06d8085200fa465b586f44fa",
|
||||
"url": "https://api.github.com/repos/symfony/error-handler/zipball/30fd0b3cf0e972e82636038ce4db0e4fe777112c",
|
||||
"reference": "30fd0b3cf0e972e82636038ce4db0e4fe777112c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5199,7 +5203,7 @@
|
||||
"description": "Provides tools to manage errors and ease debugging PHP code",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/error-handler/tree/v6.4.23"
|
||||
"source": "https://github.com/symfony/error-handler/tree/v6.4.24"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -5210,12 +5214,16 @@
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-06-13T07:39:48+00:00"
|
||||
"time": "2025-07-24T08:25:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
@@ -5375,16 +5383,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v6.4.17",
|
||||
"version": "v6.4.24",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/finder.git",
|
||||
"reference": "1d0e8266248c5d9ab6a87e3789e6dc482af3c9c7"
|
||||
"reference": "73089124388c8510efb8d2d1689285d285937b08"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/1d0e8266248c5d9ab6a87e3789e6dc482af3c9c7",
|
||||
"reference": "1d0e8266248c5d9ab6a87e3789e6dc482af3c9c7",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/73089124388c8510efb8d2d1689285d285937b08",
|
||||
"reference": "73089124388c8510efb8d2d1689285d285937b08",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5419,7 +5427,7 @@
|
||||
"description": "Finds files and directories via an intuitive fluent interface",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/finder/tree/v6.4.17"
|
||||
"source": "https://github.com/symfony/finder/tree/v6.4.24"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -5430,25 +5438,29 @@
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-12-29T13:51:37+00:00"
|
||||
"time": "2025-07-15T12:02:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/html-sanitizer",
|
||||
"version": "v6.4.21",
|
||||
"version": "v6.4.24",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/html-sanitizer.git",
|
||||
"reference": "f66d6585c6ece946239317c339f8b2860dfdf2db"
|
||||
"reference": "8e9bb309986809af4cd9e049f9362d736387f083"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/html-sanitizer/zipball/f66d6585c6ece946239317c339f8b2860dfdf2db",
|
||||
"reference": "f66d6585c6ece946239317c339f8b2860dfdf2db",
|
||||
"url": "https://api.github.com/repos/symfony/html-sanitizer/zipball/8e9bb309986809af4cd9e049f9362d736387f083",
|
||||
"reference": "8e9bb309986809af4cd9e049f9362d736387f083",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5488,7 +5500,7 @@
|
||||
"sanitizer"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/html-sanitizer/tree/v6.4.21"
|
||||
"source": "https://github.com/symfony/html-sanitizer/tree/v6.4.24"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -5499,25 +5511,29 @@
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-03-31T07:29:45+00:00"
|
||||
"time": "2025-07-10T08:14:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-foundation",
|
||||
"version": "v6.4.23",
|
||||
"version": "v6.4.24",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/http-foundation.git",
|
||||
"reference": "452d19f945ee41345fd8a50c18b60783546b7bd3"
|
||||
"reference": "0341e41d8d8830c31a1dff5cbc5bdb3ec872a073"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/452d19f945ee41345fd8a50c18b60783546b7bd3",
|
||||
"reference": "452d19f945ee41345fd8a50c18b60783546b7bd3",
|
||||
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/0341e41d8d8830c31a1dff5cbc5bdb3ec872a073",
|
||||
"reference": "0341e41d8d8830c31a1dff5cbc5bdb3ec872a073",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5565,7 +5581,7 @@
|
||||
"description": "Defines an object-oriented layer for the HTTP specification",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/http-foundation/tree/v6.4.23"
|
||||
"source": "https://github.com/symfony/http-foundation/tree/v6.4.24"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -5576,25 +5592,29 @@
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-05-26T09:17:58+00:00"
|
||||
"time": "2025-07-10T08:14:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-kernel",
|
||||
"version": "v6.4.23",
|
||||
"version": "v6.4.24",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/http-kernel.git",
|
||||
"reference": "2bb2cba685aabd859f22cf6946554e8e7f3c329a"
|
||||
"reference": "b81dcdbe34b8e8f7b3fc7b2a47fa065d5bf30726"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/2bb2cba685aabd859f22cf6946554e8e7f3c329a",
|
||||
"reference": "2bb2cba685aabd859f22cf6946554e8e7f3c329a",
|
||||
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/b81dcdbe34b8e8f7b3fc7b2a47fa065d5bf30726",
|
||||
"reference": "b81dcdbe34b8e8f7b3fc7b2a47fa065d5bf30726",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5679,7 +5699,7 @@
|
||||
"description": "Provides a structured process for converting a Request into a Response",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/http-kernel/tree/v6.4.23"
|
||||
"source": "https://github.com/symfony/http-kernel/tree/v6.4.24"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -5690,25 +5710,29 @@
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-06-28T08:14:51+00:00"
|
||||
"time": "2025-07-31T09:23:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/mailer",
|
||||
"version": "v6.4.23",
|
||||
"version": "v6.4.24",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/mailer.git",
|
||||
"reference": "a480322ddf8e54de262c9bca31fdcbe26b553de5"
|
||||
"reference": "b4d7fa2c69641109979ed06e98a588d245362062"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/mailer/zipball/a480322ddf8e54de262c9bca31fdcbe26b553de5",
|
||||
"reference": "a480322ddf8e54de262c9bca31fdcbe26b553de5",
|
||||
"url": "https://api.github.com/repos/symfony/mailer/zipball/b4d7fa2c69641109979ed06e98a588d245362062",
|
||||
"reference": "b4d7fa2c69641109979ed06e98a588d245362062",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5759,7 +5783,7 @@
|
||||
"description": "Helps sending emails",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/mailer/tree/v6.4.23"
|
||||
"source": "https://github.com/symfony/mailer/tree/v6.4.24"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -5770,25 +5794,29 @@
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-06-26T21:24:02+00:00"
|
||||
"time": "2025-07-24T08:25:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/mime",
|
||||
"version": "v6.4.21",
|
||||
"version": "v6.4.24",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/mime.git",
|
||||
"reference": "fec8aa5231f3904754955fad33c2db50594d22d1"
|
||||
"reference": "664d5e844a2de5e11c8255d0aef6bc15a9660ac7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/mime/zipball/fec8aa5231f3904754955fad33c2db50594d22d1",
|
||||
"reference": "fec8aa5231f3904754955fad33c2db50594d22d1",
|
||||
"url": "https://api.github.com/repos/symfony/mime/zipball/664d5e844a2de5e11c8255d0aef6bc15a9660ac7",
|
||||
"reference": "664d5e844a2de5e11c8255d0aef6bc15a9660ac7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5844,7 +5872,7 @@
|
||||
"mime-type"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/mime/tree/v6.4.21"
|
||||
"source": "https://github.com/symfony/mime/tree/v6.4.24"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -5855,12 +5883,16 @@
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-04-27T13:27:38+00:00"
|
||||
"time": "2025-07-15T12:02:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
@@ -6501,16 +6533,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v6.4.20",
|
||||
"version": "v6.4.24",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "e2a61c16af36c9a07e5c9906498b73e091949a20"
|
||||
"reference": "8eb6dc555bfb49b2703438d5de65cc9f138ff50b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/e2a61c16af36c9a07e5c9906498b73e091949a20",
|
||||
"reference": "e2a61c16af36c9a07e5c9906498b73e091949a20",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/8eb6dc555bfb49b2703438d5de65cc9f138ff50b",
|
||||
"reference": "8eb6dc555bfb49b2703438d5de65cc9f138ff50b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -6542,7 +6574,7 @@
|
||||
"description": "Executes commands in sub-processes",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/process/tree/v6.4.20"
|
||||
"source": "https://github.com/symfony/process/tree/v6.4.24"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -6553,25 +6585,29 @@
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-03-10T17:11:00+00:00"
|
||||
"time": "2025-07-10T08:14:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/routing",
|
||||
"version": "v6.4.22",
|
||||
"version": "v6.4.24",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/routing.git",
|
||||
"reference": "1f5234e8457164a3a0038a4c0a4ba27876a9c670"
|
||||
"reference": "e4f94e625c8e6f910aa004a0042f7b2d398278f5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/routing/zipball/1f5234e8457164a3a0038a4c0a4ba27876a9c670",
|
||||
"reference": "1f5234e8457164a3a0038a4c0a4ba27876a9c670",
|
||||
"url": "https://api.github.com/repos/symfony/routing/zipball/e4f94e625c8e6f910aa004a0042f7b2d398278f5",
|
||||
"reference": "e4f94e625c8e6f910aa004a0042f7b2d398278f5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -6625,7 +6661,7 @@
|
||||
"url"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/routing/tree/v6.4.22"
|
||||
"source": "https://github.com/symfony/routing/tree/v6.4.24"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -6636,12 +6672,16 @@
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-04-27T16:08:38+00:00"
|
||||
"time": "2025-07-15T08:46:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/service-contracts",
|
||||
@@ -6728,16 +6768,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/string",
|
||||
"version": "v7.3.0",
|
||||
"version": "v7.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/string.git",
|
||||
"reference": "f3570b8c61ca887a9e2938e85cb6458515d2b125"
|
||||
"reference": "42f505aff654e62ac7ac2ce21033818297ca89ca"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/f3570b8c61ca887a9e2938e85cb6458515d2b125",
|
||||
"reference": "f3570b8c61ca887a9e2938e85cb6458515d2b125",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/42f505aff654e62ac7ac2ce21033818297ca89ca",
|
||||
"reference": "42f505aff654e62ac7ac2ce21033818297ca89ca",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -6795,7 +6835,7 @@
|
||||
"utf8"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/string/tree/v7.3.0"
|
||||
"source": "https://github.com/symfony/string/tree/v7.3.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -6806,25 +6846,29 @@
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-04-20T20:19:01+00:00"
|
||||
"time": "2025-07-10T08:47:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/translation",
|
||||
"version": "v6.4.23",
|
||||
"version": "v6.4.24",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/translation.git",
|
||||
"reference": "de8afa521e04a5220e9e58a1dc99971ab7cac643"
|
||||
"reference": "300b72643e89de0734d99a9e3f8494a3ef6936e1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/translation/zipball/de8afa521e04a5220e9e58a1dc99971ab7cac643",
|
||||
"reference": "de8afa521e04a5220e9e58a1dc99971ab7cac643",
|
||||
"url": "https://api.github.com/repos/symfony/translation/zipball/300b72643e89de0734d99a9e3f8494a3ef6936e1",
|
||||
"reference": "300b72643e89de0734d99a9e3f8494a3ef6936e1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -6890,7 +6934,7 @@
|
||||
"description": "Provides tools to internationalize your application",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/translation/tree/v6.4.23"
|
||||
"source": "https://github.com/symfony/translation/tree/v6.4.24"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -6901,12 +6945,16 @@
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-06-26T21:24:02+00:00"
|
||||
"time": "2025-07-30T17:30:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/translation-contracts",
|
||||
@@ -6988,16 +7036,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/uid",
|
||||
"version": "v6.4.23",
|
||||
"version": "v6.4.24",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/uid.git",
|
||||
"reference": "9c8592da78d7ee6af52011eef593350d87e814c0"
|
||||
"reference": "17da16a750541a42cf2183935e0f6008316c23f7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/uid/zipball/9c8592da78d7ee6af52011eef593350d87e814c0",
|
||||
"reference": "9c8592da78d7ee6af52011eef593350d87e814c0",
|
||||
"url": "https://api.github.com/repos/symfony/uid/zipball/17da16a750541a42cf2183935e0f6008316c23f7",
|
||||
"reference": "17da16a750541a42cf2183935e0f6008316c23f7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -7042,7 +7090,7 @@
|
||||
"uuid"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/uid/tree/v6.4.23"
|
||||
"source": "https://github.com/symfony/uid/tree/v6.4.24"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -7053,25 +7101,29 @@
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-06-26T08:06:12+00:00"
|
||||
"time": "2025-07-10T08:14:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/var-dumper",
|
||||
"version": "v6.4.23",
|
||||
"version": "v6.4.24",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/var-dumper.git",
|
||||
"reference": "d55b1834cdbfcc31bc2cd7e095ba5ed9a88f6600"
|
||||
"reference": "aa29484ce0544bd69fa9f0df902e5ed7b7fe5034"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/d55b1834cdbfcc31bc2cd7e095ba5ed9a88f6600",
|
||||
"reference": "d55b1834cdbfcc31bc2cd7e095ba5ed9a88f6600",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/aa29484ce0544bd69fa9f0df902e5ed7b7fe5034",
|
||||
"reference": "aa29484ce0544bd69fa9f0df902e5ed7b7fe5034",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -7083,7 +7135,6 @@
|
||||
"symfony/console": "<5.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-iconv": "*",
|
||||
"symfony/console": "^5.4|^6.0|^7.0",
|
||||
"symfony/error-handler": "^6.3|^7.0",
|
||||
"symfony/http-kernel": "^5.4|^6.0|^7.0",
|
||||
@@ -7127,7 +7178,7 @@
|
||||
"dump"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/var-dumper/tree/v6.4.23"
|
||||
"source": "https://github.com/symfony/var-dumper/tree/v6.4.24"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -7138,12 +7189,16 @@
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-06-27T15:05:27+00:00"
|
||||
"time": "2025-07-29T18:40:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "tightenco/ziggy",
|
||||
@@ -7890,16 +7945,16 @@
|
||||
},
|
||||
{
|
||||
"name": "myclabs/deep-copy",
|
||||
"version": "1.13.3",
|
||||
"version": "1.13.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/myclabs/DeepCopy.git",
|
||||
"reference": "faed855a7b5f4d4637717c2b3863e277116beb36"
|
||||
"reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/faed855a7b5f4d4637717c2b3863e277116beb36",
|
||||
"reference": "faed855a7b5f4d4637717c2b3863e277116beb36",
|
||||
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a",
|
||||
"reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -7938,7 +7993,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/myclabs/DeepCopy/issues",
|
||||
"source": "https://github.com/myclabs/DeepCopy/tree/1.13.3"
|
||||
"source": "https://github.com/myclabs/DeepCopy/tree/1.13.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -7946,7 +8001,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-07-05T12:25:42+00:00"
|
||||
"time": "2025-08-01T08:46:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nunomaduro/collision",
|
||||
@@ -9890,16 +9945,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v7.3.1",
|
||||
"version": "v7.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/yaml.git",
|
||||
"reference": "0c3555045a46ab3cd4cc5a69d161225195230edb"
|
||||
"reference": "b8d7d868da9eb0919e99c8830431ea087d6aae30"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/0c3555045a46ab3cd4cc5a69d161225195230edb",
|
||||
"reference": "0c3555045a46ab3cd4cc5a69d161225195230edb",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/b8d7d868da9eb0919e99c8830431ea087d6aae30",
|
||||
"reference": "b8d7d868da9eb0919e99c8830431ea087d6aae30",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -9942,7 +9997,7 @@
|
||||
"description": "Loads and dumps YAML files",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/yaml/tree/v7.3.1"
|
||||
"source": "https://github.com/symfony/yaml/tree/v7.3.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -9953,12 +10008,16 @@
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-06-03T06:57:57+00:00"
|
||||
"time": "2025-07-10T08:47:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "theseer/tokenizer",
|
||||
|
||||
@@ -12,8 +12,7 @@ return new class extends Migration
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('settings', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('key')->unique();
|
||||
$table->string('key')->primary();
|
||||
$table->text('value')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->boolean('email_notifications_enabled')->default(true);
|
||||
$table->string('theme_preference')->default('light');
|
||||
$table->string('locale')->default('en');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->dropColumn(['email_notifications_enabled', 'theme_preference', 'locale']);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('images', function (Blueprint $table) {
|
||||
$table->boolean('is_public')->default(false);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('images', function (Blueprint $table) {
|
||||
$table->dropColumn('is_public');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->text('two_factor_secret')
|
||||
->nullable();
|
||||
|
||||
$table->text('two_factor_recovery_codes')
|
||||
->nullable();
|
||||
|
||||
$table->timestamp('two_factor_confirmed_at')
|
||||
->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->dropColumn([
|
||||
'two_factor_secret',
|
||||
'two_factor_recovery_codes',
|
||||
'two_factor_confirmed_at',
|
||||
]);
|
||||
});
|
||||
}
|
||||
};
|
||||
71
package-lock.json
generated
71
package-lock.json
generated
@@ -4,6 +4,11 @@
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "^7.0.0",
|
||||
"@fortawesome/free-solid-svg-icons": "^7.0.0",
|
||||
"@fortawesome/vue-fontawesome": "^3.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@inertiajs/vue3": "^1.0.0",
|
||||
"@tailwindcss/forms": "^0.5.3",
|
||||
@@ -34,7 +39,6 @@
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
|
||||
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -44,7 +48,6 @@
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
|
||||
"integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -54,7 +57,6 @@
|
||||
"version": "7.28.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz",
|
||||
"integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.28.0"
|
||||
@@ -70,7 +72,6 @@
|
||||
"version": "7.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz",
|
||||
"integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-string-parser": "^7.27.1",
|
||||
@@ -471,6 +472,49 @@
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@fortawesome/fontawesome-common-types": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-7.0.0.tgz",
|
||||
"integrity": "sha512-PGMrIYXLGA5K8RWy8zwBkd4vFi4z7ubxtet6Yn13Plf6krRTwPbdlCwlcfmoX0R7B4Z643QvrtHmdQ5fNtfFCg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@fortawesome/fontawesome-svg-core": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-7.0.0.tgz",
|
||||
"integrity": "sha512-obBEF+zd98r/KtKVW6A+8UGWeaOoyMpl6Q9P3FzHsOnsg742aXsl8v+H/zp09qSSu/a/Hxe9LNKzbBaQq1CEbA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-common-types": "7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@fortawesome/free-solid-svg-icons": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-7.0.0.tgz",
|
||||
"integrity": "sha512-njSLAllkOddYDCXgTFboXn54Oe5FcvpkWq+FoetOHR64PbN0608kM02Lze0xtISGpXgP+i26VyXRQA0Irh3Obw==",
|
||||
"license": "(CC-BY-4.0 AND MIT)",
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-common-types": "7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@fortawesome/vue-fontawesome": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/vue-fontawesome/-/vue-fontawesome-3.1.1.tgz",
|
||||
"integrity": "sha512-U5azn4mcUVpjHe4JO0Wbe7Ih8e3VbN83EH7OTBtA5/QGw9qcPGffqcmwsLyZYgEkpVkYbq/6dX1Iyl5KUGMp6Q==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "~1 || ~6 || ~7",
|
||||
"vue": ">= 3.0.0 < 4"
|
||||
}
|
||||
},
|
||||
"node_modules/@inertiajs/core": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@inertiajs/core/-/core-1.3.0.tgz",
|
||||
@@ -542,7 +586,6 @@
|
||||
"version": "1.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz",
|
||||
"integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@jridgewell/trace-mapping": {
|
||||
@@ -923,7 +966,6 @@
|
||||
"version": "3.5.18",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.18.tgz",
|
||||
"integrity": "sha512-3slwjQrrV1TO8MoXgy3aynDQ7lslj5UqDxuHnrzHtpON5CBinhWjJETciPngpin/T3OuW3tXUf86tEurusnztw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.28.0",
|
||||
@@ -937,7 +979,6 @@
|
||||
"version": "3.5.18",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.18.tgz",
|
||||
"integrity": "sha512-RMbU6NTU70++B1JyVJbNbeFkK+A+Q7y9XKE2EM4NLGm2WFR8x9MbAtWxPPLdm0wUkuZv9trpwfSlL6tjdIa1+A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/compiler-core": "3.5.18",
|
||||
@@ -948,7 +989,6 @@
|
||||
"version": "3.5.18",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.18.tgz",
|
||||
"integrity": "sha512-5aBjvGqsWs+MoxswZPoTB9nSDb3dhd1x30xrrltKujlCxo48j8HGDNj3QPhF4VIS0VQDUrA1xUfp2hEa+FNyXA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.28.0",
|
||||
@@ -966,7 +1006,6 @@
|
||||
"version": "3.5.18",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.18.tgz",
|
||||
"integrity": "sha512-xM16Ak7rSWHkM3m22NlmcdIM+K4BMyFARAfV9hYFl+SFuRzrZ3uGMNW05kA5pmeMa0X9X963Kgou7ufdbpOP9g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/compiler-dom": "3.5.18",
|
||||
@@ -977,7 +1016,6 @@
|
||||
"version": "3.5.18",
|
||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.18.tgz",
|
||||
"integrity": "sha512-x0vPO5Imw+3sChLM5Y+B6G1zPjwdOri9e8V21NnTnlEvkxatHEH5B5KEAJcjuzQ7BsjGrKtfzuQ5eQwXh8HXBg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/shared": "3.5.18"
|
||||
@@ -987,7 +1025,6 @@
|
||||
"version": "3.5.18",
|
||||
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.18.tgz",
|
||||
"integrity": "sha512-DUpHa1HpeOQEt6+3nheUfqVXRog2kivkXHUhoqJiKR33SO4x+a5uNOMkV487WPerQkL0vUuRvq/7JhRgLW3S+w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/reactivity": "3.5.18",
|
||||
@@ -998,7 +1035,6 @@
|
||||
"version": "3.5.18",
|
||||
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.18.tgz",
|
||||
"integrity": "sha512-YwDj71iV05j4RnzZnZtGaXwPoUWeRsqinblgVJwR8XTXYZ9D5PbahHQgsbmzUvCWNF6x7siQ89HgnX5eWkr3mw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/reactivity": "3.5.18",
|
||||
@@ -1011,7 +1047,6 @@
|
||||
"version": "3.5.18",
|
||||
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.18.tgz",
|
||||
"integrity": "sha512-PvIHLUoWgSbDG7zLHqSqaCoZvHi6NNmfVFOqO+OnwvqMz/tqQr3FuGWS8ufluNddk7ZLBJYMrjcw1c6XzR12mA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/compiler-ssr": "3.5.18",
|
||||
@@ -1025,7 +1060,6 @@
|
||||
"version": "3.5.18",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.18.tgz",
|
||||
"integrity": "sha512-cZy8Dq+uuIXbxCZpuLd2GJdeSO/lIzIspC2WtkqIpje5QyFbvLaI5wZtdUjLHjGZrlVX6GilejatWwVYYRc8tA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ansi-regex": {
|
||||
@@ -1390,7 +1424,6 @@
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/deepmerge": {
|
||||
@@ -1467,7 +1500,6 @@
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
||||
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
@@ -1578,7 +1610,6 @@
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-glob": {
|
||||
@@ -2027,7 +2058,6 @@
|
||||
"version": "0.30.17",
|
||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
|
||||
"integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/sourcemap-codec": "^1.5.0"
|
||||
@@ -2142,7 +2172,6 @@
|
||||
"version": "3.3.11",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
|
||||
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -2269,7 +2298,6 @@
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
@@ -2309,7 +2337,6 @@
|
||||
"version": "8.5.6",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
|
||||
"integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -2734,7 +2761,6 @@
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -3074,7 +3100,6 @@
|
||||
"version": "3.5.18",
|
||||
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.18.tgz",
|
||||
"integrity": "sha512-7W4Y4ZbMiQ3SEo+m9lnoNpV9xG7QVMLa+/0RFwwiAVkeYoyGXqWE85jabU4pllJNUzqfLShJ5YLptewhCWUgNA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/compiler-dom": "3.5.18",
|
||||
|
||||
@@ -15,5 +15,10 @@
|
||||
"tailwindcss": "^3.2.1",
|
||||
"vite": "^5.0.0",
|
||||
"vue": "^3.4.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "^7.0.0",
|
||||
"@fortawesome/free-solid-svg-icons": "^7.0.0",
|
||||
"@fortawesome/vue-fontawesome": "^3.1.1"
|
||||
}
|
||||
}
|
||||
|
||||
83
public/js/app/custom-navigation-state.js
Normal file
83
public/js/app/custom-navigation-state.js
Normal file
@@ -0,0 +1,83 @@
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const navigation = document.querySelector('.fi-main-nav');
|
||||
if (!navigation) return;
|
||||
|
||||
const KEY = 'navigation_state';
|
||||
const TABLE_PAGES_KEY = 'table_pages_state';
|
||||
|
||||
// Function to get the state from session via a custom endpoint
|
||||
const getState = () => {
|
||||
return JSON.parse(sessionStorage.getItem(KEY)) || {};
|
||||
};
|
||||
|
||||
// Function to save the state to session via a custom endpoint
|
||||
const saveState = (state) => {
|
||||
sessionStorage.setItem(KEY, JSON.stringify(state));
|
||||
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
|
||||
fetch('/api/admin/navigation-state', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-TOKEN': csrfToken,
|
||||
},
|
||||
body: JSON.stringify({ groups: state }),
|
||||
});
|
||||
};
|
||||
|
||||
// Function to get table page state
|
||||
const getTablePageState = () => {
|
||||
return JSON.parse(sessionStorage.getItem(TABLE_PAGES_KEY)) || {};
|
||||
};
|
||||
|
||||
// Function to save table page state
|
||||
const saveTablePageState = (tableId, page) => {
|
||||
let tablePages = getTablePageState();
|
||||
tablePages[tableId] = page;
|
||||
sessionStorage.setItem(TABLE_PAGES_KEY, JSON.stringify(tablePages));
|
||||
};
|
||||
|
||||
let currentState = getState();
|
||||
let currentTablePages = getTablePageState();
|
||||
|
||||
// Apply the saved navigation state on page load
|
||||
const groups = navigation.querySelectorAll('.fi-nav-group');
|
||||
groups.forEach(group => {
|
||||
const label = group.querySelector('.fi-nav-group-label').textContent.trim();
|
||||
if (currentState[label] === 'collapsed') {
|
||||
group.classList.add('collapsed');
|
||||
}
|
||||
});
|
||||
|
||||
// Add event listeners to save navigation state on click
|
||||
navigation.addEventListener('click', (e) => {
|
||||
const labelElement = e.target.closest('.fi-nav-group-label');
|
||||
if (!labelElement) return;
|
||||
|
||||
const group = labelElement.closest('.fi-nav-group');
|
||||
const label = labelElement.textContent.trim();
|
||||
|
||||
if (group.classList.contains('collapsed')) {
|
||||
currentState[label] = 'expanded';
|
||||
group.classList.remove('collapsed');
|
||||
} else {
|
||||
currentState[label] = 'collapsed';
|
||||
group.classList.add('collapsed');
|
||||
}
|
||||
|
||||
saveState(currentState);
|
||||
});
|
||||
|
||||
// Livewire hook to save table page when pagination changes
|
||||
Livewire.hook('component.initialized', (component) => {
|
||||
if (component.name.includes('table')) {
|
||||
const tableId = component.el.id;
|
||||
if (currentTablePages[tableId]) {
|
||||
component.set('tablePage', currentTablePages[tableId], false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Livewire.on('table-pagination-updated', (tableId, page) => {
|
||||
saveTablePageState(tableId, page);
|
||||
});
|
||||
});
|
||||
@@ -1,3 +1,23 @@
|
||||
@import '@fortawesome/fontawesome-svg-core/styles.css';
|
||||
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
/* Theme variables */
|
||||
:root {
|
||||
--color-background: #ffffff;
|
||||
--color-text: #000000;
|
||||
}
|
||||
|
||||
html.dark {
|
||||
--color-background: #333333; /* Dark grey */
|
||||
--color-text: #ffffff;
|
||||
}
|
||||
|
||||
/* Apply theme to body */
|
||||
body {
|
||||
background-color: var(--color-background);
|
||||
color: var(--color-text);
|
||||
transition: background-color 0.3s ease, color 0.3s ease;
|
||||
}
|
||||
@@ -8,20 +8,31 @@
|
||||
@click="$emit('imageTapped', image, $event)"
|
||||
>
|
||||
<img :src="image.path" :alt="'Image ' + image.name" />
|
||||
<div v-if="image.is_new" class="new-badge">{{ __('new') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { defineProps, defineEmits } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
images: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
translations: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const emits = defineEmits(['imageTapped']);
|
||||
|
||||
const __ = (key) => {
|
||||
return props.translations[key] || key;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@@ -46,6 +57,7 @@ const emits = defineEmits(['imageTapped']);
|
||||
overflow: hidden;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
position: relative; /* Added for badge positioning */
|
||||
}
|
||||
|
||||
.grid-item img {
|
||||
@@ -54,4 +66,17 @@ const emits = defineEmits(['imageTapped']);
|
||||
object-fit: cover; /* Bilder zuschneiden, um den Bereich zu füllen */
|
||||
display: block;
|
||||
}
|
||||
|
||||
.new-badge {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
background-color: red;
|
||||
color: white;
|
||||
padding: 5px 10px;
|
||||
border-radius: 5px;
|
||||
font-size: 0.8em;
|
||||
font-weight: bold;
|
||||
z-index: 10;
|
||||
}
|
||||
</style>
|
||||
@@ -4,16 +4,45 @@
|
||||
<div class="context-menu-image-preview">
|
||||
<img :src="image.path" :alt="'Selected Image ' + image.name" />
|
||||
</div>
|
||||
<ul>
|
||||
<li @click="$emit('print', image)">Drucken</li>
|
||||
<li @click="$emit('changeStyle', image)">Stil ändern</li>
|
||||
<li @click="$emit('close')">Schließen</li>
|
||||
</ul>
|
||||
<div class="context-menu-options">
|
||||
<ul v-if="!showStyleSelectorView">
|
||||
<li @click="$emit('print', image)">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-5 h-5 inline-block align-middle mr-2">
|
||||
<path fill-rule="evenodd" d="M7.875 1.5C6.839 1.5 6 2.34 6 3.375v2.25a.75.75 0 0 0 1.5 0V3.375c0-.39.315-.75.75-.75h6.75c.39 0 .75.36.75.75v2.25a.75.75 0 0 0 1.5 0V3.375c0-1.036-.84-1.875-1.875-1.875H7.875Z" clip-rule="evenodd" />
|
||||
<path fill-rule="evenodd" d="M19.875 9a.75.75 0 0 0-.75-.75H4.875a.75.75 0 0 0-.75.75v6.75c0 1.036.84 1.875 1.875 1.875h11.25c1.036 0 1.875-.84 1.875-1.875V9ZM12 12.75a.75.75 0 0 0 0 1.5h.007a.75.75 0 0 0 0-1.5H12Z" clip-rule="evenodd" />
|
||||
<path d="M2.25 17.75a.75.75 0 0 0 0 1.5h19.5a.75.75 0 0 0 0-1.5H2.25Z" />
|
||||
</svg>
|
||||
Drucken
|
||||
</li>
|
||||
<li @click="showStyleSelectorView = true">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-5 h-5 inline-block align-middle mr-2">
|
||||
<path fill-rule="evenodd" d="M10.788 3.212a.75.75 0 0 0-1.06 0L7.212 5.788a.75.75 0 0 0 0 1.06l1.59 1.59a.75.75 0 0 0 1.06 0l2.576-2.576a.75.75 0 0 0 0-1.06L10.788 3.212ZM15.75 10.5a.75.75 0 0 1 .75-.75h.75a.75.75 0 0 1 0 1.5h-.75a.75.75 0 0 1-.75-.75ZM12 12a.75.75 0 0 1 .75-.75h.75a.75.75 0 0 1 0 1.5H12a.75.75 0 0 1-.75-.75ZM18.75 10.5a.75.75 0 0 1 .75-.75h.75a.75.75 0 0 1 0 1.5h-.75a.75.75 0 0 1-.75-.75ZM12 15a.75.75 0 0 1 .75-.75h.75a.75.75 0 0 1 0 1.5H12a.75.75 0 0 1-.75-.75ZM15.75 15a.75.75 0 0 1 .75-.75h.75a.75.75 0 0 1 0 1.5h-.75a.75.75 0 0 1-.75-.75ZM18.75 15a.75.75 0 0 1 .75-.75h.75a.75.75 0 0 1 0 1.5h-.75a.75.75 0 0 1-.75-.75ZM12 18a.75.75 0 0 1 .75-.75h.75a.75.75 0 0 1 0 1.5H12a.75.75 0 0 1-.75-.75ZM15.75 18a.75.75 0 0 1 .75-.75h.75a.75.75 0 0 1 0 1.5h-.75a.75.75 0 0 1-.75-.75ZM18.75 18a.75.75 0 0 1 .75-.75h.75a.75.75 0 0 1 0 1.5h-.75a.75.75 0 0 1-.75-.75ZM12 21a.75.75 0 0 1 .75-.75h.75a.75.75 0 0 1 0 1.5H12a.75.75 0 0 1-.75-.75Z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
Stil ändern
|
||||
</li>
|
||||
<li @click="$emit('close')">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-5 h-5 inline-block align-middle mr-2">
|
||||
<path fill-rule="evenodd" d="M5.47 5.47a.75.75 0 0 1 1.06 0L12 10.94l5.47-5.47a.75.75 0 1 1 1.06 1.06L13.06 12l5.47 5.47a.75.75 0 1 1-1.06 1.06L12 13.06l-5.47 5.47a.75.75 0 0 1-1.06-1.06L10.94 12 5.47 6.53a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
Schließen
|
||||
</li>
|
||||
</ul>
|
||||
<StyleSelector
|
||||
v-else
|
||||
:image_id="image.image_id"
|
||||
@styleSelected="(style, imageId) => $emit('styleSelected', style, imageId)"
|
||||
@back="showStyleSelectorView = false"
|
||||
@close="$emit('close')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import StyleSelector from './StyleSelector.vue';
|
||||
|
||||
const props = defineProps({
|
||||
position: {
|
||||
type: Object,
|
||||
@@ -25,7 +54,9 @@ const props = defineProps({
|
||||
},
|
||||
});
|
||||
|
||||
const emits = defineEmits(['close', 'print', 'changeStyle']);
|
||||
const emits = defineEmits(['close', 'print', 'changeStyle', 'styleSelected']);
|
||||
|
||||
const showStyleSelectorView = ref(false);
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@@ -43,19 +74,19 @@ const emits = defineEmits(['close', 'print', 'changeStyle']);
|
||||
}
|
||||
|
||||
.context-menu {
|
||||
background: white;
|
||||
border: 1px solid #ccc;
|
||||
box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.1);
|
||||
background: var(--color-background);
|
||||
border: 1px solid var(--color-text);
|
||||
box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.5);
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
flex-direction: row; /* Bild und Menü nebeneinander */
|
||||
max-width: 80%;
|
||||
max-height: 80%;
|
||||
max-width: 90%;
|
||||
height: 80vh; /* 80% of viewport height */
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.context-menu-image-preview {
|
||||
flex: 1; /* Nimmt den verfügbaren Platz ein */
|
||||
flex: 7; /* Takes 70% of the space (7 out of 10 parts) */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
@@ -65,14 +96,21 @@ const emits = defineEmits(['close', 'print', 'changeStyle']);
|
||||
.context-menu-image-preview img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
width: 80%; /* 80% width of its container */
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.context-menu-options {
|
||||
flex: 3; /* Takes 30% of the space (3 out of 10 parts) */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.context-menu ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border-left: 1px solid #eee; /* Trennlinie zwischen Bild und Menü */
|
||||
border-left: 1px solid var(--color-text); /* Trennlinie zwischen Bild und Menü */
|
||||
min-width: 150px; /* Mindestbreite für das Menü */
|
||||
}
|
||||
|
||||
@@ -80,7 +118,7 @@ const emits = defineEmits(['close', 'print', 'changeStyle']);
|
||||
padding: 15px;
|
||||
cursor: pointer;
|
||||
font-size: 1.1em;
|
||||
border-bottom: 1px solid #eee;
|
||||
border-bottom: 1px solid var(--color-text);
|
||||
}
|
||||
|
||||
.context-menu li:last-child {
|
||||
@@ -88,6 +126,7 @@ const emits = defineEmits(['close', 'print', 'changeStyle']);
|
||||
}
|
||||
|
||||
.context-menu li:hover {
|
||||
background: #f0f0f0;
|
||||
background: var(--color-text); /* Adjust hover background for dark mode */
|
||||
color: var(--color-background); /* Adjust hover text color for dark mode */
|
||||
}
|
||||
</style>
|
||||
@@ -27,9 +27,10 @@ const emits = defineEmits(['prevPage', 'nextPage']);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
background-color: #f0f0f0;
|
||||
background-color: var(--color-background);
|
||||
width: 100%;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.navigation button {
|
||||
@@ -51,6 +52,6 @@ const emits = defineEmits(['prevPage', 'nextPage']);
|
||||
.navigation span {
|
||||
font-size: 1.2em;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
color: var(--color-text);
|
||||
}
|
||||
</style>
|
||||
@@ -1,22 +1,24 @@
|
||||
<template>
|
||||
<div class="context-menu-overlay" @click.self="$emit('close')">
|
||||
<div class="style-selector" :style="{ top: `${position.y}px`, left: `${position.x}px` }">
|
||||
<div class="style-selector-header">
|
||||
<span class="back-arrow" @click="$emit('back')">←</span>
|
||||
<h3>Verfügbare Stile</h3>
|
||||
</div>
|
||||
<div class="styles-list">
|
||||
<div
|
||||
v-for="style in styles"
|
||||
:key="style.id"
|
||||
class="style-item"
|
||||
@click="selectStyle(style)"
|
||||
>
|
||||
<img :src="'/storage/' + style.preview_image" :alt="style.title" class="style-thumbnail" />
|
||||
<div class="style-details">
|
||||
<h4>{{ style.title }}</h4>
|
||||
<p>{{ style.description }}</p>
|
||||
</div>
|
||||
<div class="style-selector">
|
||||
<div class="style-selector-header">
|
||||
<span class="back-arrow" @click="$emit('back')">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6">
|
||||
<path fill-rule="evenodd" d="M11.03 4.272a.75.75 0 0 1 0 1.06L6.31 10.5H20.25a.75.75 0 0 1 0 1.5H6.31l4.72 5.168a.75.75 0 0 1-1.06 1.06l-6-6a.75.75 0 0 1 0-1.06l6-6a.75.75 0 0 1 1.06 0Z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</span>
|
||||
<h3>Verfügbare Stile</h3>
|
||||
</div>
|
||||
<div class="styles-list">
|
||||
<div
|
||||
v-for="style in styles"
|
||||
:key="style.id"
|
||||
class="style-item"
|
||||
@click="selectStyle(style)"
|
||||
>
|
||||
<img :src="'/storage/' + style.preview_image" :alt="style.title" class="style-thumbnail" />
|
||||
<div class="style-details">
|
||||
<h4>{{ style.title }}</h4>
|
||||
<p>{{ style.description }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -30,10 +32,6 @@ import { ref, onMounted } from 'vue';
|
||||
const styles = ref([]);
|
||||
|
||||
const props = defineProps({
|
||||
position: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
image_id: {
|
||||
type: Number,
|
||||
required: true,
|
||||
@@ -63,19 +61,6 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.context-menu-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.5); /* Halbdurchsichtiger Hintergrund */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.style-selector {
|
||||
background: white;
|
||||
border: 1px solid #ccc;
|
||||
@@ -83,10 +68,9 @@ onMounted(() => {
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-width: 80%;
|
||||
max-height: 80%;
|
||||
max-width: 100%; /* Adjusted to fit parent */
|
||||
max-height: 100%; /* Adjusted to fit parent */
|
||||
overflow: hidden;
|
||||
position: absolute; /* Positionierung innerhalb des Overlays */
|
||||
}
|
||||
|
||||
.style-selector-header {
|
||||
@@ -106,14 +90,16 @@ onMounted(() => {
|
||||
|
||||
.back-arrow {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
font-size: 1.5em;
|
||||
left: 5px; /* Adjusted position */
|
||||
font-size: 2em; /* Slightly larger */
|
||||
cursor: pointer;
|
||||
padding: 5px;
|
||||
padding: 10px; /* Larger clickable area */
|
||||
color: var(--color-text); /* Adapt to theme */
|
||||
}
|
||||
|
||||
.back-arrow:hover {
|
||||
color: #007bff;
|
||||
color: var(--color-background); /* Adjust hover color for dark mode */
|
||||
background: var(--color-text); /* Adjust hover background for dark mode */
|
||||
}
|
||||
|
||||
.styles-list {
|
||||
|
||||
@@ -2,8 +2,13 @@
|
||||
<div class="home">
|
||||
<div class="main-content">
|
||||
<div class="gallery-container" @touchstart="handleTouchStart" @touchend="handleTouchEnd">
|
||||
<h1 class="text-2xl font-bold text-center my-4">Style Gallery</h1>
|
||||
<GalleryGrid :images="paginatedImages" @imageTapped="showContextMenu" />
|
||||
<h1 class="text-2xl font-bold text-center my-4">{{ props.galleryHeading }}</h1>
|
||||
<div class="absolute top-4 right-4">
|
||||
<button @click="toggleTheme" class="theme-toggle-button">
|
||||
{{ currentTheme === 'light' ? __('api.dark_mode') : __('api.light_mode') }}
|
||||
</button>
|
||||
</div>
|
||||
<GalleryGrid :images="paginatedImages" @imageTapped="showContextMenu" :translations="props.translations" />
|
||||
<Navigation
|
||||
:currentPage="currentPage"
|
||||
:totalPages="totalPages"
|
||||
@@ -17,18 +22,10 @@
|
||||
v-if="currentOverlayComponent === 'contextMenu'"
|
||||
:position="contextMenuPosition"
|
||||
:image="selectedImage"
|
||||
@close="currentOverlayComponent = null"
|
||||
@close="currentOverlayComponent = null; selectedImage = null"
|
||||
@print="printImage"
|
||||
@changeStyle="showStyleSelector"
|
||||
/>
|
||||
|
||||
<StyleSelector
|
||||
v-if="currentOverlayComponent === 'styleSelector'"
|
||||
:position="contextMenuPosition"
|
||||
:image_id="selectedImage.image_id"
|
||||
@styleSelected="applyStyle"
|
||||
@back="goBackToContextMenu"
|
||||
@close="currentOverlayComponent = null"
|
||||
/>
|
||||
|
||||
<div v-if="errorMessage" class="fixed bottom-4 right-4 bg-red-500 text-white p-4 rounded-lg shadow-lg z-50">
|
||||
@@ -46,38 +43,15 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Navigation from '../Components/Navigation.vue';
|
||||
import GalleryGrid from '../Components/GalleryGrid.vue';
|
||||
import ImageContextMenu from '../Components/ImageContextMenu.vue';
|
||||
import StyleSelector from '../Components/StyleSelector.vue';
|
||||
import StyledImageDisplay from '../Components/StyledImageDisplay.vue'; // Import the new component
|
||||
import LoadingSpinner from '../Components/LoadingSpinner.vue'; // Import the new component
|
||||
import axios from 'axios';
|
||||
import { ref, computed, onMounted, onUnmounted } from 'vue';
|
||||
import { defineProps } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
galleryHeading: String,
|
||||
translations: Object,
|
||||
});
|
||||
|
||||
const images = ref([]);
|
||||
const imagesPerPage = 12;
|
||||
const currentPage = ref(1);
|
||||
const currentOverlayComponent = ref(null); // null, 'contextMenu', 'styleSelector', 'styledImageDisplay'
|
||||
const contextMenuPosition = ref({ x: 0, y: 0 });
|
||||
const selectedImage = ref(null);
|
||||
const styledImage = ref(null); // To store the newly styled image
|
||||
const errorMessage = ref(null); // New ref for error messages
|
||||
const isLoading = ref(false); // New ref for loading state
|
||||
let fetchInterval = null;
|
||||
let touchStartX = 0;
|
||||
let touchEndX = 0;
|
||||
|
||||
|
||||
const totalPages = computed(() => {
|
||||
return Math.ceil(images.value.length / imagesPerPage);
|
||||
});
|
||||
|
||||
const paginatedImages = computed(() => {
|
||||
const start = (currentPage.value - 1) * imagesPerPage;
|
||||
const end = start + imagesPerPage;
|
||||
return images.value.slice(start, end);
|
||||
});
|
||||
|
||||
const fetchImages = () => {
|
||||
axios.get('/api/images')
|
||||
@@ -90,6 +64,50 @@ const fetchImages = () => {
|
||||
});
|
||||
};
|
||||
|
||||
import Navigation from '../Components/Navigation.vue';
|
||||
import GalleryGrid from '../Components/GalleryGrid.vue';
|
||||
import ImageContextMenu from '../Components/ImageContextMenu.vue';
|
||||
import StyleSelector from '../Components/StyleSelector.vue';
|
||||
import StyledImageDisplay from '../Components/StyledImageDisplay.vue'; // Import the new component
|
||||
import LoadingSpinner from '../Components/LoadingSpinner.vue'; // Import the new component
|
||||
import axios from 'axios';
|
||||
import { ref, computed, onMounted, onUnmounted } from 'vue';
|
||||
|
||||
const imagesPerPage = 12;
|
||||
const currentPage = ref(1);
|
||||
const currentOverlayComponent = ref(null); // null, 'contextMenu', 'styleSelector', 'styledImageDisplay'
|
||||
const contextMenuPosition = ref({ x: 0, y: 0 });
|
||||
const selectedImage = ref(null);
|
||||
const styledImage = ref(null); // To store the newly styled image
|
||||
const errorMessage = ref(null); // New ref for error messages
|
||||
const isLoading = ref(false); // New ref for loading state
|
||||
const currentTheme = ref('light'); // New ref for current theme
|
||||
|
||||
let touchStartX = 0;
|
||||
let touchEndX = 0;
|
||||
|
||||
const applyTheme = (theme) => {
|
||||
document.documentElement.classList.remove('light', 'dark');
|
||||
document.documentElement.classList.add(theme);
|
||||
localStorage.setItem('theme', theme);
|
||||
currentTheme.value = theme;
|
||||
};
|
||||
|
||||
const toggleTheme = () => {
|
||||
const newTheme = currentTheme.value === 'light' ? 'dark' : 'light';
|
||||
applyTheme(newTheme);
|
||||
};
|
||||
|
||||
const totalPages = computed(() => {
|
||||
return Math.ceil(images.value.length / imagesPerPage);
|
||||
});
|
||||
|
||||
const paginatedImages = computed(() => {
|
||||
const start = (currentPage.value - 1) * imagesPerPage;
|
||||
const end = start + imagesPerPage;
|
||||
return images.value.slice(start, end);
|
||||
});
|
||||
|
||||
const showError = (message) => {
|
||||
errorMessage.value = message;
|
||||
setTimeout(() => {
|
||||
@@ -142,8 +160,6 @@ const applyStyle = (style, imageId) => {
|
||||
const keepStyledImage = (imageToKeep) => {
|
||||
console.log('Keeping styled image:', imageToKeep);
|
||||
// Implement API call to mark image as kept/permanent if needed
|
||||
// For now, just refresh the image list to show the new image
|
||||
fetchImages();
|
||||
currentOverlayComponent.value = null; // Close the display
|
||||
};
|
||||
|
||||
@@ -186,6 +202,16 @@ const handleSwipeGesture = () => {
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
// Apply theme from localStorage on mount
|
||||
const savedTheme = localStorage.getItem('theme');
|
||||
if (savedTheme) {
|
||||
applyTheme(savedTheme);
|
||||
} else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||
applyTheme('dark');
|
||||
} else {
|
||||
applyTheme('light');
|
||||
}
|
||||
|
||||
fetchImages();
|
||||
fetchInterval = setInterval(fetchImages, 5000);
|
||||
});
|
||||
@@ -216,4 +242,35 @@ onUnmounted(() => {
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.theme-toggle-button {
|
||||
margin-top: 10px;
|
||||
padding: 8px 15px;
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.theme-toggle-button:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
|
||||
.image-visibility-toggle-button {
|
||||
margin-top: 10px;
|
||||
padding: 8px 15px;
|
||||
background-color: #28a745;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
font-size: 0.9em;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.image-visibility-toggle-button:hover {
|
||||
background-color: #218838;
|
||||
}
|
||||
</style>
|
||||
@@ -6,15 +6,25 @@ import { createInertiaApp } from '@inertiajs/vue3';
|
||||
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
|
||||
import { ZiggyVue } from '../../vendor/tightenco/ziggy';
|
||||
|
||||
/* Font Awesome imports */
|
||||
import { library } from '@fortawesome/fontawesome-svg-core';
|
||||
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
|
||||
import { faPrint, faMagicWandSparkles, faXmark } from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
// Add icons to the library
|
||||
library.add(faPrint, faMagicWandSparkles, faXmark);
|
||||
|
||||
const appName = import.meta.env.VITE_APP_NAME || 'Laravel';
|
||||
|
||||
createInertiaApp({
|
||||
title: (title) => `${title} - ${appName}`,
|
||||
resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')),
|
||||
setup({ el, App, props, plugin }) {
|
||||
console.log('Inertia Page Props (app.js):', props.initialPage.props);
|
||||
return createApp({ render: () => h(App, props) })
|
||||
.use(plugin)
|
||||
.use(ZiggyVue)
|
||||
.component('font-awesome-icon', FontAwesomeIcon) // Register Font Awesome component
|
||||
.mixin({
|
||||
methods: {
|
||||
__: (key, replace = {}) => {
|
||||
|
||||
83
resources/js/custom/navigation-state.js
Normal file
83
resources/js/custom/navigation-state.js
Normal file
@@ -0,0 +1,83 @@
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const navigation = document.querySelector('.fi-main-nav');
|
||||
if (!navigation) return;
|
||||
|
||||
const KEY = 'navigation_state';
|
||||
const TABLE_PAGES_KEY = 'table_pages_state';
|
||||
|
||||
// Function to get the state from session via a custom endpoint
|
||||
const getState = () => {
|
||||
return JSON.parse(sessionStorage.getItem(KEY)) || {};
|
||||
};
|
||||
|
||||
// Function to save the state to session via a custom endpoint
|
||||
const saveState = (state) => {
|
||||
sessionStorage.setItem(KEY, JSON.stringify(state));
|
||||
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
|
||||
fetch('/api/admin/navigation-state', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-TOKEN': csrfToken,
|
||||
},
|
||||
body: JSON.stringify({ groups: state }),
|
||||
});
|
||||
};
|
||||
|
||||
// Function to get table page state
|
||||
const getTablePageState = () => {
|
||||
return JSON.parse(sessionStorage.getItem(TABLE_PAGES_KEY)) || {};
|
||||
};
|
||||
|
||||
// Function to save table page state
|
||||
const saveTablePageState = (tableId, page) => {
|
||||
let tablePages = getTablePageState();
|
||||
tablePages[tableId] = page;
|
||||
sessionStorage.setItem(TABLE_PAGES_KEY, JSON.stringify(tablePages));
|
||||
};
|
||||
|
||||
let currentState = getState();
|
||||
let currentTablePages = getTablePageState();
|
||||
|
||||
// Apply the saved navigation state on page load
|
||||
const groups = navigation.querySelectorAll('.fi-nav-group');
|
||||
groups.forEach(group => {
|
||||
const label = group.querySelector('.fi-nav-group-label').textContent.trim();
|
||||
if (currentState[label] === 'collapsed') {
|
||||
group.classList.add('collapsed');
|
||||
}
|
||||
});
|
||||
|
||||
// Add event listeners to save navigation state on click
|
||||
navigation.addEventListener('click', (e) => {
|
||||
const labelElement = e.target.closest('.fi-nav-group-label');
|
||||
if (!labelElement) return;
|
||||
|
||||
const group = labelElement.closest('.fi-nav-group');
|
||||
const label = labelElement.textContent.trim();
|
||||
|
||||
if (group.classList.contains('collapsed')) {
|
||||
currentState[label] = 'expanded';
|
||||
group.classList.remove('collapsed');
|
||||
} else {
|
||||
currentState[label] = 'collapsed';
|
||||
group.classList.add('collapsed');
|
||||
}
|
||||
|
||||
saveState(currentState);
|
||||
});
|
||||
|
||||
// Livewire hook to save table page when pagination changes
|
||||
Livewire.hook('component.initialized', (component) => {
|
||||
if (component.name.includes('table')) {
|
||||
const tableId = component.el.id;
|
||||
if (currentTablePages[tableId]) {
|
||||
component.set('tablePage', currentTablePages[tableId], false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Livewire.on('table-pagination-updated', (tableId, page) => {
|
||||
saveTablePageState(tableId, page);
|
||||
});
|
||||
});
|
||||
@@ -8,4 +8,10 @@ return [
|
||||
'image_deleted_successfully' => 'Bild erfolgreich gelöscht.',
|
||||
'image_or_provider_not_found' => 'Bild oder API-Anbieter nicht gefunden.',
|
||||
'no_styles_available' => 'Keine Stile oder API-Anbieter aktiviert/verfügbar.',
|
||||
'api.dark_mode' => 'Dunkler Modus',
|
||||
'api.light_mode' => 'Heller Modus',
|
||||
'gallery_title' => 'Eure Bilder aus der Fotobox',
|
||||
'navigation.previous' => 'Zurück',
|
||||
'navigation.next' => 'Weiter',
|
||||
'navigation.page_of' => 'Seite :currentPage von :totalPages',
|
||||
];
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'gallery_title' => 'Eure Bilder aus der Fotobox',
|
||||
'api.image_uploaded_successfully' => 'Bild erfolgreich hochgeladen',
|
||||
'api.style_or_provider_not_found' => 'Stil oder API-Anbieter nicht gefunden',
|
||||
'api.image_or_provider_not_found' => 'Bild oder API-Anbieter nicht gefunden',
|
||||
'navigation.previous' => 'Zurück',
|
||||
'navigation.next' => 'Weiter',
|
||||
'navigation.page_of' => 'Seite :currentPage von :totalPages',
|
||||
];
|
||||
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'gallery_heading' => 'Galerie Überschrift',
|
||||
|
||||
'saved_successfully' => 'Einstellungen erfolgreich gespeichert.',
|
||||
'save_button' => 'Speichern',
|
||||
'new' => 'Neu',
|
||||
];
|
||||
|
||||
@@ -8,4 +8,10 @@ return [
|
||||
'image_deleted_successfully' => 'Image deleted successfully.',
|
||||
'image_or_provider_not_found' => 'Image or API provider not found.',
|
||||
'no_styles_available' => 'No styles or API providers enabled/available.',
|
||||
'dark_mode' => 'Dark Mode',
|
||||
'light_mode' => 'Light Mode',
|
||||
'gallery_title' => 'Your images from the photobooth',
|
||||
'navigation.previous' => 'Previous',
|
||||
'navigation.next' => 'Next',
|
||||
'navigation.page_of' => 'Page :currentPage of :totalPages',
|
||||
];
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'gallery_title' => 'Your images from the photobooth',
|
||||
'api.image_uploaded_successfully' => 'Image uploaded successfully',
|
||||
'api.style_or_provider_not_found' => 'Style or API Provider not found',
|
||||
'api.image_or_provider_not_found' => 'Image or API Provider not found',
|
||||
'navigation.previous' => 'Previous',
|
||||
'navigation.next' => 'Next',
|
||||
'navigation.page_of' => 'Page :currentPage of :totalPages',
|
||||
];
|
||||
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'gallery_heading' => 'Gallery Heading',
|
||||
|
||||
'saved_successfully' => 'Settings saved successfully.',
|
||||
'save_button' => 'Save',
|
||||
'new' => 'New',
|
||||
];
|
||||
|
||||
@@ -16,10 +16,14 @@ use App\Http\Controllers\Api\StyleController;
|
||||
|
|
||||
*/
|
||||
|
||||
use App\Http\Controllers\Admin\NavigationStateController;
|
||||
|
||||
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
|
||||
return $request->user();
|
||||
});
|
||||
|
||||
Route::post('/admin/navigation-state', [NavigationStateController::class, 'store'])->middleware('auth:sanctum');
|
||||
|
||||
// Publicly accessible routes
|
||||
Route::get('/images', [ImageController::class, 'index']);
|
||||
Route::get('/styles', [StyleController::class, 'index']);
|
||||
|
||||
@@ -29,4 +29,14 @@ Route::middleware('auth')->group(function () {
|
||||
Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');
|
||||
});
|
||||
|
||||
require __DIR__.'/auth.php';
|
||||
require __DIR__.'/auth.php';
|
||||
|
||||
Route::get('/test-translations-en', function () {
|
||||
app()->setLocale('en');
|
||||
return response()->json(trans('api'));
|
||||
});
|
||||
|
||||
Route::get('/test-translations-de', function () {
|
||||
app()->setLocale('de');
|
||||
return response()->json(trans('api'));
|
||||
});
|
||||
245
stack.txt
Normal file
245
stack.txt
Normal file
@@ -0,0 +1,245 @@
|
||||
Filament \ Forms \ Components \ Actions \ Action : 21
|
||||
getComponent
|
||||
Filament \ Forms \ Components \ Actions \ Action : 56
|
||||
resolveDefaultClosureDependencyForEvaluationByName
|
||||
Filament \ Support \ Components \ ViewComponent : 57
|
||||
resolveClosureDependencyForEvaluation
|
||||
Filament \ Support \ Components \ ViewComponent : 32
|
||||
evaluate
|
||||
Filament \ Actions \ StaticAction : 101
|
||||
isHidden
|
||||
Filament \ Forms \ Components \ Actions \ ActionContainer : 31
|
||||
isHidden
|
||||
Filament \ Forms \ Components \ Component : 133
|
||||
isVisible
|
||||
Filament \ Forms \ ComponentContainer : 114
|
||||
Filament\Forms\Concerns\{closure}
|
||||
.unknown0
|
||||
array_filter
|
||||
Filament \ Forms \ ComponentContainer : 112
|
||||
getComponents
|
||||
C:\wwwroot\stylegallery\backend\vendor\filament\forms\resources\views\components\actions.blade.php : 23
|
||||
include
|
||||
App \ Filament \ Resources \ UserResource \ Pages \ EditUser : 37
|
||||
Livewire\Mechanisms\ExtendBlade\{closure}
|
||||
Livewire \ Mechanisms \ ExtendBlade \ ExtendedCompilerEngine : 38
|
||||
evaluatePath
|
||||
Illuminate \ View \ Engines \ CompilerEngine : 72
|
||||
get
|
||||
Livewire \ Mechanisms \ ExtendBlade \ ExtendedCompilerEngine : 16
|
||||
get
|
||||
Illuminate \ View \ View : 207
|
||||
getContents
|
||||
Illuminate \ View \ View : 190
|
||||
renderContents
|
||||
Illuminate \ View \ View : 159
|
||||
render
|
||||
Filament \ Support \ Components \ ViewComponent : 166
|
||||
toHtml
|
||||
C:\wwwroot\stylegallery\backend\vendor\laravel\framework\src\Illuminate\Support\helpers.php : 117
|
||||
e
|
||||
C:\wwwroot\stylegallery\backend\vendor\filament\forms\resources\views\component-container.blade.php : 59
|
||||
include
|
||||
App \ Filament \ Resources \ UserResource \ Pages \ EditUser : 37
|
||||
Livewire\Mechanisms\ExtendBlade\{closure}
|
||||
Livewire \ Mechanisms \ ExtendBlade \ ExtendedCompilerEngine : 38
|
||||
evaluatePath
|
||||
Illuminate \ View \ Engines \ CompilerEngine : 72
|
||||
get
|
||||
Livewire \ Mechanisms \ ExtendBlade \ ExtendedCompilerEngine : 16
|
||||
get
|
||||
Illuminate \ View \ View : 207
|
||||
getContents
|
||||
Illuminate \ View \ View : 190
|
||||
renderContents
|
||||
Illuminate \ View \ View : 159
|
||||
render
|
||||
Filament \ Support \ Components \ ViewComponent : 166
|
||||
toHtml
|
||||
C:\wwwroot\stylegallery\backend\vendor\laravel\framework\src\Illuminate\Support\helpers.php : 117
|
||||
e
|
||||
C:\wwwroot\stylegallery\backend\vendor\filament\forms\resources\views\components\section.blade.php : 25
|
||||
include
|
||||
App \ Filament \ Resources \ UserResource \ Pages \ EditUser : 37
|
||||
Livewire\Mechanisms\ExtendBlade\{closure}
|
||||
Livewire \ Mechanisms \ ExtendBlade \ ExtendedCompilerEngine : 38
|
||||
evaluatePath
|
||||
Illuminate \ View \ Engines \ CompilerEngine : 72
|
||||
get
|
||||
Livewire \ Mechanisms \ ExtendBlade \ ExtendedCompilerEngine : 16
|
||||
get
|
||||
Illuminate \ View \ View : 207
|
||||
getContents
|
||||
Illuminate \ View \ View : 190
|
||||
renderContents
|
||||
Illuminate \ View \ View : 159
|
||||
render
|
||||
Filament \ Support \ Components \ ViewComponent : 166
|
||||
toHtml
|
||||
C:\wwwroot\stylegallery\backend\vendor\laravel\framework\src\Illuminate\Support\helpers.php : 117
|
||||
e
|
||||
C:\wwwroot\stylegallery\backend\vendor\filament\forms\resources\views\component-container.blade.php : 59
|
||||
include
|
||||
App \ Filament \ Resources \ UserResource \ Pages \ EditUser : 37
|
||||
Livewire\Mechanisms\ExtendBlade\{closure}
|
||||
Livewire \ Mechanisms \ ExtendBlade \ ExtendedCompilerEngine : 38
|
||||
evaluatePath
|
||||
Illuminate \ View \ Engines \ CompilerEngine : 72
|
||||
get
|
||||
Livewire \ Mechanisms \ ExtendBlade \ ExtendedCompilerEngine : 16
|
||||
get
|
||||
Illuminate \ View \ View : 207
|
||||
getContents
|
||||
Illuminate \ View \ View : 190
|
||||
renderContents
|
||||
Illuminate \ View \ View : 159
|
||||
render
|
||||
Filament \ Support \ Components \ ViewComponent : 166
|
||||
toHtml
|
||||
C:\wwwroot\stylegallery\backend\vendor\laravel\framework\src\Illuminate\Support\helpers.php : 117
|
||||
e
|
||||
App \ Filament \ Resources \ UserResource \ Pages \ EditUser : 15
|
||||
{closure}
|
||||
C:\wwwroot\stylegallery\backend\vendor\filament\filament\resources\views\resources\pages\edit-record.blade.php : 31
|
||||
include
|
||||
App \ Filament \ Resources \ UserResource \ Pages \ EditUser : 37
|
||||
Livewire\Mechanisms\ExtendBlade\{closure}
|
||||
Livewire \ Mechanisms \ ExtendBlade \ ExtendedCompilerEngine : 38
|
||||
evaluatePath
|
||||
Illuminate \ View \ Engines \ CompilerEngine : 72
|
||||
get
|
||||
Livewire \ Mechanisms \ ExtendBlade \ ExtendedCompilerEngine : 16
|
||||
get
|
||||
Illuminate \ View \ View : 207
|
||||
getContents
|
||||
Illuminate \ View \ View : 190
|
||||
renderContents
|
||||
Illuminate \ View \ View : 159
|
||||
render
|
||||
Livewire \ Mechanisms \ HandleComponents \ HandleComponents : 259
|
||||
Livewire\Mechanisms\HandleComponents\{closure}
|
||||
Livewire \ Mechanisms \ HandleComponents \ HandleComponents : 303
|
||||
trackInRenderStack
|
||||
Livewire \ Mechanisms \ HandleComponents \ HandleComponents : 251
|
||||
render
|
||||
Livewire \ Mechanisms \ HandleComponents \ HandleComponents : 54
|
||||
mount
|
||||
Livewire \ LivewireManager : 73
|
||||
mount
|
||||
Livewire \ Component : 17
|
||||
Livewire\Features\SupportPageComponents\{closure}
|
||||
Livewire \ Features \ SupportPageComponents \ SupportPageComponents : 117
|
||||
interceptTheRenderOfTheComponentAndRetreiveTheLayoutConfiguration
|
||||
Livewire \ Component : 14
|
||||
__invoke
|
||||
Illuminate \ Routing \ ControllerDispatcher : 46
|
||||
dispatch
|
||||
Illuminate \ Routing \ Route : 259
|
||||
runController
|
||||
Illuminate \ Routing \ Route : 205
|
||||
run
|
||||
Illuminate \ Routing \ Router : 806
|
||||
Illuminate\Routing\{closure}
|
||||
Illuminate \ Pipeline \ Pipeline : 144
|
||||
Illuminate\Pipeline\{closure}
|
||||
Filament \ Http \ Middleware \ DispatchServingFilamentEvent : 15
|
||||
handle
|
||||
Illuminate \ Pipeline \ Pipeline : 183
|
||||
Illuminate\Pipeline\{closure}
|
||||
Filament \ Http \ Middleware \ DisableBladeIconComponents : 14
|
||||
handle
|
||||
Illuminate \ Pipeline \ Pipeline : 183
|
||||
Illuminate\Pipeline\{closure}
|
||||
Illuminate \ Routing \ Middleware \ SubstituteBindings : 50
|
||||
handle
|
||||
Illuminate \ Pipeline \ Pipeline : 183
|
||||
Illuminate\Pipeline\{closure}
|
||||
Illuminate \ Foundation \ Http \ Middleware \ VerifyCsrfToken : 78
|
||||
handle
|
||||
Illuminate \ Pipeline \ Pipeline : 183
|
||||
Illuminate\Pipeline\{closure}
|
||||
Illuminate \ Session \ Middleware \ AuthenticateSession : 60
|
||||
handle
|
||||
Illuminate \ Pipeline \ Pipeline : 183
|
||||
Illuminate\Pipeline\{closure}
|
||||
Illuminate \ Auth \ Middleware \ Authenticate : 57
|
||||
handle
|
||||
Illuminate \ Pipeline \ Pipeline : 183
|
||||
Illuminate\Pipeline\{closure}
|
||||
Illuminate \ View \ Middleware \ ShareErrorsFromSession : 49
|
||||
handle
|
||||
Illuminate \ Pipeline \ Pipeline : 183
|
||||
Illuminate\Pipeline\{closure}
|
||||
Illuminate \ Session \ Middleware \ StartSession : 121
|
||||
handleStatefulRequest
|
||||
Illuminate \ Session \ Middleware \ StartSession : 64
|
||||
handle
|
||||
Illuminate \ Pipeline \ Pipeline : 183
|
||||
Illuminate\Pipeline\{closure}
|
||||
Illuminate \ Cookie \ Middleware \ AddQueuedCookiesToResponse : 37
|
||||
handle
|
||||
Illuminate \ Pipeline \ Pipeline : 183
|
||||
Illuminate\Pipeline\{closure}
|
||||
Illuminate \ Cookie \ Middleware \ EncryptCookies : 67
|
||||
handle
|
||||
Illuminate \ Pipeline \ Pipeline : 183
|
||||
Illuminate\Pipeline\{closure}
|
||||
Filament \ Http \ Middleware \ SetUpPanel : 19
|
||||
handle
|
||||
Illuminate \ Pipeline \ Pipeline : 183
|
||||
Illuminate\Pipeline\{closure}
|
||||
Illuminate \ Pipeline \ Pipeline : 119
|
||||
then
|
||||
Illuminate \ Routing \ Router : 805
|
||||
runRouteWithinStack
|
||||
Illuminate \ Routing \ Router : 784
|
||||
runRoute
|
||||
Illuminate \ Routing \ Router : 748
|
||||
dispatchToRoute
|
||||
Illuminate \ Routing \ Router : 737
|
||||
dispatch
|
||||
Illuminate \ Foundation \ Http \ Kernel : 200
|
||||
Illuminate\Foundation\Http\{closure}
|
||||
Illuminate \ Pipeline \ Pipeline : 144
|
||||
Illuminate\Pipeline\{closure}
|
||||
Livewire \ Features \ SupportDisablingBackButtonCache \ DisableBackButtonCacheMiddleware : 19
|
||||
handle
|
||||
Illuminate \ Pipeline \ Pipeline : 183
|
||||
Illuminate\Pipeline\{closure}
|
||||
Illuminate \ Foundation \ Http \ Middleware \ TransformsRequest : 21
|
||||
handle
|
||||
Illuminate \ Foundation \ Http \ Middleware \ ConvertEmptyStringsToNull : 31
|
||||
handle
|
||||
Illuminate \ Pipeline \ Pipeline : 183
|
||||
Illuminate\Pipeline\{closure}
|
||||
Illuminate \ Foundation \ Http \ Middleware \ TransformsRequest : 21
|
||||
handle
|
||||
Illuminate \ Foundation \ Http \ Middleware \ TrimStrings : 40
|
||||
handle
|
||||
Illuminate \ Pipeline \ Pipeline : 183
|
||||
Illuminate\Pipeline\{closure}
|
||||
Illuminate \ Foundation \ Http \ Middleware \ ValidatePostSize : 27
|
||||
handle
|
||||
Illuminate \ Pipeline \ Pipeline : 183
|
||||
Illuminate\Pipeline\{closure}
|
||||
Illuminate \ Foundation \ Http \ Middleware \ PreventRequestsDuringMaintenance : 99
|
||||
handle
|
||||
Illuminate \ Pipeline \ Pipeline : 183
|
||||
Illuminate\Pipeline\{closure}
|
||||
Illuminate \ Http \ Middleware \ HandleCors : 62
|
||||
handle
|
||||
Illuminate \ Pipeline \ Pipeline : 183
|
||||
Illuminate\Pipeline\{closure}
|
||||
Illuminate \ Http \ Middleware \ TrustProxies : 39
|
||||
handle
|
||||
Illuminate \ Pipeline \ Pipeline : 183
|
||||
Illuminate\Pipeline\{closure}
|
||||
Illuminate \ Pipeline \ Pipeline : 119
|
||||
then
|
||||
Illuminate \ Foundation \ Http \ Kernel : 175
|
||||
sendRequestThroughRouter
|
||||
Illuminate \ Foundation \ Http \ Kernel : 144
|
||||
handle
|
||||
C:\wwwroot\stylegallery\backend\public\index.php : 51
|
||||
require_once
|
||||
C:\wwwroot\stylegallery\backend\vendor\laravel\framework\src\Illuminate\Foundation\resources\server.php : 16
|
||||
Reference in New Issue
Block a user