feat: add theme

This commit is contained in:
2026-06-14 15:06:11 +03:30
parent fb17f4c08b
commit b1e39dfabf
8 changed files with 258 additions and 7 deletions
+12 -6
View File
@@ -12,11 +12,11 @@ class SceneController extends Controller
// CONSOLIDATED: everything the scene-settings screen needs in one call.
public function settings()
{
$settings = UserSceneSetting::with('activeScene')
$settings = UserSceneSetting::with('activeScene.theme')
->firstOrNew(['user_id' => auth()->id()]);
return response()->json([
'scenes' => Scene::where('is_active', true)->orderBy('order')->get(),
'scenes' => Scene::with('theme')->where('is_active', true)->orderBy('order')->get(),
'settings' => [
'active_scene_id' => $settings->active_scene_id,
'active_scene' => $settings->activeScene,
@@ -55,7 +55,7 @@ public function updateSettings(Request $request)
public function index(Request $request)
{
$query = Scene::query();
$query = Scene::query()->with('theme');
if (!$request->boolean('include_inactive')) {
$query->where('is_active', true);
@@ -66,7 +66,7 @@ public function index(Request $request)
public function show($id)
{
return response()->json(Scene::findOrFail($id));
return response()->json(Scene::with('theme')->findOrFail($id));
}
// CREATE a scene with its image / video / sound uploads.
@@ -74,6 +74,7 @@ public function store(Request $request)
{
$data = $request->validate([
'name' => 'required|string|max:255',
'theme_id' => 'nullable|exists:themes,id',
'order' => 'nullable|integer',
'is_active' => 'nullable|boolean',
'image' => 'nullable|file|extensions:jpg,jpeg,png,gif,webp,bmp,svg|max:8192',
@@ -83,6 +84,7 @@ public function store(Request $request)
$scene = Scene::create([
'name' => $data['name'],
'theme_id' => $data['theme_id'] ?? null,
'order' => $data['order'] ?? 0,
'is_active' => $data['is_active'] ?? true,
'image_path' => $request->hasFile('image') ? $request->file('image')->store('scenes/images', 'public') : null,
@@ -92,7 +94,7 @@ public function store(Request $request)
return response()->json([
'message' => 'Scene created successfully',
'scene' => $scene,
'scene' => $scene->load('theme'),
], 201);
}
@@ -103,6 +105,7 @@ public function update(Request $request, $id)
$data = $request->validate([
'name' => 'sometimes|string|max:255',
'theme_id' => 'nullable|exists:themes,id',
'order' => 'nullable|integer',
'is_active' => 'nullable|boolean',
'image' => 'nullable|file|extensions:jpg,jpeg,png,gif,webp,bmp,svg|max:8192',
@@ -113,6 +116,9 @@ public function update(Request $request, $id)
if (array_key_exists('name', $data)) {
$scene->name = $data['name'];
}
if (array_key_exists('theme_id', $data)) {
$scene->theme_id = $data['theme_id'];
}
if (array_key_exists('order', $data)) {
$scene->order = $data['order'];
}
@@ -134,7 +140,7 @@ public function update(Request $request, $id)
return response()->json([
'message' => 'Scene updated successfully',
'scene' => $scene,
'scene' => $scene->load('theme'),
]);
}
+26
View File
@@ -0,0 +1,26 @@
<?php
namespace App\Http\Controllers;
use App\Models\Theme;
use Illuminate\Http\Request;
class ThemeController extends Controller
{
// List themes (for the scene theme picker and the app).
public function index(Request $request)
{
$query = Theme::query();
if (!$request->boolean('include_inactive')) {
$query->where('is_active', true);
}
return response()->json($query->orderBy('order')->get());
}
public function show($id)
{
return response()->json(Theme::findOrFail($id));
}
}
+7 -1
View File
@@ -3,16 +3,22 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Scene extends Model
{
protected $fillable = ['name', 'image_path', 'video_path', 'sound_path', 'order', 'is_active'];
protected $fillable = ['theme_id', 'name', 'image_path', 'video_path', 'sound_path', 'order', 'is_active'];
protected $casts = [
'is_active' => 'boolean',
'order' => 'integer',
];
public function theme(): BelongsTo
{
return $this->belongsTo(Theme::class);
}
protected $appends = ['image_url', 'video_url', 'sound_url', 'has_video'];
public function getImageUrlAttribute(): ?string
+22
View File
@@ -0,0 +1,22 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Theme extends Model
{
protected $fillable = ['key', 'name', 'colors', 'order', 'is_active'];
protected $casts = [
'colors' => 'array',
'is_active' => 'boolean',
'order' => 'integer',
];
public function scenes(): HasMany
{
return $this->hasMany(Scene::class);
}
}