feat: Vote Functionality

main
Flycro 2024-03-20 18:12:23 +01:00
parent 1d7f41e812
commit e393ba5943
3 changed files with 77 additions and 4 deletions

View File

@ -3,6 +3,7 @@
namespace App\Http\Controllers;
use App\Models\BookRecommendation;
use App\Models\User;
use App\Models\Vote;
use Illuminate\Http\Request;
@ -29,4 +30,22 @@ class VoteController extends Controller
return response()->json(['message' => 'No remaining votes.'], 403);
}
public function addTotalVotesAll(Request $request)
{
$request->validate([
'total_votes' => 'required|integer|min:1',
]);
if (!(auth()->user()->hasRole('admin')) ) {
return response()->json(['message' => 'Keine Berechtigung.'], 403);
}
$users = User::all();
foreach ($users as $user) {
$user->increment('total_votes', $request->total_votes);
}
return response()->json(['message' => 'Total votes added to all book recommendations.']);
}
}

View File

@ -0,0 +1,48 @@
<script setup lang="ts">
const isOpen = ref(false)
const state = reactive({
total_votes: 2,
})
const { refresh: onClick, status } = useFetch<any>(`admin/add-total-votes-all`, {
method: 'POST',
body: state,
immediate: false,
watch: false,
async onResponse({ response }) {
if (response.ok) {
useToast().add({
icon: 'i-heroicons-check-circle-20-solid',
title: 'Es wurden allen Nutzern 2 Votes hinzugefügt.',
color: 'emerald',
})
}
isOpen.value = false
},
})
</script>
<template>
<UButton icon="i-heroicons-star" solid label="Nutzern Votes hinzufügen" @click="isOpen = true" />
<UDashboardModal
v-model="isOpen"
title="Votes hinzufügen"
description="Bist du dir sicher das du jedem Benutzer 2 Votes geben möchtest?"
icon="i-heroicons-star"
:ui="{
icon: { base: 'text-primary dark:text-primary-400' } as any,
footer: { base: 'ml-16' } as any,
}"
>
<template #footer>
<UButton color="primary" label="Bestätigen" :loading="status === 'pending'" @click="onClick" />
<UButton color="white" label="Abbrechen" @click="isOpen = false" />
</template>
</UDashboardModal>
</template>
<style scoped>
</style>

View File

@ -1,10 +1,12 @@
<script setup lang="ts">
import type { BookRecommendationStatusEnum } from '~/stores/book-recommendations'
import { useBookRecommendationStore } from '~/stores/book-recommendations'
const props = defineProps<{
row: {
id: number
book_name: string
status: BookRecommendationStatusEnum
}
}>()
@ -16,6 +18,10 @@ const state = reactive({
book_recommendation_id: props.row.id,
})
watch(() => props.row, (newRow) => {
state.book_recommendation_id = newRow.id
})
const bookRecommendationStore = useBookRecommendationStore()
const { refresh: onVote, status } = useFetch<any>(`vote`, {
@ -39,14 +45,14 @@ const { refresh: onVote, status } = useFetch<any>(`vote`, {
</script>
<template>
<UButton icon="i-heroicons-star" size="sm" color="green" variant="solid" square :disabled="authStore.user.total_votes === 0" @click="isOpen = true" />
<UButton v-if="props.row.status === 'PENDING'" class="transition-150 transform-gpu hover:scale-110" icon="i-heroicons-star" size="sm" color="green" variant="solid" square :disabled="authStore.user.total_votes === 0" @click="isOpen = true" />
<UDashboardModal
v-model="isOpen"
title="Buch Empfehlung löschen"
:description="`Bist du dir sicher das du für die Buchempfehlung ${row.book_name} abstimmen möchtest?`"
title="Für Buch abstimmen"
:description="`Bist du dir sicher das du für die Buchempfehlung &quot;${row.book_name}&quot; abstimmen möchtest?`"
icon="i-heroicons-star"
:ui="{
icon: { base: 'text-green-500 dark:text-green-400' } as any,
icon: { base: 'text-primary-500 dark:text-primary-400' } as any,
footer: { base: 'ml-16' } as any,
}"
>