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 /songs(/@id)', 'findSong');
|
||||||
Flight::route('GET /albums(/@id)', 'findAlbum');
|
Flight::route('GET /albums(/@id)', 'findAlbum');
|
||||||
Flight::route('GET /artists(/@id)', 'findArtist');
|
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)
|
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();
|
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
|
class Database
|
||||||
{
|
{
|
||||||
private $host;
|
private $host;
|
||||||
private $user;
|
private $user;
|
||||||
private $pass;
|
private $pass;
|
||||||
private $dbname;
|
private $dbname;
|
||||||
private $pdo;
|
private $pdo;
|
||||||
|
|
||||||
public function __construct($host, $user, $pass, $dbname) {
|
public function __construct($host, $user, $pass, $dbname) {
|
||||||
$this->host = $host;
|
$this->host = $host;
|
||||||
@ -127,5 +127,32 @@ class MusicAPI
|
|||||||
return $stmt->fetchAll();
|
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]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
16
index.html
16
index.html
@ -1,11 +1,13 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Riot App</title>
|
<title>Riot App</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-neutral-50">
|
|
||||||
|
<body class="bg-neutral-50">
|
||||||
|
|
||||||
<onzer></onzer>
|
<onzer></onzer>
|
||||||
|
|
||||||
@ -16,16 +18,20 @@
|
|||||||
<script type="javascript" src="./onzer.riot"></script>
|
<script type="javascript" src="./onzer.riot"></script>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
function fetch_data(){
|
function fetch_data() {
|
||||||
return fetch("https://dwarves.iut-fbleau.fr/~fauvet/api/albums").then(response => {
|
return fetch("https://dwarves.iut-fbleau.fr/~fauvet/api/albums").then(response => {
|
||||||
return response.json();
|
return response.json();
|
||||||
} )
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
riot.compile().then(() => {
|
riot.compile().then(() => {
|
||||||
riot.mount('onzer', {items: fetch_data()});
|
riot.mount('onzer', { items: fetch_data() });
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
<script src="./navigation.riot" type="riot"></script>
|
||||||
|
<script src="./playlist-form.riot" type="riot"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
124
onzer.riot
124
onzer.riot
@ -14,35 +14,56 @@
|
|||||||
<input class="flex-grow-1 border-solid border bg-emerald-100 w-half rounded-lg border-emerald-300 border h-20 pl-6 grow"
|
<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 } />
|
placeholder={ state.placeholder } onkeyup={ edit } />
|
||||||
<input type="button" value="Playlists"
|
<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"/>
|
class="ml-2 border-solid bg-emerald-300 border rounded-lg border-emerald-600 mb-4 h-20 w-48 mt-2"/>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-wrap px-12 justify-between mt-8">
|
<div if={ state.items && state.items.length > 0 } 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">
|
<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"
|
||||||
<p> { album.name } </p>
|
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>
|
</div>
|
||||||
|
|
||||||
|
<div if={ !state.items || state.items.length === 0 } class="no-results">
|
||||||
|
<p>Aucun résultat trouvé.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="pagination">
|
<div class="pagination">
|
||||||
<button onclick={prevPage} disabled={state.page === 1}>Previous</button>
|
<button onclick={prevPage} disabled={state.page === 1}>Previous</button>
|
||||||
<span>Page {state.page} of {state.totalPages}</span>
|
<span>Page {state.page} of {state.totalPages}</span>
|
||||||
<button onclick={nextPage} disabled={state.page === state.totalPages}>Next</button>
|
<button onclick={nextPage} disabled={state.page === state.totalPages}>Next</button>
|
||||||
</div>
|
</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>
|
<script>
|
||||||
|
riot.compile().then(() => {
|
||||||
|
riot.mount('playlist-form');
|
||||||
|
})
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
async onBeforeMount(props){
|
async onBeforeMount(props) {
|
||||||
let data = await props.items;
|
let data = await props.items;
|
||||||
this.state = {
|
this.state = {
|
||||||
placeholder: "Rechercher dans les albums",
|
placeholder: "Rechercher dans les albums",
|
||||||
items: data.results,
|
items: data.results || [],
|
||||||
search: "albums",
|
search: "albums",
|
||||||
filter: undefined,
|
filter: undefined,
|
||||||
id: undefined,
|
id: undefined,
|
||||||
page: 1,
|
page: 1,
|
||||||
totalPages: Math.ceil(data.results.length / 9),
|
totalPages: Math.ceil((data.results || []).length / 9),
|
||||||
|
showModal: false,
|
||||||
};
|
};
|
||||||
this.paintButton();
|
this.paintButton();
|
||||||
this.album_style = "isActivate";
|
this.album_style = "isActivate";
|
||||||
@ -79,16 +100,29 @@
|
|||||||
},
|
},
|
||||||
async fetchData(){
|
async fetchData(){
|
||||||
let data = await this.execQuery(this.state.search, this.state.filter, this.state.id);
|
let data = await this.execQuery(this.state.search, this.state.filter, this.state.id);
|
||||||
this.state.items = data.results;
|
this.state.items = data.results || [];
|
||||||
this.state.totalPages = Math.ceil(data.results.length / 9);
|
this.state.totalPages = Math.ceil((data.results || []).length / 9);
|
||||||
this.update();
|
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(){
|
paintButton(){
|
||||||
this.album_style = "isDeactivate";
|
this.album_style = "isDeactivate";
|
||||||
this.artist_style = "isDeactivate";
|
this.artist_style = "isDeactivate";
|
||||||
this.song_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 baseHttpRequest = "https://dwarves.iut-fbleau.fr/~fauvet/api/";
|
||||||
let computeHttpRequest;
|
let computeHttpRequest;
|
||||||
if(filter !== undefined){
|
if(filter !== undefined){
|
||||||
@ -106,6 +140,19 @@
|
|||||||
}
|
}
|
||||||
return fetch(computeHttpRequest).then(response => response.json());
|
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() {
|
prevPage() {
|
||||||
if (this.state.page > 1) {
|
if (this.state.page > 1) {
|
||||||
this.state.page -= 1;
|
this.state.page -= 1;
|
||||||
@ -134,6 +181,9 @@
|
|||||||
border-color: #6EE7B7;
|
border-color: #6EE7B7;
|
||||||
width: 32%;
|
width: 32%;
|
||||||
}
|
}
|
||||||
|
.item[song] {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
.pagination {
|
.pagination {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -152,5 +202,59 @@
|
|||||||
background-color: #D1FAE5;
|
background-color: #D1FAE5;
|
||||||
cursor: not-allowed;
|
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>
|
</style>
|
||||||
</onzer>
|
</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