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:
@@ -1,8 +1,7 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useState } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { Button } from '@/components/ui/Button';
|
import { Button } from '@/components/ui/Button';
|
||||||
import { Input } from '@/components/ui/Input';
|
|
||||||
import { Card, CardContent } from '@/components/ui/Card';
|
import { Card, CardContent } from '@/components/ui/Card';
|
||||||
import { useUserPreferences } from '@/contexts/UserPreferencesContext';
|
import { useUserPreferences } from '@/contexts/UserPreferencesContext';
|
||||||
|
|
||||||
@@ -23,41 +22,66 @@ const PRESET_BACKGROUNDS = [
|
|||||||
{
|
{
|
||||||
id: 'theme-primary',
|
id: 'theme-primary',
|
||||||
name: 'Dégradé primaire',
|
name: 'Dégradé primaire',
|
||||||
description: 'Dégradé avec la couleur primaire du thème',
|
description: 'Dégradé marqué avec la couleur primaire',
|
||||||
preview: 'linear-gradient(135deg, var(--background) 0%, color-mix(in srgb, var(--primary) 20%, var(--background)) 100%)'
|
preview: 'linear-gradient(135deg, var(--background) 0%, color-mix(in srgb, var(--primary) 60%, var(--background)) 100%)'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'theme-accent',
|
id: 'theme-accent',
|
||||||
name: 'Dégradé accent',
|
name: 'Dégradé accent',
|
||||||
description: 'Dégradé avec la couleur d\'accent du thème',
|
description: 'Dégradé marqué avec la couleur d\'accent',
|
||||||
preview: 'linear-gradient(135deg, var(--background) 0%, color-mix(in srgb, var(--accent) 20%, var(--background)) 100%)'
|
preview: 'linear-gradient(135deg, var(--background) 0%, color-mix(in srgb, var(--accent) 60%, var(--background)) 100%)'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'theme-success',
|
id: 'theme-success',
|
||||||
name: 'Dégradé succès',
|
name: 'Dégradé succès',
|
||||||
description: 'Dégradé avec la couleur de succès du thème',
|
description: 'Dégradé marqué avec la couleur de succès',
|
||||||
preview: 'linear-gradient(135deg, var(--background) 0%, color-mix(in srgb, var(--success) 20%, var(--background)) 100%)'
|
preview: 'linear-gradient(135deg, var(--background) 0%, color-mix(in srgb, var(--success) 60%, var(--background)) 100%)'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'theme-purple',
|
id: 'theme-purple',
|
||||||
name: 'Dégradé violet',
|
name: 'Dégradé violet',
|
||||||
description: 'Dégradé avec la couleur violette du thème',
|
description: 'Dégradé marqué avec la couleur violette',
|
||||||
preview: 'linear-gradient(135deg, var(--background) 0%, color-mix(in srgb, var(--purple) 20%, var(--background)) 100%)'
|
preview: 'linear-gradient(135deg, var(--background) 0%, color-mix(in srgb, var(--purple) 60%, var(--background)) 100%)'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'theme-diagonal',
|
id: 'theme-diagonal',
|
||||||
name: 'Dégradé diagonal',
|
name: 'Dégradé diagonal',
|
||||||
description: 'Dégradé diagonal avec plusieurs couleurs du thème',
|
description: 'Dégradé diagonal avec plusieurs couleurs',
|
||||||
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%)'
|
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',
|
id: 'theme-radial',
|
||||||
name: 'Dégradé radial',
|
name: 'Dégradé radial',
|
||||||
description: 'Dégradé radial centré avec les couleurs du thème',
|
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() {
|
export function BackgroundImageSelector() {
|
||||||
const { preferences, updateViewPreferences } = useUserPreferences();
|
const { preferences, updateViewPreferences } = useUserPreferences();
|
||||||
const [customUrl, setCustomUrl] = useState('');
|
const [customUrl, setCustomUrl] = useState('');
|
||||||
@@ -81,6 +105,7 @@ export function BackgroundImageSelector() {
|
|||||||
setShowCustomInput(false);
|
setShowCustomInput(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const handleRemoveCustom = () => {
|
const handleRemoveCustom = () => {
|
||||||
updateViewPreferences({ backgroundImage: undefined });
|
updateViewPreferences({ backgroundImage: undefined });
|
||||||
};
|
};
|
||||||
@@ -93,6 +118,11 @@ export function BackgroundImageSelector() {
|
|||||||
updateViewPreferences({ backgroundOpacity: opacity });
|
updateViewPreferences({ backgroundOpacity: opacity });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Réinitialiser les options avancées quand l'image change
|
||||||
|
useEffect(() => {
|
||||||
|
setShowAdvancedOptions(false);
|
||||||
|
}, [currentBackground]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<div className="flex items-center justify-between">
|
<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"
|
className="w-full h-24 rounded-lg border border-[var(--border)]/30 overflow-hidden"
|
||||||
style={{
|
style={{
|
||||||
backgroundImage: currentBackground && !PRESET_BACKGROUNDS.find(p => p.id === currentBackground)
|
backgroundImage: currentBackground && !PRESET_BACKGROUNDS.find(p => p.id === currentBackground)
|
||||||
? `url(${currentBackground})`
|
? `url("${currentBackground}")`
|
||||||
: PRESET_BACKGROUNDS.find(p => p.id === currentBackground)?.preview || 'var(--background)',
|
: PRESET_BACKGROUNDS.find(p => p.id === currentBackground)?.preview || 'var(--background)',
|
||||||
backgroundSize: 'cover',
|
backgroundSize: 'cover',
|
||||||
backgroundPosition: 'center',
|
backgroundPosition: 'center',
|
||||||
@@ -170,6 +200,7 @@ export function BackgroundImageSelector() {
|
|||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
|
|
||||||
{/* URL personnalisée */}
|
{/* URL personnalisée */}
|
||||||
<Card>
|
<Card>
|
||||||
<CardContent className="p-4">
|
<CardContent className="p-4">
|
||||||
@@ -193,12 +224,14 @@ export function BackgroundImageSelector() {
|
|||||||
{showCustomInput && (
|
{showCustomInput && (
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<Input
|
<input
|
||||||
type="url"
|
type="url"
|
||||||
placeholder="https://example.com/image.jpg"
|
placeholder="https://example.com/image.jpg"
|
||||||
value={customUrl}
|
value={customUrl}
|
||||||
onChange={(e) => setCustomUrl(e.target.value)}
|
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
|
<Button
|
||||||
onClick={handleCustomUrlSubmit}
|
onClick={handleCustomUrlSubmit}
|
||||||
@@ -208,9 +241,14 @@ export function BackgroundImageSelector() {
|
|||||||
Appliquer
|
Appliquer
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-xs text-[var(--muted-foreground)]">
|
<div className="p-3 bg-[var(--card)] border border-[var(--border)] rounded-lg">
|
||||||
Entrez l'URL d'une image (JPG, PNG, GIF, WebP)
|
<div className="flex items-start gap-2">
|
||||||
</p>
|
<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 (< 500KB) et hébergées sur un CDN pour de meilleures performances. Les formats WebP et AVIF sont recommandés.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -228,8 +266,8 @@ export function BackgroundImageSelector() {
|
|||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
{/* Options avancées */}
|
{/* Options avancées - seulement pour les URLs personnalisées */}
|
||||||
{currentBackground && (
|
{currentBackground && !PRESET_BACKGROUNDS.find(p => p.id === currentBackground) && (
|
||||||
<Card>
|
<Card>
|
||||||
<CardContent className="p-4">
|
<CardContent className="p-4">
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
@@ -237,7 +275,7 @@ export function BackgroundImageSelector() {
|
|||||||
<div>
|
<div>
|
||||||
<h4 className="text-sm font-medium text-[var(--foreground)]">Options avancées</h4>
|
<h4 className="text-sm font-medium text-[var(--foreground)]">Options avancées</h4>
|
||||||
<p className="text-xs text-[var(--muted-foreground)] mt-1">
|
<p className="text-xs text-[var(--muted-foreground)] mt-1">
|
||||||
Personnalisez l'effet de l'image de fond
|
Ajustez l'effet de votre image personnalisée
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
@@ -326,24 +364,6 @@ export function BackgroundImageSelector() {
|
|||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</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'interface.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user