157 lines
5.6 KiB
React
157 lines
5.6 KiB
React
import { motion, useReducedMotion } from 'framer-motion';
|
|
import { assetUrl } from '../lib/assetUrl';
|
|
|
|
const ACCENT_GRADIENTS = [
|
|
'linear-gradient(0deg, #ffffff 0%, #ffffff 50%, #e6f7ef 100%)',
|
|
'linear-gradient(0deg, #ffffff 0%, #ffffff 50%, #f7effe 100%)',
|
|
'linear-gradient(0deg, #ffffff 0%, #ffffff 50%, #fefce8 100%)',
|
|
];
|
|
|
|
export default function ProductCard({ product, isMobile, delay = 0, index = 0 }) {
|
|
if (!product) return null;
|
|
const shouldReduceMotion = useReducedMotion();
|
|
|
|
const dashWidth = isMobile ? '92%' : '520px';
|
|
const dashLeft = isMobile ? '4%' : '20px';
|
|
const dashHeight = isMobile ? '220px' : '300px';
|
|
|
|
// Badge position configurations matching exact design screenshot
|
|
const statPositions = [
|
|
// Index 0: Nebula AI Platform
|
|
[
|
|
{ bottom: '25px', left: '20px', bg: 'rgba(30, 30, 35, 0.65)', color: '#ffffff' }, // Bottom Left: 60% Faster Process Automation
|
|
{ top: '15px', right: '15px', bg: 'rgba(30, 30, 35, 0.65)', color: '#ffffff' } // Top Right: 24/7 AI Driven Assistance
|
|
],
|
|
// Index 1: PRODMAX
|
|
[
|
|
{ top: '40px', left: '15px', bg: 'rgba(255, 255, 255, 0.65)', color: '#000000' }, // Top/Middle Left: 5%+ OEE Improvement
|
|
{ bottom: '15px', right: '15px', bg: 'rgba(30, 30, 35, 0.65)', color: '#ffffff' } // Bottom Right: 15% Reduction in Downtime
|
|
],
|
|
// Index 2: Budgie
|
|
[
|
|
{ bottom: '40px', left: '20px', bg: 'rgba(255, 255, 255, 0.75)', color: '#166534' } // Bottom Left: 40% Faster HR Operations
|
|
]
|
|
];
|
|
|
|
const currentPos = statPositions[index % statPositions.length] || [];
|
|
|
|
return (
|
|
<motion.div
|
|
initial={shouldReduceMotion ? false : { opacity: 0, y: 40 }}
|
|
whileInView={shouldReduceMotion ? undefined : { opacity: 1, y: 0 }}
|
|
viewport={{ once: true, amount: 0.15 }}
|
|
transition={{ duration: 0.8, ease: [0.22, 1, 0.36, 1], delay }}
|
|
style={{ height: '100%' }}
|
|
>
|
|
<div
|
|
className="product-card"
|
|
style={{
|
|
borderRadius: '24px',
|
|
border: '6px solid #ffffff',
|
|
background: ACCENT_GRADIENTS[index % ACCENT_GRADIENTS.length],
|
|
padding: isMobile ? '1.75rem 1.25rem 0' : '2.2rem 2rem 0 2rem',
|
|
boxShadow: '0 8px 25px rgba(0, 0, 0, 0.06), 0 0 0 1px rgba(255, 255, 255, 0.8)',
|
|
position: 'relative',
|
|
overflow: 'hidden',
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
height: '100%',
|
|
minHeight: isMobile ? '400px' : '520px',
|
|
transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',
|
|
}}
|
|
onMouseEnter={(e) => {
|
|
if (isMobile) return;
|
|
e.currentTarget.style.transform = 'translateY(-6px)';
|
|
e.currentTarget.style.boxShadow = '0 12px 35px rgba(0, 0, 0, 0.08)';
|
|
e.currentTarget.style.borderColor = 'rgba(0, 0, 0, 0.15)';
|
|
}}
|
|
onMouseLeave={(e) => {
|
|
e.currentTarget.style.transform = 'translateY(0)';
|
|
e.currentTarget.style.boxShadow = '0 8px 25px rgba(0, 0, 0, 0.04)';
|
|
e.currentTarget.style.borderColor = 'rgba(0, 0, 0, 0.08)';
|
|
}}
|
|
>
|
|
<h3 style={{
|
|
fontSize: isMobile ? '1.4rem' : '1.8rem',
|
|
fontWeight: 600,
|
|
color: '#0f172a',
|
|
margin: '0 0 0.6rem 0',
|
|
letterSpacing: '-0.02em',
|
|
position: 'relative',
|
|
zIndex: 3,
|
|
}}>
|
|
{product.name}
|
|
</h3>
|
|
|
|
<p style={{
|
|
color: '#475569',
|
|
fontSize: isMobile ? '0.88rem' : '0.94rem',
|
|
lineHeight: '1.55',
|
|
margin: '0 0 1.5rem 0',
|
|
fontWeight: 400,
|
|
maxWidth: '100%',
|
|
position: 'relative',
|
|
zIndex: 3,
|
|
}}>
|
|
{product.description}
|
|
</p>
|
|
|
|
{/* Dashboard Image Container */}
|
|
<div style={{
|
|
position: 'relative',
|
|
marginTop: 'auto',
|
|
width: '100%',
|
|
height: isMobile ? '220px' : '310px',
|
|
borderRadius: '14px 14px 0 0',
|
|
overflow: 'hidden',
|
|
zIndex: 2,
|
|
boxShadow: '0 -4px 20px rgba(0, 0, 0, 0.06)'
|
|
}}>
|
|
<img
|
|
src={assetUrl(product.image)}
|
|
alt={`${product.name} dashboard`}
|
|
style={{
|
|
width: '100%',
|
|
height: '100%',
|
|
objectFit: 'cover',
|
|
objectPosition: 'top center',
|
|
display: 'block'
|
|
}}
|
|
/>
|
|
|
|
{/* Floating Stat Badges */}
|
|
{product.stats?.map((stat, sIdx) => {
|
|
const pos = currentPos[sIdx] || {};
|
|
return (
|
|
<div
|
|
key={sIdx}
|
|
style={{
|
|
position: 'absolute',
|
|
...pos,
|
|
background: pos.bg || 'rgba(30, 30, 35, 0.65)',
|
|
backdropFilter: 'blur(12px)',
|
|
WebkitBackdropFilter: 'blur(12px)',
|
|
border: '1px solid rgba(255, 255, 255, 0.2)',
|
|
padding: '0.5rem 0.85rem',
|
|
borderRadius: '10px',
|
|
boxShadow: '0 6px 20px rgba(0, 0, 0, 0.15)',
|
|
zIndex: 5,
|
|
whiteSpace: 'nowrap',
|
|
maxWidth: 'none'
|
|
}}
|
|
>
|
|
<span style={{ fontWeight: 700, color: pos.color || '#ffffff', fontSize: '1.1rem', display: 'block', lineHeight: 1.1 }}>
|
|
{stat.value}
|
|
</span>
|
|
<span style={{ fontSize: '0.7rem', color: pos.color || '#ffffff', opacity: 0.9, fontWeight: 500, whiteSpace: 'nowrap', display: 'block' }}>
|
|
{stat.label}
|
|
</span>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
</motion.div>
|
|
);
|
|
}
|