Sacha VAUDEY 81e63e5a8d
Some checks failed
Build and Test / Classic Build (pull_request) Failing after 40s
Build and Test / Docker Build (pull_request) Has been skipped
fix service cards icons
2025-09-14 15:01:25 +02:00

150 lines
7.1 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useEffect } from 'react';
import Image from 'next/image';
import { URLS } from '@/lib/config/constants';
import { FeatureBadge, FeatureItem, SectionTitle } from './PopupComponents';
import { cn, commonClasses } from '@/lib/utils';
import type { Service } from '@/types/service';
import type { Translation } from '@/types/i18n';
import { ClipboardList, Zap, Check, Lock, Rocket } from 'lucide-react';
interface PopupProps {
service: Service;
onClose: () => void;
translations: Translation['common'];
}
export const Popup: React.FC<PopupProps> = ({ service, onClose, translations }) => {
// Empêcher le scroll du body quand la popup est ouverte
useEffect(() => {
const originalStyle = document.body.style.overflow;
document.body.style.overflow = 'hidden';
return () => {
document.body.style.overflow = originalStyle || 'unset';
};
}, []);
return (
<div className="fixed inset-0 bg-black/60 flex justify-center items-center z-50 p-4 backdrop-blur-md animate-fadeIn">
<div className="bg-white text-gray-800 rounded-3xl max-w-4xl w-full max-h-[90vh] shadow-2xl relative animate-slideUp border border-gray-200 overflow-hidden">
{/* Bouton de fermeture fixe au-dessus du contenu */}
<div className="absolute top-4 right-4 z-50">
<button
onClick={onClose}
className={cn(
'bg-white/90 hover:bg-white border border-gray-300',
'text-xl cursor-pointer text-gray-700',
'flex items-center justify-center w-10 h-10 sm:w-12 sm:h-12 rounded-full',
commonClasses.transition,
commonClasses.hoverScale,
'shadow-lg backdrop-blur-sm'
)}
aria-label={translations.close}
>
×
</button>
</div>
{/* Contenu avec scroll vertical uniquement */}
<div className="overflow-y-auto overflow-x-hidden max-h-[90vh] popup-content">
{/* Header */}
<div className="relative bg-gradient-to-r from-blue-600 to-blue-500 p-6 sm:p-8 text-white pr-16 sm:pr-20">
<div className="flex flex-col lg:flex-row items-center lg:items-start mb-4">
<div className="w-16 h-16 sm:w-20 sm:h-20 lg:w-24 lg:h-24 bg-white/20 rounded-3xl flex items-center justify-center mb-4 lg:mb-0 lg:mr-8 backdrop-blur-sm">
{service.iconType === 'image' ? (
<Image
src={service.image as string}
alt={service.name}
width={48}
height={48}
className="w-12 h-12 sm:w-14 sm:h-14 lg:w-16 lg:h-16 object-contain"
/>
) : service.lucideIcon ? (
<service.lucideIcon className="w-12 h-12 sm:w-14 sm:h-14 lg:w-16 lg:h-16 text-white" strokeWidth={1.5} />
) : (
<span className="text-3xl sm:text-4xl lg:text-5xl">{service.icon}</span>
)}
</div>
<div className="text-center lg:text-left flex-1">
<h2 className="font-heading text-2xl sm:text-3xl lg:text-4xl mt-0 mb-3 lg:mb-4 leading-tight font-bold text-white">
{service.name}
</h2>
<div className="text-white/90 text-base sm:text-lg lg:text-xl font-medium">
Service d&apos;hébergement professionnel
</div>
<div className="mt-4 lg:mt-6 flex flex-wrap gap-2 justify-center lg:justify-start">
<span className="bg-white/20 text-white px-3 py-1 rounded-full text-sm font-medium backdrop-blur-sm">Haute disponibilité</span>
<span className="bg-white/20 text-white px-3 py-1 rounded-full text-sm font-medium backdrop-blur-sm">Open Source</span>
<span className="bg-white/20 text-white px-3 py-1 rounded-full text-sm font-medium backdrop-blur-sm">Communautaire</span>
</div>
</div>
</div>
</div>
{/* Content - Forcer le fond blanc */}
<div className="p-6 sm:p-8 bg-white">
{/* Description */}
<SectionTitle icon={ClipboardList} title="Description détaillée" />
<div className="bg-gradient-to-br from-blue-50 to-blue-100/50 rounded-2xl p-4 lg:p-6 border border-blue-200 mb-8">
<p className="text-gray-700 leading-relaxed text-base sm:text-lg lg:text-xl mb-4">
{service.description}
</p>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 mt-6">
<FeatureBadge
icon={Check}
title="99.9% Uptime"
subtitle="Disponibilité garantie"
/>
<FeatureBadge
icon={Lock}
title="Sécurisé"
subtitle="SSL & Backups"
/>
</div>
</div>
{/* Fonctionnalités */}
<SectionTitle icon={Zap} title={translations.discoverFeatures} />
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 mb-8">
{service.features.map((feature, index) => (
<FeatureItem key={index} feature={feature} index={index} />
))}
</div>
{/* Call to action */}
<div className="pt-6 lg:pt-8 border-t border-gray-200">
<a
href={service.url}
target="_blank"
rel="noopener noreferrer"
className={cn(
'w-full inline-flex items-center justify-center',
'bg-gradient-to-r from-blue-600 to-blue-500 text-white',
'border-0 py-4 px-6 sm:px-8 rounded-2xl cursor-pointer no-underline',
'font-bold tracking-wide shadow-lg',
commonClasses.transition,
commonClasses.hoverScale,
'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-500',
'text-base lg:text-lg'
)}
>
<Rocket className="w-6 h-6 lg:w-7 lg:h-7 mr-3" strokeWidth={2} />
<span>Accéder à {service.name}</span>
</a>
<p className="text-center text-sm text-gray-500 mt-4">
Besoin d&apos;aide ? Rejoignez notre <a href={URLS.social.discord} className={cn('text-blue-600 hover:text-blue-700 font-medium', commonClasses.transition)}>Discord</a> pour obtenir du support
</p>
</div>
</div>
</div>
{/* Decorative elements */}
<div className="absolute top-0 right-0 w-16 h-16 sm:w-24 sm:h-24 lg:w-32 lg:h-32 bg-blue-100/30 rounded-full -translate-y-8 translate-x-8 sm:-translate-y-12 sm:translate-x-12 lg:-translate-y-16 lg:translate-x-16 hidden sm:block pointer-events-none"></div>
<div className="absolute bottom-0 left-0 w-12 h-12 sm:w-16 sm:h-16 lg:w-24 lg:h-24 bg-blue-50 rounded-full translate-y-6 -translate-x-6 sm:translate-y-8 sm:-translate-x-8 lg:translate-y-12 lg:-translate-x-12 hidden sm:block pointer-events-none"></div>
</div>
</div>
);
};