diff --git a/frontend/src/App.css b/frontend/src/App.css index ad167e3..0588f74 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -1863,3 +1863,49 @@ html { color: var(--text-muted); } +/* Autocomplete Input Styles */ +.autocomplete-wrapper { + position: relative; + width: 100%; +} + +.autocomplete-wrapper input { + width: 100%; + position: relative; + z-index: 2; + background: transparent; +} + +.autocomplete-suggestion { + position: absolute; + top: 0; + left: 0; + right: 0; + pointer-events: none; + border-radius: 10px; + border: 1px solid transparent; + padding: 0.55rem 0.75rem; + font-size: 0.9rem; + min-height: 44px; + display: flex; + align-items: center; + color: var(--text-muted); + z-index: 1; +} + +@media (min-width: 768px) { + .autocomplete-suggestion { + padding: 0.4rem 0.65rem; + min-height: auto; + } +} + +.autocomplete-typed { + opacity: 0; +} + +.autocomplete-rest { + color: var(--text-muted); + opacity: 0.5; +} + diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index c140a67..c780abf 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -580,6 +580,7 @@ function App() { onSubmit={handleFormSubmit} editingRecipe={editingRecipe} currentUser={user} + allRecipes={recipes} /> )} diff --git a/frontend/src/components/AutocompleteInput.jsx b/frontend/src/components/AutocompleteInput.jsx new file mode 100644 index 0000000..eeb572d --- /dev/null +++ b/frontend/src/components/AutocompleteInput.jsx @@ -0,0 +1,49 @@ +import { useState, useEffect, useRef } from "react"; + +function AutocompleteInput({ value, onChange, onKeyDown, suggestions = [], placeholder, inputRef, ...props }) { + const [suggestion, setSuggestion] = useState(""); + const localRef = useRef(null); + const ref = inputRef || localRef; + + useEffect(() => { + if (value && suggestions.length > 0) { + const match = suggestions.find(s => + s.toLowerCase().startsWith(value.toLowerCase()) && s.toLowerCase() !== value.toLowerCase() + ); + setSuggestion(match || ""); + } else { + setSuggestion(""); + } + }, [value, suggestions]); + + const handleKeyDown = (e) => { + if (e.key === 'Tab' && suggestion) { + e.preventDefault(); + onChange({ target: { value: suggestion } }); + setSuggestion(""); + } else if (onKeyDown) { + onKeyDown(e); + } + }; + + return ( +
+ + {suggestion && ( +
+ {value} + {suggestion.slice(value.length)} +
+ )} +
+ ); +} + +export default AutocompleteInput; diff --git a/frontend/src/components/RecipeFormDrawer.jsx b/frontend/src/components/RecipeFormDrawer.jsx index 45a5d35..39261bc 100644 --- a/frontend/src/components/RecipeFormDrawer.jsx +++ b/frontend/src/components/RecipeFormDrawer.jsx @@ -1,6 +1,7 @@ import { useEffect, useState, useRef } from "react"; +import AutocompleteInput from "./AutocompleteInput"; -function RecipeFormDrawer({ open, onClose, onSubmit, editingRecipe = null, currentUser = null }) { +function RecipeFormDrawer({ open, onClose, onSubmit, editingRecipe = null, currentUser = null, allRecipes = [] }) { const [name, setName] = useState(""); const [mealType, setMealType] = useState("lunch"); const [timeMinutes, setTimeMinutes] = useState(15); @@ -10,6 +11,16 @@ function RecipeFormDrawer({ open, onClose, onSubmit, editingRecipe = null, curre const [ingredients, setIngredients] = useState([""]); const [steps, setSteps] = useState([""]); + + // Extract unique made_by values for autocomplete + const uniqueMadeBy = Array.from( + new Set(allRecipes.map(r => r.made_by).filter(Boolean)) + ).sort(); + + // Extract unique ingredients for autocomplete + const uniqueIngredients = Array.from( + new Set(allRecipes.flatMap(r => r.ingredients || []).filter(Boolean)) + ).sort(); const lastIngredientRef = useRef(null); const lastStepRef = useRef(null); @@ -162,9 +173,10 @@ function RecipeFormDrawer({ open, onClose, onSubmit, editingRecipe = null, curre
- setMadeBy(e.target.value)} + suggestions={uniqueMadeBy} placeholder="שם האדם שיצר את הגרסה הזו..." />
@@ -212,8 +224,8 @@ function RecipeFormDrawer({ open, onClose, onSubmit, editingRecipe = null, curre
{ingredients.map((val, idx) => (
- handleChangeIngredient(idx, e.target.value)} onKeyDown={(e) => { @@ -222,6 +234,7 @@ function RecipeFormDrawer({ open, onClose, onSubmit, editingRecipe = null, curre handleAddIngredient(); } }} + suggestions={uniqueIngredients} placeholder="למשל: 2 ביצים" />