Add auto complete

This commit is contained in:
dvirlabs 2025-12-20 23:02:47 +02:00
parent 9f781d784d
commit 013d5692bf
4 changed files with 113 additions and 4 deletions

View File

@ -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;
}

View File

@ -580,6 +580,7 @@ function App() {
onSubmit={handleFormSubmit}
editingRecipe={editingRecipe}
currentUser={user}
allRecipes={recipes}
/>
)}

View File

@ -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 (
<div className="autocomplete-wrapper">
<input
ref={ref}
value={value}
onChange={onChange}
onKeyDown={handleKeyDown}
placeholder={placeholder}
{...props}
/>
{suggestion && (
<div className="autocomplete-suggestion">
<span className="autocomplete-typed">{value}</span>
<span className="autocomplete-rest">{suggestion.slice(value.length)}</span>
</div>
)}
</div>
);
}
export default AutocompleteInput;

View File

@ -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);
@ -11,6 +12,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
<div className="field">
<label>המתכון של:</label>
<input
<AutocompleteInput
value={madeBy}
onChange={(e) => setMadeBy(e.target.value)}
suggestions={uniqueMadeBy}
placeholder="שם האדם שיצר את הגרסה הזו..."
/>
</div>
@ -212,8 +224,8 @@ function RecipeFormDrawer({ open, onClose, onSubmit, editingRecipe = null, curre
<div className="dynamic-list">
{ingredients.map((val, idx) => (
<div key={idx} className="dynamic-row">
<input
ref={idx === ingredients.length - 1 ? lastIngredientRef : null}
<AutocompleteInput
inputRef={idx === ingredients.length - 1 ? lastIngredientRef : null}
value={val}
onChange={(e) => handleChangeIngredient(idx, e.target.value)}
onKeyDown={(e) => {
@ -222,6 +234,7 @@ function RecipeFormDrawer({ open, onClose, onSubmit, editingRecipe = null, curre
handleAddIngredient();
}
}}
suggestions={uniqueIngredients}
placeholder="למשל: 2 ביצים"
/>
<button