Second commit

added few test, first api to add book
This commit is contained in:
2025-09-23 17:16:48 +02:00
parent 0457ca2011
commit 8432902df1
19 changed files with 298 additions and 123 deletions

View File

@@ -8,7 +8,8 @@
"name": "personal-library-manager",
"version": "0.0.0",
"dependencies": {
"vue": "^3.5.18"
"vue": "^3.5.18",
"vue-router": "^4.5.1"
},
"devDependencies": {
"@eslint/js": "^9.31.0",
@@ -1682,6 +1683,12 @@
"@vue/shared": "3.5.21"
}
},
"node_modules/@vue/devtools-api": {
"version": "6.6.4",
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz",
"integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==",
"license": "MIT"
},
"node_modules/@vue/devtools-core": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/@vue/devtools-core/-/devtools-core-8.0.1.tgz",
@@ -3989,6 +3996,21 @@
"eslint": "^8.57.0 || ^9.0.0"
}
},
"node_modules/vue-router": {
"version": "4.5.1",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.1.tgz",
"integrity": "sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw==",
"license": "MIT",
"dependencies": {
"@vue/devtools-api": "^6.6.4"
},
"funding": {
"url": "https://github.com/sponsors/posva"
},
"peerDependencies": {
"vue": "^3.2.0"
}
},
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",

View File

@@ -14,7 +14,8 @@
"format": "prettier --write src/"
},
"dependencies": {
"vue": "^3.5.18"
"vue": "^3.5.18",
"vue-router": "^4.5.1"
},
"devDependencies": {
"@eslint/js": "^9.31.0",

41
front/src/AddBook.vue Normal file
View File

@@ -0,0 +1,41 @@
<script setup>
import { ref } from 'vue'
import { postBook } from './api.js'
import { useRouter, useRoute } from 'vue-router'
const router = useRouter();
const book = ref({
title: "",
author: ""
});
function onSubmit(e) {
postBook(book);
router.push('/');
}
</script>
<template>
<form @submit.prevent="onSubmit">
<div class="field">
<label class="label">Title</label>
<div class="control">
<input class="input" type="text" v-model="book.title" placeholder="Title">
</div>
</div>
<div class="field">
<label class="label">Author</label>
<div class="control">
<input class="input" type="text" v-model="book.author" placeholder="Author">
</div>
</div>
<div class="field">
<div class="control">
<button class="button is-link">Submit</button>
</div>
</div>
</form>
</template>
<style scoped></style>

View File

@@ -1,6 +1,6 @@
<script setup>
import BooksBrowser from './BooksBrowser.vue'
import AppNavBar from './AppNavBar.vue'
import { RouterView } from 'vue-router'
</script>
<template>
@@ -8,7 +8,7 @@
<AppNavBar/>
</header>
<main class="section">
<BooksBrowser/>
<RouterView />
</main>
</template>

View File

@@ -1,4 +1,6 @@
<script setup></script>
<script setup>
import { RouterLink } from 'vue-router'
</script>
<template>
<nav class="navbar">
@@ -9,9 +11,12 @@
</div>
<div class="navbar-menu">
<div class="navbar-start">
<a class="navbar-item">
<RouterLink to="/" class="navbar-item" activeClass="is-active">
Home
</a>
</RouterLink>
<RouterLink to="/add" class="navbar-item" activeClass="is-active">
Add Book
</RouterLink>
<a class="navbar-item">
Books
</a>

View File

@@ -22,7 +22,7 @@ const imagePathOrDefault = (props.imagePath == "" || typeof props.imagePath ===
<div class="media-content">
<div class="is-size-4">{{title}}</div>
<div class="is-size-5 is-italic">{{author}}</div>
<p>{{rating}}/5</p>
<p>{{rating}}/10</p>
</div>
</div>
</div>
@@ -37,7 +37,8 @@ img {
}
.box {
transition:ease-in-out 0.04s
transition:ease-in-out 0.04s;
margin-bottom: 15px;
}
.box:hover {

View File

@@ -1,72 +1,38 @@
<script setup>
import BookCard from './BookCard.vue';
import { useFetch } from './fetch.js'
import { getBooks } from './api.js'
const { data, error } = useFetch('http://localhost:8080/books');
const { data, error } = getBooks();
console.log(data.value);
let books = [];
const dumas = {
id: 1,
title: "Le Comte de Monte-Cristo",
author: "Alexandre Dumas",
imagePath: "./comtemontecristo.png",
rating: 4.5
};
const celine = {
id: 2,
title: "Guerre",
author: "Céline",
imagePath: "",
rating: 5
}
const proust = {
id: 3,
title: "La Prisonnière",
author: "Marcel Proust",
imagePath: "",
rating: 5
}
const proust2 = {
id: 4,
title: "Du côté de chez Swann",
author: "Marcel Proust",
imagePath: "",
rating: 5
}
const balzac = {
id: 5,
title: "Splendeurs et misères des courtisanes",
author: "Balzac",
imagePath: "",
rating: 3
}
const cervantes = {
id: 6,
title: "LIngénieux Hidalgo Don Quichotte de la Manche ou L'Ingénieux Noble Don Quichotte de la Manche",
author: "Cervantès",
imagePath: "",
rating: 3
}
books.push(dumas);
books.push(celine);
books.push(proust);
books.push(proust2);
books.push(balzac);
books.push(cervantes);
</script>
<template>
<div class="grid">
<div class="books">
<div v-if="error">Error when loading books: {{ error.message }}</div>
<div class="cell" v-else-if="data" v-for="book in data" :key="book.id">
<div class="book" v-else-if="data" v-for="book in data" :key="book.id">
<BookCard v-bind="book" />
</div>
<div v-else>Loading...</div>
</div>
</template>
<style scoped></style>
<style scoped>
.books {
position:relative;
float:left;
width:100%; height:auto;
padding-bottom: 100px;
line-height: 2.5;
column-count: 4;
column-gap: 15px;
}
#book {
width: 100% !important;
height: auto !important;
transition: ease-in-out 0.15s;
}
</style>

29
front/src/api.js Normal file
View File

@@ -0,0 +1,29 @@
import { ref } from 'vue'
const baseUrl = "http://localhost:8080"
function useFetch(url) {
const data = ref(null)
const error = ref(null)
fetch(url)
.then((res) => res.json())
.then((json) => (data.value = json))
.catch((err) => (error.value = err))
return { data, error }
}
export function getBooks() {
return useFetch(baseUrl + '/books');
}
export function postBook(book) {
fetch(baseUrl + '/book', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(book.value)
});
}

View File

@@ -1,13 +0,0 @@
import { ref } from 'vue'
export function useFetch(url) {
const data = ref(null)
const error = ref(null)
fetch(url)
.then((res) => res.json())
.then((json) => (data.value = json))
.catch((err) => (error.value = err))
return { data, error }
}

View File

@@ -1,4 +1,18 @@
import { createApp } from 'vue'
import { createRouter, createWebHistory } from 'vue-router'
import App from './App.vue'
import BooksBrowser from './BooksBrowser.vue'
import AddBook from './AddBook.vue'
createApp(App).mount('#app')
const routes = [
{ path: '/', component: BooksBrowser },
{ path: '/add', component: AddBook },
]
export const router = createRouter({
history: createWebHistory(),
routes,
})
createApp(App).use(router).mount('#app')