diff options
| author | George Halkiadakis <gchalkiadakis@sklavenitis.co.gr> | 2023-06-01 03:33:18 +0300 |
|---|---|---|
| committer | George Halkiadakis <gchalkiadakis@sklavenitis.co.gr> | 2023-06-01 03:33:18 +0300 |
| commit | 864fbb806621c8167c49f7449486fbc3bdaca1a6 (patch) | |
| tree | 1b5b5933dbb184b130c248d3281e709bd6286c5d /public | |
| parent | 950798a91c0bed3f2d6e53182b0cff49f07eff0c (diff) | |
| download | gyraf1gov-864fbb806621c8167c49f7449486fbc3bdaca1a6.tar.gz gyraf1gov-864fbb806621c8167c49f7449486fbc3bdaca1a6.tar.bz2 gyraf1gov-864fbb806621c8167c49f7449486fbc3bdaca1a6.zip | |
user update; user petitions copy; fixed docker performance issues
Diffstat (limited to 'public')
20 files changed, 801 insertions, 158 deletions
diff --git a/public/app/config/setup_application.php b/public/app/config/setup_application.php index 068c8a8..f56cc1a 100644 --- a/public/app/config/setup_application.php +++ b/public/app/config/setup_application.php @@ -283,6 +283,76 @@ define('REGISTRATION_FORM', [ ] ]); + + +define('USER_PROPERTIES_FORM', [ + 'defaults' => [ + 'outer_class' => 'col-12', + 'inner_class' => 'form-control', + 'type' => 'text', + 'source' => '\app\controllers\User::current' + ], + 'form' => [ + [ + 'name' => 'first_name', + 'label' => 'Όνομα', + 'attributes' => ['required', 'auto'] + ], + [ + 'name' => 'last_name', + 'label' => 'Επίθετο', + 'attributes' => ['required', 'auto'] + ], + [ + 'name' => 'email', + 'label' => 'Email', + 'type' => 'email', + 'attributes' => ['required', 'auto'] + ], + [ + 'name' => 'father_name', + 'label' => 'Πατρώνυμο', + 'attributes' => ['required', 'auto'] + ], + [ + 'name' => 'registration_number', + 'label' => 'Αριθμός μητρώου', + 'class' => 'col-8', + 'attributes' => ['required', 'auto'] + ], + [ + 'name' => 'sector', + 'label' => 'Κλάδος / Ειδικότητα', + 'type' => 'select', + 'attributes' => ['required', 'auto'], + 'options' => TEACHER_SECTORS + ], + [ + 'name' => 'belonging_school', + 'label' => 'Σχολείο τοποθέτησης', + 'attributes' => ['required', 'auto'] + ], + // [ // working school = (obviously) is the current school + // 'name' => 'working_school', + // 'label' => 'Σχολείο εργασίας', + // 'attributes' => ['required'] + // ], + [ + 'name' => 'position', + 'label' => 'Θέση', + 'type' => 'select', + 'attributes' => ['required', 'auto'], + 'options' => [] + ], + [ + 'name' => 'phone', + 'label' => 'Τηλέφωνο', + 'class' => 'col-8', + 'attributes' => ['required', 'auto'] + ] + ] +]); + // Application (common request) form // --- define('APPLICATION_FORM', [ diff --git a/public/app/controllers/Auth.php b/public/app/controllers/Auth.php index 9f440ed..cbf4d19 100644 --- a/public/app/controllers/Auth.php +++ b/public/app/controllers/Auth.php @@ -20,7 +20,7 @@ use app\extends\SendMail_service; */ class Auth { - /** login + /** AJAX POST: login * * checks visitor's credentials; * if valid, authenticates user @@ -98,7 +98,7 @@ class Auth { } - /** activate + /** AJAX POST: activate * resolves call POST:/account/activate * * @param void : all parametres passed via request->POST @@ -118,20 +118,50 @@ class Auth { if ($check != 0) { Render::json([ 'title' => ACCOUNT_ACTIVATED_TITLE, - 'message' => ACCOUNT_ACTIVATED_MESSAGE . '<br>(msg code: '. $check .')' + 'message' => ACCOUNT_ACTIVATED_MESSAGE . '<br>(msg code: '. $check .')' ]); } else { Render::json([ 'title' => NOT_VALID_ACTIVATION_TITLE, - 'message' => NOT_VALID_ACTIVATION_MESSAGE + 'message' => NOT_VALID_ACTIVATION_MESSAGE ]); } } - /** invitation + + /** AJAX POST: update_user + * + * resolves call POST:/user/update_properties; + * updates user's proiperties with POSTed data + * + * @param void : all parametres passed via request->POST + */ + public static function update_user() + { + $req = Registry::get('REQUEST'); + $manager = new App_manager(); + ; + // print_r($req->POST); die(); + + // ask model to update user; get user-id from user-manager + $check = Access_model::update_user( + $req->POST, + $manager->getUserToken()->getUser()->getID() + ); + + // TODO: message for user updating properties + Render::json([ + 'title' => ACCOUNT_ACTIVATED_TITLE, + 'message' => ACCOUNT_ACTIVATED_MESSAGE . '<br>(msg code: '. $check .')' + ]); + + } + + + /** SERVE FORM: invitation * * setups and renders the form for a certain invitation * @@ -188,6 +218,48 @@ class Auth { } + /** SERVE FORM: update_form + * + * renders a form with all user's properties + * + * NOTE: + * after form is submited, client shall call Auth::update_user() + * + */ + public static function update_form() + { + $user = json_decode(json_encode(self::user_data(), JSON_UNESCAPED_UNICODE)); + + // format form_setup to a json array + $form_setup = json_decode(json_encode(USER_PROPERTIES_FORM, JSON_UNESCAPED_UNICODE)); + + // get $key of position item inside the form_setup->form array + for( $i=0; $i < sizeof($form_setup->form) ; $i++ ) { + if ($form_setup->form[$i]->name == 'position') { $key = $i; } + } + + // prepare gendered options to position field + $positions = ($user->prefix != 'η') + ? GENDERED_POSITIONS['he'] + : GENDERED_POSITIONS['she']; + $gendered_position = json_decode( json_encode( $positions, JSON_UNESCAPED_UNICODE )); + $form_setup->form[$key]->options = $gendered_position; + + // attach default values + $form_setup->defaults = $user; + + // get Form's HTML and Jsvascript + $form = JsonToForm::json_form($form_setup, [ + // pass invitation identity for security + ['name' => 'id', 'value' => $user->id] + ]); // print_r($form_setup); die(); + + Render::view('user/update_properties', [ + 'form' => $form + ]); + } + + /** is_connected * checks if the user is connected * diff --git a/public/app/controllers/Office.php b/public/app/controllers/Office.php index 83135de..f57cf08 100644 --- a/public/app/controllers/Office.php +++ b/public/app/controllers/Office.php @@ -327,6 +327,26 @@ class Office { + public static function petition_copy($sign) + { + if (false) { //(Auth::in_admin_group()) { + $petition = Content_model::get_petition(['signature' => $sign]); + + } else { + $manager = new App_manager(); + $petition = Content_model::get_petition([ + 'signature' => $sign, + 'user_id' => $manager->getUserToken()->getUser()->getID() + ]); + } + if ($petition === false) Render::view('error/404'); + else { + Render::view( 'templates/create_pdf',['petition' => $petition]); + } + } + + + ## TICKET METHODS (create, remove) ## tickets eliminate CSRF attacks ## ------------------------------------------------------------------------- diff --git a/public/app/models/Access_model.php b/public/app/models/Access_model.php index 844ff6b..5c9f991 100644 --- a/public/app/models/Access_model.php +++ b/public/app/models/Access_model.php @@ -41,7 +41,7 @@ class Access_model { return Registry::use('database')->query( "SELECT * FROM user WHERE invitation = :invitation", - ['invitation' => $invitation] + [ 'invitation' => $invitation ] )->getFirst(); } @@ -166,6 +166,58 @@ class Access_model + /** update_user + * + * activate user and set password + * + * @param array $post; + * @param int $id: user id + */ + public static function update_user($post, $id) + { + // Update and set activate = true + $rowCount = Registry::use('database')->query( + "UPDATE user + SET first_name = :first_name, + last_name = :last_name, + email = :email, + father_name = :father_name, + registration_number = :registration_number, + sector = :sector, + belonging_school = :belonging_school, + position = :position, + phone = :phone, + invitation = NULL, + active = :active + WHERE id = :id", + [ + ':first_name' => $post['first_name'], + ':last_name' => $post['last_name'], + ':email' => $post['email'], + ':father_name' => $post['father_name'], + ':registration_number' => $post['registration_number'], + ':sector' => $post['sector'], + ':belonging_school' => $post['belonging_school'], + ':position' => $post['position'], + ':phone' => $post['phone'], + ':active' => 1, + ':id' => $id + ] + )->rowCount(); + + // update history + if ($rowCount != 0) { + History_model::trackUserAccess( + $id, TRACK_ACCOUNT, 'User properties changed' + ); + } + + return $rowCount; + + } + + + ## Set permission methods ## ------------------------------------------------------------------------- diff --git a/public/app/models/Content_model.php b/public/app/models/Content_model.php index 2a79159..1f145a0 100644 --- a/public/app/models/Content_model.php +++ b/public/app/models/Content_model.php @@ -73,6 +73,7 @@ class Content_model { 'subject' => $rec['subject'], 'signature' => $rec['signature'], 'protocol' => $rec['protocol'] ?? '', + 'creation_date' => date("Y-m-d", strtotime($rec['creation_date'])), 'form_structure' => unserialize($rec['form_structure']) ]; } @@ -96,6 +97,35 @@ class Content_model { } + public static function get_petition($filters) + { + $where = []; + $binds = []; + foreach($filters as $key => $val) { + $where[] = $key ." = :". $key; + $binds[':'.$key] = $val; + } + + $rec = Registry::use('database')->query( + "SELECT * FROM petition WHERE ". implode(" AND ", $where), + $filters + )->getFirst(); + + if ($rec === false) return false; + else { + return [ + 'id' => $rec['id'], + 'type' => (($rec['type_id'] == 1) ? 'application' : 'penalty'), + 'subject' => $rec['subject'], + 'signature' => $rec['signature'], + 'protocol' => $rec['protocol'] ?? false, + 'creation_date' => date("Y-m-d", strtotime($rec['creation_date'])), + 'form_structure' => unserialize($rec['form_structure']) + ]; + } + } + + ## F I L E S ## ------------------------------------------------------------------------- diff --git a/public/app/routes/user.php b/public/app/routes/user.php index 4a09801..2ecd3c1 100644 --- a/public/app/routes/user.php +++ b/public/app/routes/user.php @@ -111,13 +111,30 @@ if (Auth::is_connected()) { Office::request_petition($tag); }); - // request EXISTING PETITION + // request EXISTING petition copy // --- -- -- - - - Route::add('/petition/signature/([0-9a-f]*)', function($signature) { - Office::filter_request_petition($signature); + Office::petition_copy($signature); }); + + // UPDATE user properties + // ------------------------------------------------------------------------- + + // request UPDADE FORM + // --- -- -- - - - + Route::add('/user/update_form', function() { + Auth::update_form(); + }); + + // update user (data via post) + // --- -- -- - - - + Route::add('/user/update_properties', function() { + Auth::update_user(); + }, 'post'); + + // CRUD content // ------------------------------------------------------------------------- diff --git a/public/app/views/components/header_includes.php b/public/app/views/components/header_includes.php index c20811b..0600450 100644 --- a/public/app/views/components/header_includes.php +++ b/public/app/views/components/header_includes.php @@ -4,12 +4,15 @@ } ?> -<!-- 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"> --> +<!-- FONTS (CDN) + /////////////////////////////////////////////////////////////////////////--> +<?php /* DEPRICATED: + <!-- 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"> --> + */ +?> <!-- Fira Sans --> <link rel="preconnect" href="https://fonts.googleapis.com"> @@ -20,7 +23,9 @@ <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 --> + +<!-- 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"> @@ -31,7 +36,10 @@ <!-- select2 css --> <link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" /> -<!-- CUSTOM CSS --> + + +<!-- CUSTOM CSS + /////////////////////////////////////////////////////////////////////////--> <!-- 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> @@ -42,7 +50,10 @@ <!-- overides --> <link href="/assets/css/overides.css" rel="stylesheet"> -<!-- JAVASCRIPT --> + + +<!-- 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> @@ -50,20 +61,12 @@ <!-- basic cookie handling (vanilla js) --> <script src="/assets/js/cookie.js"></script> -<!-- datatables js --> -<!-- -<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/pdfmake.min.js"></script> -<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/vfs_fonts.js"></script> - -<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/pdfmake.min.js"></script> -<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.32/vfs_fonts.js"></script> ---> - +<!-- pdfmake --> <script src="<?=SITE_URL?>/assets/js/pdfmake/pdfmake.min.js"></script> <script src="<?=SITE_URL?>/assets/js/pdfmake/vfs_fonts.js"></script> -<!-- -<script src="https://cdn.datatables.net/v/bs5/jszip-2.5.0/dt-1.13.4/b-2.3.6/b-colvis-2.3.6/b-html5-2.3.6/b-print-2.3.6/cr-1.6.2/date-1.4.0/fc-4.2.2/fh-3.3.2/kt-2.8.2/r-2.4.1/rr-1.3.3/sc-2.1.1/sl-1.6.2/sr-1.2.2/datatables.min.js"></script>--> +<!-- datatables js --> +<script src="https://cdn.datatables.net/v/bs5/jszip-2.5.0/dt-1.13.4/b-2.3.6/b-colvis-2.3.6/b-html5-2.3.6/b-print-2.3.6/cr-1.6.2/date-1.4.0/fc-4.2.2/fh-3.3.2/kt-2.8.2/r-2.4.1/rr-1.3.3/sc-2.1.1/sl-1.6.2/sr-1.2.2/datatables.min.js"></script> <!-- select2 js --> <script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script> @@ -71,36 +74,37 @@ <!-- marked --> <script src="/assets/js/marked/marked.min.js"></script> +<?php /* NOTE: + <!-- date handling in vanilla js ... + https://stackoverflow.com/questions/27267565/javascript-returning-incorrect-date-from-an-input-type-date -<!-- date handling ... -https://stackoverflow.com/questions/27267565/javascript-returning-incorrect-date-from-an-input-type-date - -// convert to UTC to avoid "date minus one" issues where the supplied date is interpreted incorrectly as -// the previous date. + // convert to UTC to avoid "date minus one" issues where the supplied date is interpreted incorrectly as + // the previous date. -date = new Date(document.getElementById('date').value); -console.log("original date: " + date.toString()); -console.log("UTC date string: " + date.toUTCString()); + date = new Date(document.getElementById('date').value); + console.log("original date: " + date.toString()); + console.log("UTC date string: " + date.toUTCString()); -//produces local machine timezone, and therefore incorrect date value + //produces local machine timezone, and therefore incorrect date value -date = new Date(date.toUTCString()); -console.log("UTC date string Date constructor: " + date.toString()); + date = new Date(date.toUTCString()); + console.log("UTC date string Date constructor: " + date.toString()); -utcDate = new Date(utcString.substr(0, utcString.indexOf("GMT"))); -console.log("UTC date string Date constructor (without 'GMT*'): " + utcDate.toString()); -console.log("UTC date number: " + date.getUTCDate()); -date.setDate(date.getUTCDate()); -date.setMonth(date.getUTCMonth()); -date.setFullYear(date.getUTCFullYear()); -console.log("UTC modified date: " + date.toString()); + utcDate = new Date(utcString.substr(0, utcString.indexOf("GMT"))); + console.log("UTC date string Date constructor (without 'GMT*'): " + utcDate.toString()); + console.log("UTC date number: " + date.getUTCDate()); + date.setDate(date.getUTCDate()); + date.setMonth(date.getUTCMonth()); + date.setFullYear(date.getUTCFullYear()); + console.log("UTC modified date: " + date.toString()); -Output: + Output: -original date: Fri Jan 29 2021 23:16:11 GMT-0600 (Central Standard Time) -UTC date string: Sat, 30 Jan 2021 05:16:11 GMT -UTC date string Date constructor: Fri Jan 29 2021 23:16:11 GMT-0600 (Central Standard Time) -UTC date string Date constructor (without 'GMT*'): Sat Jan 30 2021 23:16:11 GMT-0600 (Central Standard Time) -UTC date number: 30 -UTC modified date: Sat Jan 30 2021 23:16:11 GMT-0600 (Central Standard Time) --->
\ No newline at end of file + original date: Fri Jan 29 2021 23:16:11 GMT-0600 (Central Standard Time) + UTC date string: Sat, 30 Jan 2021 05:16:11 GMT + UTC date string Date constructor: Fri Jan 29 2021 23:16:11 GMT-0600 (Central Standard Time) + UTC date string Date constructor (without 'GMT*'): Sat Jan 30 2021 23:16:11 GMT-0600 (Central Standard Time) + UTC date number: 30 + UTC modified date: Sat Jan 30 2021 23:16:11 GMT-0600 (Central Standard Time) + --> +*/
\ No newline at end of file diff --git a/public/app/views/components/menu.php b/public/app/views/components/menu.php index 524547c..3e1748d 100644 --- a/public/app/views/components/menu.php +++ b/public/app/views/components/menu.php @@ -15,8 +15,8 @@ <li class="list-group-item"><a href="/user/petitions">Πρακτικά και αιτήσεις</a></li> <li class="list-group-item separator">Προφίλ</li> - <li class="list-group-item"><a href="/user/update">Ενημέρωση στοιχείων</a></li> - <li class="list-group-item"><a href="/user/new-password">Αλλαγή password</a></li> + <li class="list-group-item"><a href="/user/update_form">Ενημέρωση στοιχείων</a></li> + <li class="list-group-item"><a href="/user/change_password">Αλλαγή password</a></li> <?php if ($is_admin) : ?> <li class="list-group-item separator">Διαχείριση</li> diff --git a/public/app/views/components/own_petitions.php b/public/app/views/components/own_petitions.php index 4b076c4..41e59b4 100644 --- a/public/app/views/components/own_petitions.php +++ b/public/app/views/components/own_petitions.php @@ -1,15 +1,18 @@ - <!-- title bar --> - <div class="title-bar"> - <div><h5>Διαχείριση Αιτήσεων και Δοικητικών Εγγράφων</h5></div> - <div> - <!-- Button trigger modal --> - <a type="button" class="btn pull-right" href="/admin/edit_lesson"> - <i class="fas fa-plus"></i> Νέο Μάθημα - </a> +<div class="manage"> + <!-- title bar --> + <div class="title-bar"> + <div class="row"> + <h5 class="col-md-10">Διαχείριση Αιτήσεων και Δοικητικών Εγγράφων</h5> + <div class="col-md-2"> + <a type="button" class="btn btn-sm btn-back2panel pull-right" href="/panel"> + Επιστροφή + </a> + </div> + </div> + </div> -</div> -<div class="manage"> + <div class="row"> <div class="col-md-12"> @@ -18,9 +21,9 @@ <table id="dt-petitions" class="table table-responsive dt-table" style="width:100%"> <thead> <!--<th class="dt-id">α/α</th>--> - <th class="dt-title">Τίτλος</th> + <th class="dt-subject">Θέμα</th> <th class="dt-protocol">Αρ.Πρωτόκολλου</th> - <th class="dt-signature">Signature</th> + <!-- <th class="dt-signature">Signature</th> --> <th class="dt-datepost">Ημερ. Καταχώρισης</th> <th class="dt-actions"></th> </thead> @@ -30,8 +33,5 @@ </div> </div> + </div><!-- /manage --> - - - - diff --git a/public/app/views/js/submit/application-form.php b/public/app/views/js/submit/application-form.php index 168ca0d..272fbcb 100644 --- a/public/app/views/js/submit/application-form.php +++ b/public/app/views/js/submit/application-form.php @@ -21,7 +21,8 @@ position: selected_text($('select[name=position]')), request: $('textarea[name=request]').val(), now: Math.floor(Date.now() / 1000), // client timestamp - ticket: ref.ticket + ticket: ref.ticket, + ref: ref }; } diff --git a/public/app/views/js/submit/penalty-form.php b/public/app/views/js/submit/penalty-form.php index a5a8ec6..e3d2748 100644 --- a/public/app/views/js/submit/penalty-form.php +++ b/public/app/views/js/submit/penalty-form.php @@ -23,7 +23,8 @@ president: selected_text($('select[name=president]')), now: Math.floor(Date.now() / 1000), // client timestamp members: selected_multitexts($('select[name="members[]"]')), - ticket: ref.ticket + ticket: ref.ticket, + ref: ref }; } diff --git a/public/app/views/js/submit/update-properties.php b/public/app/views/js/submit/update-properties.php new file mode 100644 index 0000000..651ef3e --- /dev/null +++ b/public/app/views/js/submit/update-properties.php @@ -0,0 +1,38 @@ +<script> + $(document).ready(function() { + + // When form is submited + //////////////////////////////////////////////////////////////////////////// + + $('form').submit( event => { + event.preventDefault(); + + // prepare data to POST + var data = { + // identification fields + id: $('input[name=id]').val(), + // data fields + first_name: $('input[name=first_name]').val(), + last_name: $('input[name=last_name]').val(), + father_name: $('input[name=father_name]').val(), + email: $('input[name=email]').val(), + registration_number: $('input[name=registration_number]').val(), + sector: $('select[name=sector]').select2('data')[0].text, + belonging_school: $('input[name=belonging_school]').val(), + position: $('select[name=position]').select2('data')[0].text, + phone: $('input[name=phone]').val(), + }; + console.log(data); + + var request = '/user/update_properties'; // set action url + + // send POST request + $.post(request, data) + .done(function( data ) { + $('.office .content-form').html(`<h4>${data.title}<h4><br>${data.message}`) + }); + + }); + + }); +</script>
\ No newline at end of file diff --git a/public/app/views/templates/create_pdf.php b/public/app/views/templates/create_pdf.php new file mode 100644 index 0000000..19b2894 --- /dev/null +++ b/public/app/views/templates/create_pdf.php @@ -0,0 +1,69 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title><?=SITE_TITLE?></title> + + <style> + html,body{ + padding:0; margin:0; + font-size:1.15em; font-family: Arial, Helvetica, Ubuntu, sans-serif; + 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:320px; width: 100%; + margin: auto auto; padding: 1.5em 1.5em 3em 1.5em; + text-align: center; justify-center: center; + opacity: .5; + } + .btn { font-size: 18px; padding: 4px 12px; } + </style> + + <script src="<?=SITE_URL?>/assets/js/pdfmake/pdfmake.min.js"></script> + <script src="<?=SITE_URL?>/assets/js/pdfmake/vfs_fonts.js"></script> + + <?php // load pdf-designer + //////////////////////////////////////////////////////////////////////// + Render::view('js/pdf-designer/'. $petition['type']); + ?> +</head> +<body> + <div class='container'> + <div class='content'> + + <!--<h3>Παρακαλώ περιμένετ</h3>--> + Η διαδικασία λήψης του εγγράφου είναι σε εξέλιξη...<br /> + + </div> + </div> +</body> +<script> +var data = <?=json_encode($petition, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE)?>; + +pdfMake.fonts = { + FiraSans: { + normal: '<?=SITE_URL?>/assets/fonts/FiraSans-Light.ttf', + bold: '<?=SITE_URL?>/assets/fonts/FiraSans-Medium.ttf' + // italics: 'https://example.com/fonts/fontFile3.ttf', + // bolditalics: 'https://example.com/fonts/fontFile4.ttf' + }, + FiraMono: { + normal: '<?=SITE_URL?>/assets/fonts/FiraMono-Regular.ttf', + } + } + +pdfMake.createPdf( + designer( data.form_structure, data.form_structure.ref ) +).download('<?=$petition['signature']?>.pdf'); +</script> +</html>
\ No newline at end of file diff --git a/public/app/views/user/panel.php b/public/app/views/user/panel.php index 80f4071..fbfdd0c 100644 --- a/public/app/views/user/panel.php +++ b/public/app/views/user/panel.php @@ -38,18 +38,6 @@ ]); ?> - <!-- content - ** petitions datatable - * change password -> link out (?) - * update properties -> link out (?) - ** admin petitions datatable - * send invitations -> link out (?) - * create member -> link out (?) - - TODO: - switch / case (?) - --> - </div> </div> @@ -110,6 +98,7 @@ </body> + <script src="/assets/js/panel/<?=$content?>.js"></script> <!-- scripts * handle show petition request diff --git a/public/app/views/user/update_properties.php b/public/app/views/user/update_properties.php new file mode 100644 index 0000000..35a1b1e --- /dev/null +++ b/public/app/views/user/update_properties.php @@ -0,0 +1,70 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title><?=SITE_TITLE?> - Ενημέρωση στοιχείων</title> + + <?php // header includes + //////////////////////////////////////////////////////////////////////// + Render::view('components/header_includes'); + ?> +</head> +<body class="office central-form"> + + <div class='container'> + <div class="content max540px"> + + <div class='content-form'> + <form method="post"> + <div> + <h4>Ενημέρωση στοιχείων</h4> + <hr/> + + <?=$form['html']?> + + <br /> + <button type="submit" class="btn btn-primary btn-sm col-12">Ενημέρωση</button> + + </div> + </form> + </div> + + </div> + </div> + +</body> + +<script>// initialize needed global variables + var values = {}; + var empty = ''; +</script> + + +<?php // include select2 supplementary functions + //////////////////////////////////////////////////////////////////////////// + Render::view('js/select2-supplementary'); +?> + +<script> +$(document).ready(function() { + + // intializations from form-definition + //////////////////////////////////////////////////////////////////////////// + + <?=$form['init_js']?> + + + // set known values + //////////////////////////////////////////////////////////////////////////// + + <?=$form['values_js']?> + +}); +</script> + + +<?php // handle form submition + //////////////////////////////////////////////////////////////////////////// + Render::view('js/submit/invitation-form'); +?> +</html> diff --git a/public/assets/css/class.css b/public/assets/css/class.css index 7fe88c7..53602d3 100644 --- a/public/assets/css/class.css +++ b/public/assets/css/class.css @@ -22,7 +22,6 @@ :root { --bs-heading-color: #458; /* header color */ - --class-blue: #337ab7; --class-blue-opaque: #337ab799; --class-blue-dark: #082e44; @@ -36,9 +35,10 @@ --form-content-font-size: .87rem; --form-input-height: 31px; --form-layer-bgr: #dddb; /* form layer background */ - --select2-arrow-top: -1px; - --background-image: url(/assets/media/spring-04.jpg); /* main background */ - --menu-hover-bgr: #efefa6 /* <-- spring-04 ; default: #def */; + --select2-arrow-top: 8px; + --background-image: #fafafa; /* main background */ + --menu-hover-bgr: #def /* <-- spring-04 ; default: #def */; + --info-text-color: #554e; } @@ -49,7 +49,12 @@ select, select option { font-weight: 400; font-size: 1rem; } -body { padding: 0; background: var(--background-image); background-size: cover; } +body { + padding: 0; + background: var(--background-image); + background-size: cover; + background-position: center; +} .h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 { font-weight: 400; }; @@ -133,7 +138,7 @@ html, body { .central-form .content .info { padding: 1.5em; font-size: .92em; } .central-form .content .info p { - color: #554e; + color: var(--info-text-color); font-size: .9rem; line-height: 150%; } diff --git a/public/assets/css/overides.css b/public/assets/css/overides.css index 110b35b..19cd3ce 100644 --- a/public/assets/css/overides.css +++ b/public/assets/css/overides.css @@ -9,48 +9,47 @@ input.form-control-sm { height: var(--form-input-height); } .form-control, .form-select { border: 1px solid #7777; } .form-label { font-size: .72em; color: var(--bs-heading-color); } -.footer__listLink { color: #bbb; } -.footer__listLink:hover { color: #eee; } -.footer__title { color: #bbb7; } - /* .user .dropdown button { min-width: 256px; } */ .user .dropdown ul.dropdown-menu { - right: 0 !important; - left: unset !important; - transform: translate(0, 34px) !important; + right: 0 !important; + left: unset !important; + transform: translate(0, 34px) !important; } -.admin-container { font-size: .96em; } -.admin-container .top-bar a:hover { background: #ddd; } -.admin-container .manage { padding: 1em; } +/* +.footer__listLink { color: #bbb; } +.footer__listLink:hover { color: #eee; } +.footer__title { color: #bbb7; } +.admin-container { font-size: .96em; } +.admin-container .top-bar a:hover { background: #ddd; } .admin-container .title-bar { display: flex; justify-content: space-between; align-items: center; padding: 1.5em 1em 1.5em 1em; } - .admin-container .dt-table { font-size: 14px; } - .admin-container .dt-table .btn-sm { --bs-btn-padding-y: .2rem; --bs-btn-padding-x: .35rem; --bs-btn-font-size: .65rem; } - .admin-container .modal .form-group { padding: .35em 0;} -/*.admin-container .modal .form-control { padding: 1px 8px; border-radius: 4px; font-size: 15px; } */ + .admin-container .table > :not(caption) > * > * { padding: .35rem .35rem; } .admin-container .table tbody tr:hover { background: #eee; } +*/ + 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; } .admin-container .title-bar h5 { margin-bottom: 0; color: #333; } @@ -63,6 +62,7 @@ ul.select2-results__options li { .admin-container form label { padding: 8px 1em 2px 1em; } .admin-container .form-control { border-radius: 4px; } +*/ /* hack select2 caret styling @@ -71,21 +71,11 @@ ul.select2-results__options li { */ .select2-container--default .select2-selection--single .select2-selection__arrow b { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"); - background-color: transparent; - background-size: contain; - border: none !important; - width: 12px !important; - margin: auto !important; - top: 12px !important; - left: auto !important; - height: 14px; + background-color: transparent; background-size: contain; border: none !important; + height: 14px; width: 12px; + margin: auto !important; top: var(--select2-arrow-top); left: auto !important; } -.select2-container--default .select2-selection--single .select2-selection__arrow { width: 24px; } -.select2-container--default .select2-selection--single { height: var(--form-input-height); } -/** select2|multiple overides - * --- -- -- - - - - */ input.select2-search__field { font-size: var(--form-content-font-size); } .select2-selection__choice { @@ -93,32 +83,36 @@ input.select2-search__field { font-size: var(--form-content-font-size); } font-weight: 400; } -ul.select2-selection__rendered { margin-bottom: 0; } /* select2: ul */ +ul.select2-selection__rendered { margin-bottom: 0; } .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 */ +.select2-container--default .select2-selection--multiple .select2-selection__choice__remove { border-right: none; padding: 1px 4px; } .select2-container--default .select2-selection--multiple { font-size: 15px; } - - - -/* select2.min.css | https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css */ - .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; } + +.select2-container .select2-selection--single .select2-selection__rendered { + font-size: var(--form-content-font-size); + padding: 2px 20px 2px 8px; +} .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); +.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; } - - @@ -131,37 +125,13 @@ ul.select2-selection__rendered { margin-bottom: 0; } /* select2: ul */ */ - -/* 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; color: #433; } - /* 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; - } @@ -203,7 +173,15 @@ ul.select2-selection__rendered { margin-bottom: 0; } /* select2: ul */ } -.central-form .content .info p { color: #334; } + +.btn-xs { height: 24px; padding: 1px 8px; font-size: 14px; } + +.manage { padding: 1.5em; } +.manage .title-bar h5 { margin-bottom: 1rem; } + +.manage tbody, td, tfoot, th, thead, tr { background: #ddd4; } +.manage tbody, td, tfoot, th, thead, tr.odd { background: #fff4; } +.manage tbody td { font-size: 14px; } /** cc photo sources @@ -284,3 +262,17 @@ https://www.flickr.com/photos/drtonygeorge/1474585836/ ! --- -- -- - - - */ + +/* spring 04 + --- -- -- - - -*/ + :root { + --background-image: url(/assets/media/spring-04.jpg); + --bs-heading-color: #230; + --menu-hover-bgr: #efefa6; + --info-text-color: #334; + } + .central-form .content-form { background: #dddb; } + .central-form .content-form { border: 1px solid #dddb } + .info li.list-group-item:hover { background: #c9f490; } +/* --- -- -- - - - +*/
\ No newline at end of file diff --git a/public/assets/js/DataTables/localization/Greek.json b/public/assets/js/DataTables/localization/Greek.json new file mode 100644 index 0000000..a92f6cf --- /dev/null +++ b/public/assets/js/DataTables/localization/Greek.json @@ -0,0 +1,29 @@ + + +{ + "sDecimal": ",", + "sEmptyTable": "Δεν υπάρχουν δεδομένα στον πίνακα", + "sInfo": "Εμφανίζονται _START_ έως _END_ από _TOTAL_ εγγραφές", + "sInfoEmpty": "Εμφανίζονται 0 έως 0 από 0 εγγραφές", + "sInfoFiltered": "(φιλτραρισμένες από _MAX_ συνολικά εγγραφές)", + "sInfoPostFix": "", + "sInfoThousands": ".", + "sLengthMenu": "Εμφάνιση _MENU_ εγγραφών", + "sLoadingRecords": "Φόρτωση...", + "sProcessing": "Επεξεργασία...", + "sSearch": "Αναζήτηση:", + "sSearchPlaceholder": "Αναζήτηση", + "sThousands": ".", + "sUrl": "", + "sZeroRecords": "Δεν βρέθηκαν εγγραφές που να ταιριάζουν", + "oPaginate": { + "sFirst": "Πρώτη", + "sPrevious": "<", + "sNext": ">", + "sLast": "Τελευταία" + }, + "oAria": { + "sSortAscending": ": ενεργοποιήστε για αύξουσα ταξινόμηση της στήλης", + "sSortDescending": ": ενεργοποιήστε για φθίνουσα ταξινόμηση της στήλης" + } +} diff --git a/public/assets/js/panel/info.js b/public/assets/js/panel/info.js new file mode 100644 index 0000000..d046e1f --- /dev/null +++ b/public/assets/js/panel/info.js @@ -0,0 +1 @@ +// null
\ No newline at end of file diff --git a/public/assets/js/panel/own_petitions.js b/public/assets/js/panel/own_petitions.js new file mode 100644 index 0000000..84121e6 --- /dev/null +++ b/public/assets/js/panel/own_petitions.js @@ -0,0 +1,183 @@ +// Globals +// ----------------------------------------------------------------------------- +var petitions = []; +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; + }; +} + + +// return petitions record by petition-id +// --- -- -- - - - +function petition_record(id) { + var record = false; + petitions.forEach(el => { if (el.id == id) record = el; }); + + return record; +} + + +// create actions html (edit and delete buttons) +// --- -- -- - - - +function create_actions_html(signature) { + + var del, edit, show; + + del = ""; + edit = ""; + + show = [ + '<a type="button" target="_blank" class="btn btn-xs btn-warning"', + 'href="/petition/signature/'+ signature +'">', + '<i class="fa-regular fa-circle-down"></i>', + '</a>' + ].join('\n'); + + return show +' '+ 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( "/user/get/petitions") + .done(function( json ) { + // then ... + console.log(json); + + // reset categories + petitions.length = 0; + + // construct petitions data + json.data.forEach( el => { + petitions.push({ + id: parseInt(el.id), + subject: el.subject, + protocol: el.protocol, + signature: el.signature, + datepost: el.creation_date, + actions: create_actions_html(el.signature) + }); + }); + + + // destroy previous datatable table instances + $('#dt-petitions').dataTable().fnClearTable(); + $('#dt-petitions').dataTable().fnDestroy(); + + // (re-)create categories datatable + table = $('#dt-petitions').DataTable({ + language: { url: '/assets/js/DataTables/localization/Greek.json' }, + data: petitions, + // ordering: false, + columns: [ + { data: 'subject', width: '55%' }, + { data: 'protocol' }, + // { data: 'signature' }, + { data: 'datepost' }, + { 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 + }) + + + + // 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 + }); + + }); + +}); |
