feat(layout): Layout-Einstellungen, Dark-Mode, Logo, Hilfe-Menü
- Settings Key-Value Store (DB + Cache) - Einstellungen → Layout: Seitenname, Logo, Button-Farbe, Dark/Light-Mode - Hilfe-Menü (Ebene 0): Handbuch + Changelog im Browser - Navigation erweitert: Einstellungen-Dropdown + Hilfe-Dropdown - CHANGELOG v0.4.0 Version: 0.4.0
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Services\SettingsService;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class LayoutController extends Controller
|
||||
{
|
||||
public function __construct(private SettingsService $settings) {}
|
||||
|
||||
public function index(): View
|
||||
{
|
||||
return view('admin.layout.index', [
|
||||
'settings' => $this->settings->all(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(Request $request): RedirectResponse
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'site_name' => ['required', 'string', 'max:100'],
|
||||
'button_color' => ['required', 'string', 'regex:/^#[0-9a-fA-F]{6}$/'],
|
||||
'theme_mode' => ['required', 'in:light,dark'],
|
||||
'site_logo' => ['nullable', 'image', 'max:2048'],
|
||||
]);
|
||||
|
||||
// Logo-Upload verarbeiten
|
||||
if ($request->hasFile('site_logo')) {
|
||||
$path = $request->file('site_logo')->store('logos', 'public');
|
||||
$this->settings->set('site_logo', $path);
|
||||
}
|
||||
|
||||
$this->settings->setMany([
|
||||
'site_name' => $validated['site_name'],
|
||||
'button_color' => $validated['button_color'],
|
||||
'theme_mode' => $validated['theme_mode'],
|
||||
]);
|
||||
|
||||
return redirect()
|
||||
->route('admin.layout.index')
|
||||
->with('success', 'Layout-Einstellungen gespeichert.');
|
||||
}
|
||||
|
||||
public function removeLogo(): RedirectResponse
|
||||
{
|
||||
$this->settings->set('site_logo', '');
|
||||
|
||||
return redirect()
|
||||
->route('admin.layout.index')
|
||||
->with('success', 'Logo entfernt.');
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,7 @@ class UserController extends Controller
|
||||
|
||||
return redirect()
|
||||
->route('admin.users.index')
|
||||
->with('success', "Benutzer „{$user->name}" wurde angelegt.");
|
||||
->with('success', "Benutzer \"{$user->name}\" wurde angelegt.");
|
||||
}
|
||||
|
||||
public function edit(User $user): View
|
||||
@@ -79,7 +79,7 @@ class UserController extends Controller
|
||||
|
||||
return redirect()
|
||||
->route('admin.users.index')
|
||||
->with('success', "Benutzer „{$user->name}" wurde aktualisiert.");
|
||||
->with('success', "Benutzer \"{$user->name}\" wurde aktualisiert.");
|
||||
}
|
||||
|
||||
public function destroy(User $user): RedirectResponse
|
||||
@@ -95,6 +95,6 @@ class UserController extends Controller
|
||||
|
||||
return redirect()
|
||||
->route('admin.users.index')
|
||||
->with('success', "Benutzer „{$name}" wurde gelöscht.");
|
||||
->with('success', "Benutzer \"{$name}\" wurde gelöscht.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\View\View;
|
||||
|
||||
class HelpController extends Controller
|
||||
{
|
||||
public function manual(): View
|
||||
{
|
||||
return view('help.manual');
|
||||
}
|
||||
|
||||
public function changelog(): View
|
||||
{
|
||||
$changelogPath = base_path('CHANGELOG.md');
|
||||
$content = file_exists($changelogPath)
|
||||
? file_get_contents($changelogPath)
|
||||
: 'Kein Changelog gefunden.';
|
||||
|
||||
return view('help.changelog', compact('content'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Setting extends Model
|
||||
{
|
||||
protected $fillable = ['key', 'value'];
|
||||
|
||||
public static function get(string $key, mixed $default = null): mixed
|
||||
{
|
||||
return static::where('key', $key)->value('value') ?? $default;
|
||||
}
|
||||
|
||||
public static function set(string $key, mixed $value): void
|
||||
{
|
||||
static::updateOrCreate(['key' => $key], ['value' => $value]);
|
||||
}
|
||||
|
||||
public static function allAsArray(): array
|
||||
{
|
||||
return static::pluck('value', 'key')->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Services\SettingsService;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class SettingsServiceProvider extends ServiceProvider
|
||||
{
|
||||
public function register(): void
|
||||
{
|
||||
$this->app->singleton(SettingsService::class);
|
||||
}
|
||||
|
||||
public function boot(): void
|
||||
{
|
||||
// Settings nur laden wenn die Tabelle existiert (z.B. vor Migration schützen)
|
||||
if (!$this->app->runningInConsole() && Schema::hasTable('settings')) {
|
||||
$settings = $this->app->make(SettingsService::class)->all();
|
||||
|
||||
View::share('appSettings', $settings);
|
||||
} else {
|
||||
View::share('appSettings', [
|
||||
'site_name' => config('app.name'),
|
||||
'site_logo' => '',
|
||||
'button_color' => '#4f46e5',
|
||||
'theme_mode' => 'light',
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Setting;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
class SettingsService
|
||||
{
|
||||
private const CACHE_KEY = 'app_settings';
|
||||
private const CACHE_TTL = 3600;
|
||||
|
||||
public function all(): array
|
||||
{
|
||||
return Cache::remember(self::CACHE_KEY, self::CACHE_TTL, fn() => Setting::allAsArray());
|
||||
}
|
||||
|
||||
public function get(string $key, mixed $default = null): mixed
|
||||
{
|
||||
return $this->all()[$key] ?? $default;
|
||||
}
|
||||
|
||||
public function set(string $key, mixed $value): void
|
||||
{
|
||||
Setting::set($key, $value);
|
||||
Cache::forget(self::CACHE_KEY);
|
||||
}
|
||||
|
||||
public function setMany(array $data): void
|
||||
{
|
||||
foreach ($data as $key => $value) {
|
||||
Setting::set($key, $value);
|
||||
}
|
||||
Cache::forget(self::CACHE_KEY);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user