summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/classes/session/DefaultSession.php6
-rw-r--r--public/app/config/app_constants.php43
-rw-r--r--public/app/controllers/Auth.php19
-rw-r--r--public/app/controllers/JsonToForm.php4
-rw-r--r--public/app/controllers/Office.php7
-rw-r--r--public/app/views/components/header_includes.php20
-rw-r--r--public/app/views/templates/course.php93
-rw-r--r--public/app/views/templates/lesson.php82
-rw-r--r--public/app/views/templates/page.php64
-rw-r--r--public/app/views/templates/penalty.php227
-rw-r--r--public/app/views/user/invitation.php166
-rw-r--r--public/app/views/user/login.php82
-rw-r--r--public/assets/css/class.css81
-rw-r--r--public/assets/css/overides.css120
-rw-r--r--public/assets/js/cookie.js41
15 files changed, 578 insertions, 477 deletions
diff --git a/core/classes/session/DefaultSession.php b/core/classes/session/DefaultSession.php
index 819f00a..5e7ce39 100644
--- a/core/classes/session/DefaultSession.php
+++ b/core/classes/session/DefaultSession.php
@@ -16,6 +16,12 @@ class DefaultSession implements SessionHandlerInterface {
// and let the session* functions
// do what they know
ini_set( "session.gc_maxlifetime", MAX_SESSION_LIFE );
+ session_set_cookie_params([
+ 'path' => '/',
+ // 'domain' => COOKIE_DOMAIN, # on localhost must be omitted entirely
+ 'secure' => COOKIE_SECURE,
+ 'samesite' => COOKIE_SAMESITE
+ ]);
session_name(SESSION_NAME);
session_start();
}
diff --git a/public/app/config/app_constants.php b/public/app/config/app_constants.php
index 262a727..3404033 100644
--- a/public/app/config/app_constants.php
+++ b/public/app/config/app_constants.php
@@ -23,7 +23,7 @@ if (file_exists("../core/auth/.env")) {
// WEB-APP name and url
// --- -- -- - - -
define('SITE_TITLE', 'Classroom');
-define('SITE_URL', 'http://localhost');
+define('SITE_URL', $env['ANOM_HOSTNAME']);
// Session and cookie names
// --- -- -- - - -
@@ -31,6 +31,19 @@ define('SESSION_NAME', 'offticket'); // cookie for session (office ticket)
define('CONNECTION_COOKIE', 'con'); // cookie for connection
define('MAX_SESSION_LIFE', 2*60*60); // maximum session lifetime (2 hours)
+// Cookie Policy
+// --- -- -- - - -
+# define('COOKIE_DOMAIN', $env['ANOM_HOSTNAME']); // domain to be visible on
+define('COOKIE_SECURE', false); // Secure cookie policy [true|false]
+define('COOKIE_SAMESITE', 'Strict'); // SameSite cookie policy [Strict|Lax|None]
+ // recomended values:
+ // COOKIE_SECURE=true, COOKIE_SAMESITE='Strict'
+ // --- -- -- - - -
+ // for more info about cookie policy read:
+ // https://www.php.net/manual/en/function.session-set-cookie-params.php
+
+
+
// email setup
// --- -- -- - - -
// SMTP
@@ -180,7 +193,7 @@ define('REGISTRATION_FORM', [
],
[
'name' => 'email',
- 'label' => 'e-mail',
+ 'label' => 'Email',
'type' => 'email',
'value' => 'auto',
'attributes' => ['required']
@@ -284,6 +297,11 @@ define('COMMON_REQUEST_FORM', [
],
'form' => [
[
+ 'name' => 'subject',
+ 'label' => 'Θέμα (χαρακτηριστικός τίτλος για αναφορά)',
+ 'attributes' => ['required']
+ ],
+ [
'name' => 'first_name',
'label' => 'Όνομα',
'attributes' => ['auto']
@@ -364,12 +382,21 @@ define('PENALTY_FORM', [
],
'form' => [
[
+ 'name' => 'subject',
+ 'label' => 'Θέμα (χαρακτηριστικός τίτλος για αναφορά)',
+ 'attributes' => ['required']
+ ],
+ [
+ 'label' => '',
+ 'type' => 'label'
+ ],
+ [
'label' => 'Πειθαρχική υπόθεση',
'type' => 'label'
],
[
'name' => 'of_article',
- 'label' => 'του/της...',
+ 'label' => 'του/της/των...',
'type' => 'select',
'options' => [
'του μαθητή',
@@ -377,33 +404,33 @@ define('PENALTY_FORM', [
'των μαθητών',
'των μαθητριών'
],
- 'class' => 'col-4',
+ 'class' => 'col-md-4',
'attributes' => ['required']
],
[
'name' => 'student_names',
'label' => '(ονοματεπώνυ-μο/μα, πτώση γενική)',
'type' => 'textarea',
- 'class' => 'col-8',
+ 'class' => 'col-md-8',
'attributes' => ['required']
],
[
'name' => 'of_department',
'label' => 'του τμήματος...',
- 'class' => 'col-4',
+ 'class' => 'col-md-4',
'attributes' => ['required']
],
[
'name' => 'date',
'label' => 'Ημερομηνία',
'type' => 'date',
- 'class' => 'col-4',
+ 'class' => 'col-md-4',
'attributes' => ['required']
],
[
'name' => 'time',
'label' => 'Ώρα',
- 'class' => 'col-4',
+ 'class' => 'col-md-4',
'attributes' => ['required']
],
[
diff --git a/public/app/controllers/Auth.php b/public/app/controllers/Auth.php
index 118b4d0..f1e9819 100644
--- a/public/app/controllers/Auth.php
+++ b/public/app/controllers/Auth.php
@@ -62,9 +62,17 @@ class Auth {
// set cookie for connected user
setcookie(
CONNECTION_COOKIE,
- 'connected;'. $user->getName(),
- time()+60*60*10, // 10 hours
- '/'
+ rawurlencode(json_encode(
+ [ 'rid' => $record['role_id'], 'name' => $user->getName() ],
+ JSON_UNESCAPED_UNICODE
+ )),
+ [
+ 'expires' =>time()+60*60*10, // 10 hours
+ 'path' => '/',
+ // 'domain' => COOKIE_DOMAIN,
+ 'secure' => COOKIE_SECURE,
+ 'samesite' => COOKIE_SAMESITE
+ ]
);
// login OK, set Token in session
@@ -174,7 +182,10 @@ class Auth {
]);
- Render::view('user/invitation', ['form' => $form]);
+ Render::view('user/invitation', [
+ 'form' => $form,
+ 'invitation_number' => $user->invitation
+ ]);
}
diff --git a/public/app/controllers/JsonToForm.php b/public/app/controllers/JsonToForm.php
index 5df650d..7df8098 100644
--- a/public/app/controllers/JsonToForm.php
+++ b/public/app/controllers/JsonToForm.php
@@ -219,7 +219,7 @@ class JsonToForm
// print_r([ $set_value, $name, ($default_values->$name ?? 'none') ]);
$appendKey = in_array('append-key', $attributes) ? true : false; // append key (for selects)
- $required = in_array('required', $attributes) ? '' : ''; // required
+ $required = in_array('required', $attributes) ? 'required' : ''; // required
$asterisk = in_array('required', $attributes) ? '*' : ''; // asterisk in label if required
$html .= "
@@ -239,7 +239,7 @@ class JsonToForm
// prepare initialization of select2 (multiple)
$initSelectsJS .= "
var {$name} = $('#{$name}');
- {$name}.select2({ width: '100%', placeholde: '{$label}' });";
+ {$name}.select2({ width: '100%' });";
if ($set_value) { // if default value is set
$initSelectsJS .= "
diff --git a/public/app/controllers/Office.php b/public/app/controllers/Office.php
index cfadde3..44428af 100644
--- a/public/app/controllers/Office.php
+++ b/public/app/controllers/Office.php
@@ -160,6 +160,11 @@ class Office {
}
+ private static function render_common_petition($opts)
+ {
+
+ }
+
private static function render_penalty_form($opts)
{
$user_id = $opts['user']->getID();
@@ -193,7 +198,7 @@ class Office {
// get Form's HTML and Jsvascript
$form = JsonToForm::json_form($form_setup, [
- ['name' => 'id', 'value' => $user_id] // pass user identity
+ ['name' => 'user_id', 'value' => $user_id] // pass user identity
]);
Render::view('templates/penalty', ['form' => $form]);
diff --git a/public/app/views/components/header_includes.php b/public/app/views/components/header_includes.php
index 433cc4e..15685b5 100644
--- a/public/app/views/components/header_includes.php
+++ b/public/app/views/components/header_includes.php
@@ -4,14 +4,24 @@
}
?>
-<!-- fonts (CDN) -->
+<!-- FONTS (CDN) -->
+
+<!-- Roboto slab
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
-<link href="https://fonts.googleapis.com/css2?family=Roboto+Slab:wght@400&display=swap" rel="stylesheet">
+<link href="https://fonts.googleapis.com/css2?family=Roboto+Slab:wght@400&display=swap" rel="stylesheet"> -->
+
+<!-- Fira Sans -->
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link href="https://fonts.googleapis.com/css2?family=Fira+Sans:wght@300;400;500&display=swap" rel="stylesheet">
<!-- fontawesome icons (CDN) -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" integrity="sha512-iecdLmaskl7CVkqkXNQ/ZH/XLlvWZOJyj7Yy7tcenmpD1ypASozpmT/E0iPtmFIB46ZmdtAc9eNBvH0H/ZpiBw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
+
+<!-- LIBRARY (dependencies) CSS -->
+
<!-- bootstap (CDN) -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-aFq/bzH65dt+w6FI2ooMVUpc+21e0SRygnTpmBvdBgSdnuTN7QbdgL+OapgHtvPp" crossorigin="anonymous">
@@ -21,6 +31,7 @@
<!-- select2 css -->
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
+<!-- CUSTOM CSS -->
<!-- main css -->
<link href="/assets/css/class.css" rel="stylesheet">
@@ -28,11 +39,11 @@
<!-- overides -->
<link href="/assets/css/overides.css" rel="stylesheet">
-
-
<!-- bootstrap javascript (CDN) -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha2/dist/js/bootstrap.bundle.min.js" integrity="sha384-qKXV1j0HvMUeCBQ+QVp7JcfGl760yU08IQ+GpUo5hlbpg51QRiuqHAJz8+BrxE/N" crossorigin="anonymous"></script>
+<!-- JAVASCRIPT -->
+
<!-- jQuery (CDN) -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.4/jquery.min.js" integrity="sha512-pumBsjNRGGqkPzKHndZMaAG+bir374sORyzM3uulLV14lN5LyykqNk8eEeUlUkB3U0M4FApyaHraT65ihJhDpQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
@@ -51,7 +62,6 @@
<script src="/assets/js/marked/marked.min.js"></script>
-
<!-- date handling ...
https://stackoverflow.com/questions/27267565/javascript-returning-incorrect-date-from-an-input-type-date
diff --git a/public/app/views/templates/course.php b/public/app/views/templates/course.php
deleted file mode 100644
index 1d212b8..0000000
--- a/public/app/views/templates/course.php
+++ /dev/null
@@ -1,93 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <title><?=SITE_TITLE?> - <?=$title?></title>
-
- <?php // header includes
- ////////////////////////////////////////////////////////////////////////
- Render::view('components/header_includes');
- ?>
-
-</head>
-<body class="classroom">
-
- <?php // top-bar
- ////////////////////////////////////////////////////////////////////////
- Render::view('components/top_bar', [
- 'id' => $id,
- 'label' => $breadcrumbs[ $id ]['rec']['label'],
- 'parents' => $breadcrumbs[ $id ]['parents']
- ]);
- ?>
-
-
-<div class="main-content container">
- <div class="row">
-
- <div class="col col-md-5 col-lg-4 d-sm-none d-md-block side-bar">
-
- <?php // tree of courses
- ////////////////////////////////////////////////////////////////////////
- Render::view('components/courses_menu', [
- 'categories' => $categories,
- 'open_path' => $course_path
- ]);
- ?>
-
- </div>
-
- <div class="col col-sm-12 col-md-7 col-lg-8 course-view">
-
- <!-- Category Title -->
- <h3>
- <?=$breadcrumbs[ $id ]['rec']['label']?>
- </h3>
-
-
- <!-- Sub-Categories -->
- <?php
- Render::view('components/subcategories',[
- 'id' => $id,
- 'breadcrumbs' => $breadcrumbs
- ])
- ?>
-
-
- <!-- Articles List -->
- <?php if ($lessons) : ?>
-
- <h5>Μαθήματα</h5>
-
- <?php // list of posts/articles
- ////////////////////////////////////////////////////
- Render::view("components/lessons_list", [
- 'lessons' => $lessons,
- 'fieldset' => ['intro', 'level'] // ['intro', 'date']
- ]);
- ?>
- <?php endif; ?>
-
-
-
-
- </div>
-
- </div>
- </div>
-
- <footer>
- <div class="container">
-
- <?php // render footer
- ////////////////////////////////////////////////////////////////
- Render::view('components/footer', [ 'entity' => $entity ]);
- ?>
-
- </div>
- </footer>
-
-
- <script src="/assets/js/classroom.js"></script>
-</body>
-</html>
diff --git a/public/app/views/templates/lesson.php b/public/app/views/templates/lesson.php
deleted file mode 100644
index 0867cd3..0000000
--- a/public/app/views/templates/lesson.php
+++ /dev/null
@@ -1,82 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <title><?=SITE_TITLE?> - <?=$title?></title>
-
- <?php // header includes
- ////////////////////////////////////////////////////////////////////////
- Render::view('components/header_includes');
- ?>
-
-</head>
-<body class="classroom">
-
- <?php // top-bar
- ////////////////////////////////////////////////////////////////////////
- Render::view('components/top_bar', [
- 'id' => $id,
- 'label' => $breadcrumbs[ $course_id ]['rec']['label'],
- 'parents' => $breadcrumbs[ $course_id ]['parents']
- ]);
- ?>
-
-
-<div class="main-content container">
- <div class="row">
-
- <div class="col col-md-5 col-lg-4 d-sm-none d-md-block side-bar">
-
- <?php // tree of courses
- ////////////////////////////////////////////////////////////////////////
- Render::view('components/courses_menu', [
- 'categories' => $categories,
- 'open_path' => $course_path
- ]);
- ?>
-
- </div>
-
- <div class="col col-sm-12 col-md-7 col-lg-8 lesson-view">
-
- <!-- Lesson Title -->
- <h3>
- <?=$title?>
- </h3>
-
- <!-- intro -->
- <?php if ($lesson['intro'] != "") : ?>
- <p class="intro"><?=$lesson['intro']?></p>
- <?php endif; ?>
-
- <!-- body -->
- <div class="article-body">
- <?php
-
- $parsedown = new Parsedown();
- echo $parsedown->text($lesson['body']);
-
- ?>
- </div>
-
-
- </div>
-
- </div>
- </div>
-
- <footer>
- <div class="container">
-
- <?php // render footer
- ////////////////////////////////////////////////////////////////
- Render::view('components/footer', [ 'entity' => $entity ]);
- ?>
-
- </div>
- </footer>
-
- <script src="/assets/js/classroom.js"></script>
- <script src="/assets/js/lesson-features.js"></script>
-</body>
-</html>
diff --git a/public/app/views/templates/page.php b/public/app/views/templates/page.php
deleted file mode 100644
index 6afe45e..0000000
--- a/public/app/views/templates/page.php
+++ /dev/null
@@ -1,64 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <title><?=SITE_TITLE?> - <?=$page['title']?></title>
-
- <?php // header includes
- ////////////////////////////////////////////////////////////////////////
- Render::view('components/header_includes');
- ?>
-
-</head>
-<body class="classroom">
-
- <?php // top-bar
- ////////////////////////////////////////////////////////////////////////
- Render::view('components/top_bar', [
- 'id' => 0,
- 'label' => '',
- 'parents' => []
- ]);
- ?>
-
-
- <div class="main-content container page-container">
-
-
- <div class="lesson-view">
-
- <!-- page Title -->
- <h3>
- <?=$page['title']?>
- </h3>
-
- <!-- page body -->
- <div class="article-body">
- <?php
-
- $parsedown = new Parsedown();
- echo $parsedown->text($page['body']);
-
- ?>
- </div>
-
-
- </div>
-
- </div>
-
- <footer>
- <div class="container">
-
- <?php // render footer
- ////////////////////////////////////////////////////////////////
- Render::view('components/footer', [ 'entity' => $entity ]);
- ?>
-
- </div>
- </footer>
-
- <script src="/assets/js/classroom.js"></script>
- <script src="/assets/js/lesson-features.js"></script>
-</body>
-</html>
diff --git a/public/app/views/templates/penalty.php b/public/app/views/templates/penalty.php
index bbd7b4a..17e5426 100644
--- a/public/app/views/templates/penalty.php
+++ b/public/app/views/templates/penalty.php
@@ -9,115 +9,198 @@
Render::view('components/header_includes');
?>
- <style>
- html,body{
- padding:0; margin:0;
- font-size:1.25em;
- color: #037; background: #f6f6f6;
- line-height:1.2em;
- }
- h3 {
- font-size: 2em; font-style: normal;
- font-weight: 400;
- color: #05a;
- margin: 0; padding: 5px;
- opacity: 0.27;
- border-bottom: 1px solid #05a;
- }
- .container { display: flex; height: 100vh; align-items:center; }
- .content { position: relative;
- max-width: 800px; width: 100%;
- margin: auto auto; padding: .5em;
- justify-center: center;
- font-size: .78em;
- }
- .content-form {
- padding: 1.5em;
- background: #eee;
- border-radius: 8px;
- box-shadow: 1px 5px 7px #7777;
- }
- .content .info { padding: 1.5em; font-size: .92em; }
- .content .info p { padding: .5em; color: #444; font-size: .82em }
- .form-label { margin-bottom: .25rem; }
-
- .select2-container--default .select2-selection--multiple { font-size: 15px; }
- .select2-container--default.select2-container--focus .select2-selection--multiple { line-height: 100%; }
- label { font-size: 14px; }
- </style>
</head>
-<body class="classroom">
- <div class='container'>
- <div class="content">
- <div class="info">
- <!--<h4>1o Γυμνάσιο Ραφήνας</h4>
- <p>1o Γυμνάσιο Ραφήνας: Πλατφόρμα ηλεκτρονικών αιτήσεων και δημιουργίας εγγράφων</p>-->
- </div>
+<body class="office central-form">
+
+<div class='container'>
+ <div class="content max720px">
+
<div class='content-form'>
<form method="post">
<div>
- <h2>Πρακτικό Πειθαρχικής Υπόθεσης</h2>
+ <h4>Πρακτικό Πειθαρχικής Υπόθεσης</h4>
+ <hr />
<?=$form['html']?>
<br />
- <button type="submit" class="btn btn-primary btn-sm col-12">Εγγραφή</button>
+ <button type="submit" class="btn btn-primary btn-sm col-12">Καταχώριση</button>
</div>
</form>
</div>
- <div class="info">
- <p>Απαιτείται η συμπλήρωση όλων των στοιχείων προκειμένου να γίνεται γρήγορα η σύνταξη των εγγράφων. Τα στοιχεία σας δεν πρόκειται να δημοσιοποιηθούν και προστατεύονται κατά την εισαγωγή τους με κρυπτογράφιση AES. Παράλληλα η σύνδεση στο site γίνεται με χρήση πιστοποιητικού SSL (RSA 2048 bits).</p>
- <p>Αν έχετε ενεργοποιήσει ήδη το λογαρισμό σας <a href="/login">μπορείτε να συνδεθείτε</a>.</p>
-
</div>
</div>
-</body>
+</body>
<script>
+var values = {};
+var empty = '';
+
+$(document).ready(function() {
+
+ // supplementary functions to select2 control
+ ////////////////////////////////////////////////////////////////////////////
+
+ /** getValues
+ * --- -- -- - - -
+ * Get selected value(s) of Select2 control
+ *
+ * @param arg: source-element
+ * @return (string) value(s) comma-separated
+ */
+ function getValues(srcElm) {
+ var res;
+ var obj = srcElm.select2('data'); // get delected data array
+
+ if (obj.length === 0) return ''; // if empty list then nothig is selected
+ else {
+ var i = 0;
+ obj.forEach(function(elm){ // loop through object elements array
+
+ if (i) res += ',' + elm.id; // if not first item, prepend ',' befor value(id)
+ else res = elm.id; // else set (first) checked value
+
+ i++;
+ });
+ }
+ return res;
+ }
+
+ /** select2_set_text
+ * --- -- -- - - -
+ * select an (select2-)option by text
+ * onto a (single) select2 control
+ *
+ * @param control = jquery selector,
+ * @param t (string) = text of option
+ */
+ function select2_set_text(control, t) {
+ opts = control.select2()[0].options;
+ var id;
+ for(i=0; i<opts.length; i++) { if (opts[i].text == t) id = i; }
+ control.val(id).trigger('change');
+ }
+
+ /** get_id_of_text
+ * --- -- -- - - -
+ * get id (=value) of an option with `t` as text
+ * onto a select2 control;
+ *
+ * Can be used on single or multiple select2 contols
+ *
+ * @param control = jquery selector,
+ * @param t (string) = text of option
+ */
+ function get_id_of_text( control , t) {
+ opts = control.select2()[0].options;
+ var id = false;
+ for(i=0; i<opts.length; i++) { if (opts[i].text == t) id = i; }
+ return id;
+ }
+
+ /** select2_set_multi_text
+ * --- -- -- - - -
+ * select several (select2-)options by text
+ *
+ * @param control = jquery selector,
+ * @param t_list (string) = list of selected texts
+ */
+ function select2_set_multi_text(control, t_list) { /* define function */
+ var ids = [];
+ t_list.forEach (t => { let id = get_id_of_text(control, t);
+ if (id !== false) ids.push(id);
+ })
+ control.val(ids).change();
+ }
+
+ /**
+ * get selected text of a select2 control
+ */
+ function selected_text(control) {
+ if (typeof control.select2('data') === 'undefined') return false;
+ else if (control.select2('data').length == 0) return false;
+ else return control.select2('data')[0].text;
+ }
+
+ /**
+ * get all selected texts from a multi-select2 contol
+ */
+ function selected_multitexts(control) {
+ if (typeof control.select2('data') === 'undefined') return false;
+ else if (control.select2('data').length == 0) return false;
+ else {
+ var result = [];
+ control.select2('data').forEach( item => { result.push(item.text); });
+ return result;
+ }
+ }
+
+ // intializations from form-definition
+ ////////////////////////////////////////////////////////////////////////////
+
+ <?=$form['init_js']?>
+
+
+ // track empty values
+ ////////////////////////////////////////////////////////////////////////////
+
+
+
+
+
// When form is submited
- // -------------------------------------------------------------------------
+ ////////////////////////////////////////////////////////////////////////////
$('.content-form form').submit( event => {
event.preventDefault();
- if ($('input[name=password]').val() != $('input[name=password2]').val()) {
+ if (false) {
alert('Τα δυο passrods δεν ταιριάζουν!');
} else {
- // prepare data to POST
- var data = {
- first_name: $('input[name=first_name]').val(),
- last_name: $('input[name=last_name]').val(),
- email: $('input[name=email]').val(),
- registration_number: $('input[name=registration_number]').val(),
- sector: $('input[name=sector]').val(),
- belonging_school: $('input[name=belonging_school]').val(),
- working_shcool: $('input[name=working_shcool]').val(),
- position_type_id: $('input[name=position_type_id]').val(),
- phone: $('input[name=phone]').val(),
- password: $('input[name=password]').val()
+ var data = { // select content data
+ of_article: selected_text($('select[name=of_article]')),
+ student_names: $('textarea[name=student_names]').val(),
+ of_department: $('input[name=of_department]').val(),
+ date: $('input[name=date]').val(),
+ time: $('input[name=time]').val(),
+ place: selected_text($('select[name=place]')),
+ rapporteur: selected_text($('select[name=rapporteur]')),
+ charge: $('textarea[name=charge]').val(),
+ apology: $('textarea[name=apology]').val(),
+ decision_reasoning: $('textarea[name=decision_reasoning]').val(),
+ decision: selected_text($('select[name=decision]')),
+ decision_more: $('input[name=decision_more]').val(),
+ president: selected_text($('select[name=president]')),
+ members: selected_multitexts($('select[name="members[]"]'))
};
+ var form_data = { // prepare data to post
+ subject: $('input[name=of_department]').val(),
+ content: JSON.stringify(data),
+ on_date: $('input[name=date]').val(),
+ user_id: $('input[name=id]').val()
+ }
+
// select action url (add or update)
- var request = '/account/register';
+ // var request = '/account/register';
+ console.log(data);
// send POST request
- $.post(request, data)
- .done(function( data ) {
- $('.classroom .content-form').html(data.message)
- });
+ // $.post(request, form_data)
+ // .done(function( data ) {
+ // $('.classroom .content-form').html(data.message)
+ // });
}
});
- <?=$form['init_js']?>
-
- <?=$form['values_js']?>
+ });
</script>
</html>
diff --git a/public/app/views/user/invitation.php b/public/app/views/user/invitation.php
index eb34bc4..564b722 100644
--- a/public/app/views/user/invitation.php
+++ b/public/app/views/user/invitation.php
@@ -8,71 +8,55 @@
////////////////////////////////////////////////////////////////////////
Render::view('components/header_includes');
?>
-
- <style>
- html,body{
- padding:0; margin:0;
- font-size:1.25em;
- color: #037; background: #f6f6f6;
- line-height:1.2em;
- }
- h3 {
- font-size: 2em; font-style: normal;
- font-weight: 400;
- color: #05a;
- margin: 0; padding: 5px;
- opacity: 0.27;
- border-bottom: 1px solid #05a;
- }
- .container { display: flex; height: 100vh; align-items:center; }
- .content { position: relative;
- max-width: 540px; width: 100%;
- margin: auto auto; padding: .5em;
- justify-center: center;
- font-size: .78em;
- }
- .content-form {
- padding: 1.5em;
- background: #eee;
- border-radius: 8px;
- box-shadow: 1px 5px 7px #7777;
- }
- .content .info { padding: 1.5em; font-size: .92em; }
- .content .info p { padding: .5em; color: #444; font-size: .82em }
- .form-label { margin-bottom: .25rem; }
- label { font-size: 14px; }
- </style>
</head>
-<body class="office">
+<body class="office central-form">
+
<div class='container'>
- <div class="content">
+ <div class="content max540px">
+
<div class="info">
- <!--<h4>1o Γυμνάσιο Ραφήνας</h4>
- <p>1o Γυμνάσιο Ραφήνας: Πλατφόρμα ηλεκτρονικών αιτήσεων και δημιουργίας εγγράφων</p>-->
+ <h4>1o Γυμνάσιο Ραφήνας</h4>
+ <p>
+ Πλατφόρμα ηλεκτρονικών αιτήσεων
+ και δημιουργίας διαδικαστικών εγγράφων.
+ </p>
</div>
+
<div class='content-form'>
<form method="post">
<div>
- <p>1o Γυμνάσιο Ραφήνας /<br />
- Πλατφόρμα ηλεκτρονικών αιτήσεων και δημιουργίας διαδικαστικών εγγράφων</p>
-
- <h2>Πρόσκληση #</h2>
+ <h4>Πρόσκληση #<?=$invitation_number?></h4>
+ <hr/>
<?=$form['html']?>
<br />
- <button type="submit" class="btn btn-primary btn-sm col-12">Εγγραφή</button>
+ <button type="submit" class="btn btn-primary btn-sm col-12">Ενεργοποίηση Λογαριασμού</button>
</div>
</form>
</div>
<div class="info">
- <p>Απαιτείται η συμπλήρωση όλων των στοιχείων προκειμένου να γίνεται γρήγορα η σύνταξη των εγγράφων. Τα στοιχεία σας δεν πρόκειται να δημοσιοποιηθούν και προστατεύονται κατά την εισαγωγή τους με κρυπτογράφιση AES. Παράλληλα η σύνδεση στο site γίνεται με χρήση πιστοποιητικού SSL (RSA 2048 bits).</p>
- <p>Αν έχετε ενεργοποιήσει ήδη το λογαρισμό σας <a href="/login">μπορείτε να συνδεθείτε</a>.</p>
+ <p>
+ Απαιτείται η συμπλήρωση όλων των στοιχείων
+ προκειμένου να γίνεται γρήγορα η σύνταξη των εγγράφων.
+ </p>
+ <p>
+ Αν έχετε ενεργοποιήσει ήδη το λογαρισμό σας
+ <a href="/login">μπορείτε να συνδεθείτε</a>.
+ </p>
+ <p>
+ Τα στοιχεία σας δεν πρόκειται να δημοσιοποιηθούν και προστατεύονται
+ κατά την μεταφορά τους στον server με ισχυρή κρυπτογράφιση.
+ Η ασφάλεια της σύνδεσης με το site πιστοποιείται από την
+ <a href="https://letsencrypt.org/" target="_blanc">Let's Encrypt</a>.
+ </p>
+ </div>
</div>
</div>
+
</body>
<script>
@@ -81,13 +65,44 @@ var empty = '';
$(document).ready(function() {
+ // supplementary functions to select2 control
+ ////////////////////////////////////////////////////////////////////////////
+
+ /** getValues
+ * --- -- -- - - -
+ * Get selected value(s) of Select2 control
+ *
+ * @param arg: source-element
+ * @return (string) value(s) comma-separated
+ */
+ function getValues(srcElm) {
+ var res;
+ var obj = srcElm.select2('data'); // get delected data array
+
+ if (obj.length === 0) return ''; // if empty list then nothig is selected
+ else {
+ var i = 0;
+ obj.forEach(function(elm){ // loop through object elements array
+
+ if (i) res += ',' + elm.id; // if not first item, prepend ',' befor value(id)
+ else res = elm.id; // else set (first) checked value
+
+ i++;
+ });
+ }
+ return res;
+ }
+
+
/** select2_set_text
+ * --- -- -- - - -
* select an (select2-)option by text
+ * onto a (single) select2 control
*
* @param control = jquery selector,
* @param t (string) = text of option
*/
- function select2_set_text(control, t) { /* define function */
+ function select2_set_text(control, t) {
opts = control.select2()[0].options;
var id;
for(i=0; i<opts.length; i++) { if (opts[i].text == t) id = i; }
@@ -95,23 +110,28 @@ $(document).ready(function() {
}
/** get_id_of_text
- * get id (=value) of an option with `t` text
+ * --- -- -- - - -
+ * get id (=value) of an option with `t` as text
+ * onto a select2 control;
+ *
+ * Can be used on single or multiple select2 contols
*
* @param control = jquery selector,
* @param t (string) = text of option
*/
- function get_id_of_text( control , t) { /* define id from text */
+ function get_id_of_text( control , t) {
opts = control.select2()[0].options;
var id = false;
for(i=0; i<opts.length; i++) { if (opts[i].text == t) id = i; }
return id;
}
- /** select2_set_multi_text
+ /** select2_set_multi_text
+ * --- -- -- - - -
* select several (select2-)options by text
*
* @param control = jquery selector,
- * #param t_list (string) = list of selected texts
+ * @param t_list (string) = list of selected texts
*/
function select2_set_multi_text(control, t_list) { /* define function */
var ids = [];
@@ -122,12 +142,40 @@ $(document).ready(function() {
}
+ /**
+ * get selected text of a select2 control
+ */
+ function selected_text(control) {
+ if (control.select2('data').lenght == 0) return false
+ else return control.select2('data')[0].text;
+ }
+
+ /**
+ * get all selected texts from a multi-select2 contol
+ */
+ function selected_multitexts(control) {
+ if (control.select2('data').legth == 0) return false;
+ else {
+ var result = [];
+ control.select2('data').forEach( item => { result.push(item.text); });
+ return result;
+ }
+ }
+
+ // intializations from form-definition
+ ////////////////////////////////////////////////////////////////////////////
+
<?=$form['init_js']?>
+
+ // track empty values
+ ////////////////////////////////////////////////////////////////////////////
+
<?=$form['values_js']?>
+
// When form is submited
- // -------------------------------------------------------------------------
+ ////////////////////////////////////////////////////////////////////////////
$('form').submit( event => {
event.preventDefault();
@@ -161,15 +209,15 @@ $(document).ready(function() {
// access verification
password: $('input[name=password]').val()
};
- // console.log('post:', data);
+ console.log(data);
- var request = '/account/activate'; // set action url
-
- // send POST request
- $.post(request, data)
- .done(function( data ) {
- $('.office .content-form').html(data.message)
- });
+// var request = '/account/activate'; // set action url
+//
+// // send POST request
+// $.post(request, data)
+// .done(function( data ) {
+// $('.office .content-form').html(data.message)
+// });
}
});
diff --git a/public/app/views/user/login.php b/public/app/views/user/login.php
index 58bfdbb..871e501 100644
--- a/public/app/views/user/login.php
+++ b/public/app/views/user/login.php
@@ -2,58 +2,66 @@
<html lang="en">
<head>
<meta charset="utf-8">
- <title><?=SITE_TITLE?> - Είσοδος Χρήστη</title>
+ <title><?=SITE_TITLE?> - Είσοδος Χρήστη</title>
- <?php // header includes
+ <?php // header includes
////////////////////////////////////////////////////////////////////////
Render::view('components/header_includes');
?>
-
- <style>
- html,body{
- padding:0; margin:0;
- font-size:1.25em;
- color: #037; background: #eee;
- line-height:1.2em;
- }
- h3 {
- font-size: 2em; font-style: normal;
- font-weight: 400;
- color: #05a;
- margin: 0; padding: 5px;
- opacity: 0.27;
- border-bottom: 1px solid #05a;
- }
- .container { display: flex; height: 100vh; align-items:center; }
- .content { position: relative;
- max-width:480px; width: 100%;
- margin: auto auto; padding: 1.5em;
- justify-center: center;
- background: #e3e3e3;
- border-radius: 8px;
- box-shadow: 1px 5px 7px #7777;
- }
- </style>
+<style>
+:root { /* login-form overides */
+ --form-content-font-size: 1rem;
+ --form-input-height: 34px;
+ --select2-arrow-top: 1px;
+}
+</style>
</head>
-<body class="classroom">
+<body class="office central-form">
+
<div class='container'>
- <div class='content'>
- <h4>Είσοδος Χρήστη</h4>
+ <div class='content max420px'>
+
+ <div class="info">
+ <h4>1o Γυμνάσιο Ραφήνας</h4>
+ <p>Πλατφόρμα ηλεκτρονικών αιτήσεων και δημιουργίας διαδικαστικών εγγράφων.</p>
+ </div>
+
+ <div class="content-form">
+ <h4>Είσοδος</h4>
<hr />
<form method="post">
- <div class="mb-3">
- <label for="exampleInputEmail1" class="form-label">Email</label>
+ <div class="form-group">
+ <label for="exampleInputEmail1">Email</label>
<input type="email" class="form-control form-control-sm" name="email" aria-describedby="emailHelp" required>
</div>
- <div class="mb-3">
- <label for="exampleInputPassword1" class="form-label">Κωδικός Πρόσβασης</label>
+ <div class="form-group">
+ <label for="exampleInputPassword1">Κωδικός πρόσβασης</label>
<input type="password" class="form-control form-control-sm" name="password" required>
</div>
<br />
- <button type="submit" class="btn btn-primary btn-sm col-12">Επιβεβαίωση και Είσοδος</button>
+ <div class="row justify-content-center"><div class="col-6">
+ <button type="submit" class="btn btn-primary btn-sm col-12">Σύνδεση</button>
+ </div></div>
</form>
+ </div>
+
+ <div class="info">
+ <!--
+ <p>Αν ξεχάσατε τον κωδικό πρόσβασης μπορείτε να δημιουργήσετε ένα νέο (υπο κατασκευή).</p>
+ -->
+ <p>
+ Εαν δικαιούστε αλλά δεν έχετε πρόσβαση στο site, παρακαλούμε επικοινωνήστε
+ με τη διεύθυνση του σχολείου προκειμένου να σας αποσταλεί σχετική πρόσκληση.
+ </p>
+ <p>
+ Ο ιστότοπος χρησιμοποιεί cookies τα οποία έχουν αποκλειστικά λειτουργικό ρόλο.
+ Η χρήση των υπηρεσιών του site συνεπάγεται την αποδοχή διατήρησης αυτών των cookies.
+ </p>
+ </div>
+
</div>
</div>
+
</body>
<script>
@@ -80,7 +88,7 @@
window.location.href = data.status.goto;
} else {
- alert('Wrong credentials; please try again');
+ alert('Τα στοιχεία πρόσβασης που δώσατε είναι λάθος. Παρακαλώ προσπαθήστε ξανά.');
}
});
diff --git a/public/assets/css/class.css b/public/assets/css/class.css
index 4747507..5333f29 100644
--- a/public/assets/css/class.css
+++ b/public/assets/css/class.css
@@ -28,9 +28,88 @@
--class-orange-opaque: #f4792099;
--class-grey-background: #eeedeb;
--class-red: #d13;
- --light-grey-bgr: #f2f3f8;
+ --light-grey-bgr: #f5f6f7;
+ --light-grey-layer-bgr: #eeeded;
+ --light-grey-shade: 1px 5px 7px #7773;
+ --form-content-font-size: .87rem;
+ --form-input-height: 31px;
+ --form-layer-border: 1px solid #e7e5e5;
+ --select2-arrow-top: -1px;
}
+html, body,
+select, select option {
+ font-family: "Fira Sans", sans-serif;
+ font-weight: 400;
+ font-size: 1rem;
+}
+
+.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 { font-weight: 400; };
+
+html, body {
+ padding:0; margin:0;
+ font-size:1.25em;
+ color: #037; background: var(--light-grey-bgr);
+ line-height:1.2em;
+}
+
+.office h3 {
+ font-size: 2em; font-style: normal;
+ color: #05a;
+ margin: 0; padding: 5px;
+ opacity: 0.27;
+ border-bottom: 1px solid #05a;
+}
+
+
+/** micro-positioning classes
+ * -----------------------------------------------------------------------------
+ */
+
+.max420px { max-width: 420px; width: 100%; }
+.max480px { max-width: 480px; width: 100%; }
+.max540px { max-width: 540px; width: 100%; }
+.max720px { max-width: 720px; width: 100%; }
+.bottom3em { padding-bottom: 3em; }
+
+
+
+
+/** central form
+ * -----------------------------------------------------------------------------
+ * includes login / invitation / reset password forms
+ */
+
+.central-form .container {
+ display: flex;
+ min-height: 100vh;
+ align-items:center;
+}
+.central-form .content {
+ width: 100%;
+ margin: auto auto; padding: .5em;
+ font-size: .78em;
+}
+
+.central-form .content-form {
+ padding: 1.5em;
+ background: var(--light-grey-layer-bgr);
+ border-radius: 8px;
+ box-shadow: var(--light-grey-shade);
+ border: var(--form-layer-border);
+}
+
+.central-form .content .info { padding: 1.5em; font-size: .92em; }
+.central-form .content .info p {
+ color: #554e;
+ font-size: .9rem;
+ line-height: 150%;
+}
+
+.central-form form label { font-size: 14px; }
+
+.central-form h4 { font-size: 1.24rem; }
+
/* main layout classes
diff --git a/public/assets/css/overides.css b/public/assets/css/overides.css
index 3fd143f..aa3173a 100644
--- a/public/assets/css/overides.css
+++ b/public/assets/css/overides.css
@@ -2,14 +2,14 @@
--bs-heading-color: #679;
}
-html, body, select, select option, .select2-selection__choice { font-family: "Roboto Slab", serif; font-weight: 400; }
+.content { text-align: unset; }
-.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 { font-weight: 400; };
+.form-control-sm { font-size: var(--form-content-font-size); }
-.content { text-align: unset; }
+input.form-control-sm { height: var(--form-input-height); }
-.form-group { margin-bottom: 8px; }
-.form-control, .form-select { border: 1px solid #7777; font-size: .857em; }
+.form-group { margin-bottom: 12px; }
+.form-control, .form-select { border: 1px solid #7777; }
.form-label { font-size: .72em; color: var(--bs-heading-color); }
.footer__listLink { color: #bbb; }
@@ -49,7 +49,10 @@ html, body, select, select option, .select2-selection__choice { font-family: "Ro
.admin-container .table > :not(caption) > * > * { padding: .35rem .35rem; }
.admin-container .table tbody tr:hover { background: #eee; }
-ul.select2-results__options li { font-size: 14px; padding: 4px 8px; }
+ul.select2-results__options li {
+ font-size: var(--form-content-font-size);
+ padding: 4px 8px;
+}
.admin-container .modal-footer .form-actions { display: flex; gap: 8px; }
@@ -74,7 +77,6 @@ ul.select2-results__options li { font-size: 14px; padding: 4px 8px; }
background-color: transparent;
background-size: contain;
border: none !important;
- height: 16 !important;
width: 12px !important;
margin: auto !important;
top: 12px !important;
@@ -82,49 +84,18 @@ ul.select2-results__options li { font-size: 14px; padding: 4px 8px; }
height: 14px;
}
.select2-container--default .select2-selection--single .select2-selection__arrow { width: 24px; }
-.select2-container--default .select2-selection--single { height: 37px; }
-/* ------------------------------------------------------------------------- end
-*/
-
-/*
- .admin-container .edit-post textarea[name=intro] { height: 94px ;}
-
-
- .admin-container .post-media button.over-bar { margin: -26px 0 0 0; float: right; }
- .admin-container .post-media ul {
- border: 1px solid #ccc;
- border-radius: 4px;
- padding: 6px;
- }
-
- .admin-container .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;
- }
- .admin-container .post-media ul li:last-child { border-bottom: none ;}
- .admin-container .post-media ul li:hover { background: #eee; }
-
- .admin-container .post-media li .btn-xs { font-size: 14px; width: 24px; height: 24px; padding:0; }
-
- .classroom .edit-post textarea[name=body],
- .classroom .edit-page textarea[name=body] {
- min-height:320px;
- font-family: Consolas, 'Ubuntu Mono','Courier New', Courier, monospace;
- color: #333;
- }
-
-*/
-
+.select2-container--default .select2-selection--single { height: var(--form-input-height); }
/** select2|multiple overides
* --- -- -- - - -
*/
-input.select2-search__field { font-size: 15px; }
+input.select2-search__field { font-size: var(--form-content-font-size); }
+
+.select2-selection__choice {
+ font-size: var(--form-content-font-size);
+ font-weight: 400;
+}
+
ul.select2-selection__rendered { margin-bottom: 0; } /* select2: ul */
.select2-container--default .select2-selection--multiple .select2-selection__choice { padding: 2px; } /* select2: li */
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove { /* select2: button */
@@ -141,4 +112,59 @@ ul.select2-selection__rendered { margin-bottom: 0; } /* select2: ul */
.select2-container--default .select2-selection--single .select2-selection__clear { margin-right: 32px; }
.select2-container .select2-selection--single .select2-selection__rendered { font-size: 15px; padding: 2px 20px 2px 8px; }
- \ No newline at end of file
+
+.select2-container--default .select2-selection--multiple .select2-selection__choice__display {
+ padding-left: 16px;
+}
+
+.select2-container--default .select2-selection--single .select2-selection__arrow {
+ top: var(--select2-arrow-top);
+}
+
+
+
+
+
+/*
+================================================================================
+
+ - - - -- -- --- C H A N G E S --- -- -- - - -
+
+================================================================================
+*/
+
+
+
+/* overides.css | http://localhost/assets/css/overides.css */
+
+
+ .select2-container .select2-selection--single .select2-selection__rendered {
+ font-size: var(--form-content-font-size);
+ }
+
+
+
+.central-form form label {
+ /* font-size: 14px; */
+ font-size: .92rem; color: #554c;
+ }
+
+ /* bootstrap.min.css | https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha2/dist/css/bootstrap.min.css */
+
+
+
+
+
+
+ .select2-container--default .select2-selection--single:focus-visible,
+ .select2-container--focus .select2-selection--multiple {
+ border-color: #86b7fe;
+ box-shadow: 0 0 0 .25rem rgba(13,110,253,.25);
+ outline: none;
+ color: var(--bs-body-color);
+ }
+
+ .select2-container--default.select2-container--focus .select2-selection--multiple {
+ border: 1px solid #86b7fe;;
+ outline: 0;
+ } \ No newline at end of file
diff --git a/public/assets/js/cookie.js b/public/assets/js/cookie.js
index fcd3006..ab51c05 100644
--- a/public/assets/js/cookie.js
+++ b/public/assets/js/cookie.js
@@ -21,7 +21,10 @@ function createCookie(name, value, expire) {
expires = "";
}
- document.cookie = name+"="+value+expires+"; path=/";
+ // encode cookie
+ let enc = encodeRFC3986URIComponent(value);
+
+ document.cookie = name +"="+ enc + expires +"; path=/; SameSite=Strict";
}
@@ -41,7 +44,7 @@ function readCookie(name) {
c = c.substring(1,c.length);
}
if (c.indexOf(nameEQ) == 0) {
- return c.substring(nameEQ.length,c.length);
+ return decodeURIComponent(c.substring(nameEQ.length,c.length));
}
}
return null;
@@ -76,3 +79,37 @@ function cookieExists(name) {
}
return false;
}
+
+
+/** encodeRFC3986URIComponent
+ *
+ * RFC3986 compatible URI encoding
+ *
+ * @param str
+ * @returns (string) RCF3986 compatible encoded str
+ */
+function encodeRFC3986URIComponent(str) {
+ return encodeURIComponent(str).replace(
+ /[!'()*]/g,
+ (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`,
+ );
+}
+
+
+/** example:
+ * --- -- -- - - -
+ *
+ * read connection cookie (as json object)
+ *
+ * connection = JSON.parse(decodeURIComponent(readCookie('con')))
+ *
+ * then...
+ * connection = {
+ * rid: `role-id`,
+ * name: `full name` of connected user
+ * }
+ *
+ * so to refer to user's name ...
+ * console.log(connection.name)
+ *
+ */ \ No newline at end of file