summaryrefslogtreecommitdiff
path: root/public/app/views/components
diff options
context:
space:
mode:
authorGeorge Halkiadakis <gchalkiadakis@sklavenitis.co.gr>2023-04-27 03:47:30 +0300
committerGeorge Halkiadakis <gchalkiadakis@sklavenitis.co.gr>2023-04-27 03:47:30 +0300
commit059e0d95d0c28bc5060e87e146eaf7411f51bf90 (patch)
tree7c21ac432f16dde2329a0d5954d70711eceb48e6 /public/app/views/components
parent26cd8ee99659ef1926c96a049c93645ffc9b169d (diff)
downloadgyraf1gov-059e0d95d0c28bc5060e87e146eaf7411f51bf90.tar.gz
gyraf1gov-059e0d95d0c28bc5060e87e146eaf7411f51bf90.tar.bz2
gyraf1gov-059e0d95d0c28bc5060e87e146eaf7411f51bf90.zip
skeleton commit; based on an anom project
Diffstat (limited to 'public/app/views/components')
-rw-r--r--public/app/views/components/breadcrumbs.php30
-rw-r--r--public/app/views/components/courses_menu.php97
-rw-r--r--public/app/views/components/footer.php240
-rw-r--r--public/app/views/components/header_includes.php59
-rw-r--r--public/app/views/components/lessons_list.php54
-rw-r--r--public/app/views/components/subcategories.php19
-rw-r--r--public/app/views/components/top_bar.php40
-rw-r--r--public/app/views/components/user-management.php65
8 files changed, 604 insertions, 0 deletions
diff --git a/public/app/views/components/breadcrumbs.php b/public/app/views/components/breadcrumbs.php
new file mode 100644
index 0000000..59c0fca
--- /dev/null
+++ b/public/app/views/components/breadcrumbs.php
@@ -0,0 +1,30 @@
+<?php
+/** breadcrumbs
+ * -----------------------------------------------------------------------------
+ *
+ * imported variables
+ * ---
+ * @param $id : category_id of last level
+ * @param $label : category title of last level
+ * @param $parents : array of parent nodes
+ * -----------------------------------------------------------------------------
+ */
+
+?>
+<div class="breadcrumb">
+ <!-- home -->
+ <a href="/">Classroom</a>
+
+ <!-- parent nodes -->
+ <?php if ($id != 0) : ?>
+ <?php foreach($parents as $node) : ?>
+ <i class="fas fa-angle-right"></i> <a href="/course/<?=$node['id']?>"><?=$node['label']?></a>
+ <?php endforeach; ?>
+ <?php endif; ?>
+
+ <!-- last (current) node -->
+ <?php if ($id != 0) : ?>
+ <i class="fas fa-angle-right"></i> <a href="/course/<?=$id?>"><?=$label?></a>
+ <?php endif; ?>
+
+</div> \ No newline at end of file
diff --git a/public/app/views/components/courses_menu.php b/public/app/views/components/courses_menu.php
new file mode 100644
index 0000000..6539f8c
--- /dev/null
+++ b/public/app/views/components/courses_menu.php
@@ -0,0 +1,97 @@
+<?php
+/** Categories Menu
+ * -----------------------------------------------------------------------------
+ * sits in the (left) sidebar
+ *
+ * imported variables
+ * ---
+ * @param $categories (array) : the categories tree
+ * @param $open_path (array) : 'id's array of selected categories
+ *
+ * example call:
+ * (draw the categories-menu and set open the categories with ids 1 and 2)
+ * ---
+ * Render::template("section/categories_menu.php",[
+ * 'categories' => $category_tree,
+ * 'open_path' => [1 ,2]
+ * ]);
+ *
+ * -----------------------------------------------------------------------------
+ */
+
+/** tree_ul
+ * creates (recursively) a nested ul-li tree of categories
+ * --- -- -- - - -
+ * @param $tree (array) : categories array formated as tree
+ * @param $open_nodes (array) : array of categor ids that shall be marked open/selected
+ * @return $html (string)
+ */
+function tree_li($tree, $open_nodes = [], $l = 0)
+{
+ $html = "";
+
+ foreach($tree as $node) {
+
+ // if has childs ...
+ // write li ; traverse children recursively
+ if ((isset($node['childs'])) && ( $node['childs']!= [])) {
+
+ if (in_array(intval($node['rec']['id']), $open_nodes)) {
+ $inner_class = "inner show";
+ $sign = "–";
+ $a_class = "has-childs selected";
+
+ } else {
+ $inner_class = "inner";
+ $sign = "+";
+ $a_class = "has-childs";
+ }
+
+ $html .= "<li>
+ <a href='/course/{$node['rec']['id']}' class='{$a_class}'>
+ <span class='label'>{$node['rec']['label']}</span>
+ <span class='toggler'>{$sign}</span>
+ </a>
+ <ul class='{$inner_class}'>"
+ . tree_li($node['childs'], $open_nodes, $l+1)
+ ."</ul>
+ </li>";
+
+
+ } else { // else just write the li
+
+ if (in_array(intval($node['rec']['id']), $open_nodes)) {
+ $u_in = "<u>";
+ $u_out = "</u>";
+ $a_class = "selected";
+
+ } else {
+ $u_in = "";
+ $u_out = "";
+ $a_class = "";
+
+ }
+
+ $html .= "<li>
+ <a href='/course/{$node['rec']['id']}' class='{$a_class}'>
+ <span class='label'>{$node['rec']['label']}</span>
+ </a>
+ </li>";
+ }
+ }
+
+ return $html;
+
+}
+
+
+// draw the menu (hidden on XS screens)
+// -----------------------------------------------------------------------------
+echo "<h3>Διαθέσιμη ύλη</h3>";
+echo "<ul class='hidden-xs side-bar'>". tree_li($categories, $open_path) ."</ul>";
+
+
+
+// TODO:
+// draw menu for XS screens (for example, just the 1st-level categories)
+// (maybe in an accordion so it won;t take too much area on small screens)
diff --git a/public/app/views/components/footer.php b/public/app/views/components/footer.php
new file mode 100644
index 0000000..7cd4a5a
--- /dev/null
+++ b/public/app/views/components/footer.php
@@ -0,0 +1,240 @@
+<?php
+
+use app\extends\Cache_service;
+
+
+/** DESIGNERS
+ * -----------------------------------------------------------------------------
+ *
+ * structures that combine several design information
+ * in a json structrure and parses inta a quite complicated view;
+ *
+ * co-operate with pages
+ *
+ * can be used to rended menus, sections like header or footer etc;
+ *
+ * TODO:
+ * + embed it as a core \Render method
+ * + dynamic designers
+ * + recursive designers
+ *
+ * Here we implement a simplified version of the consept
+ * where entities shall always be `pages`
+ *
+ *
+ * PARAMETRES
+ * --- -- -- - - -
+ *
+ * primary properties of designer structure are 2 properties
+ *
+ * @var class (string): container class name
+ * @var struct (json array): representatoion of the "to-be-designed" structure
+ *
+ * TODO: support more complx `class` strings ex. `.container>#footer>row`
+ *
+ *
+ * Each sub-structure has 2-5 properties:
+ *
+ * @var title (string) : title of the sub-section
+ * @var entity (string) : type of entity (ex: page/lesson/etc; TODO: method of CMS_model?)
+ * @var list (array) : list of entity id(s)
+ * @var template (string) : template that is used to draw the listed pages' info
+ * @var width (string) : class that relates to sub-structure's width
+ *
+ * NOTE:
+ * designer parsing and rendering can be a quite expensive proccess
+ * thus it is strongly recommented to use cached entities
+ *
+ *
+ * Example structure:
+ {
+ "class" : "row", # container class
+ "struct" : [
+ { # block 1
+ "title" : "",
+ "entity" : "page",
+ "list" : [2, 1, 3], # pages to be listed
+ "template" : "list", # list page titles with link to the pages
+ "width" : "col-md-4"
+ },
+ {
+ "template" : "null", # list nothing
+ "width" : "col-md-3"
+ },
+ {
+ "entity" : "page",
+ "list" : [4], # list content of page 4;
+ "template" : "content", # set title to page-title
+ "width" : "col-md-5"
+ }
+
+ TODO: (wish)
+ ,{
+ "template": "struct",
+ "struct" : [
+ {
+ title, entity, list, template, width
+ },
+ ...
+ ]
+ }
+ ]
+ }
+ *
+ * brainstormin: (TODO:)
+ * use some document-describe stucture like the one on the pdfmake js-library
+ * -----------------------------------------------------------------------------
+ */
+
+
+/** check imported variables / data
+ * -----------------------------------------------------------------------------
+ */
+if (!isset($designer)) {
+
+ // default designer (and first case-study)
+ $designer = '{
+ "class" : "row",
+ "struct" : [
+ {
+ "title" : "Πληροφορίες",
+ "entity" : "page",
+ "list" : [2, 1, 3, 4],
+ "template" : "list",
+ "width" : "col-md-4 no-list-mark"
+ },
+ {
+ "entity" : "page",
+ "list" : [6],
+ "template" : "content",
+ "width" : "col-md-3 no-list-mark"
+ },
+ {
+ "entity" : "page",
+ "list" : [5],
+ "template" : "content",
+ "width" : "col-md-5 no-list-mark"
+ }
+ ]
+ }';
+}
+
+// $entity list shall be passed
+// entity link url shall be passed
+
+
+/** templating functions
+ * -----------------------------------------------------------------------------
+ */
+
+/** List template
+ * --- -- -- - - -
+ *
+ * lists entity titles with links
+ * in a `ul>li` html-structure
+ *
+ * @param $title
+ * @param $list
+ * @param $container
+ */
+function list_template($title, $list, $container, $entity) {
+
+ $result = '<div class="'. $container .'">
+ <h4>'. $title .'</h4>
+ <ul>';
+
+ foreach($list as $id) {
+
+ if ($entity[$id]['status'] == 1) { // if entity is published
+ $result .= '
+ <li>
+ <a href="/page/'. $id . '">
+ ' . $entity[$id]['title'] .'
+ </a>
+ </li>';
+ }
+
+ }
+ return $result . '</ul></div>';
+}
+
+/** content_template
+ *
+ * lists whole title and content of entity
+ *
+ * @param $list
+ * @param $container
+ */
+function content_template($list, $container, $entity) {
+
+ $parsedown = new Parsedown();
+
+ $result = '<div class="'. $container .'"><ul>';
+
+ foreach($list as $id) {
+
+ if ($entity[$id]['status'] == 1) { // if entity is published
+
+ $result .= '
+ <li>
+ <h4>'. $entity[$id]['title'] .'</h4>
+ <div>'. $parsedown->text($entity[$id]['body']) .'</div>
+ </li>';
+ }
+
+ }
+ return $result .'</ul></div>';
+}
+
+
+/** ready to start the proccessing
+ * -----------------------------------------------------------------------------
+ */
+
+// decode ...
+$parse = json_decode($designer);
+
+/** then start parse-proccessing ...
+ * -----------------------------------------------------------------------------
+ */
+?>
+
+
+
+<div class="<?=$parse->class?>">
+
+ <?php
+ foreach( $parse->struct as $section ) {
+
+ switch ($section->template) {
+
+ case 'list':
+ echo list_template(
+ $section->title,
+ $section->list,
+ $section->width,
+ $entity
+ );
+ break;
+
+ case 'content':
+ echo content_template(
+ $section->list,
+ $section->width,
+ $entity
+ );
+ break;
+
+ default: // ex. 'null'
+
+ echo '<div class="'. $section->width .'">
+ <h4>'. $section->title.'</h4>
+ </div>';
+ }
+
+ }
+ ?>
+
+</div>
+
+
diff --git a/public/app/views/components/header_includes.php b/public/app/views/components/header_includes.php
new file mode 100644
index 0000000..62dc616
--- /dev/null
+++ b/public/app/views/components/header_includes.php
@@ -0,0 +1,59 @@
+<?php
+ if (!isset($administration)) {
+ $administration = false;
+ }
+?>
+
+<!-- fonts (CDN) -->
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link href="https://fonts.googleapis.com/css2?family=Roboto+Slab:wght@400&display=swap" rel="stylesheet">
+
+<!-- fontawesome icons (CDN) -->
+<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" integrity="sha512-iecdLmaskl7CVkqkXNQ/ZH/XLlvWZOJyj7Yy7tcenmpD1ypASozpmT/E0iPtmFIB46ZmdtAc9eNBvH0H/ZpiBw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
+
+<!-- bootstap (CDN) -->
+<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-aFq/bzH65dt+w6FI2ooMVUpc+21e0SRygnTpmBvdBgSdnuTN7QbdgL+OapgHtvPp" crossorigin="anonymous">
+
+<?php if ($administration) : ?>
+ <!-- datatables css -->
+ <link href="https://cdn.datatables.net/v/bs5/jszip-2.5.0/dt-1.13.4/b-2.3.6/b-colvis-2.3.6/b-html5-2.3.6/b-print-2.3.6/cr-1.6.2/date-1.4.0/fc-4.2.2/fh-3.3.2/kt-2.8.2/r-2.4.1/rr-1.3.3/sc-2.1.1/sl-1.6.2/sr-1.2.2/datatables.min.css" rel="stylesheet"/>
+
+ <!-- select2 css -->
+ <link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
+<?php endif ?>
+
+
+<!-- main css -->
+<link href="/assets/css/class.css" rel="stylesheet">
+
+<!-- overides -->
+<link href="/assets/css/overides.css" rel="stylesheet">
+
+
+
+<!-- bootstrap javascript (CDN) -->
+<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha2/dist/js/bootstrap.bundle.min.js" integrity="sha384-qKXV1j0HvMUeCBQ+QVp7JcfGl760yU08IQ+GpUo5hlbpg51QRiuqHAJz8+BrxE/N" crossorigin="anonymous"></script>
+
+<!-- jQuery (CDN) -->
+<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.4/jquery.min.js" integrity="sha512-pumBsjNRGGqkPzKHndZMaAG+bir374sORyzM3uulLV14lN5LyykqNk8eEeUlUkB3U0M4FApyaHraT65ihJhDpQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
+
+<!-- basic cookie handling (vanilla js) -->
+<script src="/assets/js/cookie.js"></script>
+
+
+<?php if ($administration) : ?>
+ <!-- datatables js -->
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/pdfmake.min.js"></script>
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/vfs_fonts.js"></script>
+ <script src="https://cdn.datatables.net/v/bs5/jszip-2.5.0/dt-1.13.4/b-2.3.6/b-colvis-2.3.6/b-html5-2.3.6/b-print-2.3.6/cr-1.6.2/date-1.4.0/fc-4.2.2/fh-3.3.2/kt-2.8.2/r-2.4.1/rr-1.3.3/sc-2.1.1/sl-1.6.2/sr-1.2.2/datatables.min.js"></script>
+
+ <!-- select2 js -->
+ <script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
+
+ <!-- marked -->
+ <script src="/assets/js/marked/marked.min.js"></script>
+<?php endif ?>
+
+
+
diff --git a/public/app/views/components/lessons_list.php b/public/app/views/components/lessons_list.php
new file mode 100644
index 0000000..a778d59
--- /dev/null
+++ b/public/app/views/components/lessons_list.php
@@ -0,0 +1,54 @@
+<?php
+/** lessons list
+ * -----------------------------------------------------------------------------
+ *
+ * imported variables:
+ * ---
+ * @param $lessons : array of lessons
+ * @param $fieldset : array of optional fields to show [category, intro, date]
+ *
+ * example call:
+ * ---
+ * Render::template("sections/articles_list.php",[
+ * 'articles' => $category_tree,
+ * 'fieldset' => ['date', 'intro']
+ * ])
+ * -----------------------------------------------------------------------------
+ */
+?>
+
+
+<?php foreach($lessons as $post) : ?>
+
+ <!-- <div class="col-xl-4 col-lg-6"> -->
+ <div class="post-card">
+
+ <?php if (in_array('date', $fieldset)) : ?>
+ <?=$post['date']?>
+ <?php endif; ?>
+
+ <div class="post-card--content">
+
+ <h3>
+ <a href="/lesson/<?=$post['id']?>"><?=$post['title']?></a>
+ </h3>
+
+ <?php if (in_array('level', $fieldset)) : ?>
+ <p class="getegory">(επίπεδο πρόσβασης <?=$post['privilege_id']?>)</p>
+ <?php endif; ?>
+
+ <?php if (in_array('category', $fieldset)) : ?>
+ <p class="category"><?=$post['course_id']?></p>
+ <?php endif; ?>
+
+ <?php if (in_array('intro', $fieldset) && $post['intro']) : ?>
+ <p class="intro"><?=$post['intro']?></p>
+ <?php endif; ?>
+
+ </div>
+
+ </div>
+ <!-- </div> -->
+
+<?php endforeach; ?>
+
diff --git a/public/app/views/components/subcategories.php b/public/app/views/components/subcategories.php
new file mode 100644
index 0000000..5c05a94
--- /dev/null
+++ b/public/app/views/components/subcategories.php
@@ -0,0 +1,19 @@
+<!-- Sub-Categories -->
+
+<?php if ($breadcrumbs[ $id ]['childs'] != []) : ?>
+
+ <h5>Υποκεφάλαια</h5>
+
+ <div class="category-childs">
+
+ <?php foreach($breadcrumbs[ $id ]['childs'] as $key => $child) : ?>
+
+ <a href="/course/<?=$child['id']?>" class="btn btn-light">
+ <?=$child['label']?>
+ </a>
+
+ <?php endforeach; ?>
+
+ </div>
+
+<?php endif; ?> \ No newline at end of file
diff --git a/public/app/views/components/top_bar.php b/public/app/views/components/top_bar.php
new file mode 100644
index 0000000..eaffe76
--- /dev/null
+++ b/public/app/views/components/top_bar.php
@@ -0,0 +1,40 @@
+<?php
+/** top bar
+ * -----------------------------------------------------------------------------
+ *
+ * rendrers breadcrumbs and user menu
+ *
+ * imported variables
+ * ---
+ * @param $id : category_id of last level
+ * @param $label : category title of last level
+ * @param $parents : array of parent nodes
+ * -----------------------------------------------------------------------------
+ */
+
+// initialize variables needed if not passed
+// (needed while requiring breadcrumbs)
+if (!isset($id)) {
+ $id = 0;
+ $label = "";
+ $parents = [];
+}
+
+?>
+<div class="top-bar">
+
+ <?php // breadcrumbs
+ ////////////////////////////////////////////////////////////////////////
+ Render::view("components/breadcrumbs", [
+ 'id' => $id,
+ 'label' => $label,
+ 'parents' => $parents
+ ]);
+ ?>
+
+ <?php // User management drop-down
+ ////////////////////////////////////////////////////////////////////////
+ Render::view('components/user-management');
+ ?>
+
+</div><!-- /top-bar --> \ No newline at end of file
diff --git a/public/app/views/components/user-management.php b/public/app/views/components/user-management.php
new file mode 100644
index 0000000..636f2ff
--- /dev/null
+++ b/public/app/views/components/user-management.php
@@ -0,0 +1,65 @@
+<div class="user">
+
+ <div class="dropdown js-visitor">
+ <button type="button" class="btn btn-default dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
+ <i class="fa fa-regular fa-user"></i>
+ Διαχείριση Λογαριασμού
+ <span class="caret"></span>
+ </button>
+ <ul class="dropdown-menu">
+ <li><a class="dropdown-item" href="/login">Είσοδος</a></li>
+
+ <li><hr class="dropdown-divider"></li>
+
+ <li><a class="dropdown-item" href="/registration">Εγγραφή</a></li>
+ <li><a class="dropdown-item disabled" href="/reset-password">Επαναφορά password</a></li>
+ </ul>
+ </div>
+
+ <div class="dropdown js-subscriber">
+ <button type="button" class="btn btn-default dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
+ <i class="fa fa-regular fa-user"></i>
+ Διαχείριση Λογαριασμού <span class="caret"></span>
+ </button>
+ <ul class="dropdown-menu">
+ <li><a class="dropdown-item" href="/account/profile">Διαχείριση Προφίλ</a></li>
+ <li><a class="dropdown-item" href="/account/courses">Ύλη μαθημάτων</a></li>
+ <li><a class="dropdown-item" href="/account/payments">Πληρωμές</a></li>
+
+ <li><hr class="dropdown-divider"></li>
+
+ <li><a class="dropdown-item" href="/logout">Έξοδος</a></li>
+ </ul>
+ </div>
+
+</div>
+
+
+<script>
+ // if user is connected hide anonymous user menu and show connected user's content
+ if (cookieExists('cluser') && (readCookie('cluser').includes('connected'))) {
+ [].forEach.call(document.querySelectorAll('.js-visitor'), function (el) {
+ el.style.display = 'none';
+ });
+ [].forEach.call(document.querySelectorAll('.js-subscriber'), function (el) {
+ el.style.display = 'unset';
+ });
+
+ // also extract user's full name to personalize messages
+ let connection = unescape(readCookie('cluser')).split(';');
+ connection.shift(); // remove 1st item (="connection")
+ let name = connection.join(' '); console.log(name);
+ var node = document.querySelectorAll('.js-subscriber button')[0];
+ node.innerHTML = `<i class="fa fa-regular fa-user"></i> ${name} <span class="caret"></span>`;
+
+
+ } else { // else ... do the opposite
+ [].forEach.call(document.querySelectorAll('.js-subscriber'), function (el) {
+ el.style.display = 'none';
+ });
+ [].forEach.call(document.querySelectorAll('.js-visitor'), function (el) {
+ el.style.display = 'unset';
+ });
+ }
+
+</script>