A professional, production-grade mobility platform for Dubai built with Next.js 15, TypeScript, and Tailwind CSS. Combines a preserved landing page with a sophisticated AI-powered multi-modal transportation app.
ARYA Mobility OS is an integrated platform featuring:
- Landing Page: Preserved exact design from original React + Vite app (SPYLT beverage brand)
- Mobility App: AI-powered assistant for Dubai transportation with:
- EV charger finder and predictions
- Parking availability and pricing
- Heat index and health recommendations
- Multi-modal route planning
- Event impact analysis
- Real-time transit information
- User preference management
- Framework: Next.js 15 with App Router
- Language: TypeScript
- Styling: Tailwind CSS + CSS Modules
- Icons: Lucide React
- State Management: React Hooks + Context (Zustand ready)
- Mapping: Mapbox GL JS (optional integration)
- AI: Google Gemini (optional integration)
- CMS: Builder.io (optional integration)
- Content: Simulated data layer (plug real APIs later)
.
├── app/
│ ├── api/ # API routes
│ │ ├── arya/ # ARYA AI assistant
│ │ └── mobility/ # General mobility data
│ ├── app/ # ARYA Mobility OS app
│ │ ├── layout.tsx # Sidebar + top bar
│ │ ├── page.tsx # Overview dashboard
│ │ ├── map/page.tsx # Multi-layer map
│ │ ├── ev/page.tsx # EV charger suite
│ │ ├── routes/page.tsx # Route planner
│ │ ├── health/page.tsx # Heat & safety
│ │ ├── events/page.tsx # Event impacts
│ │ └── settings/page.tsx # User preferences
│ ├── globals.css # Global styles (preserved landing + new)
│ ├── layout.tsx # Root layout
│ └── page.tsx # Home (landing page)
├── components/
│ └── landing/ # Landing page components
│ ├── LandingPage.tsx # Main wrapper
│ ├── HeroSection.tsx
│ ├── MessageSection.tsx
│ ├── FlavorSection.tsx
│ ├── NutritionSection.tsx
│ ├── BenefitSection.tsx
│ ├── TestimonialSection.tsx
│ ├── BottomBanner.tsx
│ ├── FooterSection.tsx
│ ├── Navbar.tsx
│ ├── NavMenu.tsx
│ ├── PreLoader.tsx
│ ├── VideoPin.tsx
│ ├── FlavorTitle.tsx
│ ├── FlavorSlider.tsx
│ └── ClipPathTitle.tsx
├── lib/
│ ├── landing/
│ │ ├── media.ts # Image/video asset helpers
│ │ └── details.ts # Landing page constants
│ └── simulators/
│ ├── ev.ts # EV charger simulator
│ ├── parking.ts # Parking simulator
│ ├── heat.ts # Heat index simulator
│ ├── events.ts # Events simulator
│ └── transit.ts # Transit (bus/metro) simulator
├── types/
│ └── mobility.ts # TypeScript types for all data
├── public/
│ └── landing/
│ ├── assets/
│ │ ├── images/ # Landing page images
│ │ ├── videos/ # Landing page videos
│ │ └── fonts/ # Custom fonts
│ └── favicon.ico
├── .env.example # Environment variables template
├── next.config.ts # Next.js configuration
├── tailwind.config.ts # Tailwind CSS config
├── tsconfig.json # TypeScript config
└── package.json
# Clone and install dependencies
npm install
# or
pnpm installCopy .env.example to .env.local:
cp .env.example .env.localThen fill in your keys:
# Optional: Gemini AI for natural language understanding
NEXT_PUBLIC_GEMINI_API_KEY=your_gemini_api_key
# Optional: Mapbox for interactive maps
NEXT_PUBLIC_MAPBOX_TOKEN=your_mapbox_token
# Optional: Builder.io for content management
NEXT_PUBLIC_BUILDER_API_KEY=your_builder_api_key
NEXT_PUBLIC_BUILDER_API_URL=https://cdn.builder.io/api/v3
# App configuration
NEXT_PUBLIC_APP_NAME=ARYA Mobility OS
NEXT_PUBLIC_APP_URL=http://localhost:3000The landing page requires images and videos from the original Vite app. Create the directory structure:
mkdir -p public/landing/assets/{images,videos,fonts}Copy from original src/assets/:
- Images →
public/landing/assets/images/ - Videos →
public/landing/assets/videos/ - Fonts →
public/landing/assets/fonts/
npm run dev
# Server runs at http://localhost:3000Visit:
- Landing page:
http://localhost:3000 - App dashboard:
http://localhost:3000/app
npm run build
npm run startPOST /api/arya
Body: {
message: string,
conversationHistory?: ChatMessage[],
userLocation?: { latitude: number, longitude: number }
}
Response: AssistantResponse
GET /api/mobility?type=<chargers|parking|transit|events>
Response: APIResponse<MobilityData>
All data is simulated for development. The simulator functions are deterministic and can be:
- Replaced with real API calls
- Cached for better performance
- Validated against real-world data
Key simulators:
lib/simulators/ev.ts- EV charger datalib/simulators/parking.ts- Parking availabilitylib/simulators/heat.ts- Temperature and healthlib/simulators/events.ts- Dubai eventslib/simulators/transit.ts- Bus/metro routes
Uses Tailwind CSS with custom theme:
Color Palette:
- Primary:
accent-warm(#c97c3f) - Secondary:
accent-teal(#4a7c7e) - Surface:
surface/surface-dark - Text:
text-primary/text-secondary
Components:
.card-base- Standard card styling.button-primary/.button-secondary- Buttons.flex-center- Flex centering.container-app- Max-width container
The landing page is completely isolated from the app section:
- All components in
/components/landing/ - Assets from
/public/landing/assets/ - Styles preserved from original design
- Uses GSAP for animations (ScrollSmoother, ScrollTrigger)
To enable natural language understanding for ARYA:
npm install @google/generative-aiUpdate app/api/arya/route.ts and uncomment Gemini integration code.
For interactive multi-layer maps:
npm install mapbox-gl @mapbox/mapbox-gl-draw
npm install -D @types/mapbox-glCreate map component in components/map/MapContainer.tsx and integrate into /app/app/map/page.tsx.
For headless CMS content:
npm install @builder.io/reactCreate lib/builder.ts integration and content components.
For complex app state:
npm install zustandCreate stores in lib/store/ for user preferences, cache, etc.
All TypeScript types are defined in types/mobility.ts:
Location- Geographic pointEVCharger- EV charging stationParkingZone- Parking areaTransitRoute/TransitStop- Public transportHeatIndex- Temperature dataEvent- Dubai eventsRouteOption- Multi-modal routeUserPreferences- User settingsChatMessage/AssistantResponse- ARYA assistant
- Use TypeScript strictly
- Keep components small and focused
- Use React hooks for state
- Prefer functional components
- Add JSDoc comments for complex logic
- Code split at route boundaries (Next.js automatic)
- Lazy load heavy components if needed
- Cache simulator data when possible
- Use
next/imagefor images - Monitor bundle size:
npm run build
- Use semantic HTML
- Add ARIA labels
- Ensure keyboard navigation
- Test with screen readers
Edit tailwind.config.ts:
theme: {
extend: {
colors: {
'accent-warm': '#your-color',
// ...
}
}
}Edit app/app/layout.tsx and add/remove items from NAV_ITEMS.
Create new route in app/app/[feature]/page.tsx and add to navigation.
Make sure you've copied images and videos to public/landing/assets/:
ls public/landing/assets/images/
ls public/landing/assets/videos/Clear Next.js cache:
rm -rf .next
npm run devCheck browser console and npm run dev logs. Ensure environment variables are set correctly.
Verify NEXT_PUBLIC_MAPBOX_TOKEN is set and valid.
npm install -g vercel
vercel login
vercelSet environment variables in Vercel dashboard.
- Netlify: Ensure Node.js 18+ with build command
npm run build - AWS Amplify: Standard Next.js setup
- Docker: Create Dockerfile for containerization
- Real API integration (Dubai RTA data)
- User authentication (NextAuth.js)
- WebSocket for real-time updates
- Progressive Web App (PWA)
- Mobile app via React Native
- Advanced analytics dashboard
- Machine learning for route optimization
- Integration with payment systems
- Never commit
.env.local - Validate all API inputs
- Use HTTPS in production
- Implement rate limiting on APIs
- Add authentication before production
- Sanitize user inputs
- Next.js Docs: https://nextjs.org/docs
- Tailwind CSS: https://tailwindcss.com
- Mapbox GL: https://docs.mapbox.com/mapbox-gl-js
- Builder.io: https://www.builder.io/c/docs
- Google Gemini: https://ai.google.dev
[Your License Here]
Contributions welcome! Please ensure code follows style guidelines and includes tests.