diff --git a/kodorvan/site/system/controllers/index.php b/kodorvan/site/system/controllers/index.php index 31fc81e..7cdc845 100755 --- a/kodorvan/site/system/controllers/index.php +++ b/kodorvan/site/system/controllers/index.php @@ -250,6 +250,7 @@ final class index extends core $page = $this->view->render( 'pages/index.html', [ + 'uri' => 'https://' . DOMAIN, 'smartphone' => $this->request->smartphone, 'tablet' => $this->request->tablet ] diff --git a/kodorvan/site/system/controllers/offer.php b/kodorvan/site/system/controllers/offer.php index 3903061..1235d54 100755 --- a/kodorvan/site/system/controllers/offer.php +++ b/kodorvan/site/system/controllers/offer.php @@ -48,6 +48,7 @@ final class offer extends core $page = $this->view->render( 'pages/offer.html', [ + 'uri' => 'https://' . DOMAIN . '/offer', 'smartphone' => $this->request->smartphone, 'tablet' => $this->request->tablet ] diff --git a/kodorvan/site/system/controllers/superpack.php b/kodorvan/site/system/controllers/superpack.php index a05fbe7..d037db2 100755 --- a/kodorvan/site/system/controllers/superpack.php +++ b/kodorvan/site/system/controllers/superpack.php @@ -6,10 +6,11 @@ namespace kodorvan\site\controllers; // Files of the project use kodorvan\site\controllers\core, - kodorvan\site\models\superpack; + kodorvan\site\models\superpack as model; // Framework for PHP use mirzaev\minimal\http\enumerations\content, + mirzaev\minimal\http\enumerations\method, mirzaev\minimal\http\enumerations\status; // Baza database @@ -53,17 +54,18 @@ final class superpack extends core // Request for HTML response // Initializing the superpack - $superpack = new superpack()->read(filter: fn(record $record) => $record->urn === $urn && $record->active === 1); + $superpack = new model()->read(filter: fn(record $record) => $record->urn === $urn && $record->active === 1); - if ($superpack instanceof superpack) { + if ($superpack instanceof model) { // Initialized the superpack // Render page $page = $this->view->render( 'pages/article.html', [ + 'uri' => 'https://' . DOMAIN . "/superpack/$urn", 'article' => [ - 'urn' => $urn, + 'urn' => $superpack->urn, 'title' => $superpack->title, 'html' => $superpack->html ], @@ -95,4 +97,88 @@ final class superpack extends core // Exit (fail) return null; } + + /** + * Page: superpack + * + * @return null + */ + public function create( + ?string $identifier = null, + ?string $urn = null, + ?string $title = null, + ?string $html = null, + ?string $text = null, + string|int|float|null $supercost = null + ): null { + if ($this->request->method === method::get) { + // GET + + if (str_contains($this->request->headers['accept'] ?? '', content::html->value)) { + // Request for HTML response + + // Render page + $page = $this->view->render( + 'pages/system/superpack/create.html', + [ + 'uri' => 'https://' . DOMAIN . "/system/superpack/create", + 'smartphone' => $this->request->smartphone, + 'tablet' => $this->request->tablet + ] + ); + + // Sending response + $this->response + ->start() + ->clean() + ->sse() + ->write($page) + ->validate($this->request) + ?->body() + ->end(); + + // Deinitializing rendered page + unset($page); + + // Exit (success) + return null; + } + } else if ($this->request->method === method::put) { + // PUT + + // Initializing the superpack + $superpack = new model()->read(filter: fn(record $record) => $record->urn === $urn); + + if ($superpack instanceof model) { + // The superpack is already created + + } else { + // The superpack is not already created + + // Sanitizing + $urn = preg_replace('/[^\w\d\-.]+/', '', $urn); + $title = preg_replace('/[^\w\d\s\-.,!]+/u', '', $title); + $supercost = (float) preg_replace('/[^\d.]+/', '', $supercost); + + // Creating the superpack + $superpack = new model()->write( + urn: $urn, + title: $title, + html: $html, + text: $text, + supercost: $supercost + ); + + if ($superpack instanceof record) { + // Created the superpack + + // Sending redirect to the superpack + header('Location: /superpack/' . $urn); + } + } + } + + // Exit (fail) + return null; + } } diff --git a/kodorvan/site/system/models/superpack.php b/kodorvan/site/system/models/superpack.php index 8ae25d7..db8f90e 100644 --- a/kodorvan/site/system/models/superpack.php +++ b/kodorvan/site/system/models/superpack.php @@ -74,11 +74,11 @@ final class superpack extends core implements record_interface ->columns( new column('identifier', type::long_long_unsigned), /* new column('account', type::long_long_unsigned), */ - new column('urn', type::long_long_unsigned), - new column('title', type::string, ['length' => 64]), + new column('urn', type::string, ['length' => 64]), + new column('title', type::string, ['length' => 128]), new column('html', type::string, ['length' => 8192]), new column('text', type::string, ['length' => 8192]), - new column('supercost', type::integer_unsigned), + new column('supercost', type::float), new column('active', type::char), new column('updated', type::integer_unsigned), new column('created', type::integer_unsigned) @@ -99,7 +99,7 @@ final class superpack extends core implements record_interface * @param string $title Title * @param string|null $html Content (HTML) * @param string|null $html Content (text) - * @param int $supercost Cost + * @param int|float|null $supercost Cost * @param int $active Is the record active? * * @return record|false The record, if created @@ -110,7 +110,7 @@ final class superpack extends core implements record_interface string $title, ?string $html = null, ?string $text = null, - ?int $supercost = null, + int|float|null $supercost = null, bool $active = true, ): record|false { if (!empty($html) || !empty($text)) { @@ -122,7 +122,7 @@ final class superpack extends core implements record_interface $title, (string) $html, (string) $text, - (int) $supercost, + (float) $supercost, (int) $active, svoboda::timestamp(), svoboda::timestamp() diff --git a/kodorvan/site/system/public/index.php b/kodorvan/site/system/public/index.php index 3f0d94d..fe26649 100755 --- a/kodorvan/site/system/public/index.php +++ b/kodorvan/site/system/public/index.php @@ -50,6 +50,8 @@ $core->router ->write('/policy', new route('policy', 'index'), 'GET') ->write('/recomendations', new route('recomendations', 'index'), 'GET') + ->write('/system/superpack/create', new route('superpack', 'create'), 'GET') + ->write('/system/superpack/create', new route('superpack', 'create'), 'PUT') ->write('/superpack/$urn', new route('superpack', 'index'), 'GET') ->write('/project/request', new route('project', 'request'), 'PUT') diff --git a/kodorvan/site/system/public/js/core.js b/kodorvan/site/system/public/js/core.js index f760d0f..42ad505 100644 --- a/kodorvan/site/system/public/js/core.js +++ b/kodorvan/site/system/public/js/core.js @@ -10,6 +10,20 @@ * @author Arsen Mirzaev Tatyano-Muradovich */ class core { + /** + * @name Global modules + * + * @type {object} + */ + static global = {}; + + /** + * @name System modules + * + * @type {object} + */ + static system = {}; + // Domain static domain = window.location.hostname; @@ -125,7 +139,7 @@ class core { * * @return {void} */ - /* static choose = core.damper( + /* static choose = core.global.damper( ( title = "Выбор действия", text = "", @@ -299,32 +313,50 @@ Object.assign( /** * @name Connect modules * - * @param {(Array|string)} modules Names of modules without extension (`.mjs` only) + * @param {(Array|string)} global Names of global modules without extension (`.mjs` only) + * @param {(Array|string)} system Names of system modules without extenstion (`.mjs` only) * * @return {Promise} */ - async connect(modules) { + async connect(global, system) { // Normalisation required arguments - if (typeof modules === "string") modules = [modules]; + if (typeof global === "string") global = [global]; + if (typeof system === "string") system = [system]; - if (modules instanceof Array) { - // Received and validated required arguments + // Initializing the registry of connected modules + const connected = { + system: [], + global: [] + }; - // Initializing the registry of connected modules - const connected = []; + if (global?.length > 0) { + // Global - for (const module of modules) { - // Iterating over modules + for (const module of global) { + // Iterating over global modules - // Downloading, importing and writing the module into a core property and into registry of connected modules - core[module] = - connected[module] = + // Downloading, importing and writing the global module into a core property and into registry of connected modules + core.global[module] = + connected.global[module] = await (await import(`./modules/${module}.mjs`)).default; } - - // Exit (success) - return connected; } + + if (system?.length > 0) { + // System + + for (const module of system) { + // Iterating over system modules + + // Downloading, importing and writing the system module into a core property and into registry of connected modules + core.system[module] = + connected.system[module] = + await (await import(`./modules/system/${module}.mjs`)).default; + } + } + + // Exit (success) + return connected; }, }, ); @@ -347,7 +379,7 @@ core.modules.connect("damper").then(() => { * * @return {Promise} */ - damper: core.damper( + damper: core.global.damper( (...variables) => core.buffer.write.system(...variables), 300, 2, diff --git a/kodorvan/site/system/public/js/modules/paginator.mjs b/kodorvan/site/system/public/js/modules/paginator.mjs index ee6883c..2e1304b 100644 --- a/kodorvan/site/system/public/js/modules/paginator.mjs +++ b/kodorvan/site/system/public/js/modules/paginator.mjs @@ -72,6 +72,37 @@ export default class paginator { */ #page = 1; + /** + * @name Page (get) + * + * @return {number} + * + * @public + */ + get page() { + return this.#page; + } + + /** + * @name The initial page + * + * @type {number} + * + * @protected + */ + #initial = 1; + + /** + * @name The initial page (get) + * + * @return {number} + * + * @public + */ + get initial() { + return this.#initial; + } + /** * @name Constructor * @@ -79,16 +110,14 @@ export default class paginator { * Initialize a hotline instance * * @param {HTMLElement} shell The shell element - * @param {NodeList} pages - * @param {Set} hide_on_the_first_page HTML-elements that will be hidden on the first page - * @param {Set} hide_on_the_last_page HTML-elements that will be hidden on the last page + * @param {NodeList} pages The pages HTML-elements list + * @param {number} initial The initial page identifier * @param {boolean} [inject=false] Write the hotline instance into the shell element? **/ constructor( shell, pages, - hide_on_the_first_page, - hide_on_the_last_page, + initial, inject = false ) { if (shell instanceof HTMLElement) { @@ -102,11 +131,18 @@ export default class paginator { } if (pages instanceof NodeList) { - // Initialized pages + // Initialized the pages HTML-elements list - // Writing the pages + // Writing the pages HTML-elements list this.#pages = pages; } + + if (typeof initial === 'number') { + // Initialized the initial page identifier + + // Writing the initial page identifier + this.#page = this.#initial = initial; + } } /** diff --git a/kodorvan/site/system/public/js/modules/project.mjs b/kodorvan/site/system/public/js/modules/project.mjs index 44a2a83..b681c2c 100644 --- a/kodorvan/site/system/public/js/modules/project.mjs +++ b/kodorvan/site/system/public/js/modules/project.mjs @@ -1896,7 +1896,7 @@ export default class project { * * @return {void} */ - damper: core.damper( + damper: core.global.damper( (...variables) => this.send.system(...variables), 300, 2, @@ -2153,20 +2153,32 @@ export default class project { // Initializing the result HTML-element const result = this.#elements.get('result'); - // Showing the result HTML-element - result.style.removeProperty('display'); + if (result instanceof HTMLElement) { + // Initialized the result HTML-element + + // Showing the result HTML-element + result.style.removeProperty('display'); + } // Initializing the hours HTML-element const output = this.#elements.get('hours_output'); - // Writing into the hours output HTML-element - output.innerText = hours; + if (output instanceof HTMLElement) { + // Initialized the hours HTML-element + + // Writing into the hours output HTML-element + output.innerText = hours; + } // Initializing the hours wrap HTML-element const wrap = this.#elements.get('hours'); - // Showing the hours wrap HTML-element - wrap.style.removeProperty('display'); + if (wrap instanceof HTMLElement) { + // Initialized the hours wrap HTML-element + + // Showing the hours wrap HTML-element + wrap.style.removeProperty('display'); + } } // Exit (success) @@ -2197,8 +2209,12 @@ export default class project { // Initializing the days HTML-element const output = this.#elements.get('days_output'); - // Writing into the days output HTML-element - output.innerText = days; + if (output instanceof HTMLElement) { + // Initialized the days HTML-element + + // Writing into the days output HTML-element + output.innerText = days; + } } // Exit (success) @@ -2256,24 +2272,52 @@ export default class project { // Initializing the result HTML-element const result = this.#elements.get('result'); - // Showing the result HTML-element - result.style.removeProperty('display'); + if (result instanceof HTMLElement) { + // Initialized the result HTML-element - // Initializing the output HTML-elements + // Showing the result HTML-element + result.style.removeProperty('display'); + } + + // Initializing the payment output HTML-element const payment_output = this.#elements.get('payment_output'); + + if (payment_output instanceof HTMLElement) { + // Initialized the payment output HTML-element + + // Writing into the payment output HTML-element + payment_output.innerText = new Intl.NumberFormat("ru-RU", { maximumSignificantDigits: 3 }).format(costs.full); + } + + // Initializing the prepayment output HTML-element const prepayment_output = this.#elements.get('prepayment_output'); - // Writing into the output HTML-elements - payment_output.innerText = new Intl.NumberFormat("ru-RU", { maximumSignificantDigits: 3 }).format(costs.full); - prepayment_output.innerText = new Intl.NumberFormat("ru-RU", { maximumSignificantDigits: 3 }).format(costs.prepayment); + if (prepayment_output instanceof HTMLElement) { + // Initialized the prepayment output HTML-element - // Initializing the wrap HTML-elements + // Writing into the prepayment output HTML-element + prepayment_output.innerText = new Intl.NumberFormat("ru-RU", { maximumSignificantDigits: 3 }).format(costs.prepayment); + } + + // Initializing the payment wrap HTML-element const payment_wrap = this.#elements.get('payment'); + + if (payment_wrap instanceof HTMLElement) { + // Initialized the payment wrap HTML-element + + // Showing the payment wrap HTML-element + payment_wrap.style.removeProperty('display'); + } + + // Initializing the prepayment wrap HTML-element const prepayment_wrap = this.#elements.get('prepayment'); - // Showing the wrap HTML-elements - payment_wrap.style.removeProperty('display'); - prepayment_wrap.style.removeProperty('display'); + if (prepayment_wrap instanceof HTMLElement) { + // Initialized the prepayment wrap HTML-element + + // Showing the prepayment wrap HTML-element + prepayment_wrap.style.removeProperty('display'); + } } // Exit (success) diff --git a/kodorvan/site/system/public/js/modules/system/superpack.mjs b/kodorvan/site/system/public/js/modules/system/superpack.mjs new file mode 100644 index 0000000..711dffc --- /dev/null +++ b/kodorvan/site/system/public/js/modules/system/superpack.mjs @@ -0,0 +1,552 @@ +/** @module superpack */ + +"use strict"; + +/** + * @name superpack.mjs + * + * @description + * Module for creating superpacks + * + * @class + * @public + * + * {@link https://git.mirzaev.sexy/mirzaev/superpack.mjs} + * + * @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License + * @author Arsen Mirzaev Tatyano-Muradovich + */ +export default class superpack { + /** + * @name Shell + * + * @description + * Shell of all elements, top-level parent HTML-element + * + * @type {HTMLElement} + * + * @protected + */ + #shell; + + /** + * @name Elements + * + * @description + * Calculation steps shell elements + * + * @type {Map} + * + * @protected + */ + #elements = new Map(); + + /** + * @name Elements (get) + * + * @description + * Getter for `this.#elements` + * + * @return {Map} + * + * @public + */ + get elements() { + return this.#elements; + } + + /** + * @name stages + * + * @description + * Active stages for guide + * + * @return {Set} + * + * @protected + */ + #stages = new Set(); + + /** + * @name Stages (get) + * + * @description + * Getter for `this.#stages` + * + * @return {Set} + * + * @public + */ + get stages() { + return this.#stages; + } + + /** + * @name Shell (get) + * + * @description + * Getter for `this.#shell` + * + * @return {HTMLElement} + * + * @public + */ + get shell() { + return this.#shell; + } + + /** + * @name URN + * + * @description + * The superpack URN (https://kodorvan.tech/superpack/{URN}) + * + * @type {string} + * + * @protected + */ + #urn = ''; + + /** + * @name URN (set) + * + * @description + * Setter for `this.#urn` + * + * @public + */ + set urn(value) { + // Writing into the hour cost + this.#urn = value; + + // Dispatching event: "system.superpack.write" + this.#shell.dispatchEvent( + new CustomEvent("system.superpack.write", { + detail: { name: 'urn', value: value } + }) + ); + + if (this.#urn.length > 0) { + // Has a value + + // Deleting from the stages registry + this.#stages.delete('urn'); + } else { + // Has no value + + // Writing into the stages registry + this.#stages.add('urn'); + } + + // Reinitializing guide HTML-elements + this.guide(); + } + + /** + * @name Title + * + * @description + * The superpack title + * + * @type {string} + * + * @protected + */ + #title = ''; + + /** + * @name Title (set) + * + * @description + * Setter for `this.#title` + * + * @public + */ + set title(value) { + // Writing into the hour cost + this.#title = value; + + // Dispatching event: "system.superpack.write" + this.#shell.dispatchEvent( + new CustomEvent("system.superpack.write", { + detail: { name: 'title', value: value } + }) + ); + + if (this.#title.length > 0) { + // Has a value + + // Deleting from the stages registry + this.#stages.delete('title'); + } else { + // Has no value + + // Writing into the stages registry + this.#stages.add('title'); + } + + // Reinitializing guide HTML-elements + this.guide(); + } + + /** + * @name HTML + * + * @description + * The superpack content (HTML) + * + * @type {string} + * + * @protected + */ + #html = ''; + + /** + * @name HTML (set) + * + * @description + * Setter for `this.#html` + * + * @public + */ + set html(value) { + // Writing into the hour cost + this.#html = value; + + // Dispatching event: "system.superpack.write" + this.#shell.dispatchEvent( + new CustomEvent("system.superpack.write", { + detail: { name: 'html', value: value } + }) + ); + + if (this.#html.length > 0) { + // Has a value + + // Deleting from the stages registry + this.#stages.delete('html'); + } else { + // Has no value + + // Writing into the stages registry + this.#stages.add('html'); + } + + // Reinitializing guide HTML-elements + this.guide(); + } + + /** + * @name Text + * + * @description + * The superpack content (text) + * + * @type {string} + * + * @protected + */ + #text = ''; + + /** + * @name Text (set) + * + * @description + * Setter for `this.#text` + * + * @public + */ + set text(value) { + // Writing into the hour cost + this.#text = value; + + // Dispatching event: "system.superpack.write" + this.#shell.dispatchEvent( + new CustomEvent("system.superpack.write", { + detail: { name: 'text', value: value } + }) + ); + + if (this.#text.length > 0) { + // Has a value + + // Deleting from the stages registry + this.#stages.delete('text'); + } else { + // Has no value + + // Writing into the stages registry + this.#stages.add('text'); + } + + // Reinitializing guide text-elements + this.guide(); + } + + /** + * @name Supercost + * + * @description + * The superpack content (supercost) + * + * @type {number} + * + * @protected + */ + #supercost = 0; + + /** + * @name Supercost (set) + * + * @description + * Setter for `this.#supercost` + * + * @public + */ + set supercost(value) { + // Writing into the hour cost + this.#supercost = value; + + // Dispatching event: "system.superpack.write" + this.#shell.dispatchEvent( + new CustomEvent("system.superpack.write", { + detail: { name: 'supercost', value: value } + }) + ); + + if (this.#supercost > 0) { + // Has a value + + // Deleting from the stages registry + this.#stages.delete('supercost'); + } else { + // Has no value + + // Writing into the stages registry + this.#stages.add('supercost'); + } + + // Reinitializing guide supercost-elements + this.guide(); + } + + /** + * @name Constructor + * + * @description + * Initialize an instance + * + * @param {HTMLElement} shell The shell element + **/ + constructor( + shell, + urn, + title, + html, + text, + supercost + ) { + if (shell instanceof HTMLElement) { + // Initialized the shell + + // Writing the shell HTML-element + this.#shell = shell; + + if (urn instanceof HTMLElement) this.#elements.set('urn', urn); + if (title instanceof HTMLElement) this.#elements.set('title', title); + if (html instanceof HTMLElement) this.#elements.set('html', html); + if (text instanceof HTMLElement) this.#elements.set('text', text); + if (supercost instanceof HTMLElement) this.#elements.set('supercost', supercost); + + Object.assign( + this.send, + { + /** + * @name Send (system) + * + * @description + * Send the superpack data to the server + * + * @memberof superpack.send + * + * @return {void} + */ + async system(request, resolve, reject) { + try { + if ( + // typeof identifier === "string" || + true + ) { + // Validated all required arguments + + return await core.request( + "/system/superpack/create", + request, + "PUT", + ).then( + async (json) => { + if (json) { + // Received a JSON-response + + if ( + json.errors !== null && + typeof json.errors === "object" && + json.errors.length > 0 + ) { + // Fail (received errors) + + // Exit (fail) + reject(json); + } else { + // Success (not received errors) + + // Reloading the page @todo make something smarter + alert("Запрос доставлен"); + + // Exit (success) + resolve(); + } + } + }, + () => reject(), + ); + } + } catch (e) { + console.log(e); + + } + } + } + ); + + core?.modules.connect("damper").then((connected) => { + // Imported the damper.mjs module + + Object.assign( + this.send, + { + /** + * @name Send (damper) + * + * @description + * Send the superpack data to the server + * + * @memberof superpack.send + * + * @param {booleanean} [force=false] Ignore the damper? + * + * @return {void} + */ + damper: core.damper( + (...variables) => this.send.system(...variables), + 300, + 2, + ), + } + ); + }); + } + } + + /** + * @name Guide + * + * @description + * Set user interface help elements + * + * @param {(string|Set)} stages + * + * @public + **/ + guide(stages) { + if (stages !== undefined) { + // Received stages + + if (stages instanceof Set) { + // Set + + // Reinitializing stages + this.#stages = stages; + } else { + // String (expected) + + // Writing into stages + this.#stages.add(stages); + } + } + + for (const [parameter, element] of this.#elements) { + // Iterating over elements + + // Initializing the guide HTML-element + const guide = element.querySelector('.guide'); + + if (guide instanceof HTMLElement) { + // Initialized the guide HTML-element + + // Initializing the input HTML-element + const input = element.querySelector('.input'); + + if (input.value == "" || this.#stages.has(parameter)) { + // Requested guide + + // Showing the guide + guide.classList.add('active'); + } else { + // Not requested guide + + // Hiding the guide + guide.classList.remove('active'); + } + } + } + } + + /** + * @name Pack + * + * @description + * Compose the superpack parameters + * + * @public + * + * @returns {string} Parameters row for `application/x-www-form-urlencoded` + */ + pack() { + // Exit (success) + return "identifier=" + encodeURIComponent(new Date().valueOf()) + + "&urn=" + encodeURIComponent(this.#urn) + + "&title=" + encodeURIComponent(this.#title) + + "&html=" + encodeURIComponent(this.#html) + + "&text=" + encodeURIComponent(this.#text) + + "&supercost=" + encodeURIComponent(this.#supercost) + ; + } + + /** + * @name Send + * + * @description + * Compose the superpack and send to the server + * + * @public + * + * @param {boolean} [force=false] Ignore the damper? + */ + send(force = false) { + core.modules.connect("damper").then( + () => { + // Imported the damper module + + // Processing under damper + this.send.damper(this.pack(), force); + }, + () => { + // Not imported the damper module + + // Processing + this.send.system(this.pack()); + }, + ); + } +} diff --git a/kodorvan/site/system/public/js/pages/main.js b/kodorvan/site/system/public/js/pages/main.js index 675b701..9b28f4f 100755 --- a/kodorvan/site/system/public/js/pages/main.js +++ b/kodorvan/site/system/public/js/pages/main.js @@ -10,28 +10,28 @@ core.modules.connect(["damper", "project"]).then((connected) => { const files = document.getElementById("project_files"); // Initializing the instance of the project.mjs - core.project = new connected.project( - document.querySelector('section[data-paginator-page="1"]'), - document.getElementById("architecture"), - document.getElementById("purpose"), - document.getElementById("integrations"), - document.getElementById("team"), - document.getElementById("programmers"), - document.getElementById("designers"), - document.getElementById("boosters"), - document.getElementById("reward"), - document.getElementById("hour"), - document.getElementById("hour_input_number"), - document.getElementById("hour_input_range"), - document.getElementById("result"), - document.getElementById("calculated"), - document.getElementById("hours"), - document.getElementById("hours_output"), - document.getElementById("days_output"), - document.getElementById("payment"), - document.getElementById("payment_output"), - document.getElementById("prepayment"), - document.getElementById("prepayment_output"), + core.global.project = new connected.global.project( + document.querySelector('section[data-paginator-page="2"]'), + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, document.getElementById("project_name"), document.getElementById("project_description"), files, @@ -43,23 +43,6 @@ core.modules.connect(["damper", "project"]).then((connected) => { true ); - // Initializing the hour input number HTML-element - const hour_number = document.getElementById('hour_input_number'); - - // Initializing the hour input range HTML-element - const hour_range = document.getElementById('hour_input_range'); - - hour_range.addEventListener("input", () => { - hour_inputs_syncronize(hour_range, hour_number); - }); - - function hour_inputs_syncronize(range, number) { - const min = range.min ? range.min : 300; - const max = range.max ? range.max : 5000; - - number.value = range.value; - } - // Initializing the "back" button const back = document.getElementById('back'); @@ -70,17 +53,18 @@ core.modules.connect(["damper", "project"]).then((connected) => { const pages = document.querySelectorAll('section[data-paginator-page]'); // Initializing the instance of the paginator.mjs - core.paginator = new connected.paginator( + core.global.paginator = new connected.global.paginator( document.getElementById('buttons'), - pages + pages, + 2 ); // Initializing the buttons - const buttons = core.paginator.shell.querySelectorAll('button[data-paginator-page-button]'); + const buttons = core.global.paginator.shell.querySelectorAll('button[data-paginator-page-button]'); function menu(identifier) { // Initializing the target page button HTML-element - const active = core.paginator.shell.querySelector('button[data-paginator-page-button="' + identifier + '"]'); + const active = core.global.paginator.shell.querySelector('button[data-paginator-page-button="' + identifier + '"]'); if (active instanceof HTMLElement) { // Initialized the target page button HTML-element @@ -95,7 +79,7 @@ core.modules.connect(["damper", "project"]).then((connected) => { // Showing the target page button HTML-element active.style.removeProperty('display'); - if (identifier > 1) { + if (identifier > core.global.paginator.initial) { // Second or more page // Showing the "back" button @@ -109,58 +93,58 @@ core.modules.connect(["damper", "project"]).then((connected) => { } } + // Initializing the page buttons menu + core.global.paginator.shell.addEventListener("paginator.page.opened", function (event) { + // Scrolling to the introdution HTML-element + introdution?.scrollIntoView({ behavior: 'smooth' }); + + // Initializing the page buttons menu + menu(event.detail.identifier); + }); + // Connecting event listener for project calculation - core.project.shell.addEventListener("project.write", function() { - // Initializing the "calculator" page button HTML-element - const calculator = core.paginator.shell.querySelector('button[data-paginator-page-button="1"]'); - - if (calculator instanceof HTMLElement) { - // Initialized the "calculator" page button HTML-element - - // Showing or hiding the "calculator" page button HTML-element - calculator.disabled = !(core.project.architecture != null); - } + core.global.project.shell.addEventListener("project.write", function() { // Initializing the "project" page button HTML-element - const project = core.paginator.shell.querySelector('button[data-paginator-page-button="2"]'); + const project = core.global.paginator.shell.querySelector('button[data-paginator-page-button="2"]'); if (project instanceof HTMLElement) { // Initialized the "project" page button HTML-element // Showing or hiding the "project" page button HTML-element project.disabled = - !(core.project.project.name + !(core.global.project.project.name && ( - core.project.project.description != null - || core.project.project.files.length > 0 + core.global.project.project.description != null + || core.global.project.project.files.length > 0 )); } // Initializing the "requester" page button HTML-element - const requester = core.paginator.shell.querySelector('button[data-paginator-page-button="3"]'); + const requester = core.global.paginator.shell.querySelector('button[data-paginator-page-button="3"]'); if (requester instanceof HTMLElement) { // Initialized the "requester" page button HTML-element // Showing or hiding the "requester" page button HTML-element requester.disabled = - !(core.project.requester.personal + !(core.global.project.requester.personal && ( - core.project.requester.sim != null - || core.project.requester.mail != null - || core.project.requester.other != null + core.global.project.requester.sim != null + || core.global.project.requester.mail != null + || core.global.project.requester.other != null )); } }); // Connecting event listener for project calculation - core.project.shell.addEventListener("project.calculated", function() { + core.global.project.shell.addEventListener("project.calculated", function() { // Showing the buttons HTML-element - core.paginator.shell?.style.removeProperty('display'); + core.global.paginator.shell?.style.removeProperty('display'); }); // Initializing the page buttons menu - core.paginator.shell.addEventListener("paginator.page.opened", function (event) { + core.global.paginator.shell.addEventListener("paginator.page.opened", function (event) { // Scrolling to the introdution HTML-element introdution?.scrollIntoView({ behavior: 'smooth' }); @@ -215,7 +199,7 @@ core.modules.connect(["damper", "project"]).then((connected) => { const index = Array.from(list.children).indexOf(element); // Initializing the actual list of files - let files = core.project.project.files; + let files = core.global.project.project.files; // Deleting the file files.splice(index, 1); @@ -224,7 +208,7 @@ core.modules.connect(["damper", "project"]).then((connected) => { element.remove(); // Writing into the project property - core.project.project.files = files; + core.global.project.project.files = files; }) // Initializing the file label delete button image @@ -247,5 +231,5 @@ core.modules.connect(["damper", "project"]).then((connected) => { } }) - core.project.shell.parentElement.classList.remove('loading'); + core.global.project.shell.parentElement.classList.remove('loading'); }); diff --git a/kodorvan/site/system/public/js/pages/project/create.js b/kodorvan/site/system/public/js/pages/project/create.js new file mode 100755 index 0000000..ad3d835 --- /dev/null +++ b/kodorvan/site/system/public/js/pages/project/create.js @@ -0,0 +1,251 @@ +"use strict"; + +core.modules.connect(["damper", "project"]).then((connected) => { + // Imported modules + + // Initializing the introdution HTML-element + const introdution = document.getElementById('introdution'); + + // Initializing the files input wrap HTML-element + const files = document.getElementById("project_files"); + + // Initializing the instance of the project.mjs + core.global.project = new connected.global.project( + document.querySelector('section[data-paginator-page="1"]'), + document.getElementById("architecture"), + document.getElementById("purpose"), + document.getElementById("integrations"), + document.getElementById("team"), + document.getElementById("programmers"), + document.getElementById("designers"), + document.getElementById("boosters"), + document.getElementById("reward"), + document.getElementById("hour"), + document.getElementById("hour_input_number"), + document.getElementById("hour_input_range"), + document.getElementById("result"), + document.getElementById("calculated"), + document.getElementById("hours"), + document.getElementById("hours_output"), + document.getElementById("days_output"), + document.getElementById("payment"), + document.getElementById("payment_output"), + document.getElementById("prepayment"), + document.getElementById("prepayment_output"), + document.getElementById("project_name"), + document.getElementById("project_description"), + files, + document.getElementById("requester_name"), + document.getElementById("requester_sim"), + document.getElementById("requester_mail"), + document.getElementById("requester_other"), + document.getElementById("requester_personal"), + true + ); + + // Initializing the hour input number HTML-element + const hour_number = document.getElementById('hour_input_number'); + + // Initializing the hour input range HTML-element + const hour_range = document.getElementById('hour_input_range'); + + hour_range.addEventListener("input", () => { + hour_inputs_syncronize(hour_range, hour_number); + }); + + function hour_inputs_syncronize(range, number) { + const min = range.min ? range.min : 300; + const max = range.max ? range.max : 5000; + + number.value = range.value; + } + + // Initializing the "back" button + const back = document.getElementById('back'); + + core.modules.connect(["paginator"]).then((connected) => { + // Imported the paginator.mjs module + + // Initializing pages + const pages = document.querySelectorAll('section[data-paginator-page]'); + + // Initializing the instance of the paginator.mjs + core.global.paginator = new connected.global.paginator( + document.getElementById('buttons'), + pages + ); + + // Initializing the buttons + const buttons = core.global.paginator.shell.querySelectorAll('button[data-paginator-page-button]'); + + function menu(identifier) { + // Initializing the target page button HTML-element + const active = core.global.paginator.shell.querySelector('button[data-paginator-page-button="' + identifier + '"]'); + + if (active instanceof HTMLElement) { + // Initialized the target page button HTML-element + + for (const inactive of buttons) { + // Iteration over pages + + // Hiding the page button HTML-element + inactive.style.setProperty('display', 'none'); + } + + // Showing the target page button HTML-element + active.style.removeProperty('display'); + + if (identifier > 1) { + // Second or more page + + // Showing the "back" button + back.style.removeProperty('display'); + } else { + // The first page + + // Hiding the "back" button + back.style.setProperty('display', 'none'); + } + } + } + + // Connecting event listener for project calculation + core.global.project.shell.addEventListener("project.write", function() { + // Initializing the "calculator" page button HTML-element + const calculator = core.global.paginator.shell.querySelector('button[data-paginator-page-button="1"]'); + + if (calculator instanceof HTMLElement) { + // Initialized the "calculator" page button HTML-element + + // Showing or hiding the "calculator" page button HTML-element + calculator.disabled = !(core.global.project.architecture != null); + } + + // Initializing the "project" page button HTML-element + const project = core.global.paginator.shell.querySelector('button[data-paginator-page-button="2"]'); + + if (project instanceof HTMLElement) { + // Initialized the "project" page button HTML-element + + // Showing or hiding the "project" page button HTML-element + project.disabled = + !(core.global.project.project.name + && ( + core.global.project.project.description != null + || core.global.project.project.files.length > 0 + )); + } + + // Initializing the "requester" page button HTML-element + const requester = core.global.paginator.shell.querySelector('button[data-paginator-page-button="3"]'); + + if (requester instanceof HTMLElement) { + // Initialized the "requester" page button HTML-element + + // Showing or hiding the "requester" page button HTML-element + requester.disabled = + !(core.global.project.requester.personal + && ( + core.global.project.requester.sim != null + || core.global.project.requester.mail != null + || core.global.project.requester.other != null + )); + } + }); + + // Connecting event listener for project calculation + core.global.project.shell.addEventListener("project.calculated", function() { + // Showing the buttons HTML-element + core.global.paginator.shell?.style.removeProperty('display'); + }); + + // Initializing the page buttons menu + core.global.paginator.shell.addEventListener("paginator.page.opened", function (event) { + // Scrolling to the introdution HTML-element + introdution?.scrollIntoView({ behavior: 'smooth' }); + + // Initializing the page buttons menu + menu(event.detail.identifier); + }); + }); + + // Initializing the files list HTML-element + const list = files.querySelector('ol.files'); + + // Initializing the files input HTML-element + const files_input = files.querySelector('.input'); + + files_input.addEventListener('input', (event) => { + // Deleting every file label from the list + list.innerHTML = ''; + + if (files_input.files.length > 0) { + // Has files + + // Showing the list HTML-element + list.style.removeProperty('display'); + + // Initializing the file index iterator + let index = 0; + + for (const file of files_input.files) { + // Iterating over files + + // Initializing the maximum length for the file label name + const maximum = 16; + + // Initializing the end tail for the file label name + const tail = 8; + + // Initializing the file label name + const name = file.name.length > maximum ? file.name.slice(0, maximum - tail).trim() + '...' + file.name.slice(-tail).trim() : file.name; + + // Initializing the file label HTML-element + const element = document.createElement('li'); + element.id = "project_files_input_" + index; + element.setAttribute('title', file.name); + element.innerText = name; + + // Initializing the file label delete button + const button = document.createElement('button'); + button.classList.add('delete'); + + button.addEventListener('click', (event) => { + // Initializing the file index + const index = Array.from(list.children).indexOf(element); + + // Initializing the actual list of files + let files = core.global.project.project.files; + + // Deleting the file + files.splice(index, 1); + + // Deleting the file label HTML-element + element.remove(); + + // Writing into the project property + core.global.project.project.files = files; + }) + + // Initializing the file label delete button image + const image = document.createElement('img'); + image.setAttribute('src', '/themes/default/images/icons/close.svg'); + + // Writing the file label into the list HTML-element + button.appendChild(image); + element.appendChild(button); + list.appendChild(element); + + // Recalculating the index (postfix-incrementation) + index++; + } + } else { + // Has no files + + // Hiding the list HTML-element + list.style.setProperty('display', 'none'); + } + }) + + core.global.project.shell.parentElement.classList.remove('loading'); +}); diff --git a/kodorvan/site/system/public/js/pages/system/superpack.js b/kodorvan/site/system/public/js/pages/system/superpack.js new file mode 100644 index 0000000..3330e09 --- /dev/null +++ b/kodorvan/site/system/public/js/pages/system/superpack.js @@ -0,0 +1,15 @@ +"use strict"; + +core.modules.connect(["damper"], ["superpack"]).then((connected) => { + // Imported modules + + // Initializing the instance of the project.mjs + core.system.superpack = new connected.system.superpack( + document.getElementById('superpack'), + document.getElementById('superpack_urn'), + document.getElementById('superpack_title'), + document.getElementById('superpack_html'), + document.getElementById('superpack_text'), + document.getElementById('superpack_supercost'), + ); +}); diff --git a/kodorvan/site/system/public/themes/default/css/elements/project.css b/kodorvan/site/system/public/themes/default/css/elements/project.css index 71d36ff..75bb32d 100755 --- a/kodorvan/site/system/public/themes/default/css/elements/project.css +++ b/kodorvan/site/system/public/themes/default/css/elements/project.css @@ -1,10 +1,11 @@ @charset "UTF-8"; section#project { - --width: 420px; + --margin-bottom: 0.8rem; + --width: 480px; z-index: 200; position: relative; - margin-top: 2rem; + margin-top: 3rem; margin-bottom: 5rem; min-width: var(--width); max-width: var(--width); @@ -32,6 +33,14 @@ section#project { margin-bottom: 0.5em; } + &+span { + margin-top: 0.2em; + margin-bottom: 1em; + text-align: center; + color: #e9e8e2; + text-shadow: 0px 1px 3px #000C, 0px 1px 1px #000B; + } + &+small { margin-bottom: 1em; text-align: center; @@ -67,6 +76,7 @@ section#project { --shadow: 0px 6px 6px -2px rgba(0, 0, 0, 0.5), 0px 0px 14px 5px rgba(0, 0, 0, 0.4); position: relative; padding: 2rem 1.4rem; + padding: 1.6rem 1.4rem; display: flex; flex-direction: column; gap: 1.4rem; @@ -854,7 +864,7 @@ section#project { --radius: calc(var(--diameter, 4ch) / 2); position: absolute; left: calc(-1.2rem - var(--diameter, 4ch)); - top: calc(7.4rem - var(--radius, 2ch)); + top: calc(10rem - var(--radius, 2ch)); width: var(--diameter, 4ch); height: var(--diameter, 4ch); display: flex; @@ -878,6 +888,7 @@ section#project { } >section#buttons { + margin-bottom: var(--margin-bottom, 0.8rem); flex-direction: row; justify-content: center; @@ -953,6 +964,63 @@ section#project { } } + >small.description { + padding: 0.9em 1.2em; + text-align: left; + font-family: Nunito; + font-size: 0.9em; + color: #d6c1c1; + background: #b3ced31a; + border-radius: 1.25rem; + border-top: 1px solid #84d1d526; + backdrop-filter: blur(2px) contrast(1.14); + /* text-shadow: 0px 1px 3px #000C, 0px 1px 1px #000B; */ + text-shadow: unset; + + >:is(strong, b) { + /* display: block; */ + font-weight: 600; + color: #ebdada; + } + } + + >small.guarantee { + padding: 0.9em 1.2em; + text-align: left; + font-family: Nunito; + font-size: 0.9em; + color: #d6c1c1; + background: #b3ced31a; + border-radius: 1.25rem; + border-top: 1px solid #84d1d526; + backdrop-filter: blur(2px) contrast(1.14); + /* text-shadow: 0px 1px 3px #000C, 0px 1px 1px #000B; */ + text-shadow: unset; + + >:is(strong, b) { + /* display: block; */ + font-weight: 600; + color: #ebdada; + } + } + + >b.partners { + margin-top: 1.2rem; + padding: 0 1em; + text-align: center; + font-family: Bahnschrift; + font-weight: 600; + font-size: 1.2em; + color: #d6c1c1; + text-shadow: 0px 1px 3px #000C, 0px 1px 1px #000B; + + >:is(strong, b) { + /* display: block; */ + font-weight: 600; + color: #ebdada; + } + } + >small.offer { margin-top: 1.2rem; padding: 0 1.5em; @@ -998,12 +1066,13 @@ section#project { } } -@media (width < 550px) { +@media (width < 700px) { section#project { --width: 100vw; padding: 0 2rem; >div.adaptive { + margin-bottom: var(--margin-bottom, 0.8rem); display: flex; flex-direction: row; gap: 1rem; @@ -1022,6 +1091,10 @@ section#project { height: auto; border-radius: 1.25rem; } + + >section#buttons { + margin-bottom: unset; + } } } } diff --git a/kodorvan/site/system/public/themes/default/css/elements/rofls.css b/kodorvan/site/system/public/themes/default/css/elements/rofls.css index fd4a1eb..f262f20 100755 --- a/kodorvan/site/system/public/themes/default/css/elements/rofls.css +++ b/kodorvan/site/system/public/themes/default/css/elements/rofls.css @@ -21,7 +21,7 @@ body { >article#rofls { z-index: 50; - width: min-content; + width: 100vw; height: 32px; display: flex; flex-direction: row; @@ -36,7 +36,11 @@ body { >img { margin: unset; height: 100%; - overflow: hidden; + cursor: grab; + + &:is(:active) { + cursor: grabbing; + } &:is(.noclick) { cursor: not-allowed; diff --git a/kodorvan/site/system/public/themes/default/css/footer.css b/kodorvan/site/system/public/themes/default/css/footer.css index f6cb60d..d179cb9 100755 --- a/kodorvan/site/system/public/themes/default/css/footer.css +++ b/kodorvan/site/system/public/themes/default/css/footer.css @@ -154,6 +154,7 @@ footer { >article.contacts { min-height: 100px; + padding-left: 2rem; display: flex; flex-direction: column; align-items: end; @@ -240,6 +241,7 @@ footer { } >article.contacts { + padding: unset; align-items: center; } } diff --git a/kodorvan/site/system/public/themes/default/css/interface/logotype.css b/kodorvan/site/system/public/themes/default/css/interface/logotype.css index 633552d..49f9704 100644 --- a/kodorvan/site/system/public/themes/default/css/interface/logotype.css +++ b/kodorvan/site/system/public/themes/default/css/interface/logotype.css @@ -1,7 +1,7 @@ h1#logotype { z-index: 200; margin: unset; - margin-top: 4rem; + margin-top: 6rem; margin-bottom: 2rem; width: max-content; display: flex; diff --git a/kodorvan/site/system/public/themes/default/css/main.css b/kodorvan/site/system/public/themes/default/css/main.css index 425c48a..aa92530 100755 --- a/kodorvan/site/system/public/themes/default/css/main.css +++ b/kodorvan/site/system/public/themes/default/css/main.css @@ -5,6 +5,7 @@ main { --scroll-px-hundred: calc(var(--scroll-px-ten) / 10); --scroll-px-thousand: calc(var(--scroll-px-hundred) / 10); margin-top: var(--menu-height); + min-height: 100vh; display: flex; flex-direction: column; flex-grow: 1; diff --git a/kodorvan/site/system/public/themes/default/css/pages/index.css b/kodorvan/site/system/public/themes/default/css/pages/index.css index 8e804d1..f655d1b 100755 --- a/kodorvan/site/system/public/themes/default/css/pages/index.css +++ b/kodorvan/site/system/public/themes/default/css/pages/index.css @@ -23,35 +23,4 @@ body { } } } - - >div.vignette { - z-index: 100; - position: fixed; - top: 0; - width: 100vw; - height: 100vh; - justify-self: center; - align-self: center; - pointer-events: none; - background: linear-gradient(90deg, #000B -20%, #0000 50%, #000B 120%); - } - - >div.dots { - --dot-bg: #18333f; - --dot-color: #041825; - --dot-size: 23px; - --dot-space: 24px; - z-index: -50; - position: fixed; - top: 0; - left: min(-30vw, -300px); - justify-self: center; - align-self: center; - width: max(250vw, 600px); - height: 200vh; - rotate: -16deg; - pointer-events: none; - background: linear-gradient(90deg, var(--dot-bg) calc(var(--dot-space) - var(--dot-size)), transparent 1%) center / var(--dot-space) var(--dot-space), linear-gradient(var(--dot-bg) calc(var(--dot-space) - var(--dot-size)), transparent 1%) center / var(--dot-space) var(--dot-space), var(--dot-color); - transform-origin: top left; - } } diff --git a/kodorvan/site/system/public/themes/default/css/pages/offer.css b/kodorvan/site/system/public/themes/default/css/pages/offer.css index 8dcbfa4..1207b53 100755 --- a/kodorvan/site/system/public/themes/default/css/pages/offer.css +++ b/kodorvan/site/system/public/themes/default/css/pages/offer.css @@ -2,42 +2,6 @@ body { >main { - >h1#title { - z-index: 200; - margin: unset; - margin-top: 4rem; - margin-bottom: 2rem; - width: max-content; - display: flex; - flex-direction: column; - text-align: center; - gap: 0.6rem; - font-family: ""; - font-size: min(8vw, 4rem); - font-weight: 400; - /* scale: 0.8; */ - color: #fff; - - >span.slogan { - line-height: 0.8em; - font-family: "GOST"; - font-weight: 400; - font-size: 1.24em; - color: #3688a2; - } - - >a.kodorvan { - line-height: 0.8em; - font-family: "MT Sans"; - font-size: 2em; - text-decoration: unset; - color: #c2ff98; - /* text-shadow: - 0px 0px 4px #ffff00b5, - 0px 0px 11px #ffff008a */ - } - } - >article#offer { z-index: 500; border-radius: 1.25rem; @@ -57,37 +21,6 @@ body { } } } - - >div.vignette { - z-index: 100; - position: fixed; - top: 0; - width: 100vw; - height: 100vh; - justify-self: center; - align-self: center; - pointer-events: none; - background: linear-gradient(90deg, #000B -20%, #0000 50%, #000B 120%); - } - - >div.dots { - --dot-bg: #18333f; - --dot-color: #041825; - --dot-size: 23px; - --dot-space: 24px; - z-index: -50; - position: fixed; - top: 0; - left: min(-30vw, -300px); - justify-self: center; - align-self: center; - width: max(250vw, 600px); - height: 200vh; - rotate: -16deg; - pointer-events: none; - background: linear-gradient(90deg, var(--dot-bg) calc(var(--dot-space) - var(--dot-size)), transparent 1%) center / var(--dot-space) var(--dot-space), linear-gradient(var(--dot-bg) calc(var(--dot-space) - var(--dot-size)), transparent 1%) center / var(--dot-space) var(--dot-space), var(--dot-color); - transform-origin: top left; - } } @media (width < 1000px) { diff --git a/kodorvan/site/system/public/themes/default/css/pages/system/superpack/create.css b/kodorvan/site/system/public/themes/default/css/pages/system/superpack/create.css new file mode 100755 index 0000000..0f12928 --- /dev/null +++ b/kodorvan/site/system/public/themes/default/css/pages/system/superpack/create.css @@ -0,0 +1,172 @@ +@charset "UTF-8"; + +body { + >main { + >article#superpack { + z-index: 500; + border-radius: 1.25rem; + margin: 3rem 0 8rem; + width: 540px; + box-sizing: border-box; + padding: 2rem; + display: flex; + flex-direction: column; + gap: 1.4rem; + background: #fff; + + >h1 { + margin-top: unset; + margin-bottom: 0.2rem; + text-align: center; + font-family: "MT Sans"; + font-size: 2.6rem; + font-weight: 400; + } + + + &:is(.loading) { + >div.loading { + opacity: 1; + height: 100%; + transition: opacity 0.1s ease-in, height 0s linear 0s; + } + } + + >div.loading { + z-index: 1000; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 0%; + display: flex; + justify-content: center; + align-items: center; + opacity: 0; + pointer-events: all; + background: #2c2c33d4; + backdrop-filter: blur(1.4px); + transition: opacity 0.2s ease-out, height 0s linear 0.2s; + + &:before { + margin-top: 50px; + position: absolute; + content: var(--project-loading, "Loading"); + width: max-content; + text-align: center; + font-family: "Geologica"; + font-style: normal; + font-weight: 400; + font-size: 0.6rem; + color: #fff; + } + + >i.icon.loading.spinner { + color: #fff; + } + } + + small.guide { + padding: 0 0.2em; + display: none; + font-family: Bahnschrift; + font-size: 0.75em; + font-weight: 200; + color: #29262b; + + &:is(.active) { + display: inline; + } + } + + >section { + --shadow: 0px 10px 8px -4px rgba(0, 0, 0, 0.15); + position: relative; + display: flex; + flex-direction: column; + gap: 0.8em; + + span { + font-family: Bahnschrift; + font-weight: 300; + } + + + >span { + font-size: 0.85em; + } + + textarea { + margin-top: 0.2em; + min-width: 100%; + max-width: 100%; + width: 100%; + min-height: 8ch; + max-height: 60vh; + resize: vertical; + } + + >:is(label, div).input.icon { + --title-height: 0.9em; + display: grid; + grid-template-columns: 1.3em auto; + grid-template-rows: var(--title-height, 1em) repeat(2, auto); + align-items: center; + grid-column-gap: 0.5em; + grid-row-gap: 0.2em; + + >img.icon { + grid-column: 1; + grid-row: 2/3; + width: 100%; + } + + >span.title { + grid-column: 2; + grid-row: 1; + /* margin-bottom: 0.2em; */ + font-size: var(--title-height, 1em); + padding: 0 0.5em; + font-weight: 400; + font-family: 'Cascadia Code'; + } + + >:is(input, select, textarea) { + grid-column: 2; + grid-row: 2; + width: 100%; + border-radius: 0; + } + + >small.guide { + grid-column: 2; + grid-row: 3; + margin-top: 0.2em; + } + } + + >button { + padding: 1.2rem 1rem; + font-size: 1.1rem; + /* border: unset; */ + + &:first-of-type { + margin-top: 2rem; + } + } + } + } + } +} + +@media (width < 1000px) { + body { + >main { + >article#offer { + margin-bottom: unset; + width: 100%; + border-radius: unset; + } + } + } +} diff --git a/kodorvan/site/system/public/themes/default/css/system.css b/kodorvan/site/system/public/themes/default/css/system.css index f5c3b56..3fe1cc8 100755 --- a/kodorvan/site/system/public/themes/default/css/system.css +++ b/kodorvan/site/system/public/themes/default/css/system.css @@ -48,6 +48,40 @@ body { /* background: var(--background-color, #fff); background: var(--background-gradient); */ background-color: #020c13; + + >div.vignette { + z-index: 100; + position: fixed; + top: 0; + width: 100vw; + min-height: 5000px; + height: 100vh; + justify-self: center; + align-self: center; + pointer-events: none; + background: linear-gradient(90deg, #000B -20%, #0000 50%, #000B 120%); + transform-origin: top center; + } + + >div.dots { + --dot-bg: #18333f; + --dot-color: #041825; + --dot-size: 23px; + --dot-space: 24px; + z-index: -50; + position: fixed; + top: 0; + left: min(-30vw, -300px); + justify-self: center; + align-self: center; + width: max(250vw, 600px); + min-height: 5000px; + height: 200vh; + rotate: -16deg; + pointer-events: none; + background: linear-gradient(90deg, var(--dot-bg) calc(var(--dot-space) - var(--dot-size)), transparent 1%) center / var(--dot-space) var(--dot-space), linear-gradient(var(--dot-bg) calc(var(--dot-space) - var(--dot-size)), transparent 1%) center / var(--dot-space) var(--dot-space), var(--dot-color); + transform-origin: top left; + } } a { @@ -64,15 +98,27 @@ a { &::selection { color: #094ef2; - background: #FFF; + background: #dbd035; text-shadow: none; } &::-moz-selection { color: #094ef2; - background: #FFF; + background: #dbd035; text-shadow: none; } + + /* &:is(.darked)::selection { + background: #000; + } + + &:is(.darked)::-moz-selection { + background: #000; + } */ + + &:is(.tech) { + font-family: "Cascadia Code"; + } } .unselectable { diff --git a/kodorvan/site/system/views/themes/default/elements/cases.html b/kodorvan/site/system/views/themes/default/elements/cases.html index 272e330..7a9435c 100755 --- a/kodorvan/site/system/views/themes/default/elements/cases.html +++ b/kodorvan/site/system/views/themes/default/elements/cases.html @@ -51,7 +51,7 @@ // Imported the hotline.mjs module // Initializing an instance of the hotline.mjs - const instance = new connected.hotline(document.getElementById("cases")); + const instance = new connected.global.hotline(document.getElementById("cases")); // Initializing settings of the hotline instance instance.alive = true; diff --git a/kodorvan/site/system/views/themes/default/elements/companies.html b/kodorvan/site/system/views/themes/default/elements/companies.html index 855935f..8794aa1 100755 --- a/kodorvan/site/system/views/themes/default/elements/companies.html +++ b/kodorvan/site/system/views/themes/default/elements/companies.html @@ -10,7 +10,7 @@ // Imported the hotline.mjs module // Initializing an instance of the hotline.mjs - const instance = new connected.hotline(document.getElementById("companies")); + const instance = new connected.global.hotline(document.getElementById("companies")); // Initializing settings of the hotline instance instance.alive = true; diff --git a/kodorvan/site/system/views/themes/default/elements/project.html b/kodorvan/site/system/views/themes/default/elements/project/full.html similarity index 86% rename from kodorvan/site/system/views/themes/default/elements/project.html rename to kodorvan/site/system/views/themes/default/elements/project/full.html index 7182cf2..6935fd4 100755 --- a/kodorvan/site/system/views/themes/default/elements/project.html +++ b/kodorvan/site/system/views/themes/default/elements/project/full.html @@ -28,7 +28,7 @@ class="input" name="architecture_input" autocomplete="off" - oninput="core.project.architecture = this.value" + oninput="core.global.project.architecture = this.value" > {% for value, label in project.architectures %} @@ -45,7 +45,7 @@ class="input" name="purpose_input" autocomplete="off" - oninput="core.project.purpose = this.value" + oninput="core.global.project.purpose = this.value" > {% for value, label in project.purposes %} @@ -67,7 +67,7 @@ type="checkbox" value="" autocomplete="off" - onchange="this.checked ? core.project.integrate(this.value) : core.project.desintegrate(this.value)" + onchange="this.checked ? core.global.project.integrate(this.value) : core.global.project.desintegrate(this.value)" /> @@ -89,7 +89,7 @@ max="3" value="0" autocomplete="off" - onkeyup="core.project.programmers = this.value" + onkeyup="core.global.project.programmers = this.value" /> Программисты @@ -102,7 +102,7 @@ max="4" value="0" autocomplete="off" - onkeyup="core.project.designers = this.value" + onkeyup="core.global.project.designers = this.value" /> Дизайнеры @@ -115,7 +115,7 @@ max="2" value="0" autocomplete="off" - onkeyup="core.project.boosters = this.value" + onkeyup="core.global.project.boosters = this.value" /> Бустеры @@ -135,7 +135,7 @@ max="5000" value="1800" autocomplete="off" - oninput="document.getElementById('hour_input_range').value = this.value; core.project.hour = this.value;" + oninput="document.getElementById('hour_input_range').value = this.value; core.global.project.hour = this.value;" /> Введите предложение оплаты за рабочий час команды @@ -168,7 +168,7 @@ placeholder="Проект А" value="" autocomplete="off" - onkeyup="core.project.project.name = this.value" + onkeyup="core.global.project.project.name = this.value" /> Введите внутреннее название проекта @@ -184,7 +184,7 @@ value="" autocomplete="off" placeholder="Сделайте, чтобы всё было красиво, спасибо" - onkeyup="core.project.project.description = this.value" + onkeyup="core.global.project.project.description = this.value" > Опишите задачу в свободной форме @@ -204,7 +204,7 @@ multiple="true" value="" autocomplete="off" - oninput="core.project.project.files = this.files" + oninput="core.global.project.project.files = this.files" /> @@ -224,7 +224,7 @@ placeholder="Богдан" value="" autocomplete="off" - onkeyup="core.project.requester.name = this.value" + onkeyup="core.global.project.requester.name = this.value" /> Введите ваши инициалы @@ -239,7 +239,7 @@ placeholder="7 (000) 000 0000" value="" autocomplete="off" - onkeyup="core.project.requester.sim = this.value" + onkeyup="core.global.project.requester.sim = this.value" /> Введите номер телефона для связи @@ -254,7 +254,7 @@ placeholder="project@company.org" value="" autocomplete="off" - onkeyup="core.project.requester.mail = this.value" + onkeyup="core.global.project.requester.mail = this.value" /> Введите почту для связи @@ -270,7 +270,7 @@ value="" autocomplete="off" placeholder="Синяя программа: @zornhut" - onkeyup="core.project.requester.other = this.value" + onkeyup="core.global.project.requester.other = this.value" > Введите дополнительные удобные способы связи @@ -286,7 +286,7 @@ type="checkbox" value="" autocomplete="off" - oninput="core.project.requester.personal = this.checked" + oninput="core.global.project.requester.personal = this.checked" /> lock kodorvan unlock kodorvan @@ -306,20 +306,20 @@
- +
+ + Команда разработчиков - мы реальные исполнители из Перми! Передача кода заказчику в его полную собственность и подпись NDA. Не используем ИИ в разработке! Полная анонимность проектов - никто не узнает кто разработчик. Не оставляем блокировки и скрытую рекламу в коде! + Гарантия качества: небольшие и простые проекты мы передаём нашим студентам, но за качество кода и соблюдение сроков всегда отвечает наставник! + Поддерживаем проекты наших
партнёров с 2014 года!
+ +
+ {% include '/themes/default/interface/media.html' %} + {% include '/themes/default/interface/sim.html' %} + ЗВОНИТЕ ПО НОМЕРУ +
+ diff --git a/kodorvan/site/system/views/themes/default/elements/rofls.html b/kodorvan/site/system/views/themes/default/elements/rofls.html index eb7c532..266e655 100755 --- a/kodorvan/site/system/views/themes/default/elements/rofls.html +++ b/kodorvan/site/system/views/themes/default/elements/rofls.html @@ -1,50 +1,50 @@ {% endblock %} diff --git a/kodorvan/site/system/views/themes/default/pages/article.html b/kodorvan/site/system/views/themes/default/pages/article.html index d2b1c81..07e0755 100755 --- a/kodorvan/site/system/views/themes/default/pages/article.html +++ b/kodorvan/site/system/views/themes/default/pages/article.html @@ -12,7 +12,7 @@ {% endblock %} {% block main %} - {% include '/themes/default/interface/logotype.html %} + {% include '/themes/default/interface/logotype.html' %}

{{ article.title }}

diff --git a/kodorvan/site/system/views/themes/default/pages/index.html b/kodorvan/site/system/views/themes/default/pages/index.html index 2682ae9..de330ad 100755 --- a/kodorvan/site/system/views/themes/default/pages/index.html +++ b/kodorvan/site/system/views/themes/default/pages/index.html @@ -39,7 +39,7 @@ {% block main %} {% include '/themes/default/interface/logotype.html' %} - {% include '/themes/default/elements/project.html' %} + {% include '/themes/default/elements/project/short.html' %} {% include '/themes/default/elements/companies.html' %} {% include '/themes/default/elements/superpacks.html' %} diff --git a/kodorvan/site/system/views/themes/default/pages/offer.html b/kodorvan/site/system/views/themes/default/pages/offer.html index a3c3594..1a4b8fc 100755 --- a/kodorvan/site/system/views/themes/default/pages/offer.html +++ b/kodorvan/site/system/views/themes/default/pages/offer.html @@ -12,7 +12,7 @@ {% endblock %} {% block main %} - {% include '/themes/default/interface/logotype.html %} + {% include '/themes/default/interface/logotype.html' %}
@@ -116,7 +116,7 @@

Я уведомлен, что при необходимости я могу ознакомиться с актуальной версией Политики обработки - персональных данных {{ company.name.short }} по адресу https://{{ domain }}/policy.

+ персональных данных {{ company.name.short }} по адресу https://{{ domain }}/policy.

{% endblock %} diff --git a/kodorvan/site/system/views/themes/default/pages/project/calculator.html b/kodorvan/site/system/views/themes/default/pages/project/calculator.html new file mode 100755 index 0000000..da862c9 --- /dev/null +++ b/kodorvan/site/system/views/themes/default/pages/project/calculator.html @@ -0,0 +1,30 @@ +{% extends "/themes/default/index.html" %} + +{% block css %} + {{ parent() }} + + + + + + +{% endblock %} + +{% block before %} +{% endblock %} + +{% block main %} + {% include '/themes/default/interface/logotype.html' %} + + {% include '/themes/default/elements/project/full.html' %} +{% endblock %} + +{% block after %} +
+
+{% endblock %} + +{% block js %} + {{ parent() }} + +{% endblock %} diff --git a/kodorvan/site/system/views/themes/default/pages/system/superpack/create.html b/kodorvan/site/system/views/themes/default/pages/system/superpack/create.html new file mode 100644 index 0000000..e183ce9 --- /dev/null +++ b/kodorvan/site/system/views/themes/default/pages/system/superpack/create.html @@ -0,0 +1,115 @@ +{% extends "/themes/default/index.html" %} + + +{% block css %} + {{ parent() }} + + + + +{% endblock %} + +{% block before %} +{% endblock %} + +{% block main %} + {% include '/themes/default/interface/logotype.html' %} + +
+

СОЗДАНИЕ СУПЕРПАКА

+ +
+ + + + + + +
+
+{% endblock %} + +{% block after %} +
+
+{% endblock %} + +{% block js %} + {{ parent() }} + +{% endblock %}