diff --git a/components/ui/FormationCard.tsx b/components/ui/FormationCard.tsx new file mode 100644 index 0000000..3995f9c --- /dev/null +++ b/components/ui/FormationCard.tsx @@ -0,0 +1,116 @@ +import Link from "next/link" +import { Button } from "@/components/ui/button" +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" +import { Clock, Users, LucideIcon } from "lucide-react" + +interface FormationCardProps { + icon: LucideIcon + title: string + description: string + program: string[] + specialization: { + title: string + items: string[] + } + duration: string + maxParticipants: string + color: 'red' | 'green' | 'blue' + href?: string +} + +export default function FormationCard({ + icon: Icon, + title, + description, + program, + specialization, + duration, + maxParticipants, + color, + href = "/formation/devis" +}: FormationCardProps) { + const getColorClasses = () => { + switch (color) { + case 'red': + return { + card: "border-2 border-gray-700 hover:border-red-600 bg-gray-800 hover:shadow-xl transition-all duration-300", + icon: "h-16 w-16 text-red-400 mx-auto mb-4", + title: "text-2xl text-red-300", + specialization: "bg-red-900", + specializationTitle: "font-semibold text-red-200 mb-2", + specializationItems: "text-sm text-red-300 space-y-1", + button: "w-full bg-red-600 hover:bg-red-700 text-white" + } + case 'green': + return { + card: "border-2 border-gray-700 hover:border-green-600 bg-gray-800 hover:shadow-xl transition-all duration-300", + icon: "h-16 w-16 text-green-400 mx-auto mb-4", + title: "text-2xl text-green-300", + specialization: "bg-green-900", + specializationTitle: "font-semibold text-green-200 mb-2", + specializationItems: "text-sm text-green-300 space-y-1", + button: "w-full bg-green-600 hover:bg-green-700 text-white" + } + case 'blue': + return { + card: "border-2 border-gray-700 hover:border-blue-600 bg-gray-800 hover:shadow-xl transition-all duration-300", + icon: "h-16 w-16 text-blue-400 mx-auto mb-4", + title: "text-2xl text-blue-300", + specialization: "bg-blue-900", + specializationTitle: "font-semibold text-blue-200 mb-2", + specializationItems: "text-sm text-blue-300 space-y-1", + button: "w-full bg-blue-600 hover:bg-blue-700 text-white" + } + } + } + + const colorClasses = getColorClasses() + + return ( + + + + {title} + + {description} + + + + + Programme de formation : + + {program.map((item, index) => ( + • {item} + ))} + + + + + {specialization.title} + + {specialization.items.map((item, index) => ( + • {item} + ))} + + + + + + + {duration} + + + + {maxParticipants} + + + + + + S'inscrire à la formation + + + + + ) +} diff --git a/components/ui/PricingCard.tsx b/components/ui/PricingCard.tsx new file mode 100644 index 0000000..747ff96 --- /dev/null +++ b/components/ui/PricingCard.tsx @@ -0,0 +1,129 @@ +import Link from "next/link" +import { Button } from "@/components/ui/button" +import { Badge } from "@/components/ui/badge" +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" +import { CheckCircle, Database, Zap, Users, LucideIcon } from "lucide-react" + +interface TokenBreakdown { + icon: LucideIcon + title: string + value: string + description: string + color: 'blue' | 'green' | 'purple' +} + +interface PricingFeature { + text: string +} + +interface PricingCardProps { + title: string + price: string + tokensIncluded: string + tokenBreakdown: TokenBreakdown[] + features: PricingFeature[] + ctaText: string + ctaHref: string + variant?: 'default' | 'featured' +} + +export default function PricingCard({ + title, + price, + tokensIncluded, + tokenBreakdown, + features, + ctaText, + ctaHref, + variant = 'default' +}: PricingCardProps) { + const getColorClasses = (color: 'blue' | 'green' | 'purple') => { + switch (color) { + case 'blue': + return { + bg: "bg-blue-50 dark:bg-blue-800", + icon: "text-blue-600 dark:text-blue-300", + title: "text-blue-800 dark:text-blue-200", + value: "text-blue-600 dark:text-blue-300", + description: "text-blue-700 dark:text-blue-200" + } + case 'green': + return { + bg: "bg-green-50 dark:bg-green-800", + icon: "text-green-600 dark:text-green-300", + title: "text-green-800 dark:text-green-200", + value: "text-green-600 dark:text-green-300", + description: "text-green-700 dark:text-green-200" + } + case 'purple': + return { + bg: "bg-purple-50 dark:bg-purple-800", + icon: "text-purple-600 dark:text-purple-300", + title: "text-purple-800 dark:text-purple-200", + value: "text-purple-600 dark:text-purple-300", + description: "text-purple-700 dark:text-purple-200" + } + } + } + + return ( + + + + {title} + + + {price} + + + {tokensIncluded} + + + + + {/* Token Breakdown */} + + + 🎯 Que comprennent {tokensIncluded} ? + + + {tokenBreakdown.map((item, index) => { + const colorClasses = getColorClasses(item.color) + const Icon = item.icon + return ( + + + {item.title} + {item.value} + {item.description} + + ) + })} + + + + {/* Features */} + + {features.map((feature, index) => ( + + + {feature.text} + + ))} + + + {/* CTA */} + + + Tarification à la consommation + setup personnalisé + + + + {ctaText} + + + + + + ) +} diff --git a/components/ui/ProductCard.tsx b/components/ui/ProductCard.tsx new file mode 100644 index 0000000..1277dee --- /dev/null +++ b/components/ui/ProductCard.tsx @@ -0,0 +1,41 @@ +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" +import { LucideIcon } from "lucide-react" + +interface ProductCardProps { + icon: LucideIcon + title: string + description: string[] + variant?: 'default' | 'gradient' +} + +export default function ProductCard({ + icon: Icon, + title, + description, + variant = 'default' +}: ProductCardProps) { + const getCardStyles = () => { + switch (variant) { + case 'gradient': + return "border-2 border-gray-200 dark:border-gray-700 hover:border-blue-200 dark:hover:border-blue-400 transition-colors duration-300 bg-gradient-to-br from-white to-blue-50 dark:from-gray-800 dark:to-blue-900" + default: + return "border-2 border-gray-200 dark:border-gray-700 hover:border-blue-200 dark:hover:border-blue-400 transition-colors duration-300" + } + } + + return ( + + + + {title} + + + {description.map((text, index) => ( + + {text} + + ))} + + + ) +}
{item.value}
{item.description}
+ Tarification à la consommation + setup personnalisé +
+ {text} +