fix: migrate RecipeRating component to script setup and defineModel (#7203)

This commit is contained in:
ProperTeaMogul
2026-03-09 16:41:09 +00:00
committed by GitHub
parent 98c555fd20
commit 96597915ff
2 changed files with 55 additions and 74 deletions

View File

@@ -17,7 +17,7 @@
</v-card-title> </v-card-title>
<RecipeRating <RecipeRating
:key="recipe.slug" :key="recipe.slug"
:value="recipe.rating" :model-value="recipe.rating"
:recipe-id="recipe.id" :recipe-id="recipe.id"
:slug="recipe.slug" :slug="recipe.slug"
/> />

View File

@@ -1,10 +1,10 @@
<template> <template>
<div @click.prevent> <div @click.prevent>
<!-- User Rating --> <!-- User Rating -->
<v-hover v-slot="{ isHovering, props }"> <v-hover v-slot="{ isHovering, props: hoverProps }">
<v-rating <v-rating
v-if="isOwnGroup && (userRating || isHovering || !ratingsLoaded)" v-if="isOwnGroup && (userRating || isHovering || !ratingsLoaded)"
v-bind="props" v-bind="hoverProps"
:model-value="userRating" :model-value="userRating"
active-color="secondary" active-color="secondary"
color="secondary-lighten-3" color="secondary-lighten-3"
@@ -18,7 +18,7 @@
<!-- Group Rating --> <!-- Group Rating -->
<v-rating <v-rating
v-else v-else
v-bind="props" v-bind="hoverProps"
:model-value="groupRating" :model-value="groupRating"
:half-increments="true" :half-increments="true"
active-color="grey-darken-1" active-color="grey-darken-1"
@@ -32,81 +32,62 @@
</div> </div>
</template> </template>
<script lang="ts"> <script setup lang="ts">
import { useLoggedInState } from "~/composables/use-logged-in-state"; import { useLoggedInState } from "~/composables/use-logged-in-state";
import { useUserSelfRatings } from "~/composables/use-users"; import { useUserSelfRatings } from "~/composables/use-users";
export default defineNuxtComponent({ interface Props {
props: { emitOnly?: boolean;
emitOnly: { recipeId?: string;
type: Boolean, slug?: string;
default: false, small?: boolean;
}, }
recipeId: {
type: String,
default: "",
},
slug: {
type: String,
default: "",
},
modelValue: {
type: Number,
default: 0,
},
small: {
type: Boolean,
default: false,
},
},
emits: ["update:modelValue"],
setup(props, context) {
const { isOwnGroup } = useLoggedInState();
const { userRatings, setRating, ready: ratingsLoaded } = useUserSelfRatings();
const userRating = computed(() => { const props = withDefaults(defineProps<Props>(), {
return userRatings.value.find(r => r.recipeId === props.recipeId)?.rating ?? undefined; emitOnly: false,
}); recipeId: "",
slug: "",
// if a user unsets their rating, we don't want to fall back to the group rating since it's out of sync small: false,
const hideGroupRating = ref(!!userRating.value);
watch(
() => userRating.value,
() => {
if (userRating.value) {
hideGroupRating.value = true;
}
},
);
const groupRating = computed(() => {
return hideGroupRating.value ? 0 : props.modelValue;
});
function updateRating(val?: number) {
if (!isOwnGroup.value) {
return;
}
if (val === userRating.value) {
val = 0;
}
if (!props.emitOnly) {
setRating(props.slug, val || 0, null);
}
context.emit("update:modelValue", val);
}
return {
isOwnGroup,
ratingsLoaded,
groupRating,
userRating,
updateRating,
};
},
}); });
const modelValue = defineModel<number>({ default: 0 });
const { isOwnGroup } = useLoggedInState();
const { userRatings, setRating, ready: ratingsLoaded } = useUserSelfRatings();
const userRating = computed(() => {
return userRatings.value.find(r => r.recipeId === props.recipeId)?.rating ?? undefined;
});
// if a user unsets their rating, we don't want to fall back to the group rating since it's out of sync
const hideGroupRating = ref(!!userRating.value);
watch(
() => userRating.value,
() => {
if (userRating.value) {
hideGroupRating.value = true;
}
},
);
const groupRating = computed(() => {
return hideGroupRating.value ? 0 : modelValue.value;
});
function updateRating(val?: number) {
if (!isOwnGroup.value) {
return;
}
if (val === userRating.value) {
val = 0;
}
if (!props.emitOnly) {
setRating(props.slug, val || 0, null);
}
modelValue.value = val ?? 0;
}
</script> </script>
<style lang="scss" scoped></style> <style lang="scss" scoped></style>