From 9880e3c5d10679fd546a7c6eb6e6e63ac5597eea Mon Sep 17 00:00:00 2001
From: Gulilil <juan.csantoso@gmail.com>
Date: Sat, 7 Oct 2023 05:12:22 +0700
Subject: [PATCH] feat: progress fe pages

---
 app/controller/ClientController.php |   4 +
 app/models/anime.php                |   1 +
 app/models/anime_list.php           |  24 ++++--
 app/public/style/client.css         | 121 ++++++++++++++++++++++++++--
 app/public/style/global.css         |  28 +++++++
 app/public/style/list.css           |  34 ++++++++
 app/views/Client/detail.php         |  55 ++++++++++++-
 app/views/Client/list.php           |  52 ++++++++++++
 8 files changed, 304 insertions(+), 15 deletions(-)
 create mode 100644 app/public/style/list.css
 create mode 100644 app/views/Client/list.php

diff --git a/app/controller/ClientController.php b/app/controller/ClientController.php
index 8407bd7..a18ce24 100644
--- a/app/controller/ClientController.php
+++ b/app/controller/ClientController.php
@@ -7,4 +7,8 @@ class ClientController extends Controller {
   public function detail($id){
     $this->view('Client/detail', array('id' => $id));
   }
+
+  public function list($id){
+    $this->view('Client/list', array('id' => $id));
+  }
 }
\ No newline at end of file
diff --git a/app/models/anime.php b/app/models/anime.php
index 9301708..86be0a4 100644
--- a/app/models/anime.php
+++ b/app/models/anime.php
@@ -125,4 +125,5 @@ class Anime {
     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 1656eca..977c1e8 100644
--- a/app/models/anime_list.php
+++ b/app/models/anime_list.php
@@ -23,7 +23,7 @@ class Anime_List{
   }
 
   public function getAllAnimeListByClientID($id){
-    $thid->db->query('SELECT * FROM ' . $this->table . ' WHERE client_id = '. $id);
+    $this->db->query('SELECT * FROM ' . $this->table . ' WHERE client_id = '. $id);
     return $this->db->fetchAllData();
   }
 
@@ -56,10 +56,8 @@ class Anime_List{
 
   // ================ SPECIFIC QUERY ================
   public function getAnimeListByAnimeClientID($aid, $cid){
-    $this->db->query('SELECT * FROM '.$this->table.' l 
-    JOIN anime a ON l.anime_id = a.anime_id 
-    JOIN client c ON c.client_id = l.client_id 
-    WHERE a.anime_id = '.$aid.' AND c.client_id = '.$cid);
+    $this->db->query('SELECT * FROM '.$this->table.' 
+    WHERE anime_id = '.$aid.' AND client_id = '.$cid);
     return ($this->db->fetchData());
     // return true if there is a row, otherwise false
   }
@@ -69,4 +67,20 @@ class Anime_List{
     return $this->db->fetchData();
   }
 
+  public function getCountAnimeByClientID($id){
+    $this->db->query('SELECT COUNT(anime_id) as count FROM '.$this->table.' WHERE client_id = '.$id);
+    return $this->db->fetchData();
+  }
+
+  public function getAnimeListAndAnimeByClientID( $cid){
+    $this->db->query('SELECT a.title, a.image, l.list_id, l.user_score, l.watch_status, l.review  FROM '.$this->table.' l 
+    JOIN anime a ON l.anime_id = a.anime_id 
+    WHERE l.client_id = '.$cid);
+    return ($this->db->fetchAllData());
+    // return true if there is a row, otherwise false
+  }
+
+
+  
+
 }
\ No newline at end of file
diff --git a/app/public/style/client.css b/app/public/style/client.css
index 1acac2d..9945139 100644
--- a/app/public/style/client.css
+++ b/app/public/style/client.css
@@ -1,24 +1,29 @@
-.client-big-container{
+.client-big-container {
   display: flex;
   justify-content: center;
   align-items: center;
   flex-direction: row;
   padding: 20px;
-  gap: 20px;
+  gap: 10px;
+  border-radius: 5px;
   margin: auto;
+  background-color: white;
+  max-width: 85%;
 }
 
-.client-left-container{
+.client-left-container {
   display: flex;
   justify-content: center;
   align-items: center;
   flex-direction: column;
   padding: 20px;
   gap: 20px;
+  min-width: 400px;
 }
 
-.client-main-container{
+.client-main-container {
   display: flex;
+  width: 90%;
   justify-content: center;
   align-items: center;
   flex-direction: row;
@@ -27,7 +32,7 @@
   border: black 2px solid;
 }
 
-.client-image-box{
+.client-image-box {
   display: flex;
   width: 120px;
   aspect-ratio: 1;
@@ -46,7 +51,9 @@
 .client-description {
   display: flex;
   flex-direction: column;
+  min-width: 175px;
   gap: 5px;
+  padding: 0px 10px;
 }
 
 .client-username {
@@ -60,11 +67,35 @@
   font-weight: bold;
 }
 
-.client-id{
+.client-id {
   font-size: 12px;
   color: #787878;
 }
 
+.client-edit-button {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  margin: 10px auto;
+  padding: 5px;
+  width: 100px;
+  color: white;
+  font-weight: bold;
+  background-color: rgb(168, 64, 64);
+  border-radius: 20px;
+  text-align: center;
+  cursor: pointer;
+  transition: ease-in-out;
+  transition-duration: 0.2s;
+}
+
+.client-edit-button:hover {
+  background-color: rgb(201, 106, 106);
+  width: 125px;
+  transition: ease-in-out;
+  transition-duration: 0.2s;
+}
+
 .client-info-container {
   width: 100%;
   display: grid;
@@ -76,4 +107,80 @@
 
 .client-info-aspect {
   font-weight: bold;
-}
\ No newline at end of file
+}
+
+.client-right-container {
+  display: flex;
+  flex-direction: column;
+  max-width: 650px;
+  gap: 10px;
+}
+
+.client-bio-container {
+  display: flex;
+  flex-direction: column;
+  justify-content: start;
+  align-items: start;
+  width: 100%;
+  max-height: 120px;
+  overflow-y: auto;
+  padding: 0px;
+  background-color: #f4f4f4;
+}
+
+.client-list-container {
+  display: flex;
+  flex-direction: row;
+  gap: 10px;
+  overflow-x: auto;
+  max-width: 100%;
+}
+
+.client-list-container::-webkit-scrollbar {
+  display: none;
+}
+
+.client-anime-list-card {
+  min-width: 200px;
+  max-width: 200px;
+  aspect-ratio: 3/4;
+  height: auto;
+  border: black 2px solid;
+  transition: ease-in-out;
+  transition-duration: 0.2s;
+  cursor: pointer;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  gap: 5px;
+  padding: 10px;
+}
+
+.client-anime-list-card:hover {
+  background-color: #e9e9e9;
+  transition: ease-in-out;
+  transition-duration: 0.2s;
+  border-radius: 10px;
+}
+
+.client-empty-list {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  height: 200px;
+  width: 100%;
+}
+
+.client-anime-image-box {
+  width: 100px;
+  aspect-ratio: 4/5;
+  overflow: hidden;
+}
+
+.client-anime-image {
+  width: 100%;
+  object-fit: contain;
+  object-position: center;
+}
diff --git a/app/public/style/global.css b/app/public/style/global.css
index 9967c6f..0b0e76a 100644
--- a/app/public/style/global.css
+++ b/app/public/style/global.css
@@ -374,3 +374,31 @@ footer {
   margin: 5px 0;
   font-size: 14px;
 }
+
+/* width */
+::-webkit-scrollbar {
+  width: 15px;
+  cursor:pointer;
+}
+
+/* Track */
+::-webkit-scrollbar-track {
+  box-shadow: inset 0 0 3px grey; 
+  border-radius: 10px;
+}
+ 
+/* Handle */
+::-webkit-scrollbar-thumb {
+  background: #ababab; 
+  border-radius: 10px;
+  transition: ease-in-out;
+  transition-duration:0.2s;
+  opacity:0.5;
+}
+
+/* Handle on hover */
+::-webkit-scrollbar-thumb:hover {
+  background: #ababab; 
+  transition: ease-in-out;
+  transition-duration:0.2s;
+}
\ No newline at end of file
diff --git a/app/public/style/list.css b/app/public/style/list.css
new file mode 100644
index 0000000..3c13aa9
--- /dev/null
+++ b/app/public/style/list.css
@@ -0,0 +1,34 @@
+.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;
+  margin: 30px 0px;
+}
+
+.back-button:hover {
+  transition: ease-in-out;
+  transition-duration: 0.2s;
+  width: 150px;
+  background-color: #ff4500;
+  color: white;
+}
+
+.not-own {
+  display:flex; 
+  flex-direction: column;
+  justify-content: center;
+  align-items:center;
+  gap:10px;
+  padding: 20px;
+  border-radius: 10px;
+  background-color: white;
+  width: 400px;
+  margin:auto;
+}
\ No newline at end of file
diff --git a/app/views/Client/detail.php b/app/views/Client/detail.php
index 1f5e9dc..eac1a01 100644
--- a/app/views/Client/detail.php
+++ b/app/views/Client/detail.php
@@ -5,10 +5,13 @@ 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);
+
+$isUser = $c->getClientByUsername($_SESSION['username'])['client_id'] == $id;
 ?>
 
 
@@ -17,7 +20,7 @@ $client = $c->getClientByID($id);
 <head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <title>Error Page</title>
+    <title>Client 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>
@@ -42,6 +45,11 @@ $client = $c->getClientByID($id);
               <div class='client-email'> $client[email]</div>
               <div class='client-id'> Client ID: $client[client_id] </div>
             ";
+            if ($isUser){
+              echo "
+              <div class='client-edit-button'> Edit profile </div> 
+              ";
+            }
           ?>
         </div>
       </div>
@@ -52,20 +60,61 @@ $client = $c->getClientByID($id);
         $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";
+        $avgScore = $al->getAverageUserScoreByClientID($id)['avg']? round($al->getAverageUserScoreByClientID($id)['avg'],2).' / 10 ★' : "Have not been scoring";
+        $countAnime = $al->getCountAnimeByClientID($id)['count'];
         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> $countAnime </div>
           <div class='client-info-aspect'> Average Anime Scoring </div>
           <div> $avgScore</div>
         ";
         ?>
       </div>
     </div>
+    <div class='client-right-container'>
+      <div class='client-bio-container'>
+        <?php
+        $bio = $client['bio'] ?? "No bio details";
+        echo "
+        <div style='margin:20px 20px'>  $client[bio] </div>
+        ";
+        ?>
+      </div>
+      <div class='client-list-container'>
+        <?php
+        // $alc = anime list client
+        $alc = $al->getAnimeListAndAnimeByClientID($id);
+        if ($alc){
+          foreach($alc as $anime){
+            $user_score = $anime['user_score'] ? $anime['user_score'].' ★' : 'None';
+            echo "
+            <a href='/?client/list/$anime[list_id]'>
+              <div class='client-anime-list-card'> 
+                <div class='client-anime-image-box'> 
+                  <img class='client-anime-image' src='$anime[image]' alt='Anime image'/>
+                </div> 
+                <div style='text-align:center'> $anime[title] </div>
+                <div style='text-align:center'> User Score: $user_score </div>
+                <div style='text-align:center'> Status: $anime[watch_status] </div>
+              </div>
+            </a>
+            ";
+          }
+        } else {
+          echo "
+            <div class='client-empty-list'>
+              <h2> No item list </h2>
+              <div style='color:#a2a2a2'> Add some anime to your list first </div>
+            </div>
+          ";
+        }
+        ?>
+      </div>
+    </div>
   </div>  
 </body>
 </html>
diff --git a/app/views/Client/list.php b/app/views/Client/list.php
new file mode 100644
index 0000000..ed4a6bc
--- /dev/null
+++ b/app/views/Client/list.php
@@ -0,0 +1,52 @@
+<?php 
+
+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'];
+$isUserOwn = $al->getAnimeListByID($id)['client_id'] == $c->getClientByUsername($_SESSION['username'])['client_id'];
+
+?>
+
+
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <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/list.css">
+    <script src='/public/handler/navbar.js'></script>
+</head>
+
+<body>
+  <?php
+  if ($isUserOwn){
+    echo "
+      <h1> Anime List ID $id </h1>
+    ";
+  } else {
+    echo "
+    <div class='not-own'>
+      <h2> The list is not your own </h2>
+      <div style='color:#a2a2a2'> You can only edit the list of your own </div>
+      <a href='/'>
+      <div class='back-button'> Go back </div>
+      </a>
+    </div>
+    ";
+  }
+
+  ?>
+</body>
+</html>
+
+<?php
+require_once(BASE_DIR.'/views/includes/footer.php');
+?>
\ No newline at end of file
-- 
GitLab