diff --git a/client/src/pages/admin-gallery.tsx b/client/src/pages/admin-gallery.tsx index 88772ca..462997a 100644 --- a/client/src/pages/admin-gallery.tsx +++ b/client/src/pages/admin-gallery.tsx @@ -32,6 +32,7 @@ function FocalPointEditor({ image, currentFocalPoint, currentArtist, + allArtistNames, onSaveFocal, onResetFocal, onSaveArtist, @@ -41,6 +42,7 @@ function FocalPointEditor({ image: CloudinaryImage; currentFocalPoint?: { x: number; y: number }; currentArtist: string; + allArtistNames: string[]; onSaveFocal: (x: number, y: number) => Promise; onResetFocal: () => Promise; onSaveArtist: (artist: string) => Promise; @@ -52,7 +54,15 @@ function FocalPointEditor({ const [saving, setSaving] = useState(false); const [showDeleteConfirm, setShowDeleteConfirm] = useState(false); const [deleting, setDeleting] = useState(false); + const [showSuggestions, setShowSuggestions] = useState(false); const imgRef = useRef(null); + const suggestionsRef = useRef(null); + + const filteredSuggestions = artistName.length >= 1 + ? allArtistNames.filter( + (name) => name.toLowerCase().includes(artistName.toLowerCase()) && name.toLowerCase() !== artistName.toLowerCase() + ).slice(0, 8) + : []; const handleClick = (e: React.MouseEvent) => { const img = imgRef.current; @@ -105,14 +115,39 @@ function FocalPointEditor({
- setArtistName(e.target.value)} - placeholder="Interpret / Künstlername eingeben..." - className="flex-1 bg-white/10 border border-white/20 rounded px-3 py-2 text-white text-sm placeholder:text-white/30 focus:outline-none focus:border-yellow-400/60" - data-testid="input-artist-name" - /> +
+ { setArtistName(e.target.value); setShowSuggestions(true); }} + onFocus={() => setShowSuggestions(true)} + onBlur={() => setTimeout(() => setShowSuggestions(false), 200)} + placeholder="Interpret / Künstlername eingeben..." + className="w-full bg-white/10 border border-white/20 rounded px-3 py-2 text-white text-sm placeholder:text-white/30 focus:outline-none focus:border-yellow-400/60" + data-testid="input-artist-name" + /> + {showSuggestions && filteredSuggestions.length > 0 && ( +
+ {filteredSuggestions.map((name) => ( + + ))} +
+ )} +

@@ -334,6 +369,8 @@ export default function AdminGalleryPage() { const withFocal = Object.keys(fp).length; const withoutArtist = (images || []).filter((img) => !img.artist).length; + const allArtistNames = [...new Set((images || []).map((img) => img.artist).filter(Boolean))].sort(); + return (

@@ -489,6 +526,7 @@ export default function AdminGalleryPage() { image={editingImage} currentFocalPoint={fp[editingImage.fileName]} currentArtist={editingImage.artist || ""} + allArtistNames={allArtistNames} onSaveFocal={handleSaveFocalPoint} onResetFocal={handleResetFocalPoint} onSaveArtist={handleSaveArtist} diff --git a/server/gallery-artist-overrides.json b/server/gallery-artist-overrides.json index 0967ef4..ec403ef 100644 --- a/server/gallery-artist-overrides.json +++ b/server/gallery-artist-overrides.json @@ -1 +1,4 @@ -{} +{ + "DSC06296.jpg": "Simon Wild", + "DSC06416.jpg": "Simon Wild" +} \ No newline at end of file diff --git a/server/gallery-focal-points.json b/server/gallery-focal-points.json index acf0281..3506505 100644 --- a/server/gallery-focal-points.json +++ b/server/gallery-focal-points.json @@ -1,7 +1,7 @@ { "DSC07135.jpg": { - "x": 50, - "y": 30 + "x": 42, + "y": 29 }, "Arina 1.jpg": { "x": 70, @@ -18,5 +18,29 @@ "Aufw rts 1 1 .jpg": { "x": 18, "y": 43 + }, + "Christa Fartek 2.jpg": { + "x": 39, + "y": 60 + }, + "D Oimhittn Musi 2.jpg": { + "x": 43, + "y": 50 + }, + "DSC06296.jpg": { + "x": 50, + "y": 38 + }, + "DSC06416.jpg": { + "x": 46, + "y": 45 + }, + "DSC07594.jpg": { + "x": 46, + "y": 41 + }, + "DSC07438.jpg": { + "x": 57, + "y": 46 } } \ No newline at end of file