feat(icons): load Bootstrap Icons and Font Awesome from the shared platform-tools packs

Register the icons packs in platform_connect, add fit_icon_assets() with local
fallback, and add a sysadmin 'Pacotes de icones' link to platform?tool=icons.
This commit is contained in:
andre committed 2026-10-13 18:55:12 +01:00
1 parent 781a3a324e
commit 18676ad6d0
8 files changed
+46 -7

No files matched your search

+2 -2
View File
@@ -9,9 +9,9 @@ mas ainda sem versão no nome das pastas dos ficheiros hand-vendored.
| Biblioteca | Versão | Caminho | Usado em | | Biblioteca | Versão | Caminho | Usado em |
|------------------------|--------|----------------------------------------|----------------------| |------------------------|--------|----------------------------------------|----------------------|
| Bootstrap | 5.3.3 | `assets/vendor/bootstrap5/` | Site público + backoffice (unificado 25/09) | | Bootstrap | 5.3.3 | `assets/vendor/bootstrap5/` | Site público + backoffice (unificado 25/09) |
| Bootstrap Icons | — | `assets/vendor/bootstrap-icons/` | Backoffice | | Bootstrap Icons | — | `assets/vendor/bootstrap-icons/` | Backoffice (agora carregado do pacote partilhado `bootstrap-icons` 1.13.1; esta cópia só como recurso) |
| jQuery | 3.7.1 | `assets/vendor/jquery/jquery-3.7.1.min.js` | Site público + backoffice (deduplicado 25/09) | | jQuery | 3.7.1 | `assets/vendor/jquery/jquery-3.7.1.min.js` | Site público + backoffice (deduplicado 25/09) |
| Font Awesome Free | 5.13.1 | `site/assets/fonts/fontawesome/` | Site público (~18 MB, todo o pacote) | | Font Awesome Free | 5.13.1 | `site/assets/fonts/fontawesome/` | Site público: agora FA 6.7.2 do pacote partilhado `fontawesome`; esta cópia (~18 MB) só como recurso, sem uso se o submódulo tiver `functions_icons.php` |
| PHPMailer | 7.1.1 | `vendor/PHPMailer/` | Envio de email (`config/functions_mail.php`, partilhado) | | PHPMailer | 7.1.1 | `vendor/PHPMailer/` | Envio de email (`config/functions_mail.php`, partilhado) |
`assets/vendor/bootstrap/` (a cópia 4.3.1) ficou sem nenhuma referência depois da migração — `assets/vendor/bootstrap/` (a cópia 4.3.1) ficou sem nenhuma referência depois da migração —
+6
View File
@@ -156,3 +156,9 @@ or adapted for production, and these accounts must never exist in a production d
## Bootstrap re-tematizado (2026-10-13) ## Bootstrap re-tematizado (2026-10-13)
- `assets/css/bs-brand.css` (carregado depois do Bootstrap em `includes/header.php` e `includes/auth_header.php`) sobrescreve as cores do Bootstrap só com variáveis `--bs-*` e as variáveis de componente (`.btn-*`, `.form-check-input`, `.page-link`…), claro e escuro. A cor de marca é `--fitme-accent` (fallback `#C2D500`); todos os tons derivam dela com `color-mix()`; `--brand-on` é o texto sobre a cor. Secondary/success/danger/warning/info têm valores próprios. Verificação: `platform.php?tool=branding` (Montra da marca) não deve mostrar nenhum azul por omissão. O site público ainda não carrega este ficheiro. - `assets/css/bs-brand.css` (carregado depois do Bootstrap em `includes/header.php` e `includes/auth_header.php`) sobrescreve as cores do Bootstrap só com variáveis `--bs-*` e as variáveis de componente (`.btn-*`, `.form-check-input`, `.page-link`…), claro e escuro. A cor de marca é `--fitme-accent` (fallback `#C2D500`); todos os tons derivam dela com `color-mix()`; `--brand-on` é o texto sobre a cor. Secondary/success/danger/warning/info têm valores próprios. Verificação: `platform.php?tool=branding` (Montra da marca) não deve mostrar nenhum azul por omissão. O site público ainda não carrega este ficheiro.
## Pacotes de ícones partilhados (2026-10-13)
- `config/db.php` regista `'icons' => ['packs' => ['bootstrap-icons','fontawesome'], 'default' => 'bootstrap-icons']` só se `shared/platform-tools/functions_icons.php` existe. Flaticon NÃO está registado: o site usa PNGs (`uploads/modalidades/icons`), não a fonte.
- `fit_icon_assets($packs, $fallbackLocal)` (`config/functions_icons.php`) imprime `pt_icon_assets()` ou, sem submódulo novo, os `<link>` locais. Backoffice (`includes/header.php`, `includes/auth_header.php`): `bootstrap-icons`; site público (`site/includes/include.php`): `fontawesome` (FA 6.7.2; as classes `fas/far/fab` e os nomes FA5 funcionam por aliases).
- Sidebar > Sistema: «Pacotes de ícones» (sysadmin) -> `platform.php?tool=icons`.
- Sem uso quando o submódulo é novo (não apagados): `assets/vendor/bootstrap-icons/`, `site/assets/fonts/fontawesome/`, `site/assets/icon-fonts/`, `site/assets/css/flaticon.css`. `config/error_handler.php` ainda usa bootstrap-icons por CDN (página de erro autónoma).
+11 -1
View File
@@ -96,7 +96,17 @@ try {
// para deixar a porta aberta a usar o throttle partilhado no futuro. Ver // para deixar a porta aberta a usar o throttle partilhado no futuro. Ver
// views/auth/login.php para a nota completa. // views/auth/login.php para a nota completa.
require_once dirname(__DIR__) . '/shared/platform-tools/functions_connector.php'; require_once dirname(__DIR__) . '/shared/platform-tools/functions_connector.php';
platform_connect($pdo, [ // Pacotes de ícones partilhados (platform?tool=icons, pt_icon_assets()). Só se o
// submódulo já os tem; sem ele os layouts caem nas cópias locais (fit_icon_assets()).
// Flaticon NÃO está registado: o site usa PNGs (uploads/modalidades/icons), não a fonte.
$iconsFile = dirname(__DIR__) . '/shared/platform-tools/functions_icons.php';
if (is_file($iconsFile)) {
require_once $iconsFile;
}
$iconsOpt = is_file($iconsFile)
? ['icons' => ['packs' => ['bootstrap-icons', 'fontawesome'], 'default' => 'bootstrap-icons']]
: [];
platform_connect($pdo, $iconsOpt + [
'auth' => 'shared', 'auth' => 'shared',
'roles' => [ 'roles' => [
// Preserva a hierarquia que config/auth.php já tinha (sysadmin > // Preserva a hierarquia que config/auth.php já tinha (sysadmin >
+1
View File
@@ -27,6 +27,7 @@ require_once __DIR__ . '/functions_migrations.php';// platform_update.php migrat
require_once __DIR__ . '/functions_queue.php'; // message_queue + enqueue_*/flush_message require_once __DIR__ . '/functions_queue.php'; // message_queue + enqueue_*/flush_message
require_once __DIR__ . '/functions_csrf.php'; require_once __DIR__ . '/functions_csrf.php';
require_once __DIR__ . '/functions_html.php'; // allowlist HTML sanitiser (clean_richtext/clean_map_embed) require_once __DIR__ . '/functions_html.php'; // allowlist HTML sanitiser (clean_richtext/clean_map_embed)
require_once __DIR__ . '/functions_icons.php'; // fit_icon_assets(): pacotes de ícones partilhados + recurso local
require_once __DIR__ . '/ci_compat.php'; // CI4 view-helper shim (script_tag/link_tag/view/esc/session) require_once __DIR__ . '/ci_compat.php'; // CI4 view-helper shim (script_tag/link_tag/view/esc/session)
require_once __DIR__ . '/functions_gyms.php'; // multi-gym: gyms, URL folders, admin gym switcher require_once __DIR__ . '/functions_gyms.php'; // multi-gym: gyms, URL folders, admin gym switcher
require_once __DIR__ . '/functions_site.php'; // public-site data (site_info/offer/team/modalidades/horario) require_once __DIR__ . '/functions_site.php'; // public-site data (site_info/offer/team/modalidades/horario)
+18
View File
@@ -0,0 +1,18 @@
<?php
// Ícones: pacotes partilhados do platform-tools (pt_icon_assets()) com as cópias
// locais como recurso quando o submódulo ainda não os tem (produção com o
// submódulo antigo). Registo dos pacotes: config/db.php ('icons').
//
// $packs : ids dos pacotes a carregar (ex.: ['fontawesome'])
// $localHrefs: <link> locais de recurso, caminhos para link_tag()/base_url()
function fit_icon_assets(array $packs, array $localHrefs): string {
if (function_exists('pt_icon_assets')) {
$html = pt_icon_assets($packs);
if ($html !== '') return $html;
}
$out = '';
foreach ($localHrefs as $href) {
$out .= '<link href="' . htmlspecialchars(base_url($href), ENT_QUOTES) . '" rel="stylesheet">' . "\n";
}
return $out;
}
+1 -1
View File
@@ -30,7 +30,7 @@ $app_name = defined('APP_NAME') ? APP_NAME : 'FitMe 3070';
</script> </script>
<link href="<?= base_url('assets/vendor/bootstrap5/css/bootstrap.min.css') ?>" rel="stylesheet"> <link href="<?= base_url('assets/vendor/bootstrap5/css/bootstrap.min.css') ?>" rel="stylesheet">
<link href="<?= htmlspecialchars(_asset_versioned('assets/css/bs-brand.css'), ENT_QUOTES) ?>" rel="stylesheet"> <link href="<?= htmlspecialchars(_asset_versioned('assets/css/bs-brand.css'), ENT_QUOTES) ?>" rel="stylesheet">
<link href="<?= base_url('assets/vendor/bootstrap-icons/bootstrap-icons.css') ?>" rel="stylesheet"> <?= fit_icon_assets(['bootstrap-icons'], ['assets/vendor/bootstrap-icons/bootstrap-icons.css']) ?>
<style> <style>
:root { :root {
--bo-accent: #C2D500; --bo-accent: #C2D500;
+5 -1
View File
@@ -33,7 +33,7 @@ $app_name = defined('APP_NAME') ? APP_NAME : 'FitMe 3070';
</script> </script>
<link href="<?= base_url('assets/vendor/bootstrap5/css/bootstrap.min.css') ?>" rel="stylesheet"> <link href="<?= base_url('assets/vendor/bootstrap5/css/bootstrap.min.css') ?>" rel="stylesheet">
<link href="<?= htmlspecialchars(_asset_versioned('assets/css/bs-brand.css'), ENT_QUOTES) ?>" rel="stylesheet"> <link href="<?= htmlspecialchars(_asset_versioned('assets/css/bs-brand.css'), ENT_QUOTES) ?>" rel="stylesheet">
<link href="<?= base_url('assets/vendor/bootstrap-icons/bootstrap-icons.css') ?>" rel="stylesheet"> <?= fit_icon_assets(['bootstrap-icons'], ['assets/vendor/bootstrap-icons/bootstrap-icons.css']) ?>
<link href="<?= base_url('assets/vendor/summernote/summernote-bs5.min.css') ?>" rel="stylesheet"> <link href="<?= base_url('assets/vendor/summernote/summernote-bs5.min.css') ?>" rel="stylesheet">
<link href="<?= htmlspecialchars(_asset_versioned('assets/css/backoffice.css'), ENT_QUOTES) ?>" rel="stylesheet"> <link href="<?= htmlspecialchars(_asset_versioned('assets/css/backoffice.css'), ENT_QUOTES) ?>" rel="stylesheet">
<?php include __DIR__ . '/env_ribbon.php'; // moldura de aviso fora de produção ?> <?php include __DIR__ . '/env_ribbon.php'; // moldura de aviso fora de produção ?>
@@ -114,6 +114,10 @@ $app_name = defined('APP_NAME') ? APP_NAME : 'FitMe 3070';
// platform-tools passa a aparecer sozinha, sem precisar de link novo aqui. ?> // platform-tools passa a aparecer sozinha, sem precisar de link novo aqui. ?>
<?= bo_nav_link('platform.php?tool=index', 'bi-cpu', 'Sistema', ['mod' => 'sub', <?= bo_nav_link('platform.php?tool=index', 'bi-cpu', 'Sistema', ['mod' => 'sub',
'active' => (($_GET['tool'] ?? 'index') === 'index' && str_contains($_SERVER['REQUEST_URI'] ?? '', 'platform.php'))]) ?> 'active' => (($_GET['tool'] ?? 'index') === 'index' && str_contains($_SERVER['REQUEST_URI'] ?? '', 'platform.php'))]) ?>
<?php if (function_exists('pt_icon_packs')): // pacotes de ícones só existem no submódulo novo ?>
<?= bo_nav_link('platform.php?tool=icons', 'bi-grid-3x3-gap', 'Pacotes de ícones', ['mod' => 'sub',
'active' => (($_GET['tool'] ?? '') === 'icons')]) ?>
<?php endif; ?>
<?php bo_nav_group_end(); ?> <?php bo_nav_group_end(); ?>
<?php endif; ?> <?php endif; ?>
</nav> </nav>
+2 -2
View File
@@ -58,8 +58,8 @@ $canonical = $GLOBALS['_canonical_override'] ?? match ($page) {
<!-- Vendor: Bootstrap 5.3.3 --> <!-- Vendor: Bootstrap 5.3.3 -->
<?= link_tag('assets/vendor/bootstrap5/css/bootstrap.min.css') ?> <?= link_tag('assets/vendor/bootstrap5/css/bootstrap.min.css') ?>
<!-- Vendor: Font Awesome 5 --> <!-- Icons: Font Awesome 6 from the shared platform-tools pack (local FA 5.13.1 as fallback) -->
<?= link_tag('site/assets/fonts/fontawesome/css/all.css') ?> <?= fit_icon_assets(['fontawesome'], ['site/assets/fonts/fontawesome/css/all.css']) ?>
<!-- App styles (Bootstrap overrides) --> <!-- App styles (Bootstrap overrides) -->