Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: redesign recipe info card #5026

Open
wants to merge 13 commits into
base: mealie-next
Choose a base branch
from
42 changes: 21 additions & 21 deletions frontend/components/Domain/Recipe/RecipeLastMade.vue
Original file line number Diff line number Diff line change
Expand Up @@ -86,29 +86,29 @@
</BaseDialog>
</div>
<div>
<div class="d-flex justify-center flex-wrap">
<v-chip
label
:small="$vuetify.breakpoint.smAndDown"
color="accent custom-transparent"
class="ma-1 pa-3"
>
<v-icon left>
<div v-if="lastMadeReady" class="d-flex justify-center flex-wrap">
<v-row no-gutters class="d-flex flex-wrap align-center" style="font-size: larger;">
<v-icon x-large left color="primary">
{{ $globals.icons.calendar }}
</v-icon>
<div v-if="lastMadeReady">
{{ $t('recipe.last-made-date', { date: lastMade ? new Date(lastMade).toLocaleDateString($i18n.locale) : $t("general.never") } ) }}
</div>
<div v-else>
<AppLoader tiny />
</div>
</v-chip>
</div>
<div class="d-flex justify-center flex-wrap mt-1">
<BaseButton :small="$vuetify.breakpoint.smAndDown" @click="madeThisDialog = true">
<template #icon> {{ $globals.icons.chefHat }} </template>
{{ $t('recipe.made-this') }}
</BaseButton>
<p class="my-0"><span class="font-weight-bold">{{ $tc("general.last-made") }}</span><br>{{ lastMade ? new Date(lastMade).toLocaleDateString($i18n.locale) : $tc("general.never") }}</p>
<v-tooltip bottom>
<template #activator="{ on, attrs }">
<v-btn
fab
x-small
color="success"
class="ml-2"
v-bind="attrs"
v-on="on"
@click="madeThisDialog = true"
>
<v-icon>{{ $globals.icons.create }}</v-icon>
</v-btn>
</template>
<span>{{ $tc("recipe.made-this") }}</span>
</v-tooltip>
</v-row>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,16 @@
</v-card-title>
<v-divider class="my-2" />
<SafeMarkdown :source="recipe.description" />
<v-divider />
<v-divider v-if="recipe.description" />
<v-container class="d-flex flex-row flex-wrap justify-center align-center">
<div class="mx-5">
<div class="mx-6">
<v-row no-gutters class="mb-1">
<v-col v-if="recipe.recipeYieldQuantity || recipe.recipeYield" cols="12" class="d-flex flex-wrap justify-center">
<RecipeYield
:yield-quantity="recipe.recipeYieldQuantity"
:yield="recipe.recipeYield"
:scale="recipeScale"
class="mb-4"
/>
</v-col>
</v-row>
Expand All @@ -31,18 +32,18 @@
<RecipeLastMade
v-if="isOwnGroup"
:recipe="recipe"
:class="true ? undefined : 'force-bottom'"
class="mb-4"
/>
</v-col>
</v-row>
</div>
<div class="mx-5">
<div class="mx-6">
<RecipeTimeCard
stacked
container-class="d-flex flex-wrap justify-center"
:prep-time="recipe.prepTime"
:total-time="recipe.totalTime"
:perform-time="recipe.performTime"
class="mb-4"
/>
</div>
</v-container>
Expand Down
76 changes: 31 additions & 45 deletions frontend/components/Domain/Recipe/RecipeTimeCard.vue
Original file line number Diff line number Diff line change
@@ -1,41 +1,33 @@
<template>
<div v-if="stacked">
<v-container>
<v-row v-for="(time, index) in allTimes" :key="`${index}-stacked`" no-gutters>
<v-col cols="12" :class="containerClass">
<v-chip
:small="$vuetify.breakpoint.smAndDown"
label
:color="color"
class="ma-1"
>
<v-icon left>
{{ $globals.icons.clockOutline }}
</v-icon>
{{ time.name }} |
{{ time.value }}
</v-chip>
</v-col>
</v-row>
</v-container>
</div>
<div v-else>
<v-container :class="containerClass">
<v-chip
v-for="(time, index) in allTimes"
:key="index"
:small="$vuetify.breakpoint.smAndDown"
label
:color="color"
class="ma-1"
>
<v-icon left>
<template v-if="showCards">
<div class="text-center">
<!-- Total Time -->
<div v-if="validateTotalTime" class="time-card-flex mx-auto">
<v-row no-gutters class="d-flex flex-wrap align-center" style="font-size: larger;">
<v-icon x-large left color="primary">
{{ $globals.icons.clockOutline }}
</v-icon>
{{ time.name }} |
{{ time.value }}
</v-chip>
</v-container>
<p class="my-0"><span class="font-weight-bold">{{ validateTotalTime.name }}</span><br>{{ validateTotalTime.value }}</p>
</v-row>
</div>
<v-divider v-if="validateTotalTime && (validatePrepTime || validatePerformTime)" class="my-2" />
<!-- Prep Time & Perform Time -->
<div v-if="validatePrepTime || validatePerformTime" class="time-card-flex mx-auto">
<v-row no-gutters class="d-flex justify-center align-center" style="font-size: larger; width: 100%;">
<template v-if="validatePrepTime">
<v-icon large left color="primary">
{{ $globals.icons.knfife }}
</v-icon>
<p class="my-0"><span class="font-weight-bold">{{ validatePrepTime.name }}</span><br>{{ validatePrepTime.value }}</p>
</template>
<v-divider v-if="validatePrepTime && validatePerformTime" vertical class="mx-4" />
<template v-if="validatePerformTime">
<v-icon large left color="primary">
{{ $globals.icons.potSteam }}
</v-icon>
<p class="my-0"><span class="font-weight-bold">{{ validatePerformTime.name }}</span><br>{{ validatePerformTime.value }}</p>
</template>
</v-row>
</div>
</div>
</template>

Expand All @@ -44,10 +36,6 @@ import { computed, defineComponent, useContext } from "@nuxtjs/composition-api";

export default defineComponent({
props: {
stacked: {
type: Boolean,
default: false,
},
prepTime: {
type: String,
default: null,
Expand Down Expand Up @@ -92,13 +80,11 @@ export default defineComponent({
return !isEmpty(props.performTime) ? { name: i18n.t("recipe.perform-time"), value: props.performTime } : null;
});

const allTimes = computed(() => {
return [validateTotalTime.value, validatePrepTime.value, validatePerformTime.value].filter((x) => x !== null);
});

return {
showCards,
allTimes,
validateTotalTime,
validatePrepTime,
validatePerformTime,
};
},
});
Expand Down
42 changes: 17 additions & 25 deletions frontend/components/Domain/Recipe/RecipeYield.vue
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
<template>
<div v-if="displayText" class="d-flex justify-space-between align-center">
<v-chip
:small="$vuetify.breakpoint.smAndDown"
label
:color="color"
>
<v-icon left>
{{ $globals.icons.potSteam }}
<div v-if="scaledAmount" class="d-flex align-center">
<v-row no-gutters class="d-flex flex-wrap align-center" style="font-size: larger;">
<v-icon x-large left color="primary">
{{ $globals.icons.bread }}
</v-icon>
<!-- eslint-disable-next-line vue/no-v-html -->
<span v-html="displayText"></span>
</v-chip>
<p class="my-0">
<span class="font-weight-bold">{{ $i18n.tc("recipe.yield") }}</span><br>
<!-- eslint-disable-next-line vue/no-v-html -->
<span v-html="scaledAmount"></span> {{ text }}
</p>
</v-row>
</div>
</template>

<script lang="ts">
import { computed, defineComponent, useContext } from "@nuxtjs/composition-api";
import { defineComponent, computed } from "@nuxtjs/composition-api";
import DOMPurify from "dompurify";
import { useScaledAmount } from "~/composables/recipes/use-scaled-amount";

Expand All @@ -39,7 +38,6 @@ export default defineComponent({
},
},
setup(props) {
const { i18n } = useContext();

function sanitizeHTML(rawHtml: string) {
return DOMPurify.sanitize(rawHtml, {
Expand All @@ -48,21 +46,15 @@ export default defineComponent({
});
}

const displayText = computed(() => {
if (!(props.yieldQuantity || props.yield)) {
return "";
}

const { scaledAmountDisplay } = useScaledAmount(props.yieldQuantity, props.scale);

return i18n.t("recipe.yields-amount-with-text", {
amount: scaledAmountDisplay,
text: sanitizeHTML(props.yield),
}) as string;
const scaledAmount = computed(() => {
const {scaledAmountDisplay} = useScaledAmount(props.yieldQuantity, props.scale);
return scaledAmountDisplay;
});
const text = sanitizeHTML(props.yield);

return {
displayText,
scaledAmount,
text,
};
},
});
Expand Down
2 changes: 0 additions & 2 deletions frontend/lang/messages/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,6 @@
"failed-to-add-recipe-to-mealplan": "Failed to add recipe to mealplan",
"failed-to-add-to-list": "Failed to add to list",
"yield": "Yield",
"yields-amount-with-text": "Yields {amount} {text}",
Copy link
Collaborator

@michael-genson michael-genson Feb 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still used in the print view (see above)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or maybe the print view just needs to be updated with the new component

"yield-text": "Yield Text",
"quantity": "Quantity",
"choose-unit": "Choose Unit",
Expand Down Expand Up @@ -579,7 +578,6 @@
"made-this": "I Made This",
"how-did-it-turn-out": "How did it turn out?",
"user-made-this": "{user} made this",
"last-made-date": "Last Made {date}",
"api-extras-description": "Recipes extras are a key feature of the Mealie API. They allow you to create custom JSON key/value pairs within a recipe, to reference from 3rd party applications. You can use these keys to provide information, for example to trigger automations or custom messages to relay to your desired device.",
"message-key": "Message Key",
"parse": "Parse",
Expand Down
4 changes: 4 additions & 0 deletions frontend/lib/icons/icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ import {
mdiFileCabinet,
mdiSilverwareForkKnife,
mdiCodeTags,
mdiKnife,
mdiCookie
} from "@mdi/js";

export const icons = {
Expand Down Expand Up @@ -271,6 +273,8 @@ export const icons = {
windowClose: mdiWindowClose,
zip: mdiFolderZipOutline,
undo: mdiUndo,
knfife: mdiKnife,
bread: mdiCookie,

// Crud
backArrow: mdiArrowLeftBoldOutline,
Expand Down
Loading