Skip to content

Repository files navigation

Apolo Fit — Gym Website

A modern, production-minded website for a fitness brand ("Apolo") running two centers in Puertollano, Spain: Gymapolo (strength) and Apolofit (cardio, group classes, community).

Built as a fully static site with Next.js 14 (App Router), React 18, TypeScript, TailwindCSS and Framer Motion. All content, images and credentials are placeholders/mock data — swap them for real assets before going to production.

Created by oscarxdev.


Tech stack

  • Next.js 14 — App Router, Server Components, Metadata API, dynamic sitemap/robots, static export (output: "export").
  • React 18 + TypeScript 5 (strict).
  • TailwindCSS 3 — custom brand palette (brand, ink, accent).
  • Framer Motion — page and component animations.
  • Lucide React — icons.
  • Zod — form validation.
  • clsx + tailwind-merge — conditional class handling.

Auth and data are mocked in localStorage, ready to be swapped for a real provider (NextAuth, Supabase, Firebase) and a database or CMS.


What the site includes

  • Home — hero, benefits, featured classes, trainers, pricing, testimonials, centers and FAQ.
  • Facilities — filterable gallery with lightbox.
  • Classes — listing with filters + detail pages (/clases/[slug]) and a reservation flow.
  • Schedule — weekly timetable.
  • Pricing — plans with a feature comparison table.
  • Trainers — listing + individual profile pages.
  • Blog — listing with filters + article pages (/blog/[slug]).
  • Contact — form (Zod-validated), per-center info and embedded Google Maps.
  • Auth — login, register and password recovery (mock).
  • Account area (/cuenta/*) — profile, membership, reservations, payments, goals, notifications.
  • Admin panel (/admin/*) — dashboard plus CRUD sections (classes, trainers, schedule, pricing, reservations, users, blog).
  • GDPR cookie system — banner + preferences modal (necessary / analytics / marketing).
  • Accessibility widget — font sizing, high contrast, pause animations, underline links.
  • SEO — per-page metadata, JSON-LD (HealthClub/Article), dynamic sitemap and robots.

Getting started

Requires Node 18.17+ (20 LTS recommended).

# install dependencies
npm install

# development (http://localhost:3000)
npm run dev

# production build (static export to ./out)
npm run build
npm run start

# checks
npm run lint
npm run type-check

Demo accounts (mock auth)

Role Email Password
user user@apolo.fit user123
admin admin@apolo.fit admin123

Project structure

src/
├── app/            # App Router routes (home, clases, horarios, precios, entrenadores,
│                   #   blog, contacto, login/registro/recuperar, cuenta/*, admin/*)
│                   #   plus layout.tsx, sitemap.ts, robots.ts, not-found.tsx
├── components/     # layout, ui, home sections, cards, classes, gallery, schedule,
│                   #   pricing, blog, forms, admin, cookies, accessibility, providers
├── context/        # AuthContext, CookiesContext, AccessibilityContext
├── data/           # typed mock data (classes, trainers, pricing, blog, centers, faq…)
├── lib/            # utils.ts (cn, formatPrice, slugify), seo.ts (buildMetadata)
├── types/          # shared types
└── middleware.ts   # security headers

Deployment

The project is configured for static export, so it runs on any static host.

  • Cloudflare Workers/Pageswrangler.toml serves the ./out directory directly.
  • Vercelnpx vercel --prod.
  • Self-hostednpm run build then serve ./out behind a proxy (Nginx/Caddy) over HTTPS.

Set the production URL via NEXT_PUBLIC_SITE_URL (used by siteConfig in src/lib/seo.ts) so metadata, sitemap and Open Graph resolve correctly.


Before production

  1. Replace placeholder images, texts, addresses, phone numbers and emails with the real ones.
  2. Wire up real auth (NextAuth / Supabase / Firebase) and move route protection into middleware.ts.
  3. Connect a database (Prisma + Postgres) or a CMS (Sanity / Strapi / Payload).
  4. Add real payments (Stripe checkout + webhooks) and persist memberships.
  5. Implement real reservations with slot capacity and concurrency control.
  6. Load analytics conditionally, based on cookie consent.

License

No license specified. Ask before reusing.

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages