Files
InsanityLab-web/.superpowers/sdd/review-ed35491..be4d933.diff
Adriano b913a2bf90 registri dei piani in git (AI-OS#309)
Refs gitea:Adriano/AI-OS#310

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-06 10:36:26 +02:00

160 lines
6.9 KiB
Diff
Raw Permalink 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.
# Review package: ed35491..HEAD
## Commits
be4d933 feat: pagine programmi con dettaglio e pricing performance class
## Files changed
src/pages/programs/[slug].astro | 98 +++++++++++++++++++++++++++++++++++++++++
src/pages/programs/index.astro | 38 ++++++++++++++++
2 files changed, 136 insertions(+)
## Diff
diff --git a/src/pages/programs/[slug].astro b/src/pages/programs/[slug].astro
new file mode 100644
index 0000000..6f0d178
--- /dev/null
+++ b/src/pages/programs/[slug].astro
@@ -0,0 +1,98 @@
+---
+import Base from '../../layouts/Base.astro';
+import PageHero from '../../components/PageHero.astro';
+import { programs } from '../../data/programs';
+import { performanceClassPricing } from '../../data/pricing';
+export const prerender = true;
+
+export function getStaticPaths() {
+ return programs.map((p) => ({ params: { slug: p.slug }, props: { program: p } }));
+}
+const { program } = Astro.props;
+const others = programs.filter((p) => p.slug !== program.slug);
+const blogCategories = ['Fitness', 'Salute', 'Stile di vita', 'Nutrizione'];
+---
+<Base title={program.title} description={program.excerpt}>
+ <PageHero title={program.title.toUpperCase()} />
+
+ <section class="section">
+ <div class="container prog">
+ <div>
+ <h2>{program.title.toUpperCase()}</h2>
+ <p>{program.longDescription}</p>
+ <ul class="prog__features">
+ {program.features.map((f) => <li>{f}</li>)}
+ </ul>
+ <div class="prog__faq">
+ {program.faq.map((item, i) => (
+ <details open={i === 0}>
+ <summary>{item.q}</summary>
+ <p>{item.a}</p>
+ </details>
+ ))}
+ </div>
+ </div>
+ <aside class="prog__side">
+ <h3>Categorie</h3>
+ {blogCategories.map((c) => <p><a href="/blog">{c}</a></p>)}
+ <h3>Altri programmi</h3>
+ {others.map((o) => <p><a href={`/programs/${o.slug}`}>{o.title}</a></p>)}
+ </aside>
+ </div>
+ </section>
+
+ {program.hasPricing && (
+ <section class="section section--alt">
+ <div class="container">
+ <div class="section-heading">
+ <h2>{performanceClassPricing.heading}</h2>
+ <p>{performanceClassPricing.intro}</p>
+ </div>
+ {performanceClassPricing.groups.map((g) => (
+ <details class="price__group" open={g.open}>
+ <summary>{g.open ? '+' : '–'} {g.label}</summary>
+ {g.plans.length === 0 ? (
+ <p class="price__empty">Contattaci per i dettagli di questo programma. <a href="/contact">Scrivici →</a></p>
+ ) : (
+ <div class="price__row">
+ {g.plans.map((p) => (
+ <div class="price__card">
+ <p class="price__amount">{p.monthly}€</p>
+ <p class="price__per">al mese, semestrale</p>
+ <p class="price__entries">{p.entries} {p.entries === 1 ? 'ingresso settimanale' : 'ingressi settimanali'}</p>
+ <p>{p.note}</p>
+ <p>{p.installments}</p>
+ <p class="price__best">{p.best}</p>
+ <a class="btn" href="/contact">Acquista</a>
+ </div>
+ ))}
+ </div>
+ )}
+ </details>
+ ))}
+ </div>
+ </section>
+ )}
+</Base>
+
+<style>
+ .prog { display: grid; grid-template-columns: 2.2fr 1fr; gap: 60px; }
+ .prog__features { padding-left: 20px; display: grid; gap: 8px; margin-bottom: 30px; }
+ .prog__features li::marker { color: var(--c-accent); }
+ .prog__faq details { border-top: 1px solid #e4ded6; padding-block: 14px; }
+ .prog__faq summary { cursor: pointer; font-family: var(--font-heading); font-size: .85rem; letter-spacing: .08em; color: var(--c-heading); }
+ .prog__side h3 { font-size: .85rem; text-transform: uppercase; letter-spacing: .16em; margin-top: 30px; }
+ .prog__side a { text-decoration: none; color: var(--c-text); }
+ .prog__side a:hover { color: var(--c-accent-dark); }
+ .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); }
+ .price__row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 30px; margin-top: 30px; }
+ .price__card { background: #fff; padding: 36px 28px; text-align: center; }
+ .price__amount { font-family: var(--font-heading); font-size: 2.6rem; color: var(--c-heading); margin: 0; }
+ .price__per { color: var(--c-text-light); font-size: .8rem; }
+ .price__entries { font-family: var(--font-heading); text-transform: uppercase; letter-spacing: .1em; font-size: .82rem; color: var(--c-heading); }
+ .price__card p { margin-bottom: 6px; font-size: .85rem; }
+ .price__best { font-weight: 600; color: var(--c-accent-dark); }
+ .price__card .btn { margin-top: 16px; }
+ @media (max-width: 991px) { .prog { grid-template-columns: 1fr; } .price__row { grid-template-columns: 1fr; } }
+</style>
diff --git a/src/pages/programs/index.astro b/src/pages/programs/index.astro
new file mode 100644
index 0000000..d2446df
--- /dev/null
+++ b/src/pages/programs/index.astro
@@ -0,0 +1,38 @@
+---
+import Base from '../../layouts/Base.astro';
+import PageHero from '../../components/PageHero.astro';
+import { programs } from '../../data/programs';
+export const prerender = true;
+---
+<Base title="Programmi" description="I programmi InsanityLab: Personal Training, Performance Class, Coaching, Pilates Flow, Rehab e Nutrizione.">
+ <PageHero title="programmi" />
+ <section class="section">
+ <div class="container">
+ <div class="section-heading">
+ <h2>Programmi</h2>
+ <p>Questi sono i programmi delle classi di Insanity Lab selezionati per voi. Abbiamo scelto i migliori percorsi per offrirvi un'esperienza di allenamento completa e mirata.</p>
+ </div>
+ <div class="plist">
+ {programs.map((p) => (
+ <article class="plist__card">
+ <h3>{p.title}</h3>
+ <p class="plist__sub">{p.subtitle}</p>
+ <p>{p.excerpt}</p>
+ <a class="plist__more" href={`/programs/${p.slug}`}>Per saperne di più →</a>
+ </article>
+ ))}
+ </div>
+ </div>
+ </section>
+</Base>
+
+<style>
+ .plist { display: grid; grid-template-columns: repeat(3, 1fr); gap: 50px 40px; }
+ .plist__card h3 { letter-spacing: .08em; }
+ .plist__sub { font-size: .8rem; text-transform: uppercase; letter-spacing: .12em; color: var(--c-accent-dark); }
+ .plist__card p { font-size: .92rem; }
+ .plist__more { font-family: var(--font-heading); font-size: .72rem; font-weight: 600; letter-spacing: .18em; text-transform: uppercase; text-decoration: none; color: var(--c-heading); }
+ .plist__more:hover { color: var(--c-accent-dark); }
+ @media (max-width: 991px) { .plist { grid-template-columns: 1fr 1fr; } }
+ @media (max-width: 600px) { .plist { grid-template-columns: 1fr; } }
+</style>