first commit
This commit is contained in:
15
front/src/App.vue
Normal file
15
front/src/App.vue
Normal 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
41
front/src/AppNavBar.vue
Normal 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
48
front/src/BookCard.vue
Normal 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>
|
||||
72
front/src/BooksBrowser.vue
Normal file
72
front/src/BooksBrowser.vue
Normal 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: "L’Ingé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
13
front/src/fetch.js
Normal 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
4
front/src/main.js
Normal file
@@ -0,0 +1,4 @@
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
|
||||
createApp(App).mount('#app')
|
||||
Reference in New Issue
Block a user