diff --git a/api/auth/login.php b/api/auth/login.php index 941d58165a9857268b49578c096c32d106ecf916..6e50ebd26fa141656c92f5699a996fbcd62e63fa 100644 --- a/api/auth/login.php +++ b/api/auth/login.php @@ -29,8 +29,9 @@ $hashed_pass = $result["password"]; if(password_verify($password,$hashed_pass)){ $_SESSION['success'] = "Log in succesful!"; - $_SESSION['username'] = $username; $_SESSION["user_id"] = $result["user_id"]; + $courses = $user->getAllCoursesEnrolled(); + $_SESSION["courses_enrolled"] = $courses; header('Location: /'); exit; }else{ diff --git a/api/course/enroll.php b/api/course/enroll.php index e399570c6a481754b07c7c704660a0f328220424..1d6b6bc16bbfce95efaccd48fe5c279ce5121da1 100644 --- a/api/course/enroll.php +++ b/api/course/enroll.php @@ -14,14 +14,34 @@ }else{ if($_POST["course_id"]){ $user = new User(); + $course = new Course(); $course_id = $_POST["course_id"]; - $rows = $user->enroll($course_id); - if($rows){ - http_response_code(200); - $_SESSION["success"] = "You have succesfully enrolled this course!"; + $course_enrolled = $course->single_course($_POST["course_id"]); + if($course_enrolled["course_password"] !== NULL){ + if(isset($_POST["course_password"])){ + $course_password = $_POST["course_password"]; + if($course_password === $course_enrolled["course_password"]){ + // Kalau berhasil enroll + $rows = $user->enroll($course_id); + if($rows){ + $_SESSION["success"] = "You have sucesfully enrolled!"; + http_response_code(200); + echo json_encode(array("status" => "success")); + }else{ + $_SESSION["error"] = "Enrolled failed!"; + echo json_encode(array("status" => "fail")); + } + }else{ + $_SESSION["error"] = "Wrong password!"; + echo json_encode(array("status" => "fail")); + } + } }else{ - http_response_code(501); - $_SESSION["error"] = "Something went wrong!"; + $rows = $user->enroll($course_id); + if($rows){ + $_SESSION["success"] = "You have sucesfully enrolled"; + echo json_encode(array("status" => "success")); + } } } } diff --git a/api/course/search.php b/api/course/search.php new file mode 100644 index 0000000000000000000000000000000000000000..021ebbe9be382d89711383507d2b647440dde50e --- /dev/null +++ b/api/course/search.php @@ -0,0 +1,32 @@ +<?php + require_once("../../app/models/Course.php"); + require_once("../../app/core/App.php"); + require_once("../../app/core/Database.php"); + require_once("../../app/models/User.php"); + require_once("../../app/core/Table.php"); + require_once("../../config/config.php"); + if(session_status() === PHP_SESSION_NONE){ + session_start(); + } + if(isset($_GET["title"])){ + $data["title"] = $_GET["title"]; + } + if(isset($_GET["sort"])){ + $data["sort"] = $_GET["sort"]; + } + if(isset($_GET["password"])){ + $data["password"] = $_GET["password"]; + } + if(isset($_GET["release_year"])){ + $data["release_year"] = str_replace("now",date("Y"),$_GET["release_year"]); + $data["release_year"] = str_replace("<","",$data["release_year"]); + } + $course = new Course(); + $all_courses = $course->searchCourses($data); + $joined_courses = $_SESSION["courses_enrolled"]; + + $max_page = ceil(count($course->searchCourses($data))/4); + $courses = $course->searchFewCourses($_GET["page"],$data); + echo json_encode(array("courses" => $courses,"max_page" => $max_page,"joined_courses" => $joined_courses)); + +?> \ No newline at end of file diff --git a/app/controllers/AdminController.php b/app/controllers/AdminController.php index 76b7dbcd564c41220fb9714a7a40ea0f78990ebd..fc9ebf7e7f615f27b977f1841946f99b341ea28b 100644 --- a/app/controllers/AdminController.php +++ b/app/controllers/AdminController.php @@ -11,11 +11,6 @@ return $this->view("admin","register",[]); } - // Page admin untuk login - public function login(){ - return $this->view("admin","login",[]); - } - // Page admin untuk melihat semua students public function users($params = "page=1"){ if(!isset($_SESSION["user_id"])){ @@ -46,19 +41,6 @@ return $this->view("admin","editCourse",["course" => $course]); } } - // Page admin untuk melihat semua teachers - public function teachers(){ - return $this->view("admin","teachers",[]); - } - - // Page admin untuk add teacher - public function addTeacher(){ - return $this->view("admin","index",[]); - } - // Page admin untuk edit teacher - public function editTeacher(){ - return $this->view("admin","index",[]); - } // Page admin untuk melihat courses public function courses($params = "page=1"){ $components = explode("=",$params); diff --git a/app/controllers/SearchController.php b/app/controllers/SearchController.php new file mode 100644 index 0000000000000000000000000000000000000000..5bff6ec597fb10dde5cd97b03563e2b51a389e39 --- /dev/null +++ b/app/controllers/SearchController.php @@ -0,0 +1,10 @@ +<?php + + class SearchController extends Controller{ + public function index(){ + $middleware = $this->middleware("LoginMiddleware"); + $middleware->hasLoggedIn(); + return $this->view("search","index",[]); + } + } +?> \ No newline at end of file diff --git a/app/core/Controller.php b/app/core/Controller.php index 5b7513fdddf90c860ea1663100ce8853e4c4132e..e81df0f3d38c32a8062049565c9246bebcd57eae 100644 --- a/app/core/Controller.php +++ b/app/core/Controller.php @@ -8,5 +8,10 @@ echo "File not found"; } } + + public function middleware($name){ + require_once("app/middlewares/".$name . '.php'); + return new $name; + } } ?> \ No newline at end of file diff --git a/app/core/Database.php b/app/core/Database.php index 02c76b701a83e8a34eb1f6ebd01aec61591fd1ed..ca56d09fa64220310d738e63376377ab285f34ae 100644 --- a/app/core/Database.php +++ b/app/core/Database.php @@ -29,9 +29,7 @@ $this->connection->exec(Table::COURSE_TABLE); $this->connection->exec(Table::COURSE_PARTICIPANT_TABLE); $this->connection->exec(Table::MODULE_TABLE); - $this->connection->exec(Table::COURSE_MODULE_TABLE); $this->connection->exec(Table::MATERIAL_TABLE); - $this->connection->exec(Table::MODULE_MATERIAL_TABLE); } catch (PDOException $e) { die($e->getMessage()); } diff --git a/app/core/Seed.php b/app/core/Seed.php index 5e59ce22b527205fb4e8305cf7f6b254864e4991..0a3a460fceeb4ffdbe1484a11319c8fe64b64cb5 100644 --- a/app/core/Seed.php +++ b/app/core/Seed.php @@ -53,24 +53,27 @@ } } public function seed_modules(){ - $query = "INSERT INTO modules(title,description) VALUES (:title,:description);"; + $query = "INSERT INTO modules(title,description,course_id) VALUES (:title,:description,:course_id);"; $title = "title"; $desc = "desc"; $this->database->query($query); for($i = 0; $i < 30; $i++){ + $course_id = rand(1,30); $new_title = $title.$i; $new_desc = $desc.$i; $this->database->bind("title",$new_title); $this->database->bind("description",$new_desc); + $this->database->bind("course_id",$course_id); $this->database->execute(); } } public function seed_materials(){ - $query = "INSERT INTO materials(title,description,material_type) VALUES(:title,:description,:material_type);"; + $query = "INSERT INTO materials(title,description,material_type,module_id) VALUES(:title,:description,:material_type,:module_id);"; $title = "title"; $desc = "desc"; $this->database->query($query); for($i = 0; $i < 30; $i++){ + $module_id = rand(1,30); $new_title = $title.$i; $new_desc = $desc.$i; if($i%3 == 0){ @@ -81,6 +84,7 @@ $this->database->bind("title",$new_title); $this->database->bind("description",$new_desc); $this->database->bind("material_type",$type); + $this->database->bind("module_id",$module_id); $this->database->execute(); } } @@ -100,27 +104,5 @@ $this->database->execute(); } } - public function seed_course_module(){ - $query = "INSERT INTO course_module(course_id,module_id) VALUES (:course,:module);"; - $this->database->query($query); - for($i = 0; $i <30;$i++){ - $course = rand(1,30); - $module = rand(1,30); - $this->database->bind("course",$course); - $this->database->bind("module",$module); - $this->database->execute(); - } - } - public function seed_module_material(){ - $query = "INSERT INTO module_material(module_id,material_id) VALUES (:module,:material);"; - $this->database->query($query); - for($i = 0; $i < 30; $i++){ - $module = rand(1,30); - $material = rand(1,30); - $this->database->bind("module",$module); - $this->database->bind("material",$material); - $this->database->execute(); - } - } } ?> \ No newline at end of file diff --git a/app/core/Table.php b/app/core/Table.php index 7245f83b0c980431dc60f4aa679ed99048271ea9..5badcd85f5ea8cba0c09093f5671e10e86189522 100644 --- a/app/core/Table.php +++ b/app/core/Table.php @@ -49,27 +49,18 @@ ' CREATE TABLE IF NOT EXISTS modules( module_id SERIAL PRIMARY KEY, title VARCHAR(256) UNIQUE NOT NULL, - description VARCHAR(256) + description VARCHAR(256), + course_id INT REFERENCES courses(course_id) ON DELETE CASCADE NOT NULL )'; - public const COURSE_MODULE_TABLE = - ' CREATE TABLE IF NOT EXISTS course_module( - course_module_id SERIAL PRIMARY KEY, - course_id INT REFERENCES courses(course_id) ON DELETE CASCADE NOT NULL, - module_id INT REFERENCES modules(module_id) ON DELETE CASCADE NOT NULL - )'; + public const MATERIAL_TABLE = "CREATE TABLE IF NOT EXISTS materials( material_id SERIAL PRIMARY KEY, title VARCHAR(256) NOT NULL, description VARCHAR(256), + module_id INT REFERENCES modules(module_id) ON DELETE CASCADE NOT NULL, material_type source )"; - public const MODULE_MATERIAL_TABLE = - ' CREATE TABLE IF NOT EXISTS module_material( - module_material_id SERIAL PRIMARY KEY, - module_id INT REFERENCES modules(module_id) ON DELETE CASCADE NOT NULL, - material_id INT REFERENCES materials(material_id) ON DELETE CASCADE NOT NULL - )'; } ?> \ No newline at end of file diff --git a/app/init.php b/app/init.php index df126128c943316de0569f03f4c79610be18fb59..06cad74db7ef2cf90c3c7023c3a514f74df0ac87 100644 --- a/app/init.php +++ b/app/init.php @@ -17,6 +17,4 @@ // $seed->seed_modules(); // $seed->seed_materials(); // $seed->seed_course_participants(); - // $seed->seed_course_module(); - // $seed->seed_module_material(); ?> \ No newline at end of file diff --git a/app/middlewares/LoginMiddleware.php b/app/middlewares/LoginMiddleware.php new file mode 100644 index 0000000000000000000000000000000000000000..bfff617e6533d7c865ee793510907d10a1444ba7 --- /dev/null +++ b/app/middlewares/LoginMiddleware.php @@ -0,0 +1,21 @@ +<?php + class LoginMiddleware{ + private $database; + public function __construct(){ + $this->database = Database::instance(); + } + public function hasLoggedIn(){ + if(!isset($_SESSION["user_id"])){ + $_SESSION["error"] = "You have to login!"; + header("Location: /login"); + } + $user_id = $_SESSION["user_id"]; + $user = new User(); + $row = $user->getUserById($user_id); + if(!$row){ + $_SESSION["error"] = "You have to login!"; + header("Location: /login"); + } + } + } +?> \ No newline at end of file diff --git a/app/models/Course.php b/app/models/Course.php index e53d6a9edbfb812760dfbb2ffc3ed060005e3463..90abc0bf72d648467f1c942b96d76f95f9dd40be 100644 --- a/app/models/Course.php +++ b/app/models/Course.php @@ -44,8 +44,6 @@ require_once(__DIR__."/Model.php"); return $result; } - - public function search_participant($course_id,){ $query = "SELECT c.course_id FROM courses as c NATURAL JOIN course_participant WHERE c.course_id = :course_id AND participant_id = :user_id; @@ -58,11 +56,116 @@ require_once(__DIR__."/Model.php"); } public function get_modules($course_id){ - $query = "SELECT * FROM modules NATURAL JOIN course_module WHERE course_id = :course_id"; + $query = "SELECT * FROM modules WHERE course_id = :course_id"; $this->database->query($query); $this->database->bind("course_id",$course_id); $rows = $this->database->fetchAll(); return $rows; } + + public function searchCourses($data){ + $query = "SELECT * FROM courses "; + $search = false; + + if(isset($data["title"])){ + $query.= "WHERE (LOWER(title) LIKE :title OR LOWER(description) LIKE :title)"; + $search = true; + } + if(isset($data["password"])){ + $query .= ($search ? " AND (course_password IS " : " WHERE (course_password IS"); + if($data["password"] === "false"){ + $query.= " NULL)"; + }else{ + $query .= " NOT NULL)"; + } + $search = true; + } + if(isset($data["release_year"])){ + $components = explode("-",$data["release_year"]); + if(count($components) === 1){ + $year = "< :smaller_year"; + $smaller_year = $components[0]; + }else{ + $year = "BETWEEN :smaller_year AND :bigger_year"; + $smaller_year = $components[0]; + $bigger_year =$components[1]; + } + $query .= ($search ? " AND date_part('year',release_date) " .$year: "WHERE date_part('year',release_date) ". $year); + } + $this->database->query($query); + if($search){ + $this->database->bind("title",'%'.$data["title"].'%'); + } + if(isset($data["release_year"])){ + $this->database->bind("smaller_year",$smaller_year); + if(isset($bigger_year)){ + $this->database->bind("bigger_year",$bigger_year); + } + } + $results = $this->database->fetchAll(); + return $results; + } + + public function searchFewCourses($page,$params){ + $query = "SELECT * FROM courses"; + $where = false; + $search = false; + $password = false; + + if(isset($params["title"])){ + $query.= " WHERE (LOWER(title) LIKE :title OR LOWER(description) LIKE :title)"; + $where = true; + $search = true; + } + + if(isset($params["password"])){ + $query .= ($search ? " AND (course_password IS " : " WHERE (course_password IS"); + if($params["password"] === "false"){ + $query.= " NULL)"; + }else{ + $query .= " NOT NULL)"; + } + } + + if(isset($params["release_year"])){ + $components = explode("-",$params["release_year"]); + if(count($components) === 1){ + $year = "< :smaller_year"; + $smaller_year = $components[0]; + }else{ + $year = "BETWEEN :smaller_year AND :bigger_year"; + $smaller_year = $components[0]; + $bigger_year =$components[1]; + } + $query .= ($search ? " AND date_part('year',release_date) ".$year : " WHERE date_part('year',release_date) ". $year); + } + + if(isset($params["sort"])){ + $components = explode(" ",$params["sort"]); + $rules = $components[1]; + if($components[0] === "title"){ + $query .= " ORDER BY title ".$rules; + }else{ + $query .= " ORDER BY release_date " . $rules; + } + $sort = true; + } + + $query .= " LIMIT 4 OFFSET :offset"; + $this->database->query($query); + $this->database->bind("offset",($page-1)*4); + if($search){ + $this->database->bind("title", '%'.$params["title"].'%'); + } + if(isset($params["release_year"])){ + $this->database->bind("smaller_year",$smaller_year); + if(isset($bigger_year)){ + $this->database->bind("bigger_year",$bigger_year); + } + } + $results = $this->database->fetchAll(); + return $results; + } + } ?> \ No newline at end of file diff --git a/app/views/admin/courses.php b/app/views/admin/courses.php index f93cc1c05fc52c3fe82e6d099b94d59a7f453fdb..bf718113ac8d484e6cd9d02f63104d0043b55de3 100644 --- a/app/views/admin/courses.php +++ b/app/views/admin/courses.php @@ -5,7 +5,8 @@ <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Courses List</title> - <link rel="stylesheet" href="../../public/css/admin/lists.css"> + <link rel="stylesheet" href="../../public/css/components/button.css"> + <link rel="stylesheet" href="../../public/css/admin/admin.css"> <script src="../../public/js/admin.js"></script> </head> @@ -79,6 +80,7 @@ </table> <?php + $parent = "admin"; $href = "courses"; include __DIR__ . '/../components/pagination.php' ?> diff --git a/app/views/admin/users.php b/app/views/admin/users.php index 13b54192d4b2b031b02667c9d09efd28f303f219..397ea90000456862c9fb0fed85be73af582b186f 100644 --- a/app/views/admin/users.php +++ b/app/views/admin/users.php @@ -5,7 +5,8 @@ <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Users List</title> - <link rel="stylesheet" href="../../public/css/admin/lists.css"> + <link rel="stylesheet" href="../../public/css/components/button.css"> + <link rel="stylesheet" href="../../public/css/admin/admin.css"> <script src="../../public/js/admin.js"></script> </head> @@ -77,6 +78,7 @@ </tbody> </table> <?php + $parent = "admin"; $href = "users"; include __DIR__ . '/../components/pagination.php' ?> diff --git a/app/views/components/courseModal.php b/app/views/components/courseModal.php new file mode 100644 index 0000000000000000000000000000000000000000..f629fc3b2401809652178314cd6dca23d0ebfdb5 --- /dev/null +++ b/app/views/components/courseModal.php @@ -0,0 +1,41 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>Document</title> +</head> +<body> + <div id="overlay"> + <dialog id="dialog"> + <div class="modal-container"> + <div class="flex"> + <p id="upload-date"></p> + <button class="close-btn" onclick="closeDialog()"> + <i> + <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> + <path d="M9.172 16.242 12 13.414l2.828 2.828 1.414-1.414L13.414 12l2.828-2.828-1.414-1.414L12 10.586 9.172 7.758 7.758 9.172 10.586 12l-2.828 2.828z"/> + <path d="M12 22c5.514 0 10-4.486 10-10S17.514 2 12 2 2 6.486 2 12s4.486 10 10 10zm0-18c4.411 0 8 3.589 8 8s-3.589 8-8 8-8-3.589-8-8 3.589-8 8-8z"/> + </svg> + </i> + </button> + </div> + <div class="title"><h3 id="course-title"></h3></div> + <div class="description"> + <p id="course-desc"> + </p> + <p style="display:none" id="course_id"></p> + </div> + <div class="buttons-enroll" id="button"> + <button id="course-detail" class="enroll-btn" style="visibiility:hidden;" onclick='visitCourse()'>Go to this course</button> + <div class="wrapper"> + <input placeholder="Enter course password" id="password-input" type="hidden" /> + <button class='enroll-btn' id="enroll-btn" onclick='enrolled()'>Enroll this Course</button> + </div> + + </div> + </div> + </dialog> + </div> +</body> +</html> \ No newline at end of file diff --git a/app/views/components/pagination.php b/app/views/components/pagination.php index d2e26373d1f80ef2c78141f73b883767d81b0bff..0a498f23ba0667d76a1b120af3760fa9475b1d85 100644 --- a/app/views/components/pagination.php +++ b/app/views/components/pagination.php @@ -3,7 +3,8 @@ <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Document</title> + <link rel="stylesheet" href="../../public/css/components/pagination.css"> + </head> <body> <div class="paging"> @@ -11,32 +12,33 @@ <?php $start_index = $data["page_number"]; $max_page = $data["max_page"]; + $background_color = ($href === "lists" || $href==="enrolled" ? "#564c95" : "#9e51d8"); $prev_index = $start_index <= 1 ? 1 : $start_index-1; if($start_index > 1){ $prev_index = $start_index-1; - echo "<a href='/admin/$href/page=$prev_index'>PREV</a>"; + echo "<a href='/$parent/$href/page=$prev_index'>PREV</a>"; } for($i = $prev_index; $i < $start_index+2;$i++){ if($i == $max_page){ break; } if($i == $start_index){ - echo "<a class='pagination-active' style='background-color:#9e51d8;color:white;' id='pagination-active'>$i</a>"; + echo "<a style='background-color:$background_color;color:white;'>$i</a>"; }else{ - echo "<a href='/admin/$href/page=$i' id='pagination-number'>$i</a>"; + echo "<a href='/$parent/$href/page=$i' id='pagination-number'>$i</a>"; } } if($start_index < $max_page-2){ echo "<a>...</a>"; } if($start_index == $max_page){ - echo "<a style='background-color:#9e51d8;color:white;' href='/admin/$href/page=$max_page'>$max_page</a>"; + echo "<a style='background-color:$background_color;color:white;' href='/admin/$href/page=$max_page'>$max_page</a>"; }else{ - echo "<a href='/admin/$href/page=$max_page'>$max_page</a>"; + echo "<a href='/$parent/$href/page=$max_page' >$max_page</a>"; } if($start_index < $max_page){ $next_index = $start_index + 1; - echo "<a href='/admin/$href/page=$next_index'> NEXT</a>"; + echo "<a href='/$parent/$href/page=$next_index'> NEXT</a>"; } ?> </div> diff --git a/app/views/courses/edit.php b/app/views/courses/edit.php deleted file mode 100644 index 00bb0f096119a312ca7bb3084e7d617c16dca1a4..0000000000000000000000000000000000000000 --- a/app/views/courses/edit.php +++ /dev/null @@ -1,55 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -<head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <link href="../../public/css/course/add.css" rel="stylesheet"></link> - <title>Document</title> - <script src="../../public/js/course.js"> - </script> -</head> -<body> - <?php include __DIR__ . '/../navbar/navbar.php'?> - <section class="form-section"> - <div class="form-container"> - <h1> - Edit <?php $course=$data["course"]; echo $course["title"] ?> - </h1> - <form class="form" action="javascript:" onsubmit="return handleUpdate()"> - <div class="image-container"> - <?php - $course = $data["course"]; - if($course["image_path"]){ - echo "<img src=$course[image_path] id='course-image' class='course-image' alt='$course[title]' />"; - } - ?> - </div> - <div class="edit-detail-container"> - <label>Course's Title</label><br> - <input - name="title" - placeholder="Course's title" - class="login-input" - id="title-input" - onkeyup="checkTitle()" - value=<?php echo $course["title"] ?> - /> - <p id="title-alert"></p><br> - <label>Enter descriptions for this course</label> <br> - <input - placeholder="Enter Description" - class="login-input" - name="description" - id="description-input" - value=<?php echo $course["description"] ?> - /> <br> <br> - <label>Customize course's image</label> <br> - <input type="file" name="image" class="login-input" accept="image/png, image/jpeg" id="image-input" /> - <button type="submit">Edit Course</button> - </div> - - </form> - </div> - </section> -</body> -</html> \ No newline at end of file diff --git a/app/views/enrolled/index.php b/app/views/enrolled/index.php deleted file mode 100644 index 348a5cba1e256f25e9575a78053a0e58f0367209..0000000000000000000000000000000000000000 --- a/app/views/enrolled/index.php +++ /dev/null @@ -1,13 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -<head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Enrolled Courses</title> -</head> -<body> - <?php - - ?> -</body> -</html> \ No newline at end of file diff --git a/app/views/home/index.php b/app/views/home/index.php index 06b47532521e0e840015814d8fc8fe327f9a1cda..4a79426cf88dfbebc027b949cfc04c4f0f51e9b2 100644 --- a/app/views/home/index.php +++ b/app/views/home/index.php @@ -6,6 +6,7 @@ <title>HomePage</title> <link href="../../public/css/home/home.css" rel="stylesheet"> <script src="../../public/js/home.js" defer></script> + <script src="../../public/js/search.js"></script> <title>Document</title> </head> <body> @@ -53,43 +54,6 @@ </div> </div> - <!-- SEARCH BAR --> - - <div class="search-sort"> - <div class="search-bar"> - <div id="select"> - <p id="selectText">All Courses</p> - <i> - <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> - <path d="M16.293 9.293 12 13.586 7.707 9.293l-1.414 1.414L12 16.414l5.707-5.707z"/> - </svg> - </i> - <ul id="list"> - <li class="options">All Courses</li> - <li class="options">Art and Design</li> - <li class="options">Business</li> - <li class="options">Math and Science</li> - <li class="options">Programming</li> - </ul> - </div> - <input type="text" id="inputField" placeholder="Search In All Courses"> - </div> - <div id="sort"> - <p id="sortText">Sort By</p> - <i> - <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> - <path d="M16.293 9.293 12 13.586 7.707 9.293l-1.414 1.414L12 16.414l5.707-5.707z"/> - </svg> - </i> - <ul id="sortList"> - <li class="sort-options">Course Ascending</li> - <li class="sort-options">Course Descending</li> - <li class="sort-options">Lecturer Ascending</li> - <li class="sort-options">Lecturer Descending</li> - </ul> - </div> - </div> - <!-- COURSES CARDS --> <div class="card-container"> @@ -110,7 +74,7 @@ $image_path = isset($course["image_path"]) ? $course["image_path"]:"../../public/asset/banner1.png"; $formattedDate = date('d-m-y', strtotime($course['release_date'])); echo" - <div class='card' onclick='openModal(\"$joined\",\"$course[course_id]\",\"$course[title]\",\"$course[description]\",\"$formattedDate\")' style='cursor: pointer;'> + <div class='card' onclick='openModal(\"$joined\",\"$course[course_id]\",\"$course[title]\",\"$course[description]\",\"$formattedDate\",\"$course[course_password]\")' style='cursor: pointer;'> <div class='card-top'> <img src='$image_path' alt='Blog Name'> </div> @@ -130,12 +94,12 @@ </div> </div> - <div id="overlay" onclick="closeDialog()"> + <div id="overlay"> <dialog id="dialog"> <div class="modal-container"> <div class="flex"> <p id="upload-date"></p> - <button class="close-btn"> + <button class="close-btn" onclick="closeDialog()"> <i> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> <path d="M9.172 16.242 12 13.414l2.828 2.828 1.414-1.414L13.414 12l2.828-2.828-1.414-1.414L12 10.586 9.172 7.758 7.758 9.172 10.586 12l-2.828 2.828z"/> @@ -151,52 +115,23 @@ <p style="display:none" id="course_id"></p> </div> <div class="buttons-enroll" id="button"> - <button id="course-detail" class="enroll-btn" style="display:none;" onclick='visitCourse()'>Go to this course</button> + <button id="course-detail" class="enroll-btn" style="visibiility:hidden;" onclick='visitCourse()'>Go to this course</button> <!-- <div class="lecturer"><h4>Lecturer: Bapak saya, kakek, nenek, pak dosen</h4></div> --> - <button class='enroll-btn' id="enroll-btn" onclick='enrolled()'>Enroll this Course</button> + <div class="wrapper"> + <input placeholder="Enter course password" id="password-input" type="hidden" /> + <button class='enroll-btn' id="enroll-btn" onclick='enrolled()'>Enroll this Course</button> + </div> + </div> </div> </dialog> </div> - <div class="paging"> - <div class="pagination"> - <?php - $start_index = $data["page_number"]; - $max_page = $data["max_page"]; - $type = $data["type"]; - $prev_index = $start_index <= 1 ? 1 : $start_index-1; - - if($start_index > 1){ - $prev_index = $start_index-1; - echo "<a href='/course/$type/page=$prev_index'>PREV</a>"; - } - for($i =$prev_index; $i < $start_index+2;$i++){ - if($i == $max_page){ - break; - } - $classname = ''; - if($i == $start_index){ - echo "<a class='pagination-active' style='background-color:#5271e9;color:white;' id='pagination-active'>$i</a>"; - }else{ - echo "<a href='/course/$type/page=$i'id='pagination-number'>$i</a>"; - } - } - if($start_index < $max_page-2){ - echo "<a>...</a>"; - } - if($start_index == $max_page){ - echo "<a style='background-color:#5271e9;color:white;' href='/course/$type/page=$max_page'>$max_page</a>"; - }else{ - echo "<a href='/course/$type/page=$max_page'>$max_page</a>"; - } - if($start_index < $max_page){ - $next_index = $start_index + 1; - echo "<a href='/course/$type/page=$next_index'> NEXT</a>"; - } - ?> - </div> - </div> + <?php + $parent = "course"; + $href = $data["type"]; + include __DIR__ . '/../components/pagination.php' + ?> </section> </body> </html> \ No newline at end of file diff --git a/app/views/navbar/navbar.php b/app/views/navbar/navbar.php index 628bb9b14db8f752bb1924dac5d99db97aeae6d8..97da92416aab8377e23abd912a0c6e010efa892f 100644 --- a/app/views/navbar/navbar.php +++ b/app/views/navbar/navbar.php @@ -5,6 +5,8 @@ <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Side Bar</title> <link href="../../public/css/navbar/navbar.css" rel="stylesheet"> + <link href="../../public/css/components/button.css" rel="stylesheet"> + <script src="../../public/js/navbar.js" defer></script> </head> <body> @@ -13,7 +15,7 @@ <img src="../../public/asset/teslogo.png" alt="Homepage" class="logo-img"> <i id="btn"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> - <path d="M4 6h16v2H4zm0 5h16v2H4zm0 5h16v2H4z"/> + <path fill="white" d="M4 6h16v2H4zm0 5h16v2H4zm0 5h16v2H4z"/> </svg> </i> </div> @@ -29,24 +31,22 @@ // Fetch the user by ID $user = new User; $thisUser = $user->getUserById($_SESSION["user_id"]); - echo " + ?> <li> <div class='profile-details'> <a href='/profile'> - <img src='{$thisUser['image_path']}' alt='profileImg' class='photo'/> + <img src= <?php echo ($thisUser["image_path"] ? $thisUser["image_path"] : "../../public/image/profile/defaultprofilepicture.jpg") ?> alt='profileImg' class='photo'/> <div class='name-job'> - <div class='name'>{$thisUser['username']}</div> - <div class='job'>{$thisUser['user_role']}</div> + <div class='name'><?php echo $thisUser['username']?></div> + <div class='job'><?php echo $thisUser['user_role'] ?></div> </div> </a> <span class='tooltip'>Profile</span> </div> </li> - "; - } - else{ - // JIKA USER BELUM LOGIN, PROFILE MENGARAHKAN KE PAGE LOGIN - echo " + <?php } + else{ ?> + <!-- JIKA USER BELUM LOGIN, PROFILE MENGARAHKAN KE PAGE LOGIN --> <li> <div class='profile-details'> <a href='/login'> @@ -58,11 +58,7 @@ <span class='tooltip'>Login</span> </div> </li> - "; - } - ?> - - + <?php } ?> <!-- HOMEPAGE BUTTON --> <li> <a href="/"> @@ -89,19 +85,16 @@ </a> <span class="tooltip">My Courses</span> </li> - - <!-- ASSIGNMENTS BUTTON --> <li> - <a href="#"> + <a href="/search"> <i> - <svg fill="white" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> - <path d="M5 22h14c1.103 0 2-.897 2-2V5c0-1.103-.897-2-2-2h-2a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1H5c-1.103 0-2 .897-2 2v15c0 1.103.897 2 2 2zM5 5h2v2h10V5h2v15H5V5z"/> - <path d="m11 13.586-1.793-1.793-1.414 1.414L11 16.414l5.207-5.207-1.414-1.414z"/> - </svg> + <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" style="fill: rgba(0, 0, 0, 1);transform: ;msFilter:;"> + <path fill="white" d="M19.023 16.977a35.13 35.13 0 0 1-1.367-1.384c-.372-.378-.596-.653-.596-.653l-2.8-1.337A6.962 6.962 0 0 0 16 9c0-3.859-3.14-7-7-7S2 5.141 2 9s3.14 7 7 7c1.763 0 3.37-.66 4.603-1.739l1.337 2.8s.275.224.653.596c.387.363.896.854 1.384 1.367l1.358 1.392.604.646 2.121-2.121-.646-.604c-.379-.372-.885-.866-1.391-1.36zM9 14c-2.757 0-5-2.243-5-5s2.243-5 5-5 5 2.243 5 5-2.243 5-5 5z"></path> + </svg> </i> - <span class="link-name">Assignments</span> + <span class="link-name">Search</span> </a> - <span class="tooltip">Assignments</span> + <span class="tooltip">Search</span> </li> <!-- LOGOUT BUTTON --> @@ -110,19 +103,7 @@ session_start(); } if(isset($_SESSION["user_id"])){ - echo " - <li> - <a href='#'> - <i> - <svg fill='white' xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'> - <path d='M12 16c2.206 0 4-1.794 4-4s-1.794-4-4-4-4 1.794-4 4 1.794 4 4 4zm0-6c1.084 0 2 .916 2 2s-.916 2-2 2-2-.916-2-2 .916-2 2-2z'/> - <path d='m2.845 16.136 1 1.73c.531.917 1.809 1.261 2.73.73l.529-.306A8.1 8.1 0 0 0 9 19.402V20c0 1.103.897 2 2 2h2c1.103 0 2-.897 2-2v-.598a8.132 8.132 0 0 0 1.896-1.111l.529.306c.923.53 2.198.188 2.731-.731l.999-1.729a2.001 2.001 0 0 0-.731-2.732l-.505-.292a7.718 7.718 0 0 0 0-2.224l.505-.292a2.002 2.002 0 0 0 .731-2.732l-.999-1.729c-.531-.92-1.808-1.265-2.731-.732l-.529.306A8.1 8.1 0 0 0 15 4.598V4c0-1.103-.897-2-2-2h-2c-1.103 0-2 .897-2 2v.598a8.132 8.132 0 0 0-1.896 1.111l-.529-.306c-.924-.531-2.2-.187-2.731.732l-.999 1.729a2.001 2.001 0 0 0 .731 2.732l.505.292a7.683 7.683 0 0 0 0 2.223l-.505.292a2.003 2.003 0 0 0-.731 2.733zm3.326-2.758A5.703 5.703 0 0 1 6 12c0-.462.058-.926.17-1.378a.999.999 0 0 0-.47-1.108l-1.123-.65.998-1.729 1.145.662a.997.997 0 0 0 1.188-.142 6.071 6.071 0 0 1 2.384-1.399A1 1 0 0 0 11 5.3V4h2v1.3a1 1 0 0 0 .708.956 6.083 6.083 0 0 1 2.384 1.399.999.999 0 0 0 1.188.142l1.144-.661 1 1.729-1.124.649a1 1 0 0 0-.47 1.108c.112.452.17.916.17 1.378 0 .461-.058.925-.171 1.378a1 1 0 0 0 .471 1.108l1.123.649-.998 1.729-1.145-.661a.996.996 0 0 0-1.188.142 6.071 6.071 0 0 1-2.384 1.399A1 1 0 0 0 13 18.7l.002 1.3H11v-1.3a1 1 0 0 0-.708-.956 6.083 6.083 0 0 1-2.384-1.399.992.992 0 0 0-1.188-.141l-1.144.662-1-1.729 1.124-.651a1 1 0 0 0 .471-1.108z'/> - </svg> - </i> - <span class='link-name'>Setting</span> - </a> - <span class='tooltip'>Setting</span> - </li> + ?> <li> <button class='logbtn' onclick='openModalLogout()'> <i id='log-out'> @@ -136,8 +117,7 @@ <span class='tooltip'>Log Out</span> </li> "; - } - ?> + <?php } ?> <div class="footer"> <p class="text-xs"> @@ -163,8 +143,8 @@ <h2>Logout</h2> <p>Are you sure want to logout?</p> <div class="buttons-logout"> - <button class="close-btn-logout">Cancel</button> <!-- CANCEL LOGOUT AND CLOSE POPUP --> - <button class="confirm-logout"><a href="/api/auth/logout.php">Logout</a></button> <!-- IF CONFIRM TO LOGOUT CLICK HERE --> + <button class="cancelbtn">Cancel</button> <!-- CANCEL LOGOUT AND CLOSE POPUP --> + <button class="deletebtn"><a href="/api/auth/logout.php" class="delete-link">Logout</a></button> <!-- IF CONFIRM TO LOGOUT CLICK HERE --> </div> </div> </dialog> diff --git a/app/views/register/index.php b/app/views/register/index.php index 40801598397ec234e88c788126974966ee90cac2..001a1695b8b17ed9814c805fad3128624a5364e3 100644 --- a/app/views/register/index.php +++ b/app/views/register/index.php @@ -36,7 +36,7 @@ id="username-input" name="username" class="login-input" - onkeyup="check_username()" + onkeyup="check_username_debounce()" required /> </div> diff --git a/app/views/search/index.php b/app/views/search/index.php new file mode 100644 index 0000000000000000000000000000000000000000..cc420e8cf211d45235fb809efc30d6ff9d1dac1b --- /dev/null +++ b/app/views/search/index.php @@ -0,0 +1,61 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <link href="../../public/css/components/pagination.css" rel="stylesheet"> + <link href="../../public/css/home/home.css" rel="stylesheet"> + <link href="../../public/css/search/search.css" rel="stylesheet"> + + <script src="../../public/js/debounce.js"></script> + <script src="../../public/js/home.js"></script> + <script src="../../public/js/search.js"></script> + <title>Document</title> +</head> +<body> + <?php include __DIR__ . '/../navbar/navbar.php'?> + <div class="container"> + <div class="search-box"> + <input placeholder="Search courses..." type="text" onkeyup="searchWithDebounce()" class="search-input" id = "search" /> + <button type="submit" onclick="searchCourse()" class="search-btn"> + <svg xmlns="http://www.w3.org/2000/svg" width="45" height="45" viewBox="0 0 24 24" style="transform: ;msFilter:;"> + <path fill= "#564c95" d="M19.023 16.977a35.13 35.13 0 0 1-1.367-1.384c-.372-.378-.596-.653-.596-.653l-2.8-1.337A6.962 6.962 0 0 0 16 9c0-3.859-3.14-7-7-7S2 5.141 2 9s3.14 7 7 7c1.763 0 3.37-.66 4.603-1.739l1.337 2.8s.275.224.653.596c.387.363.896.854 1.384 1.367l1.358 1.392.604.646 2.121-2.121-.646-.604c-.379-.372-.885-.866-1.391-1.36zM9 14c-2.757 0-5-2.243-5-5s2.243-5 5-5 5 2.243 5 5-2.243 5-5 5z"></path> + </svg> + </button> + </div> + <div class="sort-filter-container"> + <select class="sort"name="sort" id="sort" onchange="searchCourse()"> + <option selected value="">Sort By</option> + <option value="title+asc">Title Asc</option> + <option value="title+desc">Title Desc </option> + <option value="course+desc">Newest Course</option> + <option value="course+asc">Latest Course</option> + </select> + <select class="filter" name="course_password" id="course_password" onchange="searchCourse()"> + <option selected value="">Filter By Password</option> + <option value="free">Free</option> + <option value="required">Need Password</option> + </select> + <select class="filter" name="release_year" id="release_year" onchange="searchCourse()"> + <option selected value="">Filter By Year</option> + <option value="2021-now">2021 - Now</option> + <option value="2019-2021">2019 - 2021</option> + <option value="2016 - 2018">2016 - 2018</option> + <option value="<2016">Before 2016</option> + </select> + </div> + + <div class="card-container"> + <div class="cards grid-row" id="result-container"> + </div> + </div> + <?php include __DIR__ . "/../components/courseModal.php" ?> + <div class="paging"> + <div class="pagination" id="pagination"> + + </div> + </div> + </div> + +</body> +</html> \ No newline at end of file diff --git a/public/css/admin/courses.css b/public/css/admin/admin.css similarity index 72% rename from public/css/admin/courses.css rename to public/css/admin/admin.css index fa751bb1f2adc6b363183d83dbb0d65dfd9faa91..21ceff5a7e168b059e7a29446ff476ca4b1d359c 100644 --- a/public/css/admin/courses.css +++ b/public/css/admin/admin.css @@ -158,7 +158,23 @@ td { .delete-user:hover { background: red; } +.add-user { + padding-block: 10px; + border-width: 0px; + border-radius: 13px; + padding-inline: 25px; + background-color: #564c95; + cursor: pointer; +} + +.add-user a { + font-weight: bold; + color: white; +} +.add-user:hover { + opacity: 0.8; +} @media screen and (max-width: 490px) { .recent-Articles { font-size: 20px; @@ -263,37 +279,6 @@ td { visibility: visible; } -.cancelbtn, -.deletebtn { - float: center; - cursor: pointer; - padding-block: 10px; - padding-inline: 30px; - border-radius: 8px; - border-width: 0px; - font-size: 16px; - font-weight: bolder; -} - -.cancelbtn { - background-color: #ccc; -} - -.cancelbtn:hover { - background-color: darkgray; - opacity: 1; -} - -.deletebtn { - background-color: #f44336; - color: white; -} - -.deletebtn:hover { - background-color: red; - opacity: 1; -} - .clearfix { display: flex; margin-top: 20px; @@ -307,87 +292,3 @@ td { clear: both; display: table; } - -.paging { - display: flex; - align-items: center; - justify-content: center; - padding: 0 20px 20px 20px; - margin-top: 10px; -} -.pagination { - background-color: #f2f2f2; - display: flex; - position: relative; - overflow: hidden; - border-radius: 50px; -} - -.pagination a { - width: 60px; - height: 35px; - line-height: 35px; - text-align: center; - color: #333; - font-size: 12px; - font-weight: 700; - transition: 0.3s linear; - text-decoration: none; -} - -.pagination a:hover { - color: #fff; - background-color: #9e51d8; -} - -.bottom_bar { - position: absolute; - width: 100px; - height: 4px; - background-color: #000; - bottom: 0; - left: -100px; - transition: 0.4s; -} - -.pagination a:nth-child(1):hover ~ .bottom_bar { - left: 0; -} - -.pagination a:nth-child(2):hover ~ .bottom_bar { - left: 101px; -} - -.pagination a:nth-child(3):hover ~ .bottom_bar { - left: 201px; -} - -.pagination a:nth-child(4):hover ~ .bottom_bar { - left: 301px; -} - -.pagination a:nth-child(5):hover ~ .bottom_bar { - left: 401px; -} - -.pagination a:nth-child(6):hover ~ .bottom_bar { - left: 501px; -} - -.pagination a:nth-child(7):hover ~ .bottom_bar { - left: 601px; -} - -.pagination a:nth-child(8):hover ~ .bottom_bar { - left: 701px; -} - -@media (max-width: 600px) { - .pagination a:nth-child(4) { - display: none; - } - - .pagination a:nth-child(5) { - display: none; - } -} diff --git a/public/css/admin/lists.css b/public/css/admin/lists.css deleted file mode 100644 index 8d28f91c46bb5188c7d8b437d765fb0be72259b6..0000000000000000000000000000000000000000 --- a/public/css/admin/lists.css +++ /dev/null @@ -1,416 +0,0 @@ -@import url("https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"); - -* { - margin: 0; - padding: 0; - box-sizing: border-box; - font-family: "Poppins", sans-serif; -} -:root { - --background-color1: #ffeaff; - --background-color2: #ffffff; - --background-color3: #ededed; - --background-color4: #cad7fda4; - --primary-color: #4b49ac; - --secondary-color: #0c007d; - --Border-color: #3f0097; - --one-use-color: #3f0097; - --two-use-color: #5500cb; -} - -.main { - margin: auto; - padding: auto 20px; - padding-top: 60px; -} - -body { - background-color: var(--background-color1); - max-width: 100%; - overflow-x: hidden; -} - -.report-container { - max-height: 80vh; - max-width: 80vw; - margin: auto; - background-color: #ffffff; - border-radius: 30px; - box-shadow: 3px 3px 10px rgb(188, 188, 188); - padding: 0px 20px 20px 20px; -} - -.report-header { - height: 80px; - width: 100%; - display: flex; - align-items: center; - justify-content: space-between; - padding: 20px 20px 10px 20px; - border-bottom: 2px solid rgba(0, 20, 151, 0.59); -} - -.add-user { - padding-block: 10px; - border-width: 0px; - border-radius: 13px; - padding-inline: 25px; - background-color: #564c95; - - cursor: pointer; -} - -.add-user a { - font-weight: bold; - color: white; -} - -.add-user:hover { - opacity: 0.8; -} - -.header-button { - margin-right: 10px; -} - -.recent-Articles { - font-size: 30px; - font-weight: 600; - color: #5500cb; -} - -.report-body { - width: 100%; - padding: 15px; -} - -.label-tag { - width: 100px; - text-align: center; - border-radius: 4px; -} - -.report-body .container { - max-height: 80%; - width: 100%; -} - -table { - word-break: break-word; - margin-left: auto; - margin-right: auto; - font-size: 14px; - width: 100%; - table-layout: fixed; - justify-content: center; - margin-top: 5px; - border-collapse: collapse; -} - -.id-column { - width: 7%; -} - -th { - background-color: #564c95; - color: white; -} - -td { - border: 1px solid black; - text-align: center; - padding: 10px; -} -.action { - align-items: center; - justify-content: center; - gap: 10px; -} -.edit-icon, -.delete-icon { - cursor: pointer; - font-size: 14px; - font-weight: bold; -} - -.edit-icon:hover, -.delete-icon:hover { - opacity: 0.5; -} - -tr:nth-child(even) { - background-color: #f8e4ff; -} - -th { - padding-block: 12px; -} -.data, -td { - padding-inline: 12px; - border: none; -} - -.action { - margin: 0; - display: flex; -} - -.edit-user { - width: 40%; - cursor: pointer; - background: #597aff; - color: white; - font-weight: 700px; - border: 1px solid black; -} - -.edit-user:hover { - background: #214dff; -} - -.delete-user { - width: 40%; - cursor: pointer; - background: rgb(255, 61, 61); - color: white; - font-weight: 700px; - border: 1px solid black; -} - -.delete-user:hover { - background: red; -} - -@media screen and (max-width: 490px) { - .recent-Articles { - font-size: 20px; - } -} - -@media screen and (max-width: 400px) { - .report-header { - height: 60px; - padding: 10px 10px 5px 10px; - } -} - -@media screen and (max-width: 320px) { - .recent-Articles { - font-size: 12px; - } - .report-header { - height: 60px; - padding: 10px 5px 5px 5px; - } - .report-body { - padding: 10px; - } -} - -.delete-user a { - width: 40%; - cursor: pointer; - background: rgb(255, 61, 61); - color: white; - font-weight: 700px; - border: none; - text-decoration: none; - margin-left: 3px; -} - -#edit-popup { - width: 100%; - height: 100%; - position: fixed; - background: rgba(0, 0, 0, 0.7); - top: 0; - left: 0; - z-index: 9999; - visibility: hidden; - padding-block: 10px; -} - -#delete-popup { - width: 100%; - height: 100%; - position: fixed; - background: rgba(0, 0, 0, 0.7); - top: 0; - left: 0; - z-index: 9999; - visibility: hidden; - padding-block: 10px; -} - -.window { - width: 500px; - height: 300px; - background: #fff; - border-radius: 10px; - position: absolute; - left: 35%; - top: 25%; - justify-content: center; - align-items: center; - display: flex; - flex-direction: column; - padding-bottom: 20px; -} - -.window h2 { - margin: 30px 0 0 0; -} - -.close-button { - width: 50px; - height: 50px; - line-height: 23px; - background: #000; - border-radius: 50%; - border: 3px solid #fff; - display: block; - text-align: center; - color: #fff; - text-decoration: none; - position: absolute; - top: -10px; - right: -10px; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; -} - -#popup:target { - visibility: visible; -} - -.cancelbtn, -.deletebtn { - float: center; - cursor: pointer; - padding-block: 10px; - padding-inline: 30px; - border-radius: 8px; - border-width: 0px; - font-size: 16px; - font-weight: bolder; -} - -.cancelbtn { - background-color: #ccc; -} - -.cancelbtn:hover { - background-color: darkgray; - opacity: 1; -} - -.deletebtn { - background-color: #f44336; - color: white; -} - -.deletebtn:hover { - background-color: red; - opacity: 1; -} - -.clearfix { - display: flex; - margin-top: 20px; - width: 100%; - justify-content: center; - gap: 15px; -} - -.clearfix::after { - content: ""; - clear: both; - display: table; -} - -.paging { - display: flex; - align-items: center; - justify-content: center; - padding: 0 20px 20px 20px; - margin-top: 10px; -} -.pagination { - background-color: #f2f2f2; - display: flex; - position: relative; - overflow: hidden; - border-radius: 50px; -} - -.pagination a { - width: 60px; - height: 35px; - line-height: 35px; - text-align: center; - color: #333; - font-size: 12px; - font-weight: 700; - transition: 0.3s linear; - text-decoration: none; -} - -.pagination a:hover { - color: #fff; - background-color: #9e51d8; -} - -.bottom_bar { - position: absolute; - width: 100px; - height: 4px; - background-color: #000; - bottom: 0; - left: -100px; - transition: 0.4s; -} - -.pagination a:nth-child(1):hover ~ .bottom_bar { - left: 0; -} - -.pagination a:nth-child(2):hover ~ .bottom_bar { - left: 101px; -} - -.pagination a:nth-child(3):hover ~ .bottom_bar { - left: 201px; -} - -.pagination a:nth-child(4):hover ~ .bottom_bar { - left: 301px; -} - -.pagination a:nth-child(5):hover ~ .bottom_bar { - left: 401px; -} - -.pagination a:nth-child(6):hover ~ .bottom_bar { - left: 501px; -} - -.pagination a:nth-child(7):hover ~ .bottom_bar { - left: 601px; -} - -.pagination a:nth-child(8):hover ~ .bottom_bar { - left: 701px; -} - -@media (max-width: 600px) { - .pagination a:nth-child(4) { - display: none; - } - - .pagination a:nth-child(5) { - display: none; - } -} diff --git a/public/css/components/button.css b/public/css/components/button.css new file mode 100644 index 0000000000000000000000000000000000000000..9eb11f10cea44c63eb4579b53409ddb4bca7c37e --- /dev/null +++ b/public/css/components/button.css @@ -0,0 +1,35 @@ +.cancelbtn, +.deletebtn { + float: center; + cursor: pointer; + padding-block: 10px; + padding-inline: 30px; + border-radius: 8px; + border-width: 0px; + font-size: 16px; + font-weight: bolder; +} +.cancelbtn { + background-color: #ccc; +} + +.cancelbtn:hover { + background-color: darkgray; + opacity: 1; +} + +.deletebtn { + background-color: #f44336; + color: white; +} + +.deletebtn:hover { + background-color: red; + opacity: 1; +} + +.delete-link{ + text-decoration: none; + color: #fff; + font-weight: bold; +} diff --git a/public/css/components/pagination.css b/public/css/components/pagination.css new file mode 100644 index 0000000000000000000000000000000000000000..cc5d1b724bdbd7aef928eb8fe8d28dc27db7da1f --- /dev/null +++ b/public/css/components/pagination.css @@ -0,0 +1,83 @@ +.paging { + display: flex; + align-items: center; + justify-content: center; + padding: 0 20px 20px 20px; + margin-top: 10px; +} +.pagination { + background-color: #f2f2f2; + display: flex; + position: relative; + overflow: hidden; + border-radius: 50px; +} + +.pagination a { + width: 60px; + height: 35px; + line-height: 35px; + text-align: center; + color: #333; + font-size: 12px; + font-weight: 700; + transition: 0.3s linear; + text-decoration: none; +} + +.pagination a:hover { + color: #fff; + background-color: #9e51d8; +} + +.bottom_bar { + position: absolute; + width: 100px; + height: 4px; + background-color: #000; + bottom: 0; + left: -100px; + transition: 0.4s; +} + +.pagination a:nth-child(1):hover ~ .bottom_bar { + left: 0; +} + +.pagination a:nth-child(2):hover ~ .bottom_bar { + left: 101px; +} + +.pagination a:nth-child(3):hover ~ .bottom_bar { + left: 201px; +} + +.pagination a:nth-child(4):hover ~ .bottom_bar { + left: 301px; +} + +.pagination a:nth-child(5):hover ~ .bottom_bar { + left: 401px; +} + +.pagination a:nth-child(6):hover ~ .bottom_bar { + left: 501px; +} + +.pagination a:nth-child(7):hover ~ .bottom_bar { + left: 601px; +} + +.pagination a:nth-child(8):hover ~ .bottom_bar { + left: 701px; +} + +@media (max-width: 600px) { + .pagination a:nth-child(4) { + display: none; + } + + .pagination a:nth-child(5) { + display: none; + } +} diff --git a/public/css/home/home.css b/public/css/home/home.css index 022ed0590f87c7f02369e4dc19c134547739eab3..f8f3ca6f89d96469574d698475434f8225ff61b8 100644 --- a/public/css/home/home.css +++ b/public/css/home/home.css @@ -86,132 +86,6 @@ to{opacity: 1} } -/* Search Bar */ -.search-sort{ - display: flex; - margin: auto; - padding: 0px 10px; -} - -.search-bar{ - background: #fff; - width: 90%; - max-width: 600px; - display: flex; - padding: 5px; - border-radius: 4px; - height: 40px; - margin: auto; - margin-right: 20px; -} - -#select{ - background: #ffffff; - display: flex; - align-items: center; - justify-content: space-between; - color: #1c1c1c; - width: 33%; - padding: 10px 2px 10px 10px; - font-size: 13px; - cursor: pointer; - border: 1px solid #dadada; - display: inline-flex; - min-width: fit-content; -} - -#select:hover{ - background-color: #dadada; -} - -#select ul{ - position: absolute; - margin-top: 198px; - list-style: none; - background: #fff; - color: #555; - width: 10.329%; - min-width: fit-content; - max-height: 0; - overflow: hidden; - transition: max-height 0.3s; - transform: translateX(-11px); - justify-content: space-between; -} - -#select ul li{ - padding: 8px 10px; - cursor: pointer; -} - -#select ul li:hover{ - background-color: #dadada; -} - -.search-bar input{ - padding: 10px 25px; - width: 100%; - border: none; - outline: none; - font-size: 13px; - border-radius: 4px; -} - -#select ul.open{ - max-height: 300px; - border: 1px solid #dadada; -} - -#sort{ - margin: auto; - margin-left: 0px; - background: #ffffff; - display: flex; - align-items: center; - justify-content: space-between; - color: #1c1c1c; - width: 12%; - padding: 10px; - font-size: 13px; - cursor: pointer; - display: inline-flex; - min-width: fit-content; - border-radius: 4px; -} - -#sort:hover{ - background-color: #dadada; -} - -#sort ul{ - position: absolute; - margin-top: 174px; - list-style: none; - background: #fff; - color: #555; - width: 10.329%; - min-width: fit-content; - max-height: 0; - overflow: hidden; - transition: max-height 0.3s; - transform: translateX(-11px); - justify-content: space-between; -} - -#sort ul li{ - padding: 8px 10px; - cursor: pointer; -} - -#sort ul li:hover{ - background-color: #dadada; -} - -#sort ul.open{ - max-height: 300px; - border: 1px solid #dadada; -} - /* Courses */ .grid-row{ display: grid; @@ -300,6 +174,17 @@ background-color: #c180ff; } +.wrapper{ + display: flex; + width: 100%; + flex-direction: column; +} + +.wrapper input{ + padding: 10px; + margin-bottom: 5px; +} + @media screen and (max-width: 753px) { div.header{ display: none; @@ -309,82 +194,6 @@ } } -/* PAGINATION */ -.paging{ - display: flex; - align-items: center; - justify-content: center; - padding: 0 20px 20px 20px; -} - -.pagination{ - background-color: #ffffff; - display: flex; - position: relative; - overflow: hidden; - border-radius: 50px; -} - -.pagination a{ - width: 60px; - height: 35px; - line-height: 35px; - text-align: center; - color: #333; - font-size: 12px; - font-weight: 700; - transition: .3s linear; - text-decoration: none; -} - -.pagination a:hover{ - color: #fff; - background-color: #5271e9; -} - -.pagination a:nth-child(1):hover ~ .bottom_bar{ - left: 0; -} - -.pagination a:nth-child(2):hover ~ .bottom_bar{ - left: 101px; -} - -.pagination a:nth-child(3):hover ~ .bottom_bar{ - left: 201px; -} - -.pagination a:nth-child(4):hover ~ .bottom_bar{ - left: 301px; -} - -.pagination a:nth-child(5):hover ~ .bottom_bar{ - left: 401px; -} - -.pagination a:nth-child(6):hover ~ .bottom_bar{ - left: 501px; -} - -.pagination a:nth-child(7):hover ~ .bottom_bar{ - left: 601px; -} - -.pagination a:nth-child(8):hover ~ .bottom_bar{ - left: 701px; -} - -@media (max-width:600px) - { - .pagination a:nth-child(4){ - display: none; - } - - .pagination a:nth-child(5){ - display: none; - } - } - .modal-container .flex{ display: flex; align-items: center; diff --git a/public/css/navbar/navbar.css b/public/css/navbar/navbar.css index 3d4382ab51f5fe18e3fc2435d4dd30f72a9b9d34..a3c62b45d7d22ca8b78774dae5e7faaaad89e6fe 100644 --- a/public/css/navbar/navbar.css +++ b/public/css/navbar/navbar.css @@ -1,31 +1,31 @@ @import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600;700&display=swap"); -*{ +* { margin: 0; padding: 0; box-sizing: border-box; - font-family: "Open Sans" , sans-serif; + font-family: "Open Sans", sans-serif; } -.sidebar{ +.sidebar { position: fixed; left: 0; top: 0; height: 100%; width: 78px; - background: #564C95; + background: #564c95; padding: 6px 14px; z-index: 99; transition: all 0.5s ease; } -.sidebar.open{ +.sidebar.open { width: 250px; border-top-right-radius: 10px; border-bottom-right-radius: 10px; } -.sidebar .logo-details{ +.sidebar .logo-details { height: 70px; width: 100; display: flex; @@ -33,19 +33,19 @@ position: relative; } -.sidebar .logo-details .logo-img{ - opacity: 0; - width: 130px; - height: auto; - transition: all 0.25s ease; +.sidebar .logo-details .logo-img { + opacity: 0; + width: 130px; + height: auto; + transition: all 0.25s ease; } - -.sidebar.open .logo-details .logo-img{ + +.sidebar.open .logo-details .logo-img { transition: all 0.8s ease; opacity: 1; } -.sidebar .logo-details #btn{ +.sidebar .logo-details #btn { position: absolute; top: 50%; right: 13px; @@ -58,12 +58,12 @@ transition: all 0.5s ease; } -.sidebar.open .logo-details #btn{ +.sidebar.open .logo-details #btn { text-align: right; right: -10px; } -.sidebar .nav-list .profile-details .photo{ +.sidebar .nav-list .profile-details .photo { width: 50px; height: 50px; object-fit: contain; @@ -76,7 +76,7 @@ } .sidebar .nav-list .profile-details .name, -.sidebar .nav-list .profile-details .job{ +.sidebar .nav-list .profile-details .job { font-size: 15px; font-weight: 400; color: white; @@ -86,17 +86,17 @@ margin-left: 10px; } -.sidebar .nav-list .profile-details .job{ +.sidebar .nav-list .profile-details .job { font-size: 12px; } .sidebar.open .nav-list .profile-details .name, -.sidebar.open .nav-list .profile-details .job{ +.sidebar.open .nav-list .profile-details .job { display: flex; opacity: 1; } -.sidebar .nav-list i{ +.sidebar .nav-list i { color: #000000; min-width: 50px; font-size: 32px; @@ -104,19 +104,19 @@ line-height: 50px; } -.sidebar .nav-list{ +.sidebar .nav-list { margin-top: 20px; height: 100%; width: 100%; } -.sidebar li{ +.sidebar li { position: relative; margin: 8px 0; list-style: none; } -.sidebar li .tooltip{ +.sidebar li .tooltip { position: absolute; top: -20px; left: calc(100% + 15px); @@ -132,7 +132,7 @@ transition: 0s; } -.sidebar li:hover .tooltip{ +.sidebar li:hover .tooltip { opacity: 1; pointer-events: auto; transition: all 0.4s ease; @@ -140,11 +140,12 @@ transform: translateY(-50%); } -.sidebar.open li .tooltip{ +.sidebar.open li .tooltip { display: none; } -.sidebar li a, .sidebar li .logbtn{ +.sidebar li a, +.sidebar li .logbtn { display: flex; height: 100%; width: 100%; @@ -154,13 +155,15 @@ transition: all 0.4s ease; } -.sidebar li a:hover, .sidebar li .logbtn:hover{ +.sidebar li a:hover, +.sidebar li .logbtn:hover { background: #dbdbdb; } -.name-job .name{ +.name-job .name { color: white; } -.sidebar li a .link-name, .sidebar li .logbtn .link-name{ +.sidebar li a .link-name, +.sidebar li .logbtn .link-name { color: #ffffff; font-size: 15px; font-weight: 400; @@ -171,7 +174,8 @@ margin-left: 8px; } -.sidebar.open li a .link-name, .sidebar.open li .logbtn .link-name{ +.sidebar.open li a .link-name, +.sidebar.open li .logbtn .link-name { opacity: 1; pointer-events: auto; color: white; @@ -180,37 +184,38 @@ .sidebar li a:hover .link-name, .sidebar li a:hover i, .sidebar li .logbtn:hover .link-name, -.sidebar li .logbtn:hover i{ +.sidebar li .logbtn:hover i { transition: all 0.5s ease; color: #b700ff; } -.sidebar li .logbtn{ +.sidebar li .logbtn { border: none; cursor: pointer; background-color: transparent; } -.sidebar .footer{ +.sidebar .footer { position: absolute; left: 0; bottom: 0; - background: #564C95; + background: #564c95; width: 78px; padding: 6px 14px; z-index: 99; transition: all 0.5s ease; font-size: 8px; text-align: center; + color: white; } -.sidebar.open .footer{ - width:200px; +.sidebar.open .footer { + width: 200px; } -.home-section{ +.home-section { position: relative; - background: #E4E9F7; + background: #e4e9f7; min-height: 100vh; top: 0; left: 78px; @@ -219,71 +224,79 @@ z-index: 2; } -.sidebar.open ~ .home-section{ +.sidebar.open ~ .home-section { left: 180px; width: calc(100% - 180px); } -.home-section .text{ +.home-section .text { display: inline-block; color: #11101d; font-size: 25px; font-weight: 500; - margin: 18px + margin: 18px; } @media (max-width: 420px) { - .sidebar li .tooltip{ + .sidebar li .tooltip { display: none; } } -.modal-container-logout .buttons-logout{ +.modal-container-logout .buttons-logout { margin-top: 40px; + display: flex; + flex-direction: row; + gap: 10px; + align-self: center; + justify-content: center; } .modal-container-logout .close-btn-logout, -.modal-container-logout .confirm-logout{ +.modal-container-logout .confirm-logout { cursor: pointer; - border: none; - font-size: 16px; - color: white; - background: #597aff; - padding: 5px 15px; - border-radius: 4px; - font-weight: 700px; - left: 100px; + border: none; + font-size: 16px; + color: white; + background-color: #ccc; + padding: 5px 15px; + border-radius: 4px; + font-weight: 700px; + left: 100px; } -.modal-container-logout .close-btn-logout:hover{ +.modal-container-logout .close-btn-logout:hover { background: #214dff; } -.modal-container-logout .confirm-logout:hover{ +.modal-container-logout .confirm-logout:hover { background: red; } -.modal-container-logout .confirm-logout{ - background: rgb(255, 61, 61); +.modal-container-logout .confirm-logout { + background-color: #f44336; margin-left: 25px; } -.modal-container-logout{ +.modal-container-logout { margin-left: 20%; margin-right: 20%; width: 60%; - text-align: center; + text-align: center; } -.modal-container-logout i{ +.modal-container-logout i { font-size: 100px; color: red; margin-top: 20px; } -#dialog-logout{ - width: 350px; +#dialog-logout { + width: 500px; height: 300px; + border-radius: 10px; + justify-content: center; + align-items: center; min-width: 300px; min-height: 300px; border: none; @@ -291,9 +304,13 @@ padding: auto; } -#overlay-logout{ +#overlay-logout { width: 100%; background-color: transparent; display: none; position: fixed; } + +.text-xs { + color: white; +} diff --git a/public/css/search/search.css b/public/css/search/search.css new file mode 100644 index 0000000000000000000000000000000000000000..61b6348a55190f785d0b5852ee6385c8bd51bbc2 --- /dev/null +++ b/public/css/search/search.css @@ -0,0 +1,143 @@ +.container{ + width: 100vw; + height: 100vh; + background-color: #e6c5e6; + display: flex; + flex-direction: column; + align-items: center; + padding-top: 30px; + padding-left: 10em; + padding-right: 30px; + overflow-y: auto; +} +.search-box{ + width: 100%; + display: flex; +} + +.search-input{ + width: 80%; + padding-inline: 10px; + padding-block: 12px; + border-radius: 20px; + border-width: 0px; +} + +/* Header */ +.home-section .search-field{ + width: 100%; + max-width: 700px; + background: rgba(255, 0, 0, 0.2); + display: flex; + align-items: center; + border-radius: 60px; + padding: 10px 20px; +} + +.home-section .search-field input{ + background: transparent; + flex: 1; + border: 0; + outline: none; + padding: 14px 20px; + font-size: 20px; + color: #cac7ff; +} + +*{box-sizing:border-box} + +.header{ + padding: 30px 10px; +} + +.slideshow-container{ + max-width: 1250px; + max-height: 200px; + position: relative; + margin: auto; +} + +.mySlides{ + display: none; +} + +.prev, .next{ + cursor: pointer; + position: absolute; + top: 50%; + width: auto; + margin-top: -22px; + padding: 16px; + color: white; + background-color: rgba(0, 0, 0, 0.5); + font-weight: bold; + font-size: 18px; + transition: 0.6s ease; + border-radius: 0 3px 3px 0; + user-select: none; +} + +.next{ + right: 0; + border-radius: 3px 0 0 3px; +} + +.prev:hover, .next:hover{ + background-color: rgba(0,0,0,0.8); +} + +.dot{ + cursor: pointer; + height: 10px; + width: 10px; + margin: 0 2px; + background-color: #bbb; + border-radius: 50%; + display: inline-block; + transition: background-color 0.6s ease; +} + +.active, .dot:hover{ + background-color: #717171; +} + +.fade{ + animation-name: fade; + animation-duration: 1.5s; +} + +@keyframes fade{ + from{opacity: .4} + to{opacity: 1} +} + +/* Search Bar */ +.search-sort{ + display: flex; + margin: auto; + padding: 0px 10px; +} + +.sort-filter-container{ + width: 100%; + display: flex; + flex-direction: row; + align-items: start; + margin-top: 10px; + gap: 10px; +} +.sort, .filter{ + padding: 10px; + border-radius: 10px; + border-width: 0px; + width: 20%; +} + +.search-btn{ + background-color: transparent; + border-width: 0px; +} + +#pagination a{ + cursor: pointer; +} diff --git a/public/js/debounce.js b/public/js/debounce.js new file mode 100644 index 0000000000000000000000000000000000000000..72b9326f9acacc8eb4249676a07a5842f210cc15 --- /dev/null +++ b/public/js/debounce.js @@ -0,0 +1,9 @@ +const debounce = (fn, delay = 1000) => { + let timer; + return (...args) => { + clearTimeout(timer); + timer = setTimeout(() => { + fn(...args); + }, delay); + }; + }; \ No newline at end of file diff --git a/public/js/home.js b/public/js/home.js index 5a0ddb05b5e45d66eb7bcc865f92f35c916d3f9f..6bb657a8d9ba60008a85409f4af991fd0c8b300e 100644 --- a/public/js/home.js +++ b/public/js/home.js @@ -1,6 +1,9 @@ // -------------- HEADER SLIDESHOW ---------------------- let slideIndex = 1; -showSlides(slideIndex); + +if (!window.location.href.includes("search")) { + showSlides(slideIndex); +} function plusSlides(n) { showSlides((slideIndex += n)); @@ -30,41 +33,17 @@ function showSlides(n) { dots[slideIndex - 1].className += " active"; } -// -------------- SEARCH BAR WITH FILTER ---------------------- -let select = document.getElementById("select"); -let list = document.getElementById("list"); -let selectText = document.getElementById("selectText"); -let inputField = document.getElementById("inputField"); -let options = document.getElementsByClassName("options"); - -select.onclick = function () { - list.classList.toggle("open"); -}; - -for (option of options) { - option.onclick = function () { - selectText.innerHTML = this.innerHTML; - inputField.placeholder = "Search In " + selectText.innerHTML; - }; -} - -// ---------------------- SORT -------------------------- -let sort = document.getElementById("sort"); -let sortOptions = document.getElementsByClassName("sort-options"); - -sort.onclick = function () { - sortList.classList.toggle("open"); -}; - -for (option of sortOptions) { - option.onclick = function () { - sortText.innerHTML = this.innerHTML; - }; -} - // ------------------- ENROLLMENT POPUP ----------------------- -function openModal(joined, id, title, description, formattedDate) { +function openModal( + joined, + id, + title, + description, + formattedDate, + course_password +) { + console.log(joined,id,title,description,formattedDate,course_password); var myDialog = document.getElementById("dialog"); var overlay = document.getElementById("overlay"); var upload_text = document.getElementById("upload-date"); @@ -80,36 +59,39 @@ function openModal(joined, id, title, description, formattedDate) { upload_text.innerText = formattedDate; course_id.innerText = id; if (joined) { + // Kalau sudah bergabung enroll_button.style.display = "none"; - go_button.style.display = "block"; + go_button.style.visibility = "visible"; } else { + // Kalau belum berabung + enroll_button.style.display = "block"; + go_button.style.visibility = "hidden"; + if (course_password && course_password !== "null") { + var input_button = document.getElementById("password-input"); + input_button.type = "text"; + } } } -const closeModalBtn = document.querySelector(".close-btn"); - -// close modal when the Esc key is pressed -document.addEventListener("keydown", function (e) { - if (e.key === "Escape" && !modal.classList.contains("hidden")) { - closeModal(); - } -}); - -closeModalBtn.addEventListener("click", () => { - dialog.close(); -}); - function closeDialog() { var dialog = document.getElementById("dialog"); var overlay = document.getElementById("overlay"); + var input = document.getElementById("password-input"); + var enroll = document.getElementById("course-detail"); + enroll.style.visibility = "hidden"; + input.value = ""; + input.type = "hidden"; dialog.close(); overlay.style.display = "none"; } function enrolled() { + var password_input = document.getElementById("password-input"); const course_id = document.getElementById("course_id").innerText; + var course_password = password_input.value; const data = new FormData(); data.append("course_id", course_id); + data.append("course_password", course_password); const xml = new XMLHttpRequest(); xml.open("POST", "/api/course/enroll.php"); xml.onload = function () { diff --git a/public/js/register.js b/public/js/register.js index d22ee7539be50e97fbe496e45c240684619d48fc..73d95bbeaf666ca22c5a1409d991acdf19e2c467 100644 --- a/public/js/register.js +++ b/public/js/register.js @@ -62,14 +62,14 @@ const check_username = () => { // Kalau response success, berarti username unique reset(username_alert); username_input.style.borderColor = "green"; - }else{ + } else { // Kalau tidak succes, berarti username sudah dimiliki pengguna lain - username_alert.className = "alert-show" + username_alert.className = "alert-show"; username_alert.innerText = response.message; username_input.style.borderColor = "red"; - check_button() + check_button(); } - } + } }; check_button(); xmr.send(JSON.stringify({ username: username })); @@ -99,3 +99,14 @@ const check_password = () => { } check_button(); }; +const debounce = (fn, delay = 1000) => { + let timer; + return (...args) => { + clearTimeout(timer); + timer = setTimeout(() => { + fn(...args); + }, delay); + }; +}; + +const check_username_debounce = debounce(check_username); diff --git a/public/js/search.js b/public/js/search.js new file mode 100644 index 0000000000000000000000000000000000000000..eb95d439457b517553ad7fa9a1c9bf1ddf9121c8 --- /dev/null +++ b/public/js/search.js @@ -0,0 +1,119 @@ +const getNewUrl = (added_url) => { + return "/search/" + added_url; +}; + +const searchCourse = (page_number = 1) => { + let request_url = "/api/course/search.php?"; + let added_url = ""; + try { + const title = document.getElementById("search").value; + const sort = document.getElementById("sort").value; + const password = document.getElementById("course_password").value; + const release_year = document.getElementById("release_year").value; + if (title.length > 0) { + added_url += "title=" + title; + } + if (sort) { + added_url += "&sort=" + sort; + } + if (password) { + if (password === "required") { + added_url += "&password=true"; + } else { + added_url += "&password=false"; + } + } + if (release_year) { + added_url += "&release_year=" + release_year; + } + } catch (error) { + console.log(error); + } + + let page = "&page=" + page_number; + added_url += page; + let final_url = (request_url += added_url); + window.history.pushState( + { path: getNewUrl(added_url) }, + "", + getNewUrl(added_url) + ); + const xhr = new XMLHttpRequest(); + xhr.open("GET", final_url, true); + xhr.onload = function () { + console.log(this); + if (this.status === 200) { + let data = JSON.parse(this.responseText); + let courses = data["courses"]; + let max_page = data["max_page"]; + let joined_courses = data["joined_courses"]; + let result_container = document.getElementById("result-container"); + let pagination = document.getElementById("pagination"); + let prev_index = page_number <= 1 ? 1 : page_number - 1; + let has_joined = false; + result_container.innerHTML = ""; + pagination.innerHTML = ""; + if (courses.length === 0) { + result_container.innerHTML = `<p>No courses match your search...</p>`; + } else { + courses.forEach((course) => { + if (joined_courses.includes(course)) { + has_joined = true; + } + const formattedDate = new Date(course["release_date"]); + const day = formattedDate.getDay(); + result_container.innerHTML += `<div class='card' onclick='openModal( + ${has_joined}, + "${course["course_id"]}", + "${course["title"]}", + "${course["description"]}", + "${course["release_date"]}", + "${course["course_password"]}")' style='cursor:pointer'> + <div class='card-top'> + <img src='${course["image_path"]}' /? + </div> + <div class='card-info'> + <div class='course-name'> + <h2>${course["title"]}</h2> + </div> + <span class='lecturer'>${course["description"]}</span> + </div> + <div class='card-bottom flex-row'> + <p>${day}</p> + </div> + </div>`; + }); + if (page_number > 1) { + prev_index = page_number - 1; + pagination.innerHTML += `<a onclick='searchCourse(${prev_index})'>PREV</a>`; + } + for (let i = prev_index; i < page_number + 2; i++) { + if (i == max_page) { + break; + } + if (i === page_number) { + pagination.innerHTML += `<a style='background-color:#9e51d8;color:white;'>${i}</a>`; + } else { + pagination.innerHTML += `<a id='pagination-number' onclick='searchCourse(${i})'>${i}</a>`; + } + } + if (page_number < max_page - 2) { + pagination.innerHTML += "<a>...</a>"; + } + if (page_number === max_page) { + pagination.innerHTML += `<a style='background-color:#9e51d8;color:white;'>${max_page}</a>`; + } else { + pagination.innerHTML += `<a onclick='searchCourse(${max_page})'>${max_page}</a>`; + } + + if (page_number < max_page) { + next_index = page_number + 1; + pagination.innerHTML += `<a onclick='searchCourse(${next_index})'>NEXT</a>`; + } + } + } + }; + xhr.send(); +}; + +const searchWithDebounce = debounce(searchCourse); \ No newline at end of file