diff --git a/docker-compose.yml b/docker-compose.yaml similarity index 72% rename from docker-compose.yml rename to docker-compose.yaml index f2bc69acb6bece698c80c41de0936eaeacb8b0a2..629c548b5492cd2aaa71a286b7158e02824a023b 100644 --- a/docker-compose.yml +++ b/docker-compose.yaml @@ -1,21 +1,23 @@ -version: '1.0' +version: '3.9' services: - web: + php-app-web: build: . ports: - 8080:80 - hostname: web-tubes-1 + hostname: tubes-php-app env_file: .env volumes: - ./src:/var/www/html depends_on: - - db - db: + - php-app-db + php-app-db: image: mysql:latest restart: always ports: - 3308:3307 - hostname: db-tubes-1 + expose: + - 3307 + hostname: tubes-php-db env_file: .env volumes: - ./src/app/database/mysql:/docker-entrypoint-initdb.d/:ro diff --git a/scripts/build-image.sh b/scripts/build-image.sh deleted file mode 100644 index ce096bac1ad2e7c6eec731197a2b126c245fa237..0000000000000000000000000000000000000000 --- a/scripts/build-image.sh +++ /dev/null @@ -1 +0,0 @@ -docker build -t tubes-1:latest . \ No newline at end of file diff --git a/src/app/components/library/playlist.php b/src/app/components/library/playlist.php index 1e9f64e74925fed71245ea08a2a5389f7e1e938f..1f5c858f1f45840c9dc70e6e84f835ccc4c7384f 100644 --- a/src/app/components/library/playlist.php +++ b/src/app/components/library/playlist.php @@ -15,6 +15,6 @@ </div> <?php else : ?> <h5> - no results found. + you don't have any playlist. </h5> <?php endif;?> \ No newline at end of file diff --git a/src/app/components/playlist/playlist.php b/src/app/components/playlist/playlist.php index be04d8bcea14396ad6ab79b23fecdc167732ef36..a4dd9e9a1ddbb6704d86f52b378d9b9d672a8ff2 100644 --- a/src/app/components/playlist/playlist.php +++ b/src/app/components/playlist/playlist.php @@ -7,6 +7,8 @@ <link rel="stylesheet" type="text/css" href="<?= BASE_URL ?>/styles/globals.css"> <!-- Page-specific CSS --> <link rel="stylesheet" type="text/css" href="<?= BASE_URL ?>/styles/library/library.css"> + <script type="module" src="<?= BASE_URL ?>/javascript/library/library.js" defer> </script> + <title>Playlist</title> </head> <body> @@ -15,7 +17,7 @@ <main> - <div class="playlist-container"> + <div class="playlist-container" data-id="<?=$_GET["playlist_id"]?>"> <?php include(dirname(__DIR__) . "/playlist/playlist_content.php")?> </div> </main> diff --git a/src/app/components/playlist/playlist_content.php b/src/app/components/playlist/playlist_content.php index fb216c4ba37de95941bb3c829e69c30ff3fb0adb..375f8971528e2ef88758f125e0438ceadf455043 100644 --- a/src/app/components/playlist/playlist_content.php +++ b/src/app/components/playlist/playlist_content.php @@ -1,4 +1,5 @@ <link rel="stylesheet" type="text/css" href="<?= BASE_URL ?>/styles/library/library.css"> +<link href='https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css' rel='stylesheet'> <?php if (!empty($this->data)): ?> <div class="user-playlist"> @@ -10,6 +11,7 @@ <div class="info"> <div class="sh5"><?=$podcast['title']?> </div> </div> + <i class='bx bx-trash' data-id="<?=$podcast["id_podcast"]?>"></i> </div> <?php endforeach; ?> </div> @@ -17,4 +19,6 @@ <h5> your playlist is empty. </h5> -<?php endif;?> \ No newline at end of file +<?php endif;?> + +<script type="module" src="<?= BASE_URL ?>/javascript/library/library.js" defer> </script> diff --git a/src/app/components/podcast/page.php b/src/app/components/podcast/page.php index af5c57c113ed9d0bd8feed01e6bd3db2ea15ad95..1c127e60e244cafef64c2fba7f66a789fa82e800 100644 --- a/src/app/components/podcast/page.php +++ b/src/app/components/podcast/page.php @@ -7,7 +7,7 @@ <link rel="stylesheet" type="text/css" href="<?= BASE_URL ?>/styles/globals.css"> <link rel="stylesheet" type="text/css" href="<?= BASE_URL ?>/styles/podcast/style.css"> - <script type="text/javascript" src="<?= BASE_URL ?>/javascript/podcast/script.js" defer> + <script type="module" src="<?= BASE_URL ?>/javascript/podcast/script.js" defer> </script> <title>Main Dashboard</title> </head> @@ -38,11 +38,13 @@ <p>Add To Library</p> </button> - <ul id="library-choices" class="hidden"> + <ul id="library-choices" class="hidden" data-id-podcast="<?=$this->data["podcast"]->id_podcast ?>"> <?php foreach ($this->data["libraries"] as $library) : ?> <!-- Ini sekarang pake li tapi ntar kalo mau diganti jadi button atau a bisa juga --> <li> - <p class="b3"><?= $library ?></p> + <p class="b3 playlist" + data-id="<?= $library->id_playlist?>"> + <?= $library->title ?></p> </li> <?php endforeach; ?> </ul> diff --git a/src/app/controllers/episode/post_play_episode.php b/src/app/controllers/episode/post_play_episode.php new file mode 100644 index 0000000000000000000000000000000000000000..f21f6d8510396ceeb4af08ffb60a8be398dab569 --- /dev/null +++ b/src/app/controllers/episode/post_play_episode.php @@ -0,0 +1,31 @@ +<?php + +class PostPlayEpisodeController +{ + public function call() + { + session_start(); + if (!isset($_SESSION["user_id"])) { + http_response_code(403); + header("Content-Type: application/json"); + echo json_encode(["message" => "unauthorized"]); + + return; + } + + // Check for podcast id + if (!isset($_POST["idEpisode"])) { + http_response_code(400); + header("Content-Type: application/json"); + echo json_encode(["message" => "missing episode id"]); + + return; + } + + $_SESSION["eps_id"] = $_POST["idEpisode"]; + + http_response_code(200); + header("Content-Type: application/json"); + echo json_encode(["message" => "success"]); + } +} diff --git a/src/app/controllers/library/get_library.php b/src/app/controllers/library/get_library.php index 60363e8d741fdfd0a1be1940f788008038f3dc4d..466cbab67861b0b6ce3f27e2e0967f6cb9d87dfe 100644 --- a/src/app/controllers/library/get_library.php +++ b/src/app/controllers/library/get_library.php @@ -5,7 +5,6 @@ class GetLibraryController public function call() { require_once __DIR__ . "/../../views/library/library_view.php"; - require_once __DIR__ . "/../../models/playlist.php"; $data = []; session_start(); @@ -22,7 +21,7 @@ class GetLibraryController $view = new LibraryView($data); $view->render(); }else{ - header("Location: "); + header("Location: " . BASE_URL . "/login"); } } diff --git a/src/app/controllers/login/get_login.php b/src/app/controllers/login/get_login.php index f1f7fd41aa629ddb6506166a96347d54cd1ee8a9..44627b028f597b1a2d46150bb2d66b8a45b41171 100644 --- a/src/app/controllers/login/get_login.php +++ b/src/app/controllers/login/get_login.php @@ -10,7 +10,8 @@ class GetLoginController if(isset($_SESSION['user_id'])){ - header("Location: http://localhost:8080/public/home?user_id=" . $_SESSION['user_id']); + header("Location: " . BASE_URL . "/home?user_id=" . $_SESSION["user_id"]); + }else{ $data = []; $view = new LoginView($data); diff --git a/src/app/controllers/login/post_login.php b/src/app/controllers/login/post_login.php index 1d1dbb1a70c84628dc63aae0e065cf7eb2aed394..b063c411299f144c64efe2be5c6f90fba8f6a25b 100644 --- a/src/app/controllers/login/post_login.php +++ b/src/app/controllers/login/post_login.php @@ -4,8 +4,7 @@ class PostLoginController { public function call() { - require_once __DIR__ . "/../../views/login/login.php"; - require_once __DIR__ . "/../../models/user.php"; + // require_once __DIR__ . "/../../views/login/login.php"; session_start(); if(isset($_POST['username']) && isset($_POST['password'])){ @@ -15,7 +14,7 @@ class PostLoginController $model = new UserModel(); try{ - $user = $model->getUser($_POST['username']); + $user = $model->getUser($username); $user = json_decode(json_encode($user), true); if(!$user){ diff --git a/src/app/controllers/playlist/post_playlist.php b/src/app/controllers/playlist/post_playlist.php new file mode 100644 index 0000000000000000000000000000000000000000..fada90eac7ea0b386395aaa40ca9bbb6518341bb --- /dev/null +++ b/src/app/controllers/playlist/post_playlist.php @@ -0,0 +1,36 @@ +<?php + +class PostPlaylistController +{ + public function call() + { + + session_start(); + if(!isset($_SESSION["user_id"])){ + header("Location: " . BASE_URL . "/login"); + + return; + } + + $idPodcast = ""; + $idPlaylist = ""; + + if(isset($_POST["id_playlist"]) && isset($_POST["id_podcast"])){ + $idPlaylist = $_POST["id_playlist"]; + $idPodcast = $_POST["id_podcast"]; + } + + $model = new PlaylistModel(); + + try{ + $model->removePodcastFromPlaylist($idPodcast, $idPlaylist); + http_response_code(201); + exit; + }catch(PDOException $e){ + $e->getMessage(); + http_response_code(200); + exit; + } + + } +} diff --git a/src/app/controllers/podcast/get_page.php b/src/app/controllers/podcast/get_page.php index 12bb94de4ff454bd2aa4b076e84e2b7208d1e561..3f82502c59c5d06caa59daa6d7e9aebf01bd2848 100644 --- a/src/app/controllers/podcast/get_page.php +++ b/src/app/controllers/podcast/get_page.php @@ -4,6 +4,7 @@ class GetPodcastPageController { public function call() { + session_start(); if (!isset($_SESSION["user_id"])) { http_response_code(403); @@ -24,14 +25,17 @@ class GetPodcastPageController $podcastModel = new PodcastModel(); $episodeModel = new EpisodeModel(); + $playlistModel = new PlaylistModel(); $podcast = $podcastModel->getById($idPodcast); $episodes = $episodeModel->getByPodcastId($idPodcast); + $playlists = $playlistModel->getUserPlaylist($_SESSION["user_id"]); + $data = [ "podcast" => $podcast, "episodes" => $episodes, - "libraries" => ["Contoh Library 1", "Contoh Library 2", "Contoh Library 3"] + "libraries" => $playlists, ]; $view = new PodcastPageView($data); diff --git a/src/app/controllers/podcast/post_page.php b/src/app/controllers/podcast/post_page.php new file mode 100644 index 0000000000000000000000000000000000000000..1a62717a81319e89024bd7aefc657ff802c15271 --- /dev/null +++ b/src/app/controllers/podcast/post_page.php @@ -0,0 +1,38 @@ +<?php + +class PostPodcastPageController +{ + public function call() + { + session_start(); + if(!isset($_SESSION["user_id"])){ + header("Location: " . BASE_URL . "/login"); + + return; + } + + $idPodcast = ""; + $idPlaylist = ""; + if(isset($_POST["id_playlist"]) && isset($_POST["id_podcast"])){ + $idPlaylist = $_POST["id_playlist"]; + $idPodcast = $_POST["id_podcast"]; + } + + $model = new PlaylistModel(); + + try{ + $model->addPodcastToPlaylist($idPlaylist, $idPodcast); + http_response_code(201); + exit; + + }catch(PDOException $e){ + // duplicate entries, violate integrity constraint (SQL code 23000) + if($e->getCode() === 23000){ + http_response_code(203); + }else{ // other type of error causing failure + http_response_code(200); + }; + exit; + } + } +} diff --git a/src/app/controllers/signup/get_signup.php b/src/app/controllers/signup/get_signup.php index 83adadb948f34900d76d4b25be1aae06a9ea124e..a680a69873413ce8b9ca1413b50e5b3011c5be9a 100644 --- a/src/app/controllers/signup/get_signup.php +++ b/src/app/controllers/signup/get_signup.php @@ -4,6 +4,8 @@ class GetSignupController { public function call() { + session_start(); + if(!isset($_SESSION['user_id'])){ require_once __DIR__ . "/../../views/signup/signup.php"; @@ -11,7 +13,7 @@ class GetSignupController $view = new SignupView($data); $view->render(); }else{ - header("Location: " . BASE_URL . "/home"); + header("Location: " . BASE_URL . "/home?user_id=" . $_SESSION["user_id"]); } } diff --git a/src/app/controllers/signup/post_signup.php b/src/app/controllers/signup/post_signup.php index cb5331b1ec84097f1f3e786ca89a5ff0ea274238..c9bafbd92257385eb0bc1add1db90306b4282a9c 100644 --- a/src/app/controllers/signup/post_signup.php +++ b/src/app/controllers/signup/post_signup.php @@ -5,7 +5,6 @@ class PostSignupController public function call() { require_once __DIR__ . "/../../views/signup/signup.php"; - require_once __DIR__ . "/../../models/user.php"; session_start(); if(!isset($_SESSION['user_id'])){ diff --git a/src/app/core/app.php b/src/app/core/app.php index 326ce639ff35217d7aa4eb3a33480ecf00dbf142..75b6eee8ddb24014c45ecc723ad35d36a0281002 100644 --- a/src/app/core/app.php +++ b/src/app/core/app.php @@ -40,12 +40,21 @@ class App $router->delete("public/dashboard/podcast", new DeletePodcastController()); $router->get("public/podcast", new GetPodcastPageController()); - + $router->post("public/episode/play", new PostPlayEpisodeController()); + $router->post("public/podcast", new PostPodcastPageController()); + + + $router->post("public/logout", new LogoutController()); + + $router->get("public/home", new GetHomeController()); + $router->get("public/search", new GetSearchController()); $router->get("public/login", new GetLoginController()); $router->post("public/login", new PostLoginController()); $router->get("public/signup", new GetSignupController()); $router->post("public/signup", new PostSignupController()); - $router->post("public/logout", new LogoutController()); + $router->get("public/library", new GetLibraryController()); + $router->get("public/playlist", new GetPlaylistController()); + $router->post("public/playlist", new PostPlaylistController()); $router->directRequest($url); } diff --git a/src/app/init.php b/src/app/init.php index f936aa1b16d90ab1a10cd76a44456e9d6ad83485..21ccb491f84af93bf4c16c6a002cec764273b130 100644 --- a/src/app/init.php +++ b/src/app/init.php @@ -22,6 +22,9 @@ require_once __DIR__ . "/controllers/dashboard/post_edit_podcast.php"; require_once __DIR__ . "/controllers/dashboard/delete_podcast.php"; require_once __DIR__ . "/controllers/podcast/get_page.php"; +require_once __DIR__ . "/controllers/episode/post_play_episode.php"; +require_once __DIR__ . "/controllers/podcast/post_page.php"; + require_once __DIR__ . "/controllers/logout/logout.php"; @@ -31,6 +34,7 @@ require_once __DIR__ . "/controllers/login/post_login.php"; require_once __DIR__ . "/controllers/library/get_library.php"; require_once __DIR__ . "/controllers/playlist/get_playlist.php"; +require_once __DIR__ . "/controllers/playlist/post_playlist.php"; require_once __DIR__ . "/controllers/library/get_library.php"; require_once __DIR__ . "/controllers/signup/get_signup.php"; require_once __DIR__ . "/controllers/signup/post_signup.php"; @@ -41,3 +45,4 @@ require_once __DIR__ . "/controllers/app/app_controller.php"; require_once __DIR__ . "/models/podcast.php"; require_once __DIR__ . "/models/episode.php"; require_once __DIR__ . "/models/user.php"; +require_once __DIR__ . "/models/playlist.php"; diff --git a/src/app/models/playlist.php b/src/app/models/playlist.php index e8b6b0533abb955f4ae904be2dbe05fcc04581ad..ba55193a3ebd0d41d076c6eba58a88a65414e2be 100644 --- a/src/app/models/playlist.php +++ b/src/app/models/playlist.php @@ -37,4 +37,61 @@ class PlaylistModel return $playlistPodcast; } + public function addPlaylist($id_user, $title, $id_playlist) + { + $query = " + INSERT INTO playlist (id_playlist, title, id_user) + VALUES(:id_playlist, :title, :id_user) + "; + + $this->db->query($query); + $this->db->bind("id_user", $id_user); + $this->db->bind("title", $title); + $this->db->bind("id_playlist", $id_playlist); + + $this->db->execute(); + } + + public function addPodcastToPlaylist($id_playlist, $id_podcast) + { + $query = " + INSERT INTO podcast_x_playlist (id_playlist, id_podcast) + VALUES(:id_playlist, :id_podcast) + "; + + $this->db->query($query); + $this->db->bind("id_playlist", $id_playlist); + $this->db->bind("id_podcast", $id_podcast); + + $this->db->execute(); + + } + + public function deletePlaylist($id_playlist) + { + $query = " + DELETE FROM playlist + WHERE id_playlist = :id_playlist + "; + + $this->db->query($query); + $this->db->bind("id_playlist", $id_playlist); + + $this->db->execute(); + } + + public function removePodcastFromPlaylist($id_podcast, $id_playlist) + { + $query = " + DELETE FROM podcast_x_playlist + WHERE id_playlist = :id_playlist AND id_podcast = :id_podcast + "; + + $this->db->query($query); + $this->db->bind("id_playlist", $id_playlist); + $this->db->bind("id_podcast", $id_podcast); + + $this->db->execute(); + } + } diff --git a/src/app/models/podcast.php b/src/app/models/podcast.php index f0c3eabfc0359b25d03e5042d7ebc2470f8e6f81..e93138bd65ddb882b27dbb9324aab3e941e56835 100644 --- a/src/app/models/podcast.php +++ b/src/app/models/podcast.php @@ -140,18 +140,18 @@ class PodcastModel return $podcasts; } - public function getPodcast($id_podcast) { - $query = " - SELECT * FROM podcast - WHERE id_podcast = :id_podcast - "; - - $this->db->query($query); - $this->db->bind("id_podcast", $id_podcast); - $podcast = $this->db->fetchAll(); - - return $podcast; - } + // public function getPodcast($id_podcast) { + // $query = " + // SELECT * FROM podcast + // WHERE id_podcast = :id_podcast + // "; + + // $this->db->query($query); + // $this->db->bind("id_podcast", $id_podcast); + // $podcast = $this->db->fetchAll(); + + // return $podcast; + // } public function getById($idPodcast) { diff --git a/src/public/javascript/library/library.js b/src/public/javascript/library/library.js new file mode 100644 index 0000000000000000000000000000000000000000..906458bd1d23dfa46bbfd6d7981687e7e3ae8074 --- /dev/null +++ b/src/public/javascript/library/library.js @@ -0,0 +1,38 @@ +"use strict" + +import { showErrorToast, showSuccessToast } from "../toast.mjs"; + + +document.addEventListener("DOMContentLoaded", (e) =>{ + + const trashEl = document.querySelectorAll('.bx-trash'); + const playlistContainer = document.querySelector('.playlist-container') + + if(trashEl.length !== 0){ + trashEl.forEach(function(trash){ + trash.addEventListener("click", (e) => { + e.preventDefault(); + + const data = new FormData(); + + const xhr = new XMLHttpRequest(); + + data.append("id_podcast", trash.dataset.id); + data.append("id_playlist", playlistContainer.dataset.id); + + xhr.open("POST", "/public/playlist", true); + + xhr.onload = function () { + if (xhr.readyState === XMLHttpRequest.DONE) { + if (xhr.status === 201) { + showSuccessToast("Podcast berhasil dihapus dari playlist!"); + }else{ // status code 200, some error + showErrorToast("Podcast gagal dihapus dari playlist!"); + } + } + } + xhr.send(data); + }) + }) + } +}); \ No newline at end of file diff --git a/src/public/javascript/podcast/script.js b/src/public/javascript/podcast/script.js index b1dd6defd8e22f8a8f396a15231d0703892d4203..122b303623acb13f36b474574422af08c8657463 100644 --- a/src/public/javascript/podcast/script.js +++ b/src/public/javascript/podcast/script.js @@ -1,17 +1,31 @@ "use strict"; +import { showSuccessToast, showErrorToast, showInformationToast } from "../toast.mjs"; + // Get DOM elements const playButtonsEl = document.querySelectorAll(".play-button"); const addLibraryButtonEl = document.getElementById("add-library-btn") const libraryChoicesEl = document.getElementById("library-choices") const overlayEl = document.getElementById("overlay-library") +const playlists = document.querySelectorAll(".playlist"); // Handle play episode Array.from(playButtonsEl).forEach((el) => { el.addEventListener("click", (e) => { e.preventDefault(); - console.log(`play episode id: ${el.dataset.id}`); + const formData = new FormData(); + formData.append("idEpisode", el.dataset.id); + + const xhr = new XMLHttpRequest(); + xhr.open("POST", "/public/episode/play"); + + xhr.onreadystatechange = () => { + if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) { + } + }; + + xhr.send(formData); }); }); @@ -31,3 +45,35 @@ overlayEl.addEventListener("click", (e) => { libraryChoicesEl.classList.toggle("hidden"); overlayEl.classList.toggle("hidden"); }); + + +if(playlists.length !== 0){ + playlists.forEach(function(playlist){ + playlist.addEventListener("click", (e) => { + e.preventDefault(); + + const data = new FormData(); + + const xhr = new XMLHttpRequest(); + + xhr.open("POST", "/public/podcast", true); + + data.append("id_playlist", playlist.dataset.id); + data.append("id_podcast", libraryChoicesEl.dataset.idPodcast); + + xhr.onload = function () { + if (xhr.readyState === XMLHttpRequest.DONE) { + if (xhr.status === 201) { + showSuccessToast("Podcast berhasil ditambahkan ke playlist!"); + }else if(xhr.status === 203){ + showInformationToast("Podcast sudah ada dalam playlist!") + } + else{ // status code 200, some other error + showErrorToast("Podcast gagal ditambahkan ke playlist!"); + } + } + } + xhr.send(data); + }) + }) +} \ No newline at end of file diff --git a/src/public/styles/globals.css b/src/public/styles/globals.css index 303883faeba1392aa20ca485f3b5775cd9e9026e..f7951e9ea118c840b231903f3a08a6f324945d1e 100644 --- a/src/public/styles/globals.css +++ b/src/public/styles/globals.css @@ -315,7 +315,7 @@ aside .sidebar-item { .progress-bar::-webkit-slider-thumb { cursor: pointer; border-radius: 99px; - background-color: var(--PINK-1); /* Blue color with 100% opacity */ + background-color: white; /* Blue color with 100% opacity */ height: 14px; width: 14px; }