summaryrefslogtreecommitdiff
path: root/public/assets
diff options
context:
space:
mode:
authorGeo Halkiadakis <gchalkiadakis@sklavenitis.co.gr>2023-06-06 18:34:51 +0300
committerGeo Halkiadakis <gchalkiadakis@sklavenitis.co.gr>2023-06-06 18:34:51 +0300
commitb6fea434ad2888de8dbc87d25ba0444c991d42d6 (patch)
tree55ff4ea770c3c8da834ea37bb5a50cf53e72381a /public/assets
parent1388a64651f1c61a6aafc32f8e3e60f7a6ffd339 (diff)
downloadgyraf1gov-b6fea434ad2888de8dbc87d25ba0444c991d42d6.tar.gz
gyraf1gov-b6fea434ad2888de8dbc87d25ba0444c991d42d6.tar.bz2
gyraf1gov-b6fea434ad2888de8dbc87d25ba0444c991d42d6.zip
send invitation(s) form is ready
Diffstat (limited to 'public/assets')
-rw-r--r--public/assets/css/admin.css124
-rw-r--r--public/assets/css/class.css4
-rw-r--r--public/assets/css/main.css9
-rw-r--r--public/assets/css/normalize.css349
-rw-r--r--public/assets/js/admin/categories.js288
-rw-r--r--public/assets/js/admin/edit_lesson.js600
-rw-r--r--public/assets/js/admin/edit_page.js382
-rw-r--r--public/assets/js/admin/files.js302
-rw-r--r--public/assets/js/admin/lessons.js364
-rw-r--r--public/assets/js/admin/pages.js240
-rw-r--r--public/assets/js/admin/panel.js1
-rw-r--r--public/assets/js/admin/privileges.js291
-rw-r--r--public/assets/js/classroom.js27
-rw-r--r--public/assets/js/edit-post.js612
-rw-r--r--public/assets/js/lesson-features.js218
-rw-r--r--public/assets/js/manage-category.js287
-rw-r--r--public/assets/js/manage-posts.js177
-rw-r--r--public/assets/js/manage-tags.js163
18 files changed, 3 insertions, 4435 deletions
diff --git a/public/assets/css/admin.css b/public/assets/css/admin.css
deleted file mode 100644
index 58fcc45..0000000
--- a/public/assets/css/admin.css
+++ /dev/null
@@ -1,124 +0,0 @@
-:root {
- --class-btn-blue: #337ab7;
- --class-btn-cyan: #5bc0de;
- --class-btn-grey: #c9c9c9;
- --class-btn-grey-light: #c9c9c999;
-}
-
-.office .manage {
- width: 100%;
- max-width: 1600px;
- margin: 0 auto 2em;
-}
-.office .manage.maximized { max-width: 1960px; }
-.office .manage.minimized { max-width: 960px; }
-.office .manage.edit-post { max-width: 1420px; }
-
-.office .edit-post textarea[name=intro] { height: 12vh; }
-.office .edit-post textarea[name=body] {
- height: calc(100vh - 492px);
- min-height:320px;
- font-family: Consolas, 'Ubuntu Mono','Courier New', Courier, monospace;
- color: #333;
-}
-
-.office .edit-post .post-media button.over-bar { margin: -26px 0 0 0; }
-.office .edit-post .post-media ul {
- border: 1px solid #ccc;
- border-radius: 4px;
- padding: 6px;
-}
-
-.office .edit-post .post-media ul li {
- border-bottom: 1px solid #ddd;
- list-style-type: none;
- padding: 3px 6px;
-
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
-.office .edit-post .post-media ul li:last-child { border-bottom: none ;}
-.office .edit-post .post-media ul li:hover { background: #eee; }
-
-.office .manage h2 {
- font-size: 20px;
- color: #445;
- margin: 20px 0;
-}
-
-.office .manage.edit-post textarea { width: 100% !important;}
-.office .manage.edit-post .select2-selection { min-height: 34px; }
-
-.office .manage.edit-post select#status.published {
- background-color: #5cb85c;
- border-color: #4cae4c;
- color: #fff;
- text-align: center;
-}
-.office .manage.edit-post select#status option {
- background: #fff;
- color: #333;
-}
-
-/* --- optional fields: defaut=hide --- */
-
-.office .edit-post .optional label {
- margin-bottom: 1em;
- padding-bottom: .5em;
- border-bottom: 1px solid var(--class-btn-grey-light)
-}
-.office .edit-post .optional label.show {
- margin-bottom: unset;
- border: none;
-}
-
-
-.office .edit-post .optional label:hover {
- cursor: pointer;
- color: var(--class-btn-blue);
-}
-.office .edit-post .optional label::after { float: right; content: "+"; }
-.office .edit-post .optional label.show::after { content: "–"; }
-.office .edit-post .optional label + div { display: none; }
-.office .edit-post .optional label.show + div { display: block; }
-
-
-.alert.alert-info.title-bar { min-height: 52px; margin-top: 20px; }
-.alert.alert-info.title-bar button { margin-left: 8px; }
-
-.office .title-bar {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 8px 8px 8px 16px;
-}
-
-.office .action-btn button { float: right; }
-
-.office .top-bar { padding: 4px 0; }
-
-.office .top-bar .breadcrumb .btn {
- margin-left: 0;
- margin-right: 8px;
- border-radius: 3px;
- color: var(--class-btn-blue);
-}
-
-.office .top-bar .btn:hover {
- background-color: var(--class-btn-grey-light);
-}
-.office .top-bar .btn.selected {
- color: #fff;
- background-color: var(--class-btn-blue);
-}
-
-
-/* --- dataTables --- */
-
-.office .manage .dataTable tbody tr:hover { background: #f8f8f8; }
-.office .manage .dataTable .dt-actions { width: 48px; text-align: right }
-
-/* --- unpublished posts -- */
-.office .manage .dataTable .fa-eye-slash { color: #999; }
-
diff --git a/public/assets/css/class.css b/public/assets/css/class.css
index d1e7715..6e44227 100644
--- a/public/assets/css/class.css
+++ b/public/assets/css/class.css
@@ -201,4 +201,6 @@ html, body {
}
.image-credits a:hover { color: var(--img-credit-hover-color); }
-.manage .table tbody tr:hover { background: #eeea; } \ No newline at end of file
+.manage .table tbody tr:hover { background: #eeea; }
+
+.select2-results__option--selected { display: none; } \ No newline at end of file
diff --git a/public/assets/css/main.css b/public/assets/css/main.css
deleted file mode 100644
index 016e0ab..0000000
--- a/public/assets/css/main.css
+++ /dev/null
@@ -1,9 +0,0 @@
-:root {
-
- --wrapperXXS: 816px;
- --wrapperXS: 984px;
- --wrapperS: 1142px;
- --wrapper: 1240px;
- --wrapperL: 1514px;
- --wrapperFull: 1920px;
-} \ No newline at end of file
diff --git a/public/assets/css/normalize.css b/public/assets/css/normalize.css
deleted file mode 100644
index 192eb9c..0000000
--- a/public/assets/css/normalize.css
+++ /dev/null
@@ -1,349 +0,0 @@
-/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
-
-/* Document
- ========================================================================== */
-
-/**
- * 1. Correct the line height in all browsers.
- * 2. Prevent adjustments of font size after orientation changes in iOS.
- */
-
-html {
- line-height: 1.15; /* 1 */
- -webkit-text-size-adjust: 100%; /* 2 */
-}
-
-/* Sections
- ========================================================================== */
-
-/**
- * Remove the margin in all browsers.
- */
-
-body {
- margin: 0;
-}
-
-/**
- * Render the `main` element consistently in IE.
- */
-
-main {
- display: block;
-}
-
-/**
- * Correct the font size and margin on `h1` elements within `section` and
- * `article` contexts in Chrome, Firefox, and Safari.
- */
-
-h1 {
- font-size: 2em;
- margin: 0.67em 0;
-}
-
-/* Grouping content
- ========================================================================== */
-
-/**
- * 1. Add the correct box sizing in Firefox.
- * 2. Show the overflow in Edge and IE.
- */
-
-hr {
- box-sizing: content-box; /* 1 */
- height: 0; /* 1 */
- overflow: visible; /* 2 */
-}
-
-/**
- * 1. Correct the inheritance and scaling of font size in all browsers.
- * 2. Correct the odd `em` font sizing in all browsers.
- */
-
-pre {
- font-family: monospace, monospace; /* 1 */
- font-size: 1em; /* 2 */
-}
-
-/* Text-level semantics
- ========================================================================== */
-
-/**
- * Remove the gray background on active links in IE 10.
- */
-
-a {
- background-color: transparent;
-}
-
-/**
- * 1. Remove the bottom border in Chrome 57-
- * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
- */
-
-abbr[title] {
- border-bottom: none; /* 1 */
- text-decoration: underline; /* 2 */
- text-decoration: underline dotted; /* 2 */
-}
-
-/**
- * Add the correct font weight in Chrome, Edge, and Safari.
- */
-
-b,
-strong {
- font-weight: bolder;
-}
-
-/**
- * 1. Correct the inheritance and scaling of font size in all browsers.
- * 2. Correct the odd `em` font sizing in all browsers.
- */
-
-code,
-kbd,
-samp {
- font-family: monospace, monospace; /* 1 */
- font-size: 1em; /* 2 */
-}
-
-/**
- * Add the correct font size in all browsers.
- */
-
-small {
- font-size: 80%;
-}
-
-/**
- * Prevent `sub` and `sup` elements from affecting the line height in
- * all browsers.
- */
-
-sub,
-sup {
- font-size: 75%;
- line-height: 0;
- position: relative;
- vertical-align: baseline;
-}
-
-sub {
- bottom: -0.25em;
-}
-
-sup {
- top: -0.5em;
-}
-
-/* Embedded content
- ========================================================================== */
-
-/**
- * Remove the border on images inside links in IE 10.
- */
-
-img {
- border-style: none;
-}
-
-/* Forms
- ========================================================================== */
-
-/**
- * 1. Change the font styles in all browsers.
- * 2. Remove the margin in Firefox and Safari.
- */
-
-button,
-input,
-optgroup,
-select,
-textarea {
- font-family: inherit; /* 1 */
- font-size: 100%; /* 1 */
- line-height: 1.15; /* 1 */
- margin: 0; /* 2 */
-}
-
-/**
- * Show the overflow in IE.
- * 1. Show the overflow in Edge.
- */
-
-button,
-input { /* 1 */
- overflow: visible;
-}
-
-/**
- * Remove the inheritance of text transform in Edge, Firefox, and IE.
- * 1. Remove the inheritance of text transform in Firefox.
- */
-
-button,
-select { /* 1 */
- text-transform: none;
-}
-
-/**
- * Correct the inability to style clickable types in iOS and Safari.
- */
-
-button,
-[type="button"],
-[type="reset"],
-[type="submit"] {
- -webkit-appearance: button;
-}
-
-/**
- * Remove the inner border and padding in Firefox.
- */
-
-button::-moz-focus-inner,
-[type="button"]::-moz-focus-inner,
-[type="reset"]::-moz-focus-inner,
-[type="submit"]::-moz-focus-inner {
- border-style: none;
- padding: 0;
-}
-
-/**
- * Restore the focus styles unset by the previous rule.
- */
-
-button:-moz-focusring,
-[type="button"]:-moz-focusring,
-[type="reset"]:-moz-focusring,
-[type="submit"]:-moz-focusring {
- outline: 1px dotted ButtonText;
-}
-
-/**
- * Correct the padding in Firefox.
- */
-
-fieldset {
- padding: 0.35em 0.75em 0.625em;
-}
-
-/**
- * 1. Correct the text wrapping in Edge and IE.
- * 2. Correct the color inheritance from `fieldset` elements in IE.
- * 3. Remove the padding so developers are not caught out when they zero out
- * `fieldset` elements in all browsers.
- */
-
-legend {
- box-sizing: border-box; /* 1 */
- color: inherit; /* 2 */
- display: table; /* 1 */
- max-width: 100%; /* 1 */
- padding: 0; /* 3 */
- white-space: normal; /* 1 */
-}
-
-/**
- * Add the correct vertical alignment in Chrome, Firefox, and Opera.
- */
-
-progress {
- vertical-align: baseline;
-}
-
-/**
- * Remove the default vertical scrollbar in IE 10+.
- */
-
-textarea {
- overflow: auto;
-}
-
-/**
- * 1. Add the correct box sizing in IE 10.
- * 2. Remove the padding in IE 10.
- */
-
-[type="checkbox"],
-[type="radio"] {
- box-sizing: border-box; /* 1 */
- padding: 0; /* 2 */
-}
-
-/**
- * Correct the cursor style of increment and decrement buttons in Chrome.
- */
-
-[type="number"]::-webkit-inner-spin-button,
-[type="number"]::-webkit-outer-spin-button {
- height: auto;
-}
-
-/**
- * 1. Correct the odd appearance in Chrome and Safari.
- * 2. Correct the outline style in Safari.
- */
-
-[type="search"] {
- -webkit-appearance: textfield; /* 1 */
- outline-offset: -2px; /* 2 */
-}
-
-/**
- * Remove the inner padding in Chrome and Safari on macOS.
- */
-
-[type="search"]::-webkit-search-decoration {
- -webkit-appearance: none;
-}
-
-/**
- * 1. Correct the inability to style clickable types in iOS and Safari.
- * 2. Change font properties to `inherit` in Safari.
- */
-
-::-webkit-file-upload-button {
- -webkit-appearance: button; /* 1 */
- font: inherit; /* 2 */
-}
-
-/* Interactive
- ========================================================================== */
-
-/*
- * Add the correct display in Edge, IE 10+, and Firefox.
- */
-
-details {
- display: block;
-}
-
-/*
- * Add the correct display in all browsers.
- */
-
-summary {
- display: list-item;
-}
-
-/* Misc
- ========================================================================== */
-
-/**
- * Add the correct display in IE 10+.
- */
-
-template {
- display: none;
-}
-
-/**
- * Add the correct display in IE 10.
- */
-
-[hidden] {
- display: none;
-}
diff --git a/public/assets/js/admin/categories.js b/public/assets/js/admin/categories.js
deleted file mode 100644
index e4d2955..0000000
--- a/public/assets/js/admin/categories.js
+++ /dev/null
@@ -1,288 +0,0 @@
-// Globals
-// -----------------------------------------------------------------------------
-var categories = [];
-var table;
-
-
-
-// Supplamentary functions
-// -----------------------------------------------------------------------------
-
-// array.indexOf polyfill
-// --- -- -- - - -
-if (!Array.prototype.indexOf)
-{
- Array.prototype.indexOf = function(elt /*, from*/)
- {
- var len = this.length >>> 0;
-
- var from = Number(arguments[1]) || 0;
- from = (from < 0)
- ? Math.ceil(from)
- : Math.floor(from);
- if (from < 0)
- from += len;
-
- for (; from < len; from++)
- {
- if (from in this &&
- this[from] === elt)
- return from;
- }
- return -1;
- };
-}
-
-
-// function for sorting an array by 'breadcrumb' attribute
-// --- -- -- - - -
-function compare_breadcrumb (a,b) {
- if ( a.breadcrumb < b.breadcrumb ) { return -1; }
- if ( a.breadcrumb > b.breadcrumb ) { return 1; }
- return 0;
-}
-
-// return category record by category-id
-// --- -- -- - - -
-function category_record(id) {
- var record = 0;
- categories.forEach(el => { if (el.id == id) record = el; });
-
- return record;
-}
-
-
-// return children of parent
-// --- -- -- - - -
-function childs_of_parents(list) {
- // if 'list' is integer then make it an one-item list
- parents = (Number.isInteger(list)) ? [ list ] : list;
-
- var childs = [];
-
- if (parents.length == 0) { return []; }
-
- parents.forEach( pid => {
- categories.forEach( el => { if (el.parent == pid) childs.push(el.id)});
- });
-
- var grandchilds = childs_of_parents(childs);
-
- return childs.concat(grandchilds);
-}
-
-
-// create actions html (edit and delete buttons)
-// --- -- -- - - -
-function create_actions_html(id) {
-
- var del, edit;
-
- del = "";
-
- edit = [
- '<button type="button" class="btn btn-sm btn-warning"',
- 'data-bs-toggle="modal" data-bs-target="#manageCategory"',
- 'data-id="'+ id +'">',
- '<i class="fas fa-pencil-alt"></i>',
- '</button>'
- ].join('\n');
-
- return edit +' '+ del;
-}
-
-
-
-$(document).ready(function() {
-
- // When document is ready
- // -------------------------------------------------------------------------
-
-
- /** init selec2 element (used to specify parent-category)
- * --- -- -- - - -
- */
- $("#parent_id").select2({
- placeholder: 'Γονική Κατηγορία',
- dropdownParent: $('#manageCategory'),
- width: '100%',
- // dropdownParent: "#manageCategory" // ref: https://github.com/select2/select2-bootstrap-theme/issues/41
- });
-
-
- /** init_table
- * --- -- -- - - -
- * get categories
- * constuct categories array
- * render dataTable
- */
- function init_table() {
-
- // get all categories from server (ajax)
- $.getJSON( "/admin/api/categories")
- .done(function( json ) {
- // then ...
-
- // reset categories
- categories.length = 0;
-
- // construct (new) categories data
- Object.keys(json).forEach( key => {
- el = json[key];
- categories.push({
- id: parseInt(el.rec.id),
- label: el.rec.label,
- breadcrumb: el.breadcrumb.replaceAll('\t', ' / '),
- parent: parseInt(el.rec.parent),
- actions: create_actions_html(el.rec.id)
- });
- });
-
- // sort by breadcrumb
- categories.sort( compare_breadcrumb );
-
- // destroy previous datatable table instances
- $('#dt-categories').dataTable().fnClearTable();
- $('#dt-categories').dataTable().fnDestroy();
-
- // (re-)create categories datatable
- table = $('#dt-categories').DataTable({
- language: { url: '/libs/DataTables/localization/Greek.json' },
- data: categories,
- ordering: false,
- columns: [
- { data: 'breadcrumb' },
- { data: 'actions' }
- ]
- });
-
- })
- .fail(function( jqxhr, textStatus, error ) {
- console.log( "Request Failed (" + error +")" );
- });
-
- }
- init_table(); // init table on first run
-
-
-
- /** When modal show-up
- * -------------------------------------------------------------------------
- * ... prepare the manage-category form
- * ... update select2 with possible parents
- */
- $('#manageCategory').on('show.bs.modal', event => {
- var button = $(event.relatedTarget); // Button that triggered the modal
- var id = parseInt( button.data('id') ); // category_id from data-id
- // var modal = $(this); // modal object
-
- // update modal literature
- // ---
- $('#manageCategory .modal-title').html( // modal title
- (id) ? 'Ενημέρωση Κατηγορίας' : 'Δημιουργία Κατηγορίας'
- );
- $('#manageCategory form input[name=id]').val( id ); // category id (hidden)
- $('#manageCategory form input[name=label]').val( // category label
- (id) ? category_record(id).label : ""
- );
- prepare_parents_element(id); // prepare <select> for parents
- })
-
- /** prepare_parents_element()
- * ---
- * @param id (int) : id of selected category
- * -> Get all posible parents
- * -> call set_parent_options() to render the options
- */
- function prepare_parents_element(id) {
- var parents = [];
-
- if (id) { // get all possible parents
-
- // id-category and subcategories are fobiden parents
- var forbiden = childs_of_parents(id);
- forbiden.push(id);
-
- // filter catogories adn prepare parents
- categories.forEach( el => {
- if (!forbiden.includes(el.id)) {
- parents.push({
- id: el.id,
- breadcrumb: el.breadcrumb,
- });
- }
- });
- set_parent_options(parents, category_record(id).parent);
-
-
- } else { // new record; all categories are possible parrents
- categories.forEach( el => {
- parents.push({
- id: el.id,
- breadcrumb: el.breadcrumb,
- });
- })
- set_parent_options(parents, -1);
- }
- }
-
- /** set_parent_options()
- * -> create options for parents <select>
- * -> choose selected parent
- * @param parents (array): array of parents
- * @param selected (int): selected parent
- */
- function set_parent_options(parents, selected) {
- // sort parents by breadcrumb
- parents.sort( compare_breadcrumb );
-
- // remove any olded options from select2
- $('#parent_id option').each(function() { $(this).remove(); });
-
- // first option is the root category
- $('#parent_id').append('<option value="0">Root</option>')
-
- // add all other parent options
- parents.forEach( i => {
- $('#parent_id').append(`<option value="${i.id}">${i.breadcrumb}</option>`);
- });
-
- if (selected == -1) { // new category; remove any parent pre-selection
- $('#parent_id').val(null).trigger('change');
-
- } else { // category exists; choose selected parent
- $('#parent_id').val(selected).trigger('change');
- }
- }
-
-
-
-
- // When form is submited
- // -------------------------------------------------------------------------
-
- $('#manageCategory form').submit( event => {
- event.preventDefault();
-
- // prepare data to POST
- var data = {
- id: parseInt($('#manageCategory form input[name=id]').val()),
- label: $('#manageCategory form input[name=label]').val(),
- parent_id: parseInt($('#parent_id').select2('data')[0].id)
- };
-
- // select action url (add or update)
- var request = '/admin/api/categories/' + ((data.id == 0) ? 'add' : 'update');
-
- // send POST request
- $.post(request, data)
- .done(function( data ) {
-
- $('#manageCategory').modal('hide'); // when done, close modal
-
- init_table(); // reload table of categories
- });
-
- });
-
-});
diff --git a/public/assets/js/admin/edit_lesson.js b/public/assets/js/admin/edit_lesson.js
deleted file mode 100644
index 367c3b7..0000000
--- a/public/assets/js/admin/edit_lesson.js
+++ /dev/null
@@ -1,600 +0,0 @@
-/** NOTE:
- * depricated code for tag-system is commented-out and kept in the source-code
- * as case-study; the code is operational;
- */
-
-
-// Globals
-// -----------------------------------------------------------------------------
-
-// NOTE:
-// Variable `entity_id` is defined before evaluating this script
-// id (int) : the id of edited post (or 0 if new post)
-
-var lesson;
-
-var id = (entity_id == 0) ? false : entity_id;
-
-var categories = [
- // Nope! root can not be a post's category ... { id: 0 , label: 'Ρίζα (root)' }
-];
-
-var privileges = [
- { id: 0, label: '_Δημόσιο_'}
-];
-
-var files = []; // array of { id:.., title:.., type:.., path:.. } records
-
-// TODO: support tags
-// var tags = []; // array of integers
-
-
-// an alternative--id when a lesson_id not exists (needed for file-upload)
-// ... consist of a 6-digit date string + random number up to 999
-const yymmdd = new Date().toISOString().slice(2, 10).replaceAll('-','');
-var rnd999 = Math.floor(Math.random() * 1000);
-var altID = (id == 0) ? ( yymmdd +'-'+ rnd999.toString() ) : id;
-
-
-
-
-// Supplamentary functions
-// -----------------------------------------------------------------------------
-
-// function for sorting an array by 'label' attribute
-// --- -- -- - - -
-function compare_label (a,b) {
- if ( a.label < b.label ) { return -1; }
- if ( a.label > b.label ) { return 1; }
- return 0;
-}
-
-// return course record by course-id
-// --- -- -- - - -
-function course_record(id) {
- var record = 0;
- categories.forEach(el => { if (el.id == id) record = el; });
-
- return record;
-}
-
-
-
-
-// Modal HTML Creators
-// -----------------------------------------------------------------------------
-
-const modal_header = (title) => {
- return [
- '<div class="modal-header">',
- '<h4 class="modal-title" id="myModalLabel">',
- title,
- '</h4>',
- '<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">',
- '<span aria-hidden="true"></span>',
- '</button>',
- '</div>'
- ].join('\n');
-}
-
-
-const upload_file_form = () => {
- return [
- '<form method="POST" id="file_upload_form" name="upload_file_form">',
-
- '<div class="modal-body">',
-
- '<input type="hidden" name="folder" value="'+ altID +'">',
-
- '<div class="form-group">',
- '<label for="title">Τίτλος/Περιγραφή για το Αρχείο</label>',
- '<input type="text" class="form-control " value="" name="title" id="title" placeholder="Τίτλος για το Αρχείο" required="">',
- '</div>',
-
- '<div class="form-group">',
- '<label class="control-label" for="file">Εισαγωγή Αρχείου</label>',
- '<input class="form-control" type="file" id="file" name="file" required="">',
- '</div>',
-
- '</div>',
-
- '<div class="modal-footer">',
- '<div class="row" style="width: 50%;">',
- '<div class="form-actions">',
- '<div class="col col-4">',
- '<buton type="button" class="btn btn-default js-modal-close col-12" data-bs-dismiss="modal">',
- 'Κλείσιμο',
- '</button>',
- '</div>',
- '<div class="col-8">',
- '<button class="btn btn-success col-12" type="submit">Καταχώριση</button>',
- '</div>',
- '</div>',
- '</div>',
- '</div>',
-
- '</form>'
- ].join('\n');
-}
-
-
-const preview_article = (title, intro, body) => {
- return [
- '<div class="modal-body">',
- '<div class="post">',
-
- '<h2>'+ title +'</h2>',
-
- ((intro == '') ? '' : ('<div class="intro">'+ intro +'</div>')),
-
- '<div class="article-body">',
- marked.parse(body, { sanitize: true }),
- '</div>',
-
- '</div>',
- '</div>',
- '<div class="modal-footer">',
- '<div class="row" style="width: 50%;">',
- '<div class="form-actions">',
- '<div class="col-md-4 col-md-offset-4 col-6 col-offset-3">',
- '<buton type="button" class="btn btn-default js-modal-close col-12" data-bs-dismiss="modal">',
- 'Κλείσιμο',
- '</button>',
- '</div>',
- '</div>',
- '</div>',
- '</div>'
- ].join('\n');
-}
-
-
-$(document).ready(function() {
-
- // When document is ready
- // -------------------------------------------------------------------------
-
-
- // inti category (select2)
- // ...
- $("#course_id").select2({
- placeholder: 'Κεφάλαιο',
- width: '100%'
- });
-
- // inti category (select2)
- // ...
- $("#privilege_id").select2({
- placeholder: 'Επίπεδο Πρόσβασης',
- width: '100%'
- });
-
-
- /** DEPRICATED: (tag system)
- *
- * // init tags (select2)
- * // ...
- * $('#tags').select2({
- * placeholder: 'Ετικέτες (tags/keywords)',
- * width: '100%',
- * tags: true
- * });
- */
-
- /** DEPRICATED:
- *
- * // TINY-MCE EDITOR
- * init editor (tiny MCE)
- * tinymce.init({
- * selector: 'form textarea[name=body]',
- * language: 'el',
- * menubar: true
- * });
- */
-
-
- /** preload content
- * --- -- -- - - -
- * get post
- * get categories
- * get tags
- * update content (form-elements)
- */
- if (id) { // if an `id` is given, load post .. then init_form
-
- $.getJSON( "/admin/api/lesson/" + id )
- .done( function (data) {
- lesson = data; // keep post
-
- // update fields' values
- $('input[name=id]').val(lesson.id); // id
- $('input[name=title]').val(lesson.title); // title
- $('textarea[name=intro]').val(lesson.intro); // intro
- $('textarea[name=body]').val(lesson.body); // body
- $('select[name=status]').val(
- (lesson.status == 0) ? '0' : "one"
- ).trigger('change');
- // $('input[name=status]').prop( // status
- // 'checked',
- // ((lesson.status==1)? true : false))
- // .trigger('change');
-
- // $('#post-info').html('Δημιουργία: '+post.creation_date+'<br>Τελευταία Ενημέρωση: '+ post.update_date);
-
- // parse media files; then draw
- if (lesson.medias_json != null) {
- files = JSON.parse(lesson.medias_json);
- }
- draw_files_list(); // then draw the files list
-
- init_form_values(); // init all (other) values
- });
-
- } else { // else ... just init_form
- init_form_values();
- }
-
-
-
- /**
- * load categories and tags;
- * if not a new post (id!=0) update form elemnts with post's values
- */
- function init_form_values() {
-
- $.when( // when loaded posts and categories
-
- $.getJSON( "/admin/api/categories" ),
-
- $.getJSON( "/admin/api/privileges" )
-
- ).done( function( categories_response, privileges_response ) {
-
- // construct categories data
- // ---
- Object.keys(categories_response[0]).forEach( key => {
- cat = categories_response[0][key];
- categories.push({
- id: cat.rec.id,
- label: cat.breadcrumb.replaceAll('\t', ' / ')
- });
- });
- categories.sort( compare_label ); // sort categories by breadcrumb
-
- /** DEPRICATED: (tag system)
- *
- * // construct tags data
- * // ---
- * Object.keys(tags_response[0]).forEach( key => {
- * tag = tags_response[0][key];
- * tags.push({
- * id: tag.id,
- * label: tag.name
- * });
- * });
- */
-
- // construct provileges data
- // ---
- Object.keys(privileges_response[0]).forEach( key => {
- priv = privileges_response[0][key];
- privileges.push({
- id: priv.id,
- label: priv.label
- });
- });
- privileges.sort( compare_label ); // sort categories by breadcrumb
-
- // pass categories and tags options onto select2 elements
- // --- -- -- - - -
- if (id == 0) {
- set_parent_options( $('#course_id'), categories );
- set_parent_options( $('#privilege_id'), privileges );
-
- } else {
- // setup category_id options; select post's chosen category-id
- set_parent_options( $('#course_id'), categories, lesson.course_id );
-
- /*** DEPRICATED: (tag system)
- *
- * // parse selected tags
- * // ---
- * var selected_tag_ids = [];
- * if (post.tags_json != null) {
- * var selected_tags = JSON.parse(post.tags_json);
- * selected_tags.forEach( itag => { selected_tag_ids.push(itag.id); })
- * }
- */
-
- // setup tags options; select post's chosen tags
- set_parent_options( $('#privilege_id'), privileges, lesson.privilege_id );
-
- // DEPRICATED: ALSO: if tags selectd, show tags field
- // if (selected_tag_ids.length != 0) { $('.optional label[for=tags]').addClass('show'); }
- }
-
- });
-
- }
-
-
- /** set_parent_options()
- *
- * -> create options for parents <select>
- * -> choose selected parent
- *
- * NOTE:
- * the targer <select> should be a select2 control
- *
- * @param parents (array): array of parents
- * @param selected (int): selected parent
- */
- function set_parent_options(selector, list, selected_value = false) {
-
- list.forEach( li => { // attach options into <select> control
- selector.append(`<option value="${li.id}">${li.label}</option>`);
- });
-
- if (selected_value !== false) { // mark selected option(s)
- selector.val(selected_value).trigger('change');
- }
- else { selector.val(null).trigger('change'); }
- }
-
-
- /** draw_files_list
- * --- -- -- - - -
- */
- function draw_files_list() {
- var li_list = [];
- var ref_icon, ref_class;
-
- files.forEach( item => {
- var copy = [ // copy button
- '<button type="button" class="btn btn-xs btn-default js-copy"',
- ' data-url="' + item.path +'"',
- ' data-type="' + item.type + '"',
- '>',
- '<i class="far fa-clone"></i>',
- '</button>'
- ].join('');
-
- var del = [ // delete button
- '<button type="button" class="btn btn-xs btn-danger js-delete"',
- 'data-id="' + item.id + '">',
- '<i class="fas fa-trash-alt"></i>',
- '</button>'
- ].join('');
- var option = [ // li html
- '<li>',
- '<div class="text">' + item.label + '</div>',
- '<div class="actions">',
- copy, ' ', del,
- '</div>',
- '</li>'
- ].join('');
- li_list.push(option); // push to li_list
- });
- $('#files_list').html( li_list.join('\n') );
-
- }
-
-
-
- // When form's action-buttons are clicked
- // -------------------------------------------------------------------------
-
-
- // form submit
- // --- -- -- - - -
- $('.edit-post form').submit( event => {
- event.preventDefault();
-
- /** DEPRICATED:
- *
- ### TAG SYSTEM
- # // rearrange tags to old and new ones
- # // ---
- # var old_tags = [];
- # var new_tags = [];
- # var tags = $('#tags').select2('data');
- # tags.forEach( t => {
- # if (!parseInt(t.id)) {
- # new_tags.push(t.text);
- # } else { old_tags.push(t.id); }
- # })
- */
-
- var attachments = [];
- // attachments (array) of "`media_id`;`reference`" strings
- files.forEach( f => { attachments.push( f.id ) });
-
- // prepare data to POST
- // ---
- var data = {
- id: parseInt($('.edit-post form input[name=id]').val()),
- title: $('.edit-post form input[name=title]').val(),
- course_id: parseInt($('#course_id').select2('data')[0].id),
- intro: $('.edit-post form textarea[name=intro]').val(),
- body: $('.edit-post form textarea[name=body]').val(),
- status: ( ($('select[name=status]').val() == "0") ? 0 : 1 ),
- privilege_id: parseInt($('#privilege_id').select2('data')[0].id),
- // tags: old_tags,
- // new_tags: new_tags,
- media: attachments
- };
-
- // select action url (add or update)
- // ---
- var request = '/admin/api/lesson/' + ((data.id == 0) ? 'add' : 'update');
-
- // send POST (ajax) request
- $.post(request, data)
- .done(function( data ) {
- // console.log(data);
- window.location.href = '/admin/lessons'; // seems ok; bach to articles
- });
-
- });
-
-
- // go-back (to lessons)
- // --- -- -- - - -
- $('#go-back').click( event => {
- if (confirm('Θέλετε να ακυρώσετε τις όποιες αλλαγές και να φύγτε από τη σελίδα;')) {
- window.location.href = '/admin/lessons';
- }
- });
-
-
- // copy url button
- // --- -- -- - - -
- $('.admin-container').on('click', 'button.js-copy', function (e) {
- var copytext = ''; // default: copy nothing
-
- if ($(this).data('id') !== undefined) {
- copytext = window.location.origin +'/lesson/' + $(this).data('id');
- }
-
- if ($(this).data('url') !== undefined) {
- copytext = window.location.origin + '/serve/file/' + $(this).data('url') + '?type=' + $(this).data('type');
- }
-
- navigator.clipboard
- .writeText(copytext)
- .then(() => { // notify the copy event
- $(this).addClass('copied');
- setTimeout( () => { $(this).removeClass('copied'); }, 700);
- console.log(copytext, ' copied!');
- })
- .catch(() => {
- console.log("error on coping text");
- });
- });
-
-
-
- // delete (remove) file button
- // --- -- -- - - -
- $('.admin-container').on('click', 'button.js-delete', function (e) {
- console.log('delete!');
- var media_id = $(this).data('id');
-
- // remove from files array the one with id == media_id
- // ---
- var temp = [];
- files.forEach( it => { if (it.id != media_id) temp.push(it); });
-
- files = temp; // re-define files
- draw_files_list(); // then re-draw files list
- });
-
-
-
- /** DEPRICATED:
- *
- # // show|hide file as referece button
- # // --- -- -- - - -
- # $('.admin-container').on('click', 'button.js-reference', function (e) {
- # var id = $(this).data('id');
- #
- # // toggle reference attribute of item with `id` = id
- # // ---
- # var temp = [];
- # files.forEach( it => {
- # if (it.id == id) {
- # it.reference = (it.reference==0) ? 1 : 0;
- # }
- # temp.push(it)
- # });
- #
- # files = temp; // re-define files
- # draw_files_list(); // then re-draw files list
- # });
- */
-
-
-
-
-
- /** When modal show-up
- * -------------------------------------------------------------------------
- * ... prepare the manage-category form
- * ... update select2 with possible parents
- */
- $('#editorModal').on('show.bs.modal', event => {
- let button = $(event.relatedTarget); // Button that triggered the modal
- let action = button.data('action'); // action
- // var modal = $(this); // modal object
-
- // update modal literature
-
- switch (action) {
- case 'upload_file':
- $("#editorModal .modal-content").html(
- modal_header('Εισαγωγή Αρχείου') + upload_file_form()
- );
- break;
-
- case 'preview':
- let preview = preview_article(
- $('.edit-post form input[name=title]').val(),
- $('.edit-post form textarea[name=intro]').val(),
- $('.edit-post form textarea[name=body]').val()
- );
- $("#editorModal .modal-content").html( modal_header('Προεπισκόπηση') + preview);
- break;
-
- default:
- // do nothing
- }
-
- });
-
-
-
- /** submit upload file event
- * -------------------------------------------------------------------------
- */
- $('#editorModal').on('submit', 'form[name=upload_file_form]', function (event) {
- event.preventDefault();
-
- // create the FormData object
- // --- -- -- - - -
- var fd = new FormData(document.getElementById('file_upload_form'));
-
- // post the form (via ajax)
- $.ajax({
- url: '/admin/api/file_upload',
- type: 'POST',
- data: fd,
- contentType: false,
- processData: false,
- dataType: 'json',
- success: function(response) { // on success
-
- if (response.success) {
- files.push({ // ... update files array
- id: response.id,
- label: response.title,
- path: response.path,
- type: response.type
- });
- draw_files_list();
-
- $('#editorModal').modal('hide');
-
- } else {
- console.log('File not uploaded');
- }
- }
- });
- });
-
-
- // TODO:
- // disable links while previewing the article
- // OR add a target="_blank"
-
-
-});
-
diff --git a/public/assets/js/admin/edit_page.js b/public/assets/js/admin/edit_page.js
deleted file mode 100644
index ec0e84e..0000000
--- a/public/assets/js/admin/edit_page.js
+++ /dev/null
@@ -1,382 +0,0 @@
-// Globals
-// -----------------------------------------------------------------------------
-
-// NOTE:
-// Variable `entity_id` is defined before evaluating this script
-// id (int) : the id of edited post (or 0 if new post)
-
-var page;
-
-var id = (entity_id == 0) ? false : entity_id;
-
-var files = []; // array of { id:.., title:.., type:.., path:.. } records
-
-// TODO: support tags
-// var tags = []; // array of integers
-
-
-
-// an alternative--id when a page_id not exists (needed for file-upload)
-// ... consist of a 6-digit date string + random number up to 999
-const yymmdd = new Date().toISOString().slice(2, 10).replaceAll('-','');
-var rnd999 = Math.floor(Math.random() * 1000);
-var altID = (id == 0) ? ( yymmdd +'-'+ rnd999.toString() ) : id;
-
-
-
-
-// Supplamentary functions
-// -----------------------------------------------------------------------------
-
-// function for sorting an array by 'label' attribute
-// --- -- -- - - -
-function compare_label (a,b) {
- if ( a.label < b.label ) { return -1; }
- if ( a.label > b.label ) { return 1; }
- return 0;
-}
-
-// return course record by course-id
-// --- -- -- - - -
-function course_record(id) {
- var record = 0;
- categories.forEach(el => { if (el.id == id) record = el; });
-
- return record;
-}
-
-
-
-
-// Modal HTML Creators
-// -----------------------------------------------------------------------------
-
-const modal_header = (title) => {
- return [
- '<div class="modal-header">',
- '<h4 class="modal-title" id="myModalLabel">',
- title,
- '</h4>',
- '<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">',
- '<span aria-hidden="true"></span>',
- '</button>',
- '</div>'
- ].join('\n');
-}
-
-
-const upload_file_form = () => {
- return [
- '<form method="POST" id="file_upload_form" name="upload_file_form">',
-
- '<div class="modal-body">',
-
- '<input type="hidden" name="folder" value="'+ altID +'">',
-
- '<div class="form-group">',
- '<label for="title">Τίτλος/Περιγραφή για το Αρχείο</label>',
- '<input type="text" class="form-control " value="" name="title" id="title" placeholder="Τίτλος για το Αρχείο" required="">',
- '</div>',
-
- '<div class="form-group">',
- '<label class="control-label" for="file">Εισαγωγή Αρχείου</label>',
- '<input class="form-control" type="file" id="file" name="file" required="">',
- '</div>',
-
- '</div>',
-
- '<div class="modal-footer">',
- '<div class="row" style="width: 50%;">',
- '<div class="form-actions">',
- '<div class="col col-4">',
- '<buton type="button" class="btn btn-default js-modal-close col-12" data-bs-dismiss="modal">',
- 'Κλείσιμο',
- '</button>',
- '</div>',
- '<div class="col-8">',
- '<button class="btn btn-success col-12" type="submit">Καταχώριση</button>',
- '</div>',
- '</div>',
- '</div>',
- '</div>',
-
- '</form>'
- ].join('\n');
-}
-
-
-const preview_article = (title, body) => {
- return [
- '<div class="modal-body">',
- '<div class="post">',
-
- '<h2>'+ title +'</h2>',
-
- '<div class="article-body">',
- marked.parse(body, { sanitize: true }),
- '</div>',
-
- '</div>',
- '</div>',
- '<div class="modal-footer">',
- '<div class="row" style="width: 50%;">',
- '<div class="form-actions">',
- '<div class="col-md-4 col-md-offset-4 col-6 col-offset-3">',
- '<buton type="button" class="btn btn-default js-modal-close col-12" data-bs-dismiss="modal">',
- 'Κλείσιμο',
- '</button>',
- '</div>',
- '</div>',
- '</div>',
- '</div>'
- ].join('\n');
-}
-
-
-$(document).ready(function() {
-
- // When document is ready
- // -------------------------------------------------------------------------
-
- /** preload content
- * --- -- -- - - -
- * get page
- * update content (form-elements)
- */
- if (id) { // if an `id` is given, load post .. then init_form
-
- $.getJSON( "/admin/api/page/" + id )
- .done( function (data) {
- page = data; // keep post
-
- // update fields' values
- $('input[name=id]').val(page.id); // id
- $('input[name=title]').val(page.title); // title
- $('textarea[name=body]').val(page.body); // body
- $('select[name=status]').val(
- (page.status == 0) ? '0' : "one"
- ).trigger('change');
-
- // $('#post-info').html('Δημιουργία: '+post.creation_date+'<br>Τελευταία Ενημέρωση: '+ post.update_date);
-
- // parse media files; then draw
- if (page.medias_json != null) {
- files = JSON.parse(page.medias_json);
- }
- draw_files_list(); // then draw the files list
-
- });
-
- }
-
-
- /** draw_files_list
- * --- -- -- - - -
- */
- function draw_files_list() {
- var li_list = [];
- var ref_icon, ref_class;
-
- files.forEach( item => {
- var copy = [ // copy button
- '<button type="button" class="btn btn-xs btn-default js-copy"',
- ' data-url="' + item.path +'"',
- ' data-type="' + item.type + '"',
- '>',
- '<i class="far fa-clone"></i>',
- '</button>'
- ].join('');
-
- var del = [ // delete button
- '<button type="button" class="btn btn-xs btn-danger js-delete"',
- 'data-id="' + item.id + '">',
- '<i class="fas fa-trash-alt"></i>',
- '</button>'
- ].join('');
- var option = [ // li html
- '<li>',
- '<div class="text">' + item.label + '</div>',
- '<div class="actions">',
- copy, ' ', del,
- '</div>',
- '</li>'
- ].join('');
- li_list.push(option); // push to li_list
- });
- $('#files_list').html( li_list.join('\n') );
-
- }
-
-
-
- // When form's action-buttons are clicked
- // -------------------------------------------------------------------------
-
-
- // form submit
- // --- -- -- - - -
- $('.edit-page form').submit( event => {
- event.preventDefault();
-
- var attachments = [];
- // attachments (array) of "`media_id`;`reference`" strings
- files.forEach( f => { attachments.push( f.id ) });
-
- // prepare data to POST
- // ---
- var data = {
- id: parseInt($('.edit-page form input[name=id]').val()),
- title: $('.edit-page form input[name=title]').val(),
- body: $('.edit-page form textarea[name=body]').val(),
- status: ( ($('select[name=status]').val() == "0") ? 0 : 1 ),
- media: attachments
- };
-
- // select action url (add or update)
- // ---
- var request = '/admin/api/page/' + ((data.id == 0) ? 'add' : 'update');
-
- // send POST (ajax) request
- $.post(request, data)
- .done(function( data ) {
- console.log(data);
- window.location.href = '/admin/pages'; // seems ok; bach to articles
- });
-
- });
-
-
- // go-back (to pages)
- // --- -- -- - - -
- $('#go-back').click( event => {
- if (confirm('Θέλετε να ακυρώσετε τις όποιες αλλαγές και να φύγτε από τη σελίδα;')) {
- window.location.href = '/admin/pages';
- }
- });
-
-
- // copy url button
- // --- -- -- - - -
- $('.admin-container').on('click', 'button.js-copy', function (e) {
- var copytext = ''; // default: copy nothing
-
- if ($(this).data('id') !== undefined) {
- copytext = window.location.origin +'/page/' + $(this).data('id');
- }
-
- if ($(this).data('url') !== undefined) {
- copytext = window.location.origin + '/serve/file/' + $(this).data('url') + '?type=' + $(this).data('type');
- }
-
- navigator.clipboard
- .writeText(copytext)
- .then(() => { // notify the copy event
- $(this).addClass('copied');
- setTimeout( () => { $(this).removeClass('copied'); }, 700);
- console.log(copytext, ' copied!');
- })
- .catch(() => {
- console.log("error on coping text");
- });
- });
-
-
-
- // delete (remove) file button
- // --- -- -- - - -
- $('.admin-container').on('click', 'button.js-delete', function (e) {
- console.log('delete!');
- var media_id = $(this).data('id');
-
- // remove from files array the one with id == media_id
- // ---
- var temp = [];
- files.forEach( it => { if (it.id != media_id) temp.push(it); });
-
- files = temp; // re-define files
- draw_files_list(); // then re-draw files list
- });
-
-
-
- /** When modal show-up
- * -------------------------------------------------------------------------
- * ... prepare the manage-category form
- * ... update select2 with possible parents
- */
- $('#editorModal').on('show.bs.modal', event => {
- let button = $(event.relatedTarget); // Button that triggered the modal
- let action = button.data('action'); // action
- // var modal = $(this); // modal object
-
- // update modal literature
-
- switch (action) {
- case 'upload_file':
- $("#editorModal .modal-content").html(
- modal_header('Εισαγωγή Αρχείου') + upload_file_form()
- );
- break;
-
- case 'preview':
- let preview = preview_article(
- $('.edit-page form input[name=title]').val(),
- $('.edit-page form textarea[name=body]').val()
- );
- $("#editorModal .modal-content").html( modal_header('Προεπισκόπηση') + preview);
- break;
-
- default:
- // do nothing
- }
-
- });
-
-
-
- /** submit upload file event
- * -------------------------------------------------------------------------
- */
- $('#editorModal').on('submit', 'form[name=upload_file_form]', function (event) {
- event.preventDefault();
-
- // create the FormData object
- // --- -- -- - - -
- var fd = new FormData(document.getElementById('file_upload_form'));
-
- // post the form (via ajax)
- $.ajax({
- url: '/admin/api/file_upload',
- type: 'POST',
- data: fd,
- contentType: false,
- processData: false,
- dataType: 'json',
- success: function(response) { // on success
-
- if (response.success) {
- files.push({ // ... update files array
- id: response.id,
- label: response.title,
- path: response.path,
- type: response.type
- });
- draw_files_list();
-
- $('#editorModal').modal('hide');
-
- } else {
- console.log('File not uploaded');
- }
- }
- });
- });
-
-
- // TODO:
- // disable links while previewing the article
- // OR add a target="_blank"
-
-
-});
-
diff --git a/public/assets/js/admin/files.js b/public/assets/js/admin/files.js
deleted file mode 100644
index e100b30..0000000
--- a/public/assets/js/admin/files.js
+++ /dev/null
@@ -1,302 +0,0 @@
-// Globals
-// -----------------------------------------------------------------------------
-var privileges = [ { id: 0, label: 'Δημόσιο' } ];
-var files = [];
-var table;
-
-
-
-// Supplamentary functions
-// -----------------------------------------------------------------------------
-
-// array.indexOf polyfill
-// --- -- -- - - -
-if (!Array.prototype.indexOf)
-{
- Array.prototype.indexOf = function(elt /*, from*/)
- {
- var len = this.length >>> 0;
-
- var from = Number(arguments[1]) || 0;
- from = (from < 0)
- ? Math.ceil(from)
- : Math.floor(from);
- if (from < 0)
- from += len;
-
- for (; from < len; from++)
- {
- if (from in this &&
- this[from] === elt)
- return from;
- }
- return -1;
- };
-}
-
-
-// function for sorting an array by 'label' attribute
-// --- -- -- - - -
-function compare_label (a,b) {
- if ( a.label < b.label ) { return -1; }
- if ( a.label > b.label ) { return 1; }
- return 0;
-}
-
-
-// return file record by file-id
-// --- -- -- - - -
-function privilege_record(id) {
- var record = 0;
- files.forEach(el => { if (el.id == id) record = el; });
- return record;
-}
-
-
-/** privilege(id)
- * label of privilege with
- * @param id (int)
- */
-function privilege_(id) {
- let reply = false;
- privileges.forEach( pri => { if (pri.id == id) reply = pri.label; });
- return reply;
-}
-
-
-// create actions html (edit and delete buttons)
-// --- -- -- - - -
-function create_actions_html(id) {
-
- var del, edit;
-
- del = "";
-
- edit = [
- '<button type="button" class="btn btn-sm btn-warning"',
- 'data-bs-toggle="modal" data-bs-target="#manageFiles"',
- 'data-id="'+ id +'">',
- '<i class="fas fa-pencil-alt"></i>',
- '</button>'
- ].join('\n');
-
- return edit +' '+ del;
-}
-
-
-
-$(document).ready(function() {
-
- // When document is ready
- // -------------------------------------------------------------------------
-
-
- /** init selec2 element (used to specify parent-category)
- * --- -- -- - - -
- */
- $("#privilege_id").select2({
- placeholder: 'Επίπεδο πρόσβασης',
- dropdownParent: $('#manageFiles'),
- width: '100%',
- });
-
-
- /** init_table
- * --- -- -- - - -
- * get categories
- * constuct categories array
- * render dataTable
- */
- function init_table() {
-
- // get all categories from server (ajax)
- $.getJSON( "/admin/api/files")
- .done(function( json ) {
- // then ...
-
- // reset categories
- files.length = 0;
-
- // construct (new) categories data
- Object.keys(json).forEach( key => {
- el = json[key];
- files.push({
- id: el.id,
- label: el.label,
- path: el.path,
- type: el.type,
- privilege_id: ((el.privilege_id == null) ? 0 : el.privilege_id),
- privilege: privilege_( ((el.privilege_id == null) ? 0 : el.privilege_id) ),
- actions: create_actions_html(el.id)
- });
- });
-
- // sort by breadcrumb
- // categories.sort( compare_breadcrumb );
-
- // destroy previous datatable table instances
- $('#dt-files').dataTable().fnClearTable();
- $('#dt-files').dataTable().fnDestroy();
-
- // (re-)create categories datatable
- table = $('#dt-files').DataTable({
- language: { url: '/libs/DataTables/localization/Greek.json' },
- data: files,
- ordering: false,
- columns: [
- { data: 'id' },
- { data: 'label' },
- { data: 'path' },
- { data: 'type' },
- { data: 'privilege' },
- { data: 'actions' }
- ]
- });
-
- })
- .fail(function( jqxhr, textStatus, error ) {
- console.log( "Request Failed (" + error +")" );
- });
-
- }
-
-
-
- $.getJSON( "/admin/api/privileges" )
- .done( function( response ) {
-
- // construct provileges data
- // ---
- response.forEach( el => {
- privileges.push({
- id: el.id,
- label: el.label
- });
- });
- privileges.sort( compare_label ); // sort categories by breadcrumb
-
- init_table(); // init table on first run
- });
-
-
-
- /** When modal show-up
- * -------------------------------------------------------------------------
- * ... prepare the manage-category form
- * ... update select2 with possible parents
- */
- $('#managePrivileges').on('show.bs.modal', event => {
- var button = $(event.relatedTarget); // Button that triggered the modal
- var id = parseInt( button.data('id') ); // category_id from data-id
- // var modal = $(this); // modal object
-
- // update modal literature
- // ---
- $('#managePrivileges .modal-title').html( // modal title
- (id) ? 'Ενημέρωση Επιπέδου Πρόσβασης' : 'Δημιουργία Επιπέδου Πρόσβασης'
- );
- $('#managePrivileges form input[name=id]').val( id ); // category id (hidden)
- $('#managePrivileges form input[name=label]').val( // category label
- (id) ? privilege_record(id).label : ""
- );
- prepare_included_element(id); // prepare <select> for parents
- })
-
- /** prepare_included_element()
- * ---
- * @param id (int) : id of selected privilege
- * -> Get all posible included privileges
- * -> call set_included_options() to render the options
- */
- function prepare_included_element(id) {
- var may_included = [];
-
- if (id) { // get all possible parents
-
- // TODO:
- // specify forbiden privilege IDs for being included
-
- // filter privileges adn prepare possible included privileges
- privileges.forEach( el => {
- if (id != el.id) {
- may_included.push({
- id: el.id,
- label: el.label
- });
- }
- });
- console.log(may_included);
- set_included_options(may_included, privilege_record(id).included_id);
-
-
- } else { // new record; all categories are possible parrents
- privileges.forEach( el => {
- may_included.push({
- id: el.id,
- label: el.label,
- });
- })
- set_included_options(may_included, -1);
- }
- }
-
- /** set_included_options()
- * -> create options for parents <select>
- * -> choose selected parent
- * @param may_included (array): array of possible included privileges
- * @param selected (int): selected included privilege
- */
- function set_included_options(may_included, selected) {
- // sort parents by breadcrumb
- // parents.sort( compare_breadcrumb );
-
- // remove any olded options from select2
- $('#included_id option').each(function() { $(this).remove(); });
-
- // first option is the root category
- $('#included_id').append('<option value="0">— κανένα —</option>')
-
- // add all other parent options
- may_included.forEach( i => {
- $('#included_id').append(`<option value="${i.id}">${i.label}</option>`);
- });
-
- if (selected == -1) { // new category; remove any parent pre-selection
- $('#included_id').val(0).trigger('change');
-
- } else { // category exists; choose selected parent
- $('#included_id').val(selected).trigger('change');
- }
- }
-
-
-
-
- // When form is submited
- // -------------------------------------------------------------------------
-
- $('#manageCategory form').submit( event => {
- event.preventDefault();
-
- // prepare data to POST
- var data = {
- id: parseInt($('#manageCategory form input[name=id]').val()),
- label: $('#manageCategory form input[name=label]').val(),
- parent_id: parseInt($('#parent_id').select2('data')[0].id)
- };
-
- // select action url (add or update)
- var request = '/admin/api/category/' + ((data.id == 0) ? 'add' : 'update');
-
- // send POST request
- $.post(request, data)
- .done(function( data ) {
-
- $('#manageCategory').modal('hide'); // when done, close modal
-
- init_table(); // reload table of categories
- });
-
- });
-
-});
diff --git a/public/assets/js/admin/lessons.js b/public/assets/js/admin/lessons.js
deleted file mode 100644
index 1a08875..0000000
--- a/public/assets/js/admin/lessons.js
+++ /dev/null
@@ -1,364 +0,0 @@
-// Globals
-// -----------------------------------------------------------------------------
-var categories = [];
-var privileges = [ { id: 0, label: 'Δημόσιο' } ];
-var lessons = [];
-var table;
-
-
-
-// Supplamentary functions
-// -----------------------------------------------------------------------------
-
-// array.indexOf polyfill
-// --- -- -- - - -
-if (!Array.prototype.indexOf)
-{
- Array.prototype.indexOf = function(elt /*, from*/)
- {
- var len = this.length >>> 0;
-
- var from = Number(arguments[1]) || 0;
- from = (from < 0)
- ? Math.ceil(from)
- : Math.floor(from);
- if (from < 0)
- from += len;
-
- for (; from < len; from++)
- {
- if (from in this &&
- this[from] === elt)
- return from;
- }
- return -1;
- };
-}
-
-
-// function for sorting an array by 'label' attribute
-// --- -- -- - - -
-function compare_label (a,b) {
- if ( a.label < b.label ) { return -1; }
- if ( a.label > b.label ) { return 1; }
- return 0;
-}
-
-
-// function for sorting an array by 'breadcrumb' attribute
-// --- -- -- - - -
-function compare_breadcrumb (a,b) {
- if ( a.breadcrumb < b.breadcrumb ) { return -1; }
- if ( a.breadcrumb > b.breadcrumb ) { return 1; }
- return 0;
-}
-
-// return category record by category-id
-// --- -- -- - - -
-function lesson_record(id) {
- var record = 0;
- lessons.forEach(el => { if (el.id == id) record = el; });
-
- return record;
-}
-
-/** course(id)
- * label of course with
- * @param id (int)
- */
-function course_(id) {
- let reply = false;
- categories.forEach( cat => { if (cat.id == id) reply = cat.label; })
- return reply;
-}
-
-/** privilege(id)
- * label of privilege with
- * @param id (int)
- */
-function privilege_(id) {
- let reply = false;
- privileges.forEach( pri => { if (pri.id == id) reply = pri.label; });
- return reply;
-}
-
-
-//// return children of parent
-//// --- -- -- - - -
-//function childs_of_parents(list) {
-// // if 'list' is integer then make it an one-item list
-// parents = (Number.isInteger(list)) ? [ list ] : list;
-//
-// var childs = [];
-//
-// if (parents.length == 0) { return []; }
-//
-// parents.forEach( pid => {
-// categories.forEach( el => { if (el.parent == pid) childs.push(el.id)});
-// });
-//
-// var grandchilds = childs_of_parents(childs);
-//
-// return childs.concat(grandchilds);
-//}
-
-
-// create actions html (edit and delete buttons)
-// --- -- -- - - -
-function create_actions_html(el) {
-
- var pub, del, edit;
-
- // preapre [show|hide]-file as reference
- if (el.status == 1) {
- pub = '<span class="btn btn-sm"><i class="fas fa-eye"></i></span>';
-
- } else {
- pub = '<span class="btn btn-sm"><i class="fas fa-eye-slash"></i></span>';
- }
-
- del = "";
-
- fast_edit = [
- '<button type="button" class="btn btn-sm btn-light"',
- 'data-bs-toggle="modal" data-bs-target="#manageLessons"',
- 'data-id="'+ el.id +'">',
- '<i class="fa-solid fa-bolt"></i>',
- '</button>'
- ].join('\n');
-
- edit = [
- '<a type="button" class="btn btn-sm btn-warning "',
- 'href="/admin/edit_lesson/'+ el.id +'">',
- '<i class="fas fa-pencil-alt"></i>',
- '</a>'
- ].join('\n');
-
- return pub +' '+ fast_edit +' '+ edit +' '+ del;
-}
-
-
-
-$(document).ready(function() {
-
- // When document is ready
- // -------------------------------------------------------------------------
-
-
- // inti category (select2)
- // ...
- $("#privilege_id").select2({
- placeholder: 'Επίπεδο Πρόσβασης',
- dropdownParent: $('#manageLessons'),
- width: '100%'
- });
-
- /** init selec2 element (used to specify parent-category)
- * --- -- -- - - -
- */
- $("#course_id").select2({
- placeholder: 'Κεφάλαιο',
- dropdownParent: $('#manageLessons'),
- width: '100%',
- });
-
-
- /** init_table
- * --- -- -- - - -
- * get categories
- * constuct categories array
- * render dataTable
- */
- function init_table() {
-
- // get all categories from server (ajax)
- $.getJSON( "/admin/api/lessons")
- .done(function( json ) {
- // then ...
-
- // reset categories
- lessons.length = 0;
-
- // construct (new) categories data
- Object.keys(json).forEach( key => {
- el = json[key];
- lessons.push({
- id: parseInt(el.id),
- title: el.title,
- course_id: el.course_id,
- course: course_(el.course_id),
- privilege_id: el.privilege_id,
- privilege: privilege_(el.privilege_id),
- actions: create_actions_html(el)
- });
- });
-
- // sort by breadcrumb
- // categories.sort( compare_breadcrumb );
-
- // destroy previous datatable table instances
- $('#dt-lessons').dataTable().fnClearTable();
- $('#dt-lessons').dataTable().fnDestroy();
-
- // (re-)create categories datatable
- table = $('#dt-lessons').DataTable({
- language: { url: '/libs/DataTables/localization/Greek.json' },
- data: lessons,
- ordering: false,
- columns: [
- { data: 'id' },
- { data: 'title' },
- { data: 'course' },
- { data: 'privilege' },
- { data: 'actions' }
- ]
- });
-
- })
- .fail(function( jqxhr, textStatus, error ) {
- console.log( "Request Failed (" + error +")" );
- });
-
- }
-
-
- $.when( // when loaded posts and categories
-
- $.getJSON( "/admin/api/categories" ),
-
- $.getJSON( "/admin/api/privileges" )
-
- ).done( function( categories_response, privileges_response ) {
-
- // construct categories data
- // ---
- Object.keys(categories_response[0]).forEach( key => {
- cat = categories_response[0][key];
- categories.push({
- id: cat.rec.id,
- label: cat.breadcrumb.replaceAll('\t', ' / ')
- });
- });
- categories.sort( compare_label ); // sort categories by breadcrumb
-
- // construct provileges data
- // ---
- Object.keys(privileges_response[0]).forEach( key => {
- priv = privileges_response[0][key];
- privileges.push({
- id: priv.id,
- label: priv.label
- });
- });
- privileges.sort( compare_label ); // sort categories by breadcrumb
-
- set_parent_options( $('#course_id'), categories );
- set_parent_options( $('#privilege_id'), privileges );
-
- init_table(); // init table on first run
- });
-
-
- /** set_parent_options()
- *
- * -> create options for parents <select>
- * -> choose selected parent
- *
- * NOTE:
- * the targer <select> should be a select2 control
- *
- * @param parents (array): array of parents
- * @param selected (int): selected parent
- */
- function set_parent_options(selector, list, selected_value = false) {
-
- list.forEach( li => { // attach options into <select> control
- selector.append(`<option value="${li.id}">${li.label}</option>`);
- });
-
- if (selected_value !== false) { // mark selected option(s)
- selector.val(selected_value).trigger('change');
- }
- else { selector.val(null).trigger('change'); }
- }
-
-
-
- /** When modal show-up
- * -------------------------------------------------------------------------
- * ... prepare the manage-category form
- * ... update select2 with possible parents
- */
- $('#manageLesson').on('show.bs.modal', event => {
- var button = $(event.relatedTarget); // Button that triggered the modal
- var id = parseInt( button.data('id') ); // category_id from data-id
- // var modal = $(this); // modal object
-
- //// update modal literature
- //// ---
- //$('#manageCategory .modal-title').html( // modal title
- // (id) ? 'Ενημέρωση Κατηγορίας' : 'Δημιουργία Κατηγορίας'
- //);
- //$('#manageCategory form input[name=id]').val( id ); // category id (hidden)
- //$('#manageCategory form input[name=label]').val( // category label
- // (id) ? category_record(id).label : ""
- //);
- //prepare_parents_element(id); // prepare <select> for parents
- })
-
-
- /** set_parent_options()
- *
- * -> create options for parents <select>
- * -> choose selected parent
- *
- * NOTE:
- * the targer <select> should be a select2 control
- *
- * @param parents (array): array of parents
- * @param selected (int): selected parent
- */
- function set_parent_options(selector, list, selected_value = false) {
-
- list.forEach( li => { // attach options into <select> control
- selector.append(`<option value="${li.id}">${li.label}</option>`);
- });
-
- if (selected_value !== false) { // mark selected option(s)
- selector.val(selected_value).trigger('change');
- }
- else { selector.val(null).trigger('change'); }
- }
-
-
-
-
-
- // When form is submited
- // -------------------------------------------------------------------------
-
- $('#manageCategory form').submit( event => {
- event.preventDefault();
-
- // prepare data to POST
- var data = {
- id: parseInt($('#manageCategory form input[name=id]').val()),
- label: $('#manageCategory form input[name=label]').val(),
- parent_id: parseInt($('#parent_id').select2('data')[0].id)
- };
-
- // select action url (add or update)
- var request = '/admin/api/categories/' + ((data.id == 0) ? 'add' : 'update');
-
- // send POST request
- $.post(request, data)
- .done(function( data ) {
-
- $('#manageCategory').modal('hide'); // when done, close modal
-
- init_table(); // reload table of categories
- });
-
- });
-
-});
diff --git a/public/assets/js/admin/pages.js b/public/assets/js/admin/pages.js
deleted file mode 100644
index 4aa02ca..0000000
--- a/public/assets/js/admin/pages.js
+++ /dev/null
@@ -1,240 +0,0 @@
-// Globals
-// -----------------------------------------------------------------------------
-var categories = [];
-var privileges = [ { id: 0, label: 'Δημόσιο' } ];
-var pages = [];
-var table;
-
-
-
-// Supplamentary functions
-// -----------------------------------------------------------------------------
-
-// array.indexOf polyfill
-// --- -- -- - - -
-if (!Array.prototype.indexOf)
-{
- Array.prototype.indexOf = function(elt /*, from*/)
- {
- var len = this.length >>> 0;
-
- var from = Number(arguments[1]) || 0;
- from = (from < 0)
- ? Math.ceil(from)
- : Math.floor(from);
- if (from < 0)
- from += len;
-
- for (; from < len; from++)
- {
- if (from in this &&
- this[from] === elt)
- return from;
- }
- return -1;
- };
-}
-
-
-// function for sorting an array by 'label' attribute
-// --- -- -- - - -
-function compare_label (a,b) {
- if ( a.label < b.label ) { return -1; }
- if ( a.label > b.label ) { return 1; }
- return 0;
-}
-
-
-// function for sorting an array by 'breadcrumb' attribute
-// --- -- -- - - -
-function compare_breadcrumb (a,b) {
- if ( a.breadcrumb < b.breadcrumb ) { return -1; }
- if ( a.breadcrumb > b.breadcrumb ) { return 1; }
- return 0;
-}
-
-// return category record by category-id
-// --- -- -- - - -
-function page_record(id) {
- var record = 0;
- pages.forEach(el => { if (el.id == id) record = el; });
-
- return record;
-}
-
-
-// create actions html (edit and delete buttons)
-// --- -- -- - - -
-function create_actions_html(el) {
-
- var pub, del, edit;
-
- // preapre [show|hide]-file as reference
- if (el.status == 1) {
- pub = '<span class="btn btn-sm"><i class="fas fa-eye"></i></span>';
-
- } else {
- pub = '<span class="btn btn-sm"><i class="fas fa-eye-slash"></i></span>';
- }
-
- del = "";
-
- fast_edit = [
- '<button type="button" class="btn btn-sm btn-light"',
- 'data-bs-toggle="modal" data-bs-target="#managePages"',
- 'data-id="'+ el.id +'">',
- '<i class="fa-solid fa-bolt"></i>',
- '</button>'
- ].join('\n');
-
- edit = [
- '<a type="button" class="btn btn-sm btn-warning "',
- 'href="/admin/edit_page/'+ el.id +'">',
- '<i class="fas fa-pencil-alt"></i>',
- '</a>'
- ].join('\n');
-
- return pub +' '+ fast_edit +' '+ edit +' '+ del;
-}
-
-
-
-$(document).ready(function() {
-
- // When document is ready
- // -------------------------------------------------------------------------
-
-
- /** init_table
- * --- -- -- - - -
- * get categories
- * constuct categories array
- * render dataTable
- */
- function init_table() {
-
- // get all categories from server (ajax)
- $.getJSON( "/admin/api/pages")
- .done(function( json ) {
- // then ...
-
- // reset categories
- pages.length = 0;
-
- // construct (new) categories data
- Object.keys(json).forEach( key => {
- el = json[key];
- pages.push({
- id: parseInt(el.id),
- title: el.title,
- actions: create_actions_html(el)
- });
- });
-
- // sort by breadcrumb
- // categories.sort( compare_breadcrumb );
-
- // destroy previous datatable table instances
- $('#dt-pages').dataTable().fnClearTable();
- $('#dt-pages').dataTable().fnDestroy();
-
- // (re-)create categories datatable
- table = $('#dt-pages').DataTable({
- language: { url: '/libs/DataTables/localization/Greek.json' },
- data: pages,
- ordering: false,
- columns: [
- { data: 'id' },
- { data: 'title' },
- { data: 'actions' }
- ]
- });
-
- })
- .fail(function( jqxhr, textStatus, error ) {
- console.log( "Request Failed (" + error +")" );
- });
-
- }
- init_table(); // init table on first run
-
-
-
- /** When modal show-up
- * -------------------------------------------------------------------------
- * ... prepare the manage-category form
- * ... update select2 with possible parents
- */
- $('#managePages').on('show.bs.modal', event => {
- var button = $(event.relatedTarget); // Button that triggered the modal
- var id = parseInt( button.data('id') ); // category_id from data-id
- // var modal = $(this); // modal object
-
- //// update modal literature
- //// ---
- //$('#manageCategory .modal-title').html( // modal title
- // (id) ? 'Ενημέρωση Κατηγορίας' : 'Δημιουργία Κατηγορίας'
- //);
- //$('#manageCategory form input[name=id]').val( id ); // category id (hidden)
- //$('#manageCategory form input[name=label]').val( // category label
- // (id) ? category_record(id).label : ""
- //);
- //prepare_parents_element(id); // prepare <select> for parents
- })
-
-
- /** set_parent_options()
- *
- * -> create options for parents <select>
- * -> choose selected parent
- *
- * NOTE:
- * the targer <select> should be a select2 control
- *
- * @param parents (array): array of parents
- * @param selected (int): selected parent
- */
- function set_parent_options(selector, list, selected_value = false) {
-
- list.forEach( li => { // attach options into <select> control
- selector.append(`<option value="${li.id}">${li.label}</option>`);
- });
-
- if (selected_value !== false) { // mark selected option(s)
- selector.val(selected_value).trigger('change');
- }
- else { selector.val(null).trigger('change'); }
- }
-
-
-
-
-
- // When form is submited
- // -------------------------------------------------------------------------
-
- $('#manageCategory form').submit( event => {
- event.preventDefault();
-
- // prepare data to POST
- var data = {
- id: parseInt($('#manageCategory form input[name=id]').val()),
- label: $('#manageCategory form input[name=label]').val(),
- parent_id: parseInt($('#parent_id').select2('data')[0].id)
- };
-
- // select action url (add or update)
- var request = '/admin/api/categories/' + ((data.id == 0) ? 'add' : 'update');
-
- // send POST request
- $.post(request, data)
- .done(function( data ) {
-
- $('#manageCategory').modal('hide'); // when done, close modal
-
- init_table(); // reload table of categories
- });
-
- });
-
-});
diff --git a/public/assets/js/admin/panel.js b/public/assets/js/admin/panel.js
deleted file mode 100644
index 24b465e..0000000
--- a/public/assets/js/admin/panel.js
+++ /dev/null
@@ -1 +0,0 @@
-console.log('Admin Panel!'); \ No newline at end of file
diff --git a/public/assets/js/admin/privileges.js b/public/assets/js/admin/privileges.js
deleted file mode 100644
index e4355c5..0000000
--- a/public/assets/js/admin/privileges.js
+++ /dev/null
@@ -1,291 +0,0 @@
-// Globals
-// -----------------------------------------------------------------------------
-var privileges = [];
-var table;
-
-
-
-// Supplamentary functions
-// -----------------------------------------------------------------------------
-
-// array.indexOf polyfill
-// --- -- -- - - -
-if (!Array.prototype.indexOf)
-{
- Array.prototype.indexOf = function(elt /*, from*/)
- {
- var len = this.length >>> 0;
-
- var from = Number(arguments[1]) || 0;
- from = (from < 0)
- ? Math.ceil(from)
- : Math.floor(from);
- if (from < 0)
- from += len;
-
- for (; from < len; from++)
- {
- if (from in this &&
- this[from] === elt)
- return from;
- }
- return -1;
- };
-}
-
-/*
-// function for sorting an array by 'breadcrumb' attribute
-// --- -- -- - - -
-function compare_breadcrumb (a,b) {
- if ( a.breadcrumb < b.breadcrumb ) { return -1; }
- if ( a.breadcrumb > b.breadcrumb ) { return 1; }
- return 0;
-}
-*/
-
-// return category record by category-id
-// --- -- -- - - -
-function privilege_record(id) {
- var record = 0;
- privileges.forEach(el => { if (el.id == id) record = el; });
-
- return record;
-}
-
-/*
-// return children of parent
-// --- -- -- - - -
-function childs_of_parents(list) {
- // if 'list' is integer then make it an one-item list
- parents = (Number.isInteger(list)) ? [ list ] : list;
-
- var childs = [];
-
- if (parents.length == 0) { return []; }
-
- parents.forEach( pid => {
- categories.forEach( el => { if (el.parent == pid) childs.push(el.id)});
- });
-
- var grandchilds = childs_of_parents(childs);
-
- return childs.concat(grandchilds);
-}
-*/
-
-// create actions html (edit and delete buttons)
-// --- -- -- - - -
-function create_actions_html(id) {
-
- var del, edit;
-
- del = "";
-
- edit = [
- '<button type="button" class="btn btn-sm btn-warning"',
- 'data-bs-toggle="modal" data-bs-target="#managePrivileges"',
- 'data-id="'+ id +'">',
- '<i class="fas fa-pencil-alt"></i>',
- '</button>'
- ].join('\n');
-
- return edit +' '+ del;
-}
-
-
-
-$(document).ready(function() {
-
- // When document is ready
- // -------------------------------------------------------------------------
-
-
- /** init selec2 element (used to specify parent-category)
- * --- -- -- - - -
- */
- $("#included_id").select2({
- placeholder: 'Περιλαμβάνει τα δικαιώματα της',
- dropdownParent: $('#managePrivileges'),
- width: '100%',
- // dropdownParent: "#manageCategory" // ref: https://github.com/select2/select2-bootstrap-theme/issues/41
- });
-
-
- /** init_table
- * --- -- -- - - -
- * get categories
- * constuct categories array
- * render dataTable
- */
- function init_table() {
-
- // get all categories from server (ajax)
- $.getJSON( "/admin/api/privileges")
- .done(function( json ) {
- // then ...
-
- // reset categories
- privileges.length = 0;
-
- // construct (new) categories data
- Object.keys(json).forEach( key => {
- el = json[key];
- privileges.push({
- id: el.id,
- label: el.label,
- includes: ((el.includes == null) ? [] : el.includes),
- included_id: ((el.included_id == null) ? 0 : el.included_id),
- actions: create_actions_html(el.id)
- });
- });
-
- // sort by breadcrumb
- // categories.sort( compare_breadcrumb );
-
- // destroy previous datatable table instances
- $('#dt-privileges').dataTable().fnClearTable();
- $('#dt-privileges').dataTable().fnDestroy();
-
- // (re-)create categories datatable
- table = $('#dt-privileges').DataTable({
- language: { url: '/libs/DataTables/localization/Greek.json' },
- data: privileges,
- ordering: false,
- columns: [
- { data: 'id' },
- { data: 'label' },
- { data: 'includes' },
- { data: 'actions' }
- ]
- });
-
- })
- .fail(function( jqxhr, textStatus, error ) {
- console.log( "Request Failed (" + error +")" );
- });
-
- }
- init_table(); // init table on first run
-
-
-
- /** When modal show-up
- * -------------------------------------------------------------------------
- * ... prepare the manage-category form
- * ... update select2 with possible parents
- */
- $('#managePrivileges').on('show.bs.modal', event => {
- var button = $(event.relatedTarget); // Button that triggered the modal
- var id = parseInt( button.data('id') ); // category_id from data-id
- // var modal = $(this); // modal object
-
- // update modal literature
- // ---
- $('#managePrivileges .modal-title').html( // modal title
- (id) ? 'Ενημέρωση Επιπέδου Πρόσβασης' : 'Δημιουργία Επιπέδου Πρόσβασης'
- );
- $('#managePrivileges form input[name=id]').val( id ); // category id (hidden)
- $('#managePrivileges form input[name=label]').val( // category label
- (id) ? privilege_record(id).label : ""
- );
- prepare_included_element(id); // prepare <select> for parents
- })
-
- /** prepare_included_element()
- * ---
- * @param id (int) : id of selected privilege
- * -> Get all posible included privileges
- * -> call set_included_options() to render the options
- */
- function prepare_included_element(id) {
- var may_included = [];
-
- if (id) { // get all possible parents
-
- // TODO:
- // specify forbiden privilege IDs for being included
-
- // filter privileges adn prepare possible included privileges
- privileges.forEach( el => {
- if (id != el.id) {
- may_included.push({
- id: el.id,
- label: el.label
- });
- }
- });
- console.log(may_included);
- set_included_options(may_included, privilege_record(id).included_id);
-
-
- } else { // new record; all categories are possible parrents
- privileges.forEach( el => {
- may_included.push({
- id: el.id,
- label: el.label,
- });
- })
- set_included_options(may_included, -1);
- }
- }
-
- /** set_included_options()
- * -> create options for parents <select>
- * -> choose selected parent
- * @param may_included (array): array of possible included privileges
- * @param selected (int): selected included privilege
- */
- function set_included_options(may_included, selected) {
- // sort parents by breadcrumb
- // parents.sort( compare_breadcrumb );
-
- // remove any olded options from select2
- $('#included_id option').each(function() { $(this).remove(); });
-
- // first option is the root category
- $('#included_id').append('<option value="0">— κανένα —</option>')
-
- // add all other parent options
- may_included.forEach( i => {
- $('#included_id').append(`<option value="${i.id}">${i.label}</option>`);
- });
-
- if (selected == -1) { // new category; remove any parent pre-selection
- $('#included_id').val(0).trigger('change');
-
- } else { // category exists; choose selected parent
- $('#included_id').val(selected).trigger('change');
- }
- }
-
-
-
-
- // When form is submited
- // -------------------------------------------------------------------------
-
- $('#manageCategory form').submit( event => {
- event.preventDefault();
-
- // prepare data to POST
- var data = {
- id: parseInt($('#manageCategory form input[name=id]').val()),
- label: $('#manageCategory form input[name=label]').val(),
- parent_id: parseInt($('#parent_id').select2('data')[0].id)
- };
-
- // select action url (add or update)
- var request = '/admin/api/category/' + ((data.id == 0) ? 'add' : 'update');
-
- // send POST request
- $.post(request, data)
- .done(function( data ) {
-
- $('#manageCategory').modal('hide'); // when done, close modal
-
- init_table(); // reload table of categories
- });
-
- });
-
-});
diff --git a/public/assets/js/classroom.js b/public/assets/js/classroom.js
deleted file mode 100644
index b1947f8..0000000
--- a/public/assets/js/classroom.js
+++ /dev/null
@@ -1,27 +0,0 @@
-$(document).ready(function() {
-
-
- /** Categories Menu Toggler
- * -------------------------------------------------------------------------
- */
- $('.toggler').click(function(e) {
- e.preventDefault();
-
- // inner div (contains children of this category)
- var inner = $(this).parent().parent().find("ul.inner").first();
-
- // toggle 'show' class on/off
- if (inner.hasClass('show')) {
- inner.removeClass('show');
- inner.slideUp(350);
- $(this).html("+");
- } else {
- inner.addClass('show');
- inner.slideDown(350);
- $(this).html("–");
- }
- });
-
-
-
-});
diff --git a/public/assets/js/edit-post.js b/public/assets/js/edit-post.js
deleted file mode 100644
index 49446ce..0000000
--- a/public/assets/js/edit-post.js
+++ /dev/null
@@ -1,612 +0,0 @@
-// Globals
-// -----------------------------------------------------------------------------
-
-// NOTE:
-// Variable `id` is defined before evaluating this script
-// id (int) : the id of edited post (or 0 if new post)
-
-var post;
-var categories = [
- // Nope! root can not be a post's category ... { id: 0 , label: 'Ρίζα (root)' }
-];
-var tags = []; // array of integers
-var files = []; // array of { id:.., title:.., type:.., path:.. } records
-
-const files_root = 'https://cdn.sklavenitis.co.gr/'; // files root firectory
-
-
-
-var pageUrl = new URL(window.location.href);
-
-// an alternative--id when a post id not exists (needed for file-upload)
-// ... consist of a 6-digit date string + random number up to 999
-const yymmdd = new Date().toISOString().slice(2, 10).replaceAll('-','');
-var rnd999 = Math.floor(Math.random() * 1000);
-var altID = (id == 0) ? ( yymmdd +'-'+ rnd999.toString() ) : id;
-
-
-
-
-// Supplamentary functions
-// -----------------------------------------------------------------------------
-
-// function for sorting an array by 'label' attribute
-// --- -- -- - - -
-function compare_label (a,b) {
- if ( a.label < b.label ) { return -1; }
- if ( a.label > b.label ) { return 1; }
- return 0;
-}
-
-// return category record by category-id
-// --- -- -- - - -
-function category_record(id) {
- var record = 0;
- categories.forEach(el => { if (el.id == id) record = el; });
-
- return record;
-}
-
-
-
-
-// Modal HTML Creators
-// -----------------------------------------------------------------------------
-
-const modal_header = (title) => {
- return [
- '<div class="modal-header">',
- '<button type="button" class="close" data-dismiss="modal" aria-label="Close">',
- '<span aria-hidden="true">&times;</span>',
- '</button>',
- '<h4 class="modal-title" id="myModalLabel">',
- title,
- '</h4>',
- '</div>'
- ].join('\n');
-}
-
-
-const upload_file_form = () => {
- return [
- '<form method="POST" id="file_upload_form" name="upload_file_form">',
-
- '<div class="modal-body">',
-
- '<input type="hidden" name="folder" value="'+ altID +'">',
-
- '<div class="form-group">',
- '<label for="title">Τίτλος/Περιγραφή για το Αρχείο</label>',
- '<input type="text" class="form-control " value="" name="title" id="title" placeholder="Τίτλος για το Αρχείο" required="">',
- '</div>',
-
- '<div class="row">',
-
- '<div class="form-group col-md-7">',
- '<label class="control-label" for="file">Εισαγωγή Αρχείου</label>',
- '<input class="form-control" type="file" id="file" name="file" required="">',
- '</div>',
-
- '<div class="form-group col-md-5">',
- '<label class="control-label" for="category_id">Είδος</label>',
- '<select class="form-control" id="reference" name="reference" required="">',
- '<option"></option>',
- '<option value="1">Παραπομπή (εμφανίζεται)</option>',
- '<option value="0">Βοηθητικό αρχείο (κρυφό)</option>',
- '</select>',
- '</div>',
-
- '</div>',
-
- '</div>',
-
- '<div class="modal-footer">',
- '<div class="row">',
- '<div class="form-actions">',
- '<div class="col-lg-3 col-lg-offset-6 col-md-4 col-md-offset-4 col-xs-6">',
- '<buton type="button" class="btn btn-default js-modal-close col-xs-12" data-dismiss="modal">',
- 'Κλείσιμο',
- '</button>',
- '</div>',
- '<div class="col-lg-3 col-md-4 col-xs-6">',
- '<button class="btn btn-success col-xs-12" type="submit">Καταχώριση</button>',
- '</div>',
- '</div>',
- '</div>',
- '</div>',
-
- '</form>'
- ].join('\n');
-}
-
-
-const preview_article = (title, intro, body) => {
- return [
- '<div class="modal-body">',
- '<div class="post">',
-
- '<h2>'+ title +'</h2>',
-
- ((intro == '') ? '' : ('<div class="intro">'+ intro +'</div>')),
-
- '<div class="article-body">',
- marked.parse(body, { sanitize: true }),
- '</div>',
-
- '</div>',
- '</div>',
- '<div class="modal-footer">',
- '<div class="row">',
- '<div class="form-actions">',
- '<div class="col-md-4 col-md-offset-4 col-xs-6 col-xs-offset-3">',
- '<buton type="button" class="btn btn-default js-modal-close col-xs-12" data-dismiss="modal">',
- 'Κλείσιμο',
- '</button>',
- '</div>',
- '</div>',
- '</div>',
- '</div>'
- ].join('\n');
-}
-
-
-$(document).ready(function() {
-
- // When document is ready
- // -------------------------------------------------------------------------
-
-
- // inti category (select2)
- // ...
- $("#category_id").select2({
- placeholder: 'Γονική Κατηγορία',
- width: '100%'
- });
-
-
- // init tags (select2)
- // ...
- $('#tags').select2({
- placeholder: 'Ετικέτες (tags/keywords)',
- width: '100%',
- tags: true
- });
-
-
- // init editor (tiny MCE)
- // tinymce.init({
- // selector: 'form textarea[name=body]',
- // language: 'el',
- // menubar: true
- // });
- // --- -- -- - - -
-
-
- /** preload content
- * --- -- -- - - -
- * get post
- * get categories
- * get tags
- * update content (form-elements)
- */
- if (id) { // if an `id` is given, load post .. then init_form
-
- $.getJSON( "/wiki/ajax", { action: "get_post", id: id } )
- .done( function (data) {
- post = data; // keep post
-
- // update fields' values
- $('input[name=id]').val(post.id); // id
- $('input[name=title]').val(post.title); // title
- $('textarea[name=intro]').val(post.intro); // intro
- $('textarea[name=body]').val(post.body); // body
- $('input[name=status]').prop( // status
- 'checked',
- ((post.status==1)? true : false))
- .trigger('change');
-
- $('#post-info').html('Δημιουργία: '+post.creation_date+'<br>Τελευταία Ενημέρωση: '+ post.update_date);
-
- $('#delete').prop( "disabled", false ); // enable delete button
-
- // if intro exist, show intro (optinal) field
- if ((post.intro != null) && (post.intro != '')) {
- $('.optional label[for=intro]').addClass('show'); // unhide section
- }
-
- // parse media files; then draw
- if (post.medias_json != null) {
- files = JSON.parse(post.medias_json);
- $('.optional label[for=media]').addClass('show'); // unhide section
- }
- draw_files_list(); // then draw the files list
-
- init_form_values(); // init all (other) values
- });
-
- } else { // else ... just init_form
- $('#delete').prop( "disabled", true ); // disable delete button for new post attempt
- // depricated $('select[name=status').val('0').trigger('change'); // pre-selecd unpublished
- init_form_values();
- }
-
-
-
- /**
- * load categories and tags;
- * if not a new post (id!=0) update form elemnts with post's values
- */
- function init_form_values() {
-
- $.when( // when loaded posts and categories
-
- $.getJSON( "/wiki/ajax", { action: "get_categories_array", exclude: '0' } ),
-
- $.getJSON( "/wiki/ajax", { action: "get_all_tags" } )
-
- ).done( function( categories_response, tags_response ) {
-
- // construct categories data
- // ---
- Object.keys(categories_response[0]).forEach( key => {
- cat = categories_response[0][key];
- categories.push({
- id: cat.rec.id,
- label: cat.breadcrumb.replaceAll('\t', ' / ')
- });
- });
- categories.sort( compare_label ); // sort categories by breadcrumb
-
- // construct tags data
- // ---
- Object.keys(tags_response[0]).forEach( key => {
- tag = tags_response[0][key];
- tags.push({
- id: tag.id,
- label: tag.name
- });
- });
-
- // pass categories and tags options onto select2 elements
- // --- -- -- - - -
- if (id == 0) {
- set_parent_options( $('#category_id'), categories );
- set_parent_options( $('#tags'), tags );
-
- } else {
- // setup category_id options; select post's chosen category-id
- set_parent_options( $('#category_id'), categories, post.category_id );
-
- // parse selected tags
- // ---
- var selected_tag_ids = [];
- if (post.tags_json != null) {
- var selected_tags = JSON.parse(post.tags_json);
- selected_tags.forEach( itag => { selected_tag_ids.push(itag.id); })
- }
- // setup tags options; select post's chosen tags
- set_parent_options( $('#tags'), tags, selected_tag_ids );
-
- // ALSO: if tags selectd, show tags field
- if (selected_tag_ids.length != 0) { $('.optional label[for=tags]').addClass('show'); }
- }
-
- });
-
- }
-
-
- /** set_parent_options()
- *
- * -> create options for parents <select>
- * -> choose selected parent
- *
- * NOTE:
- * the targer <select> should be a select2 control
- *
- * @param parents (array): array of parents
- * @param selected (int): selected parent
- */
- function set_parent_options(selector, list, selected_value = false) {
-
- list.forEach( li => { // attach options into <select> control
- selector.append(`<option value="${li.id}">${li.label}</option>`);
- });
-
- if (selected_value !== false) { // mark selected option(s)
- selector.val(selected_value).trigger('change');
- }
- else { selector.val(null).trigger('change'); }
- }
-
-
- /** draw_files_list
- * --- -- -- - - -
- */
- function draw_files_list() {
- var li_list = [];
- var ref_icon, ref_class;
-
- files.forEach( item => {
- // preapre [show|hide]-file as reference
- if (item.reference == 1) {
- ref_icon = '<i class="fas fa-eye"></i>';
- ref_class = 'btn-default';
-
- } else {
- ref_icon = '<i class="fas fa-eye-slash"></i>';
- ref_class = 'btn-disabled';
- }
-
- var copy = [ // copy button
- '<button type="button" class="btn btn-xs btn-default js-copy"',
- 'data-url="' + item.path + '">',
- '<i class="far fa-clone"></i>',
- '</button>'
- ].join('');
- var ref = [ // show|hide (is_reference)
- '<button type="button" class="btn btn-xs '+ ref_class +' js-reference"',
- 'data-id="' + item.id + '">',
- ref_icon,
- '</button>'
- ].join('');
- var del = [ // delete button
- '<button type="button" class="btn btn-xs btn-danger js-delete"',
- 'data-id="' + item.id + '">',
- '<i class="fas fa-trash-alt"></i>',
- '</button>'
- ].join('');
- var option = [ // li html
- '<li>',
- '<div class="text">' + item.title + '</div>',
- '<div class="actions">',
- ref, ' ', copy, ' ', del,
- '</div>',
- '</li>'
- ].join('');
- li_list.push(option); // push to li_list
- });
- $('#files_list').html( li_list.join('\n') );
-
- }
-
-
-
- // When form's action-buttons are clicked
- // -------------------------------------------------------------------------
-
-
- // form submit
- // --- -- -- - - -
- $('.edit-post form').submit( event => {
- event.preventDefault();
-
- // rearrange tags to old and new ones
- // ---
- var old_tags = [];
- var new_tags = [];
- var tags = $('#tags').select2('data');
- tags.forEach( t => {
- if (!parseInt(t.id)) {
- new_tags.push(t.text);
- } else { old_tags.push(t.id); }
- })
-
- var attachments = [];
- // attachments (array) of "`media_id`;`reference`" strings
- files.forEach( f => { attachments.push( f.id +';'+ f.reference ) });
-
- // prepare data to POST
- // ---
- var data = {
- id: parseInt($('.edit-post form input[name=id]').val()),
- title: $('.edit-post form input[name=title]').val(),
- category_id: parseInt($('#category_id').select2('data')[0].id),
- intro: $('.edit-post form textarea[name=intro]').val(),
- body: $('.edit-post form textarea[name=body]').val(),
- status: (($('input[name=status]').is(":checked")) ? 1 : 0),
- tags: old_tags,
- new_tags: new_tags,
- media: attachments
- };
-
- // select action url (add or update)
- // ---
- var request = '/wiki/ajax?action=' + ((data.id == 0) ? 'add_post' : 'update_post');
-
- // send POST (ajax) request
- $.post(request, data)
- .done(function( data ) {
- window.location.href = '/wiki/admin?action=posts'; // seems ok; bach to articles
- });
-
- });
-
-
- // go-back (to posts)
- // --- -- -- - - -
- $('#go-back').click( event => {
- window.location.href = '/wiki/admin?action=posts';
- });
-
-
- // delete
- // --- -- -- - - -
- $('#delete').click( event => {
- // ask before deletion
- swal({
- title: 'Είστε βέβαιος;',
- html: "Ζητήσατε να διαγραφεί το άρθρο.<br>Παρακαλώ επιβεβαιώστε την διαγραφή.<br>ΠΡΟΣΟΧΗ: Δεν θα έχετε την δυνατότητα αναίρεσης!",
- type: 'warning',
- showCancelButton: true,
- confirmButtonColor: '#3085d6',
- cancelButtonColor: '#d33',
- cancelButtonText: 'Ακύρωση',
- confirmButtonText: 'Ναι, να διαγραφεί',
- showLoaderOnConfirm: true,
- preConfirm: function() {
- return new Promise(function(resolve) {
- $.getJSON( "/wiki/ajax", { action: "delete_post", id: id } )
- .done( function (data) {
- // return to posts-administration
- window.location.href = '/wiki/admin?action=posts';
- });
- });
- },
- allowOutsideClick: false
- }).catch(swal.noop);
-
- });
-
-
-
- // copy url button
- // --- -- -- - - -
- $('.wiki').on('click', 'button.js-copy', function (e) {
- var copytext = ''; // default: copy nothing
-
- if ($(this).data('id') !== undefined) {
- copytext = pageUrl.origin +'/wiki/post?id=' + $(this).data('id');
- }
-
- if ($(this).data('url') !== undefined) {
- copytext = files_root + $(this).data('url');
- }
-
- navigator.clipboard
- .writeText(copytext)
- .then(() => { // notify the copy event
- $(this).addClass('copied');
- setTimeout( () => { $(this).removeClass('copied'); }, 700);
- })
- .catch(() => {
- console.log("error on coping text");
- });
- });
-
-
-
- // delete (remove) file button
- // --- -- -- - - -
- $('.wiki').on('click', 'button.js-delete', function (e) {
- var media_id = $(this).data('id');
-
- // remove from files array the one with id == media_id
- // ---
- var temp = [];
- files.forEach( it => { if (it.id != media_id) temp.push(it); });
-
- files = temp; // re-define files
- draw_files_list(); // then re-draw files list
- });
-
-
-
-
-
- // show|hide file as referece button
- // --- -- -- - - -
- $('.wiki').on('click', 'button.js-reference', function (e) {
- var id = $(this).data('id');
-
- // toggle reference attribute of item with `id` = id
- // ---
- var temp = [];
- files.forEach( it => {
- if (it.id == id) {
- it.reference = (it.reference==0) ? 1 : 0;
- }
- temp.push(it)
- });
-
- files = temp; // re-define files
- draw_files_list(); // then re-draw files list
- });
-
-
-
-
-
- /** When modal show-up
- * -------------------------------------------------------------------------
- * ... prepare the manage-category form
- * ... update select2 with possible parents
- */
- $('#editorModal').on('show.bs.modal', event => {
- let button = $(event.relatedTarget); // Button that triggered the modal
- let action = button.data('action'); // action
- // var modal = $(this); // modal object
-
- // update modal literature
-
- switch (action) {
- case 'upload_file':
- $("#editorModal .modal-content").html(
- modal_header('Εισαγωγή Αρχείου') + upload_file_form()
- );
- break;
-
- case 'preview':
- let preview = preview_article(
- $('.edit-post form input[name=title]').val(),
- $('.edit-post form textarea[name=intro]').val(),
- $('.edit-post form textarea[name=body]').val()
- );
- $("#editorModal .modal-content").html( modal_header('Προεπισκόπηση') + preview);
- break;
-
- default:
- // do nothing
- }
-
- });
-
-
-
- /** submit upload file event
- * -------------------------------------------------------------------------
- */
- $('#editorModal').on('submit', 'form[name=upload_file_form]', function (event) {
- event.preventDefault();
-
- // create the FormData object
- // --- -- -- - - -
- var fd = new FormData(document.getElementById('file_upload_form'));
-
- // post the form (via ajax)
- $.ajax({
- url: '/wiki/ajax?action=file_upload',
- type: 'POST',
- data: fd,
- contentType: false,
- processData: false,
- dataType: 'json',
- success: function(response) { // on success
-
- if (response.success) {
- files.push({ // ... update files array
- id: response.id,
- title: response.title,
- path: response.path,
- type: response.type,
- reference: $('#reference').val()
- });
- draw_files_list();
-
- $('#editorModal').modal('hide');
-
- } else {
- console('File not uploaded');
- }
- }
- });
- });
-
-
- // TODO:
- // disable links while previewing the article
- // OR add a target="_blank"
-
-
-});
-
diff --git a/public/assets/js/lesson-features.js b/public/assets/js/lesson-features.js
deleted file mode 100644
index 189b301..0000000
--- a/public/assets/js/lesson-features.js
+++ /dev/null
@@ -1,218 +0,0 @@
-const valid_codeblocks = [ // supported sort-code keys
- 'youtube',
- 'spotify',
- 'spotify-track',
- 'world-data',
- 'vimeo',
- 'dailymotion'
-];
-
-
-const symbol_escapes = [
- { esc: '&gt;', chr: '>' },
- { esc: '&lt;', chr: '<' },
- { esc: '&amp;', chr: '&' },
- { esc: '&quot;', chr: '\"' },
- { esc: '&apos;', chr: '\'' },
- { esc: '&euro;', chr: '€' },
- { esc: '&copy;', chr: '©' },
- { esc: '&reg;', chr: '®' }
-];
-
-
-var youtube_template = ( id => {
- return '<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/'+ id +'?rel=0&controls=0" title="YouTube video player" frameborder="0" allow="clipboard-write; encrypted-media; picture-in-picture; web-share" allowfullscreen></iframe>';
-});
-
-
-var spotify_template = ( id => {
- return '<iframe style="border-radius:12px" src="https://open.spotify.com/embed/episode/'+ id +'?utm_source=generator" width="100%" height="152" frameBorder="0" allowfullscreen="" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" loading="lazy"></iframe>';
-});
-
-var spotify_track = ( id => {
- return '<iframe style="border-radius:12px" src="https://open.spotify.com/embed/track/'+ id +'?utm_source=generator" width="100%" height="152" frameBorder="0" allowfullscreen="" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" loading="lazy"></iframe>';
-});
-
-var owid_template = ( id => { // our world in data (explorer)
- return '<iframe src="https://ourworldindata.org/explorers/'+ id +'?zoomToSelection=true&hideControls=true" loading="lazy" style="width: 100%; height: 480px; border: 0px none;"></iframe>'
-});
-
-var vimeo_template = ( id => {
- return '<div style="padding:56.25% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/'+ id +'?h=2e7bdb3901&title=0&byline=0&portrait=0" style="position:absolute;top:0;left:0;width:100%;height:100%;" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen></iframe></div><script src="https://player.vimeo.com/api/player.js"></script>'
-});
-
-var dailymotion_template = ( id => {
- return '<div style="position:relative;padding-bottom:56.25%;height:0;overflow:hidden;"> <iframe style="width:100%;height:100%;position:absolute;left:0px;top:0px;overflow:hidden" frameborder="0" type="text/html" src="https://www.dailymotion.com/embed/video/'+ id +'" width="100%" height="100%" allowfullscreen title="Dailymotion Video Player" > </iframe> </div>'
-});
-
-
-
-/** inject_codeblocks
- * --- -- -- - - -
- *
- * NOTE:
- * a short-code is a mustache block of 3 parametres:
- * {{ object = someID ; some label description }}
- * ex. `{{product=1507175; Coca Cola Zero}}`
- *
- * The short-code is parsed to a code-block:
- * an `a` modal-toggler link with certain data-attributes (+label), ex:
- * `<a class='modal-toggler view-product' data-id='1507175'>Coca Cola Zero</a>`
- *
- * @param code (string): original content html with short-codes
- * @returns (string): html content with code-blocks
- */
-function inject_codeblocks(code) {
- // isolate all mustache blocks
- const regexp = /{{(.*?)}}/g; // regex makes multiple-matching easier
- const matches = [...code.matchAll(regexp)];
- // console.log(matches);
-
- var output = code; // use a copy of (source) code
-
- console.log(matches);
-
- matches.forEach( match => {
- // parse (every) match
- // NOTE:
- // match array has 3 items; example:
- // match[0] : `{{youtube=6EA-MIYY1bg}}`
- // match[1] : `youtube=6EA-MIYY1bg`
- // match[3] : the (source) code string
-
- // let blockparts = unescaped_str( match[1] ).trim().split('=');
- let blockparts = match[1].trim().split('=');
- let target = blockparts[0].toLowerCase();
- let id = blockparts[1];
- // let label = escaped_str(blockparts[1]);
- if (valid_codeblocks.includes(target)) {
-
- var codeblock = '';
-
- console.log(target, id);
-
- switch (target) {
-
- case 'youtube':
- codeblock = youtube_template(id);
- break;
-
- case 'spotify':
- codeblock = spotify_template(id);
- break;
-
- case 'spotify-track':
- codeblock = spotify_track(id);
- break;
-
- case 'world-data':
- codeblock = owid_template(id);
- break;
-
- case 'vimeo':
- codeblock = vimeo_template(id);
- break;
-
- case 'dailymotion':
- codeblock = dailymotion_template(id);
- break;
-
- default:
- codeblock = id;
-
- }
-
- output = output.replaceAll(match[0], codeblock);
-
- }
- });
-
- return output;
-}
-
-
-// pair of function to escepe/unescape special html symbols
-// --- -- -- - - -
-function unescaped_str(txt) {
- symbol_escapes.forEach( pair => { txt = txt.replaceAll(pair.esc, pair.chr); })
- return txt;
-}
-
-function escaped_str(txt) {
- symbol_escapes.forEach( pair => { txt = txt.replaceAll(pair.chr, pair.esc); })
- return txt;
-}
-
-
-$(document).ready(function() {
-
-
- /** translate short-codes to code-blocks
- * -------------------------------------------------------------------------
- */
- var content = $('.main-content .article-body').html(); // get code with shorts
- $('.main-content .article-body').html( inject_codeblocks(content) ); // put code with blocks
-
-
-
- /** modal listeners
- * -------------------------------------------------------------------------
- */
-/* DEPRICATED: not needed
- // open store modal listener
- // --- -- -- - - -
- $(document).on('click', '.js-get_store', function (e) {
- e.preventDefault();
- var id = $(this).data('id'); // id for requesting content via ajax
-
- $('#dynamic-content').html('');
- $('#modal-loader').show();
-
- $.ajax({
- url: '/libs/modals/modalStore.php',
- type: 'POST',
- cache: false,
- data: 'id=' + id,
- dataType: 'html'
- })
- .done(function (data) {
- $('#dynamic-content').html('');
- $('#dynamic-content').html(data);
- $('#modal-loader').hide();
- })
- .fail(function () {
- $('#dynamic-content').html('<i class="glyphicon glyphicon-info-sign"></i> Υπήρξε κάποιο πρόβλημα, παρακαλώ προσπαθήστε ξανά.');
- $('#modal-loader').hide();
- });
- });
-
- // open product modal listener
- // ---
- $(document).on('click', '.js-get_product', function (e) {
- e.preventDefault();
- var id = $(this).data('id'); // id for requesting content via ajax
-
- $('#dynamic-product').html('');
- $('#modal-loader').show();
-
- $.ajax({
- url: '/products/ajax/get_product_full',
- cache: false,
- type: 'POST',
- data: { id: id },
- dataType: 'html'
- })
- .done(function (data) {
- $('#dynamic-product').html('');
- $('#dynamic-product').html(data);
- $('#modal-loader').hide();
-
- })
- .fail(function () {
- $('#dynamic-product').html('<i class="glyphicon glyphicon-info-sign"></i> Υπήρξε κάποιο πρόβλημα, παρακαλώ προσπαθήστε ξανά.');
- $('#modal-loader').hide();
-
- });
- });
-*/
-});
diff --git a/public/assets/js/manage-category.js b/public/assets/js/manage-category.js
deleted file mode 100644
index 85a4851..0000000
--- a/public/assets/js/manage-category.js
+++ /dev/null
@@ -1,287 +0,0 @@
-// Globals
-// -----------------------------------------------------------------------------
-var categories = [];
-var table;
-
-
-
-// Supplamentary functions
-// -----------------------------------------------------------------------------
-
-// array.indexOf polyfill
-// --- -- -- - - -
-if (!Array.prototype.indexOf)
-{
- Array.prototype.indexOf = function(elt /*, from*/)
- {
- var len = this.length >>> 0;
-
- var from = Number(arguments[1]) || 0;
- from = (from < 0)
- ? Math.ceil(from)
- : Math.floor(from);
- if (from < 0)
- from += len;
-
- for (; from < len; from++)
- {
- if (from in this &&
- this[from] === elt)
- return from;
- }
- return -1;
- };
-}
-
-
-// function for sorting an array by 'breadcrumb' attribute
-// --- -- -- - - -
-function compare_breadcrumb (a,b) {
- if ( a.breadcrumb < b.breadcrumb ) { return -1; }
- if ( a.breadcrumb > b.breadcrumb ) { return 1; }
- return 0;
-}
-
-// return category record by category-id
-// --- -- -- - - -
-function category_record(id) {
- var record = 0;
- categories.forEach(el => { if (el.id == id) record = el; });
-
- return record;
-}
-
-
-// return children of parent
-// --- -- -- - - -
-function childs_of_parents(list) {
- // if 'list' is integer then make it an one-item list
- parents = (Number.isInteger(list)) ? [ list ] : list;
-
- var childs = [];
-
- if (parents.length == 0) { return []; }
-
- parents.forEach( pid => {
- categories.forEach( el => { if (el.parent == pid) childs.push(el.id)});
- });
-
- var grandchilds = childs_of_parents(childs);
-
- return childs.concat(grandchilds);
-}
-
-
-// create actions html (edit and delete buttons)
-// --- -- -- - - -
-function create_actions_html(id) {
-
- var del, edit;
-
- del = "";
-
- edit = [
- '<button type="button" class="btn btn-xs btn-warning"',
- 'data-toggle="modal" data-target="#manageCategory"',
- 'data-id="'+ id +'">',
- '<i class="fas fa-pencil-alt"></i>',
- '</button>'
- ].join('\n');
-
- return edit +' '+ del;
-}
-
-
-
-$(document).ready(function() {
-
- // When document is ready
- // -------------------------------------------------------------------------
-
-
- /** init selec2 element (used to specify parent-category)
- * --- -- -- - - -
- */
- $("#parent_id").select2({
- placeholder: 'Γονική Κατηγορία',
- width: '100%',
- // dropdownParent: "#manageCategory" // ref: https://github.com/select2/select2-bootstrap-theme/issues/41
- });
-
-
- /** init_table
- * --- -- -- - - -
- * get categories
- * constuct categories array
- * render dataTable
- */
- function init_table() {
-
- // get all categories from server (ajax)
- $.getJSON( "/wiki/ajax", { action: "get_categories_array", exclude: '0' } )
- .done(function( json ) {
- // then ...
-
- // reset categories
- categories.length = 0;
-
- // construct (new) categories data
- Object.keys(json).forEach( key => {
- el = json[key];
- categories.push({
- id: parseInt(el.rec.id),
- title: el.rec.title,
- breadcrumb: el.breadcrumb.replaceAll('\t', ' / '),
- parent: parseInt(el.rec.parent),
- actions: create_actions_html(el.rec.id)
- });
- });
-
- // sort by breadcrumb
- categories.sort( compare_breadcrumb );
-
- // destroy previous datatable table instances
- $('#dt-categories').dataTable().fnClearTable();
- $('#dt-categories').dataTable().fnDestroy();
-
- // (re-)create categories datatable
- table = $('#dt-categories').DataTable({
- language: { url: '/libs/DataTables/localization/Greek.json' },
- data: categories,
- ordering: false,
- columns: [
- { data: 'breadcrumb' },
- { data: 'actions' }
- ]
- });
-
- })
- .fail(function( jqxhr, textStatus, error ) {
- console.log( "Request Failed (" + error +")" );
- });
-
- }
- init_table(); // init table on first run
-
-
-
- /** When modal show-up
- * -------------------------------------------------------------------------
- * ... prepare the manage-category form
- * ... update select2 with possible parents
- */
- $('#manageCategory').on('show.bs.modal', event => {
- var button = $(event.relatedTarget); // Button that triggered the modal
- var id = parseInt( button.data('id') ); // category_id from data-id
- // var modal = $(this); // modal object
-
- // update modal literature
- // ---
- $('#manageCategory .modal-title').html( // modal title
- (id) ? 'Ενημέρωση Κατηγορίας' : 'Δημιουργία Κατηγορίας'
- );
- $('#manageCategory form input[name=id]').val( id ); // category id (hidden)
- $('#manageCategory form input[name=title]').val( // category title
- (id) ? category_record(id).title : ""
- );
- prepare_parents_element(id); // prepare <select> for parents
- })
-
- /** prepare_parents_element()
- * ---
- * @param id (int) : id of selected category
- * -> Get all posible parents
- * -> call set_parent_options() to render the options
- */
- function prepare_parents_element(id) {
- var parents = [];
-
- if (id) { // get all possible parents
-
- // id-category and subcategories are fobiden parents
- var forbiden = childs_of_parents(id);
- forbiden.push(id);
-
- // filter catogories adn prepare parents
- categories.forEach( el => {
- if (!forbiden.includes(el.id)) {
- parents.push({
- id: el.id,
- breadcrumb: el.breadcrumb,
- });
- }
- });
- set_parent_options(parents, category_record(id).parent);
-
-
- } else { // new record; all categories are possible parrents
- categories.forEach( el => {
- parents.push({
- id: el.id,
- breadcrumb: el.breadcrumb,
- });
- })
- set_parent_options(parents, -1);
- }
- }
-
- /** set_parent_options()
- * -> create options for parents <select>
- * -> choose selected parent
- * @param parents (array): array of parents
- * @param selected (int): selected parent
- */
- function set_parent_options(parents, selected) {
- // sort parents by breadcrumb
- parents.sort( compare_breadcrumb );
-
- // remove any olded options from select2
- $('#parent_id option').each(function() { $(this).remove(); });
-
- // first option is the root category
- $('#parent_id').append('<option value="0">Root</option>')
-
- // add all other parent options
- parents.forEach( i => {
- $('#parent_id').append(`<option value="${i.id}">${i.breadcrumb}</option>`);
- });
-
- if (selected == -1) { // new category; remove any parent pre-selection
- $('#parent_id').val(null).trigger('change');
-
- } else { // category exists; choose selected parent
- $('#parent_id').val(selected).trigger('change');
- }
- }
-
-
-
-
- // When form is submited
- // -------------------------------------------------------------------------
-
- $('#manageCategory form').submit( event => {
- event.preventDefault();
-
- // prepare data to POST
- var data = {
- id: parseInt($('#manageCategory form input[name=id]').val()),
- title: $('#manageCategory form input[name=title]').val(),
- parent_id: parseInt($('#parent_id').select2('data')[0].id)
- };
-
- // select action url (add or update)
- var request = '/wiki/ajax?action=' + ((data.id == 0) ? 'add_category' : 'update_category');
-
- // send POST request
- $.post(request, data)
- .done(function( data ) {
-
- $('#manageCategory').modal('hide'); // when done, close modal
-
- init_table(); // reload table of categories
- });
-
- });
-
-});
diff --git a/public/assets/js/manage-posts.js b/public/assets/js/manage-posts.js
deleted file mode 100644
index 028c773..0000000
--- a/public/assets/js/manage-posts.js
+++ /dev/null
@@ -1,177 +0,0 @@
-// Globals
-// -----------------------------------------------------------------------------
-var categories = [];
-var posts = [];
-var table;
-
-var pageUrl = new URL(window.location.href);
-
-
-// Supplamentary functions
-// -----------------------------------------------------------------------------
-
-// function for sorting an array by 'breadcrumb' attribute
-// --- -- -- - - -
-function compare_breadcrumb (a,b) {
- if ( a.breadcrumb < b.breadcrumb ) { return -1; }
- if ( a.breadcrumb > b.breadcrumb ) { return 1; }
- return 0;
-}
-
-// return category record by category-id
-// --- -- -- - - -
-function category_record(id) {
- var record = 0;
- categories.forEach(el => { if (el.id == id) record = el; });
-
- return record;
-}
-
-// create actions html (edit and delete buttons)
-// --- -- -- - - -
-function create_actions_html(id) {
-
- var copy, edit;
-
- edit = [
- '<button type="button" class="btn btn-xs btn-warning js-edit"',
- 'data-id="'+ id +'">',
- '<i class="fas fa-pencil-alt"></i>',
- '</button>'
- ].join('\n');
-
- copy = [
- '<button type="button" class="btn btn-xs btn-dafault js-copy"',
- 'data-id="'+ id +'">',
- '<i class="far fa-clone"></i>',
- '</button>'
- ].join('\n');
-
- return copy +' '+ edit;
-}
-
-
-
-$(document).ready(function() {
-
- // When document is ready
- // -------------------------------------------------------------------------
-
- /** init_table for 1st time
- * --- -- -- - - -
- * get posts + categories
- * constuct posts + categories array
- * render dataTable
- */
- // function init_table() {
-
- $.when( // when loaded posts and categories
-
- $.getJSON( "/wiki/ajax", { action: "all_posts_props" } ),
-
- $.getJSON( "/wiki/ajax", { action: "get_categories_array", exclude: '0' } )
-
- ).done( function( posts_response, categories_response ) {
-
- // each response is an array of 3 items:
- // [0] => data (array)
- // [1] => [success|fail]
- // [2] => xhr object
-
- // construct categories data
- Object.keys(categories_response[0]).forEach( key => {
- cat = categories_response[0][key];
- categories.push({
- id: cat.rec.id,
- breadcrumb: cat.breadcrumb.replaceAll('\t', ' / ')
- });
- });
-
- // construct posts data
- Object.keys(posts_response[0]).forEach( key => {
- po = posts_response[0][key];
- posts.push({
- id: po.id,
- title: po.title,
- category: category_record(po.category_id).breadcrumb,
- updated: po.update_date,
- status: ((po.status == 1) ? '<i class="fas fa-eye"></i>' : '<i class="fas fa-eye-slash"></i>'),
- actions: create_actions_html(po.id)
- });
- });
-
- // (re-)create categories datatable
- table = $('#dt-posts').DataTable({
- language: { url: '/libs/DataTables/localization/Greek.json' },
- data: posts,
- order: [[2, 'desc']],
- columns: [
- { data: 'title' },
- { data: 'category' },
- { // update date
- data: 'updated',
- render: {
- _: function (data, row, full) { return data; },
- display: function (data, row, full) { return mini_date(data); }
- }
- },
- { data: 'status' },
- { data: 'actions', width: '64px' }
- ],
- columnDefs: [{
- 'targets': [3,4],
- 'orderable': false
- }]
- });
-
- });
-
-
- function mini_date(d){
- let yy = d.substring(2,4); // year 2digit
- let mo = d.substring(5,7); // month
- let dd = d.substring(8,10); // dat
- let h = d.substring(11,13); // hour
- let m = d.substring(14,16); // minute
- return dd +'/'+ mo +'/'+ yy +' '+ h +':'+ m;
- }
-
-
-
- /** When user ckicks button
- * -------------------------------------------------------------------------
- */
-
-
- /** on(click, .edit-btn)
- * --- -- -- - - -
- * We need to attach the event handler to some element
- * higher up in the DOM tree that will remain present;
- * so the handled attached on #dt-posts
- *
- * get post-id ; load editpost
- */
- $('#dt-posts').on('click', 'button.js-edit', function (e) {
-
- var id = $(this).data('id');
- window.location.href = '/wiki/admin?action=editpost&id=' + id
-
- });
-
-
- $('#dt-posts').on('click', 'button.js-copy', function (e) {
- var postUrl = pageUrl.origin +'/wiki/post?id=' + $(this).data('id');
-
- navigator.clipboard
- .writeText(postUrl)
- .then(() => {
- $(this).addClass('copied');
- setTimeout( () => { $(this).removeClass('copied'); }, 700);
- })
- .catch(() => {
- console.log("error on coping text");
- });
- });
-
-
-});
diff --git a/public/assets/js/manage-tags.js b/public/assets/js/manage-tags.js
deleted file mode 100644
index c287849..0000000
--- a/public/assets/js/manage-tags.js
+++ /dev/null
@@ -1,163 +0,0 @@
-// Globals
-// -----------------------------------------------------------------------------
-var tags = [];
-var table;
-
-
-
-// Supplamentary functions
-// -----------------------------------------------------------------------------
-
-
-
-// return category record by category-id
-// --- -- -- - - -
-function category_record(id) {
- var record = 0;
- categories.forEach(el => { if (el.id == id) record = el; });
-
- return record;
-}
-
-// create actions html (edit and delete buttons)
-// --- -- -- - - -
-function create_actions_html(id) {
-
- var del, edit;
-
- del = [
- '<button type="button" class="btn btn-xs btn-danger"',
- 'data-toggle="modal" data-target="#manageCategory"',
- 'data-id="'+ id +'" disabled>',
- '<i class="fas fa-times"></i>',
- '</button>'
- ].join('\n');
-
- edit = [
- '<button type="button" class="btn btn-xs btn-warning"',
- 'data-toggle="modal" data-target="#manageCategory"',
- 'data-id="'+ id +'" disabled>',
- '<i class="fas fa-pencil-alt"></i>',
- '</button>'
- ].join('\n');
-
- return edit +' '+ del;
-}
-
-
-
-$(document).ready(function() {
-
- // When document is ready
- // -------------------------------------------------------------------------
-
-
-
- /** init_table
- * --- -- -- - - -
- * get categories
- * constuct categories array
- * render dataTable
- */
- function init_table() {
-
- // get all categories from server (ajax)
- $.getJSON( "/wiki/ajax", { action: "tags_stats" } )
- .done(function( json ) {
- // then ...
-
- // reset tags
- tags.length = 0;
-
- // construct tags data
- Object.keys(json).forEach( key => {
- el = json[key];
- tags.push({
- id: parseInt(el.id),
- title: el.name,
- counter: parseInt(el.totals),
- actions: create_actions_html(el.id)
- });
- });
-
- // destroy previous datatable table instances
- $('#dt-tags').dataTable().fnClearTable();
- $('#dt-tags').dataTable().fnDestroy();
-
- // (re-)create categories datatable
- table = $('#dt-tags').DataTable({
- language: { url: '/libs/DataTables/localization/Greek.json' },
- data: tags,
- order: [[1, 'desc']],
- columns: [
- { data: 'title' },
- { data: 'counter' },
- { data: 'actions', width: '64px' }
- ],
- columnDefs: [{
- 'targets': [2],
- 'orderable': false
- }]
- });
-
- })
- .fail(function( jqxhr, textStatus, error ) {
- console.log( "Request Failed (" + error +")" );
- });
-
- }
- init_table(); // init table on first run
-
-
-
- /** When modal show-up
- * -------------------------------------------------------------------------
- * ... prepare the manage-category form
- * ... update select2 with possible parents
- */
- $('#manageCategory').on('show.bs.modal', event => {
- var button = $(event.relatedTarget); // Button that triggered the modal
- var id = parseInt( button.data('id') ); // category_id from data-id
- // var modal = $(this); // modal object
-
- // update modal literature
- // ---
- $('#manageCategory .modal-title').html( // modal title
- (id) ? 'Ενημέρωση Κατηγορίας' : 'Δημιουργία Κατηγορίας'
- );
- $('#manageCategory form input[name=id]').val( id ); // category id (hidden)
- $('#manageCategory form input[name=title]').val( // category title
- (id) ? category_record(id).title : ""
- );
- prepare_parents_element(id); // prepare <select> for parents
- })
-
-
- // When form is submited
- // -------------------------------------------------------------------------
-
- $('#manageCategory form').submit( event => {
- event.preventDefault();
-
- // prepare data to POST
- var data = {
- id: parseInt($('#manageCategory form input[name=id]').val()),
- title: $('#manageCategory form input[name=title]').val(),
- parent_id: parseInt($('#parent_id').select2('data')[0].id)
- };
-
- // select action url (add or update)
- var request = '/wiki/ajax?action=' + ((data.id == 0) ? 'add_category' : 'update_category');
-
- // send POST request
- $.post(request, data)
- .done(function( data ) {
-
- $('#manageCategory').modal('hide'); // when done, close modal
-
- init_table(); // reload table of categories
- });
-
- });
-
-});