113 lines
5.1 KiB
TypeScript
113 lines
5.1 KiB
TypeScript
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
import { faClock, faFilePdf, faPenToSquare, faTrash } from "@fortawesome/free-solid-svg-icons";
|
|
import { MealTemplate } from "../../../types";
|
|
import { RECIPE_FLAVOR_NAMES } from "../enums";
|
|
import {
|
|
deriveRecipe, formatCalories, formatCount, formatIngredientAmount, formatPrepTime, formatPrice, formatWeight,
|
|
getIngredientCalories,
|
|
} from "../Utils";
|
|
import RecipeNote from "./RecipeNote";
|
|
import RecipeLinks from "./RecipeLinks";
|
|
|
|
type Props = {
|
|
template: MealTemplate,
|
|
busy?: boolean,
|
|
/** Všechny recepty — bez nich se vazby na jiné recepty nezobrazí. */
|
|
recipeList?: MealTemplate[],
|
|
onOpenRecipe?: (recipe: MealTemplate) => void,
|
|
/** Bez úpravy a smazání je karta jen k nahlédnutí (kolo štěstí). */
|
|
onEdit?: () => void,
|
|
onDelete?: () => void,
|
|
onExport?: () => void,
|
|
};
|
|
|
|
/**
|
|
* Karta receptu uvnitř jídla v seznamu jídel — suroviny, hodnoty celého hrnce
|
|
* i jedné porce a postup. Název a zdroj neopakuje, nese je jídlo.
|
|
*/
|
|
const MealTemplateCard = ({ template, busy, recipeList, onOpenRecipe, onEdit, onDelete, onExport }: Readonly<Props>) => {
|
|
const recipe = deriveRecipe(template.ingredients, template.servings, template.cookedWeight);
|
|
|
|
return (
|
|
<div className="card-panel template-card">
|
|
<div className="template-head">
|
|
<div className="template-title">
|
|
Recept
|
|
{template.category && <span className="tag">{template.category}</span>}
|
|
<span className="tag">{RECIPE_FLAVOR_NAMES[template.flavor].toLowerCase()}</span>
|
|
{template.prepMinutes != null && (
|
|
<span className="tag" title="Čas přípravy">
|
|
<FontAwesomeIcon icon={faClock} /> {formatPrepTime(template.prepMinutes)}
|
|
</span>
|
|
)}
|
|
{template.weight != null && <span className="tag">porce {formatWeight(template.weight)}</span>}
|
|
{(template.servings ?? 1) > 1 && (
|
|
<span className="tag">{formatCount(template.servings ?? 1, 'porce', 'porce', 'porcí')}</span>
|
|
)}
|
|
</div>
|
|
{template.calories != null && (
|
|
<span className="template-calories">{formatCalories(template.calories)}</span>
|
|
)}
|
|
{template.price != null && (
|
|
<span className="meal-template-price">{formatPrice(template.price)}</span>
|
|
)}
|
|
{onExport && (
|
|
<button
|
|
className="btn-icon"
|
|
onClick={() => onExport()}
|
|
disabled={busy}
|
|
title="Stáhnout jako PDF"
|
|
aria-label="Stáhnout recept jako PDF"
|
|
>
|
|
<FontAwesomeIcon icon={faFilePdf} />
|
|
</button>
|
|
)}
|
|
{onEdit && (
|
|
<button className="btn-icon" onClick={() => onEdit()} title="Upravit" aria-label="Upravit recept">
|
|
<FontAwesomeIcon icon={faPenToSquare} />
|
|
</button>
|
|
)}
|
|
{onDelete && (
|
|
<button
|
|
className="btn-icon danger"
|
|
onClick={() => onDelete()}
|
|
disabled={busy}
|
|
title="Smazat"
|
|
aria-label="Smazat recept"
|
|
>
|
|
<FontAwesomeIcon icon={faTrash} />
|
|
</button>
|
|
)}
|
|
</div>
|
|
|
|
{!!template.ingredients.length && (
|
|
<ul className="template-items">
|
|
{template.ingredients.map((ingredient, index) => (
|
|
// Suroviny nemají vlastní id, v rámci jednoho receptu je index stabilní
|
|
<li key={index}>
|
|
<span className="template-item-name">{ingredient.name}</span>
|
|
<span className="template-item-quantity">{formatIngredientAmount(ingredient)}</span>
|
|
<span className="template-item-calories">
|
|
{formatCalories(getIngredientCalories(ingredient))}
|
|
</span>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
)}
|
|
|
|
<div className="recipe-summary">
|
|
Celkem {formatCalories(recipe.totalCalories)}
|
|
{recipe.totalWeight != null && <> · {formatWeight(recipe.totalWeight)}</>}
|
|
{recipe.caloriesPer100g != null && <> · {recipe.caloriesPer100g} kcal/100 g</>}
|
|
{recipe.totalPrice != null && <> · {formatPrice(recipe.totalPrice)}</>}
|
|
</div>
|
|
|
|
{recipeList && <RecipeLinks template={template} recipeList={recipeList} onOpen={onOpenRecipe} />}
|
|
|
|
{template.note && <RecipeNote note={template.note} />}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default MealTemplateCard;
|