added rating books

This commit is contained in:
2025-10-29 22:38:38 +01:00
parent b4df375e4c
commit 26df6417b1
14 changed files with 353 additions and 153 deletions

View File

@@ -2,6 +2,7 @@
import { computed } from 'vue'
import { useRouter } from 'vue-router'
import { getImagePathOrDefault } from './api.js'
import { VRating } from 'vuetify/components/VRating';
const props = defineProps({
id: Number,
@@ -31,7 +32,15 @@ function openBook() {
<div class="media-content">
<div class="is-size-4">{{title}}</div>
<div class="is-size-5 is-italic">{{author}}</div>
<p>{{rating}}/10</p>
<VRating
half-increments
readonly
:length="5"
size="medium"
:model-value="rating/2"
active-color="bulma-body-color"
/>
</div>
<nav v-if="read" class="level">
<div class="level-left">

View File

@@ -1,7 +1,8 @@
<script setup>
import { computed } from 'vue'
import { getBook, getImagePathOrDefault } from './api.js'
import { getBook, getImagePathOrDefault, putBookUpdate } from './api.js'
import { onBeforeRouteUpdate } from 'vue-router'
import { VRating } from 'vuetify/components/VRating';
const props = defineProps({
id: String
@@ -15,6 +16,11 @@
error = res.error;
})
function onRatingUpdate(rating) {
data.value.rating = rating * 2
putBookUpdate(props.id, {rating: data.value.rating})
}
</script>
<template>
@@ -22,9 +28,21 @@
<div v-if="data">
<h3 class="title">{{data.title}}</h3>
<h3 class="subtitle">{{data.author}}</h3>
<figure class="image">
<img v-bind:src="imagePathOrDefault" v-bind:alt="data.title">
</figure>
<div class="imagewithrating">
<figure class="image">
<img v-bind:src="imagePathOrDefault" v-bind:alt="data.title">
</figure>
<VRating
half-increments
hover
:length="5"
size="x-large"
density="compact"
:model-value="data.rating/2"
@update:modelValue="onRatingUpdate"
active-color="bulma-body-color"
/>
</div>
</div>
</template>
@@ -35,4 +53,10 @@ img {
height:auto;
width:auto;
}
.imagewithrating {
vertical-align: top;
display: inline-block;
text-align: center;
}
</style>

View File

@@ -1,6 +1,6 @@
<script setup>
import { ref, computed } from 'vue'
import { postReadBook, getImagePathOrDefault } from './api.js'
import { putReadBook, getImagePathOrDefault } from './api.js'
import { useRouter } from 'vue-router'
const router = useRouter();
@@ -16,7 +16,7 @@
const error = ref(null)
async function onUserBookRead() {
const res = await postReadBook({bookId: props.id});
const res = await putReadBook(props.id);
if (res.ok) {
router.push('/books')
} else {

View File

@@ -42,11 +42,15 @@ export function getBook(id) {
}
export function postBook(book) {
return genericPostCall('/book', book.value)
return genericPayloadCall('/book', book.value, 'POST')
}
export async function postReadBook(userbook) {
return genericPostCall('/book/read', userbook)
export async function putReadBook(bookId) {
return putBookUpdate(bookId, {read: true})
}
export async function putBookUpdate(bookId, payload) {
return genericPayloadCall('/book/' + bookId, payload, 'PUT')
}
export function postLogin(user) {
@@ -84,12 +88,12 @@ export function genericPostCallNoAuth(apiRoute, object) {
})
}
export function genericPostCall(apiRoute, object) {
export function genericPayloadCall(apiRoute, object, method) {
const { user } = useAuthStore();
if (user != null) {
return fetch(baseUrl + apiRoute, {
method: 'POST',
method: method,
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + user.token

View File

@@ -2,7 +2,10 @@ import { createApp } from 'vue'
import { createI18n } from "vue-i18n";
import { createPinia } from 'pinia'
import { BootstrapIconsPlugin } from "bootstrap-icons-vue";
import { router } from './router.js'
import { router } from './router.js';
import { createVuetify } from 'vuetify'
import { aliases, mdi } from 'vuetify/iconsets/mdi-svg'
import { VRating } from 'vuetify/components/VRating';
import App from './App.vue'
import fr from './locales/fr.json';
@@ -17,6 +20,18 @@ const i18n = createI18n({
});
const vuetify = createVuetify({
VRating,
icons: {
defaultSet: 'mdi',
aliases,
sets: {
mdi,
},
},
})
const pinia = createPinia()
createApp(App).use(i18n).use(pinia).use(BootstrapIconsPlugin).use(router).mount('#app')
createApp(App).use(i18n).use(vuetify).use(pinia).use(BootstrapIconsPlugin).use(router).mount('#app')