diff --git a/assets/css/detail.css b/assets/css/detail.css new file mode 100644 index 0000000000000000000000000000000000000000..187d01bb19576ee5bdab41bb610766250baa9c87 --- /dev/null +++ b/assets/css/detail.css @@ -0,0 +1,152 @@ +body{ + font-family: 'Tw Cen MT'; +} + +.detail-left > h1{ + margin : 0; + color: rgba(255, 81, 0, 0.74); + font-size : 60px; +} + +.detail-left > h4{ + margin : 0; + font-size : 24px; +} + +h2{ + font-size : 48px; +} + +#order{ + margin-top : 25px; + padding : 5px 25px; + border: none; + border-radius : 3px; + background-color : rgb(38, 144, 231); + color : white; + float : right; + display: block; + cursor : pointer; +} + +.container{ + display : grid; + grid-template-columns : [col-1] 5% [col-2] 90% [col-3] 5% [col-4]; + grid-template-rows : [row-1] auto [row-2] auto [row-3] auto [row-4]; +} + +.detail{ + display : grid; + grid-column : col-2 / col-3; + grid-row : row-1 / row-2; + grid-template-columns : [col-1] 80% [col-2] 20% [col-3]; + padding-top : 50px; +} + +.detail-left{ + grid-column : col-1 / col-2; +} + +.detail-right{ + grid-column : col-2 / col-3; + text-align : center; + font-size : 24px; + font-weight : bold; +} + +.order{ + grid-column : col-2 / col-3; + grid-row : row-2 / row-3; +} + +#book-img{ + min-width: 50px; +} + +.review{ + grid-column : col-2 / col-3; + grid-row : row-3 / row-4; +} + +.review-item{ + display : grid; + grid-template-columns : [col-1] 10% [col-2] 80% [col-3] 10% [col-4]; + grid-gap : 15px; + margin-bottom : 20px; +} + +.review-left{ + grid-column : col-1 / col-2; +} + +.review-middle{ + grid-column : col-2 / col-3; + word-wrap: break-word; +} + +.review-username{ + font-size : 20px; + font-weight : bold; +} + +.review-message{ + margin-top : -15px; +} + +.review-right{ + grid-column : col-3 / col-4; + text-align : center; +} + +.profile{ + border : 1px solid black; +} + +/* The Modal (background) */ +.modal { + display: none; /* Hidden by default */ + position: fixed; /* Stay in place */ + z-index: 1; /* Sit on top */ + padding-top: 35%; /* Location of the box */ + width: 100%; /* Full width */ + height: 100%; /* Full height */ + overflow: auto; /* Enable scroll if needed */ + background-color: rgb(0,0,0); /* Fallback color */ + background-color: rgba(0,0,0,0.4); /* Black w/ opacity */ + top: 0; +} + +/* Modal Content */ +.modal-content { + background-color: #fefefe; + /* margin-top: 200px; */ + margin: 0 auto auto auto; + padding: 30px 20px; + border: 1px solid #888; + width: 30%; +} + +.modal-content > b{ + margin-left:40px; +} + +#order-id{ + margin-left:40px; +} + +/* The Close Button */ +.close { + color: #999999; + float: right; + font-size: 18px; + font-weight: bold; + margin-top : -23px; + margin-right : -10px; +} + +.close:hover, +.close:focus { + color: #000; + text-decoration: none; + cursor: pointer; +} \ No newline at end of file diff --git a/assets/css/navBar.css b/assets/css/navBar.css index 4f8e38828cad8c0a565d10f0c74b2ccf664995ef..ca27f3214756b20b45f45f8a0dd8a9dc3bd19f77 100644 --- a/assets/css/navBar.css +++ b/assets/css/navBar.css @@ -4,9 +4,14 @@ ul.topNavBar { overflow: hidden; margin: 0; padding: 0; + color: #ffffff; /* height: 40px; */ } +#username{ + text-decoration : underline; +} + li { display: inline-table; font-family: 'Tw Cen MT'; diff --git a/assets/css/search.css b/assets/css/search.css new file mode 100644 index 0000000000000000000000000000000000000000..61f1d31096b3d63b0f391b3f250952fd7c185061 --- /dev/null +++ b/assets/css/search.css @@ -0,0 +1,130 @@ +body{ + font-family: 'Tw Cen MT'; +} + +.container{ + display : grid; + grid-template-columns : [col-1] 5% [col-2] 90% [col-3] 5% [col-4]; + grid-template-rows : [row-1] 100px [row-2] auto [row-3] auto [row-4]; +} + +#searchSection{ + grid-column : col-2 / col-3; +} + +#header{ + grid-row : row-1 / row-2; + display : grid; + grid-template-columns : [col-11] 60% [col-21] 40% [col-31]; + grid-template-rows : [row-11] 35px [row-21] 20px [row-31]; + padding-top : 25px; +} + +#searchbook{ + grid-column : col-11 / col-21; + grid-row : row-11 / row-21; +} + +#searchbook > h1{ + margin : 0; + color: rgba(255, 81, 0, 0.74); + font-size : 60px; +} + +#resultcount{ + grid-column : col-21 / col-31; + grid-row : row-21 / row-31; + text-align : right; +} + +#resultcount > h5{ + font-size:20px; + margin-top:0px; +} + +#form{ + margin-top : 50px; + grid-row : row-2 / row-3; +} + +#title{ + width:100%; + padding : 5px 5px; + border-radius : 3px; +} + +#search{ + margin-top: 15px; + padding : 5px 25px; + border: none; + border-radius : 3px; + background-color : rgb(38, 144, 231); + color : white; + float : right; + display: block; + cursor : pointer; +} + +#result{ + grid-column : col-2 / col-3; + grid-row : row-3 / row-4; +} + +.item{ + margin : 10px; + display : grid; + grid-template-columns : [col-1] 10% [col-2] 90% [col-3]; + grid-template-rows : [row-1] 20px [row-2] 20px [row-3] auto [row-4] 20px [row-5]; + grid-gap : 5px; +} + +.book-image{ + grid-column : col-1 / col-2; + grid-row : row-1 / row-4; +} + +img.book-image{ + border : 1px solid black; +} + +.book-title{ + grid-column : col-2 / col-3; + grid-row : row-1 / row-2; + font-size : 20px; + font-weight : bold; + color: rgba(255, 81, 0, 0.74); +} + +.book-author{ + grid-column : col-2 / col-2; + grid-row : row-2 / row-3; + font-size : 16px; + font-weight : bold; +} + +.book-desc{ + grid-column : col-2 / col-3; + grid-row : row-3 / row-4; + margin-top : -15px; + word-wrap : break-word; +} + +.book-detail{ + grid-column : col-2 / col-3; + grid-row : row-4 / row-5; +} + +.book-img{ + border : 1px solid black; +} + +.detail-btn{ + color : #ffffff; + float : right; + display : inline-block; + background-color : rgb(38, 144, 231); + padding : 4px 20px; + border : none; + cursor : pointer; + border-radius : 3px; +} \ No newline at end of file diff --git a/assets/image/checkmark.png b/assets/image/checkmark.png new file mode 100644 index 0000000000000000000000000000000000000000..c7a8a405767d9f1f04b2ab27fa7c5447ea18ebe4 Binary files /dev/null and b/assets/image/checkmark.png differ diff --git a/assets/js/detail.js b/assets/js/detail.js new file mode 100644 index 0000000000000000000000000000000000000000..6e00deedb7465ea86d43f71d0a40618a60947988 --- /dev/null +++ b/assets/js/detail.js @@ -0,0 +1,67 @@ +window.onload = function() { + var btn = document.getElementById("order"); + var modal = document.getElementById('modal'); + modal.style.display = "none"; + btn.onclick = order; +} + +function order(){ + var select = document.getElementById("amount"); + var amount = select.options[select.selectedIndex].value; + var book_id = window.location.search.split("=")[1]; + var d = new Date(); + var date = d.getFullYear() + '-' + d.getMonth() + '-' + d.getDate(); + + // get search result by ajax + ajax('ajax/book/order', { + data: { + "amount":amount, + "book_id":book_id + }, + success: showModal + + }); +} + +var checked = false; + +function showModal(data){ + + let orderid = document.getElementById("order-id"); + orderid.innerHTML = 'Nomor Transaksi : ' + data['data']; + orderid.style.display = "inline"; + if(!checked){ + let modalcontent = document.getElementsByClassName("modal-content")[0]; + let close = document.getElementsByClassName("close")[0]; + let img = document.createElement("img"); + img.setAttribute("src", "/book/assets/image/checkmark.png"); + img.setAttribute("width", "35px"); + img.setAttribute("height", "30px"); + img.style.display = "inline-block"; + img.style.position = "absolute"; + img.style.marginTop = 0; + img.style.marginRight = "10px"; + modalcontent.insertBefore(img, close); + checked = true; + } + + // Get the modal + var modal = document.getElementById('modal'); + modal.style.display = "block"; + + // Get the <span> element that closes the modal + var span = document.getElementsByClassName("close")[0]; + + // When the user clicks on <span> (x), close the modal + span.onclick = function() { + modal.style.display = "none"; + } + + // When the user clicks anywhere outside of the modal, close it + window.onclick = function(event) { + if (event.target == modal) { + modal.style.display = "none"; + } + } + +} \ No newline at end of file diff --git a/assets/js/result.js b/assets/js/result.js new file mode 100644 index 0000000000000000000000000000000000000000..9906448b6ef7f23ac71bc91f45a7674404721e7e --- /dev/null +++ b/assets/js/result.js @@ -0,0 +1,4 @@ +window.onload(function(){ + var data = "<?= $data['results'] ?>"; + console.log(data); +}) \ No newline at end of file diff --git a/assets/js/search.js b/assets/js/search.js index c0050a28e01519ededd307774e44ed6522f4a938..d9afbe02e05c81a8154570bab4960cd6a5400364 100644 --- a/assets/js/search.js +++ b/assets/js/search.js @@ -1,15 +1,14 @@ -function showSearchResult() { - // document.getElementById("title").value = "HUANA"; - var title = document.getElementById("title").value; - // console.log(title); - // console.log('hi'); - ajax('ajax/book/search', { - data: { - "title":title - }, - success: function(data){ - console.log('hi'); - console.log(data); +var warned = false; + +function validate(){ + let input = document.getElementById("title"); + let title = document.forms["search"]["title"].value; + if(title == null || title == ""){ + if(!warned){ + input.style.border = "3px solid red"; + input.style.transition = "border 5s"; + warned = true; } - }); + return false; + } } \ No newline at end of file diff --git a/controller/DetailController.php b/controller/DetailController.php new file mode 100644 index 0000000000000000000000000000000000000000..b111c043b7a0dc75dc009aee42dcf24685675e24 --- /dev/null +++ b/controller/DetailController.php @@ -0,0 +1,58 @@ +<?php +namespace JLAS\Book\Controller; +use \JLAS\Book\Controller\BaseController; +use \JLAS\Book\Model as Model; +use \JLAS\Book\Entity as Entity; + +class DetailController extends BaseController{ + + /** + * Get the data needed for this controller. + * @return array data passed to the view. + */ + public function run($params){ + if ($this->useArgs('id')) { + $id = $this->getArg('id'); + $book_model = new Model\BookModel(); + $criteria = 'book_id = :book_id'; + $data = array(":book_id" => $id); + $book = $book_model->findById($id); + if (isset($book)) { + $review_model = new Model\ReviewModel(); + $reviews = $review_model->where()->book_id->eq($id)->finish; + + // get biodata model + $bio_model = new Model\BiodataModel(); + + $rating_sum = 0; + $book->avgrating = 0; + if(count($reviews) > 0){ + foreach($reviews as $review){ + // get user profile pictures in review + $bio = $bio_model->findByID($review->username); + if(!empty($bio)){ + $review->image_id = $bio->pic_id; + } + + // and get average rating for the book + $rating_sum += $review->rating; + } + $book->avgrating = (float)($rating_sum / count($reviews)); + } + + $results = array( + "book" => $book, + "reviews" => $reviews + ); + $this->setResponse(200); + return $results; + } else { + $this->setResponse(404, "Unknown book id"); + return; + } + } + $this->setResponse(400); + } +} + +?> \ No newline at end of file diff --git a/controller/OrderController.php b/controller/OrderController.php new file mode 100644 index 0000000000000000000000000000000000000000..fd5ac1b1cbac22d2a774923d84a9b09d75256223 --- /dev/null +++ b/controller/OrderController.php @@ -0,0 +1,57 @@ +<?php +namespace JLAS\Book\Controller; +use \JLAS\Book\Controller\BaseController; +use \JLAS\Book\Model as Model; +use \JLAS\Book\Entity as Entity; + +class OrderController extends BaseController{ + + /** + * Get the data needed for this controller. + * @return array data passed to the view. + */ + public function run($params){ + // check if user logged in + if(isset($params['cookie'], $params['cookie']['access-token'])){ + $token_model = new Model\TokenModel(); + $token = $token_model->where()->field('access-token')->eq($this->token)->finish; + if(count($token) > 0){ + $token = $token[0]; + if($token->isExpired()){ + $this->setResponse(401, 'Not logged in'); + return; + } else { + if(isset($params['data'], $params['data']['book_id'], $params['data']['amount'])){ + $order_model = new Model\OrderModel(); + // create new order entity + $new_order = new Entity\GenericEntity(array( + "book_id" => $this->getArg('book_id'), + "amount" => $this->getArg('amount'), + "order_date" => date('Y-m-d H:i:s', strtotime(date('Y-m-d H:i:s'))), + "username" => $this->getUsername(), + "review_id" => null + )); + + // create new Order + $result = 0; + $order = $order_model->create($new_order); + if($order){ + $result = $new_order->order_id; + } + return $result; + + } else { + $this->setResponse(400); + return; + } + } + } + } else { + $this->setResponse(401, 'Not logged in'); + return; + } + + } +} + +?> \ No newline at end of file diff --git a/controller/SearchController.php b/controller/SearchController.php index 8fa7381c1b52a9af1d0fc7498300e6e42e04cba4..882edc2cb1aa0ccb3a6bc89a5d1b2d8043d0195e 100644 --- a/controller/SearchController.php +++ b/controller/SearchController.php @@ -14,25 +14,41 @@ class SearchController extends BaseController { if(isset($params['data'], $params['data']['title'])){ $book_model = new Model\BookModel(); $review_model = new Model\ReviewModel(); + + // get books by input query with limit $data = array(":title"=>'%'.$params['data']['title'].'%'); $criteria = 'title LIKE :title'; - $results = $book_model->find($criteria, $data); + $qresults = $book_model->find($criteria, $data); + + // get books count by input query + $criteria = 'title LIKE :title'; + $qcount = $book_model->countBy($criteria, $data); + + // get average rating from reviews $criteria = 'book_id = :book_id'; - foreach($results as $result){ + foreach($qresults as $result){ $data = array(":book_id"=>$result->book_id); + + // get all reviews of the current book $review_results = $review_model->find($criteria, $data); + $rating_count = 0; $result->avgrating = 0; if(count($review_results)>0){ + // get average rating $rating_sum = 0; - $rating_count = 0; foreach($review_results as $review_result){ $rating_sum += $review_result->rating; - $rating_count += 1; } - $result->avgrating = (float) ($rating_sum / $rating_count); + $result->avgrating = (float)($rating_sum / count($review_results)); } + $result->votes = count($review_results); } + $results = array( + "count" => $qcount, + "results" => $qresults + ); + return $results; } } diff --git a/mocks/detail.png b/mocks/detail.png index 98369bdd1bb9f86b470caf41e3fccc2955f8b6ef..1803f6e5cdc559863801be2a997e56a82ac435c0 100644 Binary files a/mocks/detail.png and b/mocks/detail.png differ diff --git a/mocks/login.png b/mocks/login.png index 70f8a4633a0e99554eca07b9591255b861fdef0f..a59224cdc7f90639db5da5d324a29ec65482d2fc 100644 Binary files a/mocks/login.png and b/mocks/login.png differ diff --git a/mocks/notification.png b/mocks/notification.png index b14e859a5e33348f4102aaf466139bc317ce48d6..44cc946b3fc926482c099a88ffe9ebb877a83544 100644 Binary files a/mocks/notification.png and b/mocks/notification.png differ diff --git a/model/BookModel.php b/model/BookModel.php index efbbe7551d7fbe9238f514a9899ef959594c2676..005fc41e8ffa4ac4e11155e42ed12342dd6054fa 100644 --- a/model/BookModel.php +++ b/model/BookModel.php @@ -35,6 +35,20 @@ class BookModel extends BaseModel { return $retval; } + + /** + * Count data with matching criteria. + * @return int number of matching data. + */ + public function countBy($criteria, $data) { + $result = $this->query("SELECT COUNT(*) as `count` FROM $this->table WHERE $criteria", $data); + $retval = 0; + if($result){ + $retval = (int)$this->queryResult[0]['count']; + } + return $retval; + } + /** * Insert a new entity into the database. * @param GenericEntity $entity the entity to be created. diff --git a/model/OrderModel.php b/model/OrderModel.php index 37102c7c5248f9bf871225c117217eecb502ad0c..f972e9822a574942098c220f1a52c85c8be32897 100644 --- a/model/OrderModel.php +++ b/model/OrderModel.php @@ -44,7 +44,7 @@ class OrderModel extends BaseModel { */ public function create($entity) { $result = $this->query( - "INSERT INTO $this->table (`username`, `book_id`, `amount`, `order_date`, `review_id`) VALUES (:username, :order_id, :book_id, :amount, :order_date, :review_id)", + "INSERT INTO $this->table (`username`, `book_id`, `amount`, `order_date`, `review_id`) VALUES (:username, :book_id, :amount, :order_date, :review_id)", array( ":username" => $entity->username, ":book_id" => $entity->book_id, @@ -53,7 +53,8 @@ class OrderModel extends BaseModel { ":review_id" => $entity->review_id ) ); - $entity->order_id = $this->connect()->lastInsertedID(); + $entity->order_id = $this->connect()->lastInsertId(); + return $result; } diff --git a/routing/detail.php b/routing/detail.php new file mode 100644 index 0000000000000000000000000000000000000000..db49b4d45ed050a7beaf80fc0a713a4a625ff40b --- /dev/null +++ b/routing/detail.php @@ -0,0 +1,7 @@ +<?php +namespace JLAS\Book; +use SuPHP\Routing as Routing; + +Routing\addRoute("^browse\/detail$", "GET", ["detail.php"], "DetailController"); + +?> \ No newline at end of file diff --git a/routing/order.php b/routing/order.php new file mode 100644 index 0000000000000000000000000000000000000000..2d035c46db082274d2ea97f535484379d2f8a0ce --- /dev/null +++ b/routing/order.php @@ -0,0 +1,7 @@ +<?php +namespace JLAS\Book; +use SuPHP\Routing as Routing; + +Routing\addRoute("^ajax\/book\/order$", "GET", ["json.php"], "OrderController"); + +?> \ No newline at end of file diff --git a/routing/search.php b/routing/search.php new file mode 100644 index 0000000000000000000000000000000000000000..c647204b3c20f261b6615f6397b3867b0e1ded5b --- /dev/null +++ b/routing/search.php @@ -0,0 +1,9 @@ +<?php +namespace JLAS\Book; +use SuPHP\Routing as Routing; + +Routing\addRoute("^browse$", "GET", ["search.php"], "SearchController"); +Routing\addRoute("^ajax\/book\/search$", "GET", ["json.php"], "SearchController"); +Routing\addRoute("^browse\/result$", "GET", ["result.php"], "SearchController"); + +?> \ No newline at end of file diff --git a/sql/orders.sql b/sql/orders.sql index 4b1cdb4bbcb689a74b2637afe314aed28d8f5e4c..81d4fb6e6532139d87821ad4edf4dc9fef3de6aa 100644 --- a/sql/orders.sql +++ b/sql/orders.sql @@ -3,7 +3,7 @@ -- https://www.phpmyadmin.net/ -- -- Host: 127.0.0.1 --- Generation Time: Oct 24, 2018 at 12:43 PM +-- Generation Time: Oct 24, 2018 at 05:08 PM -- Server version: 10.1.31-MariaDB -- PHP Version: 7.2.3 @@ -34,7 +34,7 @@ CREATE TABLE `orders` ( `book_id` int(11) NOT NULL, `order_id` int(11) NOT NULL, `amount` int(11) NOT NULL, - `order_date` date NOT NULL, + `order_date` datetime NOT NULL, `review_id` int(11) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1; @@ -60,6 +60,7 @@ ALTER TABLE `orders` -- ALTER TABLE `orders` MODIFY `order_id` int(11) NOT NULL AUTO_INCREMENT; +<<<<<<< Updated upstream -- -- Constraints for dumped tables @@ -72,6 +73,8 @@ ALTER TABLE `orders` ADD CONSTRAINT `book_id` FOREIGN KEY (`book_id`) REFERENCES `book` (`book_id`) ON DELETE NO ACTION ON UPDATE CASCADE, ADD CONSTRAINT `review_id` FOREIGN KEY (`review_id`) REFERENCES `review` (`review_id`) ON DELETE SET NULL ON UPDATE CASCADE, ADD CONSTRAINT `username` FOREIGN KEY (`username`) REFERENCES `account` (`username`) ON DELETE NO ACTION ON UPDATE CASCADE; +======= +>>>>>>> Stashed changes COMMIT; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; diff --git a/view/detail.php b/view/detail.php new file mode 100644 index 0000000000000000000000000000000000000000..128035983afb0531aa45ca01fbcefefa12eac3c9 --- /dev/null +++ b/view/detail.php @@ -0,0 +1,138 @@ +<?php + if ($response['code'] != 200) { + echo "<script> + alert('Error : ' + '{$response['code']}' + ' ' + '{$response['message']}'); + window.location.href='" . URLROOT . 'history' . "'; + </script>"; + die; + } +?> + +<!DOCTYPE HTML> +<html> + <head> + <meta charset="utf-8" /> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <title>Book Detail</title> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <?php + include VIEW . "navBar.php"; + js("bootstrap.js"); + css("detail.css"); + css("main.css"); + js("detail.js"); + ?> + </head> + <body> + <div class="container"> + <div class="detail"> + <div class="detail-left"> + <h1><?php echo $data['book']->title;?></h1> + <h4><?php echo $data['book']->author;?></h4> + <p> + <?php + echo $data['book']->description; + ?> + </p> + </div> + <div class="detail-right"> + <img class="profile" src= + <?php + if(empty($data['book']->image_id)){ + echo path("assets/image/empty_image.png"); + } else { + path("ajax/image/get?id=" . $data['book']->image_id); + } + ?> + alt="book picture" id="book-img" width=100px height=100px> <br> + <?php + $avgrating = $data['book']->avgrating; + echo(number_format($avgrating, 1) . " / 5.0 <br>"); + $avgrating = round($avgrating, 0, PHP_ROUND_HALF_DOWN); + + // print full star + for($i = 0; $i < $avgrating; $i++){ + echo("<img src=\"/book/assets/image/full_star.png\") width=23px height=23px>"); + } + // print empty star + for($i = 0; $i < 5-$avgrating; $i++){ + echo("<img src=\"/book/assets/image/empty_star.png\") width=23px height=23px>"); + } + ?> + </div> + </div> + <!-- end of detail div --> + <div class="order"> + <h2>Order</h2> + Jumlah : + <select name="amount" id="amount" value=1> + <option value=1 selected="selected">1</option> + <option value=2>2</option> + <option value=3>3</option> + <option value=4>4</option> + <option value=5>5</option> + <option value=6>6</option> + <option value=7>7</option> + <option value=8>8</option> + <option value=9>9</option> + <option value=10>10</option> + </select><br> + <button id="order">Order</button> + </div> + <!-- end of order div --> + <div class="review"> + <h2>Reviews</h2> + <?php + $reviews = $data['reviews']; + for($i=0; $i<count($reviews); $i++){ + $review = $reviews[$i]; + createReviewItem($review); + } + ?> + </div> + <!-- end of review div --> + </div> + <!-- end of container div --> + + <!-- Modal --> + <div id="modal" class="modal"> + + <!-- Modal content --> + <div class="modal-content"> + <span class="close">×</span> + <b>Pemesanan Berhasil!</b><br> + <div id="order-id"></div> + </div> + + </div> + </body> +</html> + +<?php + function createReviewItem($review){ + if(empty($review->image_id)){ + $image_src = "\"/book/assets/image/dummy.jpg\""; + } else { + $image_src = "/book/ajax/image/get?id=" . $review->image_id; + } + echo(" + <div class=\"review-item\"> + <div class=\"review-left\"> + <img class=\"profile\" src=" . $image_src . " width=100% height=100px> + </div> + <div class=\"review-middle\"> + <div class=\"review-username\"> + @". $review->username . + "</div> + <div class=\"review-message\"> + <p>" . $review->message . "</p> + </div> + </div> + <div class=\"review-right\"> + <img src=\"/book/assets/image/full_star.png\" width=50px height=50px><br>" + . number_format($review->rating, 1) . "/5.0" . + "</div> + </div> + "); + } +?> \ No newline at end of file diff --git a/view/item.php b/view/item.php new file mode 100644 index 0000000000000000000000000000000000000000..f701b1ba515b1efca53ea83fc1f6282bd1c226cd --- /dev/null +++ b/view/item.php @@ -0,0 +1,18 @@ +<!DOCTYPE HTML> +<div class="item"> + <div class="book-image"> + <img class="book-image" src=<?php path("ajax/image/get?id=". $image_id)?> alt="book-image" width=100px height=100px> + </div> + <div class="book-title"> + <?php echo($title) ?> + </div> + <div class="book-author"> + <?php echo($author . ' - ' . $avgrating . '/5.0' . ' (' . $votes . ' votes)') ?> + </div> + <div class="book-desc"> + <p><?php echo($description) ?></p> + </div> + <div class="book-detail"> + <a href=<?php echo("detail?id=".$book_id);?>><button class="detail-btn">Detail</button></a> + </div> +</div> \ No newline at end of file diff --git a/view/login.php b/view/login.php index 58e5a5a3bab60186d82ce4feb6d15c0895403b7e..fe6c1a84e0e571ba7fc66bfa66cdf6cde7514a85 100644 --- a/view/login.php +++ b/view/login.php @@ -62,5 +62,4 @@ </tbody> </table> </div> -</body> -</html> \ No newline at end of file +</body> \ No newline at end of file diff --git a/view/result.php b/view/result.php new file mode 100644 index 0000000000000000000000000000000000000000..f47b093e9645fba28bd8b791c9830471058e2070 --- /dev/null +++ b/view/result.php @@ -0,0 +1,73 @@ +<!DOCTYPE HTML> +<html> + <head> + <meta charset="utf-8" /> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <title>Search Result</title> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <?php + include VIEW . "navBar.php"; + js("bootstrap.js"); + css("search.css"); + css("main.css"); + js("search.js"); + ?> + </head> + <body> + <div class="container"> + <?php + // if(count($data['results']) == 0){ + // echo "no results found"; + // return; + // } + ?> + <div id="searchSection"> + <div id="header"> + <div id="searchbook"> + <h1>Search Result</h1> + </div> + <div id="resultcount"> + <h5>Found <u><b><?php echo($data['count']) ?></u></b> results.</h5> + </div> + </div> + </div> + <div id="result"> + <?php + foreach($data['results'] as $result){ + createResultItem($result); + } + ?> + </div> + <!-- end of result div --> + </div> + </body> +</html> + +<?php + function createResultItem($result){ + if(empty($result->image_id)){ + $image_src = "/book/assets/image/empty_image.png"; + } else { + $image_src = "/book/ajax/image/get?id=" . $result->image_id; + } + echo( + "<div class=\"item\"> + <div class=\"book-image\"> + <img class=\"book-image\" src=". $image_src . " alt=\"book-image\" width=100% height=80px> + </div> + <div class=\"book-title\">" + . $result->title . + "</div> + <div class=\"book-author\">" + . $result->author . " - " . number_format($result->avgrating, 1) . "/5.0" . " (" . $result->votes . " votes)" . + "</div> + <div class=\"book-desc\"> + <p>" . $result->description . "</p> + </div> + <div class=\"book-detail\"> + <a href=detail?id=". $result->book_id . "><button class=\"detail-btn\">Detail</button></a> + </div> + </div>" + ); + } +?> \ No newline at end of file diff --git a/view/search.php b/view/search.php index 8487083fd50b25e5202ae6902dda7d118c29414a..a22abf2b72779c4320669cc415713c485090755d 100644 --- a/view/search.php +++ b/view/search.php @@ -5,13 +5,30 @@ <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Browse</title> <meta name="viewport" content="width=device-width, initial-scale=1"> - <script src="assets/js/bootstrap.js"></script> - <script src="assets/js/search.js"></script> + <?php + include VIEW . "navBar.php"; + css("search.css"); + css("main.css"); + js("detail.js"); + ?> </head> <body> - <h1>hi this is search</h1> - Book Title <br> - <input id="title" type="text" value = "" name="title"><br> - <button onclick="showSearchResult()">Hey Tayo</button> + <div class="container"> + <div id="searchSection"> + <div id="header"> + <div id="searchbook"> + <h1>Search Book</h1> + </div> + <div id="resultcount"></div> + </div> + <div id="form"> + <form name="search" onsubmit="return validate()" action="browse/result" method="GET"> + <input id="title" type="text" value = "" name="title" placeholder="Input search terms..." autofocus><br> + <button id="search" type="submit">Search</button> + </form> + </div> + </div> + <div id="result"></div> + </div> </body> </html> \ No newline at end of file