Add the root "Images" page that lists all available capture images and associated capture details, with links to sub-pages (which do not yet exist/work). This new page uses the bootstrap card-group functionality to lay things out a bit better and provide a mobile reactive site.pull/123/head
@@ -0,0 +1,11 @@ | |||||
<?php | |||||
$img_per_page = 18; | |||||
require('models/db_conn.php'); | |||||
$db_conn = new Conn($configs->db_dir); | |||||
$page_count = $db_conn->totalPages($img_per_page); | |||||
if ($page < 1) $page = 1; | |||||
if ($page > $page_count) $page = $page_count; | |||||
$images = $db_conn->getImages($page, $img_per_page); | |||||
require('views/all_images.php'); | |||||
?> |
@@ -1,6 +1,6 @@ | |||||
<?php | <?php | ||||
require('models/db_conn.php'); | require('models/db_conn.php'); | ||||
$db_con = new Conn($configs->db_dir); | |||||
$passes = $db_con->getPasses(); | |||||
$db_conn = new Conn($configs->db_dir); | |||||
$passes = $db_conn->getPasses(); | |||||
require('views/pass_list.php'); | require('views/pass_list.php'); | ||||
?> | ?> |
@@ -0,0 +1,3 @@ | |||||
footer { | |||||
margin-top: 25px; | |||||
} |
@@ -0,0 +1,10 @@ | |||||
div.card-group.capture-image-cards div.image-card { | |||||
display: block; | |||||
text-align: center; | |||||
} | |||||
div.card-group.capture-image-cards div.image-card img.card-img-top { | |||||
max-height: 180px; | |||||
max-width: 100%; | |||||
width: unset; | |||||
} |
@@ -0,0 +1,7 @@ | |||||
<?php | |||||
$configs = include('config.php'); | |||||
include_once('views/header.php'); | |||||
$page = isset($_GET['page']) ? intval($_GET['page']) : 1; | |||||
require('controllers/images_controller.php'); | |||||
include_once('views/footer.php') | |||||
?> |
@@ -1,6 +1,7 @@ | |||||
<?php | |||||
include_once('views/header.php'); | |||||
$page = isset($_GET['page']) ? intval($_GET['page']) : 1; | |||||
require('controllers/pass_controller.php'); | |||||
include_once('views/footer.php') | |||||
?> | |||||
<?php | |||||
$configs = include('config.php'); | |||||
include_once('views/header.php'); | |||||
$page = isset($_GET['page']) ? intval($_GET['page']) : 1; | |||||
require('controllers/pass_controller.php'); | |||||
include_once('views/footer.php') | |||||
?> |
@@ -2,10 +2,12 @@ | |||||
class Conn { | class Conn { | ||||
private $con; | private $con; | ||||
# default constructor | |||||
public function __construct(string $db_dir) { | public function __construct(string $db_dir) { | ||||
$this->con = new SQLite3($db_dir . 'panel.db'); | $this->con = new SQLite3($db_dir . 'panel.db'); | ||||
} | } | ||||
# get scheduled pass list information | |||||
public function getPasses() { | public function getPasses() { | ||||
$today = strtotime(date('Y-m-d', time())); | $today = strtotime(date('Y-m-d', time())); | ||||
$query = $this->con->query("SELECT sat_name, | $query = $this->con->query("SELECT sat_name, | ||||
@@ -19,12 +21,46 @@ | |||||
$passes = []; | $passes = []; | ||||
$i = 0; | $i = 0; | ||||
while($row = $query->fetchArray()) { | |||||
while ($row = $query->fetchArray()) { | |||||
$passes[$i] = $row; | $passes[$i] = $row; | ||||
$i++; | $i++; | ||||
} | } | ||||
return $passes; | return $passes; | ||||
} | } | ||||
# get total number of pages to display images given the | |||||
# passed number of images per page | |||||
public function totalPages($img_per_page) { | |||||
$total_pages = $this->con->querySingle("SELECT count() from decoded_passes;"); | |||||
return ceil($total_pages/$img_per_page); | |||||
} | |||||
# get a list of images for the given page and total number | |||||
# of configured images per page | |||||
public function getImages($page, $img_per_page) { | |||||
$query = $this->con->prepare("SELECT decoded_passes.id, | |||||
predict_passes.pass_start, | |||||
file_path, | |||||
sat_type, | |||||
predict_passes.sat_name, | |||||
predict_passes.max_elev | |||||
FROM decoded_passes | |||||
INNER JOIN predict_passes | |||||
ON predict_passes.pass_start = decoded_passes.pass_start | |||||
ORDER BY decoded_passes.pass_start DESC LIMIT ? OFFSET ?;"); | |||||
$query->bindValue(1, $img_per_page); | |||||
$query->bindValue(2, $img_per_page * ($page-1)); | |||||
$result = $query->execute(); | |||||
$images = []; | |||||
$i = 0; | |||||
while ($row = $result->fetchArray()) { | |||||
$images[$i] = $row; | |||||
$i++; | |||||
} | |||||
return $images; | |||||
} | |||||
} | } | ||||
?> | ?> |
@@ -0,0 +1,56 @@ | |||||
<link rel="stylesheet" type="text/css" href="css/images.css"> | |||||
<div class="pagination"> | |||||
<?php | |||||
if ($page < 1) { | |||||
echo "<a href=\"?page=" . ($page-1) . "\">" . $lang['prev'] . "</a>"; | |||||
} | |||||
?> | |||||
</div> | |||||
<?php | |||||
$col_count=0; | |||||
$i = 0; | |||||
$img_count = count($images); | |||||
foreach ($images as $image) { | |||||
if ($col_count % 3 == 0) { | |||||
echo "<div class=\"card-group capture-image-cards\">"; | |||||
} | |||||
// automatically append filename conventions | |||||
switch($image['sat_type']) { | |||||
case 0: // Meteor-M2 | |||||
$ending = "-122-rectified.jpg"; | |||||
break; | |||||
case 1: // NOAA | |||||
$ending = "-MCIR.jpg"; | |||||
break; | |||||
case 2: // ISS | |||||
$ending = "-0.png"; | |||||
break; | |||||
} | |||||
# build image path | |||||
$img_path = "/images/thumb/" . $image['file_path'] . $ending; | |||||
// output image and details, with link to respective enhancement images | |||||
echo "<div class=\"card bg-light m-2 p-2 image-card\">"; | |||||
echo " <a href=\"detail.php?id=" . $image['id'] . "\"><img class=\"card-img-top\" src=\"" . $img_path . "\" alt=\"img\"></a>"; | |||||
echo " <div class=\"card-body\">"; | |||||
echo " <h5 class=\"card-title\">" . $image['sat_name'] . "</h5>"; | |||||
echo " <p class=\"card-text\">"; | |||||
echo " <strong>" . $lang['elev'] . ":</strong> " . $image['max_elev'] . "<br>"; | |||||
echo " <strong>" . $lang['pass_start'] . ":</strong> " . date('m/d/Y H:i:s', $image['pass_start']); | |||||
echo " </p>"; | |||||
echo " </div>"; | |||||
echo "</div>"; | |||||
$i++; | |||||
$col_count++; | |||||
if ($col_count % 3 == 0 or $i >= $img_count) { | |||||
echo "</div>"; | |||||
} | |||||
} | |||||
?> |
@@ -17,6 +17,7 @@ | |||||
<meta http-equiv="X-UA-Compatible" content="ie=edge"> | <meta http-equiv="X-UA-Compatible" content="ie=edge"> | ||||
<link rel="stylesheet" type="text/css" href="css/header.css"> | <link rel="stylesheet" type="text/css" href="css/header.css"> | ||||
<link rel="stylesheet" type="text/css" href="css/footer.css"> | |||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" | <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" | ||||
integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous"> | integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous"> | ||||
@@ -28,7 +29,7 @@ | |||||
<header class="mb-3"> | <header class="mb-3"> | ||||
<div class="navbar navbar-expand navbar-dark bg-dark"> | <div class="navbar navbar-expand navbar-dark bg-dark"> | ||||
<ul class="navbar-nav"> | <ul class="navbar-nav"> | ||||
<li class="nav-item <?php if($page == 'index.php' || $page == 'passes.php'){ echo 'active'; }?>"> | |||||
<li class="nav-item <?php if($page == 'index.php'){ echo 'active'; }?>"> | |||||
<a class="nav-link" href="index.php"><?php echo $lang['passes']; ?></a> | <a class="nav-link" href="index.php"><?php echo $lang['passes']; ?></a> | ||||
</li> | </li> | ||||
<li class="nav-item <?php if($page == 'images.php'){ echo 'active'; }?>"> | <li class="nav-item <?php if($page == 'images.php'){ echo 'active'; }?>"> | ||||