Compare commits

..

15 Commits

Author SHA1 Message Date
sazzadulalambd
5eae6e5094 feat: update homepage copy and service offerings to reflect new rental plan options 2026-06-23 23:42:32 +06:00
sazzadulalambd
e40faf0418 feat: add Forenizence developer credit to footer with responsive layout adjustments 2026-06-23 23:08:00 +06:00
sazzadulalambd
a2ce7c7b49 refactor: update homepage copy, metrics, and coming-soon page z-index styling 2026-06-23 23:03:48 +06:00
sazzadulalambd
ba725c328d chore: update PWA dependencies, add server whitespace, and replace favicon with icon.png 2026-06-23 22:34:41 +06:00
sazzadulalambd
da2f956de9 chore: update package-lock.json dependencies 2026-06-23 01:09:49 +06:00
sazzadulalambd
7a804e84a1 chore: update dependencies, add glob, and configure npm settings 2026-06-23 01:08:03 +06:00
sazzadulalambd
468a6d48ec chore: downgrade project dependencies and remove package-lock.json 2026-06-23 00:40:29 +06:00
sazzadulalambd
a78ba9b343 perf: preload 3D assets and fix mesh material hex code formatting in HeroBackground3D 2026-06-23 00:36:43 +06:00
sazzadulalambd
241c10fe29 chore: downgrade react, @types/node, eslint, and typescript dependencies 2026-06-22 22:37:12 +06:00
sazzadulalambd
34ce6929e5 chore: update package-lock.json dependencies 2026-06-22 22:00:52 +06:00
sazzadulalambd
5c16cb788d chore: update project dependencies to latest versions 2026-06-22 21:52:00 +06:00
sazzadulalambd
cd156b0ff4 refactor: remove unnecessary eslint disable and reformat server configuration for consistency 2026-06-22 21:46:04 +06:00
sazzadulalambd
8c59ac9944 refactor: apply linting rules and consistent formatting to server configuration 2026-06-22 21:20:05 +06:00
sazzadulalambd
637e46b76f chore: clean up existing deployment artifacts before creating new ones 2026-06-22 21:11:58 +06:00
sazzadulalambd
16c9d9e6f3 refactor: simplify deployment script by updating file copy process and documentation 2026-06-22 21:10:23 +06:00
12 changed files with 1489 additions and 1727 deletions

3
.npmrc Normal file
View File

@@ -0,0 +1,3 @@
legacy-peer-deps=true
fund=false
audit=false

View File

@@ -5,22 +5,17 @@ echo "Building project..."
npm run build npm run build
# Create a deployment folder # Create a deployment folder
echo "Preparing standalone deployment files for cPanel..." echo "Preparing deployment files..."
rm -rf deploy rm -rf deploy deploy.zip
mkdir -p deploy mkdir -p deploy
cp -r .next deploy/
# Copy standalone output which includes the minimal server.js and node_modules cp -r public deploy/
cp -r .next/standalone/* deploy/ cp server.js deploy/
cp package.json deploy/
# Copy public assets cp next.config.ts deploy/
cp -r public deploy/public
# Copy static assets (required by standalone server)
mkdir -p deploy/.next
cp -r .next/static deploy/.next/static
# Optional: Zip the files # Optional: Zip the files
echo "Zipping deployment files..." echo "Zipping deployment files..."
cd deploy && zip -r ../deploy.zip . && cd .. cd deploy && zip -r ../deploy.zip . && cd ..
echo "Done! Upload 'deploy.zip' to your cPanel directory, extract it, and point the Node.js app to 'server.js'." echo "Done! Upload 'deploy.zip' to your cPanel directory and follow the guide."

View File

@@ -20,3 +20,6 @@
## Step 5: Documents ## Step 5: Documents
- To be built - To be built
"@ducanh2912/next-pwa": "^10.2.9",

2999
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -12,13 +12,14 @@
"@ducanh2912/next-pwa": "^10.2.9", "@ducanh2912/next-pwa": "^10.2.9",
"@react-three/drei": "^10.7.7", "@react-three/drei": "^10.7.7",
"@react-three/fiber": "^9.6.1", "@react-three/fiber": "^9.6.1",
"date-fns": "^4.1.0", "date-fns": "^4.4.0",
"glob": "^13.0.6",
"jspdf": "^4.2.1", "jspdf": "^4.2.1",
"jspdf-autotable": "^5.0.7", "jspdf-autotable": "^5.0.8",
"lucide-react": "^1.8.0", "lucide-react": "^1.8.0",
"next": "16.2.4", "next": "^16.2.9",
"react": "19.2.4", "react": "^19.2.7",
"react-dom": "19.2.4", "react-dom": "^19.2.7",
"react-hot-toast": "^2.6.0", "react-hot-toast": "^2.6.0",
"three": "^0.184.0" "three": "^0.184.0"
}, },

View File

@@ -1,5 +1,6 @@
const { createServer } = require('http') const { createServer } = require('http')
const { parse } = require('url') const { parse } = require('url')
const next = require('next') const next = require('next')
const dev = process.env.NODE_ENV !== 'production' const dev = process.env.NODE_ENV !== 'production'

View File

@@ -94,7 +94,7 @@ export default function ComingSoonPage() {
return ( return (
<div className="min-h-screen bg-slate-900 flex flex-col items-center justify-center p-4 text-center"> <div className="min-h-screen bg-slate-900 flex flex-col items-center justify-center p-4 text-center">
<div className="absolute top-6 left-6"> <div className="absolute top-6 left-6 z-50">
<button <button
onClick={() => router.push('/')} onClick={() => router.push('/')}
className="text-slate-400 hover:text-white flex items-center gap-2 transition-colors" className="text-slate-400 hover:text-white flex items-center gap-2 transition-colors"
@@ -128,7 +128,7 @@ export default function ComingSoonPage() {
</p> </p>
{/* Mini Game Container */} {/* Mini Game Container */}
<div className="bg-slate-800 p-6 rounded-3xl border border-slate-700 shadow-2xl"> <div className="bg-slate-800 p-6 rounded-3xl border border-slate-700 shadow-2xl z-[9999]">
<div className="flex justify-between items-center mb-6 text-slate-300"> <div className="flex justify-between items-center mb-6 text-slate-300">
<span className="font-semibold">Moves: <span className="text-accent">{moves}</span></span> <span className="font-semibold">Moves: <span className="text-accent">{moves}</span></span>
{won && <span className="text-yellow-400 font-bold flex items-center gap-1"><Trophy className="w-5 h-5" /> You Won!</span>} {won && <span className="text-yellow-400 font-bold flex items-center gap-1"><Trophy className="w-5 h-5" /> You Won!</span>}
@@ -145,8 +145,7 @@ export default function ComingSoonPage() {
<button <button
key={card.id} key={card.id}
onClick={() => handleCardClick(index)} onClick={() => handleCardClick(index)}
className={`aspect-square rounded-xl flex items-center justify-center text-2xl transition-all duration-300 transform ${ className={`aspect-square rounded-xl flex items-center justify-center text-2xl transition-all duration-300 transform ${isVisible
isVisible
? 'bg-accent/20 border-2 border-accent text-accent scale-100 rotate-0' ? 'bg-accent/20 border-2 border-accent text-accent scale-100 rotate-0'
: 'bg-slate-700 border-2 border-slate-600 hover:bg-slate-600 scale-95' : 'bg-slate-700 border-2 border-slate-600 hover:bg-slate-600 scale-95'
} ${card.isMatched ? 'opacity-50' : ''}`} } ${card.isMatched ? 'opacity-50' : ''}`}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

BIN
src/app/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 981 KiB

View File

@@ -62,7 +62,7 @@ export default function LandingPage() {
}; };
return ( return (
<div className="min-h-screen bg-slate-50 font-sans selection:bg-accent selection:text-white pb-20 lg:pb-0"> <div className="min-h-screen bg-slate-50 font-sans selection:bg-accent selection:text-white">
{/* Dynamic Header */} {/* Dynamic Header */}
<header className={`fixed top-0 left-0 right-0 z-50 transition-all duration-300 ${scrolled ? 'bg-white/90 backdrop-blur-md shadow-sm py-3' : 'bg-transparent py-5'}`}> <header className={`fixed top-0 left-0 right-0 z-50 transition-all duration-300 ${scrolled ? 'bg-white/90 backdrop-blur-md shadow-sm py-3' : 'bg-transparent py-5'}`}>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex items-center justify-between"> <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex items-center justify-between">
@@ -102,7 +102,7 @@ export default function LandingPage() {
<span className="text-transparent bg-clip-text bg-gradient-to-r from-accent via-emerald-400 to-accent-light">Go Electric</span> with JAIBEN. <span className="text-transparent bg-clip-text bg-gradient-to-r from-accent via-emerald-400 to-accent-light">Go Electric</span> with JAIBEN.
</h1> </h1>
<p className="text-slate-300 text-lg sm:text-xl mb-10 drop-shadow-lg"> <p className="text-slate-300 text-lg sm:text-xl mb-10 drop-shadow-lg">
The largest EV Tech platform enabling the Gig Economy. Rent, Rent-to-Own, or Invest in EVs. Join the sustainable mobility revolution today. The largest EV Tech platform enabling the Gig Economy. Choose from Single Rent, Rent to Own, or Share an EV. Join the sustainable mobility revolution today.
</p> </p>
<div className="flex flex-col sm:flex-row items-center lg:items-start justify-center lg:justify-start gap-4"> <div className="flex flex-col sm:flex-row items-center lg:items-start justify-center lg:justify-start gap-4">
<button <button
@@ -140,7 +140,7 @@ export default function LandingPage() {
<h3 className="text-4xl md:text-5xl font-black text-slate-900 mb-2 text-accent"> <h3 className="text-4xl md:text-5xl font-black text-slate-900 mb-2 text-accent">
<AnimatedCounter end={18} suffix="%" /> <AnimatedCounter end={18} suffix="%" />
</h3> </h3>
<p className="text-xs sm:text-sm font-semibold text-slate-500 uppercase tracking-wider">Avg. Investor ROI</p> <p className="text-xs sm:text-sm font-semibold text-slate-500 uppercase tracking-wider">Avg. Rider Savings</p>
</div> </div>
<div className="flex flex-col items-center justify-center text-center px-2"> <div className="flex flex-col items-center justify-center text-center px-2">
<h3 className="text-4xl md:text-5xl font-black text-slate-900 mb-2"> <h3 className="text-4xl md:text-5xl font-black text-slate-900 mb-2">
@@ -171,7 +171,7 @@ export default function LandingPage() {
</div> </div>
<h4 className="text-2xl font-extrabold text-slate-900 mb-4 relative z-10">Biker Rentals</h4> <h4 className="text-2xl font-extrabold text-slate-900 mb-4 relative z-10">Biker Rentals</h4>
<p className="text-slate-600 mb-8 flex-grow relative z-10 leading-relaxed">Save on petrol costs and rent a high-performance e-scooter for your daily commute or delivery gigs.</p> <p className="text-slate-600 mb-8 flex-grow relative z-10 leading-relaxed">Save money on fuel. Pick the plan that works for you: Single Rent for quick trips, Rent to Own to keep the bike later, or Share an EV for flexibility.</p>
<button <button
onClick={() => router.push('/coming-soon')} onClick={() => router.push('/coming-soon')}
@@ -182,7 +182,7 @@ export default function LandingPage() {
</button> </button>
</div> </div>
{/* Service 2 - FICO Investment - User will redesign this section */} {/* Service 2 - FICO Partners - User will redesign this section */}
{/* {/*
<div className="group bg-white rounded-3xl p-8 shadow-sm hover:shadow-2xl transition-all duration-300 border border-slate-100 relative overflow-hidden flex flex-col h-full"> <div className="group bg-white rounded-3xl p-8 shadow-sm hover:shadow-2xl transition-all duration-300 border border-slate-100 relative overflow-hidden flex flex-col h-full">
... ...
@@ -198,7 +198,7 @@ export default function LandingPage() {
</div> </div>
<h4 className="text-2xl font-extrabold text-slate-900 mb-4 relative z-10">Swap Stations</h4> <h4 className="text-2xl font-extrabold text-slate-900 mb-4 relative z-10">Swap Stations</h4>
<p className="text-slate-600 mb-8 flex-grow relative z-10 leading-relaxed">Never wait to charge. Swap your depleted battery for a fully charged one in less than 2 minutes.</p> <p className="text-slate-600 mb-8 flex-grow relative z-10 leading-relaxed">Never wait hours to charge your bike. Find a swap station near you, drop off your empty battery, and get a full one in under 2 minutes so you can keep riding.</p>
<button <button
onClick={() => router.push('/coming-soon')} onClick={() => router.push('/coming-soon')}
@@ -218,7 +218,7 @@ export default function LandingPage() {
</div> </div>
<h4 className="text-2xl font-extrabold text-slate-900 mb-4 relative z-10">Merchants & Deliveries</h4> <h4 className="text-2xl font-extrabold text-slate-900 mb-4 relative z-10">Merchants & Deliveries</h4>
<p className="text-slate-600 mb-8 flex-grow relative z-10 leading-relaxed">Are you a delivery partner or company? Request any amount of riders for your delivery needs. Partner with us for dedicated EV riders.</p> <p className="text-slate-600 mb-8 flex-grow relative z-10 leading-relaxed">Grow your delivery business with ease. Request verified EV riders whenever you need them, deliver more orders smoothly, and help keep the environment green.</p>
<button <button
onClick={() => router.push('/coming-soon')} onClick={() => router.push('/coming-soon')}
@@ -303,7 +303,7 @@ export default function LandingPage() {
<div className="absolute -top-2 -right-2 w-8 h-8 bg-accent rounded-full flex items-center justify-center font-bold text-sm">2</div> <div className="absolute -top-2 -right-2 w-8 h-8 bg-accent rounded-full flex items-center justify-center font-bold text-sm">2</div>
</div> </div>
<h4 className="text-xl font-bold mb-3">Choose Your Plan</h4> <h4 className="text-xl font-bold mb-3">Choose Your Plan</h4>
<p className="text-slate-400">Select your EV model and subscription plan (Daily, Weekly, or Rent-to-Own).</p> <p className="text-slate-400">Select your EV model and preferred plan (Single Rent, Rent to Own, or Share an EV).</p>
</div> </div>
<div className="relative text-center"> <div className="relative text-center">
@@ -337,14 +337,14 @@ export default function LandingPage() {
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10 flex flex-col md:flex-row items-center justify-between gap-12"> <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10 flex flex-col md:flex-row items-center justify-between gap-12">
<div className="w-full md:w-1/2 text-center md:text-left text-white"> <div className="w-full md:w-1/2 text-center md:text-left text-white">
<h2 className="text-3xl md:text-5xl font-extrabold mb-6 leading-tight drop-shadow-sm">Ready to ride? <br/>Download the JAIBEN App</h2> <h2 className="text-3xl md:text-5xl font-extrabold mb-6 leading-tight drop-shadow-sm">Ready to ride? <br />Download the JAIBEN App</h2>
<p className="text-white/90 text-lg mb-8 max-w-lg mx-auto md:mx-0 drop-shadow-sm">Get full access to biker rentals, swap station locations, and real-time earnings directly from your smartphone.</p> <p className="text-white/90 text-lg mb-8 max-w-lg mx-auto md:mx-0 drop-shadow-sm">Get full access to biker rentals, swap station locations, and real-time earnings directly from your smartphone.</p>
<div className="flex flex-col sm:flex-row items-center justify-center md:justify-start gap-4"> <div className="flex flex-col sm:flex-row items-center justify-center md:justify-start gap-4">
<button <button
onClick={() => router.push('/coming-soon')} onClick={() => router.push('/coming-soon')}
className="flex items-center gap-3 bg-black text-white px-6 py-3 rounded-xl hover:bg-slate-900 hover:scale-105 transition-all shadow-xl shadow-black/20 w-full sm:w-auto justify-center" className="flex items-center gap-3 bg-black text-white px-6 py-3 rounded-xl hover:bg-slate-900 hover:scale-105 transition-all shadow-xl shadow-black/20 w-full sm:w-auto justify-center"
> >
<svg viewBox="0 0 512 512" className="w-6 h-6 fill-current"><path d="M325.3 234.3L104.6 13l280.8 161.2-60.1 60.1zM47 0C34 6.8 25.3 19.2 25.3 35.3v441.3c0 16.1 8.7 28.5 21.7 35.3l256.6-256L47 0zm425.2 225.6l-58.9-34.1-65.7 64.5 65.7 64.5 60.1-34.1c18-14.3 18-46.5-1.2-60.8zM104.6 499l280.8-161.2-60.1-60.1L104.6 499z"/></svg> <svg viewBox="0 0 512 512" className="w-6 h-6 fill-current"><path d="M325.3 234.3L104.6 13l280.8 161.2-60.1 60.1zM47 0C34 6.8 25.3 19.2 25.3 35.3v441.3c0 16.1 8.7 28.5 21.7 35.3l256.6-256L47 0zm425.2 225.6l-58.9-34.1-65.7 64.5 65.7 64.5 60.1-34.1c18-14.3 18-46.5-1.2-60.8zM104.6 499l280.8-161.2-60.1-60.1L104.6 499z" /></svg>
<div className="flex flex-col text-left"> <div className="flex flex-col text-left">
<span className="text-[10px] leading-none text-slate-300 font-semibold">GET IT ON</span> <span className="text-[10px] leading-none text-slate-300 font-semibold">GET IT ON</span>
<span className="text-lg font-bold leading-none mt-1">Google Play</span> <span className="text-lg font-bold leading-none mt-1">Google Play</span>
@@ -354,7 +354,7 @@ export default function LandingPage() {
onClick={() => router.push('/coming-soon')} onClick={() => router.push('/coming-soon')}
className="flex items-center gap-3 bg-black text-white px-6 py-3 rounded-xl hover:bg-slate-900 hover:scale-105 transition-all shadow-xl shadow-black/20 w-full sm:w-auto justify-center" className="flex items-center gap-3 bg-black text-white px-6 py-3 rounded-xl hover:bg-slate-900 hover:scale-105 transition-all shadow-xl shadow-black/20 w-full sm:w-auto justify-center"
> >
<svg viewBox="0 0 384 512" className="w-6 h-6 fill-current"><path d="M318.7 268.7c-.2-36.7 16.4-64.4 50-84.8-18.8-26.9-47.2-41.7-84.7-44.6-35.5-2.8-74.3 20.7-88.5 20.7-15 0-49.4-19.7-76.4-19.7C63.3 141.2 4 184.8 4 273.5q0 39.3 14.4 81.2c12.8 36.7 59 126.7 107.2 125.2 25.2-.6 43-17.9 75.8-17.9 31.8 0 48.3 17.9 76.4 17.9 48.6-.7 90.4-82.5 102.6-119.3-65.2-30.7-61.7-90-61.7-91.9zm-56.6-164.2c27.3-32.4 24.8-61.9 24-72.5-24.1 1.4-52 16.4-67.9 34.9-17.5 19.8-27.8 44.3-25.6 71.9 26.1 2 49.9-11.4 69.5-34.3z"/></svg> <svg viewBox="0 0 384 512" className="w-6 h-6 fill-current"><path d="M318.7 268.7c-.2-36.7 16.4-64.4 50-84.8-18.8-26.9-47.2-41.7-84.7-44.6-35.5-2.8-74.3 20.7-88.5 20.7-15 0-49.4-19.7-76.4-19.7C63.3 141.2 4 184.8 4 273.5q0 39.3 14.4 81.2c12.8 36.7 59 126.7 107.2 125.2 25.2-.6 43-17.9 75.8-17.9 31.8 0 48.3 17.9 76.4 17.9 48.6-.7 90.4-82.5 102.6-119.3-65.2-30.7-61.7-90-61.7-91.9zm-56.6-164.2c27.3-32.4 24.8-61.9 24-72.5-24.1 1.4-52 16.4-67.9 34.9-17.5 19.8-27.8 44.3-25.6 71.9 26.1 2 49.9-11.4 69.5-34.3z" /></svg>
<div className="flex flex-col text-left"> <div className="flex flex-col text-left">
<span className="text-[10px] leading-none text-slate-300 font-semibold">Download on the</span> <span className="text-[10px] leading-none text-slate-300 font-semibold">Download on the</span>
<span className="text-lg font-bold leading-none mt-1">App Store</span> <span className="text-lg font-bold leading-none mt-1">App Store</span>
@@ -438,9 +438,9 @@ export default function LandingPage() {
<div> <div>
<h4 className="text-white font-bold mb-6">Services</h4> <h4 className="text-white font-bold mb-6">Services</h4>
<ul className="space-y-3 text-slate-400"> <ul className="space-y-3 text-slate-400">
<li><button onClick={() => router.push('/coming-soon')} className="hover:text-accent transition-colors">EV for Deliveries</button></li> <li><button onClick={() => router.push('/coming-soon')} className="hover:text-accent transition-colors">Single Rent</button></li>
<li><button onClick={() => router.push('/coming-soon')} className="hover:text-accent transition-colors">Rent to Own</button></li> <li><button onClick={() => router.push('/coming-soon')} className="hover:text-accent transition-colors">Rent to Own</button></li>
<li><button onClick={() => router.push('/coming-soon')} className="hover:text-accent transition-colors">Investor Platform</button></li> <li><button onClick={() => router.push('/coming-soon')} className="hover:text-accent transition-colors">Share an EV</button></li>
<li><button onClick={() => router.push('/coming-soon')} className="hover:text-accent transition-colors">Swap Stations</button></li> <li><button onClick={() => router.push('/coming-soon')} className="hover:text-accent transition-colors">Swap Stations</button></li>
</ul> </ul>
</div> </div>
@@ -457,8 +457,8 @@ export default function LandingPage() {
</div> </div>
<div className="border-t border-slate-800 pt-8 flex flex-col md:flex-row justify-between items-center gap-4"> <div className="border-t border-slate-800 pt-8 flex flex-col md:flex-row justify-between items-center gap-4">
<p className="text-slate-500 text-sm"> <p className="text-slate-500 text-sm text-center md:text-left">
&copy; {new Date().getFullYear()} JAIBEN Mobility Ltd. All rights reserved. &copy; {new Date().getFullYear()} JAIBEN Mobility Ltd. All rights reserved. <span className="hidden md:inline">|</span><br className="md:hidden" /> Developed by <a href="https://forenizence.com/" target="_blank" rel="noopener noreferrer" className="hover:text-accent transition-colors font-medium">Forenizence</a>
</p> </p>
<div className="flex gap-6 text-sm text-slate-500"> <div className="flex gap-6 text-sm text-slate-500">
<a href="#" className="hover:text-white transition-colors">Privacy Policy</a> <a href="#" className="hover:text-white transition-colors">Privacy Policy</a>

View File

@@ -14,6 +14,9 @@ import {
import * as THREE from 'three'; import * as THREE from 'three';
import { OBJLoader } from 'three-stdlib'; import { OBJLoader } from 'three-stdlib';
useLoader.preload(OBJLoader, '/aerox.obj');
useLoader.preload(THREE.TextureLoader, '/jaiben.png');
const ACCENT = '#00bc84'; const ACCENT = '#00bc84';
const ACCENT_BRIGHT = '#10b981'; const ACCENT_BRIGHT = '#10b981';
@@ -138,7 +141,7 @@ function Battery({ position, scale = 1, rotation = [0, 0, 0] }: { position: [num
{/* Handle */} {/* Handle */}
<mesh position={[0, 0.70, 0]} castShadow receiveShadow> <mesh position={[0, 0.70, 0]} castShadow receiveShadow>
<torusGeometry args={[0.15, 0.04, 16, 32, Math.PI]} /> <torusGeometry args={[0.15, 0.04, 16, 32, Math.PI]} />
<meshStandardMaterial color="#0d7a33ff" roughness={0.2} metalness={0.9} /> <meshStandardMaterial color="#0d7a33" roughness={0.2} metalness={0.9} />
</mesh> </mesh>
{/* Glowing Indicator Light */} {/* Glowing Indicator Light */}

BIN
zivrehiG Normal file

Binary file not shown.