ifnex/04_Laravel/app/Helpers/number.php
Kazem Alghasi 91984dbde3 feat(ui): redesign admin dashboard with layered grid and custom branding
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.
2026-10-03 11:08:50 +03:30

146 lines
4.2 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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];
}
}