Calendario delle class: popup a pieno schermo dalle pagine Performance e Holistic
Le due griglie fornite dal cliente (1-18 settembre, dal 21 in poi) sono trascritte come dato e ridisegnate nello stile del sito: si leggono da telefono, si stampano in PDF e per correggere una cella non serve rifare uno screenshot. Quale griglia compare lo decide la data, come per le edizioni della promo: quella in vigore, oppure - se nessuna lo e' ancora - la prossima, dichiarando da quando entra. Serve perche' il link esiste da subito e ad agosto un "nessun calendario" non direbbe niente a chi vuole gli orari di settembre. Il popup e' un <dialog> nativo: fondale, Esc e trappola del focus senza librerie. "Scarica in PDF" stampa la sola griglia, gia' impaginata in orizzontale dal CSS di stampa. Le discipline hanno una barra colorata a sinistra oltre al fondo, cosi' restano distinguibili anche quando il browser stampa senza sfondi. Quattordici test sul dato: confini al secondo in ora italiana, fasce orarie uniche e in ordine, nessuna lezione in un giorno di chiusura, e il buco vero fra il 19 e il 20 settembre resta dichiarato invece che nascosto. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -7,12 +7,18 @@ import { performanceClassPricing } from '../../data/pricing';
|
||||
import { serviceIcons } from '../../data/service-icons';
|
||||
import T from '../../components/content/T.astro';
|
||||
import TImg from '../../components/content/TImg.astro';
|
||||
import CalendarioModal from '../../components/CalendarioModal.astro';
|
||||
import { calendarioDaMostrare, SERVIZI_CON_CALENDARIO } from '../../data/calendari';
|
||||
import { t } from '../../lib/content';
|
||||
export const prerender = false;
|
||||
|
||||
const service = getService(Astro.params.slug!);
|
||||
if (!service) return new Response(null, { status: 404 });
|
||||
const slug = service.slug;
|
||||
// Il calendario della sala si apre dalle pagine delle class. La voce compare solo se c'è
|
||||
// davvero una griglia da mostrare (in vigore o prossima): un link che apre un popup vuoto è
|
||||
// peggio di nessun link.
|
||||
const conCalendario = SERVIZI_CON_CALENDARIO.includes(slug) && calendarioDaMostrare(new Date()) !== null;
|
||||
const others = services.filter((p) => p.slug !== service.slug && p.grid !== false);
|
||||
const images = import.meta.glob<{ default: ImageMetadata }>('../../assets/img/program-*.jpg', { eager: true });
|
||||
const imgOf = (slug: string) => Object.entries(images).find(([p]) => p.includes(`program-${slug}.`))?.[1]?.default;
|
||||
@@ -59,6 +65,16 @@ const tones = ['tan', 'taupe', 'dark'];
|
||||
<T tag={`service.${o.slug}.title`} />
|
||||
</a>
|
||||
))}
|
||||
{conCalendario && (
|
||||
<button type="button" class="prog__other prog__other--calendario" data-apri-calendario>
|
||||
<span class="prog__icon">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.4" width="26" height="26" aria-hidden="true">
|
||||
<path d="M4 6h16v14H4zM4 10h16M8 3v4M16 3v4M8 14h3M8 17h3M14 14h2" />
|
||||
</svg>
|
||||
</span>
|
||||
{t('calendario.link-label')}
|
||||
</button>
|
||||
)}
|
||||
</aside>
|
||||
</div>
|
||||
</section>
|
||||
@@ -95,6 +111,8 @@ const tones = ['tan', 'taupe', 'dark'];
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{conCalendario && <CalendarioModal />}
|
||||
</Base>
|
||||
|
||||
<style>
|
||||
@@ -109,6 +127,9 @@ const tones = ['tan', 'taupe', 'dark'];
|
||||
.prog__cat { font-family: var(--font-heading); font-size: .72rem; letter-spacing: .18em; text-transform: uppercase; color: var(--c-text); margin-bottom: 10px; }
|
||||
.prog__other { display: flex; align-items: center; gap: 14px; text-decoration: none; color: var(--c-text); margin-bottom: 14px; font-family: var(--font-heading); font-size: .78rem; letter-spacing: .14em; text-transform: uppercase; }
|
||||
.prog__other:hover { color: var(--c-accent-dark); }
|
||||
/* La voce del calendario apre un popup, quindi è un bottone e non un link: qui gli si
|
||||
toglie l'aspetto da bottone perché nella colonna sia indistinguibile dalle altre voci. */
|
||||
.prog__other--calendario { background: none; border: 0; padding: 0; cursor: pointer; width: 100%; text-align: left; }
|
||||
.prog__icon { display: inline-flex; align-items: center; justify-content: center; width: 48px; height: 48px; background: var(--c-accent); color: #fff; flex-shrink: 0; }
|
||||
.price__group { border-top: 1px solid #ddd5ca; padding-block: 18px; }
|
||||
.price__group summary { cursor: pointer; font-family: var(--font-heading); letter-spacing: .12em; text-transform: uppercase; font-size: .85rem; color: var(--c-heading); }
|
||||
|
||||
Reference in New Issue
Block a user