From 1b5b51d1837915d361b39ac9464eba63665c51f7 Mon Sep 17 00:00:00 2001 From: "Joseph.Rawlings" Date: Wed, 3 Dec 2025 20:03:57 -0500 Subject: [PATCH] refactor: integrate Remix Icon catalog for improved icon selection in NavbarLinkResource --- .cursor/rules/core.mdc | 18 ++++ .../Admin/Resources/NavbarLinkResource.php | 2 + .../Support/RemixIconCatalog.php | 100 ++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 .cursor/rules/core.mdc create mode 100644 extensions/Others/NavbarManager/Support/RemixIconCatalog.php diff --git a/.cursor/rules/core.mdc b/.cursor/rules/core.mdc new file mode 100644 index 000000000..15174a3b2 --- /dev/null +++ b/.cursor/rules/core.mdc @@ -0,0 +1,18 @@ +--- +description: +globs: +alwaysApply: true +--- +## Core Rules + +You have two modes of operation: + +1. Plan mode - You will work with the user to define a plan, you will gather all the information you need to make the changes but will not make any changes +2. Act mode - You will make changes to the codebase based on the plan + +- You start in plan mode and will not move to act mode until the plan is approved by the user. +- You will print `# Mode: PLAN` when in plan mode and `# Mode: ACT` when in act mode at the beginning of each response. +- Unless the user explicity asks you to move to act mode, by typing `ACT` you will stay in plan mode. +- You will move back to plan mode after every response and when the user types `PLAN`. +- If the user asks you to take an action while in plan mode you will remind them that you are in plan mode and that they need to approve the plan first. +- When in plan mode always output the full updated plan in every response. \ No newline at end of file diff --git a/extensions/Others/NavbarManager/Admin/Resources/NavbarLinkResource.php b/extensions/Others/NavbarManager/Admin/Resources/NavbarLinkResource.php index db59e5689..15cab85c0 100644 --- a/extensions/Others/NavbarManager/Admin/Resources/NavbarLinkResource.php +++ b/extensions/Others/NavbarManager/Admin/Resources/NavbarLinkResource.php @@ -4,6 +4,7 @@ namespace Paymenter\Extensions\Others\NavbarManager\Admin\Resources; use Paymenter\Extensions\Others\NavbarManager\Models\NavbarLink; use Paymenter\Extensions\Others\NavbarManager\Admin\Resources\NavbarLinkResource\Pages; +use Paymenter\Extensions\Others\NavbarManager\Support\RemixIconCatalog; use Filament\Forms; use Filament\Forms\Form; use Filament\Forms\Get; @@ -272,6 +273,7 @@ class NavbarLinkResource extends Resource ->helperText('Use any Remix Icon (see https://github.com/Remix-Design/RemixIcon/blob/master/tags.json). Prefix is optional—we will auto-add `ri-`.') ->regex('/^(?:ri-)?[a-z0-9-]+$/i') ->maxLength(80) + ->datalist(array_values(RemixIconCatalog::all())) ->dehydrateStateUsing(fn ($state) => self::normalizeIcon($state)), Forms\Components\Select::make('condition') diff --git a/extensions/Others/NavbarManager/Support/RemixIconCatalog.php b/extensions/Others/NavbarManager/Support/RemixIconCatalog.php new file mode 100644 index 000000000..621b21138 --- /dev/null +++ b/extensions/Others/NavbarManager/Support/RemixIconCatalog.php @@ -0,0 +1,100 @@ + + */ + public static function all(): array + { + return Cache::remember(self::CACHE_KEY, now()->addDay(), function () { + try { + $response = Http::timeout(8)->get(self::REMIX_TAGS_URL); + if (! $response->successful()) { + return self::fallback(); + } + + $json = $response->json(); + if (! is_array($json)) { + return self::fallback(); + } + + $icons = []; + foreach ($json as $group) { + if (! is_array($group)) { + continue; + } + + foreach ($group as $iconName => $unusedTags) { + if (! is_string($iconName)) { + continue; + } + + $normalized = self::normalizeIconName($iconName); + $icons[$normalized] = $normalized; + } + } + + ksort($icons); + + return ! empty($icons) ? $icons : self::fallback(); + } catch (\Throwable $e) { + \Log::warning('NavbarManager: Failed to load Remix icon catalog', [ + 'error' => $e->getMessage(), + ]); + + return self::fallback(); + } + }); + } + + public static function clearCache(): void + { + Cache::forget(self::CACHE_KEY); + } + + protected static function fallback(): array + { + $icons = [ + 'ri-home-line', + 'ri-user-line', + 'ri-settings-3-line', + 'ri-dashboard-line', + 'ri-menu-line', + 'ri-link', + 'ri-folder-line', + 'ri-shopping-bag-3-line', + 'ri-megaphone-line', + 'ri-book-open-line', + 'ri-file-text-line', + 'ri-customer-service-2-line', + 'ri-questionnaire-line', + 'ri-information-line', + 'ri-lock-line', + 'ri-server-line', + ]; + + return array_combine($icons, $icons); + } + + protected static function normalizeIconName(string $icon): string + { + $icon = Str::lower(trim($icon)); + + if (! Str::startsWith($icon, 'ri-')) { + $icon = 'ri-' . ltrim($icon, '-'); + } + + return $icon; + } +} +