Debut gestion playlist dans api + creation playlist front
This commit is contained in:
parent
35a6e4266f
commit
286e660f63
41
api/index.php
Normal file → Executable file
41
api/index.php
Normal file → Executable file
@ -8,6 +8,9 @@ MusicAPI::init();
|
||||
Flight::route('GET /songs(/@id)', 'findSong');
|
||||
Flight::route('GET /albums(/@id)', 'findAlbum');
|
||||
Flight::route('GET /artists(/@id)', 'findArtist');
|
||||
Flight::route('GET /playlists(/@id)', 'findPlaylist');
|
||||
Flight::route('POST /playlists', 'createPlaylist');
|
||||
Flight::route('DELETE /playlists/@id', 'deletePlaylist');
|
||||
|
||||
function findSong($id = null)
|
||||
{
|
||||
@ -74,6 +77,44 @@ function findArtist($id = null)
|
||||
}
|
||||
}
|
||||
|
||||
function findPlaylist($id = null)
|
||||
{
|
||||
if ($id === null) {
|
||||
$res = MusicAPI::findAllPlaylists();
|
||||
Flight::json(["results" => $res]);
|
||||
} else {
|
||||
$res = MusicAPI::findPlaylistById($id);
|
||||
if ($res) {
|
||||
Flight::json($res);
|
||||
} else {
|
||||
Flight::halt(404);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createPlaylist()
|
||||
{
|
||||
$data = Flight::request()->data;
|
||||
$name = $data->name ?? null;
|
||||
|
||||
if ($name) {
|
||||
$id = MusicAPI::createPlaylist($name);
|
||||
Flight::json(["id" => $id], 201);
|
||||
} else {
|
||||
Flight::halt(400, "Missing name parameter");
|
||||
}
|
||||
}
|
||||
|
||||
function deletePlaylist($id)
|
||||
{
|
||||
$res = MusicAPI::deletePlaylist($id);
|
||||
if ($res) {
|
||||
Flight::json(["status" => "success"]);
|
||||
} else {
|
||||
Flight::halt(404);
|
||||
}
|
||||
}
|
||||
|
||||
Flight::start();
|
||||
|
||||
?>
|
||||
|
33
api/model/model.php
Normal file → Executable file
33
api/model/model.php
Normal file → Executable file
@ -3,10 +3,10 @@
|
||||
class Database
|
||||
{
|
||||
private $host;
|
||||
private $user;
|
||||
private $pass;
|
||||
private $user;
|
||||
private $pass;
|
||||
private $dbname;
|
||||
private $pdo;
|
||||
private $pdo;
|
||||
|
||||
public function __construct($host, $user, $pass, $dbname) {
|
||||
$this->host = $host;
|
||||
@ -127,5 +127,32 @@ class MusicAPI
|
||||
return $stmt->fetchAll();
|
||||
}
|
||||
|
||||
// Fonctions gestion des playlists
|
||||
public static function findAllPlaylists()
|
||||
{
|
||||
$sql = "SELECT * FROM Playlist;";
|
||||
$stmt = self::$db->query($sql);
|
||||
return $stmt->fetchAll();
|
||||
}
|
||||
|
||||
public static function findPlaylistById($id)
|
||||
{
|
||||
$sql = "SELECT * FROM Playlist WHERE Playlist.id=?;";
|
||||
$stmt = self::$db->query($sql, [$id]);
|
||||
return $stmt->fetchAll();
|
||||
}
|
||||
|
||||
public static function createPlaylist($name)
|
||||
{
|
||||
$sql = "INSERT INTO Playlist (name) VALUES (?);";
|
||||
self::$db->query($sql, [$name]);
|
||||
return self::$db->lastInsertId();
|
||||
}
|
||||
|
||||
public static function deletePlaylist($id)
|
||||
{
|
||||
$sql = "DELETE FROM Playlist WHERE id=?;";
|
||||
return self::$db->query($sql, [$id]);
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
18
index.html
18
index.html
@ -1,11 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Riot App</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
</head>
|
||||
<body class="bg-neutral-50">
|
||||
|
||||
<body class="bg-neutral-50">
|
||||
|
||||
<onzer></onzer>
|
||||
|
||||
@ -16,16 +18,20 @@
|
||||
<script type="javascript" src="./onzer.riot"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
function fetch_data(){
|
||||
function fetch_data() {
|
||||
return fetch("https://dwarves.iut-fbleau.fr/~fauvet/api/albums").then(response => {
|
||||
return response.json();
|
||||
} )
|
||||
})
|
||||
}
|
||||
|
||||
riot.compile().then(() => {
|
||||
riot.mount('onzer', {items: fetch_data()});
|
||||
riot.mount('onzer', { items: fetch_data() });
|
||||
})
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
<script src="./navigation.riot" type="riot"></script>
|
||||
<script src="./playlist-form.riot" type="riot"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
126
onzer.riot
126
onzer.riot
@ -13,36 +13,57 @@
|
||||
<div class="flex flex-row items-baseline">
|
||||
<input class="flex-grow-1 border-solid border bg-emerald-100 w-half rounded-lg border-emerald-300 border h-20 pl-6 grow"
|
||||
placeholder={ state.placeholder } onkeyup={ edit } />
|
||||
<input type="button" value="Playlists"
|
||||
class="ml-2 border-solid bg-emerald-300 border rounded-lg border-emerald-600 mb-4 h-20 w-48 mt-2"/>
|
||||
<input type="button" value="Playlists"
|
||||
class="ml-2 border-solid bg-emerald-300 border rounded-lg border-emerald-600 mb-4 h-20 w-48 mt-2"/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap px-12 justify-between mt-8">
|
||||
<div each={ album in state.items.slice((state.page - 1) * 9, state.page * 9) } class="item mb-4 border border-solid rounded-lg h-64 flex justify-center items-center">
|
||||
<p> { album.name } </p>
|
||||
<div if={ state.items && state.items.length > 0 } class="flex flex-wrap px-12 justify-between mt-8">
|
||||
<div each={ item in state.items.slice((state.page - 1) * 9, state.page * 9) } class="item mb-4 border border-solid rounded-lg h-64 flex justify-center items-center"
|
||||
style={ state.search === 'songs' ? 'width: 100%;' : '' }>
|
||||
<div class="text-center">
|
||||
<p>{ item.name }</p>
|
||||
<button if={ state.search === 'songs' } onclick={ () => addSong(item) } class="add-button">Ajouter</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div if={ !state.items || state.items.length === 0 } class="no-results">
|
||||
<p>Aucun résultat trouvé.</p>
|
||||
</div>
|
||||
|
||||
<div class="pagination">
|
||||
<button onclick={prevPage} disabled={state.page === 1}>Previous</button>
|
||||
<span>Page {state.page} of {state.totalPages}</span>
|
||||
<button onclick={nextPage} disabled={state.page === state.totalPages}>Next</button>
|
||||
</div>
|
||||
|
||||
<!-- Modal pour le formulaire de création de playlist -->
|
||||
<div class="modal" if={ state.showModal }>
|
||||
<div class="modal-content">
|
||||
<span class="close" onclick={ closeModal }>×</span>
|
||||
<playlist-form></playlist-form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
riot.compile().then(() => {
|
||||
riot.mount('playlist-form');
|
||||
})
|
||||
|
||||
export default {
|
||||
async onBeforeMount(props){
|
||||
async onBeforeMount(props) {
|
||||
let data = await props.items;
|
||||
this.state = {
|
||||
placeholder: "Rechercher dans les albums",
|
||||
items: data.results,
|
||||
items: data.results || [],
|
||||
search: "albums",
|
||||
filter: undefined,
|
||||
id: undefined,
|
||||
page: 1,
|
||||
totalPages: Math.ceil(data.results.length / 9),
|
||||
totalPages: Math.ceil((data.results || []).length / 9),
|
||||
showModal: false,
|
||||
};
|
||||
this.paintButton();
|
||||
this.album_style = "isActivate";
|
||||
@ -79,16 +100,29 @@
|
||||
},
|
||||
async fetchData(){
|
||||
let data = await this.execQuery(this.state.search, this.state.filter, this.state.id);
|
||||
this.state.items = data.results;
|
||||
this.state.totalPages = Math.ceil(data.results.length / 9);
|
||||
this.state.items = data.results || [];
|
||||
this.state.totalPages = Math.ceil((data.results || []).length / 9);
|
||||
this.update();
|
||||
},
|
||||
async fetchPlaylists() {
|
||||
try {
|
||||
const response = await fetch('https://dwarves.iut-fbleau.fr/~fauvet/api/playlists');
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok');
|
||||
}
|
||||
const data = await response.json();
|
||||
console.log('Playlists:', data);
|
||||
// Utilisez les données des playlists comme nécessaire ici
|
||||
} catch (error) {
|
||||
console.error('Error fetching playlists:', error);
|
||||
}
|
||||
},
|
||||
paintButton(){
|
||||
this.album_style = "isDeactivate";
|
||||
this.artist_style = "isDeactivate";
|
||||
this.song_style = "isDeactivate";
|
||||
},
|
||||
execQuery(table, filter = undefined, id = undefined){
|
||||
execQuery(table, filter = undefined, id = undefined){
|
||||
let baseHttpRequest = "https://dwarves.iut-fbleau.fr/~fauvet/api/";
|
||||
let computeHttpRequest;
|
||||
if(filter !== undefined){
|
||||
@ -105,6 +139,19 @@
|
||||
computeHttpRequest = baseHttpRequest + table;
|
||||
}
|
||||
return fetch(computeHttpRequest).then(response => response.json());
|
||||
},
|
||||
openModal() {
|
||||
this.state.showModal = true;
|
||||
this.update();
|
||||
},
|
||||
closeModal() {
|
||||
this.state.showModal = false;
|
||||
this.update();
|
||||
},
|
||||
addSong(item) {
|
||||
console.log("Ajouter le titre:", item);
|
||||
// Ajoutez ici le code pour gérer l'ajout du titre à une playlist ou une autre action
|
||||
this.openModal(); // Appel à openModal pour ouvrir le modal
|
||||
},
|
||||
prevPage() {
|
||||
if (this.state.page > 1) {
|
||||
@ -134,6 +181,9 @@
|
||||
border-color: #6EE7B7;
|
||||
width: 32%;
|
||||
}
|
||||
.item[song] {
|
||||
width: 100%;
|
||||
}
|
||||
.pagination {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
@ -152,5 +202,59 @@
|
||||
background-color: #D1FAE5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.add-button {
|
||||
background-color: #34D399;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
padding: 8px 16px;
|
||||
margin-top: 8px;
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
}
|
||||
.no-results {
|
||||
text-align: center;
|
||||
margin-top: 16px;
|
||||
font-size: 18px;
|
||||
color: #6B7280;
|
||||
}
|
||||
|
||||
/* Modal */
|
||||
.modal {
|
||||
/*display: none; /* Par défaut, le modal est caché */
|
||||
position: fixed;
|
||||
z-index: 10;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
background-color: rgba(0,0,0,0.4); /* Fond semi-transparent pour le modal */
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
background-color: #fefefe;
|
||||
margin: 10% auto; /* Centre le modal à l'écran */
|
||||
padding: 20px;
|
||||
border: 1px solid #888;
|
||||
width: 80%;
|
||||
max-width: 600px;
|
||||
border-radius: 8px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.close {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.close:hover,
|
||||
.close:focus {
|
||||
color: #000;
|
||||
}
|
||||
</style>
|
||||
</onzer>
|
||||
|
63
playlist-form.riot
Normal file
63
playlist-form.riot
Normal file
@ -0,0 +1,63 @@
|
||||
<playlist-form>
|
||||
<form onsubmit={handleSubmit}>
|
||||
<label for="playlist-name">Nom de la playlist</label>
|
||||
<input type="text" id="playlist-name" name="playlist-name"/>
|
||||
|
||||
<button>Créer la playlist</button>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
this.handleSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
const formData = new FormData(event.target);
|
||||
const playlistName = formData.get('playlist-name');
|
||||
|
||||
try {
|
||||
const response = await fetch('https://dwarves.iut-fbleau.fr/~fauvet/api/playlists', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({name: playlistName})
|
||||
});
|
||||
|
||||
if(!response.ok) {
|
||||
throw new Error('Erreur lors de la création de la playlist');
|
||||
}
|
||||
|
||||
event.target.reset();
|
||||
alert('Playlist créée avec succès !');
|
||||
} catch(error) {
|
||||
console.error('Erreur : ', error);
|
||||
alert('Une erreur est survenue lors de la création de la playlist');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-width: 300px;
|
||||
margin: 20px auto;
|
||||
z-index: 15;
|
||||
}
|
||||
|
||||
label, input {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 10px;
|
||||
background-color: #6EE7B7;
|
||||
border: none;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #059669;
|
||||
}
|
||||
</style>
|
||||
</playlist-form>
|
Loading…
Reference in New Issue
Block a user