15bab87998
- SpaController: injects data-theme on <html> and window.__PF_USER__ before JS
hydrates — theme applied without FOUC; no initial API call needed for user data
- UserApiController: PATCH /api/user/theme validates against 6 allowed theme IDs,
persists to user.theme column, returns {theme}
- useTheme composable: applyTheme() sets html[data-theme], saveTheme() calls API
and falls back with toast on error
- SettingsView: 3-col theme grid with swatch previews, aria-checked radio semantics,
active indicator; Sign out link; signed-in email display
- App.vue: onMounted syncs Pinia theme state with SpaController-stamped html[data-theme]
Verified: data-theme injected on / load; PATCH saves to DB; reload shows persisted theme
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
47 lines
1.3 KiB
PHP
47 lines
1.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Controller;
|
|
|
|
use App\Entity\User;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
use Symfony\Component\Routing\Attribute\Route;
|
|
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
|
|
|
#[Route('/api/user')]
|
|
#[IsGranted('ROLE_USER')]
|
|
class UserApiController extends AbstractController
|
|
{
|
|
private const VALID_THEMES = [
|
|
'warm-craft',
|
|
'playful-pop',
|
|
'sage-cream',
|
|
'dusty-mauve',
|
|
'ocean-dusk',
|
|
'honey-slate',
|
|
];
|
|
|
|
#[Route('/theme', name: 'api_user_theme', methods: ['PATCH'])]
|
|
public function updateTheme(Request $request, EntityManagerInterface $em): JsonResponse
|
|
{
|
|
$body = json_decode($request->getContent(), true);
|
|
$theme = $body['theme'] ?? null;
|
|
|
|
if (!is_string($theme) || !in_array($theme, self::VALID_THEMES, true)) {
|
|
return $this->json(['error' => 'Invalid theme'], Response::HTTP_UNPROCESSABLE_ENTITY);
|
|
}
|
|
|
|
/** @var User $user */
|
|
$user = $this->getUser();
|
|
$user->setTheme($theme);
|
|
$em->flush();
|
|
|
|
return $this->json(['theme' => $theme]);
|
|
}
|
|
}
|