diff --git a/app/controllers/Learn.php b/app/controllers/Learn.php index 968c0b96c54ec1bea14ab3bed18e78952cf456c0..30156ec9c19a855a03c8332b908590bae475066f 100644 --- a/app/controllers/Learn.php +++ b/app/controllers/Learn.php @@ -7,15 +7,45 @@ class Learn extends Controller { exit(); } - $data["pageTitle"] = "Toco | Your journey starts here!"; + $data["pageTitle"] = "Your journey starts here!"; + $data["languages"] = $this->model("LanguageModel")->getAllLanguage(); $this->view('header/index', $data); $this->view('navbar/index'); - $this->view('learn/index'); + $this->view('learn/index', $data); $this->view('footer/index'); } private function isLoggedIn() { return isset($_SESSION['username']) && !empty($_SESSION['username']); } + + public function lesson($languageId = null, $moduleId = null, $videoId = null) { + if (!$this->isLoggedIn()) { + header('Location: /login'); + exit(); + } + + // Video + if (isset($languageId) && !empty($languageId) && isset($moduleId) && !empty($moduleId) && isset($videoId) && !empty($videoId)) { + + } + // List of modules + else if (isset($languageId) && !empty($languageId)) { + $data["pageTitle"] = "Keep learning!"; + $data["language"] = $this->model("LanguageModel")->getLanguageById($languageId); + $data["modules"] = $this->model("ModuleModel")->getModulesByLanguageId($languageId); + for ($i = 0; $i < count($data["modules"]); $i++) { + $data["modules"][$i]["videos"] = $this->model("VideoModel")->getVideosByModuleId($data["modules"][$i]["module_id"]); + } + + $this->view('header/index', $data); + $this->view('navbar/index'); + $this->view('lesson/index', $data); + $this->view('footer/index'); + } else { + header('Location: /404'); + exit(); + } + } } diff --git a/app/views/header/index.php b/app/views/header/index.php index 03bea77e2eebf5d20f0b36a9ff72d98b3274fe3d..598baeef7d93a8354ba830aa12298e96547b7398 100644 --- a/app/views/header/index.php +++ b/app/views/header/index.php @@ -19,6 +19,7 @@ <link rel="stylesheet" href="/public/css/login.css"> <link rel="stylesheet" href="/public/css/register.css"> <link rel="stylesheet" href="/public/css/learn.css"> + <link rel="stylesheet" href="/public/css/lesson.css"> <link rel="stylesheet" href="/public/css/profile.css"> <link rel="stylesheet" href="/public/css/dashboard.css"> <link rel="stylesheet" href="/public/css/manage.css"> diff --git a/app/views/learn/index.php b/app/views/learn/index.php index 56f6c8dc55f129fa26e24685886f576ea7671b78..49f9d0de948d561e5b69061b204663f7787d8b10 100644 --- a/app/views/learn/index.php +++ b/app/views/learn/index.php @@ -16,46 +16,18 @@ I want to learn ... </h1> <div class="learn-container"> + <?php foreach ($data["languages"] as $language): ?> <div class="learn-card"> - <a href="/preview"> + <a href="/learn/lesson/<?= $language["language_id"] ?>"> <div> - <img class="learn-card-image" src="../../../public/icons/uk-flag.svg" alt="English" height="130px"> + <img class="learn-card-image" src="<?= $language["language_flag"] ?>" alt="English" height="130px"> <h2 class="learn-card-header"> - English - </h2> - </div> - </a> - </div> - <div class="learn-card"> - <a href="/preview"> - <div> - <img class="learn-card-image" src="../../../public/icons/id-flag.svg" alt="Indonesian" height="130px"> - <h2 class="learn-card-header"> - Indonesian - </h2> - </div> - </a> - </div> - <div class="learn-card"> - <a href="/preview"> - <div> - <img class="learn-card-image" src="../../../public/icons/fr-flag.svg" alt="French" height="130px"> - <h2 class="learn-card-header"> - French - </h2> - </div> - </a> - </div> - <div class="learn-card"> - <a href="?preview"> - <div> - <img class="learn-card-image" src="../../../public/icons/gr-flag.svg" alt="Germany" height="130px"> - <h2 class="learn-card-header"> - Germany + <?= $language["language_name"] ?> </h2> </div> </a> </div> + <?php endforeach ?> </div> </div> </div> diff --git a/app/views/lesson/index.php b/app/views/lesson/index.php new file mode 100644 index 0000000000000000000000000000000000000000..4dd73150e632d834bfb3295ba4509dc9f4c1ec94 --- /dev/null +++ b/app/views/lesson/index.php @@ -0,0 +1,104 @@ +<?php +?> + +<div class="lesson"> + <div class="container lesson-container"> + <h1 class="font-bold text-xl text-blue-purple-gradient"> + <?= $data["language"]["language_name"] ?> + </h1> + + <form action="" method="GET"> + <div class="search-bar"> + <input type="text" placeholder="Search modules or videos" class="text-sm text-black font-reg"> + <button type="submit"> + <img id="search-icon" src="/public/icons/search-icon.svg" alt="Search icon"> + </button> + </div> + + <div class="filter-sort"> + <select name="difficulty" id="difficulty-input" class="text-sm font-reg text-black"> + <option value="Beginner" selected>Beginner</option> + <option value="Intermediate">Intermediate</option> + <option value="Advanced">Advanced</option> + </select> + + <label class="sort-container text-sm font-reg">Sort A-Z + <input type="checkbox" id="sort-input" name="sort" value="true"> + <span class="checkmark"></span> + </label> + </div> + </form> + + <div class="card-container"> + <?php foreach ($data["modules"] as $module): ?> + <div class="module-card"> + <div class="module-head"> + <div class="content"> + <h2 class="font-bold text-md"> + <?= $module["module_name"] ?> + </h2> + <span class="font-reg text-xs"> + <?= $module["difficulty"] ?> ● <?= $module["category"] ?> ● <?= count($module["videos"]) ?> videos + </span> + </div> + + <svg class="check-icon" width="41" height="42" viewBox="0 0 41 42" fill="none" xmlns="http://www.w3.org/2000/svg"> + <path fill-rule="evenodd" clip-rule="evenodd" d="M20.5 41.5C31.8221 41.5 41 32.3221 41 21C41 9.67785 31.8221 0.5 20.5 0.5C9.17785 0.5 0 9.67785 0 21C0 32.3221 9.17785 41.5 20.5 41.5ZM27.7488 13.7512C28.1337 13.3668 28.6556 13.1511 29.1996 13.1515C29.7436 13.1518 30.2652 13.3683 30.6495 13.7533C31.0339 14.1382 31.2497 14.6601 31.2493 15.2041C31.2489 15.748 31.0324 16.2696 30.6475 16.654L19.0588 28.2426L19.0506 28.2508C18.8607 28.4419 18.6349 28.5935 18.3861 28.6969C18.1374 28.8004 17.8707 28.8536 17.6013 28.8536C17.3319 28.8536 17.0652 28.8004 16.8165 28.6969C16.5677 28.5935 16.3419 28.4419 16.1519 28.2508L16.1437 28.2426L10.3525 22.4514C10.1567 22.2623 10.0005 22.0361 9.89309 21.786C9.78565 21.5359 9.7291 21.2669 9.72674 20.9947C9.72437 20.7225 9.77624 20.4525 9.87931 20.2006C9.98239 19.9487 10.1346 19.7198 10.3271 19.5273C10.5196 19.3348 10.7485 19.1826 11.0004 19.0795C11.2523 18.9764 11.5223 18.9246 11.7945 18.9269C12.0667 18.9293 12.3357 18.9859 12.5858 19.0933C12.8359 19.2007 13.0621 19.3569 13.2512 19.5527L17.6013 23.9007L27.7488 13.7533V13.7512Z" fill="#F37021"/> + </svg> + <svg class="white-check-icon" width="41" height="42" viewBox="0 0 41 42" fill="none" xmlns="http://www.w3.org/2000/svg"> + <path fill-rule="evenodd" clip-rule="evenodd" d="M20.5 41.5C31.8221 41.5 41 32.3221 41 21C41 9.67785 31.8221 0.5 20.5 0.5C9.17785 0.5 0 9.67785 0 21C0 32.3221 9.17785 41.5 20.5 41.5ZM27.7488 13.7512C28.1337 13.3668 28.6556 13.1511 29.1996 13.1515C29.7436 13.1518 30.2652 13.3683 30.6495 13.7533C31.0339 14.1382 31.2497 14.6601 31.2493 15.2041C31.2489 15.748 31.0324 16.2696 30.6475 16.654L19.0588 28.2426L19.0506 28.2508C18.8607 28.4419 18.6349 28.5935 18.3861 28.6969C18.1374 28.8004 17.8707 28.8536 17.6013 28.8536C17.3319 28.8536 17.0652 28.8004 16.8165 28.6969C16.5677 28.5935 16.3419 28.4419 16.1519 28.2508L16.1437 28.2426L10.3525 22.4514C10.1567 22.2623 10.0005 22.0361 9.89309 21.786C9.78565 21.5359 9.7291 21.2669 9.72674 20.9947C9.72437 20.7225 9.77624 20.4525 9.87931 20.2006C9.98239 19.9487 10.1346 19.7198 10.3271 19.5273C10.5196 19.3348 10.7485 19.1826 11.0004 19.0795C11.2523 18.9764 11.5223 18.9246 11.7945 18.9269C12.0667 18.9293 12.3357 18.9859 12.5858 19.0933C12.8359 19.2007 13.0621 19.3569 13.2512 19.5527L17.6013 23.9007L27.7488 13.7533V13.7512Z" fill="#FFFFFF"/> + </svg> + </div> + + <div class="video-card-container"> + <?php if ($module["videos"] == null): ?> + <div class="video-card"> + <div class="content"> + <h3 class="font-bold text-md"> + No videos yet + </h3> + <!-- masih hardcode --> + <span> + Coming soon + </span> + <!-- --> + </div> + </div> + <?php else: ?> + <?php foreach ($module["videos"] as $video): ?> + <div class="video-card"> + <div class="content"> + <h3 class="font-bold text-md"> + <?= $video["video_name"] ?> + </h3> + <!-- masih hardcode --> + <span> + Not completed + </span> + <!-- --> + </div> + + <a class="watch-btn text-xs font-reg" href="/learn/lesson/<?= $data["language"]["language_id"] ?>/<?= $module["module_id"] ?>/<?= $video["video_id"] ?>"> + Watch > + </a> + </div> + <?php endforeach; ?> + <?php endif; ?> + </div> + </div> + <?php endforeach; ?> + </div> + + <div class="pagination-container"> + <a class="text-sm" href=""><</a> + <a class="text-sm active" href="">1</a> + <a class="text-sm" href="">2</a> + <a class="text-sm" href="">...</a> + <a class="text-sm" href="">5</a> + <a class="text-sm" href="">></a> + </div> + </div> +</div> + +<script src="/public/js/sort-btn.js"></script> +<script src="/public/js/module-card.js"></script> \ No newline at end of file diff --git a/db/toco.sql b/db/toco.sql index 5f6044f1f2cfb88fe68a8efbb8276df27c822309..6e3d9d82a9d5936eea90be28e2f6deca601810cb 100644 --- a/db/toco.sql +++ b/db/toco.sql @@ -22,10 +22,10 @@ CREATE TABLE languages ( language_flag VARCHAR(256) NOT NULL ); -INSERT INTO languages (language_name, language_flag) VALUES ('English', ''); -INSERT INTO languages (language_name, language_flag) VALUES ('Indonesian', ''); -INSERT INTO languages (language_name, language_flag) VALUES ('French', ''); -INSERT INTO languages (language_name, language_flag) VALUES ('Germany', ''); +INSERT INTO languages (language_name, language_flag) VALUES ('English', '/public/icons/uk-flag.svg'); +INSERT INTO languages (language_name, language_flag) VALUES ('Indonesian', '/public/icons/id-flag.svg'); +INSERT INTO languages (language_name, language_flag) VALUES ('French', '/public/icons/fr-flag.svg'); +INSERT INTO languages (language_name, language_flag) VALUES ('Germany', '/public/icons/gr-flag.svg'); DROP TABLE IF EXISTS progress; CREATE TABLE progress ( diff --git a/public/css/lesson.css b/public/css/lesson.css new file mode 100644 index 0000000000000000000000000000000000000000..4b9f6d322cfe167c466ca7f84edeff381ea44cca --- /dev/null +++ b/public/css/lesson.css @@ -0,0 +1,247 @@ +/* ===#===#===#===#===#=== Mobile ===#===#===#===#===#=== */ + +.lesson { + width: 100%; + padding-top: 120px; + display: flex; + align-items: center; + justify-content: center; + padding-bottom: 60px; +} + +.lesson .lesson-container { + /* background-color: red; */ + display: flex; + flex-direction: column; + align-items: center; + gap: 50px; +} + +.lesson .lesson-container h1 { + text-align: center; +} + +/* === SEARCH BAR === */ + +.lesson .lesson-container form { + display: flex; + flex-direction: column; + align-items: center; + gap: 10px; + width: 100%; +} + +.lesson .lesson-container form .search-bar { + width: 100%; + max-width: 600px; + + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + + border: 1px solid var(--grey); + border-radius: 50px; + padding: 8px 16px; +} + +.lesson .lesson-container form .search-bar input { + border: none; + width: 100%; +} + +.lesson .lesson-container form .search-bar button { + border: none; + background-color: transparent; +} + +.lesson .lesson-container form .filter-sort { + width: 100%; + height: fit-content; + display: flex; + align-items: center; + justify-content: center; + gap: 8px; +} + +/* === FILTER === */ + +.lesson .lesson-container form .filter-sort select { + padding: 10px 14px; + border: 1px solid var(--grey); + border-radius: 50px; +} + +/* === SORT === */ + +.lesson .lesson-container form .filter-sort .sort-container { + padding: 10px 14px; + border-radius: 50px; + position: relative; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + border: 1px solid var(--grey); + color: var(--black); +} + +.lesson .lesson-container form .filter-sort .sort-container.active { + background-color: var(--orange); + border: 1px solid var(--orange); + color: var(--white); +} + +.lesson .lesson-container form .filter-sort .sort-container input { + position: absolute; + opacity: 0; + cursor: pointer; + height: 0; + width: 0; +} + +/* === MODULE CARD === */ + +.lesson .lesson-container .card-container { + display: flex; + max-width: 600px; + flex-direction: column; + align-items: center; + gap: 10px; + width: 100%; +} + +.lesson .lesson-container .card-container .module-card { + border: 2px solid var(--orange); + padding: 10px 16px 16px 16px; + width: 100%; + border-radius: 10px; + background-color: var(--white); + cursor: pointer; +} + +.lesson .lesson-container .card-container .module-card.active { + background-color: var(--orange); +} + +.lesson .lesson-container .card-container .module-card .module-head { + display: flex; + align-items: center; + justify-content: space-between; +} + +.lesson .lesson-container .card-container .module-card .module-head .content { + display: flex; + flex-direction: column; + gap: -5px; +} + +.lesson .lesson-container .card-container .module-card .module-head .content h2 { + color: var(--orange); +} + +.lesson .lesson-container .card-container .module-card .module-head .content span { + color: var(--grey); +} + +.lesson .lesson-container .card-container .module-card.active .module-head .content h2, +.lesson .lesson-container .card-container .module-card.active .module-head .content span { + color: var(--white); +} + +.lesson .lesson-container .card-container .module-card .module-head .check-icon { + display: inline; +} + +.lesson .lesson-container .card-container .module-card .module-head .white-check-icon { + display: none; +} + +.lesson .lesson-container .card-container .module-card.active .module-head .check-icon { + display: none; +} + +.lesson .lesson-container .card-container .module-card.active .module-head .white-check-icon { + display: inline; +} + +/* === VIDEO CARD === */ + +.lesson .lesson-container .card-container .module-card .video-card-container { + display: none; +} + +.lesson .lesson-container .card-container .module-card.active .video-card-container { + display: flex; + flex-direction: column; + align-items: center; + gap: 10px; + width: 100%; + margin-top: 20px; + cursor: default; +} + +.lesson .lesson-container .card-container .module-card.active .video-card-container .video-card { + padding: 10px 16px; + width: 100%; + border-radius: 10px; + background-color: var(--white); + + display: flex; + align-items: center; + justify-content: space-between; +} + +.lesson .lesson-container .card-container .module-card.active .video-card-container .video-card .content { + display: flex; + flex-direction: column; + gap: -5px; +} + +.lesson .lesson-container .card-container .module-card.active .video-card-container .video-card .content h3 { + color: var(--orange); +} + +.lesson .lesson-container .card-container .module-card.active .video-card-container .video-card .content span { + color: var(--grey); +} + +.lesson .lesson-container .card-container .module-card.active .video-card-container .video-card .watch-btn { + padding: 8px 16px; + border: 2px solid var(--orange); + background-color: var(--white); + border-radius: 50px; + color: var(--orange); +} + +.lesson .lesson-container .card-container .module-card.active .video-card-container .video-card .watch-btn:hover { + background-color: var(--orange); + color: var(--white); +} + +/* ===#===#===#===#===#=== Laptop ===#===#===#===#===#=== */ + +@media (min-width: 1024px) { + + .lesson { + padding-top: 180px; + padding-bottom: 120px; + } + + .lesson .lesson-container { + gap: 90px; + } +} + +@media (min-width: 1440px) { + + .lesson .lesson-container form .search-bar { + max-width: 800px; + } + + .lesson .lesson-container .card-container { + max-width: 1000px; + } + +} \ No newline at end of file diff --git a/public/icons/checked.svg b/public/icons/checked.svg new file mode 100644 index 0000000000000000000000000000000000000000..021d3f842446249cce4bbda9c3141422844810c4 --- /dev/null +++ b/public/icons/checked.svg @@ -0,0 +1,3 @@ +<svg width="41" height="42" viewBox="0 0 41 42" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M20.5 41.5C31.8221 41.5 41 32.3221 41 21C41 9.67785 31.8221 0.5 20.5 0.5C9.17785 0.5 0 9.67785 0 21C0 32.3221 9.17785 41.5 20.5 41.5ZM27.7488 13.7512C28.1337 13.3668 28.6556 13.1511 29.1996 13.1515C29.7436 13.1518 30.2652 13.3683 30.6495 13.7533C31.0339 14.1382 31.2497 14.6601 31.2493 15.2041C31.2489 15.748 31.0324 16.2696 30.6475 16.654L19.0588 28.2426L19.0506 28.2508C18.8607 28.4419 18.6349 28.5935 18.3861 28.6969C18.1374 28.8004 17.8707 28.8536 17.6013 28.8536C17.3319 28.8536 17.0652 28.8004 16.8165 28.6969C16.5677 28.5935 16.3419 28.4419 16.1519 28.2508L16.1437 28.2426L10.3525 22.4514C10.1567 22.2623 10.0005 22.0361 9.89309 21.786C9.78565 21.5359 9.7291 21.2669 9.72674 20.9947C9.72437 20.7225 9.77624 20.4525 9.87931 20.2006C9.98239 19.9487 10.1346 19.7198 10.3271 19.5273C10.5196 19.3348 10.7485 19.1826 11.0004 19.0795C11.2523 18.9764 11.5223 18.9246 11.7945 18.9269C12.0667 18.9293 12.3357 18.9859 12.5858 19.0933C12.8359 19.2007 13.0621 19.3569 13.2512 19.5527L17.6013 23.9007L27.7488 13.7533V13.7512Z" fill="#F37021"/> +</svg> diff --git a/public/js/module-card.js b/public/js/module-card.js new file mode 100644 index 0000000000000000000000000000000000000000..d4b10b529f6bb12edfb3b3f06a2e222f32ed2f34 --- /dev/null +++ b/public/js/module-card.js @@ -0,0 +1,7 @@ +const moduleCard = document.querySelectorAll(".module-card"); + +for(let i = 0; i < moduleCard.length; i++) { + moduleCard[i].addEventListener("click", () => { + moduleCard[i].classList.toggle("active") + }) +} \ No newline at end of file diff --git a/public/js/sort-btn.js b/public/js/sort-btn.js new file mode 100644 index 0000000000000000000000000000000000000000..90fb694b4b1f153a864363cd6032c25cd93eed7f --- /dev/null +++ b/public/js/sort-btn.js @@ -0,0 +1,6 @@ +const filterBtn = document.querySelector(".sort-container"); +const checkbox = document.querySelector("#sort-input"); + +checkbox.addEventListener("click", () => { + filterBtn.classList.toggle("active"); +});