Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
@ -9,6 +9,7 @@ use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use App\Repository\FavorisRepository;
|
||||
use App\Entity\Favoris;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
|
||||
class APISearchController extends AbstractController
|
||||
{
|
||||
@ -31,27 +32,46 @@ class APISearchController extends AbstractController
|
||||
}
|
||||
|
||||
#[Route('/toggleLike/{idGoogle}', name: 'like', methods: "POST")]
|
||||
public function addFavoris(FavorisRepository $favorisRepository, String $idGoogle)
|
||||
public function addFavoris(Request $request, FavorisRepository $favorisRepository, String $idGoogle)
|
||||
{
|
||||
$content = $request->getContent();
|
||||
$data = json_decode($content, true);
|
||||
|
||||
if (json_last_error() !== JSON_ERROR_NONE || empty($data)) {
|
||||
return new JsonResponse(['status' => 'error', 'message' => 'Invalid data'], 400);
|
||||
}
|
||||
|
||||
$title = $data['title'] ?? '';
|
||||
$authors = $data['authors'] ?? '';
|
||||
$images = $data['images'] ?? '';
|
||||
$description = $data['description'] ?? '';
|
||||
$date = $data['date'] ?? '';
|
||||
$pages = $data['pages'] ?? '';
|
||||
|
||||
$favoris = new Favoris();
|
||||
$user = $this->getUser();
|
||||
$favoris->setUser($user);
|
||||
$favoris->setIdGoogle($idGoogle);
|
||||
$favoris->setTitle($title);
|
||||
$favoris->setAuthors($authors);
|
||||
$favoris->setImage($images);
|
||||
$favoris->setDescription($description);
|
||||
$favoris->setPublication($date);
|
||||
$favoris->setPages($pages);
|
||||
$favoris->setPublication($date);
|
||||
|
||||
|
||||
$favorisRepository->addFavoris($favoris);
|
||||
return $this->json(['success' => true, 'message' => 'Favoris ajouté']);
|
||||
return $this->json(['success' => true, 'message' => 'Favoris ajouté', "status" => "added"]);
|
||||
}
|
||||
|
||||
#[Route('/untoggleLike/{idGoogle}', name: 'unlike', methods: "POST")]
|
||||
public function removeFavoris(FavorisRepository $favorisRepository, String $idGoogle)
|
||||
{
|
||||
$favoris = new Favoris();
|
||||
$user = $this->getUser();
|
||||
$favoris->setUser($user);
|
||||
$favoris->setIdGoogle($idGoogle);
|
||||
$favorisRepository->removeFavoris($user, $idGoogle);
|
||||
|
||||
return $this->json(['success' => true, 'message' => 'Favoris supprimé']);
|
||||
return $this->json(['success' => true, 'message' => 'Favoris supprimé', "status" => "removed"]);
|
||||
}
|
||||
|
||||
#[Route('/api/search', name: 'api_search')]
|
||||
|
@ -22,10 +22,8 @@ class FavorisController extends AbstractController
|
||||
public function index(FavorisRepository $favorisRepository): Response
|
||||
{
|
||||
$favorisUser = $favorisRepository->findBy(['user' => $this->getUser()]);
|
||||
foreach ($favorisUser as $favori) {
|
||||
array_push($this->favorisResult, $this->googleBooksService->searchBooks($favori->getIdGoogle(), 'fr', 0));
|
||||
|
||||
}
|
||||
ini_set('memory_limit', '512M');
|
||||
array_push($this->favorisResult, $favorisRepository->getFavorisByUser($this->getUser()));
|
||||
return $this->render('favoris/index.html.twig', [
|
||||
'controller_name' => 'FavorisController',
|
||||
'datas' => $this->favorisResult,
|
||||
|
@ -19,6 +19,30 @@ class Favoris
|
||||
#[ORM\ManyToOne(inversedBy: 'favoris')]
|
||||
private ?User $user = null;
|
||||
|
||||
#[ORM\Column(length: 255)]
|
||||
private ?string $title = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $authors = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $edition = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $publication = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $categorie = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $pages = null;
|
||||
|
||||
#[ORM\Column(length: 2555, nullable: true)]
|
||||
private ?string $description = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $image = null;
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
@ -47,4 +71,100 @@ class Favoris
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getTitle(): ?string
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
public function setTitle(string $title): static
|
||||
{
|
||||
$this->title = $title;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAuthors(): ?string
|
||||
{
|
||||
return $this->authors;
|
||||
}
|
||||
|
||||
public function setAuthors(?string $authors): static
|
||||
{
|
||||
$this->authors = $authors;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getEdition(): ?string
|
||||
{
|
||||
return $this->edition;
|
||||
}
|
||||
|
||||
public function setEdition(?string $edition): static
|
||||
{
|
||||
$this->edition = $edition;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPublication(): ?string
|
||||
{
|
||||
return $this->publication;
|
||||
}
|
||||
|
||||
public function setPublication(?string $publication): static
|
||||
{
|
||||
$this->publication = $publication;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCategorie(): ?string
|
||||
{
|
||||
return $this->categorie;
|
||||
}
|
||||
|
||||
public function setCategorie(?string $categorie): static
|
||||
{
|
||||
$this->categorie = $categorie;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPages(): ?string
|
||||
{
|
||||
return $this->pages;
|
||||
}
|
||||
|
||||
public function setPages(?string $pages): static
|
||||
{
|
||||
$this->pages = $pages;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDescription(): ?string
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function setDescription(string $description): static
|
||||
{
|
||||
$this->description = $description;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getImage(): ?string
|
||||
{
|
||||
return $this->image;
|
||||
}
|
||||
|
||||
public function setImage(?string $image): static
|
||||
{
|
||||
$this->image = $image;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
@ -71,17 +71,25 @@
|
||||
{% set isLiked = book.id in favoris|map(f => f.getIdGoogle()) %}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewbox="0 0 24 24"
|
||||
fill="{{ isLiked ? 'red' : 'none' }}"
|
||||
stroke="{{ isLiked ? 'red' : 'currentColor' }}"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="absolute top-2 right-2 w-6 h-6 cursor-pointer transition-colors duration-300"
|
||||
x-data="{ liked: {{ isLiked ? 'true' : 'false' }} }"
|
||||
:fill="liked ? 'red' : 'none'"
|
||||
:stroke="liked ? 'red' : 'currentColor'"
|
||||
@click="toggleLike('{{ book.id }}', liked, $el); liked = !liked">
|
||||
class="like-button absolute top-2 right-2 w-6 h-6 cursor-pointer transition-colors duration-300"
|
||||
data-id-google="{{ book.id }}"
|
||||
data-liked="{{ isLiked ? 'true' : 'false' }}"
|
||||
data-title="{{ book.volumeInfo.title | default('Titre non disponible') }}"
|
||||
data-authors="{{ book.volumeInfo.authors is defined ? book.volumeInfo.authors | join(', ') : '' }}"
|
||||
data-images="{{ book.volumeInfo.imageLinks.smallThumbnail is defined ? book.volumeInfo.imageLinks.smallThumbnail : '' }}"
|
||||
data-description="{{ book.volumeInfo.description | raw | default('Description non disponible') }}"
|
||||
data-date="{{ book.volumeInfo.publishedDate | default('Date non disponible') }}"
|
||||
data-pages="{{ book.volumeInfo.pageCount | default('0') }}">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12Z"/>
|
||||
</svg>
|
||||
</svg>
|
||||
|
||||
|
||||
|
||||
{% endif %}
|
||||
|
||||
|
||||
@ -181,47 +189,51 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function toggleLike(idGoogle, liked, element) {
|
||||
if (liked) {
|
||||
fetch("{{ path('unlike', {'idGoogle': 'PLACEHOLDER'}) }}".replace('PLACEHOLDER', idGoogle), {
|
||||
function toggleLike(idGoogle, liked, element, bookDetails) {
|
||||
const url = liked
|
||||
? "{{ path('unlike', {'idGoogle': 'PLACEHOLDER'}) }}".replace('PLACEHOLDER', idGoogle)
|
||||
: "{{ path('like', {'idGoogle': 'PLACEHOLDER'}) }}".replace('PLACEHOLDER', idGoogle);
|
||||
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
},
|
||||
body: JSON.stringify({})
|
||||
}).then(response => response.json()).then(data => {
|
||||
if (data.status === 'removed') {
|
||||
console.log('Livre retiré des favoris');
|
||||
body: JSON.stringify(bookDetails)
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if ((liked && data.status === 'removed') || (!liked && data.status === 'added')) {
|
||||
// Mettre à jour l'état visuel
|
||||
element.setAttribute('x-data', '{ liked: false }');
|
||||
element.querySelector('path').setAttribute('fill', 'none');
|
||||
element.querySelector('path').setAttribute('stroke', 'currentColor');
|
||||
const newLikedState = !liked;
|
||||
element.setAttribute('data-liked', newLikedState.toString());
|
||||
element.querySelector('path').setAttribute('fill', newLikedState ? 'red' : 'none');
|
||||
element.querySelector('path').setAttribute('stroke', newLikedState ? 'red' : 'currentColor');
|
||||
}
|
||||
}).catch(error => {
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Erreur AJAX', error);
|
||||
});
|
||||
} else {
|
||||
fetch("{{ path('like', {'idGoogle': 'PLACEHOLDER'}) }}".replace('PLACEHOLDER', idGoogle), {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
},
|
||||
body: JSON.stringify({})
|
||||
}).then(response => response.json()).then(data => {
|
||||
if (data.status === 'added') {
|
||||
console.log('Livre ajouté aux favoris');
|
||||
// Mettre à jour l'état visuel
|
||||
element.setAttribute('x-data', '{ liked: true }');
|
||||
element.querySelector('path').setAttribute('fill', 'red');
|
||||
element.querySelector('path').setAttribute('stroke', 'red');
|
||||
}
|
||||
}).catch(error => {
|
||||
console.error('Erreur AJAX', error);
|
||||
}
|
||||
|
||||
document.querySelectorAll('.like-button').forEach(button => {
|
||||
button.addEventListener('click', function() {
|
||||
const idGoogle = this.dataset.idGoogle;
|
||||
const liked = this.getAttribute('data-liked') === 'true'; // Lire l'état actuel
|
||||
const bookDetails = {
|
||||
title: this.dataset.title,
|
||||
authors: this.dataset.authors,
|
||||
images: this.dataset.images,
|
||||
description: this.dataset.description,
|
||||
date: this.dataset.date,
|
||||
pages: this.dataset.pages
|
||||
};
|
||||
|
||||
toggleLike(idGoogle, liked, this, bookDetails);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
{% for book in datas.items %}
|
||||
const openModalBtn{{ loop.index }} = document.getElementById('openModalBtn-{{ loop.index }}');
|
||||
|
@ -3,17 +3,9 @@
|
||||
{% block title %}Mes favoris{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div>
|
||||
{% for data in datas %}
|
||||
{% if data.items is defined %}
|
||||
{% for book in data.items %}
|
||||
{% if book.volumeInfo.authors is defined %}
|
||||
<p>{{ book.volumeInfo.title }} - {{ book.volumeInfo.authors | join(", ") }} </p>
|
||||
{% endif %}
|
||||
|
||||
{% for data in datas %}
|
||||
{% for book in data %}
|
||||
<p>{{ book.title }}</p>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
Reference in New Issue
Block a user