Corporate leasing platform with an interactive lease calculator and lead generation landing page. Built with React 18, TypeScript, Vite and Tailwind CSS.
npm install
npm run dev # Dev server on port 8080
npm run build # Production build
npm run preview # Preview production build
npm run lint # ESLint| Layer | Technology |
|---|---|
| Build | Vite + SWC |
| UI | React 18 + TypeScript |
| Styling | Tailwind CSS (custom theme) |
| Routing | React Router v6 |
| i18n | Custom Context hook — PL / EN |
| Icons | Lucide React |
| SEO | react-helmet-async + JSON-LD |
| Forms | EmailJS |
| Tests | Vitest |
No component library — all UI built from plain HTML + Tailwind.
src/
├── components/
│ ├── calculator/ # Multi-step lease calculator
│ ├── forms/ # InquiryForm
│ ├── layout/ # Header, Footer
│ ├── modals/ # BookingModal
│ ├── sections/ # Page sections (Hero, Banner, About, …)
│ └── ui/ # Atoms: CTAButton, Reveal, MapPopover, …
├── hooks/
│ ├── useLanguage.tsx # i18n context + t() translation helper
│ ├── useScrollReveal.ts
│ └── useFocusTrap.ts
├── lib/
│ ├── calculator.ts # Lease instalment formula
│ ├── formFlow.ts # Shared calculator + contact form logic
│ ├── validation.ts # NIP / email / phone validators
│ ├── emailjs.ts # EmailJS integration
│ └── analytics.ts # GA4 event helpers
├── pages/
│ ├── Index.tsx
│ ├── CashBack.tsx
│ ├── Discounts.tsx
│ ├── EquipmentFinancing.tsx
│ ├── FAQ.tsx
│ ├── PrivacyPolicy.tsx
│ └── TermsOfService.tsx
└── translations/
├── pl.ts # Polish strings
└── en.ts # English strings
All user-visible strings live in src/translations/pl.ts and src/translations/en.ts. The useLanguage hook exposes a t(key) helper that resolves dot-notation paths (including array indices) against the active language object.
const { t } = useLanguage()
t('cashBack.hero.title') // scalar
t(`equipmentFinancing.sectors.items.${i}.title`) // array item- Brand colours: dark background (
#050505/#0A0A0A), warm yellow CTA (#F5A623→ Tailwindprimary) - Typography: heavy italic uppercase headings (
font-black italic uppercase), legible body text - Shapes:
shape-rhombusutility for clipped rhombus corners - Animations:
Revealcomponent (Intersection Observer fade-in), CSS marquee inBannerSection - Motion safety:
prefers-reduced-motionrespected in all CSS animations
- WCAG 2.0 target
- Semantic heading hierarchy:
h1(page) →h2(sections) →h4(cards); badge labels use<p> aria-labelon interactive icons and form controls- Visible focus states; focus trap in modals
alton all meaningful images;aria-hiddenon decorative elements
