A car park with both of its sides, built with React 19, TypeScript, Vite 6 and Tailwind CSS v4: the site that sells monthly plans and the desk that runs the yard. Drivers see each site with its live vacancy count, the rate table and the plans. Operators check a vehicle in — with the nearest compatible bay suggested — and check it out with the fee worked out from the rate table: first period, additional periods, the free-if-under tolerance, the daily cap and the night surcharge, shown line by line rather than as a bare total. There is a bay map by sector and floor, monthly customers with due dates, and a till that balances by payment method at close. Occupancy is derived from the bays themselves, so the map and the dashboard can never disagree. Three sites, a hundred and twenty bays and a month of tickets ship as seed data, persisted to localStorage, so nothing needs a backend.
Live preview: https://template.dev.br/preview/parking-react/
14 screens, covering the public site and the authenticated area:
- Home: search by site, site cards with live vacancy, monthly plans, how it works and testimonials
- Sites: address, opening hours, bays by type and current occupancy
- Site: photos, the rate table by period, a simplified bay map and a booking form
- Plans: monthly for car, motorcycle or a fixed bay, with a comparison and sign-up
- Contact: validated contact form
- Login and Register: standalone auth screens
- Dashboard: occupancy now, entries today, revenue, average stay, an occupancy-by-hour chart, vehicles inside and recent exits
- Yard: check-in with plate, type and suggested bay, and check-out with the fee worked out; the list of what is inside, searchable by plate
- Bay map: a grid by sector and floor, each bay showing free, taken, booked, monthly or blocked; click for detail and actions
- Monthly customers: CRUD with vehicle, plan, due date and status, plus this month’s charge
- Rates: table by vehicle type and time band, with tolerance, daily cap, ceiling and night surcharge, and a checkout simulator
- Till: the day by payment method, cash drops, close and history
- Settings: profile, site, sectors and bays, theme and language
- Not found: 404 page
- React 19 with react-dom 19 and TypeScript 5.7 (strict)
- Tailwind CSS v4 with CSS-first configuration (
@tailwindcss/vite) - Vite 6 with
vite-plugin-pwa(installable PWA, offline cache) - React Router 7 with a
RequireAuthwrapper on the app routes - Zustand 5 with the
persistmiddleware - i18next + react-i18next + browser language detector (en, es, pt-BR)
- ApexCharts 5 via react-apexcharts
- Formik + Yup form validation
- Node.js 18 or newer
- npm
npm install
npm run devVite starts a dev server with hot reload. Authentication is simulated in the Zustand auth store, so no backend is needed. Demo credentials:
operador@vagalivre.com/demo123
Any non-empty email and password logs in; the pair above is the account suggested on the login screen and the one the seed data belongs to.
npm run buildRuns the TypeScript check and writes the production bundle to dist/. Preview it locally with npm run preview.
src/
├── components/{app,layout,pk,ui}/
├── data/ types.ts, mock.ts, query.ts
├── i18n/locales/ en.json, es.json, pt-BR.json
├── pages/{public,app}/
└── stores/ auth.ts, ui.ts, parking.ts, desk.ts (Zustand + persist)
Tailwind CSS v4 is configured in CSS, not in a JavaScript config file. The stylesheet imports Tailwind, declares the dark variant and defines the design tokens inside @theme: the Outfit font family, extra breakpoints and the brand color ramp (--color-brand-25 through --color-brand-950). Semantic surface tokens use the --tx- prefix. Dark mode is a class on the root element, toggled at runtime and persisted. Rates, sectors and bays are data, so opening another site is a data change rather than a template change.
Three locales ship with the template: English, Spanish and Brazilian Portuguese. The browser language is detected on first load and the header switcher persists the choice. Plurals use the CLDR rules of the active language, so counts read correctly in all three. Dates, currency and durations are formatted per locale.
The same system exists in five stacks, all sharing the screens and the visual identity, and all of them are free:
- Vue 3.5: https://github.com/danilo62x/parking-vue3
- Angular 19: https://github.com/danilo62x/parking-angular
- Laravel 11 + Blade: https://github.com/danilo62x/parking-laravel
- Static HTML: https://github.com/danilo62x/parking-html
The full catalog of free and paid templates is at https://template.dev.br
This template is free and MIT licensed. If it saves you time, you can support the work with a donation at https://template.dev.br/doar?template=parking-react
MIT, copyright 2026 Danilo Quinelato.