PronounsPage/components/blog/BlogReactionSection.vue

62 lines
1.8 KiB
Vue

<script setup lang="ts">
import Tooltip from '~/components/Tooltip.vue';
import type { BlogReactions } from '~/server/blog.ts';
import { reactionOptions } from '~/src/blog/reactions.ts';
import { useMainStore } from '~/store/index.ts';
const props = defineProps<{
slug: string;
}>();
const store = useMainStore();
const { data: reactions } = useFetch<BlogReactions>(`/api/blog/${props.slug}/reactions`, { server: false, lazy: true });
const classForEmoji = (emoji: string): string => {
if (reactions.value?.user?.includes(emoji)) {
return 'btn-primary';
} else if ((reactions.value?.total[emoji] ?? 0) > 0) {
return 'btn-outline-primary';
} else {
return 'btn-outline-secondary';
}
};
const dialogue = useDialogue();
const toggleReaction = async (emoji: string) => {
if (!store.user || !reactions.value?.user) {
return;
}
reactions.value = await dialogue.postWithAlertOnError(`/api/blog/${props.slug}/reactions`, {
emoji,
reaction: !reactions.value.user.includes(emoji),
});
};
</script>
<template>
<Loading :value="reactions">
<template #header>
<p class="small mb-0">
<Icon v="hands" />
<T>links.blogReact</T><T>quotation.colon</T>
</p>
</template>
<component
:is="store.user ? 'span' : Tooltip"
v-for="emoji in reactionOptions"
:key="emoji"
:text="$t('links.blogReactAuthRequired')"
>
<button
type="button"
:inert="!store.user"
:class="['btn', classForEmoji(emoji), 'm-1']"
@click="toggleReaction(emoji)"
>
{{ reactions?.total[emoji] ?? 0 }} {{ emoji }}
</button>
</component>
</Loading>
</template>