Files
alrahma_sunday_school_api/app/Http/Controllers/Api/UiController.php
T
2026-03-05 12:29:37 -05:00

212 lines
7.2 KiB
PHP
Executable File

<?php
namespace App\Http\Controllers\Api;
use Illuminate\Http\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
class UiController extends BaseApiController
{
protected string $defaultUserTimezone = 'America/New_York';
protected function styleConfig(): array
{
$styleCfg = config('Style');
if (is_object($styleCfg)) {
return [
'stylePalettes' => $styleCfg->stylePalettes ?? [],
'menuPalettes' => $styleCfg->menuPalettes ?? [],
];
}
return [
'stylePalettes' => $styleCfg['stylePalettes'] ?? [],
'menuPalettes' => $styleCfg['menuPalettes'] ?? [],
];
}
/**
* GET /api/v1/ui/style
* Get current UI style preferences
*/
public function getStyle()
{
$user = $this->getCurrentUser();
if (!$user) {
return $this->respondError('Authentication required', Response::HTTP_UNAUTHORIZED);
}
try {
$session = session();
$cfg = $this->styleConfig();
return $this->success([
'style_color' => $session->get('style_color'),
'menu_color' => $session->get('menu_color'),
'menu_custom_bg' => $session->get('menu_custom_bg'),
'menu_custom_text' => $session->get('menu_custom_text'),
'menu_custom_mode' => $session->get('menu_custom_mode'),
'available_palettes' => $cfg['stylePalettes'] ?? [],
'available_menus' => $cfg['menuPalettes'] ?? [],
], 'UI style preferences retrieved successfully');
} catch (\Throwable $e) {
log_message('error', 'UI style error: ' . $e->getMessage());
return $this->respondError('Failed to retrieve UI style', Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* POST /api/v1/ui/style
* Update UI style preferences via POST body
*/
public function updateStyle()
{
$user = $this->getCurrentUser();
if (!$user) {
return $this->respondError('Authentication required', Response::HTTP_UNAUTHORIZED);
}
$data = $this->payloadData();
if (empty($data)) {
return $this->respondError('Invalid request data', Response::HTTP_BAD_REQUEST);
}
return $this->processStyleUpdate($data);
}
/**
* GET /api/v1/ui/style (with query parameters)
* Update UI style preferences via GET parameters (for backward compatibility)
*/
public function style()
{
$user = $this->getCurrentUser();
if (!$user) {
return $this->respondError('Authentication required', Response::HTTP_UNAUTHORIZED);
}
// Get parameters from query string
$accent = (string) $this->request->getGet('accent');
$menu = (string) $this->request->getGet('menu');
$menuBg = (string) $this->request->getGet('menu_bg');
$menuTx = (string) $this->request->getGet('menu_text');
$menuMd = (string) $this->request->getGet('menu_mode');
$data = [];
if ($accent !== '') {
$data['accent'] = $accent;
}
if ($menu !== '') {
$data['menu'] = $menu;
}
if ($menuBg !== '') {
$data['menu_bg'] = $menuBg;
}
if ($menuTx !== '') {
$data['menu_text'] = $menuTx;
}
if ($menuMd !== '') {
$data['menu_mode'] = $menuMd;
}
if (empty($data)) {
// No parameters provided, return current style
return $this->getStyle();
}
return $this->processStyleUpdate($data);
}
/**
* Process style update from either GET or POST
*/
private function processStyleUpdate(array $data): JsonResponse
{
try {
$session = session();
$cfg = $this->styleConfig();
if (isset($data['accent']) && $data['accent'] !== '' && isset(($cfg['stylePalettes'] ?? [])[$data['accent']])) {
$session->put('style_color', $data['accent']);
}
if (isset($data['menu']) && $data['menu'] !== '') {
if (isset(($cfg['menuPalettes'] ?? [])[$data['menu']])) {
$session->put('menu_color', $data['menu']);
} elseif (strtolower($data['menu']) === 'custom' || (isset($data['menu_bg']) && $data['menu_bg'] !== '') || (isset($data['menu_text']) && $data['menu_text'] !== '')) {
// Allow custom menu colors
$bg = $this->normalizeHex($data['menu_bg'] ?? '');
$tx = $this->normalizeHex($data['menu_text'] ?? '');
if ($bg === '' && $tx === '') {
// no valid values; ignore
} else {
if ($bg === '') {
$bg = '#0f172a';
}
if ($tx === '') {
$tx = '#ffffff';
}
// Determine mode if requested auto or missing
$mode = isset($data['menu_mode']) && in_array($data['menu_mode'], ['light', 'dark'], true)
? $data['menu_mode']
: $this->autoModeForBg($bg);
$session->put('menu_color', 'custom');
$session->put('menu_custom_bg', $bg);
$session->put('menu_custom_text', $tx);
$session->put('menu_custom_mode', $mode);
}
}
}
return $this->success([
'style_color' => $session->get('style_color'),
'menu_color' => $session->get('menu_color'),
'menu_custom_bg' => $session->get('menu_custom_bg'),
'menu_custom_text' => $session->get('menu_custom_text'),
'menu_custom_mode' => $session->get('menu_custom_mode'),
], 'UI style updated successfully');
} catch (\Throwable $e) {
log_message('error', 'UI style update error: ' . $e->getMessage());
return $this->respondError('Failed to update UI style', Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
private function normalizeHex(string $hex): string
{
$h = trim($hex);
if ($h === '') {
return '';
}
if ($h[0] !== '#') {
$h = '#' . $h;
}
if (preg_match('/^#([0-9a-fA-F]{3})$/', $h, $m)) {
$r = $m[1][0];
$g = $m[1][1];
$b = $m[1][2];
return '#' . $r . $r . $g . $g . $b . $b;
}
if (preg_match('/^#([0-9a-fA-F]{6})$/', $h)) {
return strtoupper($h);
}
return '';
}
private function autoModeForBg(string $hexBg): string
{
$hex = ltrim($hexBg, '#');
if (strlen($hex) !== 6) {
return 'dark';
}
$r = hexdec(substr($hex, 0, 2));
$g = hexdec(substr($hex, 2, 2));
$b = hexdec(substr($hex, 4, 2));
$lum = (0.2126 * $r + 0.7152 * $g + 0.0722 * $b) / 255;
return $lum < 0.5 ? 'dark' : 'light';
}
}