first commit

This commit is contained in:
2025-09-17 18:55:33 +02:00
commit 232cd49052
29 changed files with 4705 additions and 0 deletions

15
front/src/App.vue Normal file
View File

@@ -0,0 +1,15 @@
<script setup>
import BooksBrowser from './BooksBrowser.vue'
import AppNavBar from './AppNavBar.vue'
</script>
<template>
<header>
<AppNavBar/>
</header>
<main class="section">
<BooksBrowser/>
</main>
</template>
<style scoped></style>

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

@@ -0,0 +1,41 @@
<script setup></script>
<template>
<nav class="navbar">
<div class="navbar-brand">
<div class="navbar-item">
PLM
</div>
</div>
<div class="navbar-menu">
<div class="navbar-start">
<a class="navbar-item">
Home
</a>
<a class="navbar-item">
Books
</a>
<a class="navbar-item">
Locations
</a>
</div>
<div class="navbar-end">
</div>
</div>
<div class="navbar-end">
<div class="navbar-item">
<div class="buttons">
<a class="button is-primary">
<strong>Sign up</strong>
</a>
<a class="button is-light">
Log in
</a>
</div>
</div>
</div>
</nav>
</template>
<style scoped></style>

48
front/src/BookCard.vue Normal file
View File

@@ -0,0 +1,48 @@
<script setup>
const props = defineProps({
title: String,
author: String,
imagePath: String,
rating: Number
});
const imagePathOrDefault = (props.imagePath == "" || typeof props.imagePath === 'undefined') ? "defaultbook.png" : props.imagePath;
</script>
<template>
<div class="box container has-background-dark">
<div class="media">
<div class="media-left">
<figure class="image mb-3">
<img v-bind:src="imagePathOrDefault" v-bind:alt="title">
</figure>
</div>
<div class="media-content">
<div class="is-size-4">{{title}}</div>
<div class="is-size-5 is-italic">{{author}}</div>
<p>{{rating}}/5</p>
</div>
</div>
</div>
</template>
<style scoped>
img {
max-height:200px;
max-width:200px;
height:auto;
width:auto;
}
.box {
transition:ease-in-out 0.04s
}
.box:hover {
transform: scale(1.01);
transition: ease-in-out 0.02s;
}
</style>

View File

@@ -0,0 +1,72 @@
<script setup>
import BookCard from './BookCard.vue';
import { useFetch } from './fetch.js'
const { data, error } = useFetch('http://localhost:8080/books');
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 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">
<BookCard v-bind="book" />
</div>
<div v-else>Loading...</div>
</div>
</template>
<style scoped></style>

13
front/src/fetch.js Normal file
View File

@@ -0,0 +1,13 @@
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 }
}

4
front/src/main.js Normal file
View File

@@ -0,0 +1,4 @@
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')