Spaces:
Running
Running
import React, { useState, useEffect } from 'react'; | |
import './MobileApp.css'; | |
// Mock data for demonstration purposes | |
const mockVehicles = [ | |
{ id: 1, name: 'Tesla Model 3', type: 'sedan', range: '310 miles', available: true, image: '/images/tesla_model3.png' }, | |
{ id: 2, name: 'Tesla Model Y', type: 'suv', range: '330 miles', available: true, image: '/images/tesla_modely.png' }, | |
{ id: 3, name: 'Tesla Cybertruck', type: 'truck', range: '500 miles', available: false, image: '/images/cybertruck.png' }, | |
{ id: 4, name: 'GMC Hummer EV', type: 'truck', range: '350 miles', available: true, image: '/images/hummer_ev.png' }, | |
]; | |
const mockSubscriptions = [ | |
{ id: 1, name: 'FlexRide', price: 500, description: 'Basic access to Unity Fleet vehicles', features: ['24/7 vehicle access', 'Basic charging', 'Standard support'] }, | |
{ id: 2, name: 'Take-Home', price: 1200, description: 'Dedicated vehicle for personal use', features: ['Dedicated vehicle', 'Home charging setup', 'Premium support', 'Insurance included'] }, | |
{ id: 3, name: 'All-Access', price: 2000, description: 'Complete mobility solution', features: ['Multiple vehicle types', 'Priority charging', 'Concierge service', 'VIP lounge access', 'Unlimited miles'] }, | |
]; | |
const mockChargingLocations = [ | |
{ id: 1, name: 'The Link - Downtown', address: '123 Main St, Springfield, IL', available: 5, total: 8, amenities: ['Lounge', 'Coffee Bar', 'WiFi'] }, | |
{ id: 2, name: 'The Link - Westside', address: '456 Oak Ave, Springfield, IL', available: 2, total: 6, amenities: ['Lounge', 'Retail', 'WiFi'] }, | |
{ id: 3, name: 'The Link - University', address: '789 Campus Dr, Urbana, IL', available: 8, total: 12, amenities: ['Lounge', 'Restaurant', 'WiFi', 'Conference Room'] }, | |
]; | |
function MobileApp() { | |
const [activeTab, setActiveTab] = useState('home'); | |
const [loading, setLoading] = useState(true); | |
const [user, setUser] = useState({ | |
name: 'Matthew Lamb', | |
subscription: 'All-Access', | |
credits: 2500, | |
reservations: [ | |
{ id: 101, vehicle: 'Tesla Model 3', date: '2025-04-08', time: '09:00 AM', location: 'The Link - Downtown' } | |
] | |
}); | |
useEffect(() => { | |
// Simulate loading | |
const timer = setTimeout(() => { | |
setLoading(false); | |
}, 1500); | |
return () => clearTimeout(timer); | |
}, []); | |
if (loading) { | |
return ( | |
<div className="mobile-app loading"> | |
<div className="loading-logo"> | |
<img src="/images/unity_fleet_logo.png" alt="Unity Fleet" /> | |
<div className="loading-pulse"></div> | |
</div> | |
<p>Connecting to The Link...</p> | |
</div> | |
); | |
} | |
return ( | |
<div className="mobile-app"> | |
<header className="app-header"> | |
<h1>THE LINK</h1> | |
<div className="user-profile"> | |
<img src="/images/profile_avatar.png" alt="Profile" /> | |
</div> | |
</header> | |
<main className="app-content"> | |
{activeTab === 'home' && ( | |
<div className="home-screen"> | |
<div className="welcome-card"> | |
<h2>Welcome back, {user.name}</h2> | |
<p>{user.subscription} Member</p> | |
<div className="credit-display"> | |
<span className="credit-amount">${user.credits}</span> | |
<span className="credit-label">Available Credits</span> | |
</div> | |
</div> | |
<div className="quick-actions"> | |
<button className="action-button"> | |
<span className="icon">π</span> | |
<span>Reserve</span> | |
</button> | |
<button className="action-button"> | |
<span className="icon">β‘</span> | |
<span>Charge</span> | |
</button> | |
<button className="action-button"> | |
<span className="icon">π</span> | |
<span>Unlock</span> | |
</button> | |
<button className="action-button"> | |
<span className="icon">π</span> | |
<span>Locate</span> | |
</button> | |
</div> | |
<div className="upcoming-reservations"> | |
<h3>Upcoming Reservations</h3> | |
{user.reservations.length > 0 ? ( | |
user.reservations.map(reservation => ( | |
<div key={reservation.id} className="reservation-card"> | |
<div className="reservation-vehicle">{reservation.vehicle}</div> | |
<div className="reservation-details"> | |
<div>{reservation.date} at {reservation.time}</div> | |
<div>{reservation.location}</div> | |
</div> | |
<button className="reservation-action">Manage</button> | |
</div> | |
)) | |
) : ( | |
<p className="no-reservations">No upcoming reservations</p> | |
)} | |
</div> | |
<div className="nearby-hubs"> | |
<h3>Nearby Charging Hubs</h3> | |
<div className="hub-list"> | |
{mockChargingLocations.map(hub => ( | |
<div key={hub.id} className="hub-card"> | |
<div className="hub-info"> | |
<h4>{hub.name}</h4> | |
<p>{hub.address}</p> | |
<div className="availability"> | |
<span className={hub.available > 0 ? "available" : "unavailable"}> | |
{hub.available}/{hub.total} Available | |
</span> | |
</div> | |
</div> | |
<button className="hub-action">Navigate</button> | |
</div> | |
))} | |
</div> | |
</div> | |
</div> | |
)} | |
{activeTab === 'vehicles' && ( | |
<div className="vehicles-screen"> | |
<h2>Available Vehicles</h2> | |
<div className="vehicle-filters"> | |
<button className="filter-button active">All</button> | |
<button className="filter-button">Sedan</button> | |
<button className="filter-button">SUV</button> | |
<button className="filter-button">Truck</button> | |
</div> | |
<div className="vehicle-list"> | |
{mockVehicles.map(vehicle => ( | |
<div key={vehicle.id} className={`vehicle-card ${!vehicle.available ? 'unavailable' : ''}`}> | |
<div className="vehicle-image"> | |
<img src={vehicle.image} alt={vehicle.name} /> | |
{!vehicle.available && <div className="unavailable-overlay">Reserved</div>} | |
</div> | |
<div className="vehicle-info"> | |
<h3>{vehicle.name}</h3> | |
<p className="vehicle-type">{vehicle.type}</p> | |
<p className="vehicle-range">Range: {vehicle.range}</p> | |
</div> | |
<button className="vehicle-reserve" disabled={!vehicle.available}> | |
{vehicle.available ? 'Reserve' : 'Unavailable'} | |
</button> | |
</div> | |
))} | |
</div> | |
</div> | |
)} | |
{activeTab === 'subscriptions' && ( | |
<div className="subscriptions-screen"> | |
<h2>Subscription Plans</h2> | |
<p className="current-plan">Current Plan: <strong>{user.subscription}</strong></p> | |
<div className="subscription-list"> | |
{mockSubscriptions.map(sub => ( | |
<div key={sub.id} className={`subscription-card ${sub.name === user.subscription ? 'current' : ''}`}> | |
<div className="subscription-header"> | |
<h3>{sub.name}</h3> | |
<div className="subscription-price">${sub.price}<span>/mo</span></div> | |
</div> | |
<p className="subscription-desc">{sub.description}</p> | |
<ul className="subscription-features"> | |
{sub.features.map((feature, index) => ( | |
<li key={index}>{feature}</li> | |
))} | |
</ul> | |
<button className={`subscription-action ${sub.name === user.subscription ? 'current' : ''}`}> | |
{sub.name === user.subscription ? 'Current Plan' : 'Switch Plan'} | |
</button> | |
</div> | |
))} | |
</div> | |
</div> | |
)} | |
{activeTab === 'charging' && ( | |
<div className="charging-screen"> | |
<h2>Charging Lounges</h2> | |
<div className="map-container"> | |
<img src="/images/charging_map.png" alt="Charging Map" className="charging-map" /> | |
<div className="map-markers"> | |
{mockChargingLocations.map(location => ( | |
<div | |
key={location.id} | |
className="map-marker" | |
style={{ | |
top: `${20 + location.id * 15}%`, | |
left: `${20 + location.id * 20}%` | |
}} | |
data-available={location.available} | |
> | |
<div className="marker-pulse"></div> | |
<div className="marker-label">{location.name}</div> | |
</div> | |
))} | |
</div> | |
</div> | |
<div className="charging-list"> | |
<h3>Charging Locations</h3> | |
{mockChargingLocations.map(location => ( | |
<div key={location.id} className="charging-location-card"> | |
<div className="location-info"> | |
<h4>{location.name}</h4> | |
<p>{location.address}</p> | |
<div className="amenities"> | |
{location.amenities.map((amenity, index) => ( | |
<span key={index} className="amenity-tag">{amenity}</span> | |
))} | |
</div> | |
</div> | |
<div className="location-status"> | |
<div className={`availability-indicator ${location.available > 0 ? 'available' : 'full'}`}> | |
{location.available > 0 ? `${location.available} Available` : 'Full'} | |
</div> | |
<button className="location-action">Details</button> | |
</div> | |
</div> | |
))} | |
</div> | |
</div> | |
)} | |
{activeTab === 'chainlink' && ( | |
<div className="chainlink-screen"> | |
<h2>ChainLink Tokenization</h2> | |
<div className="token-balance"> | |
<div className="token-icon">⬑</div> | |
<div className="token-amount">125.5</div> | |
<div className="token-label">LINK Tokens</div> | |
</div> | |
<div className="token-value"> | |
<div className="value-label">Estimated Value</div> | |
<div className="value-amount">$12,550</div> | |
<div className="value-change positive">+5.2% this week</div> | |
</div> | |
<div className="token-categories"> | |
<h3>Your Token Portfolio</h3> | |
<div className="category-cards"> | |
<div className="category-card"> | |
<div className="category-icon" style={{backgroundColor: '#00E0FF'}}>β‘</div> | |
<div className="category-name">Charging Infrastructure</div> | |
<div className="category-amount">75.0 LINK</div> | |
</div> | |
<div className="category-card"> | |
<div className="category-icon" style={{backgroundColor: '#35F2DB'}}>π</div> | |
<div className="category-name">Fleet Vehicles</div> | |
<div className="category-amount">32.5 LINK</div> | |
</div> | |
<div className="category-card"> | |
<div className="category-icon" style={{backgroundColor: '#4A7AFF'}}>π</div> | |
<div className="category-name">Energy Systems</div> | |
<div className="category-amount">18.0 LINK</div> | |
</div> | |
</div> | |
</div> | |
<div className="token-actions"> | |
<button className="token-action-button">Buy Tokens</button> | |
<button className="token-action-button">Sell Tokens</button> | |
<button className="token-action-button">View Benefits</button> | |
</div> | |
<div className="token-history"> | |
<h3>Recent Transactions</h3> | |
<div className="transaction-list"> | |
<div className="transaction-item"> | |
<div className="transaction-icon purchase">+</div> | |
<div className="transaction-details"> | |
<div className="transaction-title">Purchased 10.0 LINK</div> | |
<div className="transaction-date">Apr 5, 2025</div> | |
</div> | |
<div className="transaction-amount">$1,000</div> | |
</div> | |
<div className="transaction-item"> | |
<div className="transaction-icon reward">β </div> | |
<div className="transaction-details"> | |
<div className="transaction-title">Loyalty Reward</div> | |
<div className="transaction-date">Apr 1, 2025</div> | |
</div> | |
<div className="transaction-amount">+2.5 LINK</div> | |
</div> | |
<div className="transaction-item"> | |
<div className="transaction-icon dividend">$</div> | |
<div className="transaction-details"> | |
<div className="transaction-title">Quarterly Dividend</div> | |
<div className="transaction-date">Mar 31, 2025</div> | |
</div> | |
<div className="transaction-amount">$325</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
)} | |
</main> | |
<footer className="app-navigation"> | |
<button | |
className={`nav-button ${activeTab === 'home' ? 'active' : ''}`} | |
onClick={() => setActiveTab('home')} | |
> | |
<span className="nav-icon">π </span> | |
<span className="nav-label">Home</span> | |
</button> | |
<button | |
className={`nav-button ${activeTab === 'vehicles' ? 'active' : ''}`} | |
onClick={() => setActiveTab('vehicles')} | |
> | |
<span className="nav-icon">π</span> | |
<span className="nav-label">Vehicles</span> | |
</button> | |
<button | |
className={`nav-button ${activeTab === 'subscriptions' ? 'active' : ''}`} | |
onClick={() => setActiveTab('subscriptions')} | |
> | |
<span className="nav-icon">π±</span> | |
<span className="nav-label">Plans</span> | |
</button> | |
<button | |
className={`nav-button ${activeTab === 'charging' ? 'active' : ''}`} | |
onClick={() => setActiveTab('charging')} | |
> | |
<span className="nav-icon">β‘</span> | |
<span className="nav-label">Charging</span> | |
</button> | |
<button | |
className={`nav-button ${activeTab === 'chainlink' ? 'active' : ''}`} | |
onClick={() => setActiveTab('chainlink')} | |
> | |
<span className="nav-icon">⬑</span> | |
<span className="nav-label">ChainLink</span> | |
</button> | |
</footer> | |
</div> | |
); | |
} | |
export default MobileApp; | |