CookieBanner.tsx 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import { useState, useEffect } from 'react';
  2. import { Link } from 'react-router-dom';
  3. import { Button } from '@/components/ui/button';
  4. import { Card } from '@/components/ui/card';
  5. import { X } from 'lucide-react';
  6. const COOKIE_CONSENT_KEY = 'cookie-consent';
  7. const getStorageItem = (key: string): string | null => {
  8. try {
  9. return localStorage.getItem(key);
  10. } catch {
  11. return null;
  12. }
  13. };
  14. const setStorageItem = (key: string, value: string): boolean => {
  15. try {
  16. localStorage.setItem(key, value);
  17. return true;
  18. } catch {
  19. return false;
  20. }
  21. };
  22. export function CookieBanner() {
  23. const [isVisible, setIsVisible] = useState(false);
  24. useEffect(() => {
  25. const consent = getStorageItem(COOKIE_CONSENT_KEY);
  26. if (!consent) {
  27. setIsVisible(true);
  28. }
  29. }, []);
  30. const handleAccept = () => {
  31. setStorageItem(COOKIE_CONSENT_KEY, 'accepted');
  32. setIsVisible(false);
  33. };
  34. const handleDecline = () => {
  35. setStorageItem(COOKIE_CONSENT_KEY, 'declined');
  36. setIsVisible(false);
  37. };
  38. if (!isVisible) return null;
  39. return (
  40. <div className="fixed bottom-0 left-0 right-0 z-50 p-4 animate-in slide-in-from-bottom-5">
  41. <Card className="max-w-4xl mx-auto p-6 shadow-lg border-border bg-card">
  42. <div className="flex items-start gap-4">
  43. <div className="flex-1">
  44. <h3 className="text-lg font-semibold text-foreground mb-2">
  45. 🍪 Gestion des cookies
  46. </h3>
  47. <p className="text-sm text-muted-foreground mb-4">
  48. Nous utilisons des cookies essentiels pour assurer le fonctionnement de l'authentification
  49. et mémoriser vos préférences d'interface. Aucun cookie de suivi ou publicitaire n'est utilisé.
  50. </p>
  51. <Link
  52. to="/politique-cookies"
  53. className="text-sm text-primary hover:underline"
  54. >
  55. En savoir plus sur notre politique de cookies
  56. </Link>
  57. </div>
  58. <Button
  59. variant="ghost"
  60. size="icon"
  61. onClick={handleDecline}
  62. className="shrink-0"
  63. >
  64. <X className="h-4 w-4" />
  65. </Button>
  66. </div>
  67. <div className="flex gap-3 mt-4">
  68. <Button onClick={handleAccept} className="flex-1 sm:flex-none">
  69. Accepter
  70. </Button>
  71. <Button onClick={handleDecline} variant="outline" className="flex-1 sm:flex-none">
  72. Refuser
  73. </Button>
  74. </div>
  75. </Card>
  76. </div>
  77. );
  78. }