diff --git a/app/controller/AdminController.php b/app/controller/AdminController.php index 7280f1254d7602360dff7cf2e6ff6578275499ad..9e4bf4a79d1bc2998003d577748736451735faf9 100644 --- a/app/controller/AdminController.php +++ b/app/controller/AdminController.php @@ -5,10 +5,14 @@ require_once(BASE_DIR.'/models/Controller.php'); class AdminController extends Controller { public function index(){ - if (isset($_SESSION['admin_status']) && $_SESSION['admin_status']){ - $this->view('Admin/index'); + if (isset($_SESSION['admin_status'])){ + if ($_SESSION['admin_status']){ + $this->view('Admin/index'); + } else { + $this->view('Error/index'); + } } else { - $this->view('Home/index'); + $this->view('Error/index'); } } } \ No newline at end of file diff --git a/app/database/constraints/c01_anime_score_constraints.sql b/app/database/constraints/c01_anime_score_constraints.sql deleted file mode 100644 index 7ed2ff86a22a607df0021a074ecc1518d51c0e26..0000000000000000000000000000000000000000 --- a/app/database/constraints/c01_anime_score_constraints.sql +++ /dev/null @@ -1,17 +0,0 @@ -DO $$ - BEGIN - IF NOT EXISTS ( - SELECT constraint_name - FROM information_schema.check_constraints - WHERE constraint_schema = 'public' - AND constraint_name = 'anime_score_constraint' - ) - THEN - ALTER TABLE anime - ADD CONSTRAINT anime_score_constraint - CHECK (score BETWEEN 1 and 10); - END IF; - END; -$$; - - diff --git a/app/database/constraints/c02_anime_list_score_constraint.sql b/app/database/constraints/c02_anime_list_score_constraint.sql deleted file mode 100644 index f010c50ced410838c4466ac8a03b0b505cddb777..0000000000000000000000000000000000000000 --- a/app/database/constraints/c02_anime_list_score_constraint.sql +++ /dev/null @@ -1,15 +0,0 @@ -DO $$ - BEGIN - IF NOT EXISTS ( - SELECT constraint_name - FROM information_schema.check_constraints - WHERE constraint_schema = 'public' - AND constraint_name = 'anime_list_score_constraint' - ) - THEN - ALTER TABLE anime_list - ADD CONSTRAINT anime_list_score_constraint - CHECK (user_score BETWEEN 1 and 10); - END IF; - END; -$$; diff --git a/app/database/constraints/c03_client_email_constraint.sql b/app/database/constraints/c03_client_email_constraint.sql deleted file mode 100644 index 896a191ce3023425d278d3b4dffabc8baf3ea77e..0000000000000000000000000000000000000000 --- a/app/database/constraints/c03_client_email_constraint.sql +++ /dev/null @@ -1,15 +0,0 @@ -DO $$ - BEGIN - IF NOT EXISTS ( - SELECT constraint_name - FROM information_schema.check_constraints - WHERE constraint_schema = 'public' - AND constraint_name = 'client_email_constraint' - ) - THEN - ALTER TABLE client - ADD CONSTRAINT client_email_constraint - CHECK (email LIKE '%@%.%'); - END IF; - END; -$$; diff --git a/app/database/constraints/c04_delete_client_animelist_constraint.sql b/app/database/constraints/c04_delete_client_animelist_constraint.sql deleted file mode 100644 index 5439ef58d9ca6f6bcf927175ed573725ae79604b..0000000000000000000000000000000000000000 --- a/app/database/constraints/c04_delete_client_animelist_constraint.sql +++ /dev/null @@ -1,17 +0,0 @@ -DO $$ - BEGIN - IF NOT EXISTS ( - SELECT constraint_name - FROM information_schema.check_constraints - WHERE constraint_schema = 'public' - AND constraint_name = 'delete_client_animelist' - ) - THEN - ALTER TABLE anime_list - ADD CONSTRAINT delete_client_animelist - FOREIGN KEY (client_id) - REFERENCES client(client_id) - ON DELETE CASCADE; - END IF; - END; -$$; diff --git a/app/database/constraints/temp.txt b/app/database/constraints/f01_anime_score_update.sql similarity index 73% rename from app/database/constraints/temp.txt rename to app/database/constraints/f01_anime_score_update.sql index 025b6a79ae786a4f394ece15e958d48c1a871f1b..6442f0a879113e6645b6a31c2a51df6980dbdca3 100644 --- a/app/database/constraints/temp.txt +++ b/app/database/constraints/f01_anime_score_update.sql @@ -1,5 +1,5 @@ CREATE FUNCTION anime_score_update() - RETURNS TRIGGER +RETURNS TRIGGER AS $$ BEGIN UPDATE anime @@ -14,9 +14,4 @@ BEGIN WHERE NOT NEW.user_score IS NULL AND anime.anime_id = NEW.anime_id ; RETURN NEW; END; -$$ LANGUAGE plpgsql; - -CREATE TRIGGER anime_score_update_trg - AFTER INSERT ON anime_list - FOR EACH ROW -EXECUTE FUNCTION anime_score_update(); \ No newline at end of file +$$ LANGUAGE plpgsql; \ No newline at end of file diff --git a/app/database/constraints/t01_anime_score_update.sql b/app/database/constraints/t01_anime_score_update.sql new file mode 100644 index 0000000000000000000000000000000000000000..94ce82923647ac2d5789b77f135d8cc0392f09fa --- /dev/null +++ b/app/database/constraints/t01_anime_score_update.sql @@ -0,0 +1,4 @@ +CREATE TRIGGER anime_score_update_trg + AFTER INSERT ON anime_list + FOR EACH ROW +EXECUTE FUNCTION anime_score_update(); \ No newline at end of file diff --git a/app/database/tables/004_anime.sql b/app/database/tables/004_anime.sql index 502956011dfd47a772d51decdf44b8fbf1368195..be12e850e59d1c2567bc05b05b8a300f277fcf60 100644 --- a/app/database/tables/004_anime.sql +++ b/app/database/tables/004_anime.sql @@ -7,10 +7,10 @@ CREATE TABLE IF NOT EXISTS anime release_date DATE, episodes INTEGER, rating VARCHAR(50) NOT NULL CHECK (rating IN ('G', 'PG-13', 'R(17+)', 'Rx')), - score NUMERIC(4,2) CHECK (score BETWEEN 1 AND 10), + score NUMERIC(4,2) NOT NULL CHECK (score BETWEEN 0 AND 10), image VARCHAR(255), trailer VARCHAR(255), synopsis TEXT, studio_id INTEGER NOT NULL, - FOREIGN KEY (studio_id) REFERENCES studio(studio_id) ON DELETE CASCADE + FOREIGN KEY (studio_id) REFERENCES studio(studio_id) ON DELETE CASCADE ON UPDATE CASCADE ); \ No newline at end of file diff --git a/app/database/tables/005_anime_list.sql b/app/database/tables/005_anime_list.sql index 8b022d52ac10c4cca3de2d26cafdb220dbb96293..263f94c7e6bbb13f1c16c1cefe5bbf748edba4b0 100644 --- a/app/database/tables/005_anime_list.sql +++ b/app/database/tables/005_anime_list.sql @@ -7,6 +7,6 @@ CREATE TABLE IF NOT EXISTS anime_list progress INTEGER, watch_status VARCHAR(20) CHECK (watch_status IN ('WATCHING', 'COMPLETED', 'ON-HOLD', 'DROPPED', 'PLAN TO WATCH')), review TEXT, - FOREIGN KEY (client_id) REFERENCES client(client_id) ON DELETE CASCADE, - FOREIGN KEY (anime_id) REFERENCES anime(anime_id) ON DELETE CASCADE + FOREIGN KEY (client_id) REFERENCES client(client_id) ON DELETE CASCADE ON UPDATE CASCADE, + FOREIGN KEY (anime_id) REFERENCES anime(anime_id) ON DELETE CASCADE ON UPDATE CASCADE ); \ No newline at end of file diff --git a/app/database/tables/006_anime_genre.sql b/app/database/tables/006_anime_genre.sql index 313468a8f18d279c6e18e3dea7229ba2c3b61937..45fce4567479be1d2d8e48c71d7598bad2ecea8d 100644 --- a/app/database/tables/006_anime_genre.sql +++ b/app/database/tables/006_anime_genre.sql @@ -3,6 +3,6 @@ CREATE TABLE IF NOT EXISTS anime_genre anime_genre_id SERIAL PRIMARY KEY NOT NULL, anime_id INTEGER NOT NULL, genre_id INTEGER NOT NULL, - FOREIGN KEY (anime_id) REFERENCES anime(anime_id) ON DELETE CASCADE, - FOREIGN KEY (genre_id) REFERENCES genre(genre_id) ON DELETE CASCADE + FOREIGN KEY (anime_id) REFERENCES anime(anime_id) ON DELETE CASCADE ON UPDATE CASCADE, + FOREIGN KEY (genre_id) REFERENCES genre(genre_id) ON DELETE CASCADE ON UPDATE CASCADE ); \ No newline at end of file diff --git a/app/database/tables/007_relationship.sql b/app/database/tables/007_relationship.sql deleted file mode 100644 index 07227a57a991c31116f91f74cd7733c71f5e5ab0..0000000000000000000000000000000000000000 --- a/app/database/tables/007_relationship.sql +++ /dev/null @@ -1,9 +0,0 @@ -CREATE TABLE IF NOT EXISTS relationship -( - relationship_id SERIAL PRIMARY KEY NOT NULL, - client_id_1 INTEGER NOT NULL, - client_id_2 INTEGER NOT NULL, - type VARCHAR(50) NOT NULL CHECK (type IN ('FRIEND', 'PENDING', 'BLOCKED')), - FOREIGN KEY (client_id_1) REFERENCES client(client_id) ON DELETE CASCADE, - FOREIGN KEY (client_id_2) REFERENCES client(client_id) ON DELETE CASCADE -); \ No newline at end of file diff --git a/app/index.php b/app/index.php index 9569bc9a4e99aa7196d9f4fabc6087ae3d7488a8..7ad7d092c9925354887a5b3b0e33166bb970fc4f 100644 --- a/app/index.php +++ b/app/index.php @@ -15,6 +15,7 @@ $app = new App(); // $db = new Database(); // $db->resetSchema(); // $db->migrate(); +// $db->constraints(); // seedAllData(); ?> diff --git a/app/models/anime.php b/app/models/anime.php index b706fc5f098ad3a967dbf1574b77aa997064a6c7..9286c2f5425906047d28898c4fdfa21857aa3687 100644 --- a/app/models/anime.php +++ b/app/models/anime.php @@ -115,4 +115,14 @@ class Anime { return $this->db->fetchData(); } + public function getAllAnimeByStudioIDOrdered($id, $column, $desc){ + if ($desc){ + $orderQuery = ' ORDER BY '.$column. ' DESC'; + } else { + $orderQuery = ' ORDER BY '.$column. ' ASC'; + } + $this->db->query('SELECT * FROM '.$this->table.' WHERE studio_id = '.$id.$orderQuery); + return $this->db->fetchAllData(); + } + } \ No newline at end of file diff --git a/app/models/anime_list.php b/app/models/anime_list.php index 50202dfb19edcea48b324b6f9a5e37a40cb7ef58..1656eca836c8fea2489ae2a5fa9b0cd27d646ac4 100644 --- a/app/models/anime_list.php +++ b/app/models/anime_list.php @@ -61,7 +61,12 @@ class Anime_List{ JOIN client c ON c.client_id = l.client_id WHERE a.anime_id = '.$aid.' AND c.client_id = '.$cid); return ($this->db->fetchData()); - // return true if there is a mutual relationship, otherwise false + // return true if there is a row, otherwise false + } + + public function getAverageUserScoreByClientID($id){ + $this->db->query('SELECT AVG(user_score) AS avg FROM '.$this->table.' WHERE client_id = '.$id); + return $this->db->fetchData(); } } \ No newline at end of file diff --git a/app/models/app.php b/app/models/app.php index 257701c87531af134ca003f02f68308b67bd9800..6d01d9f3babc31c7b3fbe066f62f2e235b4d9280 100644 --- a/app/models/app.php +++ b/app/models/app.php @@ -13,18 +13,44 @@ class App { public function __construct() { $url = $this->parse_url(); - if (!isset($_SESSION['username']) && $url[0] != 'signup'){ - $this->controller = 'LoginController'; + $path = explode("?", $url[0])[0]; + if (!isset($_SESSION['username']) ){ + // GUEST MODE + if ($url[0] == '' || $url[0] == 'home'){ + // Guest mode can access home page + $this->controller = 'HomeController'; + } + else if ($url[0] == 'login'){ + // Guest mode can access login page + $this->controller = 'LoginController'; + } + else if ($url[0] == 'signup'){ + // Guest mode can access signup page + $this->controller = 'SignupController'; + } + else if ($url[0] == 'error' || $url[0] == 'admin'){ + $this->controller = 'ErrorController'; + } + else if (file_exists(BASE_DIR.'/controller/' . $path . 'Controller.php')) { + // Other than home, login, and signup, GUEST needs to login first + $this->controller = 'LoginController'; + } + else { + $this->controller = 'ErrorController'; + } } else { - $path = explode("?", $url[0])[0]; - if (file_exists(BASE_DIR.'/controller/' . $path . 'Controller.php')) { + // HAS LOGGED IN + if ($url[0] == '' || $url[0] == 'login' || $url[0] == 'signup') { + $this->controller = 'HomeController'; + } + else if ($url[0] == 'error'){ + $this->controller = 'ErrorController'; + } + else if (file_exists(BASE_DIR.'/controller/' . $path . 'Controller.php')) { $this->controller = $path.'Controller'; unset($url[0]); } - else if ($url[0] == '') { - $this->controller = 'HomeController'; - } else { $this->controller = 'ErrorController'; } diff --git a/app/models/client.php b/app/models/client.php index 20afa6e4809ef8468022cda5e4e9ff9151cd056b..703b2f840726c895ede4cb436a84820c27b3f8dd 100644 --- a/app/models/client.php +++ b/app/models/client.php @@ -35,12 +35,6 @@ class Client { return $this->db->fetchData(); } - public function getAllClientRelationshipByClientID($id){ - $id = $this->db->processDataType($id); - $this->db->query('SELECT * FROM ' . $this->table . ' JOIN relationship WHERE '.$id.' = relationship.client_id_1 OR '.$id.' = relationship.client_id_2'); - return $this->db->fetchAllData(); - } - public function insertClient($data){ foreach($data as $key => $value){ $data[$key] = $this->db->processDataType($value); @@ -68,4 +62,5 @@ class Client { return ($this->db->countRow() != 0); // if countRow == 0, query fails } + } \ No newline at end of file diff --git a/app/models/database.php b/app/models/database.php index c3be99f7ff7c4291c9884d81d5a4c92bf561fb84..47ec1814e7ce49b9abf508f9b936bb3cb48cb5cf 100644 --- a/app/models/database.php +++ b/app/models/database.php @@ -70,24 +70,32 @@ class Database { $this->query($file_content); $this->execute(); } - // // Ga jadi dipake karena checknya langsung pas create table - // $constraint_files = glob(dirname(__DIR__,1).'/database/constraints/*.sql'); - // foreach($constraint_files as $file){ - // $file_content = file_get_contents($file); - // $this->query($file_content); - // $this->execute(); - // } - // echo "Migration Success"; - + echo "Migration Success \n"; } catch (Exception $e){ - echo "Migration Failed"; + echo "Migration Failed \n"; } } + public function constraints(){ + try { + $constraint_files = glob(dirname(__DIR__,1).'/database/constraints/*.sql'); + foreach($constraint_files as $constraint){ + $constraint_content = file_get_contents($constraint); + $this->query($constraint_content); + $this->execute(); + } + echo "Adding Constraints Success \n"; + } catch (Exception $e) { + echo "Adding Constraints Failed \n"; + } + } + + public function resetSchema(){ $this->query('DROP SCHEMA public CASCADE'); $this->execute(); $this->query('CREATE SCHEMA public'); $this->execute(); + echo "Successfully reset schema \n"; } } \ No newline at end of file diff --git a/app/models/genre.php b/app/models/genre.php index 3c673c8b19c1ee93c1bb7c23b8e3079e41534afb..e6696be56b4dae86098b8358487e78ac88cf50cb 100644 --- a/app/models/genre.php +++ b/app/models/genre.php @@ -22,11 +22,6 @@ class Genre { return $this->db->fetchData(); } - public function getAllGenreIDByAnimeID($id){ - $this->db->query('SELECT '.$this->table.'.genre_id FROM ' . $this->table . ' JOIN anime_genre ON '.$this->table.'.genre_id = anime_genre.genre_id JOIN anime ON anime_genre.anime_id = anime.anime_id WHERE anime.anime_id = '.$id); - return $this->db->fetchAllData(); - } - public function insertGenre($name){ $name = $this->db->processDataType($name); $this->db->query('INSERT INTO ' . $this->table . ' (name) VALUES ('.$name.')'); @@ -52,4 +47,10 @@ class Genre { // if countRow == 0, query fails } + // =========== SPECIFIC QUERY =========== + public function getAllGenreIDByAnimeID($id){ + $this->db->query('SELECT g.genre_id, g.name FROM ' . $this->table . ' g JOIN anime_genre ON g.genre_id = anime_genre.genre_id JOIN anime ON anime_genre.anime_id = anime.anime_id WHERE anime.anime_id = '.$id); + return $this->db->fetchAllData(); + } + } \ No newline at end of file diff --git a/app/models/relationship.php b/app/models/relationship.php deleted file mode 100644 index 43118eddf834d929a14bce6c4cda4e4d8dddf3ec..0000000000000000000000000000000000000000 --- a/app/models/relationship.php +++ /dev/null @@ -1,61 +0,0 @@ -<?php - -require_once(dirname(__DIR__,1).'/define.php'); -require_once(BASE_DIR.'/setup/setup.php'); -require_once('Database.php'); - -class Relationship { - private $table = 'relationship'; - private $db; - - public function __construct(){ - $this->db = new Database (); - } - - public function getAllRelationship(){ - $this->db->query('SELECT * FROM '.$this->table); - return $this->db->fetchAllData(); - } - - public function getRelationshipByID($id){ - $this->db->query('SELECT * FROM '.$this->table. ' WHERE relationship_id = '. $id); - return $this->db->fetchData(); - } - - public function insertRelationship($data){ - foreach($data as $key => $value){ - $data[$key] = $this->db->processDataType($value); - } - $this->db->query('INSERT INTO ' . $this->table . ' (client_id_1, client_id_2, type) VALUES ('.$data['client_id_1'].','.$data['client_id_2'].','.$data['type'].')'); - $this->db->execute(); - return ($this->db->countRow() != 0); - // if countRow == 0, query fails - } - - public function updateRelationship($data){ - foreach($data as $key => $value){ - $data[$key] = $this->db->processDataType($value); - } - $this->db->query('UPDATE ' . $this->table . 'SET client_id_1 = '.$data['client_id_1'].', client_id_2 = '.$data['client_id_2'].', type = '.$data['type'].' WHERE relationship_id = '. $data['relationship_id']); - $this->db->execute(); - return ($this->db->countRow() != 0); - // if countRow == 0, query fails - } - - public function deleteRelationship($id){ - $this->db->query('DELETE FROM ' . $this->table . ' WHERE relationship_id = '. $id); - $this->db->execute(); - return ($this->db->countRow() != 0); - // if countRow == 0, query fails - } - - // SPECIFIC QUERY - - public function getMutualRelationship($id1, $id2){ - $this->db->query('SELECT * FROM '.$this->table.' WHERE client_id_1 = '.$id1.' AND client_id_2 = '.$id2.' OR client_id_1 = '.$id2.' AND client_id_2 = '.$id1); - return ($this->db->fetchData()); - // return true if there is a mutual relationship, otherwise false - } - - -} \ No newline at end of file diff --git a/app/public/handler/signup.js b/app/public/handler/signup.js index 60a6534ecb9e408c95fff4bb90bc10315949ac8c..78b376ca33b89ff69d6c67aa77c7ea3186c5c848 100644 --- a/app/public/handler/signup.js +++ b/app/public/handler/signup.js @@ -1,6 +1,5 @@ function checkSubmitButton(){ if (document.getElementById('email-errmsg').innerHTML == '' && document.getElementById('username-errmsg').innerHTML == '' && document.getElementById('password-errmsg').innerHTML == ''){ - let submitBtn = document.getElementById('signup-button'); document.getElementById('signup-button').disabled = false; } else { document.getElementById('signup-button').disabled = true; diff --git a/app/public/handler/trailer.js b/app/public/handler/trailer.js new file mode 100644 index 0000000000000000000000000000000000000000..7c4dd27f0be4c3f458acbb95be0de3eeba251e66 --- /dev/null +++ b/app/public/handler/trailer.js @@ -0,0 +1,12 @@ +function displayTrailer (trailer, title){ + document.getElementById("trailer-div").style.top = "0px"; + document.getElementById("anime-trailer-iframe").src = trailer; + document.getElementById("trailer-title").innerHTML = title; +} + +function hideTrailer() { + document.getElementById("trailer-div").style.top = "-100%"; + document.getElementById("anime-trailer-iframe").src = ""; + document.getElementById("trailer-title").innerHTML = ""; + +} diff --git a/app/public/img/login_bg.jpg b/app/public/img/login_bg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ba52a1db9f7ad00677db322e79c9810a3650c489 Binary files /dev/null and b/app/public/img/login_bg.jpg differ diff --git a/app/public/img/login_icon.png b/app/public/img/login_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..07027e379e440d7a0d1b19895ff529b3799ca301 Binary files /dev/null and b/app/public/img/login_icon.png differ diff --git a/app/public/img/lost_icon.png b/app/public/img/lost_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..e9d97be549cd3af62258d3df6d6f5ffdf5eae577 Binary files /dev/null and b/app/public/img/lost_icon.png differ diff --git a/app/public/img/signup_bg.jpg b/app/public/img/signup_bg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e21b3c53e64316ac985a207bb3210edbb8a14888 Binary files /dev/null and b/app/public/img/signup_bg.jpg differ diff --git a/app/public/img/signup_icon.png b/app/public/img/signup_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..dc973dcaf1197ffc701d33aa4f4831b169b6b362 Binary files /dev/null and b/app/public/img/signup_icon.png differ diff --git a/app/public/style/admin.css b/app/public/style/admin.css index 26d9e6718dce53199a69cb72688a4b50797559cf..2f5e74286607dd64fe7e2f6360f6794e0242f8c7 100644 --- a/app/public/style/admin.css +++ b/app/public/style/admin.css @@ -1,9 +1,3 @@ -body { - font-family: Arial, sans-serif; - background-color: #f3f3f3; - margin: 0; -} - .container { display: flex; justify-content: center; diff --git a/app/public/style/anime.css b/app/public/style/anime.css index 63417801dfc6ef87d6ce5ebff837cf97526b2358..e81e8f60bd248edca396f2e74f5e6afb5ee0c017 100644 --- a/app/public/style/anime.css +++ b/app/public/style/anime.css @@ -40,18 +40,19 @@ transition: ease-in-out; transition-duration: 0.2s; cursor: pointer; + display: flex; } .box-preview:hover { scale: 110%; transition: ease-in-out; transition-duration: 0.2s; + box-shadow: 2px 5px 5px #aaaaaa; } .image-preview { width: 100%; - max-width: 320px; - object-fit: cover; + object-fit: contain; object-position: center; } @@ -130,13 +131,25 @@ flex: 1; display: flex; flex-direction: column; + justify-content: start; + align-items: center; + padding: 20px; gap: 5px; max-width: 320px; - margin-bottom: 20px; + margin-bottom: 10px; } -.anime-details div { - margin-bottom: 10px; +.grid-container { + width: 100%; + display: grid; + grid-template-columns: auto auto; + padding: 10px; + gap: 10px; + justify-content: space-between; +} + +.anime-details-aspect { + font-weight: bold; } .anime-trailer { @@ -145,7 +158,7 @@ flex-direction: column; align-items: center; background-color: #dedede; - padding: 20px; + padding: 10px; } .anime-trailer-iframe { diff --git a/app/public/style/client.css b/app/public/style/client.css new file mode 100644 index 0000000000000000000000000000000000000000..1acac2d769a1a2e176fe035a18df2106ae6373b9 --- /dev/null +++ b/app/public/style/client.css @@ -0,0 +1,79 @@ +.client-big-container{ + display: flex; + justify-content: center; + align-items: center; + flex-direction: row; + padding: 20px; + gap: 20px; + margin: auto; +} + +.client-left-container{ + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + padding: 20px; + gap: 20px; +} + +.client-main-container{ + display: flex; + justify-content: center; + align-items: center; + flex-direction: row; + padding: 20px; + gap: 20px; + border: black 2px solid; +} + +.client-image-box{ + display: flex; + width: 120px; + aspect-ratio: 1; + padding: 10px; + border-radius: 100%; + border: black 2px solid; +} + +.client-image { + width: 100%; + object-fit: cover; + object-position: center; + border-radius: 100%; +} + +.client-description { + display: flex; + flex-direction: column; + gap: 5px; +} + +.client-username { + font-size: 36px; + font-weight: bold; +} + +.client-email { + font-size: 16px; + color: #787878; + font-weight: bold; +} + +.client-id{ + font-size: 12px; + color: #787878; +} + +.client-info-container { + width: 100%; + display: grid; + grid-template-columns: auto auto; + padding: 10px; + gap: 10px; + justify-content: space-between; +} + +.client-info-aspect { + font-weight: bold; +} \ No newline at end of file diff --git a/app/public/style/error.css b/app/public/style/error.css new file mode 100644 index 0000000000000000000000000000000000000000..4f12efe2e9c7d368379f257c7fe3fcf8e07ab3c9 --- /dev/null +++ b/app/public/style/error.css @@ -0,0 +1,48 @@ +.image-box{ + padding: 40px; + border-radius: 100%; + border: black 2px solid; +} + +.image{ + width: 150px; +} + +.container{ + display: flex; + padding: 20px; + flex-direction: row; + justify-content: center; + align-items: center; + gap: 20px; + margin: auto; +} + +.description { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 10px; +} + +.back-button{ + text-align: center; + background-color: white; + width: 100px; + color: #ff4500; + border: #ff4500 2px solid; + border-radius: 5px; + padding:5px 10px; + font-weight: bold; + transition: ease-in-out; + transition-duration: 0.2s; +} + +.back-button:hover { + transition: ease-in-out; + transition-duration: 0.2s; + width: 150px; + background-color: #ff4500; + color: white; +} \ No newline at end of file diff --git a/app/public/style/global.css b/app/public/style/global.css index d06ece27b4aa4e2c25f181dc507bc5a4a9ced9d7..9967c6f991b9db53131bf054b6e490b2d9be4d58 100644 --- a/app/public/style/global.css +++ b/app/public/style/global.css @@ -3,6 +3,11 @@ body { margin: 0; padding: 0; background-color: #f2f2f2; + min-height: 100vh; + position: relative; + display: flex; + flex-direction: column; + justify-content: space-between; } a { @@ -40,7 +45,7 @@ a { } .logo { - font-size: 32px; + font-size: 24px; font-family: Georgia, "Times New Roman", Times, serif; font-weight: bold; color: #ff4500; @@ -60,18 +65,14 @@ a { justify-content: space-between; align-items: center; background-color: #ff4500; - padding-left: 10vw; - padding-right: 10vw; - padding-top: 10px; - padding-bottom: 10px; + padding: 5px 10vw ; } .nav-links { display: flex; gap: 8px; list-style: none; - padding-left: 0; -} + } .nav-links a { text-decoration: none; @@ -115,22 +116,31 @@ a { .navbar-icon-btn { background-color: rgba(255, 255, 255, 0.2); border: none; - justify-self: center; - align-self: center; - padding: 12px; - border-radius: 100%; + padding: 6px 12px; + border-radius: 10px; display: flex; + justify-content: center; + align-items: center; + flex-direction: row; cursor: pointer; transition: ease-in-out; transition-duration: 0.2s; + gap: 10px; } .navbar-icon-btn:hover { background-color: rgba(255, 255, 255, 0.5); - padding: 8px; + border-radius: 20px; transition: ease-in-out; transition-duration: 0.2s; } + +.navbar-icon-desc { + font-weight: bold; + text-align: center; + color: black; +} + .content { display: flex; justify-content: space-between; @@ -166,13 +176,14 @@ h2 { .anime-card { width: 200px; position: relative; - aspect-ratio: 3/4; + aspect-ratio: 2/3; display: flex; justify-content: center; align-items: center; overflow: hidden; transition: ease-in-out; transition-duration: 0.15s; + background-color: #dedede; } .anime-card:hover { @@ -184,7 +195,6 @@ h2 { .anime-card img { width: 100%; - max-width: 200px; object-fit: cover; object-position: center; } @@ -275,6 +285,7 @@ h2 { overflow: hidden; width: 80%; } + .anime-review-list { list-style: none; padding: 0; diff --git a/app/public/style/login.css b/app/public/style/login.css index be6773faa9754fe6b9a2bbf47e1ba5361543958c..3198b5840cbfd2c302c841cfa66d7b78955fb762 100644 --- a/app/public/style/login.css +++ b/app/public/style/login.css @@ -1,19 +1,57 @@ -body { +.background-container { + width: 100vw; + height: 100vh; display: flex; - flex-direction: column; + position: fixed; + top: 0; + left: 0; + overflow: hidden; + justify-content: center; + align-items: center; + z-index: -1; +} + +.page-container{ + width: 100vw; + height: 100vh; + display: flex; + position: relative; + justify-content: center; + align-items: center; +} + +.background { + width: 100%; + object-fit: cover; + object-position: center; } -.menuLogin{ +.header-subtitle { + margin-bottom: 15px; +} + +.menu-login{ width: 350px; background: white; - margin: auto; - padding: 30px 20px; + padding: 20px 20px; display: flex; justify-content: center; align-items: center; flex-direction: column; - margin-top: 100px; border-radius: 20px; + margin: auto auto; +} + +.menu-signup{ + width: 500px; + background: white; + padding: 20px 20px; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + border-radius: 20px; + margin: auto auto; } .form { @@ -24,49 +62,115 @@ body { width: 100%; } +.form-group { + display: flex; + flex-direction: column; + justify-content: center; + align-items: start; + width: 90%; + margin-bottom: 10px; +} + .form-label{ font-weight: bold; + font-size: 16px; margin-top: 10px; margin-bottom: 10px; justify-self: flex-start; } -.form_input{ +.form-input{ box-sizing : border-box; width: 100%; padding: 10px; font-size: 11pt; - margin-bottom: 20px; } -.login-btn{ +.signup-button, .signup-button:enabled{ + background: #f1b760; + color: white; + font-size: 11pt; + font-weight: bold; + width: 210px; + border: none; + border-radius: 3px; + padding: 10px 20px; + cursor: pointer; + transition: ease-in-out; + transition-duration: 0.2s; +} + +.signup-button:disabled { + background: #b0b0b0; + color: rgb(65, 65, 65); + font-size: 11pt; + font-weight: bold; + width: 210px; + border: none; + border-radius: 3px; + padding: 10px 20px; + cursor:not-allowed; +} + +.signup-button:hover:enabled{ + background: #ebc893; + width: 250px; + transition: ease-in-out; + transition-duration: 0.2s; +} + +.login-button{ background: #ff4500; color: white; font-size: 11pt; font-weight: bold; - width: 75%; border: none; border-radius: 3px; + width: 210px; padding: 10px 20px; cursor: pointer; + transition: ease-in-out; + transition-duration: 0.2s; } -.login-btn:hover{ - background: #f5aa8e; +.login-button:hover{ + background: #f5aa8e; + width: 250px; + transition: ease-in-out; + transition-duration: 0.2s; } -.signup-btn{ - background: #f1b760; +.home-button{ + background: #417ef7; color: white; font-size: 11pt; font-weight: bold; - width: 75%; border: none; border-radius: 3px; + width: 210px; padding: 10px 20px; cursor: pointer; + transition: ease-in-out; + transition-duration: 0.2s; } -.signup-btn:hover{ - background: #ebc893; +.home-button:hover{ + background: #86aaf3; + width: 250px; + transition: ease-in-out; + transition-duration: 0.2s; } + +.err-message { + color:#ff4500; + margin-bottom: 20px; + margin-top: 10px; +} + +.form-err-message { + color:#ff4500; + margin-top: 5px; + margin-bottom: 10px; + font-size: 12px; +} + diff --git a/app/public/style/studio.css b/app/public/style/studio.css index 254c2e796af3d8c0ef11124dc9c4c61a2f1940db..4ab818bf4fd456bd72389e024eb72bdde32cdada 100644 --- a/app/public/style/studio.css +++ b/app/public/style/studio.css @@ -118,17 +118,9 @@ margin-top: 10px; overflow: hidden; border-radius: 3px; - transition: ease-in-out; - transition-duration: 0.2s; cursor: pointer; } -.anime-box-preview:hover { - scale: 110%; - transition: ease-in-out; - transition-duration: 0.2s; -} - .anime-image-preview { width: 100%; max-width: 160px; @@ -141,14 +133,33 @@ flex-direction: column; justify-content: start; align-items: center; + border: black 1px solid; + padding: 10px; + transition: ease-in-out; + transition-duration: 0.2s; + width: 240px; +} + +.anime-container:hover { + scale: 110%; + border-radius: 10px; + transition: ease-in-out; + transition-duration: 0.2s; } .anime-description { display: flex; - flex-direction: row; + flex-direction: column; margin-top: 20px; margin-bottom: 10px; - color: white; + color: black; font-weight: bold; gap: 5px; } + +.anime-description-title { + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + width: 80%; +} \ No newline at end of file diff --git a/app/public/style/trailer.css b/app/public/style/trailer.css index 2e39e636f2498bef59e1eaf4dbd878d4ed903d39..81248161f786bb568df1fe738c3a834e884b7fb1 100644 --- a/app/public/style/trailer.css +++ b/app/public/style/trailer.css @@ -1,8 +1,5 @@ -body { - background-color: rgb(48, 48, 48); -} - .flex-wrap { + background-color: rgb(48, 48, 48); padding: 20px; display: flex; flex-wrap: wrap; @@ -17,22 +14,24 @@ body { margin-top: 10px; overflow: hidden; border-radius: 3px; - transition: ease-in-out; - transition-duration: 0.2s; cursor: pointer; + display: flex; } .box-preview:hover{ scale: 110%; + background-color: #565656; transition: ease-in-out; transition-duration: 0.2s; + box-shadow: 2px 5px 5px #232323; } -.image-preview{ +.image-preview{ width: 100%; - max-width: 320px; - object-fit: cover; + object-fit: contain; object-position: center; + transition: ease-in-out; + transition-duration: 0.2s; } .container{ @@ -50,4 +49,46 @@ body { color: white; font-weight: bold; gap: 5px; -} \ No newline at end of file +} + +.trailer-container{ + width: 100%; + height: 100%; + position: fixed; + display: block; + z-index: 2; + top: -100%; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0,0,0,0.8); + cursor: pointer; + transition: ease-in-out; + transition-duration: 0.2s; +} + +.trailer-box{ + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%,-50%); + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 10px; +} + +.trailer-title { + font-size: 24px; + font-weight: bold; + color:white; +} + +.anime-trailer-iframe { + padding: 0; + margin: 0; + width: 720px; + aspect-ratio: 16/9; +} + diff --git a/app/public/vid/trailer2.mp4 b/app/public/vid/trailer2.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..87c74de662b051d8793fc1fa6256b6b2c9ba19b1 Binary files /dev/null and b/app/public/vid/trailer2.mp4 differ diff --git a/app/public/vid/trailer3.mp4 b/app/public/vid/trailer3.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..5e30effccd8ebe097ec1b8bd97bdf47a6665e246 Binary files /dev/null and b/app/public/vid/trailer3.mp4 differ diff --git a/app/setup/seed.php b/app/setup/seed.php index aa08ecda132f0b5502b38fe741f356ec1a4ac188..a336755fde601d4c71a73abd55be672f0fa893f2 100644 --- a/app/setup/seed.php +++ b/app/setup/seed.php @@ -7,9 +7,10 @@ require_once(BASE_DIR.'/models/Genre.php'); require_once(BASE_DIR.'/models/Anime.php'); require_once(BASE_DIR.'/models/Anime_List.php'); require_once(BASE_DIR.'/models/Anime_Genre.php'); -require_once(BASE_DIR.'/models/Relationship.php'); $lorem_ipsum = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur sit amet tincidunt risus, nec dictum lectus. Cras vitae tempus elit. Maecenas nec lobortis lectus. Ut mollis neque sit amet nunc aliquet, a fermentum libero sodales. Praesent non magna suscipit dolor sagittis posuere. Proin tortor lorem, viverra tempor dignissim vel, euismod vel magna. Maecenas fermentum ultricies imperdiet. Donec sodales lacus id magna ultricies rhoncus.'; +$anime_amount = 60; +$anime_list_amount = 30; function getRandomWord($len = 10) { @@ -44,6 +45,18 @@ function seedClientData(){ 'image' => $image); $client->insertClient($clientTuple); } + + $client->insertClient( + array ( + 'username' => 'inijuan', + 'email' => 'juan@gmail.com', + 'password' => 'jujujuju', + 'admin_status' => true, + 'birthdate' => '2003-09-10', + 'bio' => 'Ini akun punya Juan iseng doang masukin biar beda soalnya kesannya kayak punya akun sendiri xixixixixixixi', + 'image' => '/public/img/admin_icon.png' + ) + ); } function seedStudioData() { @@ -106,29 +119,32 @@ function seedGenreData(){ function seedAnimeData(){ global $lorem_ipsum; + global $anime_amount; $anime = new Anime(); $typeArr = array ('TV','MOVIE', 'OVA'); $statusArr = array ('ON-GOING', 'COMPLETED', 'HIATUS', 'UPCOMING'); $ratingArr = array ('G', 'PG-13', 'R(17+)', 'Rx'); $imageArr = array (null); - for($i = 1; $i <=30; $i++){ + for($i = 1; $i <= 30; $i++){ array_push($imageArr, '/public/img/anime/anime'.$i.'.jpg'); } $trailerArr = array ( '/public/vid/trailer1.mp4', + '/public/vid/trailer2.mp4', + '/public/vid/trailer3.mp4', null ); - for($i = 0; $i < 60; $i++){ + for($i = 0; $i < $anime_amount; $i++){ $title = getRandomWord(3).' '.getRandomWord(6).' '.getRandomWord(5).' '.getRandomWord(4); $type = $typeArr[rand(0,2)]; $status = $statusArr[rand(0,3)]; $release_date = rand(2000,2020).'-'.rand(1,12).'-'.rand(1,28); $episodes = 24; $rating = $ratingArr[rand(0,3)]; - $score = rand(1,9) + rand(1,10)/10; + $score = 0; $image = $imageArr[rand(0,30)]; - $trailer = $trailerArr[rand(0,1)]; + $trailer = $trailerArr[rand(0,3)]; $studio_id = rand(1,10); $animeTuple = array( @@ -150,15 +166,24 @@ function seedAnimeData(){ function seedAnimeListData(){ global $lorem_ipsum; + global $anime_list_amount; + global $anime_amount; $anime_list = new Anime_List(); $watch_statusArr = array ('WATCHING', 'COMPLETED', 'ON-HOLD', 'DROPPED', 'PLAN TO WATCH'); - for($i = 0; $i < 5; $i++){ + for($i = 0; $i < $anime_list_amount; $i++){ $client_id = rand(1,10); - $anime_id = rand(1,10); + $anime_id = rand(1,$anime_amount); $user_score = rand(1,10); $watch_status = $watch_statusArr[rand(0,4)]; + $check = $anime_list->getAnimeListByAnimeClientID($anime_id, $client_id); + while ($check){ + $client_id = rand(1,10); + $anime_id = rand(1,$anime_amount); + $check = $anime_list->getAnimeListByAnimeClientID($anime_id, $client_id); + } + if ($watch_status == 'COMPLETED'){ $progress = 24; } else if ($watch_status == 'PLAN TO WATCH'){ @@ -181,8 +206,9 @@ function seedAnimeListData(){ } function seedAnimeGenreData(){ + global $anime_amount; $anime_genre = new Anime_Genre(); - for($i = 1; $i <= 10; $i++){ + for($i = 1; $i <= $anime_amount; $i++){ if ($i % 3 == 0){ $genre_id1 = 1; $genre_id2 = 1; @@ -204,28 +230,6 @@ function seedAnimeGenreData(){ } } -function seedRelationshipData(){ - $relationship = new Relationship(); - $typeArr = array('FRIEND', 'PENDING', 'BLOCKED'); - for ($i = 0; $i < 10; $i++){ - $id1 = rand(1,10); - $id2 = rand(1,10); - $type = $typeArr[rand(0,2)]; - while ($relationship->getMutualRelationship($id1, $id2)){ - $id1 = rand(1,10); - $id2 = rand(1,10); - $type = $typeArr[rand(0,2)]; - } - - $relationshipTuple = array ( - 'client_id_1' => $id1, - 'client_id_2' => $id2, - 'type' => $type - ); - $relationship->insertRelationship($relationshipTuple); - } -} - function seedAllData(){ seedClientData(); seedStudioData(); @@ -233,7 +237,6 @@ function seedAllData(){ seedAnimeData(); seedAnimeListData(); seedAnimeGenreData(); - seedRelationshipData(); echo 'Seeding success'; } diff --git a/app/views/Client/detail.php b/app/views/Client/detail.php index f07a8c7d4b682d4139cf44355a5af8bdc682d174..1f5e9dc9ef4cb664c47257897c439f94a61ca513 100644 --- a/app/views/Client/detail.php +++ b/app/views/Client/detail.php @@ -2,6 +2,13 @@ require_once(dirname(__DIR__,2).'/define.php'); require_once(BASE_DIR.'/views/includes/header.php'); +require_once(BASE_DIR.'/models/Client.php'); +require_once(BASE_DIR.'/models/Anime_List.php'); + +$c = new Client(); +$al = new Anime_List(); +$id = $data['id']; +$client = $c->getClientByID($id); ?> @@ -12,11 +19,54 @@ require_once(BASE_DIR.'/views/includes/header.php'); <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Error Page</title> <link rel="stylesheet" href="../../public/style/global.css"> + <link rel="stylesheet" href="../../public/style/client.css"> <script src='/public/handler/navbar.js'></script> </head> <body> - <h1> Ini Error </h1> + <div class='client-big-container'> + <div class='client-left-container'> + <div class='client-main-container'> + <div class='client-image-box'> + <?php + $image = $client['image'] ?? '/public/img/placeholder.jpg'; + echo " + <img class='client-image' src='$image' alt='Client Image'/> + "; + ?> + </div> + <div class='client-description'> + <?php + echo" + <div class='client-username'> $client[username] </div> + <div class='client-email'> $client[email]</div> + <div class='client-id'> Client ID: $client[client_id] </div> + "; + ?> + </div> + </div> + + <div class='client-info-container'> + <?php + $clientType = $client['admin_status'] ? "Admin" : "User"; + $clientTypeColor = $client['admin_status'] ? "red" : "blue"; + $birthdate = $client['birthdate'] ?? "No information"; + $bio = $client['bio'] ?? "No information"; + $avgScore = $al->getAverageUserScoreByClientID($id)['avg']? $al->getAverageUserScoreByClientID($id)['avg'].' / 10 ★' : "Have not been scoring"; + echo " + <div class='client-info-aspect'> Admin Status </div> + <div style=\"color:$clientTypeColor; font-weight:bold\"> $clientType </div> + <div class='client-info-aspect'> Birthdate </div> + <div> $birthdate </div> + <div class='client-info-aspect'> Anime List Amount </div> + <div> 9 </div> + <div class='client-info-aspect'> Average Anime Scoring </div> + <div> $avgScore</div> + "; + ?> + </div> + </div> + </div> </body> </html> diff --git a/app/views/anime/detail.php b/app/views/anime/detail.php index 5eb0889cfff0c60786b1143ae792fba6847c5fb3..6ccd27f1428103a9fc6391b886f170a4f24a5eb9 100644 --- a/app/views/anime/detail.php +++ b/app/views/anime/detail.php @@ -6,16 +6,20 @@ require_once(BASE_DIR.'/models/Anime.php'); require_once(BASE_DIR.'/models/Studio.php'); require_once(BASE_DIR.'/models/Client.php'); require_once(BASE_DIR.'/models/Anime_List.php'); +require_once(BASE_DIR.'/models/Genre.php'); $a = new Anime(); $s = new Studio(); $c = new Client(); $al = new Anime_List(); +$g = new Genre(); + $id = $data['id']; $anime = $a->getAnimeById($id); $studio = $s->getStudioByAnimeID($id); -$reviews = $a-> getReviewsByAnimeID($id); +$reviews = $a->getReviewsByAnimeID($id); +$genres = $g->getAllGenreIDByAnimeID($id); $client_id = $c->getClientByUsername($_SESSION['username'])['client_id']; @@ -56,13 +60,32 @@ $client_id = $c->getClientByUsername($_SESSION['username'])['client_id']; <?php $date = $anime['release_date'] ?? "No information"; $episodes = $anime['episodes'] ?? "No information"; - echo " <div>Score: <span> $anime[score] </span></div> "; - echo " <div>Type: <span> $anime[type] </span></div> "; - echo " <div>Status: <span> $anime[status] </span></div> "; - echo " <div>Genres: <span> Action, Drama, Thriller </span></div> "; - echo " <div>Studios: <span> $studio[name] </span></div> "; - echo " <div>Release Date: <span> $date </span></div> "; - echo " <div>Episodes: <span> $episodes </span></div> "; + $score = ((float) $anime['score']) != 0.0 ? $anime['score'].' ★' : "Has not been scored"; + if ($genres) { + $genreData = $genres[0]['name']; + for ($i = 1; $i < count($genres); $i++){ + $genreData = $genreData.', '.$genres[$i]['name']; + } + } else { + $genreData = "No information"; + } + echo " + <div class='grid-container'> + <div class='anime-details-aspect'> Score </div> + <div> $score </div> + <div class='anime-details-aspect'> Type </div> + <div> $anime[type] </div> + <div class='anime-details-aspect'> Genre </div> + <div> $genreData </div> + <div class='anime-details-aspect'> Studio </div> + <div> $studio[name] </div> + <div class='anime-details-aspect'> Release Date </div> + <div> $date </div> + <div class='anime-details-aspect'> Episodes </div> + <div> $episodes </div> + </div> + + "; ?> <center> diff --git a/app/views/anime/index.php b/app/views/anime/index.php index a2acdeb68e2ff7e97f49aaba4e777f0d57974edc..7ac5c6d2c81c41488723aff1bfa602bcf8d46dd4 100644 --- a/app/views/anime/index.php +++ b/app/views/anime/index.php @@ -41,6 +41,7 @@ $g = new Genre(); $year = date('Y', strtotime($anime['release_date'])) ?? ''; $month = date('M', strtotime($anime['release_date'])) ?? ''; $image = $anime['image'] ?? '../../public/img/placeholder.jpg'; + $score = ((float) $anime['score']) != 0.0 ? $anime['score'].' ★' : "Has not been scored"; echo " <div class='container'> <a href='/?anime/detail/$anime[anime_id]'> @@ -52,7 +53,7 @@ $g = new Genre(); <a href='/?anime/detail/$anime[anime_id]'> <div class='preview-title'> $anime[title] </div> </a> - <div> ★ $anime[score] | $month $year </div> + <div> $score | $month $year </div> <div> $anime[type] | $anime[status] </div> </div> </div> diff --git a/app/views/error/index.php b/app/views/error/index.php index f07a8c7d4b682d4139cf44355a5af8bdc682d174..9ba79095924a4fe2dc0f6343b340fd0908af3ad7 100644 --- a/app/views/error/index.php +++ b/app/views/error/index.php @@ -12,11 +12,23 @@ require_once(BASE_DIR.'/views/includes/header.php'); <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Error Page</title> <link rel="stylesheet" href="../../public/style/global.css"> + <link rel="stylesheet" href="../../public/style/error.css"> <script src='/public/handler/navbar.js'></script> </head> <body> - <h1> Ini Error </h1> + <div class='container'> + <div class='image-box'> + <img class='image' src='/public/img/lost_icon.png' alt='Lost icon'/> + </div> + <div class='description'> + <div style='font-size:24px; font-weight:bold'> Oh no! You have lost! </div> + <div> The page you are searching for does not exist! </div> + <a href='/'> + <div class='back-button'> Go back </div> + </a> + </div> + </div> </body> </html> diff --git a/app/views/home/index.php b/app/views/home/index.php index 5a7096ce9a917da8d8504da6399e4d9b3f84e7f2..03526d7b237b2c5d7c58dfab9cbdaee9ecafb9b0 100644 --- a/app/views/home/index.php +++ b/app/views/home/index.php @@ -95,7 +95,7 @@ require_once(dirname(__DIR__,2).'/define.php'); echo "<a href='/?client/detail/$review[client_id]'>"; echo "<span class='username'>" . htmlspecialchars($review['username']) . "</span>"; echo "</a>"; - echo "<div class='rating'>Score: " . htmlspecialchars($review['user_score']) . "/10★</div>"; + echo "<div class='rating'>Score: " . htmlspecialchars($review['user_score']) . "/10 ★</div>"; echo "</div>"; echo "<p>" . htmlspecialchars($review['review']) . "</p>"; echo "</div>"; @@ -114,13 +114,14 @@ require_once(dirname(__DIR__,2).'/define.php'); <!-- This is a placeholder; repeat this for each top anime --> <?php foreach($top_score as $anime){ + $score = ((float) $anime['score']) != 0.0 ? $anime['score'].' ★' : "Has not been scored"; $image = $anime['image'] ?? '../../public/img/placeholder.jpg'; echo "<a href='/?anime/detail/$anime[anime_id]' class='popular-link'>"; echo "<div class='popular-item'>"; echo "<img class='popular-item-anime' src='" . htmlspecialchars($image) . "' alt='Top Anime Image'>"; echo "<div class='popular-details'>"; echo "<h3>" . htmlspecialchars($anime['title']) . "</h3>"; - echo "<p>Score: " . htmlspecialchars($anime['score']) . "/10★</p>"; + echo "<p>Score: " . htmlspecialchars($score) . "</p>"; echo "<p>" . htmlspecialchars($anime['release_date']) . "</p>"; echo "<p>" . htmlspecialchars($anime['type']) . "</p>"; echo "</div>"; diff --git a/app/views/includes/header.php b/app/views/includes/header.php index b437373004dfe9bdc3731a1d480365d43acb11f0..605ba7de0d44b6434178c1c7c1eed6b9e7535549 100644 --- a/app/views/includes/header.php +++ b/app/views/includes/header.php @@ -5,97 +5,96 @@ require_once(BASE_DIR.'/models/Client.php'); $c = new Client(); -if (!isset($_SESSION['username'])){ - echo " - <div class='both-navbar-appear' id='navbar'> - <div class='upper-navbar'> - <a href='/'> - <div class='logo'> InfoAnimeMasse </div> - </a> - </div> +?> + +<div class='both-navbar-appear' id='navbar'> + <div class='upper-navbar'> + <a href='/'> + <div class='logo'> InfoAnimeMasse </div> + </a> </div> - "; -} else { - if (isset($_SESSION['admin_status'])){ - $id = $c->getClientByUsername($_SESSION['username'])['client_id']; - if ($_SESSION['admin_status']){ - echo " - <div class='both-navbar-appear' id='navbar'> - <div class='upper-navbar'> - <a href='/'> - <div class='logo'> InfoAnimeMasse </div> - </a> - </div> - - <div class='navbar'> - <ul class='nav-links'> - <li><a href='/'>Home</a></li> - <li><a href='/?anime'>Anime</a></li> - <li><a href='/?studio'>Studio</a></li> - <li><a href='/?trailer'>Trailer</a></li> - </ul> - - - <div class='navbar-buttons'> - <a href='/?admin' > - <button class='navbar-icon-btn'> - <img src='../../public/img/admin_icon.png' alt='Admin Button' width='30' height='30'/> - </button> - </a> - <a href='/?client/detail/$id' > - <button class='navbar-icon-btn'> - <img src='../../public/img/client_icon.png' alt='Client Button' width='30' height='30'/> - </button> - </a> - <a href='/api/auth/logout.php' > - <button class='navbar-icon-btn'> - <img src='../../public/img/logout_icon.png' alt='Logout Button' width='30' height='30' /> - </button> - </a> + <div class='navbar'> + <ul class='nav-links'> + <li><a href='/'>Home</a></li> + <li><a href='/?anime'>Anime</a></li> + <li><a href='/?studio'>Studio</a></li> + <li><a href='/?trailer'>Trailer</a></li> + </ul> + + <?php + if (!isset($_SESSION['admin_status'])){ + echo + " + <div class='navbar-buttons'> + <a href='/?login' > + <div class='navbar-icon-btn'> + <img src='../../public/img/login_icon.png' alt='Login Button' width='30' height='30'/> + <div class='navbar-icon-desc'> Login </div> </div> - </div> + </a> + <a href='/?signup' > + <div class='navbar-icon-btn'> + <img src='../../public/img/signup_icon.png' alt='Signup Button' width='30' height='30'/> + <div class='navbar-icon-desc'> Signup </div> + </div> + </a> </div> "; } else { - echo " - <div class='both-navbar-appear' id='navbar'> - <div class='upper-navbar'> - <a href='/'> - <div class='logo'> InfoAnimeMasse </div> - </a> - </div> - - <div class='navbar'> - <ul class='nav-links'> - <li><a href='/'>Home</a></li> - <li><a href='/?anime'>Anime</a></li> - <li><a href='/?studio'>Studio</a></li> - <li><a href='/?trailer'>Trailer</a></li> - </ul> - + $client = $c->getClientByUsername($_SESSION['username']); + $id = $client['client_id']; - - <div class='navbar-buttons'> - <a href='/?client/detail/$id' > - <button class='navbar-icon-btn'> - <img src='../../public/img/client_icon.png' alt='Client Button' width='30' height='30'/> - </button> - </a> - <a href='/api/auth/logout.php' > - <button class='navbar-icon-btn'> - <img src='../../public/img/logout_icon.png' alt='Logout Button' width='30' height='30' /> - </button> - </a> - </div> + if ($_SESSION['admin_status']){ + // Has logged in and an admin + echo + " + <div class='navbar-buttons'> + <a href='/?admin' > + <button class='navbar-icon-btn'> + <img src='../../public/img/admin_icon.png' alt='Admin Button' width='30' height='30'/> + <div class='navbar-icon-desc'> Admin </div> + </button> + </a> + <a href='/?client/detail/$id' > + <button class='navbar-icon-btn'> + <img src='../../public/img/client_icon.png' alt='Client Button' width='30' height='30'/> + <div class='navbar-icon-desc'> Profile </div> + </button> + </a> + <a href='/api/auth/logout.php' > + <button class='navbar-icon-btn'> + <img src='../../public/img/logout_icon.png' alt='Logout Button' width='30' height='30' /> + <div class='navbar-icon-desc'> Logout </div> + </button> + </a> </div> - </div> - "; + "; + } else { + // Has logged in but not an admin + echo + " + <div class='navbar-buttons'> + <a href='/?client/detail/$id' > + <button class='navbar-icon-btn'> + <img src='../../public/img/client_icon.png' alt='Client Button' width='30' height='30'/> + <div class='navbar-icon-desc'> Profile </div> + </button> + </a> + <a href='/api/auth/logout.php' > + <button class='navbar-icon-btn'> + <img src='../../public/img/logout_icon.png' alt='Logout Button' width='30' height='30' /> + <div class='navbar-icon-desc'> Logout </div> + </button> + </a> + </div> + "; + } } - } -} - + ?> + </div> +</div> -// <div class='search-bar'> -// <input type='text' placeholder='Search Anime/Genre/Studi/Trailer'> -// </div> \ No newline at end of file +<!-- <div class='search-bar'> + <input type='text' placeholder='Search Anime/Genre/Studi/Trailer'> +</div> --> \ No newline at end of file diff --git a/app/views/login/index.php b/app/views/login/index.php index ba7ad4a55f42916ca02ccc3366ef6b84100dbb5c..ac7be78878162bfca1cc349f45d50fd6694457ee 100644 --- a/app/views/login/index.php +++ b/app/views/login/index.php @@ -1,61 +1,69 @@ <?php - require_once(dirname(__DIR__,2).'/define.php'); -require_once(BASE_DIR.'/views/includes/header.php'); ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Ini Login </title> + <title>Login </title> <link rel="stylesheet" type="text/css"" href="../../public/style/global.css"> <link rel="stylesheet" type="text/css"" href="../../public/style/login.css"> <script src='/public/handler/navbar.js'></script> </head> <body> + <div class='background-container'> + <img class='background' src='/public/img/login_bg.jpg' alt='Login Wallpaper'/> + </div> + <div class='page-container'> + <div class="menu-login"> + <h2 class='header-subtitle'> Login to your account</h2> + <form action="/api/auth/login.php" method="post" class="form"> + <div class='form-group'> + <label class="form-label" for="username">Username:</label> + <input + type="text" + name="username" + id="username" + class="form-input" + placeholder="Enter your username" + required> + </div> + <div class='form-group'> + <label class="form-label" for="password">Password:</label> + <input + type="password" + name="password" + id="password" + class="form-input" + placeholder="Enter your password" + required> + </div> - <div class="menuLogin"> - <form action="/api/auth/login.php" method="post" class="form"> - <label class="form-label" for="username">Username</label> - <input - type="text" - name="username" - id="username" - class="form_input" - placeholder="Enter your username" - required> - - <label class="form-label" for="password">Password</label> - <input - type="password" - name="password" - id="password" - class="form_input" - placeholder="Enter your password" - required> - - <input type="submit" class="login-btn" value="LOGIN"> - </form> - - - <div class="form-label"> Does not have an account yet? </div> - - <a href='/?signup' style="width:100%; display:flex; justify-content:center; align-items:center"> - <button type="submit" class="signup-btn"> - SIGN UP - </button> - </a> + <?php + if (isset($_SESSION['error'])) { + echo " + <div class='err-message'> $_SESSION[error] </div> + "; + unset($_SESSION['error']); + } + ?> - </div> - - <?php - if (isset($_SESSION['error'])) { - echo $_SESSION['error']; - unset($_SESSION['error']); - } - ?> + <input type="submit" class="login-button" value="LOGIN"> + </form> + <div class="form-label"> Does not have an account yet? </div> + <a href='/?signup' style="width:100%; display:flex; justify-content:center; align-items:center; margin:5px 0px;"> + <button type="submit" class="signup-button"> + SIGN UP + </button> + </a> + <a href='/' style="width:100%; display:flex; justify-content:center; align-items:center; margin:5px 0px;"> + <button type="submit" class="home-button"> + BACK TO HOME + </button> + </a> + </div> </body> </html> diff --git a/app/views/signup/index.php b/app/views/signup/index.php index f67f937f96693fee55aaa8a03618529f8846815e..bf7a4fd910dd3d4aba84de1954403fe2ebf968db 100644 --- a/app/views/signup/index.php +++ b/app/views/signup/index.php @@ -1,78 +1,91 @@ +<?php +require_once(dirname(__DIR__,2).'/define.php'); +?> + <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Sign Up</title> + <link rel="stylesheet" type="text/css"" href="../../public/style/global.css"> + <link rel="stylesheet" type="text/css"" href="../../public/style/login.css"> <script src="/public/handler/signup.js" ></script> <script src='/public/handler/navbar.js'></script> </head> <body> -<div class="container"> - <div class="signup-container"> - <h2 class="header-subtitle">Sign up for free.</h2> - <form action="/api/auth/signup.php" method="post"> - <div class="form-group"> - <label for="email">E-mail</label> - <input - class="signup-input" - type="email" - id="email" - name="email" - placeholder="Enter your email." - onkeyup="checkEmail()" - required - /> - <p id="email-errmsg"></p> - </div> + <div class='background-container'> + <img class='background' src='/public/img/signup_bg.jpg' alt='Signup Wallpaper'/> + </div> + <div class='page-container'> + <div class="menu-signup"> + <h2 class="header-subtitle"> Sign up for free </h2> + <form action="/api/auth/signup.php" method="post" class='form'> + <div class="form-group"> + <label class='form-label' for="email">E-mail</label> + <input + class="form-input" + type="email" + id="email" + name="email" + placeholder="Enter your email." + onkeyup="checkEmail()" + required + /> + <div id="email-errmsg" class='form-err-message'></div> + </div> + + <div class="form-group"> + <label class='form-label' for="username">Username</label> + <input + class="form-input" + type="text" + id="username" + name="username" + onkeyup="checkUsername()" + placeholder="Enter your username." + required + /> + <div id="username-errmsg" class='form-err-message'></div> + </div> + + <div class="form-group"> + <label class='form-label' for="password">Password</label> + <input + class="form-input" + type="password" + id="password" + name="password" + onkeyup="checkPassword()" + placeholder="Create a password." + required + /> + <div id="password-errmsg" class='form-err-message'></div> + </div> - <div class="form-group"> - <label for="username">Username</label> - <input - class="signup-input" - type="text" - id="username" - name="username" - onkeyup="checkUsername()" - placeholder="Enter your username." - required - /> - <p id="username-errmsg"></p> - </div> + <?php + if (isset($_SESSION['error'])) { + echo " + <div class='err-message'> $_SESSION[error] </div> + "; + unset($_SESSION['error']); + } + ?> - <div class="form-group"> - <label for="password">Password</label> - <input - class="signup-input" - type="password" - id="password" - name="password" - onkeyup="checkPassword()" - placeholder="Create a password." - required - /> - <p id="password-errmsg"></p> - </div> + <button type="submit" class="signup-button" id="signup-button" disabled>SIGN UP</button> + </form> - <button type="submit" class="signup-button" id="signup-button" disabled>Sign up</button> - </form> - <?php - if (isset($_SESSION['error'])) { - echo $_SESSION['error']; - unset($_SESSION['error']); - } - ?> - <p class="login">Have an account? - <span - class="login-text" - onclick="window.location.href='/?login'" - > - Login - </span> - </p> - <!-- <button class="login-button" onclick="window.location.href='/?login'"> - Log in - </button> --> + <div class="form-label"> Already have an account? </div> + <a href='/?login' style="width:100%; display:flex; justify-content:center; align-items:center"> + <button type="submit" class="login-button"> + LOGIN + </button> + </a> + <a href='/' style="width:100%; display:flex; justify-content:center; align-items:center; margin:5px 0px;"> + <button type="submit" class="home-button"> + BACK TO HOME + </button> + </a> </div> </div> </body> diff --git a/app/views/studio/detail.php b/app/views/studio/detail.php index ec8b6564ca76c2868353db236660189d9d9bdb01..ac9f8accd4e4f1c1bb981580ba5be0d17324ba76 100644 --- a/app/views/studio/detail.php +++ b/app/views/studio/detail.php @@ -12,7 +12,7 @@ $s = new Studio(); $id = $data['id']; $studio = $s->getStudioByID($id); -$animes = $a->getAllAnimeByStudioID($id); +$animes = $a->getAllAnimeByStudioIDOrdered($id, 'score', true); $anime_count = count($a->getAllAnimeByStudioID($id)); $avg_score = $a->getAverageAnimeScoresByStudioID($id); $rounded_avg_score = round($avg_score['avg'], 2); @@ -73,21 +73,20 @@ $rounded_avg_score = round($avg_score['avg'], 2); <div class="flex-wrap"> <?php foreach($animes as $anime){ - $year = date('Y', strtotime($anime['release_date'])) ?? ''; $image = $anime['image'] ?? '../../public/img/placeholder.jpg'; + $score = ((float) $anime['score']) != 0.0 ? $anime['score'].' ★' : "Has not been scored"; echo " - <div class='anime-container'> - <a href='/?anime/detail/$anime[anime_id]'> + <a href='/?anime/detail/$anime[anime_id]'> + <div class='anime-container'> <div class='anime-box-preview'> <img src='$image' class='anime-image-preview'/> </div> - </a> - <div class='anime-description'> - <div> $anime[title] </div> - <div> ($year) </div> + <div class='anime-description'> + <div class='anime-description-title'> $anime[title] </div> + <div> $score </div> + </div> </div> - </div> - + </a> "; } ?> diff --git a/app/views/trailer/index.php b/app/views/trailer/index.php index bfb0e4a56c14c980f2bd8504bce1a159b2d30bd9..f103d276e51c253e78d8486357d280e532966ffc 100644 --- a/app/views/trailer/index.php +++ b/app/views/trailer/index.php @@ -16,9 +16,17 @@ $a = new Anime(); <link rel="stylesheet" href="../../public/style/global.css"> <link rel="stylesheet" href="../../public/style/trailer.css"> <script src='/public/handler/navbar.js'></script> + <script src='/public/handler/trailer.js'></script> </head> <body> + <div class="trailer-container" id='trailer-div' onclick='hideTrailer()'> + <div class='trailer-box'> + <div class='trailer-title' id='trailer-title'> HEHEHE </div> + <iframe class='anime-trailer-iframe' id='anime-trailer-iframe' src='' autoplay='false' allowfullscreen></iframe> + </div> + </div> + <div class="flex-wrap"> <?php $animes = $a->getAllAnimeWithTrailer(); @@ -26,18 +34,17 @@ $a = new Anime(); $year = date('Y', strtotime($anime['release_date'])) ?? ''; $image = $anime['image'] ?? '../../public/img/placeholder.jpg'; $arr = explode('/', $anime['trailer']); - $trailer = $arr[0].'/'.$arr[1].'/www.youtube.com/embed/'.$arr[3]; + $trailer = htmlspecialchars($anime['trailer']); echo " <div class='container'> - <div class='box-preview'> - <img src='$image' class='image-preview'/> + <div class='box-preview' onclick=\"displayTrailer('$trailer', '$anime[title]')\"> + <img src='$image' class='image-preview' id='image-preview'/> </div> <div class='description'> <div> $anime[title] </div> <div> ($year) </div> </div> </div> - "; } ?>