added rating books
This commit is contained in:
38
front/package-lock.json
generated
38
front/package-lock.json
generated
@@ -12,10 +12,12 @@
|
||||
"pinia": "^3.0.3",
|
||||
"vue": "^3.5.18",
|
||||
"vue-i18n": "^11.1.12",
|
||||
"vue-router": "^4.5.1"
|
||||
"vue-router": "^4.5.1",
|
||||
"vuetify": "^3.10.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.31.0",
|
||||
"@mdi/font": "^7.4.47",
|
||||
"@vitejs/plugin-vue": "^6.0.1",
|
||||
"@vue/eslint-config-prettier": "^10.2.0",
|
||||
"eslint": "^9.31.0",
|
||||
@@ -1256,6 +1258,13 @@
|
||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@mdi/font": {
|
||||
"version": "7.4.47",
|
||||
"resolved": "https://registry.npmjs.org/@mdi/font/-/font-7.4.47.tgz",
|
||||
"integrity": "sha512-43MtGpd585SNzHZPcYowu/84Vz2a2g31TvPMTm9uTiCSWzaheQySUcSyUH/46fPnuPQWof2yd0pGBtzee/IQWw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@pkgr/core": {
|
||||
"version": "0.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz",
|
||||
@@ -3916,6 +3925,33 @@
|
||||
"vue": "^3.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vuetify": {
|
||||
"version": "3.10.8",
|
||||
"resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.10.8.tgz",
|
||||
"integrity": "sha512-TV1bx8mUjOPbhmEsamm38/CBcVe5DHYepOZGE6aQJ2uxvg96B4k+QHgIJcD5uKVfKmxKkJRtHdEXyq6JP9wBtg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/johnleider"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=4.7",
|
||||
"vite-plugin-vuetify": ">=2.1.0",
|
||||
"vue": "^3.5.0",
|
||||
"webpack-plugin-vuetify": ">=3.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
},
|
||||
"vite-plugin-vuetify": {
|
||||
"optional": true
|
||||
},
|
||||
"webpack-plugin-vuetify": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
|
||||
@@ -18,10 +18,12 @@
|
||||
"pinia": "^3.0.3",
|
||||
"vue": "^3.5.18",
|
||||
"vue-i18n": "^11.1.12",
|
||||
"vue-router": "^4.5.1"
|
||||
"vue-router": "^4.5.1",
|
||||
"vuetify": "^3.10.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.31.0",
|
||||
"@mdi/font": "^7.4.47",
|
||||
"@vitejs/plugin-vue": "^6.0.1",
|
||||
"@vue/eslint-config-prettier": "^10.2.0",
|
||||
"eslint": "^9.31.0",
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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')
|
||||
|
||||
Reference in New Issue
Block a user