add ingredients working

This commit is contained in:
fred 2025-07-10 14:28:57 -07:00
parent 8af791deb9
commit 87c5516a9d
3 changed files with 99 additions and 57 deletions

View file

@ -1,16 +1,25 @@
import React, { useState } from 'react';
import React, { useState, useEffect } from 'react';
import { type Ingredient } from "../types/Recipe";
interface AddBulkIngredientsProps {
onChange?: (ingredients: { quantity: number; unit: string; name: string }[]) => void;
ingredients: Ingredient[];
onChange?: (ingredients: Ingredient[]) => void;
}
const AddBulkIngredients: React.FC<AddBulkIngredientsProps> = ({ onChange }) => {
const [ingredients, setIngredients] = useState<{ quantity: number; unit: string; name: string }[]>([]);
const AddBulkIngredients: React.FC<AddBulkIngredientsProps> = ({ ingredients, onChange }) => {
const [textValue, setTextValue] = useState<string>('');
const handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
const lines = e.target.value.split('\n').filter(line => line.trim() !== '');
useEffect(() => {
const textRepresentation = ingredients.map(ingredient =>
`${ingredient.quantity} ${ingredient.unit} ${ingredient.name}`
).join('\n');
setTextValue(textRepresentation);
}, [ingredients]);
const parseAndUpdate = (value: string) => {
const lines = value.split('\n').filter(line => line.trim() !== '');
const pattern = /^([0-9/.]+)?\s*(\S+)\s*((\w+\s*)*)$/;
const parsedIngredients = lines.map(line => {
const parts = line.match(pattern);
let quantity = 0;
@ -28,22 +37,38 @@ const AddBulkIngredients: React.FC<AddBulkIngredientsProps> = ({ onChange }) =>
name: parts?.[3]?.trim() || ''
};
});
setIngredients(parsedIngredients);
if (onChange) onChange(parsedIngredients); // Notify parent of change
if (onChange) onChange(parsedIngredients);
};
const handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
setTextValue(e.target.value);
};
const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
if (e.key === 'Enter') {
parseAndUpdate(textValue);
}
};
const handleBlur = () => {
parseAndUpdate(textValue);
};
return (
<div>
<p>Please enter ingredients in the following order: Quantity, Unit, Name</p> {/* Prompt for correct input format */}
<textarea rows={4} cols={50} onChange={handleInputChange} placeholder="Enter ingredients separated by newline..." />
<div>
<ul>
{ingredients.map((ing, index) => (
<li key={index}>{`${ing.quantity} ${ing.unit} ${ing.name}`}</li>
))}
</ul>
</div>
<p>Please enter ingredients: Quantity, Unit, Name</p>
<textarea
rows={4}
cols={50}
value={textValue}
onChange={handleInputChange}
onKeyDown={handleKeyDown}
onBlur={handleBlur}
placeholder="Enter ingredients separated by newline..."
/>
</div>
);
};
export default AddBulkIngredients;

View file

@ -1,43 +1,44 @@
import React, { useState } from 'react';
import { type Ingredient } from "../types/Recipe"
import { type Ingredient } from "../types/Recipe";
const AddIngredientsForm: React.FC = () => {
const [ingredients, setIngredients] = useState<Ingredient[]>([]);
interface AddIngredientFormProps {
ingredients: Ingredient[];
onSubmit?: (ingredients: Ingredient[]) => void;
}
const AddIngredientsForm: React.FC<AddIngredientFormProps> = ({ ingredients, onSubmit }) => {
const [newIngredient, setNewIngredient] = useState<Partial<Ingredient>>({});
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
console.log(e.target)
setNewIngredient(prev => ({ ...prev, [name]: value }));
};
const handleAddIngredient = () => {
if (newIngredient.name && newIngredient.quantity !== undefined && newIngredient.unit) {
setIngredients(prev => [...prev, newIngredient as Ingredient]);
setNewIngredient({});
}
};
const handleInputKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') {
handleAddIngredient();
}
const handleSelectChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
const { name, value } = e.target;
setNewIngredient(prev => ({ ...prev, [name]: value }));
};
const handleIngredientsSubmit = (e: React.FormEvent) => {
e.preventDefault();
// Here you can parse the input and convert it into ingredients
const lines = newIngredient.name?.split('\n').filter(line => line.trim() !== '');
if (lines) {
const parsedIngredients: Ingredient[] = lines.map(line => {
const parts = line.match(/^([^0-9]*)([0-9.]+)?([a-zA-Z]*)$/);
return {
name: parts?.[1]?.trim() || '',
quantity: parseFloat(parts?.[2]?.trim() || '0'),
unit: parts?.[3]?.trim() || ''
};
});
setIngredients(parsedIngredients);
if (!newIngredient.name || !newIngredient.quantity || !newIngredient.unit) {
return;
}
const newIngredientObj: Ingredient = {
quantity: parseFloat(newIngredient.quantity.toString()),
unit: newIngredient.unit,
name: newIngredient.name
};
const updatedIngredients = [...ingredients, newIngredientObj];
setNewIngredient({});
if (onSubmit) onSubmit(updatedIngredients);
};
return (
@ -46,40 +47,35 @@ const AddIngredientsForm: React.FC = () => {
<input
type="number"
name="quantity"
id="quantity"
placeholder="Quantity"
value={(newIngredient.quantity !== undefined ? newIngredient.quantity : '')}
onChange={handleChange}
onKeyDown={handleInputKeyDown}
/>
<select
name="unit"
id="unit"
value={newIngredient.unit || ''}
onChange={handleChange}
onChange={handleSelectChange}
>
<option value="">Select Unit</option>
<option value="grams">Grams</option>
<option value="kilograms">Kilograms</option>
<option value="cups">Cups</option>
{/* Add more units as needed */}
</select>
<input
type="text"
name="name"
id="name"
placeholder="Ingredient Name"
value={newIngredient.name || ''}
onChange={handleChange}
onKeyDown={handleInputKeyDown}
/>
<button type="button" onClick={handleAddIngredient}>Add Ingredient</button>
</form>
<div>
<ul>
{ingredients.map((ing, index) => (
<li key={index}>{`${ing.quantity} ${ing.unit} ${ing.name} `}</li>
))}
</ul>
</div>
<button type="submit">Add Ingredient</button>
</form>
</div>
);
};

View file

@ -2,11 +2,13 @@ import React, { useState } from 'react';
import { addRecipe } from "../services/frontendApi.js";
import { useNavigate } from "react-router-dom";
import AddBulkIngredients from "../components/AddBulkIngredients.tsx"
import AddIngredientsForm from "../components/AddIngredientsForm.tsx"
function AddRecipe() {
const [newRecipeId, setNewRecipeId] = useState<number | null>(null);
const navigate = useNavigate();
const [ingredients, setIngredients] = useState<{ quantity: number; unit: string; name: string }[]>([]);
const [showBulkForm, setShowBulkForm] = useState(true);
const addRecipeForm = async (event: React.FormEvent) => {
event.preventDefault();
@ -50,9 +52,28 @@ function AddRecipe() {
submit
</button>
</form>
<label>
<input
type="checkbox"
checked={showBulkForm}
onChange={(e) => setShowBulkForm(e.target.checked)}
/>
Bulk Entry
</label>
<div>
<AddBulkIngredients onChange={setIngredients} />
{showBulkForm ?
<AddBulkIngredients ingredients={ingredients} onChange={setIngredients} /> :
<AddIngredientsForm ingredients={ingredients} onSubmit={setIngredients} />
}
</div>
<div>
<ul>
{ingredients.map((ing, index) => (
<li key={index}>{`${ing.quantity} ${ing.unit} ${ing.name}`}</li>
))}
</ul>
</div>
</div>
)
}