feat: export + detail receptů
feat: losování jídel
This commit is contained in:
1 parent
35cbc5a9ca
commit
caffb6d8b4
23 files changed
+2674
-43
No files matched your search
@@ -1,21 +1,24 @@
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { faPenToSquare, faTrash } from "@fortawesome/free-solid-svg-icons";
|
||||
import { faFilePdf, faPenToSquare, faTrash } from "@fortawesome/free-solid-svg-icons";
|
||||
import { MealTemplate } from "../../../types";
|
||||
import { RECIPE_FLAVOR_NAMES } from "../enums";
|
||||
import { deriveRecipe, formatCalories, formatPrice, formatWeight, getIngredientCalories } from "../Utils";
|
||||
import { deriveRecipe, formatCalories, formatCount, formatPrice, formatWeight, getIngredientCalories } from "../Utils";
|
||||
import RecipeNote from "./RecipeNote";
|
||||
|
||||
type Props = {
|
||||
template: MealTemplate,
|
||||
busy: boolean,
|
||||
onEdit: () => void,
|
||||
onDelete: () => void,
|
||||
busy?: boolean,
|
||||
/** 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, onEdit, onDelete }: Readonly<Props>) => {
|
||||
const MealTemplateCard = ({ template, busy, onEdit, onDelete, onExport }: Readonly<Props>) => {
|
||||
const recipe = deriveRecipe(template.ingredients, template.servings, template.cookedWeight);
|
||||
|
||||
return (
|
||||
@@ -27,7 +30,7 @@ const MealTemplateCard = ({ template, busy, onEdit, onDelete }: Readonly<Props>)
|
||||
<span className="tag">{RECIPE_FLAVOR_NAMES[template.flavor].toLowerCase()}</span>
|
||||
{template.weight != null && <span className="tag">porce {formatWeight(template.weight)}</span>}
|
||||
{(template.servings ?? 1) > 1 && (
|
||||
<span className="tag">{template.servings} porcí</span>
|
||||
<span className="tag">{formatCount(template.servings ?? 1, 'porce', 'porce', 'porcí')}</span>
|
||||
)}
|
||||
</div>
|
||||
{template.calories != null && (
|
||||
@@ -36,18 +39,33 @@ const MealTemplateCard = ({ template, busy, onEdit, onDelete }: Readonly<Props>)
|
||||
{template.price != null && (
|
||||
<span className="meal-template-price">{formatPrice(template.price)}</span>
|
||||
)}
|
||||
<button className="btn-icon" onClick={() => onEdit()} title="Upravit" aria-label="Upravit recept">
|
||||
<FontAwesomeIcon icon={faPenToSquare} />
|
||||
</button>
|
||||
<button
|
||||
className="btn-icon danger"
|
||||
onClick={() => onDelete()}
|
||||
disabled={busy}
|
||||
title="Smazat"
|
||||
aria-label="Smazat recept"
|
||||
>
|
||||
<FontAwesomeIcon icon={faTrash} />
|
||||
</button>
|
||||
{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 && (
|
||||
@@ -74,7 +92,7 @@ const MealTemplateCard = ({ template, busy, onEdit, onDelete }: Readonly<Props>)
|
||||
{recipe.totalPrice != null && <> · {formatPrice(recipe.totalPrice)}</>}
|
||||
</div>
|
||||
|
||||
{template.note && <p className="meal-template-note">{template.note}</p>}
|
||||
{template.note && <RecipeNote note={template.note} />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user