Implement a comprehensive overhaul of the Filament admin dashboard, introducing a structured 12-column responsive grid layout and enhanced visual identity. Key changes include: - Redesigned Dashboard layout with a 4-layer progressive disclosure architecture (KPIs, Exchange Rates, Data Tables, and Trends). - Introduced custom IFNEX design tokens via CSS, including branded stat cards, status badges, and improved sidebar typography. - Enhanced FinanceOverviewWidget with real-time trend analysis and sparkline-ready data structures. - Refactored RecentShipments and RecentTransactions widgets to use custom Blade templates for a more polished, consistent UI. - Integrated brand assets including the company logo and custom authentication pages. - Added global number formatting helpers and integrated them into financial widgets. - Updated AdminPanelProvider to support custom login pages and brand-specific header/footer hooks.
146 lines
4.2 KiB
PHP
146 lines
4.2 KiB
PHP
<?php
|
||
|
||
/**
|
||
* IFNEX — Helpers for compact Persian-friendly number formatting.
|
||
*
|
||
* File: app/Helpers/number.php
|
||
* Registered in composer.json under autoload.files so the helpers
|
||
* below are globally available across the Laravel app (no namespace).
|
||
*/
|
||
|
||
if (!function_exists('ifnex_format_number')) {
|
||
/**
|
||
* Format a (potentially huge) integer into a compact Persian-friendly string.
|
||
*
|
||
* Examples:
|
||
* 950 → "۹۵۰"
|
||
* 1500 → "۲ هزار"
|
||
* 2_400_000 → "۲.۴ میلیون"
|
||
* 1_019_406_902 → "۱.۰۲ میلیارد"
|
||
*
|
||
* @param int|float|string $number
|
||
* @param string $currency Optional currency suffix (default: ریال). Pass '' to skip.
|
||
* @return string
|
||
*/
|
||
function ifnex_format_number(int|float|string $number, string $currency = 'ریال'): string
|
||
{
|
||
$number = (float) $number;
|
||
$abs = abs($number);
|
||
|
||
if ($abs >= 1_000_000_000) {
|
||
$formatted = number_format($number / 1_000_000_000, 2);
|
||
} elseif ($abs >= 1_000_000) {
|
||
$formatted = number_format($number / 1_000_000, 1);
|
||
} elseif ($abs >= 1_000) {
|
||
$formatted = number_format($number / 1_000, 0);
|
||
} else {
|
||
$formatted = number_format($number);
|
||
}
|
||
|
||
// Convert Latin digits to Persian (fa-IR)
|
||
$formatted = ifnex_persian_digits($formatted);
|
||
|
||
// Append compact unit if applicable
|
||
if ($abs >= 1_000_000_000) {
|
||
$formatted .= ' میلیارد';
|
||
} elseif ($abs >= 1_000_000) {
|
||
$formatted .= ' میلیون';
|
||
} elseif ($abs >= 1_000) {
|
||
$formatted .= ' هزار';
|
||
}
|
||
|
||
if ($currency !== '' && $currency !== null) {
|
||
$formatted .= ' ' . $currency;
|
||
}
|
||
|
||
return trim($formatted);
|
||
}
|
||
}
|
||
|
||
if (!function_exists('ifnex_persian_digits')) {
|
||
/**
|
||
* Replace Latin (0-9) digits in a string with Persian digits (۰-۹).
|
||
* Keeps other characters intact.
|
||
*/
|
||
function ifnex_persian_digits(string $text): string
|
||
{
|
||
return strtr($text, [
|
||
'0' => '۰',
|
||
'1' => '۱',
|
||
'2' => '۲',
|
||
'3' => '۳',
|
||
'4' => '۴',
|
||
'5' => '۵',
|
||
'6' => '۶',
|
||
'7' => '۷',
|
||
'8' => '۸',
|
||
'9' => '۹',
|
||
]);
|
||
}
|
||
}
|
||
|
||
if (!function_exists('ifnex_english_digits')) {
|
||
/**
|
||
* Replace Persian digits back to Latin — handy for form input parsing.
|
||
*/
|
||
function ifnex_english_digits(string $text): string
|
||
{
|
||
return strtr($text, [
|
||
'۰' => '0',
|
||
'۱' => '1',
|
||
'۲' => '2',
|
||
'۳' => '3',
|
||
'۴' => '4',
|
||
'۵' => '5',
|
||
'۶' => '6',
|
||
'۷' => '7',
|
||
'۸' => '8',
|
||
'۹' => '9',
|
||
'٠' => '0',
|
||
'١' => '1',
|
||
'٢' => '2',
|
||
'٣' => '3',
|
||
'٤' => '4',
|
||
'٥' => '5',
|
||
'٦' => '6',
|
||
'٧' => '7',
|
||
'٨' => '8',
|
||
'٩' => '9',
|
||
]);
|
||
}
|
||
}
|
||
|
||
if (!function_exists('ifnex_trend_percent')) {
|
||
/**
|
||
* Compute the percent change between two values and return a tuple of
|
||
* [percent_value, direction ('up'|'down'|'flat'), formatted Persian string].
|
||
*
|
||
* @param float|int|null $current
|
||
* @param float|int|null $previous
|
||
* @return array{0: float, 1: string, 2: string}
|
||
*/
|
||
function ifnex_trend_percent(float|int|null $current, float|int|null $previous): array
|
||
{
|
||
$current = (float) ($current ?? 0);
|
||
$previous = (float) ($previous ?? 0);
|
||
|
||
if ($previous == 0) {
|
||
return [0.0, $current > 0 ? 'up' : 'flat', '—'];
|
||
}
|
||
|
||
$diff = $current - $previous;
|
||
$percent = ($diff / abs($previous)) * 100;
|
||
|
||
if ($percent > 0.05) {
|
||
$direction = 'up';
|
||
} elseif ($percent < -0.05) {
|
||
$direction = 'down';
|
||
} else {
|
||
$direction = 'flat';
|
||
}
|
||
|
||
$formatted = ifnex_persian_digits(number_format(abs($percent), 1)) . '%';
|
||
|
||
return [$percent, $direction, $formatted];
|
||
}
|
||
} |