Files
domnitor/app/Helpers/ViewHelper.php

170 lines
5.9 KiB
PHP
Raw Normal View History

<?php
namespace App\Helpers;
class ViewHelper
{
/**
* Generate sort URL for table headers
*/
public static function sortUrl(string $column, string $currentSort, string $currentOrder, array $currentFilters = []): string
{
$newOrder = ($currentSort === $column && $currentOrder === 'asc') ? 'desc' : 'asc';
$params = $currentFilters;
$params['sort'] = $column;
$params['order'] = $newOrder;
$currentPath = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
return $currentPath . '?' . http_build_query($params);
}
/**
* Generate sort icon HTML for table headers
*/
public static function sortIcon(string $column, string $currentSort, string $currentOrder): string
{
if ($currentSort !== $column) {
return '<i class="fas fa-sort text-gray-400 ml-1 text-xs"></i>';
}
$icon = $currentOrder === 'asc' ? 'fa-sort-up' : 'fa-sort-down';
return '<i class="fas ' . $icon . ' text-primary ml-1 text-xs"></i>';
}
/**
* Generate pagination URL
*/
public static function paginationUrl(int $page, array $filters, int $perPage): string
{
$params = $filters;
$params['page'] = $page;
$params['per_page'] = $perPage;
$currentPath = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
return $currentPath . '?' . http_build_query($params);
}
/**
* Format status badge
*/
public static function statusBadge(string $status): string
{
$statusClasses = [
'active' => 'bg-green-100 text-green-800 border-green-200',
'expiring_soon' => 'bg-orange-100 text-orange-800 border-orange-200',
'expired' => 'bg-red-100 text-red-800 border-red-200',
Add domain status notifications & login alerts Introduce richer notifications and domain status handling across the app. - NotificationService: Add domain status alert formatting/sending, in-app notifications for available/registered/redemption/pending_delete, richer session_new and session_failed notifications (geolocation + UA parsing) and helpers for human-readable status labels. - Auth/TwoFactor: Emit notifications for successful logins (including remember-me and 2FA) and failed login attempts; update last-login timestamp on various flows. - DomainController: Wrap bulk domain create in try/catch to handle duplicate race conditions and log failures. - WhoisService: Detect redemption_period and pending_delete statuses from WHOIS/EPP statuses. - Settings/Setting: Add settings support for notification status triggers and bump default app_version to 1.1.2; persist/update status trigger values. - Views/Layout/View helpers: Add parsing/formatting for login notification data, add new status labels/classes (available, redemption_period, pending_delete), update notification icons/colors mapping. - Top-nav & Notifications UI: Enhance dropdown with rich login/failed-login display (flags, device icons), clickable domain redirects when marking read, badge IDs for dynamic updates. - Error admin UI: Add copy error report button with robust clipboard fallback and toast UI reused from messages; improved copy UX in admin index/detail. - Installer: Add new migration 024 to installer migration lists and adjust detected toVersion to 1.1.2. - DB: Add migration file 024_add_status_notifications_v1.1.2.sql (new file). These changes add user-facing alerts for domain lifecycle events and stronger login/security notifications while improving UI feedback and robustness during bulk operations.
2026-02-08 22:58:59 +02:00
'available' => 'bg-blue-100 text-blue-800 border-blue-200',
'redemption_period' => 'bg-amber-100 text-amber-800 border-amber-200',
'pending_delete' => 'bg-rose-100 text-rose-800 border-rose-200',
'inactive' => 'bg-gray-100 text-gray-800 border-gray-200',
];
$statusLabels = [
'active' => 'Active',
'expiring_soon' => 'Expiring Soon',
'expired' => 'Expired',
Add domain status notifications & login alerts Introduce richer notifications and domain status handling across the app. - NotificationService: Add domain status alert formatting/sending, in-app notifications for available/registered/redemption/pending_delete, richer session_new and session_failed notifications (geolocation + UA parsing) and helpers for human-readable status labels. - Auth/TwoFactor: Emit notifications for successful logins (including remember-me and 2FA) and failed login attempts; update last-login timestamp on various flows. - DomainController: Wrap bulk domain create in try/catch to handle duplicate race conditions and log failures. - WhoisService: Detect redemption_period and pending_delete statuses from WHOIS/EPP statuses. - Settings/Setting: Add settings support for notification status triggers and bump default app_version to 1.1.2; persist/update status trigger values. - Views/Layout/View helpers: Add parsing/formatting for login notification data, add new status labels/classes (available, redemption_period, pending_delete), update notification icons/colors mapping. - Top-nav & Notifications UI: Enhance dropdown with rich login/failed-login display (flags, device icons), clickable domain redirects when marking read, badge IDs for dynamic updates. - Error admin UI: Add copy error report button with robust clipboard fallback and toast UI reused from messages; improved copy UX in admin index/detail. - Installer: Add new migration 024 to installer migration lists and adjust detected toVersion to 1.1.2. - DB: Add migration file 024_add_status_notifications_v1.1.2.sql (new file). These changes add user-facing alerts for domain lifecycle events and stronger login/security notifications while improving UI feedback and robustness during bulk operations.
2026-02-08 22:58:59 +02:00
'available' => 'Available',
'redemption_period' => 'Redemption Period',
'pending_delete' => 'Pending Delete',
'inactive' => 'Inactive',
];
$class = $statusClasses[$status] ?? $statusClasses['inactive'];
$label = $statusLabels[$status] ?? ucfirst($status);
return '<span class="inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold border ' . $class . '">' . htmlspecialchars($label) . '</span>';
}
/**
* Truncate text with ellipsis
*/
public static function truncate(string $text, int $length = 50, string $suffix = '...'): string
{
if (mb_strlen($text) <= $length) {
return htmlspecialchars($text);
}
return htmlspecialchars(mb_substr($text, 0, $length)) . $suffix;
}
/**
* Format bytes to human readable size
*/
public static function formatBytes(int $bytes, int $precision = 2): string
{
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
for ($i = 0; $bytes > 1024 && $i < count($units) - 1; $i++) {
$bytes /= 1024;
}
return round($bytes, $precision) . ' ' . $units[$i];
}
/**
* Generate breadcrumb navigation
*/
public static function breadcrumbs(array $items): string
{
$html = '<nav class="flex mb-4" aria-label="Breadcrumb"><ol class="inline-flex items-center space-x-1 md:space-x-3">';
foreach ($items as $index => $item) {
$isLast = $index === count($items) - 1;
if ($index > 0) {
$html .= '<li><div class="flex items-center"><i class="fas fa-chevron-right text-gray-400 text-xs"></i></div></li>';
}
$html .= '<li class="inline-flex items-center">';
if (!$isLast && isset($item['url'])) {
$html .= '<a href="' . htmlspecialchars($item['url']) . '" class="inline-flex items-center text-sm font-medium text-gray-700 hover:text-primary">';
if (isset($item['icon'])) {
$html .= '<i class="' . htmlspecialchars($item['icon']) . ' mr-2 text-xs"></i>';
}
$html .= htmlspecialchars($item['label']) . '</a>';
} else {
$html .= '<span class="text-sm font-medium text-gray-500">';
if (isset($item['icon'])) {
$html .= '<i class="' . htmlspecialchars($item['icon']) . ' mr-2 text-xs"></i>';
}
$html .= htmlspecialchars($item['label']) . '</span>';
}
$html .= '</li>';
}
$html .= '</ol></nav>';
return $html;
}
/**
* Generate alert message HTML
*/
public static function alert(string $type, string $message): string
{
$classes = [
'success' => 'bg-green-50 border-green-200 text-green-800',
'error' => 'bg-red-50 border-red-200 text-red-800',
'warning' => 'bg-orange-50 border-orange-200 text-orange-800',
'info' => 'bg-blue-50 border-blue-200 text-blue-800',
];
$icons = [
'success' => 'fa-check-circle',
'error' => 'fa-exclamation-circle',
'warning' => 'fa-exclamation-triangle',
'info' => 'fa-info-circle',
];
$class = $classes[$type] ?? $classes['info'];
$icon = $icons[$type] ?? $icons['info'];
return '<div class="border rounded-lg p-4 ' . $class . ' flex items-start">
<i class="fas ' . $icon . ' mr-3 mt-0.5"></i>
<div class="flex-1">' . htmlspecialchars($message) . '</div>
</div>';
}
}