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)"
/>
{{ label }}
@@ -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"
/>
@@ -306,20 +306,20 @@
-
+
+
+
+ Команда разработчиков - мы реальные исполнители из Перми ! Передача кода заказчику в его полную собственность и подпись NDA . Не используем ИИ в разработке! Полная анонимность проектов - никто не узнает кто разработчик. Не оставляем блокировки и скрытую рекламу в коде!
+ Гарантия качества : небольшие и простые проекты мы передаём нашим студентам, но за качество кода и соблюдение сроков всегда отвечает наставник!
+ Поддерживаем проекты наших партнёров с 2014 года!
+
+
+
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 %}