Commit Graph
10 Commits
Author SHA1 Message Date
andreandClaude Sonnet 5.5 58d5199883 feat(gyms): gym logo field; other-gym navbar button uses that gym's brand colour and logo
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-13 17:45:17 +01:00
andreandClaude Sonnet 5.5 716eec9f6d feat(site): root opens the main gym; other gyms as navbar buttons
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-13 17:06:59 +01:00
andreandClaude Sonnet 5 4222b8f2e0 feat(backoffice,site): Sistema consistente com a frota; horário como acordeão
- Sidebar do backoffice: Backups/Auditoria/IP bans/Geo/Origem das visitas/
  Atualizações deixam de ser um link cada (enumerados à mão) e passam a um
  só link "Sistema" para o índice partilhado do platform-tools
  (platform.php?tool=index), como a fotografia/design/dance já fazem — uma
  ferramenta nova no platform-tools passa a aparecer sozinha, sem link novo
  a escrever aqui. Definições, Mensagens e Comunicações continuam com link
  próprio (são páginas do fitme, não do router).
- Horário de Aulas (home e CrossFit, mesmo componente partilhado): a grelha
  fica fechada por omissão atrás de um botão "Ver Horário das aulas"
  (Bootstrap collapse); clicar em "Horário" na navbar (ou abrir a página já
  com #horario no URL) abre-a de imediato em vez de só rolar até uma secção
  fechada.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-26 10:14:46 +01:00
andreandClaude Sonnet 5 4ddefa6dae fix(navbar): logo esticava a barra (altura 252px) — height:auto em falta
O logo tem style="width: 150px" sem height desde sempre; a auditoria
4.7 acrescentou width="756" height="252" (lidos do viewBox do SVG)
sem adicionar height:auto ao inline style. Sem height:auto, o browser
não escala a altura proporcionalmente ao width CSS — ficou fixa nos
252px do atributo, esticando a barra toda. Confirmado ao vivo:
getComputedStyle(img).height passou de "252px" para o valor
proporcional depois desta correção.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 22:00:45 +01:00
andreandClaude Sonnet 5 1e2068bea2 feat(css): site público passa de Bootstrap 4.3.1 (EOL) para 5.3.3
Auditoria: "Site público em Bootstrap 4.3.1 (EOL); backoffice em
5.3.3" — o backoffice já usa a 5.3.3 vendorizada (assets/vendor/bootstrap5/),
o site público passa a usar a mesma cópia em vez da 4.3.1.

Levantamento antes de mexer: a folha de estilo própria (style.css)
quase não usa classes utilitárias cruas do Bootstrap (grep confirma
zero ml-/mr-/pl-/pr-/float-left/float-right/custom-select/
custom-control/badge-/sr-only/font-weight-/text-left/text-right —
tudo classes próprias como .site-btn). O que precisava de mudar:

- CSS/JS: assets/vendor/bootstrap/ -> assets/vendor/bootstrap5/
  (bundle, inclui Popper).
- Os 7 atributos data-toggle/data-target/data-dismiss (BS4) ->
  data-bs-toggle/data-bs-target/data-bs-dismiss (BS5): toggle da nav
  mobile, os dois modais (aula experimental, inscrição), o botão de
  fechar do alerta. O seletor em main.js que lê data-target também
  mudou para não parar de encontrar os botões.
- .close -> .btn-close (BS5 renomeou o componente; markup sem o
  &times; interno, que o BS5 desenha via CSS).
- .form-row -> .row (BS4 tinha form-row com gutters menores; BS5 não
  tem, style.css não tinha overrides para form-row, confirmado).
- O apanhado maior: dois <script> inline chamavam
  jQuery('#trialModal').modal('show') ao estilo de plugin jQuery do
  BS4 (para reabrir o modal depois de um erro de submissão) — o BS5
  não regista plugins jQuery nenhuns, isto ficava morto em silêncio.
  Trocado por new bootstrap.Modal(...).show(), a API JS nativa do
  BS5. grep confirma zero outras chamadas .modal()/.collapse()/etc.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 21:47:15 +01:00
andreandClaude Sonnet 5 595a37fd8b fix(site): width/height nas imagens da home (auditoria 4.7)
125 imagens na home, 0 com srcset e 122 sem width/height — o browser
só sabia o tamanho depois de descarregar, o que causa layout shift.

Uploads são redimensionados a um limite de lado maior (functions_images.php),
não a uma dimensão fixa (fotos de equipa vão de 389x512 a 512x512, ícones
de oferta de 128x128 a 256x256), por isso as dimensões não dão para
hardcode: site_img_dims_attr() em functions_site.php lê o ficheiro real
com getimagesize() por pedido, tal como o gallery.php já fazia, e
devolve o par width="" height="" ou "" se o ficheiro não existir. SVG
não passa por getimagesize() (sem decoder embutido) — svg_img_dims_attr()
lê os atributos width/height (ícones fitme-*.svg, 48x48 fixo) ou cai
para o viewBox (logos do navbar, só têm viewBox).

Aplicado a: ícones da oferta, fotos de equipa (card + painel de detalhe),
ícone de modalidade em modalidade_icon_html() e no horário (index.php e
includes/horario.php), logo do navbar.

srcset ficou de fora: as imagens já vêm coartadas para pouco mais do que
o maior tamanho a que aparecem (fotos de equipa a 512px cabidas numa caixa
de no máx. 200px CSS com object-fit:cover; ícones a 128-256px mostrados a
44px) — é a folga normal para ecrãs retina, não desperdício a resolver
com múltiplas resoluções. E o layout é sempre CSS-driven (width/height:
100% + object-fit), por isso um srcset não mudaria o que é descarregado
por variação de viewport, só pouparia bytes nalguns casos — gerar 2-3
tamanhos por upload via GD seria trabalho a mais para o ganho real neste
site. Fica só o fix de dimensões, que é o que resolve o CLS que a
auditoria mediu.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 21:44:29 +01:00
andreandClaude Sonnet 5 5cf0f14ad2 fix: correções Baixo da auditoria (escaping, dvh, transições, assets)
Fecha os itens 3.2.2, 3.3.1, 4.6, 5.2, 5.6, 5.7 e 7.4 do relatório de
auditoria de 2026-09-24: escapa saídas de site_img_url()/canonical,
valida identificadores de coluna em db_info_save(), troca 100vh por
100dvh, remove a última cor solta, encurta a transição para ~150ms,
acrescenta decoding=async/fetchpriority=high nas imagens da home, e
documenta as versões vendorizadas em ASSETS.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 12:16:33 +01:00
andreandClaude Opus 5.5 5e300fc341 feat: vários ginásios (/3070/ e /<código postal>/), CRUD de ginásios, modalidades após a galeria
Estrutura multi-ginásio: as mesmas secções do site, conteúdo próprio por
ginásio, e cada um numa pasta da URL com o código postal da zona.

- migration_20260926_gyms: tabela gyms (pasta, nome, localidade, publicado,
  principal, secções visíveis, título/imagem do header, SEO, galeria, Place ID,
  página CrossFit) com o FitMe 3070 como ginásio 1 em /3070/; gym_id em team,
  modalidades (o horário segue a modalidade), work_hours, memberships,
  membership_leads e website_offer (tudo o existente → ginásio 1); events com
  gym_id NULL = todos; fitme3070_info passa a uma linha por ginásio (id = gym).
- Site: /<pasta>/, /<pasta>/crossfit, /<pasta>/agendar|inscricao. Ginásio por
  publicar → 404 para o público, pré-visualização (com faixa) para a equipa.
  / e /home → 301 para o ginásio principal (a manter a query); com mais de um
  ginásio publicado, a raiz passa a uma página para escolher. Secções
  desligadas não aparecem nem no menu; menu, canonical, JSON-LD, sitemap,
  formulários, e-mails e reviews (Place ID e cache) são do ginásio.
- Backoffice: Gestão → Ginásios (criar/editar/apagar, secções, e «começar
  com o conteúdo de» outro ginásio — cópias independentes) e o seletor
  «A editar» no topo; equipa, modalidades, horários, horário de
  funcionamento, mensalidades, pedidos, contactos e reviews trabalham sobre o
  ginásio escolhido, e um registo de outro ginásio não abre.
- Modalidades passam para logo a seguir à galeria das instalações.
- Galeria sem cantos arredondados (raio da marca).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 07:26:40 +01:00
andre 3e3382df57 idk 2026-06-12 21:20:23 +01:00
andreandClaude Opus 4.8 e68d357177 Initial import of fitme3070.pt platform
Plain-PHP fleet platform with id.andmore.pt SSO. Wires shared/platform-tools
as a submodule (platform_update, backups, git/migration tools) like the other
platforms.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 10:44:58 +01:00