feat(nav): FAQ shows all 8 sections + drag-drop reorder in Settings
FAQ sections were only 4 (service/crm/depozit/finante) even though the sidebar has 8. Added the missing 4 to Hints::AREAS with proper icons + accent colors: 📊 Analiză (pink) 📣 Marketing (orange) 🛒 Magazin (cyan) ⚙️ Admin (slate) Retagged 15 hints that were shoved into wrong areas as a workaround (admin.*/marketing.*/shop.*/analytics.* now use the matching bucket). FAQ blade reads accent color from the AREAS registry instead of a hardcoded local map. Also added per-tenant navigation group ordering: - Settings → new "Ordine meniu lateral" section with a Filament Repeater that has reorderable buttons (drag/arrow buttons) but no add/delete (fixed list of 8 groups) - Persisted to settings.nav_group_order as an array of keys - New ConfigureNavGroups middleware (runs after ResolveTenant on the web stack) reads the current tenant's order and calls $panel->navigationGroups([...]) so the sidebar renders in that order per-request Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -60,6 +60,8 @@ class Settings extends Page
|
||||
'services' => isset($settings['services']) ? implode(', ', (array) $settings['services']) : '',
|
||||
'cars' => isset($settings['cars']) ? implode(', ', (array) $settings['cars']) : '',
|
||||
'faq_video_url' => $settings['faq_video_url'] ?? null,
|
||||
'nav_group_order' => collect($settings['nav_group_order'] ?? \App\Http\Middleware\ConfigureNavGroups::DEFAULT_ORDER)
|
||||
->map(fn ($k) => ['key' => $k])->all(),
|
||||
'notify_wo_ready' => $notify['wo_ready'] ?? true,
|
||||
'notify_payment' => $notify['payment'] ?? true,
|
||||
'notify_appointment' => $notify['appointment'] ?? true,
|
||||
@@ -155,6 +157,28 @@ class Settings extends Page
|
||||
->placeholder('https://www.youtube.com/watch?v=... sau https://vimeo.com/...')
|
||||
->helperText(__('Afișat în pagina FAQ ca player embedded. Lasă gol pentru a-l ascunde.')),
|
||||
]),
|
||||
Schemas\Components\Section::make(__('Ordine meniu lateral'))
|
||||
->description(__('Trage grupurile pentru a schimba ordinea lor în sidebar-ul stâng.'))
|
||||
->columns(1)
|
||||
->schema([
|
||||
Forms\Components\Repeater::make('nav_group_order')
|
||||
->label('')
|
||||
->schema([
|
||||
Forms\Components\Select::make('key')
|
||||
->label(__('Grup'))
|
||||
->options(array_combine(
|
||||
\App\Http\Middleware\ConfigureNavGroups::DEFAULT_ORDER,
|
||||
array_map(fn ($k) => __('nav.group.' . $k), \App\Http\Middleware\ConfigureNavGroups::DEFAULT_ORDER),
|
||||
))
|
||||
->required()
|
||||
->distinct(),
|
||||
])
|
||||
->reorderable()
|
||||
->reorderableWithButtons()
|
||||
->addable(false)
|
||||
->deletable(false)
|
||||
->columnSpanFull(),
|
||||
]),
|
||||
Schemas\Components\Section::make(__('Logo & favicon'))
|
||||
->columns(2)
|
||||
->schema([
|
||||
@@ -275,6 +299,8 @@ class Settings extends Page
|
||||
'services' => array_values(array_filter(array_map('trim', explode(',', (string) ($data['services'] ?? ''))))),
|
||||
'cars' => array_values(array_filter(array_map('trim', explode(',', (string) ($data['cars'] ?? ''))))),
|
||||
'faq_video_url' => trim((string) ($data['faq_video_url'] ?? '')) ?: null,
|
||||
'nav_group_order' => collect($data['nav_group_order'] ?? [])
|
||||
->pluck('key')->filter()->values()->all() ?: null,
|
||||
'notify' => [
|
||||
'wo_ready' => (bool) ($data['notify_wo_ready'] ?? true),
|
||||
'payment' => (bool) ($data['notify_payment'] ?? true),
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Tenancy\TenantManager;
|
||||
use Closure;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Navigation\NavigationGroup;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* Read the current tenant's preferred navigation group order from
|
||||
* settings.nav_group_order and apply it to the tenant panel so the
|
||||
* sidebar groups render in that order.
|
||||
*
|
||||
* Falls back to the built-in default order when the setting is empty.
|
||||
*/
|
||||
class ConfigureNavGroups
|
||||
{
|
||||
/** Default order (matches the labels defined in lang/{ro,ru,en}/nav.php). */
|
||||
public const DEFAULT_ORDER = [
|
||||
'CRM',
|
||||
'Service',
|
||||
'Depozit',
|
||||
'Finanțe',
|
||||
'Analiză',
|
||||
'Marketing',
|
||||
'Magazin',
|
||||
'Admin',
|
||||
];
|
||||
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
$tenant = app(TenantManager::class)->current();
|
||||
if (! $tenant) return $next($request);
|
||||
|
||||
$order = (array) ($tenant->settings['nav_group_order'] ?? []);
|
||||
if (empty($order)) $order = self::DEFAULT_ORDER;
|
||||
|
||||
// Only touch the tenant panel — bail if the current request isn't in it.
|
||||
$panel = Filament::getCurrentPanel();
|
||||
if (! $panel || $panel->getId() !== 'tenant') return $next($request);
|
||||
|
||||
$groups = array_map(
|
||||
fn (string $key) => NavigationGroup::make(__('nav.group.' . $key)),
|
||||
$order,
|
||||
);
|
||||
$panel->navigationGroups($groups);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
+23
-19
@@ -21,10 +21,14 @@ namespace App\Support;
|
||||
class Hints
|
||||
{
|
||||
public const AREAS = [
|
||||
'service' => ['label' => ['ro' => 'Fișe lucru', 'ru' => 'Заказ-наряды', 'en' => 'Work orders'], 'icon' => '🔧'],
|
||||
'crm' => ['label' => ['ro' => 'CRM & Clienți', 'ru' => 'CRM и клиенты', 'en' => 'CRM & Customers'], 'icon' => '👥'],
|
||||
'depozit' => ['label' => ['ro' => 'Depozit & Piese', 'ru' => 'Склад и запчасти', 'en' => 'Warehouse & Parts'], 'icon' => '📦'],
|
||||
'finante' => ['label' => ['ro' => 'Finanțe', 'ru' => 'Финансы', 'en' => 'Finance'], 'icon' => '💰'],
|
||||
'service' => ['label' => ['ro' => 'Service (fișe lucru)', 'ru' => 'Сервис (заказы)', 'en' => 'Service (work orders)'], 'icon' => '🔧', 'color' => '#0ea5e9'],
|
||||
'crm' => ['label' => ['ro' => 'CRM & Clienți', 'ru' => 'CRM и клиенты', 'en' => 'CRM & Customers'], 'icon' => '👥', 'color' => '#8b5cf6'],
|
||||
'depozit' => ['label' => ['ro' => 'Depozit & Piese', 'ru' => 'Склад и запчасти', 'en' => 'Warehouse & Parts'], 'icon' => '📦', 'color' => '#f59e0b'],
|
||||
'finante' => ['label' => ['ro' => 'Finanțe', 'ru' => 'Финансы', 'en' => 'Finance'], 'icon' => '💰', 'color' => '#10b981'],
|
||||
'analiza' => ['label' => ['ro' => 'Analiză & Rapoarte', 'ru' => 'Аналитика и отчёты', 'en' => 'Analytics & Reports'], 'icon' => '📊', 'color' => '#ec4899'],
|
||||
'marketing' => ['label' => ['ro' => 'Marketing', 'ru' => 'Маркетинг', 'en' => 'Marketing'], 'icon' => '📣', 'color' => '#f97316'],
|
||||
'magazin' => ['label' => ['ro' => 'Magazin online', 'ru' => 'Онлайн-магазин', 'en' => 'Online shop'], 'icon' => '🛒', 'color' => '#06b6d4'],
|
||||
'admin' => ['label' => ['ro' => 'Administrare', 'ru' => 'Администрирование', 'en' => 'Administration'], 'icon' => '⚙️', 'color' => '#64748b'],
|
||||
];
|
||||
|
||||
/** @return array<string, array{area:string,title:array,body:array,links?:array,next?:array}> */
|
||||
@@ -419,7 +423,7 @@ class Hints
|
||||
|
||||
// Magazin
|
||||
'shop.orders.overview' => [
|
||||
'area' => 'crm', 'title' => ['ro' => 'Comenzi online (magazin)', 'ru' => 'Онлайн-заказы (магазин)', 'en' => 'Online orders (shop)'],
|
||||
'area' => 'magazin', 'title' => ['ro' => 'Comenzi online (magazin)', 'ru' => 'Онлайн-заказы (магазин)', 'en' => 'Online orders (shop)'],
|
||||
'body' => [
|
||||
'ro' => 'Comenzi primite din magazin-ul public (subdomeniu tenant). Poți accepta/refuza, marca livrat, genera factură. Stocul scade automat la livrare.',
|
||||
'ru' => 'Заказы из публичного магазина (тенант-поддомен). Принять/отклонить, отметить доставку, счёт. Остаток списывается при доставке.',
|
||||
@@ -427,7 +431,7 @@ class Hints
|
||||
],
|
||||
],
|
||||
'shop.customers.overview' => [
|
||||
'area' => 'crm', 'title' => ['ro' => 'Clienți magazin', 'ru' => 'Клиенты магазина', 'en' => 'Shop customers'],
|
||||
'area' => 'magazin', 'title' => ['ro' => 'Clienți magazin', 'ru' => 'Клиенты магазина', 'en' => 'Shop customers'],
|
||||
'body' => [
|
||||
'ro' => 'Clienți care s-au înregistrat pe magazin-ul online (separați de baza CRM service). Poți converti într-un client CRM cu 1 click atunci când vine în service.',
|
||||
'ru' => 'Клиенты онлайн-магазина (отдельно от CRM-базы). При приезде в сервис — 1 клик → CRM-клиент.',
|
||||
@@ -437,7 +441,7 @@ class Hints
|
||||
|
||||
// Marketing
|
||||
'marketing.channels.overview' => [
|
||||
'area' => 'crm', 'title' => ['ro' => 'Canale marketing', 'ru' => 'Маркетинговые каналы', 'en' => 'Marketing channels'],
|
||||
'area' => 'marketing', 'title' => ['ro' => 'Canale marketing', 'ru' => 'Маркетинговые каналы', 'en' => 'Marketing channels'],
|
||||
'body' => [
|
||||
'ro' => 'Sursele de leaduri: Google Ads, Facebook, recomandare, walk-in, telefon direct. Fiecare cerere se atribuie unui canal → vezi în Rapoarte care canal aduce cel mai bun ROI.',
|
||||
'ru' => 'Источники лидов: Google Ads, Facebook, рекомендация, walk-in, звонок. Каждая заявка привязывается к каналу → в Отчётах видишь ROI по каналу.',
|
||||
@@ -445,7 +449,7 @@ class Hints
|
||||
],
|
||||
],
|
||||
'marketing.templates.overview' => [
|
||||
'area' => 'crm', 'title' => ['ro' => 'Template-uri mesaje', 'ru' => 'Шаблоны сообщений', 'en' => 'Message templates'],
|
||||
'area' => 'marketing', 'title' => ['ro' => 'Template-uri mesaje', 'ru' => 'Шаблоны сообщений', 'en' => 'Message templates'],
|
||||
'body' => [
|
||||
'ro' => 'Mesaje pre-scrise pentru trimitere rapidă către client: „Fișa e gata", „Confirmare programare", „Ofertă piesă". Suportă variabile ({client.name}, {wo.number}, {eta}). Se folosesc din Chat client sau notificări automate.',
|
||||
'ru' => 'Готовые сообщения: «Заказ готов», «Подтверждение записи», «Оферта на запчасть». Поддерживают переменные ({client.name}, {wo.number}, {eta}).',
|
||||
@@ -455,7 +459,7 @@ class Hints
|
||||
|
||||
// Analiză
|
||||
'analytics.recommendations.overview' => [
|
||||
'area' => 'finante', 'title' => ['ro' => 'Recomandări automate', 'ru' => 'Автоматические рекомендации', 'en' => 'Auto recommendations'],
|
||||
'area' => 'analiza', 'title' => ['ro' => 'Recomandări automate', 'ru' => 'Автоматические рекомендации', 'en' => 'Auto recommendations'],
|
||||
'body' => [
|
||||
'ro' => 'Sistemul analizează activitatea și îți spune: „Piese cu stoc mort de X luni", „Manopere neprofitabile", „Clienți inactivi > 6 luni". Fiecare are un buton de acțiune (ex: „Trimite ofertă").',
|
||||
'ru' => 'Система анализирует и подсказывает: «Мёртвый сток X месяцев», «Убыточные работы», «Клиенты 6+ мес. без визитов». Кнопка действия рядом (напр. «Отправить оффер»).',
|
||||
@@ -463,7 +467,7 @@ class Hints
|
||||
],
|
||||
],
|
||||
'analytics.ai.overview' => [
|
||||
'area' => 'finante', 'title' => ['ro' => 'Asistent AI', 'ru' => 'AI-ассистент', 'en' => 'AI assistant'],
|
||||
'area' => 'analiza', 'title' => ['ro' => 'Asistent AI', 'ru' => 'AI-ассистент', 'en' => 'AI assistant'],
|
||||
'body' => [
|
||||
'ro' => 'Întreabă în limbaj natural: „Cât am câștigat luna trecută?", „Care e piesa cea mai vândută la BMW-uri?", „Ce mecanic e cel mai productiv?". AI-ul răspunde din datele tale, cu link-uri către raportul relevant.',
|
||||
'ru' => 'Спрашивай на естественном языке: «Сколько заработал в прошлом месяце?», «Какая запчасть чаще продаётся на BMW?», «Кто самый продуктивный механик?». AI отвечает по твоим данным + ссылки на отчёты.',
|
||||
@@ -471,7 +475,7 @@ class Hints
|
||||
],
|
||||
],
|
||||
'analytics.workload.overview' => [
|
||||
'area' => 'finante', 'title' => ['ro' => 'Încărcare STO', 'ru' => 'Загрузка СТО', 'en' => 'Workshop load'],
|
||||
'area' => 'analiza', 'title' => ['ro' => 'Încărcare STO', 'ru' => 'Загрузка СТО', 'en' => 'Workshop load'],
|
||||
'body' => [
|
||||
'ro' => 'Grafic pe post × zi cu ore rezervate + capacitate. Roșu = supra-încărcat, verde = liber. Ideal pentru planificarea programărilor și evitarea aglomerării unui maistru.',
|
||||
'ru' => 'График по посту × день: занятые часы + мощность. Красный — перегруз, зелёный — свободно. Помогает планировать записи.',
|
||||
@@ -481,7 +485,7 @@ class Hints
|
||||
|
||||
// Admin
|
||||
'admin.users.overview' => [
|
||||
'area' => 'crm', 'title' => ['ro' => 'Utilizatori (echipa)', 'ru' => 'Пользователи (команда)', 'en' => 'Users (team)'],
|
||||
'area' => 'admin', 'title' => ['ro' => 'Utilizatori (echipa)', 'ru' => 'Пользователи (команда)', 'en' => 'Users (team)'],
|
||||
'body' => [
|
||||
'ro' => 'Invită oameni pe email — primesc link de acceptare + parolă temporară. Alocare rol (owner/admin/master/accountant/receptionist) → rolul definește ce văd și ce pot modifica. Dezactivarea unui user îl blochează fără să șterge datele.',
|
||||
'ru' => 'Приглашай по email — пользователь получает ссылку + временный пароль. Роль (owner/admin/master/accountant/receptionist) — определяет права. Деактивация блокирует без удаления данных.',
|
||||
@@ -489,7 +493,7 @@ class Hints
|
||||
],
|
||||
],
|
||||
'admin.roles.overview' => [
|
||||
'area' => 'crm', 'title' => ['ro' => 'Roluri & drepturi', 'ru' => 'Роли и права', 'en' => 'Roles & permissions'],
|
||||
'area' => 'admin', 'title' => ['ro' => 'Roluri & drepturi', 'ru' => 'Роли и права', 'en' => 'Roles & permissions'],
|
||||
'body' => [
|
||||
'ro' => 'Fiecare rol are un set de permisiuni granulare (poate vedea marja internă? poate șterge fișe? poate exporta rapoarte?). Owner-ul are toate. Poți crea roluri custom pentru cazuri speciale.',
|
||||
'ru' => 'У каждой роли — набор гранулярных прав (видит внутреннюю маржу? может удалять? экспортировать?). У Owner — все. Можно создать кастомные роли.',
|
||||
@@ -497,7 +501,7 @@ class Hints
|
||||
],
|
||||
],
|
||||
'admin.posts.overview' => [
|
||||
'area' => 'service', 'title' => ['ro' => 'Posturi de lucru', 'ru' => 'Посты (рабочие места)', 'en' => 'Work posts'],
|
||||
'area' => 'admin', 'title' => ['ro' => 'Posturi de lucru', 'ru' => 'Посты (рабочие места)', 'en' => 'Work posts'],
|
||||
'body' => [
|
||||
'ro' => 'Locurile fizice unde se face lucrarea: „Elevator 1", „Elevator 2", „Zona geometrie", „Vopsitorie". Fiecare post are un maistru default (opțional). Se folosesc în Calendar pentru gruparea programărilor.',
|
||||
'ru' => 'Физические места работ: «Подъёмник 1», «Развал-схождение», «Покраска». У поста может быть мастер по умолчанию. Используются в Календаре для группировки.',
|
||||
@@ -505,7 +509,7 @@ class Hints
|
||||
],
|
||||
],
|
||||
'admin.settings.overview' => [
|
||||
'area' => 'service', 'title' => ['ro' => 'Setări service', 'ru' => 'Настройки сервиса', 'en' => 'Service settings'],
|
||||
'area' => 'admin', 'title' => ['ro' => 'Setări service', 'ru' => 'Настройки сервиса', 'en' => 'Service settings'],
|
||||
'body' => [
|
||||
'ro' => 'Config-ul general al service-ului: nume, logo, culoare temă, program de lucru, adresă, telefon public, moneda, contul bancar pentru facturi. Modificările sunt vizibile imediat pentru toți userii.',
|
||||
'ru' => 'Общий конфиг сервиса: имя, лого, цвет темы, график, адрес, телефон, валюта, банк для счетов. Изменения видны всем сразу.',
|
||||
@@ -513,7 +517,7 @@ class Hints
|
||||
],
|
||||
],
|
||||
'admin.integrations.overview' => [
|
||||
'area' => 'service', 'title' => ['ro' => 'Integrări (Telegram/WhatsApp/Google/Facebook)', 'ru' => 'Интеграции', 'en' => 'Integrations'],
|
||||
'area' => 'admin', 'title' => ['ro' => 'Integrări (Telegram/WhatsApp/Google/Facebook)', 'ru' => 'Интеграции', 'en' => 'Integrations'],
|
||||
'body' => [
|
||||
'ro' => 'Activează canale: Telegram bot (token de la @BotFather), WhatsApp Business (token Facebook), Google Ads, Facebook Lead Ads. După activare, mesajele/lead-urile intră automat în CRM.',
|
||||
'ru' => 'Активируй каналы: Telegram-бот (токен от @BotFather), WhatsApp Business (Facebook), Google Ads, Facebook Lead Ads. После активации всё уходит в CRM автоматом.',
|
||||
@@ -521,7 +525,7 @@ class Hints
|
||||
],
|
||||
],
|
||||
'admin.tokens.overview' => [
|
||||
'area' => 'service', 'title' => ['ro' => 'API Tokens', 'ru' => 'API-токены', 'en' => 'API tokens'],
|
||||
'area' => 'admin', 'title' => ['ro' => 'API Tokens', 'ru' => 'API-токены', 'en' => 'API tokens'],
|
||||
'body' => [
|
||||
'ro' => 'Token-uri pentru integrări externe (aplicații mobile, script-uri, terți). Fiecare token are un nume + drepturi. Tokenul se afișează O SINGURĂ DATĂ la creare — copiază-l imediat.',
|
||||
'ru' => 'Токены для внешних интеграций (мобильные приложения, скрипты). У каждого — имя + права. Токен показывается ОДИН РАЗ при создании — копируй сразу.',
|
||||
@@ -529,7 +533,7 @@ class Hints
|
||||
],
|
||||
],
|
||||
'admin.backup.overview' => [
|
||||
'area' => 'service', 'title' => ['ro' => 'Backup date', 'ru' => 'Резервные копии', 'en' => 'Data backup'],
|
||||
'area' => 'admin', 'title' => ['ro' => 'Backup date', 'ru' => 'Резервные копии', 'en' => 'Data backup'],
|
||||
'body' => [
|
||||
'ro' => 'Descarcă un snapshot complet al datelor tenantului (DB + fișiere media) sub formă de arhivă. Recomandat: o dată pe lună. Se poate importa înapoi manual (contactează suport).',
|
||||
'ru' => 'Скачивай снапшот всех данных (БД + медиа) архивом. Рекомендуется раз в месяц. Восстановление — через поддержку.',
|
||||
@@ -537,7 +541,7 @@ class Hints
|
||||
],
|
||||
],
|
||||
'admin.activity.overview' => [
|
||||
'area' => 'service', 'title' => ['ro' => 'Jurnal activitate', 'ru' => 'Журнал активности', 'en' => 'Activity log'],
|
||||
'area' => 'admin', 'title' => ['ro' => 'Jurnal activitate', 'ru' => 'Журнал активности', 'en' => 'Activity log'],
|
||||
'body' => [
|
||||
'ro' => 'Audit-log complet: cine, ce, când. Utile pentru investigație (ex: „cine a șters fișa X?"). Filtrează pe user, pe entitate, pe interval. Se păstrează 12 luni.',
|
||||
'ru' => 'Полный аудит: кто, что, когда. Полезно для расследований («кто удалил заказ X?»). Фильтры: пользователь, сущность, период. Хранится 12 месяцев.',
|
||||
|
||||
@@ -31,6 +31,7 @@ return Application::configure(basePath: dirname(__DIR__))
|
||||
\App\Http\Middleware\ResolveTenant::class,
|
||||
\App\Http\Middleware\CheckTenantStatus::class,
|
||||
\App\Http\Middleware\SetLocale::class,
|
||||
\App\Http\Middleware\ConfigureNavGroups::class,
|
||||
]);
|
||||
|
||||
// API routes also need tenant resolution by host so the same
|
||||
|
||||
@@ -949,6 +949,7 @@
|
||||
"Grafic": "Chart",
|
||||
"Gravitate": "Severity",
|
||||
"Gravă": "Severe",
|
||||
"Grup": "Group",
|
||||
"Grupare:": "Group:",
|
||||
"Grupează manopere + piese frecvente într-un șablon (ex: „Schimb ulei complet": "Grupează manopere + piese frecvente într-un șablon (ex: „Schimb ulei complet",
|
||||
"Grupează manopere + piese frecvente într-un șablon (ex: „Schimb ulei complet\") și aplică-l pe o fișă cu un click.": "Grupează manopere + piese frecvente într-un șablon (ex: „Schimb ulei complet\") și aplică-l pe o fișă cu un click.",
|
||||
@@ -1428,6 +1429,7 @@
|
||||
"Order number": "Order number",
|
||||
"Orders": "Orders",
|
||||
"Ordine": "Order",
|
||||
"Ordine meniu lateral": "Sidebar menu order",
|
||||
"Ordonare": "Sort",
|
||||
"Ordonat": "Sorted",
|
||||
"Ordonează după": "Sort by",
|
||||
@@ -2105,6 +2107,7 @@
|
||||
"Tracking client": "Client tracking",
|
||||
"Tracțiune": "Drive",
|
||||
"Trage fișierul aici": "Drop file here",
|
||||
"Trage grupurile pentru a schimba ordinea lor în sidebar-ul stâng.": "Drag groups to change their order in the left sidebar.",
|
||||
"Transfer": "Transfer",
|
||||
"Transfer bancar": "Bank transfer",
|
||||
"Transfer bancar: pune doar IBAN-ul tău, fără cont gateway": "Transfer bancar: pune doar IBAN-ul tău, fără cont gateway",
|
||||
|
||||
@@ -949,6 +949,7 @@
|
||||
"Grafic": "График",
|
||||
"Gravitate": "Тяжесть",
|
||||
"Gravă": "Тяжёлое",
|
||||
"Grup": "Группа",
|
||||
"Grupare:": "Группировка:",
|
||||
"Grupează manopere + piese frecvente într-un șablon (ex: „Schimb ulei complet": "Grupează manopere + piese frecvente într-un șablon (ex: „Schimb ulei complet",
|
||||
"Grupează manopere + piese frecvente într-un șablon (ex: „Schimb ulei complet\") și aplică-l pe o fișă cu un click.": "Grupează manopere + piese frecvente într-un șablon (ex: „Schimb ulei complet\") și aplică-l pe o fișă cu un click.",
|
||||
@@ -1428,6 +1429,7 @@
|
||||
"Order number": "№ заказа",
|
||||
"Orders": "Заказы",
|
||||
"Ordine": "Порядок",
|
||||
"Ordine meniu lateral": "Порядок бокового меню",
|
||||
"Ordonare": "Сортировка",
|
||||
"Ordonat": "Отсортировано",
|
||||
"Ordonează după": "Сортировать по",
|
||||
@@ -2105,6 +2107,7 @@
|
||||
"Tracking client": "Отслеживание клиента",
|
||||
"Tracțiune": "Привод",
|
||||
"Trage fișierul aici": "Перетащите файл сюда",
|
||||
"Trage grupurile pentru a schimba ordinea lor în sidebar-ul stâng.": "Перетащи группы, чтобы изменить порядок в боковом меню слева.",
|
||||
"Transfer": "Перевод",
|
||||
"Transfer bancar": "Банковский перевод",
|
||||
"Transfer bancar: pune doar IBAN-ul tău, fără cont gateway": "Transfer bancar: pune doar IBAN-ul tău, fără cont gateway",
|
||||
|
||||
@@ -7,13 +7,7 @@
|
||||
$totalHints = collect($grouped)->sum(fn ($g) => count($g));
|
||||
$videoEmbed = $this->getVideoEmbedUrl();
|
||||
$videoRaw = $this->getVideoRawUrl();
|
||||
// Distinct accent color per area for card headers
|
||||
$areaColors = [
|
||||
'service' => '#0ea5e9',
|
||||
'crm' => '#8b5cf6',
|
||||
'depozit' => '#f59e0b',
|
||||
'finante' => '#10b981',
|
||||
];
|
||||
// Read accent color from AREAS registry (single source of truth)
|
||||
@endphp
|
||||
|
||||
<style>
|
||||
@@ -348,7 +342,7 @@
|
||||
@foreach ($grouped as $areaKey => $hints)
|
||||
@php
|
||||
$area = $areas[$areaKey] ?? null;
|
||||
$accent = $areaColors[$areaKey] ?? '#6b7280';
|
||||
$accent = $area['color'] ?? '#6b7280';
|
||||
@endphp
|
||||
<div class="faq-card">
|
||||
<div class="faq-card-hd" style="background:{{ $accent }};">
|
||||
|
||||
Reference in New Issue
Block a user