recipe author and stars and a bit of cleanup
This commit is contained in:
parent
c47dac9986
commit
6f43d17ddd
21 changed files with 361 additions and 207 deletions
|
@ -1,44 +1,22 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import { type Ingredient } from "../types/Recipe";
|
||||
|
||||
interface AddBulkIngredientsProps {
|
||||
ingredients: Ingredient[];
|
||||
onChange?: (ingredients: Ingredient[]) => void;
|
||||
ingredients: string[];
|
||||
onChange?: (ingredients: string[]) => void;
|
||||
}
|
||||
|
||||
const AddBulkIngredients: React.FC<AddBulkIngredientsProps> = ({ ingredients, onChange }) => {
|
||||
const [textValue, setTextValue] = useState<string>('');
|
||||
|
||||
useEffect(() => {
|
||||
const textRepresentation = ingredients.map(ingredient =>
|
||||
`${ingredient.quantity} ${ingredient.unit} ${ingredient.name}`
|
||||
).join('\n');
|
||||
const textRepresentation = ingredients.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;
|
||||
if (parts?.[1]) {
|
||||
const [num, denom] = parts[1].split('/');
|
||||
if (denom) {
|
||||
quantity = parseFloat(num) / parseFloat(denom);
|
||||
} else {
|
||||
quantity = parseFloat(parts[1]);
|
||||
}
|
||||
}
|
||||
return {
|
||||
quantity: +quantity.toFixed(2),
|
||||
unit: parts?.[2]?.trim() || '',
|
||||
name: parts?.[3]?.trim() || ''
|
||||
};
|
||||
});
|
||||
|
||||
if (onChange) onChange(parsedIngredients);
|
||||
if (onChange) onChange(lines);
|
||||
};
|
||||
|
||||
const handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import { type Step } from "../types/Recipe";
|
||||
|
||||
interface Step {
|
||||
step_number: number;
|
||||
instruction: string;
|
||||
}
|
||||
|
||||
interface AddBulkStepsProps {
|
||||
steps: Step[];
|
||||
|
@ -11,7 +15,7 @@ const AddBulkSteps: React.FC<AddBulkStepsProps> = ({ steps, onChange }) => {
|
|||
|
||||
useEffect(() => {
|
||||
const textRepresentation = steps.map(step =>
|
||||
`${step.instructions}`
|
||||
`${step.instruction}`
|
||||
).join('\n');
|
||||
setTextValue(textRepresentation);
|
||||
}, [steps]);
|
||||
|
@ -24,8 +28,8 @@ const AddBulkSteps: React.FC<AddBulkStepsProps> = ({ steps, onChange }) => {
|
|||
const parseAndUpdate = (value: string) => {
|
||||
const lines = value.split('\n').filter(line => line.trim() !== '');
|
||||
|
||||
const parsedSteps = lines.map((line, idx) => {
|
||||
return { idx: idx + 1, instructions: line }
|
||||
const parsedSteps: Step[] = lines.map((line, idx) => {
|
||||
return { step_number: idx + 1, instruction: line }
|
||||
})
|
||||
|
||||
if (onChange) onChange(parsedSteps);
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
import React, { useState } from 'react';
|
||||
import { type Recipe } from "../types/Recipe"
|
||||
import { type RecipeSmall } from "../types/Recipe"
|
||||
import Modal from '../components/Modal.tsx'
|
||||
|
||||
interface CookbookRecipeTileProps {
|
||||
recipe: Recipe;
|
||||
recipe: RecipeSmall;
|
||||
handleDelete: (id: number | undefined) => void;
|
||||
}
|
||||
|
||||
function CookbookRecipeTile({ recipe, handleDelete }: CookbookRecipeTileProps) {
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
|
||||
const openModal = () => setIsModalOpen(true);
|
||||
const closeModal = () => setIsModalOpen(false);
|
||||
const openModal = () => { setIsModalOpen(true) };
|
||||
const closeModal = () => { setIsModalOpen(false) };
|
||||
const confirmDelete = () => {
|
||||
handleDelete(recipe.id);
|
||||
closeModal();
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import "../css/Modal.css"
|
||||
|
||||
interface ModalProps {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
|
@ -12,14 +10,14 @@ const Modal = ({ isOpen, onClose, message, confirmAction, cancelAction }: ModalP
|
|||
if (!isOpen) return null;
|
||||
|
||||
return (
|
||||
<div className="modal-overlay" onClick={onClose}>
|
||||
<div className="modal-content" onClick={(e) => e.stopPropagation()}>
|
||||
<div className="modal-overlay fixed top-0 left-0 w-full h-full bg-black bg-opacity-50 flex justify-center items-center" onClick={onClose}>
|
||||
<div className="modal-content bg-amber-200 p-12 rounded-md shadow-md" onClick={(e) => e.stopPropagation()}>
|
||||
<div className="modal-msg">
|
||||
<span aria-labelledby="message">{message}</span>
|
||||
</div>
|
||||
<div className="modal-buttons">
|
||||
<button onClick={confirmAction}>Yes, Delete</button>
|
||||
<button onClick={cancelAction}>Cancel</button>
|
||||
<button className="bg-amber-600 rounded-md m-4 pt-1 pb-1 pr-2 pl-2" onClick={confirmAction}>Yes, Delete</button>
|
||||
<button className="bg-amber-600 rounded-md m-4 pt-1 pb-1 pr-2 pl-2" onClick={cancelAction}>Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import React, { useState } from 'react';
|
||||
import { Link, useLocation } from 'react-router-dom';
|
||||
|
||||
const RecipeBookTabs = () => {
|
||||
|
|
26
frontend/src/components/StarRating.tsx
Normal file
26
frontend/src/components/StarRating.tsx
Normal file
|
@ -0,0 +1,26 @@
|
|||
interface StarRatingProps {
|
||||
rating: number;
|
||||
onRatingChange: (newRating: number) => void;
|
||||
}
|
||||
|
||||
const StarRating = ({ rating, onRatingChange }: StarRatingProps) => {
|
||||
|
||||
return (
|
||||
<div>
|
||||
{[...Array(5)].map((star, index) => {
|
||||
index += 1;
|
||||
return (
|
||||
<span
|
||||
key={index}
|
||||
onClick={() => onRatingChange(index)}
|
||||
style={{ color: index <= rating ? 'gold' : 'gray', fontSize: '2rem', cursor: 'pointer' }}
|
||||
>
|
||||
★
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default StarRating;
|
Loading…
Add table
Add a link
Reference in a new issue