feat: redesign service cards with 3D icons, enhanced hover effects, and updated action buttons

This commit is contained in:
sazzadulalambd
2026-06-22 17:17:40 +06:00
parent 24b00fefcd
commit f50b982ae1
2 changed files with 134 additions and 79 deletions

View File

@@ -161,17 +161,20 @@ export default function LandingPage() {
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
{/* Service 1 */}
<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="absolute top-0 right-0 w-32 h-32 bg-biker/10 rounded-bl-full -mr-8 -mt-8 transition-transform group-hover:scale-110"></div>
<div className="w-16 h-16 bg-biker/10 rounded-2xl flex items-center justify-center mb-6 relative z-10 text-biker group-hover:bg-biker group-hover:text-white transition-colors">
<Bike className="w-8 h-8" />
<div className="group bg-white rounded-3xl p-8 shadow-lg hover:shadow-[0_20px_50px_rgba(0,0,0,0.1)] transition-all duration-500 border border-slate-100 relative overflow-hidden flex flex-col h-full transform hover:-translate-y-2">
<div className="absolute top-0 left-0 w-64 h-64 bg-gradient-to-br from-biker/10 to-transparent rounded-full blur-3xl -ml-16 -mt-16 transition-transform duration-700 group-hover:scale-150"></div>
<div className="w-24 h-24 bg-gradient-to-br from-white to-slate-50 shadow-inner rounded-2xl flex items-center justify-center mb-8 relative z-10 border border-slate-100/50">
<CardIcon3D type="bike" />
</div>
<h4 className="text-2xl font-bold text-slate-900 mb-3 relative z-10">Biker Rentals</h4>
<p className="text-slate-600 mb-8 flex-grow relative z-10">Save on petrol costs and rent a high-performance e-scooter for your daily commute or delivery gigs.</p>
<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>
<button
onClick={() => router.push('/coming-soon')}
disabled={loading}
className="inline-flex items-center gap-2 text-biker font-bold group-hover:translate-x-2 transition-transform relative z-10"
className="inline-flex items-center gap-2 text-white bg-biker px-6 py-3 rounded-full font-bold shadow-lg shadow-biker/30 hover:bg-biker/90 hover:shadow-biker/50 transition-all relative z-10 w-fit"
>
Login as Biker <ChevronRight className="w-5 h-5" />
</button>
@@ -180,60 +183,50 @@ export default function LandingPage() {
{/* Service 2 - FICO Investment - 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="absolute top-0 right-0 w-32 h-32 bg-investor/10 rounded-bl-full -mr-8 -mt-8 transition-transform group-hover:scale-110"></div>
<div className="w-16 h-16 bg-investor/10 rounded-2xl flex items-center justify-center mb-6 relative z-10 text-investor group-hover:bg-investor group-hover:text-white transition-colors">
<Wallet className="w-8 h-8" />
</div>
<h4 className="text-2xl font-bold text-slate-900 mb-3 relative z-10">FICO Investment</h4>
<p className="text-slate-600 mb-8 flex-grow relative z-10">Invest in fractional EV ownership. Let us manage the fleet while you enjoy guaranteed monthly returns.</p>
<button
onClick={() => handleLogin('investor@email.com')}
disabled={loading}
className="inline-flex items-center gap-2 text-investor font-bold group-hover:translate-x-2 transition-transform relative z-10"
>
Login as Investor <ChevronRight className="w-5 h-5" />
</button>
...
</div>
*/}
{/* Service 3 */}
<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="absolute top-0 right-0 w-32 h-32 bg-purple-500/10 rounded-bl-full -mr-8 -mt-8 transition-transform group-hover:scale-110"></div>
<div className="w-16 h-16 bg-purple-500/10 rounded-2xl flex items-center justify-center mb-6 relative z-10 text-purple-500 group-hover:bg-purple-500 group-hover:text-white transition-colors">
<Zap className="w-8 h-8" />
<div className="group bg-white rounded-3xl p-8 shadow-lg hover:shadow-[0_20px_50px_rgba(0,0,0,0.1)] transition-all duration-500 border border-slate-100 relative overflow-hidden flex flex-col h-full transform hover:-translate-y-2">
<div className="absolute top-0 right-0 w-64 h-64 bg-gradient-to-bl from-purple-500/10 to-transparent rounded-full blur-3xl -mr-16 -mt-16 transition-transform duration-700 group-hover:scale-150"></div>
<div className="w-24 h-24 bg-gradient-to-br from-white to-slate-50 shadow-inner rounded-2xl flex items-center justify-center mb-8 relative z-10 border border-slate-100/50">
<CardIcon3D type="swap" />
</div>
<h4 className="text-2xl font-bold text-slate-900 mb-3 relative z-10">Swap Stations</h4>
<p className="text-slate-600 mb-8 flex-grow relative z-10">Never wait to charge. Swap your depleted battery for a fully charged one in less than 2 minutes.</p>
<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>
<button
onClick={() => router.push('/coming-soon')}
disabled={loading}
className="inline-flex items-center gap-2 text-purple-600 font-bold group-hover:translate-x-2 transition-transform relative z-10"
className="inline-flex items-center gap-2 text-white bg-purple-600 px-6 py-3 rounded-full font-bold shadow-lg shadow-purple-600/30 hover:bg-purple-700 hover:shadow-purple-600/50 transition-all relative z-10 w-fit"
>
Login as Swap Station <ChevronRight className="w-5 h-5" />
</button>
</div>
{/* Service 4 (Merchant/Rent to own) */}
<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 md:col-span-2 lg:col-span-3 lg:w-2/3 lg:mx-auto">
<div className="absolute top-0 right-0 w-32 h-32 bg-accent/10 rounded-bl-full -mr-8 -mt-8 transition-transform group-hover:scale-110"></div>
<div className="flex flex-col sm:flex-row gap-6 relative z-10">
<div className="w-16 h-16 shrink-0 bg-accent/10 rounded-2xl flex items-center justify-center text-accent group-hover:bg-accent group-hover:text-white transition-colors">
<Truck className="w-8 h-8" />
{/* Service 3 (Merchant/Deliveries) */}
<div className="group bg-white rounded-3xl p-8 shadow-lg hover:shadow-[0_20px_50px_rgba(0,0,0,0.1)] transition-all duration-500 border border-slate-100 relative overflow-hidden flex flex-col h-full transform hover:-translate-y-2">
<div className="absolute top-0 right-0 w-64 h-64 bg-gradient-to-bl from-accent/10 to-transparent rounded-full blur-3xl -mr-16 -mt-16 transition-transform duration-700 group-hover:scale-150"></div>
<div className="w-24 h-24 bg-gradient-to-br from-white to-slate-50 shadow-inner rounded-2xl flex items-center justify-center mb-8 relative z-10 border border-slate-100/50">
<CardIcon3D type="merchant" />
</div>
<div>
<h4 className="text-2xl font-bold text-slate-900 mb-3">Merchants & Deliveries</h4>
<p className="text-slate-600 mb-6 max-w-xl">Are you a delivery partner or company? Request any amount of riders for your delivery needs. Partner with us for dedicated EV riders.</p>
<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>
<button
onClick={() => router.push('/coming-soon')}
className="inline-flex items-center gap-2 text-accent font-bold group-hover:translate-x-2 transition-transform"
className="inline-flex items-center gap-2 text-white bg-accent px-6 py-3 rounded-full font-bold shadow-lg shadow-accent/30 hover:bg-accent-dark hover:shadow-accent/50 transition-all relative z-10 w-fit"
>
Partner With Us <ChevronRight className="w-5 h-5" />
</button>
</div>
</div>
</div>
</div>
</div>
</section>
{/* Why Choose Jaiben Features */}

View File

@@ -3,20 +3,56 @@ import { useRef } from 'react';
import { Canvas, useFrame } from '@react-three/fiber';
import { Float, Torus, Cylinder, Box, Octahedron, MeshTransmissionMaterial } from '@react-three/drei';
import * as THREE from 'three';
import { useLoader } from '@react-three/fiber';
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js';
import { Suspense, useMemo } from 'react';
function BikeIcon() {
const mesh = useRef<THREE.Mesh>(null);
useFrame((_, delta) => {
if (mesh.current) {
mesh.current.rotation.y += delta;
mesh.current.rotation.x += delta * 0.5;
function ActualBikeIcon() {
const obj = useLoader(OBJLoader, '/uploads_files_3634924_uploads_files_850048_aerox.obj');
const group = useRef<THREE.Group>(null);
const model = useMemo(() => {
const clone = obj.clone();
const box = new THREE.Box3().setFromObject(clone);
const center = box.getCenter(new THREE.Vector3());
const size = box.getSize(new THREE.Vector3());
const maxDim = Math.max(size.x, size.y, size.z);
const scale = 2.0 / maxDim;
clone.scale.setScalar(scale);
clone.position.sub(center.multiplyScalar(scale));
clone.rotation.y = -Math.PI / 4;
const bodyMat = new THREE.MeshStandardMaterial({ color: '#00bc84', roughness: 0.2, metalness: 0.8 });
const darkMat = new THREE.MeshStandardMaterial({ color: '#111111', roughness: 0.9 });
clone.traverse((child) => {
if (child instanceof THREE.Mesh) {
const b = new THREE.Box3().setFromObject(child);
const s = new THREE.Vector3();
b.getSize(s);
const minLocal = Math.min(s.x, s.y, s.z);
const maxLocal = Math.max(s.x, s.y, s.z);
if (minLocal < 0.3 && maxLocal > 0.4) child.material = darkMat;
else child.material = bodyMat;
}
});
return clone;
}, [obj]);
useFrame((_, delta) => {
if (group.current) {
group.current.rotation.y += delta * 1.5;
}
});
return (
<Float floatIntensity={2} speed={2}>
<Torus ref={mesh} args={[1.2, 0.4, 16, 32]} rotation={[Math.PI / 2, 0, 0]}>
<meshStandardMaterial color="#f97316" roughness={0.1} metalness={0.8} />
</Torus>
<Float floatIntensity={1.5} speed={2}>
<group ref={group}>
<primitive object={model} />
</group>
</Float>
);
}
@@ -38,44 +74,68 @@ function InvestorIcon() {
}
function SwapIcon() {
const mesh = useRef<THREE.Mesh>(null);
const group = useRef<THREE.Group>(null);
useFrame((_, delta) => {
if (mesh.current) {
mesh.current.rotation.x += delta;
mesh.current.rotation.y += delta * 1.2;
if (group.current) {
group.current.rotation.y += delta * 1.2;
}
});
return (
<Float floatIntensity={2} speed={2}>
<Box ref={mesh} args={[1.5, 1.5, 1.5]}>
<MeshTransmissionMaterial
color="#a855f7"
thickness={0.5}
roughness={0.1}
transmission={0.9}
ior={1.5}
/>
<Float floatIntensity={1.5} speed={2}>
<group ref={group} scale={0.7} position={[0, -0.8, 0]}>
{/* Main Station Body */}
<Box args={[1.4, 2.8, 1]} position={[0, 1.4, 0]}>
<meshStandardMaterial color="#e2e8f0" roughness={0.2} metalness={0.8} />
</Box>
<Box args={[0.8, 0.8, 0.8]}>
<meshStandardMaterial color="#d8b4fe" emissive="#a855f7" emissiveIntensity={0.5} />
{/* Glowing Screen */}
<Box args={[0.9, 0.5, 0.1]} position={[0, 2.2, 0.51]}>
<meshStandardMaterial color="#d8b4fe" emissive="#a855f7" emissiveIntensity={0.8} />
</Box>
{/* Battery Slots Container */}
<Box args={[1.2, 1.2, 0.2]} position={[0, 1.0, 0.45]}>
<meshStandardMaterial color="#1e293b" />
</Box>
{/* Battery 1 inside slot */}
<Box args={[0.3, 0.6, 0.2]} position={[-0.3, 1.2, 0.5]}>
<meshStandardMaterial color="#a855f7" />
</Box>
{/* Battery 2 inside slot */}
<Box args={[0.3, 0.6, 0.2]} position={[0.3, 0.8, 0.5]}>
<meshStandardMaterial color="#a855f7" />
</Box>
</group>
</Float>
);
}
function MerchantIcon() {
const mesh = useRef<THREE.Mesh>(null);
const group = useRef<THREE.Group>(null);
useFrame((_, delta) => {
if (mesh.current) {
mesh.current.rotation.x += delta * 0.5;
mesh.current.rotation.y += delta;
if (group.current) {
group.current.rotation.y += delta * 1.2;
group.current.rotation.z = Math.sin(_.clock.elapsedTime * 3) * 0.05;
}
});
return (
<Float floatIntensity={2} speed={2}>
<Octahedron ref={mesh} args={[1.5]}>
<meshStandardMaterial color="#00bc84" roughness={0.1} metalness={0.7} />
</Octahedron>
<Float floatIntensity={2} speed={2.5}>
<group ref={group} scale={0.9}>
{/* Main Cargo Box */}
<Box args={[1.4, 1.4, 1.4]}>
<meshStandardMaterial color="#fcd34d" roughness={0.8} />
</Box>
{/* Tape / Ribbon 1 */}
<Box args={[1.42, 0.15, 1.42]} position={[0, 0, 0]}>
<meshStandardMaterial color="#00bc84" roughness={0.3} />
</Box>
{/* Tape / Ribbon 2 */}
<Box args={[1.42, 1.42, 0.15]} position={[0, 0, 0]}>
<meshStandardMaterial color="#00bc84" roughness={0.3} />
</Box>
{/* Delivery Logo / Detail */}
<Box args={[0.5, 0.5, 0.05]} position={[0, 0.3, 0.71]}>
<meshStandardMaterial color="#ffffff" emissive="#00bc84" emissiveIntensity={0.3} />
</Box>
</group>
</Float>
);
}
@@ -87,7 +147,9 @@ export default function CardIcon3D({ type }: { type: 'bike' | 'investor' | 'swap
<ambientLight intensity={0.5} />
<directionalLight position={[5, 5, 5]} intensity={1} />
<pointLight position={[-5, -5, -5]} intensity={0.5} />
{type === 'bike' && <BikeIcon />}
<Suspense fallback={null}>
{type === 'bike' && <ActualBikeIcon />}
</Suspense>
{type === 'investor' && <InvestorIcon />}
{type === 'swap' && <SwapIcon />}
{type === 'merchant' && <MerchantIcon />}