Infrastructure for a portal-wide in-app help system:
* Users have hints_enabled (default true) and dismissed_hints (JSON
array) columns. User::shouldSeeHint(key) checks both.
* app/Support/Hints.php — single-source-of-truth registry with 14
pilot hints across Service (5), CRM (3), Depozit (3), Finanțe (3).
Each entry has RO/RU/EN title + body + optional next-step + links.
* <x-hint key="wo.dashboard.overview" /> Blade component renders a
small "?" icon with Alpine.js popover; the popover shows title,
body, next-step, related links and an "X" button that POSTs to
/app/hints/{key}/dismiss.
* HintController handles dismiss (per key), toggle (global on/off)
and reset (clear dismissed + re-enable). Routes are auth:web.
* /app/faq page (Filament Page under Admin group) renders the whole
registry grouped by area with a live search box and buttons to
toggle global hints or reset dismissed ones.
* Wired 3 pilot hints into the WO dashboard: title (overview), Docs
tab PDF preview, and the Chat client card.
Follow-ups: extend registry to cover more pages and add <x-hint>
tags where useful. Filament resource fields can also reuse the same
copy via ->hint()/->helperText().
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
// ─── Service / Work orders ────────────────────────────────
'wo.list.overview'=>[
'area'=>'service',
'title'=>[
'ro'=>'Lista fișelor de lucru',
'ru'=>'Список заказ-нарядов',
'en'=>'Work orders list',
],
'body'=>[
'ro'=>'Aici vezi toate fișele active. Click pe un rând deschide dashboard-ul fișei (Mitchell1-style). Butonul „+ Fișă nouă" creează una nouă și te duce direct pe dashboard. Filtrele de sus permit selectare pe status, plată, maistru.',
'ru'=>'Здесь все активные заказы. Клик по строке открывает дашборд заказа. Кнопка «+ Новый заказ» создаёт и сразу открывает дашборд. Фильтры вверху — статус, оплата, мастер.',
'en'=>'All active work orders. Row click opens the Mitchell1-style dashboard. "+ New" creates and lands on the dashboard. Top filters: status, payment, master.',
],
'links'=>[
['label_ro'=>'Deschide un dashboard','label_ru'=>'Открыть дашборд','label_en'=>'Open a dashboard','url'=>'/app/work-orders'],
],
'next'=>[
'ro'=>'Click pe orice rând sau „+ Fișă nouă"',
'ru'=>'Клик по строке или «+ Новый заказ»',
'en'=>'Click any row or "+ New"',
],
],
'wo.dashboard.overview'=>[
'area'=>'service',
'title'=>[
'ro'=>'Dashboard fișă (hub central)',
'ru'=>'Дашборд заказа (центр управления)',
'en'=>'Work order dashboard (hub)',
],
'body'=>[
'ro'=>'Toate acțiunile legate de această fișă într-un singur ecran: stânga = client & mașină & istoric reparații, mijloc = lucrări/piese/diagnostic/foto/documente/note (taburi), dreapta = finanțe & timeline & chat client. Jos: navigare între fișe, comandă repetată, închide fișă.',
'ru'=>'Все действия по заказу в одном экране: слева — клиент, авто, история; в центре — работы/запчасти/диагностика/фото/документы/заметки (табы); справа — финансы, лента, чат с клиентом. Внизу: навигация, повтор заказа, закрытие.',
'en'=>'Everything for this WO on one screen: left = client + vehicle + repair history; middle = tabs (works/parts/diag/photos/docs/notes); right = finance + timeline + chat. Bottom bar: prev/next, repeat, close WO.',
],
'next'=>[
'ro'=>'Explorează taburile din mijloc: Lucrări, Piese, Foto etc.',
'ru'=>'Проверьте табы в центре: Работы, Запчасти, Фото и т.д.',
'en'=>'Try the middle tabs: Works, Parts, Photos, etc.',
],
],
'wo.dashboard.pdf'=>[
'area'=>'service',
'title'=>[
'ro'=>'Vizualizare & descărcare PDF',
'ru'=>'Просмотр и скачивание PDF',
'en'=>'PDF preview & download',
],
'body'=>[
'ro'=>'Butonul „Vizualizare PDF" deschide factura într-un modal cu preview embedded. Din modal poți printa (via viewer-ul browserului) sau descărca (link „Descarcă"). Nu forțează descărcare implicit.',
'ru'=>'Кнопка «Просмотр PDF» открывает счёт в модалке с превью. Оттуда можно печатать (через просмотрщик браузера) или скачать. По умолчанию не скачивается.',
'en'=>'The "View PDF" button opens the invoice in a modal preview. You can print (via the browser PDF viewer) or download from there. It doesn\'t force download by default.',
],
],
'wo.dashboard.tracking'=>[
'area'=>'service',
'title'=>[
'ro'=>'Link tracking pentru client',
'ru'=>'Ссылка отслеживания для клиента',
'en'=>'Client tracking link',
],
'body'=>[
'ro'=>'Fiecare fișă are un token public unic. Butonul „Link tracking" deschide pagina publică pe care o poți trimite clientului prin SMS/WhatsApp/Telegram — vede statusul lucrării, ETA-ul și fotografiile.',
'ru'=>'У каждого заказа есть публичный токен. Кнопка «Ссылка отслеживания» открывает публичную страницу, которую можно отправить клиенту — он видит статус, ETA, фотографии.',
'en'=>'Each WO has a unique public token. "Tracking link" opens the customer-facing page you can send via SMS/WhatsApp/Telegram — status, ETA, photos.',
],
],
'wo.dashboard.chat'=>[
'area'=>'service',
'title'=>[
'ro'=>'Chat cu clientul (Telegram/WhatsApp)',
'ru'=>'Чат с клиентом (Telegram/WhatsApp)',
'en'=>'Client chat (Telegram/WhatsApp)',
],
'body'=>[
'ro'=>'Trimite mesaje direct din dashboard dacă ai configurat integrarea Telegram sau WhatsApp în Setări → Integrări. Dacă vezi „Mesageria nu este configurată" — mergi la Integrări și completează token-ul.',
'ru'=>'Отправляйте сообщения из дашборда, если настроен Telegram или WhatsApp в Настройки → Интеграции. Если написано «Мессенджер не настроен» — заполните токен.',
'en'=>'Send messages from the dashboard when Telegram/WhatsApp is configured under Settings → Integrations. If it says "Messaging not configured" — go set the token.',
'ro'=>'Fiecare deal trece prin coloane (New → Contactat → Diagnostic → Confirmat → Fișă creată → Închis/Pierdut). Trage-și cardurile între coloane. Când ajunge la „Fișă creată" se generează automat un WO legat de client + mașină.',
'ru'=>'Каждый deal проходит через колонки (New → Контакт → Диагностика → Подтверждён → Заказ создан → Закрыт/Проигран). Перетаскивайте карточки. На «Заказ создан» автоматически генерируется WO.',
'en'=>'Each deal moves across columns (New → Contacted → Diagnosed → Confirmed → WO created → Closed/Lost). Drag cards between columns. Reaching "WO created" auto-generates a work order.',
],
'next'=>[
'ro'=>'Trage un card la stânga/dreapta',
'ru'=>'Перетащите карточку',
'en'=>'Drag a card left/right',
],
],
'crm.leads.overview'=>[
'area'=>'crm',
'title'=>[
'ro'=>'Cereri (leaduri) — intrare centralizată',
'ru'=>'Заявки (лиды) — единая точка входа',
'en'=>'Leads — single inbox',
],
'body'=>[
'ro'=>'Aici ajung toate cererile: formularul de pe site, telefoane, mesaje Telegram, campanii Google/Facebook (dacă e configurat). Convertește-le în client + deal cu un click. Statusul „nou" apare cu galben pe dashboard.',
'ru'=>'Все входящие заявки: сайт, звонки, Telegram, Google/Facebook кампании. Одним кликом превращаешь в клиента + deal. Статус «новый» подсвечивается жёлтым на дашборде.',
'en'=>'All incoming requests: website form, calls, Telegram, Google/Facebook (if configured). Convert to client + deal in one click. "New" status shows amber on the dashboard.',
],
],
'crm.calendar.overview'=>[
'area'=>'crm',
'title'=>[
'ro'=>'Calendar programări (5 vederi)',
'ru'=>'Календарь записей (5 видов)',
'en'=>'Appointments calendar (5 views)',
],
'body'=>[
'ro'=>'Zi / Săptămână / Lună / Custom / Listă — comută cu butoanele de sus. Grupare pe post de lucru sau pe maistru. Trage evenimentele pentru re-programare. Butonul „🖨 PDF programări" exportă perioada curentă.',
'ru'=>'День / Неделя / Месяц / Свой / Список — кнопки сверху. Группировка по посту или мастеру. Перетаскивайте события. «🖨 PDF записей» экспортирует текущий период.',
'en'=>'Day / Week / Month / Custom / List — top buttons. Group by post or master. Drag events to reschedule. "🖨 PDF" exports the current period.',
'ro'=>'Fiecare piesă are cod, preț cost/vânzare, stoc curent, stoc minim și furnizor preferat. Când stocul scade sub minim, apare în widget-ul „Stoc minim atins" pe dashboard. Adaugă la o fișă din tab-ul „Piese" al fișei.',
'ru'=>'У каждой запчасти: код, цена (закупка/продажа), остаток, минимум, поставщик. Когда остаток ниже минимума — попадает в виджет «Минимальный остаток». Добавляй в заказ через таб «Запчасти».',
'en'=>'Each part has SKU, cost/sell price, current + min stock, preferred supplier. When stock drops below min, it shows up in the "Low stock" widget. Add to a WO via the WO\'s "Parts" tab.',
],
],
'depozit.excel.import'=>[
'area'=>'depozit',
'title'=>[
'ro'=>'Import factură Excel',
'ru'=>'Импорт счёта из Excel',
'en'=>'Excel invoice import',
],
'body'=>[
'ro'=>'Încarcă factura de la furnizor în Excel/CSV. Wizard-ul mapează coloanele (cod, denumire, preț, cant.) și le arată în preview. Piese noi se creează automat, cele existente se actualizează. Maparea coloanelor se salvează per furnizor.',
'ru'=>'Загрузите счёт поставщика в Excel/CSV. Мастер сопоставит колонки (код, название, цена, кол-во) и покажет превью. Новые запчасти создаются, существующие обновляются. Соответствие колонок сохраняется на поставщика.',
'en'=>'Upload the supplier invoice in Excel/CSV. The wizard maps columns (SKU, name, price, qty) and shows a preview. New parts are created, existing ones updated. Column mapping is remembered per supplier.',
],
],
'depozit.scanner.usage'=>[
'area'=>'depozit',
'title'=>[
'ro'=>'Scaner barcode',
'ru'=>'Сканер штрихкодов',
'en'=>'Barcode scanner',
],
'body'=>[
'ro'=>'Scanează codul de bare al piesei cu telefonul (camera browser) sau cu un scanner USB. Sistemul găsește piesa în catalog și te lasă să o adaugi rapid la o fișă activă sau să ajustezi stocul.',
'ru'=>'Сканируй штрихкод телефоном (камерой) или USB-сканером. Система найдёт запчасть в каталоге — можно добавить в заказ или изменить остаток.',
'en'=>'Scan the part barcode with your phone camera or a USB scanner. The system finds it in the catalog — add to an active WO or adjust stock.',
'ro'=>'Fiecare plată se leagă de o fișă (WO), o metodă (cash, card, transfer) și un user care a primit-o. Suma totală apare pe dashboard-ul principal la „Încasări (luna)" și pe dashboard-ul fișei la „Plătit".',
'ru'=>'Каждая оплата привязана к заказу, способу (наличные/карта/перевод) и пользователю. Общая сумма — на главном дашборде «Приход (месяц)» и на дашборде заказа «Оплачено».',
'en'=>'Each payment ties to a WO, a method (cash/card/transfer) and the user who took it. The total shows on the main dashboard ("Cash in / month") and on the WO dashboard ("Paid").',
],
],
'finante.salaries.overview'=>[
'area'=>'finante',
'title'=>[
'ro'=>'Salarii — calcul automat per mecanic',
'ru'=>'Зарплаты — авторасчёт по механику',
'en'=>'Salaries — auto per mechanic',
],
'body'=>[
'ro'=>'La sfârșit de perioadă (săptămână/lună), rulează „Închide perioada" în Salarii. Sistemul calculează pentru fiecare mecanic: manoperele făcute × marja internă + bonusuri − avansuri = net de plată. Toate valorile pot fi ajustate manual înainte de export.',
'ru'=>'В конце периода (неделя/месяц) нажми «Закрыть период» в Зарплатах. Система посчитает по каждому механику: работы × внутренняя маржа + бонусы − авансы = к выплате. Значения можно поправить вручную.',
'en'=>'At period end (week/month), hit "Close period" in Salaries. The system computes per mechanic: labor × internal margin + bonuses − advances = net pay. All values are editable before export.',
],
'links'=>[
['label_ro'=>'Bonusuri & avansuri','label_ru'=>'Бонусы и авансы','label_en'=>'Bonuses & advances','url'=>'/app/payroll-adjustments'],
],
],
'finante.reports.overview'=>[
'area'=>'finante',
'title'=>[
'ro'=>'Rapoarte financiare',
'ru'=>'Финансовые отчёты',
'en'=>'Financial reports',
],
'body'=>[
'ro'=>'Vezi aici P&L pe perioadă selectabilă: încasări, cheltuieli, salarii, profit brut, top clienți, top piese vândute, comparație lună-lună. Export CSV pentru contabilitate.',
'ru'=>'P&L за выбранный период: приход, расход, зарплаты, валовая прибыль, топ клиентов, топ запчастей, сравнение месяцев. Экспорт CSV.',
'en'=>'P&L for a selectable period: income, expenses, salaries, gross profit, top clients, top parts, month-over-month comparison. CSV export for accounting.',
],
],
];
}
publicstaticfunctionget(string$key):?array
{
returnstatic::all()[$key]??null;
}
/** Group all hints by area, preserving insertion order. */
publicstaticfunctionbyArea():array
{
$out=[];
foreach(static::all()as$key=>$h){
$out[$h['area']]??=[];
$out[$h['area']][$key]=$h;
}
return$out;
}
publicstaticfunctionlocale():string
{
$l=app()->getLocale();
returnin_array($l,['ro','ru','en'],true)?$l:'ro';
}
}
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.