diff options
| author | George Halkiadakis <gchalkiadakis@sklavenitis.co.gr> | 2023-04-27 03:47:30 +0300 |
|---|---|---|
| committer | George Halkiadakis <gchalkiadakis@sklavenitis.co.gr> | 2023-04-27 03:47:30 +0300 |
| commit | 059e0d95d0c28bc5060e87e146eaf7411f51bf90 (patch) | |
| tree | 7c21ac432f16dde2329a0d5954d70711eceb48e6 /public/app/views/components | |
| parent | 26cd8ee99659ef1926c96a049c93645ffc9b169d (diff) | |
| download | gyraf1gov-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.php | 30 | ||||
| -rw-r--r-- | public/app/views/components/courses_menu.php | 97 | ||||
| -rw-r--r-- | public/app/views/components/footer.php | 240 | ||||
| -rw-r--r-- | public/app/views/components/header_includes.php | 59 | ||||
| -rw-r--r-- | public/app/views/components/lessons_list.php | 54 | ||||
| -rw-r--r-- | public/app/views/components/subcategories.php | 19 | ||||
| -rw-r--r-- | public/app/views/components/top_bar.php | 40 | ||||
| -rw-r--r-- | public/app/views/components/user-management.php | 65 |
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> |
