modal de creation de livre

This commit is contained in:
Guamss 2025-12-14 15:53:19 +01:00
parent cbc02ce5cc
commit 41ea3ef924
4 changed files with 162 additions and 11 deletions

View File

@ -48,6 +48,7 @@ import { convertState } from '@/utils';
display: flex; display: flex;
align-items: center; align-items: center;
flex-direction: column; flex-direction: column;
margin-top: auto;
} }
.state-indicator { .state-indicator {
@ -64,8 +65,10 @@ import { convertState } from '@/utils';
} }
.card { .card {
display: flex;
flex-direction: column;
max-width: 300px; max-width: 300px;
min-width: 300px;; min-width: 300px;
border-radius: 0.5rem; border-radius: 0.5rem;
background-color: light-dark(#efedea, #282828); background-color: light-dark(#efedea, #282828);
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
@ -77,7 +80,11 @@ import { convertState } from '@/utils';
} }
.content { .content {
display: flex;
flex-direction: column;
padding: 1.1rem; padding: 1.1rem;
flex-grow: 1;
height: 100%;
} }
.title { .title {

View File

@ -1,8 +1,102 @@
<script lang="ts"> <script setup lang="ts">
const props = defineProps<{ isActive: boolean }>();
const emit = defineEmits(['closeBookFormModal'])
function sendBookData() {
console.log("PROUT")
emit('closeBookFormModal')
}
</script> </script>
<template> <template>
<div :class="props.isActive ? 'opened-modal' : 'closed-modal'">
<div class="overlay"></div>
<div class="modale card">
<button class="btn-close" @click="$emit('closeBookFormModal')">X</button>
<h2>COUCOU</h2>
<div class="actions">
<button class="send" @keyup.enter="sendBookData" @click="sendBookData">prout</button>
</div>
</div>
</div>
</template> </template>
<style> <style scoped>
.opened-modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.closed-modal {
display: none;
}
.overlay {
background-color: rgba(0, 0, 0, 0.7);
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
}
.modale {
position: relative;
z-index: 2;
background-color: light-dark(#ffffff, #282828);
padding: 30px;
border-radius: 10px;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5);
min-width: 300px;
max-width: 500px;
display: flex;
flex-direction: column;
gap: 15px;
}
.btn-close {
position: absolute;
top: 10px;
right: 10px;
background: none;
border: none;
cursor: pointer;
font-size: 1.2rem;
color: light-dark(#868686, #999999);
}
.btn-close:hover {
transition: 0.3s;
color: light-dark(black, white);
}
.actions {
display: flex;
justify-content: flex-end;
}
.send {
padding: 10px 20px;
background-color: #1e90ff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-weight: bold;
}
.send:hover {
transition: 0.3s;
background-color: #176cc0;
}
</style> </style>

View File

@ -5,8 +5,10 @@ import { router } from './routes'
import 'vue-toast-notification/dist/theme-sugar.css' import 'vue-toast-notification/dist/theme-sugar.css'
import { library } from "@fortawesome/fontawesome-svg-core"; import { library } from "@fortawesome/fontawesome-svg-core";
import { faArrowRightFromBracket } from "@fortawesome/free-solid-svg-icons"; import { faArrowRightFromBracket } from "@fortawesome/free-solid-svg-icons";
import { faPlus } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
library.add(faArrowRightFromBracket); library.add(faArrowRightFromBracket);
library.add(faPlus);
createApp(App).use(router).use(ToastPlugin).component("font-awesome-icon", FontAwesomeIcon).mount('#app') createApp(App).use(router).use(ToastPlugin).component("font-awesome-icon", FontAwesomeIcon).mount('#app')

View File

@ -3,9 +3,15 @@ import type { Book } from "@/models/book";
import { BookService } from "@/services/book.service"; import { BookService } from "@/services/book.service";
import { onMounted, ref } from "vue"; import { onMounted, ref } from "vue";
import BookCard from "@/components/BookCard.vue"; import BookCard from "@/components/BookCard.vue";
import CreateBookForm from "@/components/CreateBookForm.vue";
const books = ref<Book[]>([]); const books = ref<Book[]>([]);
const bookService = new BookService(); const bookService = new BookService();
const isCreatingBookFormOpened = ref<boolean>(false);
function closeBookFormModal() {
isCreatingBookFormOpened.value = false;
}
onMounted(async () => { onMounted(async () => {
books.value = await bookService.findBooks(); books.value = await bookService.findBooks();
@ -13,6 +19,7 @@ onMounted(async () => {
books.value.map((book) => { books.value.map((book) => {
book.added_at = new Date(book.added_at); book.added_at = new Date(book.added_at);
}); });
books.value.sort((a, b) => { books.value.sort((a, b) => {
if (a.updated_at > b.updated_at) { if (a.updated_at > b.updated_at) {
return -1; return -1;
@ -20,21 +27,52 @@ onMounted(async () => {
return 1; return 1;
} }
return 0; return 0;
}) });
}); });
</script> </script>
<template> <template>
<CreateBookForm
:is-active="isCreatingBookFormOpened"
@close-book-form-modal="closeBookFormModal"
/>
<main class="cards"> <main class="cards">
<BookCard v-for="book in books" <BookCard v-for="book in books" :book="book" :key="book.id" class="card" />
:book="book"
:key="book.id"
class="card"/>
</main> </main>
<div class="add-button-container">
<button @click="isCreatingBookFormOpened = true" class="add-button">
<h3><font-awesome-icon icon="fa-plus" /> Ajouter un livre</h3>
</button>
</div>
</template> </template>
<style scoped> <style scoped>
.add-button-container {
position: fixed;
bottom: 0;
left: 0;
right: 0;
margin-left: 2em;
margin-bottom: 2em;
}
.add-button {
padding-right: 1em;
padding-left: 1em;
background-color: #1e90ff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-weight: bold;
}
.add-button:hover {
transition: 0.3s;
background-color: #176cc0;
}
.cards { .cards {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
@ -51,16 +89,26 @@ onMounted(async () => {
font-weight: 500; font-weight: 500;
align-items: center; align-items: center;
gap: 0.25rem; gap: 0.25rem;
background-color: #2563EB; background-color: #2563eb;
padding: 4px 8px; padding: 4px 8px;
border-radius: 4px; border-radius: 4px;
} }
.action span { .action span {
transition: .3s ease; transition: 0.3s ease;
} }
.action:hover span { .action:hover span {
transform: translateX(4px); transform: translateX(4px);
} }
@media (max-width: 820px) {
.add-button-container {
margin-left: 0;
display: flex;
align-items: center;
justify-content: center;
}
}
</style> </style>