feat: enhance BackgroundImageSelector with new gradients and custom URL input

- Added new gradient options for background selection, including sunset, ocean, forest, and galaxy themes.
- Updated existing gradient descriptions and previews for clarity.
- Improved custom URL input with enhanced styling and performance tips for better user guidance.
- Reset advanced options when the background image changes to streamline user experience.
This commit is contained in:
Julien Froidefond
2025-10-01 22:54:06 +02:00
parent ead02e0aaa
commit 7e79dbe49c

View File

@@ -1,8 +1,7 @@
'use client';
import { useState } from 'react';
import { useState, useEffect } from 'react';
import { Button } from '@/components/ui/Button';
import { Input } from '@/components/ui/Input';
import { Card, CardContent } from '@/components/ui/Card';
import { useUserPreferences } from '@/contexts/UserPreferencesContext';
@@ -23,41 +22,66 @@ const PRESET_BACKGROUNDS = [
{
id: 'theme-primary',
name: 'Dégradé primaire',
description: 'Dégradé avec la couleur primaire du thème',
preview: 'linear-gradient(135deg, var(--background) 0%, color-mix(in srgb, var(--primary) 20%, var(--background)) 100%)'
description: 'Dégradé marqué avec la couleur primaire',
preview: 'linear-gradient(135deg, var(--background) 0%, color-mix(in srgb, var(--primary) 60%, var(--background)) 100%)'
},
{
id: 'theme-accent',
name: 'Dégradé accent',
description: 'Dégradé avec la couleur d\'accent du thème',
preview: 'linear-gradient(135deg, var(--background) 0%, color-mix(in srgb, var(--accent) 20%, var(--background)) 100%)'
description: 'Dégradé marqué avec la couleur d\'accent',
preview: 'linear-gradient(135deg, var(--background) 0%, color-mix(in srgb, var(--accent) 60%, var(--background)) 100%)'
},
{
id: 'theme-success',
name: 'Dégradé succès',
description: 'Dégradé avec la couleur de succès du thème',
preview: 'linear-gradient(135deg, var(--background) 0%, color-mix(in srgb, var(--success) 20%, var(--background)) 100%)'
description: 'Dégradé marqué avec la couleur de succès',
preview: 'linear-gradient(135deg, var(--background) 0%, color-mix(in srgb, var(--success) 60%, var(--background)) 100%)'
},
{
id: 'theme-purple',
name: 'Dégradé violet',
description: 'Dégradé avec la couleur violette du thème',
preview: 'linear-gradient(135deg, var(--background) 0%, color-mix(in srgb, var(--purple) 20%, var(--background)) 100%)'
description: 'Dégradé marqué avec la couleur violette',
preview: 'linear-gradient(135deg, var(--background) 0%, color-mix(in srgb, var(--purple) 60%, var(--background)) 100%)'
},
{
id: 'theme-diagonal',
name: 'Dégradé diagonal',
description: 'Dégradé diagonal avec plusieurs couleurs du thème',
preview: 'linear-gradient(45deg, var(--background) 0%, color-mix(in srgb, var(--primary) 15%, var(--background)) 50%, color-mix(in srgb, var(--accent) 15%, var(--background)) 100%)'
description: 'Dégradé diagonal avec plusieurs couleurs',
preview: 'linear-gradient(45deg, var(--background) 0%, color-mix(in srgb, var(--primary) 40%, var(--background)) 50%, color-mix(in srgb, var(--accent) 40%, var(--background)) 100%)'
},
{
id: 'theme-radial',
name: 'Dégradé radial',
description: 'Dégradé radial centré avec les couleurs du thème',
preview: 'radial-gradient(circle at center, var(--background) 0%, color-mix(in srgb, var(--primary) 25%, var(--background)) 100%)'
preview: 'radial-gradient(circle at center, var(--background) 0%, color-mix(in srgb, var(--primary) 50%, var(--background)) 100%)'
},
{
id: 'theme-sunset',
name: 'Dégradé coucher de soleil',
description: 'Dégradé orange-rouge intense',
preview: 'linear-gradient(135deg, color-mix(in srgb, var(--accent) 80%, var(--background)) 0%, color-mix(in srgb, var(--destructive) 60%, var(--background)) 100%)'
},
{
id: 'theme-ocean',
name: 'Dégradé océan',
description: 'Dégradé bleu profond',
preview: 'linear-gradient(135deg, color-mix(in srgb, var(--blue) 70%, var(--background)) 0%, color-mix(in srgb, var(--primary) 50%, var(--background)) 100%)'
},
{
id: 'theme-forest',
name: 'Dégradé forêt',
description: 'Dégradé vert naturel',
preview: 'linear-gradient(135deg, color-mix(in srgb, var(--green) 60%, var(--background)) 0%, color-mix(in srgb, var(--success) 40%, var(--background)) 100%)'
},
{
id: 'theme-galaxy',
name: 'Dégradé galaxie',
description: 'Dégradé violet-bleu mystique',
preview: 'linear-gradient(135deg, color-mix(in srgb, var(--purple) 70%, var(--background)) 0%, color-mix(in srgb, var(--blue) 50%, var(--background)) 100%)'
}
];
export function BackgroundImageSelector() {
const { preferences, updateViewPreferences } = useUserPreferences();
const [customUrl, setCustomUrl] = useState('');
@@ -81,6 +105,7 @@ export function BackgroundImageSelector() {
setShowCustomInput(false);
};
const handleRemoveCustom = () => {
updateViewPreferences({ backgroundImage: undefined });
};
@@ -93,6 +118,11 @@ export function BackgroundImageSelector() {
updateViewPreferences({ backgroundOpacity: opacity });
};
// Réinitialiser les options avancées quand l'image change
useEffect(() => {
setShowAdvancedOptions(false);
}, [currentBackground]);
return (
<div className="space-y-6">
<div className="flex items-center justify-between">
@@ -121,7 +151,7 @@ export function BackgroundImageSelector() {
className="w-full h-24 rounded-lg border border-[var(--border)]/30 overflow-hidden"
style={{
backgroundImage: currentBackground && !PRESET_BACKGROUNDS.find(p => p.id === currentBackground)
? `url(${currentBackground})`
? `url("${currentBackground}")`
: PRESET_BACKGROUNDS.find(p => p.id === currentBackground)?.preview || 'var(--background)',
backgroundSize: 'cover',
backgroundPosition: 'center',
@@ -170,6 +200,7 @@ export function BackgroundImageSelector() {
</CardContent>
</Card>
{/* URL personnalisée */}
<Card>
<CardContent className="p-4">
@@ -193,12 +224,14 @@ export function BackgroundImageSelector() {
{showCustomInput && (
<div className="space-y-3">
<div className="flex gap-2">
<Input
<input
type="url"
placeholder="https://example.com/image.jpg"
value={customUrl}
onChange={(e) => setCustomUrl(e.target.value)}
className="flex-1"
className="flex-1 h-10 px-3 py-2 text-sm border border-[var(--border)]/50 bg-[var(--input)] text-[var(--foreground)] placeholder:text-[var(--muted-foreground)] focus:border-[var(--primary)]/70 focus:ring-1 focus:ring-[var(--primary)]/20 rounded-md focus-visible:outline-none transition-colors"
autoComplete="off"
spellCheck="false"
/>
<Button
onClick={handleCustomUrlSubmit}
@@ -208,9 +241,14 @@ export function BackgroundImageSelector() {
Appliquer
</Button>
</div>
<p className="text-xs text-[var(--muted-foreground)]">
Entrez l&apos;URL d&apos;une image (JPG, PNG, GIF, WebP)
</p>
<div className="p-3 bg-[var(--card)] border border-[var(--border)] rounded-lg">
<div className="flex items-start gap-2">
<div className="text-[var(--accent)] text-sm mt-0.5">💡</div>
<div className="text-xs text-[var(--muted-foreground)]">
<strong className="text-[var(--foreground)]">Conseil performance :</strong> Utilisez des images optimisées (&lt; 500KB) et hébergées sur un CDN pour de meilleures performances. Les formats WebP et AVIF sont recommandés.
</div>
</div>
</div>
</div>
)}
@@ -228,8 +266,8 @@ export function BackgroundImageSelector() {
</CardContent>
</Card>
{/* Options avancées */}
{currentBackground && (
{/* Options avancées - seulement pour les URLs personnalisées */}
{currentBackground && !PRESET_BACKGROUNDS.find(p => p.id === currentBackground) && (
<Card>
<CardContent className="p-4">
<div className="space-y-4">
@@ -237,7 +275,7 @@ export function BackgroundImageSelector() {
<div>
<h4 className="text-sm font-medium text-[var(--foreground)]">Options avancées</h4>
<p className="text-xs text-[var(--muted-foreground)] mt-1">
Personnalisez l&apos;effet de l&apos;image de fond
Ajustez l&apos;effet de votre image personnalisée
</p>
</div>
<Button
@@ -326,24 +364,6 @@ export function BackgroundImageSelector() {
</CardContent>
</Card>
)}
{/* Note sur les performances */}
<Card>
<CardContent className="p-4">
<div className="flex items-start gap-3">
<div className="text-lg">💡</div>
<div>
<p className="text-sm text-[var(--warning)] font-medium mb-1">
Conseil pour les performances
</p>
<p className="text-xs text-[var(--muted-foreground)]">
Utilisez des images optimisées pour de meilleures performances.
Les images trop lourdes peuvent ralentir l&apos;interface.
</p>
</div>
</div>
</CardContent>
</Card>
</div>
);
}