0
1
Fork 0
This commit is contained in:
Juan Ferrer Toribio 2016-04-26 12:36:59 +02:00
commit ac28448dc5
396 changed files with 13827 additions and 5304 deletions

4
debian/changelog vendored
View File

@ -1,4 +1,8 @@
<<<<<<< HEAD
hedera-web (1.245-deb8) stable; urgency=low
=======
hedera-web (1.324-deb8) stable; urgency=low
>>>>>>> 5f64002b1d4eebc7fcfd7ff1916d7658fbaf57fb
* Initial Release.

View File

@ -1,6 +1,17 @@
<?php
/**
* Configuration file. Be careful to respect the PHP syntax.
*
* Do not modify this file! Instead, copy it to config.my.php and make your
* your changes there.
*
* Also, you can use a different config file depending on the virtual host. To
* do it, you have to create another configuration file and rename it to
* config.[subdomain].php. If no configutation file is found for a certain
* domain, the main file will be used. Ej:
*
* - http://www.mydomain.org -> config.www.php
* - http://test.mydomain.org -> config.test.php
**/
$conf = [
@ -9,16 +20,12 @@ $conf = [
**/
'db' => [
'host' => 'db.verdnatura.es'
,'port' => 3306
,'schema' => 'hedera-web'
,'user' => 'hedera-web'
,'pass' => 'base64pass'
]
/**
* The default language.
**/
,'defaultLang' => 'es'
];
?>

2
debian/control vendored
View File

@ -9,7 +9,7 @@ Vcs-Git: git://www.verdnatura.es/var/git/hedera-web
Package: hedera-web
Architecture: all
Depends: apache2, php5-mysql, php-vn-web
Depends: apache2, php5-mysql, php5-mcrypt, php-vn-web
Suggests: php-text-captcha, php5-imap, vn-image, tinymce
Section: misc
Priority: optional

View File

@ -8,7 +8,7 @@ if (!defined (__NAMESPACE__.'\_DEVELOPER_MODE'))
define (__NAMESPACE__.'\_LOG_DIR', '/var/log');
}
require_once (_CONFIG_DIR .'/config.php');
$conf = NULL;
ini_set ('log_errors', TRUE);
ini_set ('error_log', 'syslog');

View File

@ -10,7 +10,7 @@ class Js
static function includeFile ($fileName)
{
echo '<script type="text/javascript" src="'.$fileName.'?'. Web::getVersion () .'"></script>'."\n\t";
echo '<script type="text/javascript" src="'.$fileName.'?'. Web::getVersion () .'"></script>'."\n\t\t";
}
static function includeLib ($libName)
@ -28,7 +28,7 @@ class Js
static function includeCss ($fileName)
{
echo '<link rel="stylesheet" type="text/css" href="'.$fileName.'?'. Web::getVersion () .'"/>'."\n\t";
echo '<link rel="stylesheet" type="text/css" href="'.$fileName.'?'. Web::getVersion () .'"/>'."\n\t\t";
}
static function isMobile ()

View File

@ -16,12 +16,13 @@ class Web
{
static $sysConn = NULL;
static $conn = NULL;
static $confIncluded = FALSE;
/**
* Initializes the Hedera web library.
**/
static function init ()
{
{
if (self::isHttps ())
ini_set ('session.cookie_secure', TRUE);
@ -83,6 +84,8 @@ class Web
{
global $conf;
self::includeConf ();
if (self::$sysConn)
return;
@ -109,16 +112,49 @@ class Web
return (int) filectime (__FILE__);
}
/**
* Includes the configuration file.
**/
static function includeConf ()
{
global $conf;
if (self::$confIncluded)
return;
$customFile = _CONFIG_DIR .'/config.my.php';
if (!empty ($_SERVER['SERVER_NAME'])
&& preg_match ('/^[\w\-\.]+$/', $_SERVER['SERVER_NAME']))
{
$hostSplit = explode ('.', $_SERVER['SERVER_NAME']);
$hostFile = _CONFIG_DIR .'/config.'. $hostSplit[0] .'.php';
}
if (isset ($hostFile) && file_exists ($hostFile))
$confFile = $hostFile;
elseif (file_exists ($customFile))
$confFile = $customFile;
else
$confFile = _CONFIG_DIR .'/config.php';
require ($confFile);
self::$confIncluded = TRUE;
}
static function login ()
{
global $conf;
self::includeConf ();
$wasLoged = Auth::isLogged ();
$useCookies = TRUE;
$success = TRUE;
if (isset ($_GET['guest']))
if (isset ($_POST['guest']))
{
self::sysInit ();
$row = self::$sysConn->getRow (
'SELECT guest_user, guest_pass FROM config');
@ -130,9 +166,9 @@ class Web
}
}
try {
Auth::getCredentials ();
Auth::getCredentials ();
try {
self::$conn = new Conn ();
self::$conn->open (
$conf['db']['host']
@ -141,20 +177,20 @@ class Web
,$conf['db']['schema']
,$conf['db']['port']
);
self::$conn->query ('CALL user_session_start (#)',
[session_id ()]);
self::$conn->query ('CALL user_session_start (#)', [session_id ()]);
self::$conn->query ('SET @lang = #', [\Vn\Lib\Locale::get ()]);
Auth::login ($useCookies);
Auth::login (TRUE, $useCookies);
}
catch (\Exception $e)
{
self::$conn = NULL;
$success = FALSE;
Auth::login (FALSE);
}
// Registering the user access
if ($success && !$wasLoged)
if (!$wasLoged)
unset ($_SESSION['visitUser']);
if (isset ($_SESSION['access'])
@ -170,12 +206,10 @@ class Web
,session_id ()
]
);
if (!isset ($_SESSION['visitUnknown']) && !$success)
$_SESSION['visitUnknown'] = $_SESSION['visitUser'];
}
return $success;
}
static function deinit ()

View File

@ -18,6 +18,8 @@ class Tpv
static function init ()
{
global $conf;
require (Hedera\_CONFIG_DIR .'/config.my.php');
openlog ('hedera-web', LOG_ODELAY, LOG_LOCAL0);
@ -27,6 +29,7 @@ class Tpv
,$conf['db']['user']
,base64_decode ($conf['db']['pass'])
,$conf['db']['schema']
,$conf['db']['port']
);
}
@ -81,7 +84,7 @@ class Tpv
$params = [];
$body = imap_fetchbody ($imap, $msg, '1');
$strings = explode (';', $body);
foreach ($strings as $string)
{
$x = explode (':', $string);
@ -98,18 +101,18 @@ class Tpv
$folder = $imapConf['success_folder'];
else
$folder = $imapConf['error_folder'];
$folder = sprintf ('INBOX.%s', $folder);
if (!imap_mail_move ($imap, $msg, $folder))
error_log ('TPV: IMAP: Can\'t move message to %s: %s'
trigger_error (sprintf ('TPV: IMAP: Can\'t move message to %s: %s'
,$folder
,imap_last_error ()
);
), E_USER_WARNING);
}
if ($inbox && ($count = count ($inbox)) > 0)
error_log ('TPV: %d mails processed.', $count);
trigger_error (sprintf ('TPV: %d mails processed.', $count));
imap_expunge ($imap);
@ -138,13 +141,13 @@ class Tpv
$deleted += count ($messages);
}
error_log ('TPV: Cleaner: %d mails deleted.', $deleted);
trigger_error (sprintf ('TPV: Cleaner: %d mails deleted.', $deleted));
}
imap_close ($imap);
}
else
error_log ('TPV: IMAP: %s', imap_last_error ());
trigger_error (sprintf ('TPV: IMAP: %s', imap_last_error ()), E_USER_ERROR);
self::deinit ();
}
@ -183,36 +186,73 @@ class Tpv
&& isset ($params['Ds_Order'])
&& isset ($params['Ds_MerchantCode'])
&& isset ($params['Ds_Currency'])
&& isset ($params['Ds_Response'])
&& isset ($params['Ds_Signature']))
&& isset ($params['Ds_Response']))
{
if (isset ($params['Ds_ErrorCode']))
$error = $params['Ds_ErrorCode'];
else
$error = NULL;
try {
try {
return self::$conn->query (
'CALL transaction_confirm_with_check (#, #, #, #, #, #, #)',
'CALL transaction_confirm (#, #, #, #, #, #)',
[
$params['Ds_Amount']
,$params['Ds_Order']
,$params['Ds_MerchantCode']
,$params['Ds_Currency']
,$params['Ds_Response']
,$params['Ds_Signature']
,$error
]
);
}
catch (\Exception $e)
{
error_log ("TPV: DB: %s", $e->getMessage ());
trigger_error (sprintf ("TPV: DB: %s", $e->getMessage ()), E_USER_WARNING);
}
}
return FALSE;
}
static function transactionStart ($conn, $amount, $urlOk, $urlKo, $companyId, &$url, &$signature)
{
$row = $conn->getRow ('CALL transaction_start_sha256 (#, #)',
[$amount, $companyId]);
if (!isset($row))
throw new Exception ('Transaction error');
$transactionId = str_pad ($row['transaction_id'], 12, '0', STR_PAD_LEFT);
$urlOk = empty ($urlOk) ? '' : sprintf ($urlOk, $transactionId);
$urlKo = empty ($urlKo) ? '' : sprintf ($urlKo, $transactionId);
$merchantUrl = $row['merchant_url'] ? $row['merchant_url'] : '';
$params = [
'Ds_Merchant_Amount' => $amount
,'Ds_Merchant_Order' => $transactionId
,'Ds_Merchant_MerchantCode' => $row['merchant']
,'Ds_Merchant_Currency' => $row['currency']
,'Ds_Merchant_TransactionType' => $row['transaction_type']
,'Ds_Merchant_Terminal' => $row['terminal']
,'Ds_Merchant_MerchantURL' => $merchantUrl
,'Ds_Merchant_UrlOK' => $urlOk
,'Ds_Merchant_UrlKO' => $urlKo
];
$encodedParams = base64_encode (json_encode ($params));
$key = base64_decode ($row['secret_key']);
$bytes = array (0, 0, 0, 0, 0, 0, 0, 0);
$iv = implode (array_map ("chr", $bytes));
$key = mcrypt_encrypt (MCRYPT_3DES, $key, $transactionId, MCRYPT_MODE_CBC, $iv);
$signature = base64_encode (hash_hmac ('sha256', $encodedParams, $key, TRUE));
$url = $row['url'];
return $encodedParams;
}
/**
* Tests the confirmation process. The corresponding record

3
php-test Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
php -d auto_prepend_file=configure.php "$@"

View File

@ -1,7 +1,7 @@
Vn.AddressList = new Class
({
Extends: Vn.Module
Extends: Vn.Form
,activate: function ()
{

View File

@ -5,7 +5,7 @@
}
.address-list .box
{
max-width: 40em;
max-width: 30em;
}
.address-list .form
{
@ -15,19 +15,34 @@
}
.address
{
color: #555;
padding: .5em;
}
.address p.consignee
{
font-weight: bold;
padding: 1em;
border-bottom: 1px solid #DDD;
}
.address p
{
font-size: 1.4em;
margin: 0.2em 0;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.address p.important
{
font-size: 1.2em;
}
.address .actions
{
text-align: right;
float: right;
}
.address .actions > .htk-button
{
margin: 0;
}
.address .actions > *
{
display: inline-block;
vertical-align: middle;
}
.address .actions > input
{
margin: .6em;
}

View File

@ -1,76 +1,75 @@
<vn>
<vn-group>
<db-form id="user-form">
<db-model id="user-model" updatable="true">
SELECT user_id, default_address
FROM customer_view c
<db-model property="model" id="user-model" updatable="true">
<custom>
SELECT user_id, default_address
FROM customer_view c
</custom>
</db-model>
</db-form>
<db-model id="addresses" updatable="true">
SELECT a.id, a.consignee, p.name province, a.zip_code, a.city, a.name, a.active, c.Pais country
FROM address_view a
LEFT JOIN vn2008.province p ON a.province_id = p.province_id
JOIN vn2008.Paises c ON c.Id = p.Paises_Id
WHERE active != FALSE
<custom>
SELECT a.id, a.consignee, p.name province, a.zip_code,
a.city, a.name, a.active, c.Pais country
FROM address_view a
LEFT JOIN vn2008.province p ON a.province_id = p.province_id
JOIN vn2008.Paises c ON c.Id = p.Paises_Id
WHERE active != FALSE
</custom>
</db-model>
</vn-group>
<div id="title">
<h1><t>Addresses</t></h1>
</div>
<div id="actions">
<htk-button
image="image/dark/add.svg"
tip="_AddAddress"
on-click="onAddAddressClick"
showText="true"/>
</div>
<div id="form" class="address-list">
<div class="box">
<div class="header">
<h1><t>Addresses</t></h1>
<div class="action-bar">
<button on-click="onReturnClick">
<img src="image/dark/go-previous.svg" alt=""/>
<t>Return</t>
</button>
<button on-click="onAddAddressClick">
<img src="image/dark/add.svg" alt=""/>
<t>AddAddress</t>
</button>
<htk-radio-group
id="default-address"
column="default_address"
form="user-form"/>
<htk-repeater model="addresses" form-id="iter">
<custom>
<div class="address">
<div class="actions">
<htk-radio
form="iter"
column="id"
radio-group="default-address"
tip="_SetAsDefault"/>
<htk-button
form="iter"
column="id"
tip="_RemoveAddress"
image="image/delete.svg"
on-click="onRemoveAddressClick"/>
<htk-button
form="iter"
column="id"
tip="_EditAddress"
image="image/edit.svg"
on-click="onEditAddressClick"/>
</div>
<p class="important">
<htk-text form="iter" column="consignee"/>
</p>
<p>
<htk-text form="iter" column="name"/>
</p>
<p>
<htk-text form="iter" column="zip_code"/>,
<htk-text form="iter" column="city"/>
</p>
</div>
<div class="clear"/>
</div>
<div class="form">
<htk-radio-group
id="default-address"
column="default_address"
form="user-form"/>
<htk-repeater model="addresses" form-id="iter">
<template>
<div class="address">
<p class="consignee">
<htk-text form="iter" column="consignee"/>
</p>
<p>
<htk-text form="iter" column="name"/>
</p>
<p>
<htk-text form="iter" column="zip_code"/>,
<htk-text form="iter" column="city"/>
</p>
<div class="actions">
<htk-radio
form="iter"
column="id"
radio-group="default-address"
tip="_SetAsDefault"/>
<htk-button
form="iter"
column="id"
tip="_RemoveAddress"
image="image/delete.svg"
on-click="onRemoveAddressClick"/>
<htk-button
form="iter"
column="id"
tip="_EditAddress"
image="image/edit.svg"
on-click="onEditAddressClick"/>
</div>
</div>
</template>
</htk-repeater>
</div>
</custom>
</htk-repeater>
</div>
</div>
</vn>

View File

@ -1,7 +1,7 @@
Vn.Address = new Class
({
Extends: Vn.Module
Extends: Vn.Form
,activate: function ()
{

View File

@ -5,27 +5,16 @@
}
.address .box
{
max-width: 40em;
max-width: 30em;
padding: 2em;
}
.address .box .body
.address .form
{
margin: 0 auto;
max-width: 25em;
padding: 3em;
}
div.form-group
.address .form-group
{
padding: 0.4em;
}
.address label
{
display: block;
margin-bottom: 0.5em;
}
.address input,
.address select
{
margin: 0;
width: 100%;
}

View File

@ -1,38 +1,47 @@
<vn>
<vn-group>
<vn-param id="address">
<vn-hash-param key="address"/>
</vn-param>
<vn-param id="address"/>
<vn-hash-param key="address" param="address"/>
<db-form id="iter" on-status-changed="onStatusChange">
<db-param id="country" one-way="true" column="country_id"/>
<db-model id="model" updatable="true" mode="ON_DEMAND" on-operations-done="onOperationsDone">
SELECT a.id, a.name, a.consignee, a.city, a.zip_code, a.province_id, c.Id country_id
FROM address_view a
LEFT JOIN vn2008.province p ON p.province_id = a.province_id
JOIN vn2008.Paises c ON c.Id = p.Paises_Id
WHERE active != FALSE AND a.id = #address
<db-model
id="model"
property="model"
updatable="true"
mode="ON_DEMAND"
on-operations-done="onOperationsDone">
<custom>
SELECT a.id, a.name, a.consignee, a.city, a.zip_code, a.province_id, c.Id country_id
FROM address_view a
LEFT JOIN vn2008.province p ON p.province_id = a.province_id
JOIN vn2008.Paises c ON c.Id = p.Paises_Id
WHERE active != FALSE AND a.id = #address
</custom>
<sql-batch property="batch">
<item name="address" param="address"/>
<custom>
<item name="address" param="address"/>
</custom>
</sql-batch>
</db-model>
</db-form>
</vn-group>
<div id="title">
<h1><t>AddEditAddress</t></h1>
</div>
<div id="actions">
<htk-button
image="image/dark/ok.svg"
tip="_Accept"
on-click="onAcceptClick"
showText="true"/>
<htk-button
image="image/dark/close.svg"
tip="_Return"
on-click="onReturnClick"
showText="true"/>
</div>
<div id="form" class="address">
<div class="box">
<div class="header">
<h1><t>AddEditAddress</t></h1>
<div class="action-bar">
<button on-click="onReturnClick">
<img src="image/dark/go-previous.svg" alt=""/>
<t>Return</t>
</button>
<button on-click="onAcceptClick">
<img src="image/dark/ok.svg" alt=""/>
<t>Accept</t>
</button>
</div>
</div>
<div class="body">
<div class="form">
<div class="form-group">
<label><t>Name</t></label>
<htk-entry column="consignee" form="iter"/>
@ -51,10 +60,18 @@
</div>
<div class="form-group">
<label><t>Country</t></label>
<htk-combo param="country">
<htk-combo>
<db-param
id="country"
property="param"
form="iter"
column="country_id"
one-way="true"/>
<db-model property="model">
SELECT Id, Pais FROM vn2008.Paises
ORDER BY Pais
<custom>
SELECT Id, Pais FROM vn2008.Paises
ORDER BY Pais
</custom>
</db-model>
</htk-combo>
</div>
@ -62,11 +79,15 @@
<label><t>Province</t></label>
<htk-combo column="province_id" form="iter">
<db-model property="model">
SELECT province_id, name FROM vn2008.province
WHERE Paises_Id = #country
ORDER BY name
<custom>
SELECT province_id, name FROM vn2008.province
WHERE Paises_Id = #country
ORDER BY name
</custom>
<sql-batch property="batch">
<item name="country" param="country"/>
<custom>
<item name="country" param="country"/>
</custom>
</sql-batch>
</db-model>
</htk-combo>

View File

@ -1,7 +1,7 @@
Vn.Conf = new Class
({
Extends: Vn.Module
Extends: Vn.Form
,activate: function ()
{

View File

@ -5,29 +5,18 @@
}
.conf .box
{
max-width: 40em;
max-width: 30em;
padding: 2em;
}
.conf .form
{
margin: 0 auto;
max-width: 25em;
padding: 2em;
}
.conf .form-group
{
padding: 0.4em;
}
.conf .form-group label
{
display: block;
margin-bottom: 0.5em;
}
.conf .form-group input[type=text],
.conf .form-group input[type=password]
{
margin: 0;
width: 100%;
}
.conf .form-group input[type=password]
{
margin-bottom: 0.5em;

View File

@ -1,33 +1,37 @@
<vn>
<vn-group>
<db-form id="user-form">
<db-model id="user-model" updatable="true">
SELECT id, u.name, email, mail, c.user_id, c.default_address
FROM user_view u
LEFT JOIN customer_view c
ON u.id = c.user_id
<db-model property="model" id="user-model" updatable="true">
<custom>
SELECT id, u.name, email, mail, c.user_id, c.default_address
FROM user_view u
LEFT JOIN customer_view c
ON u.id = c.user_id
</custom>
</db-model>
</db-form>
<db-model id="addresses" updatable="true">
SELECT a.id, a.consignee, p.name province, a.zip_code, a.city, a.name, a.active, c.Pais country
FROM address_view a
LEFT JOIN vn2008.province p ON a.province_id = p.province_id
JOIN vn2008.Paises c ON c.Id = p.Paises_Id
WHERE active != FALSE
<custom>
SELECT a.id, a.consignee, p.name province, a.zip_code, a.city, a.name, a.active, c.Pais country
FROM address_view a
LEFT JOIN vn2008.province p ON a.province_id = p.province_id
JOIN vn2008.Paises c ON c.Id = p.Paises_Id
WHERE active != FALSE
</custom>
</db-model>
</vn-group>
<div id="title">
<h1><t>Configuration</t></h1>
</div>
<div id="actions">
<htk-button
image="image/dark/place.svg"
tip="_Addresses"
on-click="onAddressesClick"
showText="true"/>
</div>
<div id="form" class="conf">
<div class="box">
<div class="header">
<h1><t>Configuration</t></h1>
<div class="action-bar">
<button on-click="onAddressesClick">
<img src="image/dark/shipping.svg" alt=""/>
<t>Addresses</t>
</button>
</div>
<div class="clear"/>
</div>
<div class="form">
<div class="form-group">
<label for="user-name"><t>UserName</t></label>

View File

@ -1,6 +1,6 @@
Vn.AccessLog = new Class
({
Extends: Vn.Module
Extends: Vn.Form
});

View File

@ -1,15 +1,36 @@
.access-log
{
padding: 1em;
min-width: 35em;
}
.access-log .box
{
max-width: 50em;
max-width: 25em;
margin: 0 auto;
}
.access-log .htk-grid tbody tr
.access-log .form
{
height: 3.4em;
padding: 2em;
}
.access-log .form > p
{
font-size: 1.2em;
margin: .1em 0;
}
/* List */
.access-log .list
{
margin-top: 1em;
}
.access-log .item
{
display: block;
padding: 1em;
border-bottom: 1px solid #DDD;
}
.access-log .item > p
{
margin: .1em 0;
}

View File

@ -1,80 +1,77 @@
<vn>
<vn-group>
<vn-param id="user">
<vn-hash-param key="user"/>
</vn-param>
<vn-param id="user"/>
<vn-hash-param key="user" param="user"/>
<db-form id="user-form">
<db-model>
SELECT Id_Cliente, Cliente, Telefono, movil
FROM vn2008.Clientes WHERE Id_Cliente = #user
<db-model property="model">
<custom>
SELECT Id_Cliente, Cliente, Telefono, movil
FROM vn2008.Clientes WHERE Id_Cliente = #user
</custom>
<sql-batch property="batch">
<item name="user" param="user"/>
<custom>
<item name="user" param="user"/>
</custom>
</sql-batch>
</db-model>
</db-form>
</vn-group>
<div id="title">
<h1><t>AccessLog</t></h1>
</div>
<div id="form" class="access-log">
<div class="box">
<div class="header">
<h1><t>AccessLog</t></h1>
<div class="form">
<p>
<htk-text form="user-form" column="Id_Cliente"/>
</p>
<p>
<htk-text form="user-form" column="Cliente"/>
</p>
<p>
<htk-text form="user-form" column="Telefono"/>
</p>
<p>
<htk-text form="user-form" column="movil"/>
</p>
</div>
<table class="form">
<tbody>
<tr>
<td class="label">
<label><t>UserNumber:</t></label>
</td>
<td>
<htk-text column="Id_Cliente" form="user-form"/>
</td>
</tr>
<tr>
<td class="label">
<label><t>User:</t></label>
</td>
<td>
<htk-text column="Cliente" form="user-form"/>
</td>
</tr>
<tr>
<td class="label">
<label><t>Phone:</t></label>
</td>
<td>
<htk-text column="Telefono" form="user-form"/>
</td>
</tr>
<tr>
<td class="label">
<label><t>Mobile:</t></label>
</td>
<td>
<htk-text column="movil" form="user-form"/>
</td>
</tr>
</tbody>
</table>
</div>
<div class="list box">
<div>
<htk-grid>
<db-model>
SELECT u.date_time, a.platform, a.browser, a.version, a.javascript, a.cookies
FROM visit_user u
JOIN visit_access c ON u.access_id = c.id
JOIN visit_agent a ON c.agent_id = a.id
WHERE u.user_id = #user
ORDER BY u.date_time DESC
LIMIT 30
<htk-repeater form-id="iter">
<db-model property="model">
<custom>
SELECT u.date_time, a.platform, a.browser, a.version, a.javascript, a.cookies
FROM visit_user u
JOIN visit_access c ON u.access_id = c.id
JOIN visit_agent a ON c.agent_id = a.id
WHERE u.user_id = #user
ORDER BY u.date_time DESC
LIMIT 8
</custom>
<sql-batch property="batch">
<item name="user" param="user"/>
<custom>
<item name="user" param="user"/>
</custom>
</sql-batch>
</db-model>
<htk-column-date title="_Access" column="date_time" format="_%a, %e %b %Y at %T"/>
<htk-column-text title="_SO" column="platform"/>
<htk-column-text title="_Browser" column="browser"/>
<htk-column-text title="_Version" column="version"/>
<htk-column-check title="_Javascript" column="javascript"/>
<htk-column-check title="_Cookies" column="cookies"/>
</htk-grid>
<custom>
<div class="item">
<p>
<htk-text form="iter" column="date_time" format="_%a, %e %b %Y at %T"/>
</p>
<p>
<htk-text form="iter" column="platform"/> -
<htk-text form="iter" column="browser"/>
<htk-text form="iter" column="version"/>
</p>
<!-- <p>
<htk-text form="iter" column="javascript"/>,
<htk-text form="iter" column="cookies"/>
</p>
--> </div>
</custom>
</htk-repeater>
</div>
</div>
</div>

View File

@ -0,0 +1,53 @@
Vn.Connections = new Class
({
Extends: Vn.Form
,_timeoutId: null
,onModelStatusChange: function (model, status)
{
if (!model.ready)
return;
if (this._timeoutId)
clearTimeout (this._timeoutId);
this._timeoutId = setTimeout (this.onRefreshClick.bind (this), 60000);
}
,deactivate: function ()
{
clearTimeout (this._timeoutId);
}
,onRefreshClick: function ()
{
this.$('sessions').refresh ();
}
,onAccessLogClick: function (button, form)
{
this.hash.set ({
'form': 'admin/access-log'
,'user': form.get ('user_id')
});
}
,onChangeUserClick: function (button, form)
{
this.gui.supplantUser (form.get ('user_id'),
this.onUserSupplant.bind (this));
}
,onUserSupplant: function (userName)
{
this.hash.set ({'form': 'ecomerce/orders'});
}
,sessionsFunc: function ()
{
return 1;
}
});

View File

@ -0,0 +1,44 @@
.connections
{
padding: 1em;
}
.connections .box
{
max-width: 25em;
margin: 0 auto;
}
.action-bar .connections-sum
{
padding: .4em;
margin-top: .9em;
margin-right: .5em;
background-color: #1e88e5;
border-radius: 0.1em;
box-shadow: 0 0 0.4em #666;
}
/* List */
.connections .item
{
display: block;
padding: 1em;
border-bottom: 1px solid #DDD;
}
.connections .item > button
{
float: right;
margin: 0;
}
.connections .item > p
{
margin: .1em 0;
}
.connections .item > p.important
{
font-size: 1.2em;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}

View File

@ -0,0 +1,69 @@
<vn>
<div id="title">
<h1><t>Connections</t></h1>
</div>
<div id="actions">
<htk-button
image="image/dark/refresh.svg"
tip="_Refresh"
on-click="onRefreshClick"
showText="true"/>
<div class="connections-sum">
<htk-text>
<db-calc-sum
property="param"
model="sessions"
func="sessionsFunc"/>
</htk-text>
<t>connections</t>
</div>
</div>
<div id="form" class="connections">
<div class="box">
<htk-repeater form-id="iter">
<db-model property="model" id="sessions" on-status-changed="onModelStatusChange">
<custom>
SELECT s.id, e.user_id, c.Cliente, e.date_time login, is_new,
s.date_time last_activity, a.platform, a.browser, a.version
FROM user_session s
JOIN visit_user e ON s.visit_user_id = e.id
JOIN visit_access c ON e.access_id = c.id
JOIN visit_agent a ON c.agent_id = a.id
JOIN visit v ON a.visit_id = v.id
JOIN account.user u ON e.user_id = u.id
JOIN vn2008.Clientes c ON e.user_id = c.Id_cliente
ORDER BY last_activity DESC
</custom>
</db-model>
<custom>
<div class="item">
<htk-button
form="iter"
column="id"
tip="_Supplant user"
image="image/incognito.svg"
on-click="onChangeUserClick"/>
<htk-button
form="iter"
column="id"
tip="_Access log"
image="image/gnome.svg"
on-click="onAccessLogClick"/>
<p class="important">
<htk-text form="iter" column="Cliente"/>
</p>
<p>
<htk-text form="iter" column="login" format="%a, %T"/> -
<htk-text form="iter" column="last_activity" format="%T"/>
</p>
<p>
<htk-text form="iter" column="platform"/> -
<htk-text form="iter" column="browser"/>
<htk-text form="iter" column="version"/>
</p>
</div>
</custom>
</htk-repeater>
</div>
</div>
</vn>

23
web/forms/admin/items/items.js Executable file
View File

@ -0,0 +1,23 @@
Vn.Items = new Class
({
Extends: Vn.Form
,activate: function ()
{
this.$('warehouse').value = 7;
this.$('realm').value = null;
}
,onPreviewClick: function ()
{
var batch = new Sql.Batch ();
batch.addValues ({
'warehouse': this.$('warehouse').value
,'realm': this.$('realm').value
,'rate': this.$('rate').value
});
this.gui.openReport ('items-report', batch);
}
});

43
web/forms/admin/items/style.css Executable file
View File

@ -0,0 +1,43 @@
.items
{
padding: 1em;
}
.items .box
{
max-width: 30em;
padding: 2em;
}
.items .form
{
max-width: 25em;
margin: auto;
}
.items .form-group
{
padding: 0.4em;
}
.items form label
{
display: block;
margin-bottom: 0.5em;
}
.items input[type=text],
.items select
{
margin: 0;
width: 100%;
}
/* Footer */
.items .footer
{
text-align: center;
margin-top: 1.5em;
}
.items .footer > button
{
margin: 0 .2em;
}

48
web/forms/admin/items/ui.xml Executable file
View File

@ -0,0 +1,48 @@
<vn>
<div id="title">
<h1><t>Item list</t></h1>
</div>
<div id="form" class="items">
<div class="box">
<div class="form">
<div class="form-group">
<label><t>Store</t></label>
<htk-combo>
<vn-param property="param" id="warehouse"/>
<db-model property="model">
<custom>
SELECT id, name FROM vn2008.warehouse
WHERE reserve ORDER BY name
</custom>
</db-model>
</htk-combo>
</div>
<div class="form-group">
<label><t>Realm</t></label>
<htk-combo not-null="false">
<vn-param property="param" id="realm"/>
<db-model property="model">
<custom>
SELECT id, reino FROM vn2008.reinos
WHERE display != FALSE ORDER BY reino
</custom>
</db-model>
</htk-combo>
</div>
<div class="form-group">
<label><t>Rate</t></label>
<select id="rate">
<option>3</option>
<option>2</option>
<option>1</option>
</select>
</div>
</div>
<div class="footer">
<button class="thin" on-click="onPreviewClick">
<t>Preview</t>
</button>
</div>
</div>
</div>
</vn>

View File

@ -1,16 +1,11 @@
Vn.Links = new Class
({
Extends: Vn.Module
Extends: Vn.Form
,activate: function ()
,repeaterFunc: function (res, form)
{
this.$('column-link').renderer = this.linkRenderer;
}
,linkRenderer: function (column, form)
{
column.href = form.get ('link');
res.$('link').href = form.get ('link');
}
});

View File

@ -5,14 +5,34 @@
}
.cpanel .box
{
max-width: 60em;
min-width: 25em;
max-width: 30em;
}
.cpanel tbody tr
/* Items */
.cpanel .item
{
height: 3.5em;
display: block;
padding: 1em;
border-bottom: 1px solid #DDD;
}
.cpanel tbody td img
.cpanel .item:hover
{
min-height: 1.6em;
background-color: rgba(1, 1, 1, 0.05);
}
.cpanel .item > img
{
margin: .2em 0;
margin-right: 1em;
float: left;
max-height: 3em;
max-width: 3em;
}
.cpanel .item > p
{
margin: .1em 0;
}
.cpanel .item > p.important
{
font-size: 1.2em;
}

View File

@ -1,18 +1,32 @@
<vn>
<div id="title">
<h1><t>ControlPanel</t></h1>
</div>
<div id="form" class="cpanel">
<div class="box">
<div class="header">
<h1><t>ControlPanel</t></h1>
</div>
<htk-grid show-header="false">
<db-model>
SELECT image, name, description, link FROM link
ORDER BY name
<htk-repeater form-id="iter" renderer="repeaterFunc">
<db-model property="model">
<custom>
SELECT image, name, description, link FROM link
ORDER BY name
</custom>
</db-model>
<htk-column-image directory="link" subdir="full" column="image"/>
<htk-column-link column="name" target="\_blank" id="column-link"/>
<htk-column-text column="description"/>
</htk-grid>
<custom>
<a id="link" class="item" target="_blank">
<htk-image
form="iter"
column="image"
directory="link"
subdir="full"/>
<p class="important">
<htk-text form="iter" column="name"/>
</p>
<p>
<htk-text form="iter" column="description"/>
</p>
</a>
</custom>
</htk-repeater>
</div>
</div>
</vn>

View File

@ -1,7 +1,7 @@
Vn.Photos = new Class
({
Extends: Vn.Module
Extends: Vn.Form
,activate: function ()
{

View File

@ -1,42 +0,0 @@
<?php
session_start ();
$params = array
(
'name'
,'surname'
,'email'
,'message'
,'address'
,'pc'
,'city'
,'phone'
,'captcha'
);
$paramsOk = TRUE;
foreach ($params as $param)
if (!isset ($_POST[$param]) || $_POST[$param] == '')
{
$paramsOk = FALSE;
break;
}
header ('Content-Type: application/json');
if ($paramsOk && isset ($_SESSION['captcha'])
&& $_POST['captcha'] == $_SESSION['captcha'])
{
mail ('nuria@verdnatura.es', 'Verdnatura', print_r ($_POST, TRUE),
'From: Verdnatura <www-data@verdnatura.es>');
echo json_encode (TRUE);
}
else
echo json_encode (FALSE);
unset ($_SESSION['captcha']);
?>

View File

@ -5,28 +5,14 @@
}
.photos .box
{
max-width: 40em;
max-width: 30em;
padding: 2em;
}
.photos form
.photos .form
{
margin: 0 auto;
max-width: 25em;
}
div.form-group
{
padding: 0.4em;
}
.photos form label
{
display: block;
margin-bottom: 0.5em;
}
.photos input,
.photos select
{
margin: 0;
width: 100%;
}
.photos iframe
{
display: none;

View File

@ -1,10 +1,10 @@
<vn>
<div id="title">
<h1><t>Photos</t></h1>
</div>
<div id="form" class="photos">
<div class="box">
<div class="header">
<h1><t>Photos</t></h1>
</div>
<div class="body">
<div class="form">
<form
id="html-form"
method="post"
@ -33,7 +33,7 @@
<input type="file" name="image"/>
<input type="hidden" name="MAX_FILE_SIZE" id="photo-size"/>
</div>
<button class="flat" id="submit">
<button class="thin" id="submit">
<t>Upload</t>
</button>
</form>

View File

@ -0,0 +1,102 @@
Vn.Queries = new Class
({
Extends: Vn.Form
,activate: function ()
{
this.$('result-index').value = 0;
}
,clean: function ()
{
if (this._grid)
{
this.$('grid-holder').removeChild (this._grid.getNode ());
this._grid.unref ();
this._grid = null;
}
}
,_onExecuteClick: function ()
{
this.clean ();
var model = new Db.Model ({
conn: this.conn,
query: this.$('sql').value,
resultIndex: this.$('result-index').value,
updatable: this.$('updatable').value
});
model.on ('status-changed', this._onModelChange, this);
}
,_onCleanClick: function ()
{
this.clean ();
}
,_onModelChange: function (model, status)
{
if (status !== Db.Model.Status.LOADING)
{
model.disconnect ('status-changed', this._onModelChange, this);
model.unref ();
}
if (status !== Db.Model.Status.READY)
return;
Htk.Toast.showMessage (_('Query executed!'));
var gridHolder = this.$('grid-holder');
if (gridHolder.firstChild)
gridHolder.removeChilds (gridHolder.firstChild);
var grid = new Htk.Grid ();
var columns = model.columns;
for (var i = 0; i < columns.length; i++)
{
var c = columns[i];
switch (c.type)
{
case Db.Conn.Type.BOOLEAN:
var column = new Htk.ColumnCheck ();
break;
case Db.Conn.Type.INTEGER:
var column = new Htk.ColumnSpin ();
break;
case Db.Conn.Type.DOUBLE:
var column = new Htk.ColumnSpin ({digits: 2});
break;
case Db.Conn.Type.DATE:
var column = new Htk.ColumnDate ({format: '%a, %e %b %Y'});
break;
case Db.Conn.Type.DATE_TIME:
var column = new Htk.ColumnDate ({format: '%a, %e %b %Y, %T'});
break;
case Db.Conn.Type.STRING:
default:
var column = new Htk.ColumnText ();
}
column.setProperties ({
title: c.name,
editable: this.$('updatable').value,
columnIndex: i
});
grid.appendColumn (column);
}
grid.model = model;
gridHolder.appendChild (grid.getNode ());
this._grid = grid;
}
});

View File

@ -0,0 +1,25 @@
.queries
{
padding: 1em;
}
.queries .box
{
max-width: 40em;
margin: 0 auto;
}
.queries .form
{
box-sizing: border-box;
padding: 2em;
}
.queries textarea
{
display: block;
width: 100%;
height: 8em;
}
.queries .result
{
margin-top: 1em;
overflow: auto;
}

40
web/forms/admin/queries/ui.xml Executable file
View File

@ -0,0 +1,40 @@
<vn>
<div id="title">
<h1><t>Queries</t></h1>
</div>
<div id="actions">
<htk-button
image="image/dark/ok.svg"
tip="_Execute"
on-click="_onExecuteClick"
showText="true"/>
<htk-button
image="image/dark/delete.svg"
tip="_Clean"
on-click="_onCleanClick"
showText="true"/>
</div>
<div id="form" class="queries">
<div class="box form">
<div class="form-group">
<label><t>SQL query</t></label>
<textarea
id="sql"
autocorrect="off"
autocapitalize="off"
spellcheck="false"/>
</div>
<div class="form-group">
<label><t>Result index</t></label>
<htk-spin id="result-index"/>
</div>
<div class="form-group">
<label><t>Updatable</t></label>
<htk-check id="updatable"/>
</div>
</div>
<div class="box result">
<div id="grid-holder"/>
</div>
</div>
</vn>

View File

@ -1,7 +1,7 @@
Vn.Shelves = new Class
({
Extends: Vn.Module
Extends: Vn.Form
,activate: function ()
{
@ -25,385 +25,18 @@ Vn.Shelves = new Class
,onPreviewClick: function ()
{
var batch = new Sql.Batch ();
batch.addParam ('shelf', this.$('shelf'));
batch.addParam ('wh', this.$('warehouse'));
batch.addParam ('date', this.$('date'));
batch.addParam ('family', this.$('family'));
batch.addParam ('filter', this.$('filter'));
var report = new Vn.ShelvesReport ({conn: this.conn});
report.setParams (
this.$('report-title').value,
this.$('max-amount').value,
this.$('show-packing').value,
this.$('stack').value,
batch
);
report.open ();
batch.addValues ({
'shelf': this.$('shelf').value,
'wh': this.$('warehouse').value,
'date': this.$('date').value,
'family': this.$('family').value,
'filter': this.$('filter').value,
'title': this.$('report-title').value,
'max-amount': this.$('max-amount').value,
'show-packing': this.$('show-packing').value,
'stack': this.$('stack').value,
});
this.gui.openReport ('shelves-report', batch);
}
});
Vn.ShelvesReport = new Class
({
Extends: Vn.Report
,nItem: -1
,nColors: 5
,setParams: function (title, maxAmount, showPacking, stack, batch)
{
this.title = title;
this.maxAmount = maxAmount;
this.batch = batch;
this.showPacking = showPacking;
this.stack = stack;
}
,open: function ()
{
var query =
'SELECT id, name, width, height, depth, max_height, tray_height, '+
'first_tray_elevation, tray_density, vspacing, hspacing '+
'FROM shelf WHERE id = #shelf; '+
'CALL item_organizer (#wh, #date, #family, #filter)';
this.conn.execQuery (query, this.onQueryExec.bind (this), this.batch);
}
,onQueryExec: function (resultSet)
{
// Fetch query data
var res = resultSet.fetchResult ();
res.next ();
var maxWidth = 170;
var maxHeight = 200;
var scale = maxWidth / res.get ('width');
if (res.get ('max_height') * scale > maxHeight)
scale = maxHeight / res.get ('max_height');
var shelf = this.shelf =
{
width: res.get ('width') * scale
,height: res.get ('height') * scale
,depth: res.get ('depth') * scale
,maxHeight: res.get ('max_height') * scale
,trayHeight: res.get ('tray_height') * scale
,firstTrayElevation: res.get ('first_tray_elevation') * scale
,trayDensity: res.get ('tray_density') * scale
,vspacing: res.get ('vspacing') * scale
,hspacing: res.get ('hspacing') * scale
};
var items = [];
var remainings = [];
var res = resultSet.fetchResult ();
if (res.data.length == 0)
{
Htk.Toast.showError (_('No items found, check that all fields are correct'));
return;
}
var boxScale = scale * 10;
while (res.next ())
if (!this.maxAmount || res.get ('etiquetas') <= this.maxAmount)
{
items.push ({
id: res.get ('Id_Article')
,name: res.get ('Article')
,packing: res.get ('packing')
,amount: res.get ('etiquetas')
,boxHeight: res.get ('z') * boxScale
,boxWidth: res.get ('x') * boxScale
,boxDepth: res.get ('y') * boxScale
});
}
else
{
remainings.push ({
id: res.get ('Id_Article')
,name: res.get ('Article')
,packing: res.get ('packing')
,amount: res.get ('etiquetas')
});
}
// Intializes the allocator
alloc = new Vn.Allocator ();
alloc.items = items;
alloc.shelfFunc = this.drawShelf.bind (this);
alloc.boxFunc = this.drawBox.bind (this);
alloc.stack = this.stack;
alloc.nTrays = Math.ceil (
(shelf.height - shelf.firstTrayElevation) /
(shelf.trayHeight + shelf.trayDensity)
);
alloc.width = shelf.width - shelf.hspacing * 2;
alloc.depth = shelf.depth;
alloc.trayHeight = shelf.trayHeight - shelf.vspacing;
alloc.topTrayHeight = shelf.maxHeight - shelf.vspacing
- shelf.firstTrayElevation - (alloc.nTrays - 1) * shelf.trayHeight;
// Opens the report
if (!this.createWindow ('shelves'))
return;
// Remaining amount
if (remainings.length > 0)
{
var sheet = this.doc.createElement ('div');
sheet.className = 'sheet';
this.doc.body.appendChild (sheet);
var title = this.doc.createElement ('h1');
title.className = 'title';
title.appendChild (this.doc.createTextNode (this.title));
sheet.appendChild (title);
var subtitle = this.doc.createElement ('h2');
subtitle.className = 'subtitle';
subtitle.appendChild (this.doc.createTextNode (_('Pallets')));
sheet.appendChild (subtitle);
var ul = this.doc.createElement ('ul');
sheet.appendChild (ul);
for (var i = 0; i < remainings.length; i++)
{
var li = this.doc.createElement ('li');
ul.appendChild (li);
var span = this.doc.createElement ('span');
span.className = 'item-id';
span.appendChild (this.doc.createTextNode (remainings[i].id.toLocaleString ()));
li.appendChild (span);
var span = this.doc.createElement ('span');
span.className = 'item';
span.appendChild (this.doc.createTextNode (remainings[i].name));
li.appendChild (span);
if (this.showPacking)
span.appendChild (this.doc.createTextNode (' '+ remainings[i].packing));
var span = this.doc.createElement ('span');
span.className = 'amount';
span.appendChild (this.doc.createTextNode (remainings[i].amount));
li.appendChild (span);
}
}
// Draws the shelves
alloc.run ();
this.drawShelfEnding ();
}
,drawShelf: function (allocator, item)
{
var shelf = this.shelf;
var sheet = this.doc.createElement ('div');
sheet.className = 'sheet';
this.doc.body.appendChild (sheet);
// Draws the title
var pageNumber = this.doc.createElement ('h1');
pageNumber.className = 'page-number';
pageNumber.appendChild (this.doc.createTextNode (allocator.currentShelf + 1));
sheet.appendChild (pageNumber);
var title = this.doc.createElement ('h1');
title.className = 'title';
title.appendChild (this.doc.createTextNode (this.title));
sheet.appendChild (title);
var subtitle = this.doc.createElement ('h2');
subtitle.className = 'subtitle';
subtitle.appendChild (this.doc.createTextNode (item.id.toLocaleString ()));
sheet.appendChild (subtitle);
this.drawShelfEnding ();
this.lastSubtitle = subtitle;
// Draws the shelf
var shelfDiv = this.shelfDiv = this.doc.createElement ('div');
shelfDiv.className = 'shelf';
shelfDiv.style.width = this.mm (shelf.width);
shelfDiv.style.height = this.mm (shelf.maxHeight);
sheet.appendChild (shelfDiv);
// Draws trays
var lastTrayY = shelf.firstTrayElevation;
if (shelf.trayHeight > 0)
while (lastTrayY + shelf.trayDensity < shelf.height)
{
var tray = this.doc.createElement ('div');
tray.className = 'tray';
tray.style.width = this.mm (shelf.width);
tray.style.height = this.mm (shelf.trayDensity);
tray.style.bottom = this.mm (lastTrayY);
shelfDiv.appendChild (tray);
lastTrayY += shelf.trayHeight + shelf.trayDensity;
}
}
,drawShelfEnding: function ()
{
if (this.lastSubtitle)
this.lastSubtitle.appendChild (
this.doc.createTextNode (' - '+ this.lastItem.id.toLocaleString ()));
}
,mm: function (size)
{
return size.toFixed (2) +'mm';
}
,drawBox: function (allocator, item, amount)
{
if (item.boxWidth == 0 || item.boxHeight == 0)
return;
var shelf = this.shelf;
var x = allocator.trayX + shelf.hspacing;
var y = allocator.trayY
+ shelf.firstTrayElevation + shelf.trayDensity
+ allocator.currentTray * (shelf.trayHeight + shelf.trayDensity);
var box = this.doc.createElement ('div');
box.className = 'box';
this.shelfDiv.appendChild (box);
box.style.left = this.mm (x);
box.style.bottom = this.mm (y);
box.style.width = this.mm (item.boxWidth);
box.style.height = this.mm (item.boxHeight);
if (amount == 0)
this.nItem++;
var nColor = this.nItem % this.nColors;
Vn.Node.addClass (box, 'color'+ nColor);
if (amount == 0 || allocator.firstShelfBox)
{
var fontSize = item.boxWidth / 5.2;
if (fontSize > item.boxHeight - 1)
fontSize = item.boxHeight - 1;
var boxLabel = this.doc.createElement ('div');
boxLabel.className = 'box-label';
boxLabel.style.fontSize = this.mm (fontSize);
boxLabel.appendChild (this.doc.createTextNode (item.id.toLocaleString ()));
box.appendChild (boxLabel);
}
this.lastItem = item;
}
});
Vn.Allocator = new Class
({
addShelf: function (item)
{
this.currentShelf++;
this.firstShelfBox = true;
if (this.shelfFunc)
this.shelfFunc (this, item);
}
,addTray: function (item)
{
if (this.currentTray <= 0)
{
this.addShelf (item);
this.currentTray = this.nTrays - 1;
}
else
this.currentTray--;
this.trayX = 0;
}
,addColumn: function (item)
{
if (this.trayX + this.columnWidth + item.boxWidth > this.width
|| this.currentTray == -1)
this.addTray (item);
else
this.trayX += this.columnWidth;
this.trayY = 0;
this.columnWidth = item.boxWidth;
this.lastBoxWidth = item.boxWidth;
}
,addBox: function (item, amount)
{
var trayHeight = this.trayHeight;
if (this.currentTray == this.nTrays - 1)
trayHeight = this.topTrayHeight;
if (this.trayY + item.boxHeight > trayHeight
|| item.boxWidth > this.lastBoxWidth
|| (!this.stack && amount == 0))
this.addColumn (item);
if (this.boxFunc)
this.boxFunc (this, item, amount);
this.trayY += item.boxHeight;
if (item.boxWidth < this.lastBoxWidth)
this.lastBoxWidth = item.boxWidth;
}
,run: function ()
{
this.firstShelfBox = false;
this.currentShelf = -1;
this.currentTray = -1;
this.columnWidth = 0;
this.lastBoxWidth = 0;
this.trayX = 0;
this.trayY = 0;
this.remaining = false;
for (var i = 0; i < this.items.length; i++)
{
var item = this.items[i];
var boxIncrement = Math.floor (this.depth / item.boxDepth);
if (boxIncrement < 1)
boxIncrement = 1;
for (var amount = 0; amount < item.amount; amount += boxIncrement)
{
this.addBox (item, amount);
this.firstShelfBox = false;
}
}
return this.currentShelf + 1;
}
});

View File

@ -5,14 +5,13 @@
}
.shelves .box
{
max-width: 40em;
max-width: 30em;
padding: 2em;
}
.shelves .body
.shelves .form
{
max-width: 20em;
max-width: 25em;
margin: auto;
padding: 0;
}
.shelves .form-group
{

View File

@ -1,10 +1,12 @@
<vn>
<vn-group>
<db-model property="model" id="configs-model">
SELECT c.id, c.name, c.name_prefix, c.warehouse_id, c.family_id,
c.shelf_id, c.max_amount, c.show_packing, c.stack, t.reino_id
FROM shelf_config c
JOIN vn2008.Tipos t ON t.tipo_id = c.family_id
<custom>
SELECT c.id, c.name, c.name_prefix, c.warehouse_id, c.family_id,
c.shelf_id, c.max_amount, c.show_packing, c.stack, t.reino_id
FROM shelf_config c
JOIN vn2008.Tipos t ON t.tipo_id = c.family_id
</custom>
</db-model>
</vn-group>
<div id="title">
@ -12,7 +14,7 @@
</div>
<div id="form" class="shelves">
<div class="box">
<div class="body">
<div class="form">
<div class="form-group">
<label><t>Configuration</t></label>
<htk-combo
@ -22,12 +24,18 @@
on-changed="onConfigChange"
on-ready="onConfigChange"/>
</div>
<div class="form-group">
<label><t>Date</t></label>
<htk-date-chooser id="date"/>
</div>
<div class="form-group">
<label><t>Reign</t></label>
<htk-combo id="reign">
<db-model property="model" id="reigns">
SELECT id, reino FROM vn2008.reinos
WHERE display != FALSE ORDER BY reino
<custom>
SELECT id, reino FROM vn2008.reinos
WHERE display != FALSE ORDER BY reino
</custom>
</db-model>
</htk-combo>
</div>
@ -35,10 +43,14 @@
<label><t>Family</t></label>
<htk-combo id="family">
<db-model property="model">
SELECT tipo_id, Tipo FROM vn2008.Tipos
WHERE reino_id = #reign ORDER BY Tipo
<custom>
SELECT tipo_id, Tipo FROM vn2008.Tipos
WHERE reino_id = #reign ORDER BY Tipo
</custom>
<sql-batch property="batch">
<item name="reign" param="reign"/>
<custom>
<item name="reign" param="reign"/>
</custom>
</sql-batch>
</db-model>
</htk-combo>
@ -47,20 +59,20 @@
<label><t>Store</t></label>
<htk-combo id="warehouse">
<db-model property="model" id="warehouses">
SELECT id, name FROM vn2008.warehouse
WHERE reserve ORDER BY name
<custom>
SELECT id, name FROM vn2008.warehouse
WHERE reserve ORDER BY name
</custom>
</db-model>
</htk-combo>
</div>
<div class="form-group">
<label><t>Date</t></label>
<htk-date-chooser id="date"/>
</div>
<div class="form-group">
<label><t>Shelf</t></label>
<htk-combo id="shelf">
<db-model property="model" id="shelves">
SELECT id, name FROM shelf
<custom>
SELECT id, name FROM shelf
</custom>
</db-model>
</htk-combo>
</div>

View File

@ -1,15 +1,35 @@
.users
{
padding: 1em;
min-width: 35em;
}
.users .box
{
max-width: 50em;
max-width: 30em;
margin: 0 auto;
}
.users tbody tr
.users-box
{
height: 3.4em;
padding: 1em;
border-bottom: 1px solid #DDD;
}
.users-box > button
{
float: right;
margin: 0;
}
.users-box > p
{
margin: .2em 0;
}
.users-box > p.important
{
font-size: 1.2em;
}
/* Topbar */
.action-bar .htk-search-entry
{
margin: .8em .6em;
}

View File

@ -1,26 +1,20 @@
<vn>
<vn-group>
<vn-param id="user-name"/>
<vn-hash-param key="user" param="user-name"/>
</vn-group>
<div id="title">
<h1><t>UserManagement</t></h1>
</div>
<div id="actions">
<htk-search-entry
param="user-name"/>
</div>
<div id="form" class="users">
<div class="box">
<div class="header">
<h1><t>UserManagement</t></h1>
</div>
<table class="form">
<tbody>
<tr>
<td class="label">
<label><t>UserName:</t></label>
</td>
<td>
<htk-entry>
<vn-param id="user-name"/>
</htk-entry>
</td>
</tr>
</tbody>
</table>
<div>
<htk-grid>
<db-model>
<htk-repeater form-id="iter">
<db-model property="model">
<custom>
SELECT u.id, u.name, c.Cliente
FROM account.user u
INNER JOIN vn2008.Clientes c ON u.id = c.Id_Cliente
@ -28,25 +22,38 @@
OR c.Cliente LIKE CONCAT('%', #user, '%')
OR u.id = #user
ORDER BY u.name LIMIT 200
<sql-batch property="batch">
</custom>
<sql-batch property="batch">
<custom>
<item name="user" param="user-name"/>
</sql-batch>
</db-model>
<htk-column-button
column="id"
image="image/supplant.png"
tip="_AccessAsUser"
on-clicked="onChangeUserClick"/>
<htk-column-button
column="id"
image="image/access-log.svg"
tip="_AccessLog"
on-clicked="onAccessLogClick"/>
<htk-column-spin title="_UserNumber" column="id"/>
<htk-column-text title="_UserName" column="name"/>
<htk-column-text title="_Alias" column="Cliente"/>
</htk-grid>
</div>
</custom>
</sql-batch>
</db-model>
<custom>
<div class="users-box">
<htk-button
form="iter"
column="id"
tip="_AccessAsUser"
image="image/incognito.svg"
on-click="onChangeUserClick"/>
<htk-button
form="iter"
column="id"
tip="_AccessLog"
image="image/gnome.svg"
on-click="onAccessLogClick"/>
<p class="important">
<htk-text form="iter" column="Cliente"/>
</p>
<p>
<htk-text form="iter" column="id"/> -
<htk-text form="iter" column="name"/>
</p>
<div class="clear"/>
</div>
</custom>
</htk-repeater>
</div>
</div>
</vn>

View File

@ -1,26 +1,23 @@
Vn.Users = new Class
({
Extends: Vn.Module
Extends: Vn.Form
,onChangeUserClick: function (column, value)
{
var batch = new Sql.Batch ();
batch.addValue ('user', value);
var query = 'UPDATE user_session_view SET user_id = #user';
this.conn.execQuery (query, this.userChanged.bind (this), batch);
}
,onAccessLogClick: function (column, value)
,onAccessLogClick: function (button, form)
{
this.hash.set ({
'form': 'admin/access-log'
,'user': value
,'user': form.get ('id')
});
}
,onChangeUserClick: function (button, form)
{
this.gui.supplantUser (form.get ('id'),
this.onUserSupplant.bind (this));
}
,userChanged: function ()
,onUserSupplant: function (userName)
{
this.hash.set ({'form': 'ecomerce/orders'});
}

View File

@ -1,18 +1,46 @@
.visits
{
padding: 1em;
min-width: 50em;
}
.visits .box
{
max-width: 80em;
max-width: 25em;
margin: 0 auto;
}
/* Steps */
div.step
.visits .form
{
display: none;
padding: 1.5em;
max-width: 20em;
}
.visits .summary
{
margin-top: 1em;
}
.visits .summary p
{
padding: 1.5em;
font-size: 1.4em;
text-align: right;
}
/* List */
.visits .list
{
margin-top: 1em;
}
.visits .item
{
display: block;
padding: 1em;
border-bottom: 1px solid #DDD;
}
.visits .item > p
{
margin: .1em 0;
}
.visits .item > p.important
{
font-size: 1.2em;
}

View File

@ -1,147 +1,97 @@
<vn>
<div id="title">
<h1><t>Visits</t></h1>
</div>
<div id="actions">
<htk-button
image="image/dark/refresh.svg"
tip="_Refresh"
on-click="onRefreshClick"
showText="true"/>
<htk-button
image="image/dark/user-info.svg"
tip="_Connections"
on-click="onSessionsClick"
showText="true"/>
</div>
<div id="form" class="visits">
<div class="box">
<div class="header">
<h1><t>VisitsManagement</t></h1>
<div class="action-bar">
<button on-click="onRefreshClick">
<img src="image/dark/refresh.svg" alt=""/>
<t>Refresh</t>
</button>
<button on-click="onSessionsClick">
<img src="image/dark/user-info.svg" alt=""/>
<t>ActiveSessions</t>
</button>
<button on-click="onVisitsClick">
<img src="image/dark/graph.svg" alt=""/>
<t>VisitsQuery</t>
</button>
<div class="form">
<div class="form-group">
<label><t>From</t></label>
<htk-date-chooser>
<vn-param property="param" id="from"/>
</htk-date-chooser>
</div>
</div>
<div class="step" id="sessions-step">
<table class="form">
<tbody>
<tr>
<td class="label">
<label><t>ActiveSessions:</t></label>
</td>
<td>
<htk-label>
<db-calc-sum model="sessions" id="num-sessions"/>
</htk-label>
</td>
</tr>
<tr>
<td class="label">
<label><t>NewVisitsTotal:</t></label>
</td>
<td>
<htk-label>
<db-calc-sum model="sessions" column-name="is_new"/>
</htk-label>
</td>
</tr>
</tbody>
</table>
<div>
<htk-grid>
<db-model id="sessions">
SELECT s.id, c.Cliente, e.date_time login, is_new,
s.date_time last_activity, a.platform, a.browser, a.version
FROM user_session s
JOIN visit_user e ON s.visit_user_id = e.id
JOIN visit_access c ON e.access_id = c.id
JOIN visit_agent a ON c.agent_id = a.id
JOIN visit v ON a.visit_id = v.id
JOIN account.user u ON e.user_id = u.id
JOIN vn2008.Clientes c ON e.user_id = c.Id_cliente
ORDER BY last_activity DESC
</db-model>
<htk-column-spin title="_SessionNumber" column="id"/>
<htk-column-text title="_User" column="Cliente"/>
<htk-column-date title="_Login" column="login" format="%a, %T"/>
<htk-column-date title="_LastActivity" column="last_activity" format="%a, %T"/>
<htk-column-text title="_SO" column="platform"/>
<htk-column-text title="_Browser" column="browser"/>
<htk-column-text title="_Version" column="version"/>
<htk-column-check title="_NewVisit" column="is_new"/>
</htk-grid>
</div>
</div>
<div class="step" id="visits-step">
<table class="form">
<tbody>
<tr>
<td class="label">
<label><t>FromDate:</t></label>
</td>
<td>
<htk-date-chooser>
<vn-param id="date-from"/>
</htk-date-chooser>
</td>
</tr>
<tr>
<td class="label">
<label><t>ToDate:</t></label>
</td>
<td>
<htk-date-chooser>
<vn-param id="date-to"/>
</htk-date-chooser>
</td>
</tr>
<tr>
<td class="label">
<label><t>VisitsTotal:</t></label>
</td>
<td>
<htk-label>
<db-calc-sum model="visits" column-name="visits"/>
</htk-label>
</td>
</tr>
<tr>
<td class="label">
<label><t>NewVisitsTotal:</t></label>
</td>
<td>
<htk-label>
<db-calc-sum model="visits" column-name="new_visits"/>
</htk-label>
</td>
</tr>
</tbody>
</table>
<div>
<htk-grid empty-message="SelectDateInterval">
<db-model id="visits">
SELECT browser
,MIN(CAST(version AS DECIMAL(4,1))) min_version
,MAX(CAST(version AS DECIMAL(4,1))) max_version
,MAX(e.date_time) last_visit
,COUNT(DISTINCT c.id) visits
,SUM(is_new) new_visits
FROM visit_user e
JOIN visit_access c ON e.access_id = c.id
JOIN visit_agent a ON c.agent_id = a.id
JOIN visit v ON a.visit_id = v.id
WHERE e.date_time BETWEEN TIMESTAMP(#from,'00:00:00') AND TIMESTAMP(#to,'23:59:59')
GROUP BY browser ORDER BY visits DESC
<sql-batch property="batch">
<item name="from" param="date-from"/>
<item name="to" param="date-to"/>
</sql-batch>
</db-model>
<htk-column-text title="_Browser" column="browser"/>
<htk-column-spin title="_MinVersion" column="min_version" digits="1"/>
<htk-column-spin title="_MaxVersion" column="max_version" digits="1"/>
<htk-column-date title="_LastVisit" column="last_visit" format="_%a, %e %b %Y at %T"/>
<htk-column-spin title="_Visits" column="visits"/>
<htk-column-spin title="_NewVisits" column="new_visits"/>
</htk-grid>
<div class="form-group">
<label><t>To</t></label>
<htk-date-chooser>
<vn-param property="param" id="to"/>
</htk-date-chooser>
</div>
</div>
</div>
<div class="summary box">
<p>
<htk-text>
<db-calc-sum
property="param"
model="visits"
column-name="visits"/>
</htk-text>
<t>visits</t>,
<htk-text>
<db-calc-sum
property="param"
model="visits"
column-name="new_visits"/>
</htk-text>
<t>news</t>
</p>
</div>
<div class="list box">
<htk-repeater form-id="iter" empty-message="_Select date interval">
<db-model property="model" id="visits">
<custom>
SELECT browser
,MIN(CAST(version AS DECIMAL(4,1))) min_version
,MAX(CAST(version AS DECIMAL(4,1))) max_version
,MAX(e.date_time) last_visit
,COUNT(DISTINCT c.id) visits
,SUM(is_new) new_visits
FROM visit_user e
JOIN visit_access c ON e.access_id = c.id
JOIN visit_agent a ON c.agent_id = a.id
JOIN visit v ON a.visit_id = v.id
WHERE e.date_time BETWEEN TIMESTAMP(#from,'00:00:00') AND TIMESTAMP(#to,'23:59:59')
GROUP BY browser ORDER BY visits DESC
</custom>
<sql-batch property="batch">
<custom>
<item name="from" param="from"/>
<item name="to" param="to"/>
</custom>
</sql-batch>
</db-model>
<custom>
<div class="item">
<p class="important">
<htk-text form="iter" column="browser"/>
<htk-text form="iter" column="min_version"/> -
<htk-text form="iter" column="max_version"/>
</p>
<p>
<htk-text form="iter" column="visits"/>
<t>visits</t>,
<htk-text form="iter" column="new_visits"/>
<t>news</t>
</p>
<p>
<htk-text form="iter" column="last_visit" format="_%a, %e %b %Y at %T"/>
</p>
</div>
</custom>
</htk-repeater>
</div>
</div>
</vn>

View File

@ -1,44 +1,22 @@
Vn.Visits = new Class
({
Extends: Vn.Module
Extends: Vn.Form
,activate: function ()
{
this.$('date-to').value = new Date ();
this.$('num-sessions').func = this.sessionsFunc;
this.onSessionsClick ();
}
,showStep: function (stepId)
{
if (this.currentStep)
this.currentStep.style.display = 'none';
this.currentStep = this.$(stepId);
this.currentStep.style.display = 'inline';
this.$('from').value = new Date ();
this.$('to').value = new Date ();
}
,onRefreshClick: function ()
{
this.model.refresh ();
this.$('visits').refresh ();
}
,onSessionsClick: function ()
{
this.showStep ('sessions-step');
this.model = this.$('sessions');
}
,onVisitsClick: function ()
{
this.showStep ('visits-step');
this.model = this.$('visits');
}
,sessionsFunc: function ()
{
return 1;
this.hash.set ({'form': 'admin/connections'});
}
});

View File

@ -1,7 +1,7 @@
Vn.Packages = new Class
({
Extends: Vn.Module
Extends: Vn.Form
,onShowClick: function (column, agencyId)
{

View File

@ -1,12 +1,14 @@
<vn>
<div id="title">
<h1><t>ListByAgency</t></h1>
</div>
<div id="form" class="packages">
<div class="box">
<div class="header">
<h1><t>ListByAgency</t></h1>
</div>
<htk-grid>
<db-model property="model">
CALL vn2008.agencia_volume ()
<custom>
CALL vn2008.agencia_volume ()
</custom>
</db-model>
<htk-column-button
column="agency_id"

View File

@ -1,11 +1,6 @@
Vn.Provinces = new Class
({
Extends: Vn.Module
,onReturnClick: function ()
{
window.history.back();
}
Extends: Vn.Form
});

View File

@ -1,26 +1,22 @@
<vn>
<vn-group>
<vn-param id="agency">
<vn-hash-param key="agency"/>
</vn-param>
<vn-param id="agency"/>
<vn-hash-param key="agency" param="agency"/>
</vn-group>
<div id="title">
<h1><t>ByProvince</t></h1>
</div>
<div id="form" class="provinces">
<div class="box">
<div class="header">
<h1><t>ByProvince</t></h1>
<div class="action-bar">
<button on-click="onReturnClick">
<img src="image/dark/go-previous.svg" alt=""/>
<t>Return</t>
</button>
</div>
<div class="clear"/>
</div>
<htk-grid>
<db-model>
CALL vn2008.desglose_volume (#agency)
<db-model property="model">
<custom>
CALL vn2008.desglose_volume (#agency)
</custom>
<sql-batch property="batch">
<item name="agency" param="agency"/>
<custom>
<item name="agency" param="agency"/>
</custom>
</sql-batch>
</db-model>
<htk-column-text title="_Province" column="Provincia"/>

View File

@ -1,6 +1,6 @@
Vn.About = new Class
({
Extends: Vn.Module
Extends: Vn.Form
});

View File

@ -3,10 +3,49 @@
{
padding: 1em;
}
.about .cols
{
max-width: 85em;
margin: 0 auto;
}
@media screen and (min-width: 1000px) /* and (max-width: 1399px) */
{
.about .cols
{
column-count: 2;
-moz-column-count: 2;
-webkit-column-count: 2;
}
}/*
@media screen and (min-width: 1400px)
{
.about .cols
{
column-count: 3;
-moz-column-count: 3;
-webkit-column-count: 3;
}
}
@media screen and (min-width: 2000px)
{
.about .cols
{
column-count: 4;
-moz-column-count: 4;
-webkit-column-count: 4;
}
}*/
.about .box
{
max-width: 50em;
margin: 0 auto;
margin-bottom: 1em;
padding: 2em;
}
.about h1
{
padding: 0;
margin: 0;
font-weight: normal;
font-size: 1.6em;
}
.about h2
{
@ -20,28 +59,22 @@
text-align: center;
font-size: 1.2em;
font-weight: normal;
margin: 1em;
color: #4A1;
padding: 1em;
color: #00796B;
}
.about p
{
width: 90%;
display: block;
margin: 1em auto;
margin: 1em 0;
}
.summary
.about p.summary
{
padding-bottom: 1em;
}
.summary p
{
max-width: 30em;
max-width: 26em;
text-align: center;
background-color: #FF8;
padding: 1em;
border-radius: 0.1em;
box-shadow: 0 0.2em 0.2em #AAA;
margin: 2em auto;
margin: 1.5em auto;
}
/* Images */

View File

@ -1,10 +1,13 @@
<vn>
<div id="title">
<h1><t>About</t></h1>
</div>
<div id="form" class="about">
<div class="box">
<div>
<div class="header">
<h1><t>QualityAndVariety</t></h1>
</div>
<div class="cols">
<div class="box">
<h1>
<t>QualityAndVariety</t>
</h1>
<p><t>MaximumFreshness</t></p>
<h3><t>SquareMeters</t></h3>
<img src="forms/cms/about/image/store.png" alt="store"/>
@ -17,26 +20,26 @@
</p>
<img src="forms/cms/about/image/palletizing.png" alt="palletizing"/>
</div>
<div>
<div class="header">
<h1><t>WhatMakeUsDifferent</t></h1>
</div>
<div class="box">
<h1>
<t>WhatMakeUsDifferent</t>
</h1>
<p><t>DesignVariety</t></p>
<img src="forms/cms/about/image/differentiates_us.png" alt="differentiates_us"/>
<p><t>AdaptToYourNeeds</t></p>
<h3><t>TheBestQuality</t></h3>
</div>
<div>
<div class="header">
<h1><t>AtYourService</t></h1>
</div>
<div class="box">
<h1>
<t>AtYourService</t>
</h1>
<h2><t>BuyersAndTraders</t></h2>
<img src="forms/cms/about/image/commercial.png" alt="commercial"/>
</div>
<div>
<div class="header">
<h1><t>Training</t></h1>
</div>
<div class="box">
<h1>
<t>Verdnatura training</t>
</h1>
<p><t>GoodTraining</t></p>
<img src="forms/cms/about/image/training.png" alt="training"/>
<p><t>SpecialTrainingPrices</t></p>
@ -44,10 +47,10 @@
<h2><t>YoutubeChannel</t></h2>
<img src="forms/cms/about/image/youtube.png" alt="youtube"/>
</div>
<div>
<div class="header">
<h1><t>HowWeWork</t></h1>
</div>
<div class="box">
<h1>
<t>HowWeWork</t>
</h1>
<p><t>AalsmeerAuction</t></p>
<img src="forms/cms/about/image/auction.png" alt="auction"/>
<p><t>BeforeAuction</t></p>
@ -85,9 +88,7 @@
<p><t>AfterEmbedAgency</t></p>
<img src="forms/cms/about/image/agencies.png" alt="agencies"/>
<p><t>FreshnessGuaranteed</t></p>
</div>
<div class="summary">
<p>
<p class="summary">
<t>AboutSummary</t>
<img src="image/logo.svg" alt="Verdnatura"/>
</p>

View File

@ -1,7 +1,7 @@
Vn.Contact = new Class
({
Extends: Vn.Module
Extends: Vn.Form
,activate: function ()
{

View File

@ -26,7 +26,7 @@ header ('Content-Type: application/json');
if ($paramsOk && isset ($_SESSION['captcha'])
&& $_POST['captcha'] == $_SESSION['captcha'])
{
mail ('nuria@verdnatura.es', 'Verdnatura', print_r ($_POST, TRUE),
mail ('comunicacion@verdnatura.es', 'Verdnatura', print_r ($_POST, TRUE),
'From: Verdnatura <www-data@verdnatura.es>');
echo json_encode (TRUE);

View File

@ -5,19 +5,19 @@
}
.contact .box
{
max-width: 40em;
max-width: 30em;
padding: 2em;
}
.contact p
.contact .form
{
position: relative;
text-align: center;
text-align: left;
max-width: 25em;
margin: 1em auto;
margin: 0 auto;
}
.contact form
{
margin: 0 auto;
max-width: 25em;
}
.contact form p
{
@ -25,21 +25,6 @@
display: block;
margin-top: 2em;
}
div.form-group
{
padding: 0.4em;
}
.contact form label
{
display: block;
margin-bottom: 0.5em;
}
.contact input,
.contact textarea
{
margin: 0;
width: 100%;
}
.contact textarea
{
height: 5em;
@ -51,6 +36,10 @@ div.form-group
margin-top: 1em;
padding: 0.6em;
}
.contact .mandatory-message
{
font-size: .9em;
}
/* Captcha */

View File

@ -1,10 +1,10 @@
<vn>
<div id="title">
<h1><t>IWantCustomer</t></h1>
</div>
<div id="form" class="contact">
<div class="box">
<div class="header">
<h1><t>IWantCustomer</t></h1>
</div>
<div class="body">
<div class="form">
<p>
<t>FillFormData</t>
</p>
@ -38,13 +38,13 @@
</div>
<div class="form-group captcha">
<label><t>Anti-Spam</t></label>
<img alt="Captcha" id="captcha-img"/>
<input type="text" name="captcha"/>
<img alt="Captcha" id="captcha-img"/>
</div>
<p>
<p class="mandatory-message">
<t>AllFieldsMandatory</t>
</p>
<button class="flat">
<button class="thin">
<t>Send</t>
</button>
</form>

View File

@ -1,6 +1,11 @@
Vn.Home = new Class
({
Extends: Vn.Module
Extends: Vn.Form
,onStartOrderClick: function ()
{
this.hash.set ({'form': 'ecomerce/catalog'});
}
});

View File

@ -1,14 +1,22 @@
/* News panel */
.home
{
margin: .5em;
}
.column
{
margin: .5em;
max-width: 120em;
}
.action-bar button.start-order
{
background-color: #EF5350;
margin: .7em;
padding: .5em;
box-shadow: 0 0 0.4em rgba(1, 1, 1, 0.4);
}
.action-bar button.start-order:hover
{
background-color: #F44336;
}
/* New */
@ -19,7 +27,7 @@
color: #222;
border: none;
border-radius: 0.1em;
box-shadow: 0 0.2em 0.2em #CCC;
box-shadow: 0 0.2em 0.2em rgba(1, 1, 1, 0.2);
margin: .5em;
}
.new .top

View File

@ -1,29 +1,45 @@
<vn>
<div id="form" class="home">
<div class="column mansonry" id="news-column">
<htk-repeater form-id="new">
<db-model>
SELECT title, date_time, text, image, id FROM news
WHERE tag != 'course'
ORDER BY priority, date_time DESC
</db-model>
<template>
<div class="masonry-box">
<div class="new">
<div class="top">
<h2><htk-text form="new" column="title"/></h2>
<p class="new-info">
<htk-text format="_%a, %e %b %Y" form="new" column="date_time"/>
</p>
<div class="new-text">
<htk-html form="new" column="text"/>
</div>
</div>
<htk-image directory="news/full" form="new" column="image"/>
</div>
</div>
</template>
</htk-repeater>
<div id="title">
<h1><t>Home</t></h1>
</div>
<div id="actions" class="catalog-actions">
<htk-button
class="start-order"
image="image/dark/new-order.svg"
tip="_Start order"
on-click="onStartOrderClick"
showText="true"/>
</div>
<div id="form" class="home">
<div class="column mansonry" id="news-column">
<htk-repeater form-id="new">
<db-model property="model">
<custom>
SELECT title, date_time, text, image, id FROM news
WHERE tag != 'course'
ORDER BY priority, date_time DESC
</custom>
</db-model>
<custom>
<div class="masonry-box">
<div class="new">
<div class="top">
<h2><htk-text form="new" column="title"/></h2>
<!--
<p class="new-info">
<htk-text format="_%a, %e %b %Y" form="new" column="date_time"/>
</p>
-->
<div class="new-text">
<htk-html form="new" column="text"/>
</div>
</div>
<htk-image directory="news/full" form="new" column="image" editable="false"/>
</div>
</div>
</custom>
</htk-repeater>
<div class="clear"/>
</div>
</div>
</vn>

View File

@ -3,7 +3,7 @@ var gmapsIsLoaded = false;
Vn.Location = new Class
({
Extends: Vn.Module
Extends: Vn.Form
,locations: null

View File

@ -1,3 +1,6 @@
<vn>
<div id="title">
<h1><t>Location</t></h1>
</div>
<div id="form" class="location"/>
</vn>

View File

@ -1,5 +1,5 @@
Vn.Training = new Class
({
Extends: Vn.Module
Extends: Vn.Form
});

View File

@ -1,13 +1,18 @@
<vn>
<div id="title">
<h1><t>Training</t></h1>
</div>
<div id="form" class="training">
<div class="column masonry" id="news-column">
<htk-repeater form-id="new">
<db-model id="news">
SELECT title, date_time, text, image, id FROM news
WHERE tag = 'course'
ORDER BY priority, date_time DESC
<db-model property="model">
<custom>
SELECT title, date_time, text, image, id FROM news
WHERE tag = 'course'
ORDER BY priority, date_time DESC
</custom>
</db-model>
<template>
<custom>
<div class="masonry-box">
<div class="new">
<div class="top">
@ -22,7 +27,7 @@
<htk-image directory="news/full" form="new" column="image"/>
</div>
</div>
</template>
</custom>
</htk-repeater>
</div>
</div>

View File

@ -1,9 +1,9 @@
<vn>
<div id="title">
<h1><t>AboutCompany</t></h1>
</div>
<div id="form" class="why">
<div class="box">
<div class="header">
<h1><t>AboutCompany</t></h1>
</div>
<div class="body">
<ul>
<li><t>BecauseOurBigCatalog</t></li>

View File

@ -1,6 +1,6 @@
Vn.Why = new Class
({
Extends: Vn.Module
Extends: Vn.Form
});

View File

@ -1,27 +1,21 @@
Vn.Basket = new Class
({
Extends: Vn.Module
Extends: Vn.Form
,open: function ()
{
if (this.basketChecked)
this.parent ();
}
this.close ();
this.isOpen = true;
,activate: function ()
{
Vn.BasketChecker.check (this.conn,
this.onBasketCheck.bind (this));
}
,onBasketCheck: function (isOk)
{
if (!isOk)
return;
this.basketChecked = true;
this.open ();
if (isOk)
this.loadUi ();
}
,onConfigureClick: function ()
@ -40,55 +34,21 @@ Vn.Basket = new Class
this.hash.set ({'form': 'ecomerce/confirm'});
}
,amountRender: function (renderer, form)
,repeaterFunc: function (res, form)
{
var amount = form.get ('amount');
var grouping = form.get ('grouping');
if (amount && grouping)
renderer.value = amount / grouping;
else
renderer.value = null;
res.$('subtotal').value = this.subtotal (form);
}
,onAmountChange: function (renderer, row, newValue)
,onDeleteClick: function (button, form)
{
var model = this.$('items');
model.set (row, 'amount', newValue * model.get (row, 'grouping'));
}
,featuresRender: function (renderer, form)
{
renderer.value = form.get ('Medida') +' '+ form.get ('Categoria') +' '+ form.get ('Color');
}
,stemsRender: function (renderer, form)
{
renderer.value = Vn.Value.format (form.get ('price'), '%.2d€') +' x '+ form.get ('amount');
if (form.get ('amount') > form.get ('available'))
renderer.td.className = 'available-exceeded';
else
renderer.td.className = '';
}
,subtotalRender: function (renderer, form)
{
renderer.value = this.subtotal (form);
if (confirm (_('ReallyDelete')))
form.deleteRow ();
}
,subtotal: function (form)
{
return form.get ('amount') * form.get ('price');
}
,availableRender: function (renderer, form)
{
if (form.get ('amount') > form.get ('avail'))
renderer.value = 'unavailable';
else
renderer.value = 'invisible';
}
});

View File

@ -1,18 +1,12 @@
.basket
{
padding: 1em;
min-width: 25em;
}
.basket .box
{
max-width: 45em;
max-width: 30em;
margin: 0 auto;
}
.basket .form
{
padding: 1em;
margin: 0;
background-color: #009688;
padding: 0 2em;
}
.basket .form > p
{
@ -21,12 +15,55 @@
color: white;
text-align: right;
}
.basket .config
.basket .head
{
padding: 1.8em 0;
margin: 0;
border-bottom: 1px solid #DDD;
}
.basket .head p
{
margin: 0;
padding: 0;
font-size: 1.4em;
text-align: right;
}
/* Rows */
/* Lines */
.basket .lines
{
padding: .8em 0;
}
.basket .line
{
padding: 1em 0;
}
.basket .line > .delete
{
margin: -0.5em;
margin-top: .3em;
margin-right: .5em;
float: left;
}
.basket .line > .photo
{
margin-right: 1em;
float: left;
border-radius: 50%;
height: 3.2em;
}
.basket .line > p
{
margin: .1em 0;
margin-left: 7.5em;
}
.basket .line .subtotal
{
float: right;
}
/* Fields */
.basket td.available-exceeded input
{

View File

@ -1,54 +1,79 @@
<vn>
<div id="title">
<h1><t>ShoppingBasket</t></h1>
</div>
<div id="actions">
<htk-button
image="image/dark/ok.svg"
tip="_Checkout"
on-click="onCheckoutClick"
show-text="true"/>
<htk-button
image="image/dark/view-dual.svg"
tip="_Catalog"
on-click="onCatalogClick"
show-text="true"/>
<htk-button
image="image/dark/preferences.svg"
tip="_ConfigureOrder"
on-click="onConfigureClick"
show-text="true"/>
</div>
<div id="form" class="basket">
<div class="box">
<div class="header">
<h1><t>Basket</t></h1>
<div class="action-bar">
<button on-click="onConfigureClick" title="_ConfigureOrder">
<img class="config" src="image/dark/preferences.svg" alt=""/>
<t>ConfigureOrder</t>
</button>
<button on-click="onCatalogClick">
<img src="image/dark/menu.svg" alt=""/>
<t>Catalog</t>
</button>
<button on-click="onCheckoutClick">
<img src="image/dark/ok.svg" alt=""/>
<t>Checkout</t>
</button>
</div>
<div class="clear"/>
</div>
<div>
<htk-grid show-header="false">
<db-model id="items" updatable="true">
SELECT i.id, i.amount, i.price, a.Article, a.Categoria,
a.Medida, a.Tallos, a.Color, o.Abreviatura, a.Foto
FROM basket_item i
INNER JOIN vn2008.Articles a ON a.Id_Article = i.item_id
LEFT JOIN vn2008.Origen o ON a.id_origen = o.id;
</db-model>
<htk-column-image
column="Foto"
directory="catalog"
subdir="50x50"
show-full="true"
full-dir="900x900"
class="icon"/>
<htk-column-text title="_Item" column="Article"/>
<htk-column-text renderer="featuresRender"/>
<htk-column-text title="_Amount" column="amount" renderer="stemsRender"/>
<htk-column-spin unit="€" digits="2" renderer="subtotalRender"/>
</htk-grid>
<div class="form">
<div class="box">
<div class="head">
<p>
<t>OrderTotal</t>
<t>Total</t>
<htk-text format="%.2d€">
<db-calc-sum func="subtotal" model="items"/>
<db-calc-sum property="param" func="subtotal" model="items"/>
</htk-text>
</p>
</div>
<div class="lines">
<htk-repeater form-id="iter" renderer="repeaterFunc">
<db-model id="items" property="model" updatable="true">
<custom>
SELECT i.id, i.amount, i.price, a.Article, a.Categoria,
a.Medida, a.Tallos, a.Color, o.Abreviatura, a.Foto
FROM basket_item i
JOIN vn2008.Articles a ON a.Id_Article = i.item_id
LEFT JOIN vn2008.Origen o ON a.id_origen = o.id
</custom>
</db-model>
<custom>
<div class="line">
<htk-button
form="iter"
column="ticket_id"
class="delete"
tip="_Remove"
image="image/delete.svg"
on-click="onDeleteClick"/>
<htk-image
form="iter"
column="Foto"
class="photo"
directory="catalog"
subdir="200x200"
show-full="true"
full-dir="900x900"/>
<p class="concept">
<htk-text form="iter" column="Article"/>
<htk-text form="iter" column="Medida"/>
<htk-text form="iter" column="Categoria"/>
</p>
<p class="amount">
<htk-text form="iter" column="amount"/> x
<htk-text form="iter" column="price" format="%.2d€"/>
<span class="subtotal">
<htk-text id="subtotal" format="%.2d€"/>
</span>
</p>
<div class="clear"/>
</div>
</custom>
</htk-repeater>
</div>
</div>
</div>
</div>
</vn>

View File

@ -1,17 +1,16 @@
Vn.Catalog = new Class
({
Extends: Vn.Module
Extends: Vn.Form
,_menuShown: false
,open: function ()
{
if (this.basketChecked)
this.parent ();
}
this.close ();
this.isOpen = true;
,activate: function ()
{
if (!Vn.Url.getQuery ('guest'))
if (!Vn.Cookie.check ('hedera_guest'))
{
Vn.BasketChecker.check (this.conn,
this.onBasketCheck.bind (this));
@ -19,27 +18,65 @@ Vn.Catalog = new Class
else
{
var query = 'CALL basket_configure_for_guest ()';
this.conn.execQuery (query, this.onBasketForGuest.bind (this));
this.conn.execQuery (query, this.loadUi.bind (this));
}
}
,onBasketForGuest: function ()
{
this.onBasketCheck (true);
}
,onBasketCheck: function (isOk)
{
if (!isOk)
return;
if (isOk)
this.loadUi ();
}
,activate: function ()
{
document.body.appendChild (this.$('right-panel'));
this.basketChecked = true;
this.open ();
this.popup = new Htk.Popup ();
this.popup.setChildNode (this.$('lots-popup'));
this.$('items-model').setInfo ('a', 'Articles', 'vn2008', ['item_id']);
if (Vn.Cookie.check ('hedera_view'))
this.setView (Vn.Cookie.getInt ('hedera_view'));
else
this.setView (Vn.Catalog.View.GRID);
}
,deactivate: function ()
{
this.hideMenu ();
this.gui.$('top-bar').style.backgroundColor = '';
Vn.Node.remove (this.$('right-panel'));
}
,setView: function (view)
{
if (view === Vn.Catalog.View.GRID)
{
this.$('view-button').setProperties ({
image: 'image/dark/view-list.svg',
tip: _('List view')
});
this.view = Vn.Catalog.View.GRID;
var className = 'grid-view';
}
else
{
this.$('view-button').setProperties ({
image: 'image/dark/view-grid.svg',
tip: _('Grid view')
});
this.view = Vn.Catalog.View.LIST;
var className = 'list-view';
}
var node = this.$('grid-view').getNode ();
node.className = className;
Vn.Cookie.set ('hedera_view', this.view);
}
,onSwitchViewClick: function ()
{
this.setView (this.view === Vn.Catalog.View.LIST ?
Vn.Catalog.View.GRID : Vn.Catalog.View.LIST);
}
,onBasketReady: function (form)
@ -56,6 +93,33 @@ Vn.Catalog = new Class
link.href = this.hash.make ({'type': form.get ('tipo_id')}, true);
}
,onItemsChange: function (model, status)
{
if (status !== Db.Model.Status.CLEAN)
this.$('order').style.display = 'block';
else
this.$('order').style.display = 'none';
}
,onOrderChange: function (e)
{
var value = e.target.value;
var sortField = value.substr (2);
var sortWay = value.charAt (0) === 'A' ?
Db.Model.SortWay.ASC : Db.Model.SortWay.DESC;
if (sortField)
this.$('items-model').sortByName (sortField, sortWay);
this.hideMenu ();
}
,onFilterChange: function (param, newValue)
{
if (newValue)
this.hideMenu ();
}
,realmRenderer: function (builder, form)
{
var link = builder.$('link');
@ -65,43 +129,72 @@ Vn.Catalog = new Class
});
var img = builder.$('image');
img.src = 'image/family/'+ form.get ('id') +'.svg';
img.title = form.get ('reino');
img.src = 'image/family_dark/'+ form.get ('id') +'.svg';
img.title = form.get ('name');
img.alt = img.title;
}
,onTypeChange: function ()
,onRealmChange: function (param, newValue)
{
if (Vn.isMobile () && this.$('type').value)
this.hideMenu ();
if (newValue)
{
this.$('filters').style.display = 'block';
this.$('realm-msg').style.display = 'none';
}
else
{
this.$('filters').style.display = 'none';
this.$('realm-msg').style.display = 'block';
}
this.refreshTitleColor ();
this.refreshFilter (newValue, undefined);
}
,onTypeChange: function (param, newValue)
{
this.onFilterChange (param, newValue);
this.refreshTitle ();
this.refreshFilter (undefined, newValue);
}
,refreshFilter: function (realm, type)
{
var batch = this.$('filter-batch');
batch.block ();
this.$('realm-value').value = realm;
this.$('type-value').value = type;
this.$('search').value = undefined;
this.$('color').value = undefined;
this.$('origin').value = undefined;
this.$('category').value = undefined;
this.$('producer').value = undefined;
batch.unblock ();
batch.changed ();
}
,refreshTitleColor: function ()
{
var realms = this.$('realms-model');
if (!realms.ready)
return;
this.refreshTitle ();
var color = null;
var realm = this.$('realm').value;
if (this.$('type').value)
if (realm)
{
var row = realms.search ('id', this.$('realm').value);
var row = realms.search ('id', realm);
if (row != -1)
color = '#'+ realms.get (row, 'color');
}
this.$('header').style.backgroundColor = color;
var tr = this.$('items-grid').getNode ()
.getElementsByTagName ('thead')[0]
.getElementsByTagName ('tr')[0];
//.querySelector ('thead tr');
tr.style.backgroundColor = color;
this.gui.$('top-bar').style.backgroundColor = color;
}
,refreshTitle: function (title)
,refreshTitle: function ()
{
var types = this.$('types-model');
@ -109,73 +202,56 @@ Vn.Catalog = new Class
return;
var title = _('Catalog');
var type = this.$('type').value;
if (this.$('type').value)
if (type)
{
var row = types.search ('tipo_id', this.$('type').value);
var row = types.search ('tipo_id', type);
if (row != -1)
title = types.get (row, 'Tipo');
}
else if (this.$('search-entry').value)
title = _('SearchResults');
Vn.Node.setText (this.$('title'), title);
}
,onSearch: function (event)
{
var searchTags = this.$('search-entry').value;
searchTags = searchTags != '' ? searchTags : undefined;
var batch = this.$('batch');
batch.block ();
this.$('search').value = searchTags;
if (searchTags)
{
this.$('type').value = undefined;
this.$('realm').value = undefined;
title = types.get (row, 'name');
}
batch.unblock ();
batch.changed ();
Vn.Node.setText (this.$('title-text'), title);
}
,onMenuClick: function (event)
,onRightPanelClick: function (event)
{
event.stopPropagation ();
}
,onShowMenuClick: function (event)
{
this._menuShown = true;
event.stopPropagation ();
this.gui.showBackground ();
this.$('menu').style.display = 'block';
Vn.Node.addClass (this.$('right-panel'), 'show');
this.hideMenuCallback = this.hideMenu.bind (this);
document.addEventListener ('click', this.hideMenuCallback);
}
,hideMenu: function ()
{
if (!this._menuShown)
return;
this.gui.hideBackground ();
this.$('menu').style.display = 'none';
Vn.Node.removeClass (this.$('right-panel'), 'show');
document.removeEventListener ('click', this.hideMenuCallback);
this.hideMenuCallback = null;
}
,onBasketClick: function ()
{
if (!Vn.Url.getQuery ('guest'))
if (!Vn.Cookie.check ('hedera_guest'))
this.hash.set ({'form': 'ecomerce/basket'});
else
Htk.Toast.showError (_('YouMustBeLoggedIn'));
}
,onConfigClick: function ()
,onConfigureClick: function ()
{
if (!Vn.Url.getQuery ('guest'))
if (!Vn.Cookie.check ('hedera_guest'))
this.hash.set ({'form': 'ecomerce/checkout'});
else
Htk.Toast.showError (_('YouMustBeLoggedIn'));
@ -183,17 +259,7 @@ Vn.Catalog = new Class
,nameRenderer: function (renderer, form)
{
var producer = form.get ('producer');
// if (producer)
// producer = producer.toUpperCase ();
renderer.subtitle = producer;
}
,featuresRender: function (renderer, form)
{
renderer.value = form.get ('Medida') +' '+ form.get ('Categoria') +' '+ form.get ('Color');
renderer.subtitle = form.get ('producer');
}
,amountRender: function (renderer, form)
@ -227,10 +293,35 @@ Vn.Catalog = new Class
column.td.className = '';
}
}
,onInfoClick: function (button, form)
{
var descNode = this.$('description');
Vn.Node.removeChilds (descNode);
var desc = form.get ('description');
if (!desc)
desc = _('No info available');
descNode.appendChild (document.createTextNode (desc));
this.$('desc-popup').show (button.getNode ());
}
,onGridAddItemClick: function (button, form)
{
this.showAmountPopup (button.getNode (), form.row);
}
,onAddItemClick: function (column, value, row, button)
{
if (Vn.Url.getQuery ('guest'))
this.showAmountPopup (button, row);
}
,showAmountPopup: function (button, row)
{
if (Vn.Cookie.check ('hedera_guest'))
{
Htk.Toast.showError (_('YouMustBeLoggedIn'));
return;
@ -241,7 +332,7 @@ Vn.Catalog = new Class
this.itemRow = row;
this.onEraseClick ();
this.popup.show (button);
this.$('lots-popup').show (button);
}
,onAddLotClick: function (column, value, row, button)
@ -305,16 +396,209 @@ Vn.Catalog = new Class
sprintf (_('Added%dOf%s'), amountSum, itemName));
}
this.popup.hide ();
this.$('lots-popup').hide ();
}
,onStatusChange: function (model)
{
if (this.popup)
this.popup.reset ();
this.$('lots-popup').reset ();
}
,gridRenderer: function (res, form)
{
if (!form.get ('description'))
{
var button = res.$('info-button').getNode ();
button.style.display = 'none';
}
}
});
Vn.Catalog.extend
({
View: {
LIST: 0,
GRID: 1
}
});
Vn.Filter = new Class
({
Extends: Htk.Field
,Tag: 'vn-filter'
,Child: 'model'
,Properties:
{
model:
{
type: Db.Model
,set: function (x)
{
x.batch = this._batch;
this._model = x;
this._select.model = x;
}
,get: function ()
{
return this._model;
}
},
placeholder:
{
type: String
,set: function (x)
{
this._select.placeholder = x;
this._placeholder = x;
}
,get: function ()
{
return this._placeholder;
}
},
filter:
{
type: Sql.Filter
,set: function (x)
{
this._filter = x;
this._batch.addObject ('filter', x);
}
,get: function ()
{
return this._filter;
}
},
}
,_valueColumnIndex: 0
,_showColumnIndex: 1
,initialize: function (props)
{
this.createElement ('div');
this.node.className = 'vn-filter';
this._select = new Htk.Select ();
this._select.on ('mousedown', this._onMouseDown, this);
this._select.on ('changed', this._onChange, this);
this._select.on ('ready', this._onReady, this);
this.node.appendChild (this._select.getNode ());
this._ul = document.createElement ('ul');
this.node.appendChild (this._ul);
this._batch = new Sql.Batch ();
this.parent (props);
}
,_onMouseDown: function (e)
{
if (this._model && this._model.status === Db.Model.Status.CLEAN)
this._model.refresh ();
}
,_onCloseClick: function (li)
{
this._removeSelectionNode ();
this._changeValue (undefined);
}
,_removeSelectionNode: function ()
{
if (this._lastLi)
{
Vn.Node.remove (this._lastLi);
this._lastLi = null;
this._label = null;
}
}
,_onChange: function ()
{
if (this._select.value === null
|| this._select.value === undefined)
return;
this._realSetValue (this._select.value);
}
,_onReady: function ()
{
if (this._emptyLabel)
this._refreshLabel ();
}
,_changeValue: function (newValue)
{
this._batch.block ();
this.value = newValue;
this._batch.unblock ();
}
,_onTimeout: function ()
{
this._select.value = null;
}
,putValue: function (value)
{
this._onMouseDown ();
this._realSetValue (value);
}
,_realSetValue: function (value)
{
this._removeSelectionNode ();
if (value === null || value === undefined)
return;
var li = this._lastLi = document.createElement ('li');
this._ul.appendChild (li);
var button = document.createElement ('button');
button.addEventListener ('click',
this._onCloseClick.bind (this, li));
li.appendChild (button);
var img = document.createElement ('img');
img.src = 'image/close.svg';
button.appendChild (img);
var text = this._label = document.createTextNode ('');
li.appendChild (text);
setTimeout (this._onTimeout.bind (this));
this._changeValue (value);
this._refreshLabel ();
}
,_refreshLabel: function ()
{
if (!this._label)
return;
var row = -1;
if (this._model.ready)
row = this._model.searchByIndex (this._valueColumnIndex, this._value);
if (row != -1)
{
var label = this._model.getByIndex (row, this._showColumnIndex);
this._label.nodeValue = label;
this._emptyLabel = false;
}
else
{
this._emptyLabel = true;
this._label.nodeValue = _('Loading...');
}
}
})
Vn.ColumnItem = new Class
({
Extends: Htk.Column
@ -340,5 +624,5 @@ Vn.ColumnItem = new Class
return td;
}
});
})

View File

@ -1,288 +1,417 @@
.catalog
{
position: relative;
width: 100%;
height: 100%;
min-height: 25em;
}
.catalog div.center
{
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 17em;
margin-right: 17em;
}
/* Main */
.catalog div.main
.htk-toast
{
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
overflow: auto;
padding: 1em;
}
.catalog div.main .box
{
margin: 0 auto;
max-width: 50em;
min-width: 25em;
}
.catalog .footer-message
{
padding-bottom: 1em;
text-align: center;
margin-left: -11em;
}
/* Topbar */
.catalog .action-bar
.catalog-actions > .htk-search-entry
{
max-width: 15em;
}
.catalog .search
{
float: left;
display: block;
background-color: white;
height: 2.2em;
padding: 0;
}
.catalog .search > input
{
margin: 0;
border: none;
width: 10em;
box-shadow: none;
}
.catalog .search > input:focus
{
background-color: initial;
}
.catalog .search > img
{
margin: 0.4em;
margin-top: 0;
vertical-align: middle;
}
.catalog button.menu
{
float: left;
display: none;
border: none;
background-color: transparent;
box-shadow: none;
padding: 0.3em;
padding-left: 0;
margin-left: 0;
}
.catalog button.menu > img
{
height: 1.8em;
margin-top: .8em;
margin-right: .4em;
}
/* Right panel */
.right-panel
{
position: absolute;
z-index: 20;
top: 0;
position: fixed;
top: 3.9em;
bottom: 0;
right: 0;
width: 17em;
background-color: white;
box-shadow: 0 0.2em 0.2em #AAA;
box-shadow: 0 0 .2em rgba(1, 1, 1, 0.4);
overflow: auto;
}
.right-panel button.basket,
.right-panel button.configure
.right-panel .basket-info
{
width: 100%;
height: 3em;
font-size: 1.1em;
text-align: center;
background-color: #00BCD4;
border-radius: 0;
display: inline-block;
width: 50%;
margin: 0;
padding: 0;
background-color: #00ACC1;
color: white;
box-shadow: 0 .1em .1em rgba(1, 1, 1, 0.3);
padding: 1.2em 2em;
}
.right-panel button.basket:hover
.right-panel .basket-info > button
{
background-color: #0AB;
}
.right-panel button.configure
{
background-color: #0097A7;
}
.right-panel button.configure:hover
{
background-color: #00838F;
color: #E0F2F1;
margin: 0 auto;
display: block;
margin-top: .4em;
}
.right-panel .basket-info > p
{
margin: 1em 1.2em;
color: #555;
font-size: 1.2em;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.right-panel .basket-info span
{
font-size: 1em;
}
.right-panel .realms-box
{
box-shadow: 0 0 0.4em #AAA;
background-color: rgba(1, 1, 1, .1);
}
.right-panel .realms-box a
{
display: block;
float: left;
line-height: 0;
width: 33.3%;
}
.right-panel .realms-box a > img
{
width: 100%;
border: 0;
padding: 0;
cursor: pointer;
}
.right-panel .realms-box img:hover
{
opacity: 0.85;
}
.right-panel .types-box
{
position: absolute;
top: 21.6em;
bottom: 0;
right: 0;
left: 0;
overflow: auto;
}
.right-panel .types-box a
{
padding: .5em 1.5em;
display: block;
}
.right-panel .types-box a:hover
{
background-color: rgba(1, 1, 1, .1);
}
/* Grid view */
.item-box
{
padding: 1em;
border-bottom: 1px solid #DDD;
min-height: 14em;
}
.item-box > .image
{
width: 8em;
height: 14em;
float: left;
margin-right: 1em;
}
.item-box img
{
max-width: 8em;
max-height: 8em;
display: block;
margin: 0 auto;
}
.item-box p
{
margin: 0;
padding: 0.6em;
padding: .4em 0;
font-size: 1.1em;
text-align: left;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.item-box h2
.right-panel .filter
{
padding: 1em 1.8em;
}
.right-panel .filters,
.right-panel .order
{
display: none;
}
.right-panel .realm-msg
{
margin-top: 1em;
/* box-shadow: 0 0 .3em rgba(1, 1, 1, 0.5);
border-radius: 50%;
overflow: hidden;*/
}
.right-panel .realm-msg > h1
{
font-weight: normal;
text-align: center;
padding: 2.5em 0;
color: #777;
/* background-color: #009688;
color: white;*/
}
.item-box .amount
.right-panel h2
{
width: 3em;
font-weight: normal;
padding: .4em 0;
color: #777;
font-size: 1.1em;
}
.amount-p
.right-panel .realms
{
text-align: right;
width: 95%;
margin: .2em auto;
}
.right-panel .realms a
{
display: block;
float: left;
width: 33.33%;
}
.right-panel .realms a:hover
{
background-color: rgba(1, 1, 1, 0.05);
border-radius: .1em;
}
.right-panel .realms a > img
{
display: block;
padding: 0;
width: 100%;
}
.right-panel .vn-filter,
.right-panel select
{
margin: 0 auto;
margin-bottom: .7em;
width: 90%;
display: block;
}
.vn-filter > ul
{
margin: 0;
list-style-type: none;
text-align: left;
color: #666;
padding-left: .8em;
}
.vn-filter li
{
margin: 0;
margin-top: .3em;
line-height: 2em;
max-width: 90%;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.vn-filter li > button
{
vertical-align: middle;
text-align: center;
padding: .2em;
margin: 0;
margin-right: .2em;
}
.right-panel .filters > button
{
display: block;
margin: 0 auto;
margin-top: 1em;
}
/* Item description */
.desc-popup
{
padding: 1em;
max-width: 15em;
}
/* Lots popup*/
div.amount
.lots-popup .footer
{
text-align: center;
background-color: #009688;
color: white;
line-height: 2.5em;
padding: 0.2em;
line-height: 2em;
padding: .4em;
}
button.erase
.lots-popup .footer > button
{
margin: 0;
}
.lots-popup .erase
{
float: left;
}
button.confirm
.lots-popup .confirm
{
float: right;
}
button.erase > img,
button.confirm > img
.lots-popup .erase > img,
.lots-popup .confirm > img
{
display: block;
height: 1em;
}
/* List view */
/* Items */
.items
{
width: 100%;
}
.catalog div.box div.header,
.items > thead > tr,
.realms-bar
{
background-color: #777;
}
.items > tbody > tr
{
height: 6em;
}
.items .icon
{
width: 6em;
padding: .2em;
padding-right: .5em;
}
.items .icon > img
{
max-height: 6em;
max-width: 6em;
}
td.second-category
.catalog .second-category
{
font-weight: bold;
color: orange;
}
td.third-category
.catalog .third-category
{
font-weight: bold;
color: red;
}
td.price
.catalog .price
{
color: green;
font-size: 1.1em;
}
.catalog .footer-message
{
padding-bottom: 1em;
text-align: center;
}
.catalog .item-info > h2
{
font-weight: normal;
}
.catalog .item-info > p
{
margin: 0;
padding: 0;
color: #777;
font-size: .8em;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.grid-view .item-info > .producer
{
text-transform: uppercase;
}
.catalog .item-info > .htk-button
{
margin: -0.3em;
padding: .3em;
}
.catalog .item-info > .htk-button > img
{
vertical-align: middle;
}
.catalog .item-info .from
{
font-size: .8em;
font-style: italic;
}
/* List view */
.list-view
{
max-width: 30em;
margin: 0 auto;
padding: 1em;
}
.list-view .item-box
{
display: block;
position: relative;
width: 100%;
margin: 0;
height: 5.5em;
overflow: visible;
border-bottom: 1px solid #DDD;
}
.list-view .item-box > .image
{
margin: 1em;
width: 3.5em;
height: 3.5em;
float: left;
border-radius: 50%;
overflow: hidden;
}
.list-view .item-box > .image > img
{
max-width: 100%;
height: 100%;
display: block;
margin: 0 auto;
}
.list-view .item-info
{
position: absolute;
left: 5.5em;
right: 0;
top: 0;
bottom: 0;
margin: .9em;
margin-left: 0;
}
.list-view .item-info > h2
{
font-size: 1em;
padding: 0;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.list-view .item-info > .color
{
display: none;
}
.list-view .item-info > .aval-price
{
position: absolute;
bottom: 0;
right: .3em;
}
.list-view .item-info > .htk-button
{
float: right;
}
.list-view .item-info > .info-button
{
margin-right: 0;
}
/* Grid view */
.grid-view
{
padding: 1em;
padding-right: .2em;
padding-bottom: .4em;
text-align: center;
}
.grid-view .item-box
{
text-align: left;
position: relative;
display: inline-block;
width: 22.5em;
margin: 0;
margin-right: .8em;
margin-bottom: .6em;
height: 10em;
overflow: hidden;
}
.grid-view .item-box > .image
{
width: 10em;
height: 100%;
float: left;
}
.grid-view .item-box > .image > img
{
max-width: 100%;
height: 100%;
display: block;
margin: 0 auto;
}
.grid-view .item-info
{
position: absolute;
left: 10.4em;
right: 0;
top: 0;
bottom: 0;
margin: .6em;
}
.grid-view .item-info > h2
{
font-weight: normal;
padding-top: 0;
}
.grid-view .item-info > .aval-price
{
position: absolute;
bottom: 0;
right: 2.8em;
}
.grid-view .item-info .add-button
{
position: absolute;
bottom: 0;
right: 0;
}
.grid-view .item-info > .info-button
{
float: right;
}
/* Mobile */
.catalog-actions > button.menu
{
display: none;
padding: 1.1em .5em;
}
.catalog-actions > button.menu > img
{
height: 1.8em;
}
@media (max-width: 960px)
{
.catalog-actions > button.menu
{
display: block;
}
.right-panel
{
top: 0;
right: -17em;
z-index: 20;
transition: transform 200ms ease-out;
-webkit-transition: transform 200ms ease-out;
}
.right-panel.show
{
transform: translateZ(0) translateX(-17em);
-webkit-transform: translateZ(0) translateX(-17em);
}
.catalog
{
margin-right: 0;
}
}

View File

@ -1,111 +1,183 @@
<vn>
<vn-group>
<vn-param id="realm" on-changed="onTypeChange">
<vn-hash-param key="realm"/>
</vn-param>
<vn-param id="type" on-changed="onTypeChange">
<vn-hash-param key="type"/>
</vn-param>
<vn-param id="search"/>
<vn-param id="realm" on-changed="onRealmChange"/>
<vn-param id="type" on-changed="onTypeChange"/>
<vn-param id="search" on-changed="onFilterChange"/>
<vn-param id="color" on-changed="onFilterChange"/>
<vn-param id="origin" on-changed="onFilterChange"/>
<vn-param id="category" on-changed="onFilterChange"/>
<vn-param id="producer" on-changed="onFilterChange"/>
<vn-hash-param key="realm" param="realm"/>
<vn-hash-param key="type" param="type"/>
<sql-filter type="AND" id="filter">
<sql-filter-item type="EQUAL" id="sql-type">
<sql-field name="tipo_id"/>
<sql-value param="type"/>
<sql-filter-item type="EQUAL" primary="false" id="op-realm">
<sql-field name="reino_id" target="t"/>
<sql-value id="realm-value"/>
</sql-filter-item>
<sql-filter-item type="LIKE">
<sql-filter-item type="EQUAL" id="op-type">
<sql-field name="tipo_id" target="a"/>
<sql-value id="type-value"/>
</sql-filter-item>
<sql-filter-item type="LIKE" id="op-name">
<sql-field name="Article"/>
<sql-search-tags param="search"/>
</sql-filter-item>
<sql-filter-item type="EQUAL" id="op-color">
<sql-field name="Color"/>
<sql-value param="color"/>
</sql-filter-item>
<sql-filter-item type="EQUAL" id="op-origin">
<sql-field name="id_origen"/>
<sql-value param="origin"/>
</sql-filter-item>
<sql-filter-item type="EQUAL" id="op-category">
<sql-field name="Categoria"/>
<sql-value param="category"/>
</sql-filter-item>
<sql-filter-item type="EQUAL" id="op-producer">
<sql-field name="producer_id"/>
<sql-value param="producer"/>
</sql-filter-item>
</sql-filter>
<db-query id="basket-lines">
SELECT item_id, warehouse_id, SUM(amount) amount
FROM basket_item
GROUP BY warehouse_id
<custom>
SELECT item_id, warehouse_id, SUM(amount) amount
FROM basket_item
GROUP BY warehouse_id
</custom>
</db-query>
<db-model result-index="2" id="items-model">
CREATE TEMPORARY TABLE tmp.bionic_calc
(INDEX (item_id))
ENGINE=MEMORY
SELECT Id_Article item_id FROM vn2008.Articles
WHERE #filter;
CALL bionic_calc ();
SELECT a.Id_Article item_id, t.available, t.price, p.name producer,
a.Foto, a.Article, a.Categoria, a.Medida, a.Tallos, a.Color, o.Abreviatura
FROM tmp.bionic_item t
JOIN vn2008.Articles a ON a.Id_Article = t.item_id
LEFT JOIN vn2008.producer p ON p.producer_id = a.producer_id
LEFT JOIN vn2008.Origen o ON a.id_origen = o.id
WHERE t.available > 0
ORDER BY a.Article, a.Medida
LIMIT 400;
<sql-batch property="batch" id="batch">
<item name="filter" object="filter"/>
<db-model result-index="2" id="items-model" on-status-changed="onItemsChange">
<custom>
CREATE TEMPORARY TABLE tmp.bionic_calc
(INDEX (item_id))
ENGINE=MEMORY
SELECT a.Id_Article item_id FROM vn2008.Articles a
JOIN vn2008.Tipos t ON t.tipo_id = a.tipo_id
WHERE #filter;
CALL bionic_calc ();
SELECT a.Id_Article item_id, a.description, b.available, b.price,
p.name producer, a.Foto, a.Article, a.Categoria, a.Medida,
IF(a.Tallos > 1, a.Tallos, NULL) Tallos, c.str color, o.str origin
FROM tmp.bionic_item b
JOIN vn2008.Articles a ON a.Id_Article = b.item_id
LEFT JOIN vn2008.producer p ON p.producer_id = a.producer_id
LEFT JOIN vn_locale.color_view c ON c.color_id = a.Color
LEFT JOIN vn_locale.origin_view o ON o.origin_id = a.id_origen
WHERE b.available > 0
ORDER BY a.Article, a.Medida
LIMIT 400;
</custom>
<sql-batch property="batch" id="filter-batch">
<custom>
<item name="filter" object="filter"/>
</custom>
</sql-batch>
</db-model>
<db-model id="item-lots" result-index="1" on-status-changed-after="onStatusChange">
CALL bionic_from_item (#item);
SELECT p.warehouse_id, p.grouping, p.price, p.rate, l.available
FROM tmp.bionic_lot l
JOIN tmp.bionic_price p
ON p.warehouse_id = l.warehouse_id
ORDER BY warehouse_id, grouping;
<custom>
CALL bionic_from_item (#item);
SELECT p.warehouse_id, w.name warehouse, p.grouping, p.price, p.rate, l.available
FROM tmp.bionic_lot l
JOIN tmp.bionic_price p ON p.warehouse_id = l.warehouse_id
JOIN vn2008.warehouse w ON w.id = p.warehouse_id
ORDER BY warehouse_id, grouping;
</custom>
<sql-batch property="batch" id="lots-batch"/>
</db-model>
<db-form id="basket" on-ready="onBasketReady">
<db-model>
SELECT o.id, o.date_send, ag.description agency, v.code method
FROM basket o
JOIN vn2008.Agencias ag ON ag.Id_Agencia = o.agency_id
JOIN vn2008.Vistas v ON v.vista_id = o.delivery_method_id
<db-model property="model">
<custom>
SELECT o.id, o.date_send, ag.description agency, v.code method
FROM basket o
JOIN vn2008.Agencias ag ON ag.Id_Agencia = o.agency_id
JOIN vn2008.Vistas v ON v.vista_id = o.delivery_method_id
</custom>
</db-model>
</db-form>
</vn-group>
<div id="title">
<h1 id="title-text"><t>Catalog</t></h1>
</div>
<div id="actions" class="catalog-actions">
<button class="menu" on-click="onShowMenuClick">
<img src="image/dark/menu.svg" alt="_Menu"/>
</button>
<htk-button
id="a"
image="image/dark/basket.svg"
tip="_ShoppingBasket"
on-click="onBasketClick"
showText="true"/>
<htk-button
id="view-button"
tip="_Switch view"
on-click="onSwitchViewClick"
showText="true"/>
<htk-search-entry
param="search"/>
</div>
<div id="form" class="catalog">
<div class="center">
<div class="main">
<div class="box">
<div id="header" class="header">
<button class="menu" on-click="onShowMenuClick">
<img src="image/dark/menu.svg" alt="_Menu"/>
</button>
<h1 id="title"><t>Catalog</t></h1>
<div class="action-bar">
<div class="search">
<img src="image/search.svg" alt="_Search" class="icon"/>
<input type="text" id="search-entry" on-change="onSearch"/>
</div>
</div>
<div class="clear"/>
</div>
<htk-grid empty-message="_SelectSubtype" id="items-grid" class="items" model="items-model">
<htk-column-image
title="*"
class="icon"
column="Foto"
<div id="main" class="main">
<htk-repeater
id="grid-view"
empty-message="_Choose filter from right menu"
form-id="item"
renderer="gridRenderer"
model="items-model">
<custom>
<div class="box item-box">
<div class="image">
<htk-image
directory="catalog"
subdir="200x200"
form="item"
column="Foto"
show-full="true"
full-dir="900x900"
editable="true"/>
<vn-column-item title="_Name" column="Article" renderer="nameRenderer"/>
<htk-column-text title="_Cat" renderer="featuresRender"/>
<htk-column-spin title="_Aval" column="available"/>
<htk-column-text
title="_Price"
column="price"
format="_from %.2d€"
class="price"/>
<htk-column-button
</div>
<div class="item-info">
<htk-button
form="item"
column="id"
image="image/add.svg"
tip="_AddToBasket"
on-clicked="onAddItemClick"/>
</htk-grid>
<p class="footer-message">
<t>IndicativePhotos</t>
</p>
</div>
image="image/add.svg"
on-click="onGridAddItemClick"
class="add-button"/>
<htk-button
form="item"
column="id"
tip="_More info"
image="image/info.svg"
on-click="onInfoClick"
id="info-button"
class="info-button"/>
<div class="aval-price">
<htk-text form="item" column="available"/>
<span class="from">
<t>from</t>
</span>
<span class="price">
<htk-text form="item" column="price" format="%.2d€"/>
</span>
</div>
<h2>
<htk-text form="item" column="Article"/>
</h2>
<p class="producer">
<htk-text form="item" column="producer"/>
</p>
<p>
<t>Size</t> <htk-text form="item" column="Medida"/>,
<t>Category</t> <htk-text form="item" column="Categoria"/>
</p>
<p class="color">
<t>Color</t> <htk-text form="item" column="color"/>
<htk-text form="item" column="Tallos" format="_, %.0d Units"/>
</p>
</div>
</div>
<<<<<<< HEAD
</div>
<div id="menu" class="right-panel" on-click="onMenuClick">
<button class="basket" on-click="onBasketClick" title="Shopping basket">
@ -155,68 +227,253 @@
</a>
</template>
</htk-repeater>
=======
</custom>
</htk-repeater>
>>>>>>> 5f64002b1d4eebc7fcfd7ff1916d7658fbaf57fb
</div>
</div>
<div id="lots-popup" class="lots-popup">
<htk-grid class="lots-grid" model="item-lots" show-header="false">
<htk-column-spin title="_Price" column="price" unit="€" digits="2"/>
<htk-column-text title="_Pack" column="grouping" format="x%.0d"/>
<htk-column-button
column="id"
image="image/add.svg"
tip="_Add"
on-clicked="onAddLotClick"/>
</htk-grid>
<div class="amount">
<button on-click="onEraseClick" title="_Erase" class="erase">
<img
src="image/dark/delete.svg"
alt="_Erase"/>
<div id="right-panel" class="right-panel" on-click="onRightPanelClick">
<div class="basket-info">
<p>
<htk-text form="basket" column="date_send" format="_%A, %e of %B"/>
</p>
<p>
<span id="method"/>
<htk-text form="basket" column="agency"/>
</p>
<button class="thin" on-click="onConfigureClick">
<t>Change</t>
</button>
<htk-text id="amount"/>
<button on-click="onConfirmClick" title="_Confirm" class="confirm">
<img
src="image/dark/ok.svg"
alt="_Confirm"/>
</button>
<div class="clear"/>
</div>
</div>
<!--
<htk-repeater id="grid-view" form-id="item">
<template>
<div class="item-box">
<div class="image">
<div>
<htk-image form="item" column="Foto" directory="catalog/200x200"/>
<div class="filter">
<div class="categories">
<div class="realms">
<htk-repeater
model="realms-model"
form-id="realm-form"
renderer="realmRenderer"
class="realms-box">
<db-model
id="realms-model"
property="model"
on-status-changed="refreshTitleColor">
<custom>
SELECT r.id, l.str name, r.color
FROM vn2008.reinos r
LEFT JOIN vn_locale.realm_view l ON l.realm_id = r.id
WHERE r.display != FALSE
ORDER BY name
</custom>
</db-model>
<custom>
<a id="link">
<img id="image"/>
</a>
</custom>
</htk-repeater>
<div class="clear"/>
</div>
</div>
<h2>
<htk-text form="item" column="Article"/>
</h2>
<p>
<htk-text form="item" column="Medida"/> /
<htk-text form="item" column="Categoria"/> /
<htk-text form="item" column="Color"/> /
<htk-text form="item" column="Tallos"/> /
<htk-text form="item" column="Abreviatura"/>
</p>
<p>
<t>Available:</t>
<htk-text form="item" column="available"/>
</p>
<p>
<t>Price:</t>
<htk-text form="item" column="price" format="%.2d€"/>
</p>
<p class="amount-p">
<htk-entry id="stems" class="amount"/>
<htk-text form="item" column="grouping" format="x%.0d"/>
<htk-entry form="item" column="amount" class="amount"/>
</p>
<div class="clear"/>
<div id="realm-msg" class="realm-msg">
<h1><t>Choose a realm</t></h1>
</div>
<div id="filters" class="filters">
<h2><t>Filter by</t></h2>
<vn-filter
placeholder="_Family"
param="type">
<db-model
id="types-model"
property="model"
conn="conn"
result-index="1"
on-status-changed="refreshTitle">
<custom>
CALL item_available ();
SELECT DISTINCT t.tipo_id, l.str name
FROM vn2008.Tipos t
JOIN vn2008.Articles a ON a.tipo_id = t.tipo_id
LEFT JOIN vn_locale.family_view l ON l.family_id = t.tipo_id
JOIN tmp.item_available i ON i.item_id = a.Id_Article
WHERE #filter
ORDER BY name
</custom>
</db-model>
<sql-filter property="filter" type="AND">
<sql-filter-item type="EQUAL">
<sql-field name="reino_id" target="t"/>
<sql-value param="realm"/>
</sql-filter-item>
</sql-filter>
</vn-filter>
<vn-filter
placeholder="_Color"
param="color">
<db-model property="model" auto-load="false" result-index="1">
<custom>
CALL item_available ();
SELECT DISTINCT c.Id_Tinta, l.str name
FROM vn2008.Tintas c
JOIN vn2008.Articles a ON a.Color = c.Id_Tinta
JOIN vn2008.Tipos t ON t.tipo_id = a.tipo_id
LEFT JOIN vn_locale.color_view l ON l.color_id = c.Id_Tinta
JOIN tmp.item_available i ON i.item_id = a.Id_Article
WHERE #filter
ORDER BY name
</custom>
</db-model>
<sql-filter property="filter" always-ready="true" type="AND">
<pointer object="op-realm"/>
<pointer object="op-type"/>
<pointer object="op-name"/>
<pointer object="op-origin"/>
<pointer object="op-category"/>
<pointer object="op-producer"/>
</sql-filter>
</vn-filter>
<vn-filter
placeholder="_Producer"
param="producer">
<db-model property="model" auto-load="false" result-index="1">
<custom>
CALL item_available ();
SELECT DISTINCT p.producer_id, p.name
FROM vn2008.producer p
JOIN vn2008.Articles a ON a.producer_id = p.producer_id
JOIN vn2008.Tipos t ON t.tipo_id = a.tipo_id
JOIN tmp.item_available i ON i.item_id = a.Id_Article
WHERE #filter
ORDER BY name
</custom>
</db-model>
<sql-filter property="filter" always-ready="true" type="AND">
<pointer object="op-realm"/>
<pointer object="op-type"/>
<pointer object="op-name"/>
<pointer object="op-origin"/>
<pointer object="op-color"/>
<pointer object="op-category"/>
</sql-filter>
</vn-filter>
<vn-filter
placeholder="_Origin"
param="origin">
<db-model property="model" auto-load="false" result-index="1">
<custom>
CALL item_available ();
SELECT DISTINCT o.id, l.str name, o.Abreviatura
FROM vn2008.Origen o
JOIN vn2008.Articles a ON a.id_origen = o.id
JOIN vn2008.Tipos t ON t.tipo_id = a.tipo_id
LEFT JOIN vn_locale.origin_view l ON l.origin_id = o.id
JOIN tmp.item_available i ON i.item_id = a.Id_Article
WHERE #filter
ORDER BY name
</custom>
</db-model>
<sql-filter property="filter" always-ready="true" type="AND">
<pointer object="op-realm"/>
<pointer object="op-type"/>
<pointer object="op-name"/>
<pointer object="op-color"/>
<pointer object="op-category"/>
<pointer object="op-producer"/>
</sql-filter>
</vn-filter>
<vn-filter
placeholder="_Category"
param="category">
<db-model property="model" auto-load="false" result-index="1">
<custom>
CALL item_available ();
SELECT DISTINCT a.Categoria, a.Categoria category
FROM vn2008.Articles a
JOIN vn2008.Tipos t ON t.tipo_id = a.tipo_id
JOIN tmp.item_available i ON i.item_id = a.Id_Article
WHERE #filter
ORDER BY a.Categoria
</custom>
</db-model>
<sql-filter property="filter" always-ready="true" type="AND">
<pointer object="op-realm"/>
<pointer object="op-type"/>
<pointer object="op-name"/>
<pointer object="op-color"/>
<pointer object="op-origin"/>
<pointer object="op-producer"/>
</sql-filter>
</vn-filter>
</div>
<div id="order" class="order">
<h2><t>Order by</t></h2>
<select on-change="onOrderChange">
<option value="A|Article" selected="true">
<t>Name</t>
</option>
<option value="A|price">
<t>Lower price</t>
</option>
<option value="D|price">
<t>Higher price</t>
</option>
<option value="A|available">
<t>Available</t>
</option>
<option value="A|Medida">
<t>Lower size</t>
</option>
<option value="D|Medida">
<t>Higher size</t>
</option>
<option value="A|color">
<t>Color</t>
</option>
<option value="A|producer">
<t>Producer</t>
</option>
<option value="A|Abreviatura">
<t>Origin</t>
</option>
<option value="A|Categoria">
<t>Category</t>
</option>
</select>
</div>
</div>
</template>
</htk-repeater>
-->
</div>
<htk-popup id="desc-popup">
<div
property="child-node"
class="desc-popup"
id="description"/>
</htk-popup>
<htk-popup id="lots-popup">
<div property="child-node" class="lots-popup">
<htk-grid class="lots-grid" model="item-lots" show-header="false">
<htk-column-text title="_Store" column="warehouse"/>
<htk-column-spin title="_Price" column="price" unit="€" digits="2"/>
<htk-column-text title="_Pack" column="grouping" format="x%.0d"/>
<htk-column-button
column="id"
image="image/add.svg"
tip="_Add"
on-clicked="onAddLotClick"/>
</htk-grid>
<div class="footer">
<button on-click="onEraseClick" title="_Erase" class="erase">
<img
src="image/dark/delete.svg"
alt="_Erase"/>
</button>
<htk-text id="amount"/>
<button on-click="onConfirmClick" title="_Confirm" class="confirm">
<img
src="image/dark/ok.svg"
alt="_Confirm"/>
</button>
<div class="clear"/>
</div>
</div>
</htk-popup>
</vn>

View File

@ -1,7 +1,7 @@
Vn.Checkout = new Class
({
Extends: Vn.Module
Extends: Vn.Form
,activate: function ()
{
@ -44,9 +44,18 @@ Vn.Checkout = new Class
this.autoStepLocked = false;
}
,disableButtons: function (disable)
{
this.$('confirm-agency').disabled = disable;
this.$('confirm-delivery').disabled = disable;
this.$('confirm-pickup').disabled = disable;
}
,onConfirmClick: function ()
{
this.disableButtons (true);
var query = 'CALL basket_configure (#date, #method, #agency, #address)';
var batch = new Sql.Batch ();
@ -61,6 +70,8 @@ Vn.Checkout = new Class
,onBasketConfigured: function (resultSet)
{
this.disableButtons (false);
if (!resultSet.fetchResult ())
return;

View File

@ -18,9 +18,9 @@
{
font-size: 1.4em;
}
.answers select
.answers .htk-select
{
min-width: 8em;
max-width: 8em;
display: block;
margin: 0 auto;
font-size: 1.6em;
@ -78,7 +78,7 @@
{
color: white;
}
.htk-assistant button
.htk-assistant .thin
{
float: right;
}

View File

@ -5,61 +5,73 @@
<vn-param id="agency"/>
<vn-param id="address" on-changed="onAddressChange"/>
<db-form id="defaults" on-ready="onValuesReady">
<db-model>
SELECT delivery_method, agency_id, address_id
FROM basket_defaults
<db-model property="model">
<custom>
SELECT delivery_method, agency_id, address_id
FROM basket_defaults
</custom>
</db-model>
</db-form>
<db-form id="order-form" on-ready="onValuesReady">
<db-model>
SELECT v.code delivery_method, o.date_send, o.agency_id, o.address_id
FROM basket o
JOIN vn2008.Vistas v ON o.delivery_method_id = v.vista_id
<db-model property="model">
<custom>
SELECT v.code delivery_method, o.date_send, o.agency_id, o.address_id
FROM basket o
JOIN vn2008.Vistas v ON o.delivery_method_id = v.vista_id
</custom>
</db-model>
</db-form>
<db-model property="model" id="agencies" auto-load="false" result-index="1" on-status-changed="onAgenciesReady">
CALL agency_list_from_date (#date, #address);
SELECT a.Id_Agencia, a.description
FROM t_agency t
JOIN vn2008.Agencias a ON a.Id_Agencia = t.agency_id
JOIN vn2008.Vistas v ON a.Vista = v.vista_id
WHERE a.web != FALSE
AND v.code = 'AGENCY'
ORDER BY a.description;
DROP TEMPORARY TABLE t_agency;
<db-model id="agencies" auto-load="false" result-index="1" on-status-changed="onAgenciesReady">
<custom>
CALL agency_list_from_date (#date, #address);
SELECT a.Id_Agencia, a.description
FROM t_agency t
JOIN vn2008.Agencias a ON a.Id_Agencia = t.agency_id
JOIN vn2008.Vistas v ON a.Vista = v.vista_id
WHERE a.web != FALSE
AND v.code = 'AGENCY'
ORDER BY a.description;
DROP TEMPORARY TABLE t_agency;
</custom>
<sql-batch property="batch">
<item name="address" param="address"/>
<item name="date" param="date"/>
<custom>
<item name="address" param="address"/>
<item name="date" param="date"/>
</custom>
</sql-batch>
</db-model>
<db-model property="model" id="warehouses" auto-load="false" result-index="1" on-status-changed="onWarehousesReady">
CALL agency_list_from_date (#date, #address);
SELECT a.Id_Agencia, a.description
FROM t_agency t
JOIN vn2008.Agencias a ON a.Id_Agencia = t.agency_id
JOIN vn2008.Vistas v ON a.Vista = v.vista_id
WHERE a.web != FALSE
AND v.code = 'PICKUP'
ORDER BY a.description;
DROP TEMPORARY TABLE t_agency;
<db-model id="warehouses" auto-load="false" result-index="1" on-status-changed="onWarehousesReady">
<custom>
CALL agency_list_from_date (#date, #address);
SELECT a.Id_Agencia, SUBSTR(a.description, 5) description
FROM t_agency t
JOIN vn2008.Agencias a ON a.Id_Agencia = t.agency_id
JOIN vn2008.Vistas v ON a.Vista = v.vista_id
WHERE a.web != FALSE
AND v.code = 'PICKUP'
ORDER BY a.description;
DROP TEMPORARY TABLE t_agency;
</custom>
<sql-batch property="batch">
<item name="address" param="address"/>
<item name="date" param="date"/>
<custom>
<item name="address" param="address"/>
<item name="date" param="date"/>
</custom>
</sql-batch>
</db-model>
</vn-group>
<div id="title">
<h1><t>ConfigureOrder</t></h1>
</div>
<div id="actions">
<htk-button
image="image/dark/close.svg"
tip="_Cancel"
on-click="onCancelClick"
showText="true"/>
</div>
<div id="form" class="checkout">
<div class="box">
<div class="header">
<h1><t>ConfigureOrder</t></h1>
<div class="action-bar">
<button on-click="onCancelClick">
<img src="image/dark/close.svg" alt=""/>
<t>Cancel</t>
</button>
</div>
<div class="clear"/>
</div>
<div class="form">
<htk-assistant
id="assistant"
@ -108,14 +120,16 @@
form-id="iter"
on-change="onAddressChange"
renderer="addressRenderer">
<db-model id="addresses">
SELECT a.id, a.consignee, p.name province, a.zip_code, a.city, a.name, a.active, c.Pais country
FROM address_view a
LEFT JOIN vn2008.province p ON a.province_id = p.province_id
JOIN vn2008.Paises c ON c.Id = p.Paises_Id
WHERE active != FALSE
<db-model property="model" id="addresses">
<custom>
SELECT a.id, a.consignee, p.name province, a.zip_code, a.city, a.name, a.active, c.Pais country
FROM address_view a
LEFT JOIN vn2008.province p ON a.province_id = p.province_id
JOIN vn2008.Paises c ON c.Id = p.Paises_Id
WHERE active != FALSE
</custom>
</db-model>
<template>
<custom>
<div class="address" id="address">
<p class="consignee">
<htk-text form="iter" column="consignee"/>
@ -124,7 +138,7 @@
<htk-text form="iter" column="name"/>
</p>
</div>
</template>
</custom>
</htk-repeater>
</div>
</div>
@ -162,7 +176,7 @@
<t>Agency</t>
<htk-text form="agency-combo" column="description"/>
</p>
<button class="thin" on-click="onConfirmClick">
<button id="confirm-agency" class="thin" on-click="onConfirmClick">
<t>Confirm</t>
</button>
<div class="clear"/>
@ -181,7 +195,7 @@
<p>
<t>ReceiveThroughtRoute</t>
</p>
<button class="thin" on-click="onConfirmClick">
<button id="confirm-delivery" class="thin" on-click="onConfirmClick">
<t>Confirm</t>
</button>
<div class="clear"/>
@ -198,7 +212,7 @@
<t>Warehouse</t>
<htk-text form="warehouse-combo" column="description"/>
</p>
<button class="thin" on-click="onConfirmClick">
<button id="confirm-pickup" class="thin" on-click="onConfirmClick">
<t>Confirm</t>
</button>
<div class="clear"/>

View File

@ -1,7 +1,22 @@
Vn.Confirm = new Class
({
Extends: Vn.Module
Extends: Vn.Form
,open: function ()
{
this.close ();
this.isOpen = true;
Vn.BasketChecker.check (this.conn,
this.onBasketCheck.bind (this));
}
,onBasketCheck: function (isOk)
{
if (isOk)
this.loadUi ();
}
,onOrderReady: function (form)
{
@ -18,14 +33,98 @@ Vn.Confirm = new Class
Vn.Node.hide (this.$('address'));
Vn.Node.setText (this.$('method'), _('Warehouse'));
}
var total = form.get ('tax_base') + form.get ('vat');
if (total === null)
total = 0;
var credit = form.get ('credit');
var debt = form.get ('debt');
var totalDebt = debt + total;
var exceededCredit = totalDebt - credit;
var creditExceededCond = exceededCredit > 0;
if (creditExceededCond)
Htk.Toast.showWarning (
_('You have exceeded your credit.'));
this.$('debt').value = debt;
this.$('total-debt').value = totalDebt;
this.$('total-amount').value = totalDebt;
this.$('credit-excess').value = exceededCredit;
this.$('excess-amount').value = exceededCredit;
this.$('pay-amount').value = 'ALL';
if (credit > 0)
{
this.$('credit-info').style.display = 'table-row';
if (creditExceededCond)
{
this.$('amount-selector').style.display = 'block';
this.$('exceeded-info').style.display = 'table-row';
this.$('pay-amount').value = 'EXCEEDED';
}
}
var methods = [];
if (totalDebt <= 0)
{
methods = ['balance'];
selectedMethod = 'BALANCE';
}
else
{
methods = ['card', 'transfer', 'later'];
if (!creditExceededCond)
{
methods.push ('credit');
selectedMethod = 'CREDIT';
}
else
selectedMethod = 'CARD';
}
for (var i = 0; i < methods.length; i++)
this.$(methods[i] +'-method').style.display = 'block';
this.$('pay-method').value = selectedMethod;
}
,onImportReady: function (form)
,onPayMethodChange: function (payMethod)
{
if (form.row != -1)
this.$('total').value = form.get ('tax_base') + form.get ('vat');
else
this.$('total').value = null;
var id = this.displayedInfo;
if (id)
Vn.Node.removeClass (this.$(id), 'selected');
switch (payMethod.value)
{
case 'BALANCE':
id = 'balance-method';
break;
case 'CREDIT':
id = 'credit-method';
break;
case 'CARD':
id = 'card-method';
break;
case 'TRANSFER':
id = 'transfer-method';
break;
default:
id = null;
}
this.displayedInfo = id;
if (id)
Vn.Node.addClass (this.$(id), 'selected');
}
,disableButtons: function (disable)
@ -47,29 +146,32 @@ Vn.Confirm = new Class
,onConfirm: function (query, resultSet)
{
var res = resultSet.fetchResult ();
var debt = resultSet.fetchValue ();
if (res)
this.disableButtons (false);
if (resultSet.fetchResult ())
{
Vn.Cookie.unset ('order');
this.pay = debt > this.$('order-form').get ('credit');
this.popup = new Htk.Popup ();
this.popup.setChildNode (this.$('success-dialog'));
this.popup.showCenter ();
this.$('success-dialog').show ();
}
else
this.disableButtons (false);
}
,onAcceptClick: function ()
{
this.popup.hide ();
this.$('success-dialog').hide ();
}
,onPopupClose: function ()
{
if (this.$('pay-method').value === 'CARD')
{
if (this.$('pay-amount').value === 'EXCEEDED')
var payAmount = this.$('excess-amount').value;
else
var payAmount = this.$('total-amount').value;
if (this.pay)
Vn.Tpv.pay (this.conn, this.$('total').value,
this.$('order-form').get ('company_id'));
var tpv = new Vn.Tpv ({conn: this.conn});
tpv.pay (payAmount, this.$('order-form').get ('company_id'));
}
else
this.hash.set ({'form': 'ecomerce/orders'});
}

View File

@ -1,84 +1,125 @@
.confirm
{
padding: 1em;
max-width: 40em;
max-width: 30em;
margin: 0 auto;
color: #555;
}
.confirm .box
{
padding: 2.2em 2.5em;
}
.confirm .summary
{
margin-bottom: 1em;
}
.confirm .address
{
margin-top: .8em;
}
.confirm h2
{
font-size: 1.1em;
font-weight: normal;
padding: 0;
font-size: 1.6em;
color: black;
margin: 0 3em;
margin: 0;
margin-bottom: .5em;
color: #333;
}
.confirm .form
{
margin: 0 auto;
padding: 3em 4em;
color: #555;
}
.confirm .form p,
.confirm .form select,
.confirm .form button
.confirm button
{
font-size: 1.4em;
}
.confirm .form > div.section
{
margin-bottom: 1.5em;
}
.confirm .form p
.confirm p
{
margin: .2em 0;
}
.confirm .form p.small
{
font-size: 1em;
}
.button-bar
{
margin-top: 2em;
}
.modify-order
.confirm .modify-order
{
float: left;
}
.confirm-order
.confirm .confirm-order
{
float: right;
}
.confirm .payment > div
{
margin-bottom: 1.4em;
}
.confirm .payment > .button-bar
{
margin: 0;
margin-top: 1.8em;
}
/* Success dialog */
/* Table */
.success-dialog
{
padding: 2em;
min-width: 30em;
max-width: 35em;
}
.success-dialog *
{
font-weight: normal;
color: #555;
}
.success-dialog p,
.success-dialog button
{
font-size: 1.4em;
}
.success-dialog img
{
float: left;
height: 3em;
margin-top: 0;
margin-right: 1.5em;
}
.success-dialog p
.confirm .debt-info
{
padding: 0;
}
.success-dialog > button
.confirm .debt-info > table
{
margin-top: 0.5em;
border-collapse: collapse;
}
.confirm td
{
padding: .15em 0;
}
.confirm .sum-total > td
{
border-top: solid 1px #DDD;
font-weight: bold;
}
.confirm .currency
{
text-align: right;
}
.confirm .credit-info
{
display: none;
}
.confirm .exceeded-info
{
display: none;
color: #E53935;
}
/* Pay */
.confirm .amount-selector,
.confirm .pay-methods > div,
.confirm .pay-info
{
display: none;
}
.confirm .pay-methods > div.selected > .pay-info
{
display: block;
}
.confirm .radio > div
{
margin: .3em 0;
}
.confirm .radio > div > *
{
vertical-align: middle;
}
.confirm .radio > div > input[type=radio]
{
margin: 0;
margin-right: .5em;
}
.confirm .pay-info
{
padding: .5em 1.3em;
}
.confirm .transfer-account
{
margin-top: .5em;
}
.confirm .transfer-account > p
{
margin: .1em 0;
}

View File

@ -1,91 +1,228 @@
<vn>
<vn-group>
<db-form id="order-form" on-ready="onOrderReady">
<db-model>
SELECT o.id, o.date_send, o.note, o.company_id,
ag.description agency, v.code method, c.credit,
ad.consignee, ad.zip_code, ad.city, ad.name address
FROM basket o
JOIN vn2008.Agencias ag ON ag.Id_Agencia = o.agency_id
LEFT JOIN address_view ad ON ad.id = o.address_id
JOIN vn2008.Vistas v ON v.vista_id = o.delivery_method_id
JOIN customer_view c
</db-model>
</db-form>
<db-form id="total-form" on-ready="onImportReady">
<db-model result-index="1">
CALL basket_get_vat ();
SELECT
IFNULL(SUM(tax_base), 0) tax_base,
IFNULL(SUM(vat + surcharge), 0) vat
FROM t_order_vat;
DROP TEMPORARY TABLE t_order_vat;
<db-model property="model" result-index="1">
<custom>
CALL basket_get_vat ();
SELECT o.id, o.date_send, o.note, o.company_id,
ag.description agency, v.code method,
ad.consignee, ad.zip_code, ad.city, ad.name address,
t.*, c.credit, customer_get_debt() debt
FROM basket o
JOIN vn2008.Agencias ag ON ag.Id_Agencia = o.agency_id
LEFT JOIN address_view ad ON ad.id = o.address_id
JOIN vn2008.Vistas v ON v.vista_id = o.delivery_method_id
JOIN customer_view c
JOIN (
SELECT
IFNULL(SUM(tax_base), 0) tax_base,
IFNULL(SUM(vat + surcharge), 0) vat
FROM t_order_vat
) t;
DROP TEMPORARY TABLE t_order_vat;
</custom>
</db-model>
</db-form>
<db-query id="confirm-query" on-ready="onConfirm">
CALL basket_confirm ();
SELECT customer_get_debt();
<custom>
CALL basket_confirm ()
</custom>
</db-query>
</vn-group>
<div id="title">
<h1><t>Order summary</t></h1>
</div>
<div id="form" class="confirm">
<div class="box">
<div class="header">
<h1><t>OrderSummary</t></h1>
</div>
<div class="form">
<div class="section">
<div class="box summary">
<div>
<div class="delivery">
<p>
<t>Arrival</t>
<htk-text format="_%A, %e of %B" form="order-form" column="date_send"/>
<t>Delivery at</t>
<htk-text format="%D" form="order-form" column="date_send"/>
</p>
<p class="small">
<p>
<span id="method"><t>Agency</t></span>
<htk-text form="order-form" column="agency"/>
</p>
</div>
<div id="address" class="section">
<div id="address" class="address">
<p>
<htk-text form="order-form" column="consignee"/>
</p>
<p class="small">
<p>
<htk-text form="order-form" column="address"/>
</p>
<p class="small">
<p>
<htk-text form="order-form" column="zip_code"/>,
<htk-text form="order-form" column="city"/>
</p>
</div>
<div class="section">
<p>
<t>Total</t>
<htk-text id="total" format="%.2d€"/>
</p>
<p class="small">
(<t>TaxBase</t> <htk-text form="total-form" column="tax_base" format="%.2d€"/> +
<t>VAT</t> <htk-text form="total-form" column="vat" format="%.2d€"/>)
</p>
</div>
</div>
<div class="box payment">
<div>
<table class="debt-info">
<tbody>
<tr>
<td>
<t>Previous balance</t>
</td>
<td class="currency">
<htk-text format="%.2d€" id="debt"/>
</td>
</tr>
<tr>
<td>
<t>Order total</t>
</td>
<td class="currency">
<htk-text format="%.2d€" form="order-form" column="tax_base"/>
</td>
</tr>
<tr>
<td>
<t>Order VAT</t>
</td>
<td class="currency">
<htk-text format="%.2d€" form="order-form" column="vat"/>
</td>
</tr>
<tr class="total-debt sum-total">
<td>
<t>Total debt</t>
</td>
<td class="currency">
<htk-text format="%.2d€" id="total-debt"/>
</td>
</tr>
<tr id="credit-info" class="credit-info">
<td>
<t>Credit</t>
</td>
<td class="currency">
<htk-text format="%.2d€" form="order-form" column="credit"/>
</td>
</tr>
<tr id="exceeded-info" class="exceeded-info sum-total">
<td>
<t>Exceeded credit</t>
</td>
<td class="currency">
<htk-text format="%.2d€" id="credit-excess"/>
</td>
</tr>
</tbody>
</table>
</div>
<div id="amount-selector" class="amount-selector">
<h2>
<t>Amount to pay</t>
</h2>
<div class="radio">
<htk-radio-group
id="pay-amount"/>
<div>
<htk-radio radio-group="pay-amount" value="ALL"/>
<label>
<t>Total debt</t>,
<htk-text format="%.2d€" id="total-amount"/>
</label>
</div>
<div>
<htk-radio radio-group="pay-amount" value="EXCEEDED"/>
<label>
<t>Exceeded credit</t>,
<htk-text format="%.2d€" id="excess-amount"/>
</label>
</div>
</div>
<div class="button-bar">
<button on-click="onModifyClick" id="modify" class="thin modify-order">
<t>Modify</t>
</button>
<button on-click="onConfirmClick" id="confirm" class="thin confirm-order">
<t>Confirm</t>
</button>
<div class="clear"/>
</div>
<div>
<h2>
<t>Pay method</t>
</h2>
<div class="pay-methods radio">
<htk-radio-group
id="pay-method"
on-changed="onPayMethodChange"/>
<div id="balance-method">
<htk-radio radio-group="pay-method" value="BALANCE"/>
<label><t>Use my balance</t></label>
<div class="pay-info">
<t>You have a favorable balance.</t>
</div>
</div>
<div id="credit-method">
<htk-radio radio-group="pay-method" value="CREDIT"/>
<label><t>Use my credit</t></label>
<div class="pay-info">
<t>You have a favorable credit.</t>
</div>
</div>
<div id="card-method">
<htk-radio radio-group="pay-method" value="CARD"/>
<label><t>Credit card</t></label>
<div class="pay-info">
<t>You will be redirected to the payment.</t>
</div>
</div>
<div id="transfer-method">
<htk-radio radio-group="pay-method" value="TRANSFER"/>
<label><t>Bank Transfer</t></label>
<div class="pay-info">
<t>Make a transfer to one account.</t>
<htk-repeater form-id="iter">
<db-model property="model">
<custom>
SELECT description, iban, entity_id, office, dc, number
FROM vn2008.account_customer c
</custom>
</db-model>
<custom>
<div class="transfer-account">
<p>
<htk-text form="iter" column="description"/>
</p>
<p>
<htk-text form="iter" column="iban"/>
<htk-text form="iter" column="entity_id"/>
<htk-text form="iter" column="office"/>
<htk-text form="iter" column="DC"/>
<htk-text form="iter" column="number"/>
</p>
</div>
</custom>
</htk-repeater>
</div>
</div>
<div id="later-method">
<htk-radio radio-group="pay-method" value="LATER"/>
<label><t>Pay later</t></label>
</div>
</div>
</div>
<div class="button-bar">
<button on-click="onModifyClick" id="modify" class="thin modify-order">
<t>Modify</t>
</button>
<button on-click="onConfirmClick" id="confirm" class="thin confirm-order">
<t>Confirm</t>
</button>
<div class="clear"/>
</div>
</div>
</div>
<div id="success-dialog" class="success-dialog">
<div>
<img src="image/ok.svg" alt="_Ok"/>
<p><t>OrderPlacedSuccessfully</t></p>
<htk-popup id="success-dialog" modal="true" on-closed="onPopupClose">
<div property="child-node" class="dialog">
<div>
<img src="image/ok.svg" alt="_Ok"/>
<p><t>Order confirmed successfully</t></p>
<div class="clear"/>
</div>
<button class="thin" on-click="onAcceptClick">
<t>Accept</t>
</button>
<div class="clear"/>
</div>
<button on-click="onAcceptClick" class="thin confirm-order">
<t>Accept</t>
</button>
<div class="clear"/>
</div>
</htk-popup>
</vn>

View File

@ -1,7 +1,7 @@
Vn.Invoices = new Class
({
Extends: Vn.Module
Extends: Vn.Form
,activate: function () {}

View File

@ -1,27 +1,29 @@
<vn>
<div id="title">
<h1><t>Invoices</t></h1>
</div>
<div id="form" class="invoices">
<div class="box">
<div class="header">
<h1><t>Invoices</t></h1>
</div>
<div>
<htk-grid show-header="false">
<db-model id="tickets">
SELECT invoice_id, serial_num, issued, amount
FROM invoice_view
ORDER BY issued DESC
LIMIT 100
</db-model>
<htk-column-text title="_Serial" column="serial_num"/>
<htk-column-date title="_Date" column="issued" format="_%e %b %Y"/>
<htk-column-spin title="_Import" column="amount" unit="€" digits="2"/>
<htk-column-button
column="invoice_id"
image="image/download.svg"
tip="_Download PDF"
on-clicked="onDownloadClick"/>
</htk-grid>
</div>
<div>
<htk-grid show-header="false">
<db-model property="model" id="tickets">
<custom>
SELECT invoice_id, serial_num, issued, amount
FROM invoice_view
ORDER BY issued DESC
LIMIT 100
</custom>
</db-model>
<htk-column-text title="_Serial" column="serial_num"/>
<htk-column-date title="_Date" column="issued" format="_%e %b %Y"/>
<htk-column-spin title="_Import" column="amount" unit="€" digits="2"/>
<htk-column-button
column="invoice_id"
image="image/download.svg"
tip="_Download PDF"
on-clicked="onDownloadClick"/>
</htk-grid>
</div>
</div>
</div>
</vn>

View File

@ -1,26 +1,30 @@
Vn.Orders = new Class
({
Extends: Vn.Module
Extends: Vn.Form
,activate: function ()
{
this.payPopup = new Htk.Popup ();
this.payPopup.setChildNode (this.$('balance-popup'));
Vn.Tpv.check (this.conn);
this.tpv = new Vn.Tpv ({conn: this.conn});
this.tpv.check (this._onTpvCheck.bind (this));
}
,_onTpvCheck: function (tpv, tpvOrder, tpvStatus)
{
if (tpvStatus === 'ko')
this.$('error-dialog').show ();
}
,onBasketClick: function ()
{
this.hash.set ({'form': 'ecomerce/basket'});
}
,onShowClick: function (column, ticketId)
,repeaterFunc: function (res, form)
{
this.hash.set ({
res.$('link').href = this.hash.make ({
'form': 'ecomerce/ticket',
'ticket': ticketId
'ticket': form.get ('ticket_id')
});
}
@ -28,26 +32,15 @@ Vn.Orders = new Class
,balanceConditionalFunc: function (field, value)
{
var className = 'balance-amount ';
if (value > 0)
className += 'positive-balance';
if (value >= 0)
Vn.Node.removeClass (this.$('balance'), 'negative');
else
className += 'negative-balance';
field.node.className = className;
Vn.Node.addClass (this.$('balance'), 'negative');
}
,onPayButtonClick: function ()
{
this.payPopup.show (this.$('pay-button'));
}
,onCompanyPayClick: function (column, value, row)
{
var model = this.$('balance');
var company = model.get (row, 'id');
var amount = model.get (row, 'amount');
var amount = -this.$('debt').value;
amount = amount <= 0 ? null : amount;
@ -58,7 +51,18 @@ Vn.Orders = new Class
var amount = parseFloat (prompt (_('AmountToPay:'), defaultAmountStr));
Vn.Tpv.pay (this.conn, amount, company);
this.tpv.pay (amount, null);
}
,onCancelPay: function ()
{
this.$('error-dialog').hide ();
}
,onRetryPay: function ()
{
this.$('error-dialog').hide ();
this.tpv.retryPay ();
}
});

View File

@ -4,68 +4,38 @@
}
.orders .box
{
max-width: 45em;
}
.orders .box .header,
.balance-grid > thead > tr
{
background-color: #3F51B6;
}
.orders .htk-grid tbody tr
{
height: 5em;
}
/* Info box */
.orders .info
{
padding: 0.4em;
background-color: #FFC;
border-radius: 0.1em;
}
.orders .info > img
{
vertical-align: middle;
margin: 0.7em;
height: 1.5em;
}
/* Buttons */
.orders td.hide
{
display: none;
max-width: 25em;
}
/* Balance */
.balance img
.balance
{
margin-top: 1.2em;
margin-right: .5em;
}
.balance > *
{
vertical-align: middle;
padding-left: 0.3em;
cursor: pointer;
}
.balance-amount
.balance > .amount
{
color: white;
padding: 0.3em;
}
.balance-info
.balance > .info
{
height: 1em;
display: inline;
cursor: pointer;
height: 1.2em;
cursor: pointer;
}
.positive-balance
.balance > .negative
{
background-color: #EF5350;
border-radius: 0.1em;
box-shadow: 0 0 0.4em #666;
}
.negative-balance
{
color: white;
}
.balance-popup
{
width: 25em;
@ -76,3 +46,28 @@
margin: auto;
}
/* List */
.orders .item
{
display: block;
padding: 1em;
border-bottom: 1px solid #DDD;
}
.orders .item:hover
{
background-color: rgba(1, 1, 1, 0.05);
}
.orders .item > p
{
margin: .1em 0;
}
.orders .item > p.important
{
font-size: 1.2em;
}
.orders .item > p.total
{
float: right;
}

View File

@ -1,53 +1,90 @@
<vn>
<div id="form" class="orders">
<div class="box confirmed">
<div class="header">
<h1><t>LastOrders</t></h1>
<div class="action-bar">
<div id="balance">
<t>PendingBalance:</t>
<htk-label format="%.2d€" conditional-func="balanceConditionalFunc">
<db-calc-sum model="balance" column-name="amount"/>
</htk-label>
<img src="image/dark/info.svg" title="_PaymentInfo" class="balance-info" alt="Info"/>
</div>
<button id="pay-button" title="_MakePayment" on-click="onPayButtonClick">
<img src="image/dark/pay.svg" alt="_MakePayment"/>
</button>
<button on-click="onBasketClick" title="_ShoppingBasket">
<img src="image/dark/basket.svg" alt=""/>
<t>Basket</t>
</button>
</div>
<div class="clear"/>
</div>
<div>
<htk-grid show-header="false">
<db-model id="tickets">
CALL ticket_list ();
</db-model>
<htk-column-date column="date" format="%A, %e of %B"/>
<htk-column-text title="_SendMethod" column="type"/>
<htk-column-spin column="total" unit="€" digits="2"/>
<htk-column-button
column="ticket_id"
image="image/show.svg"
tip="_SeeOrder"
on-clicked="onShowClick"/>
</htk-grid>
</div>
<vn-group>
<db-model id="debt-model" result-index="1">
<custom>
CALL customer_get_debt_by_company ();
SELECT -amount amount FROM t_customer_debt;
DROP TEMPORARY TABLE t_customer_debt;
</custom>
</db-model>
</vn-group>
<div id="title">
<h1><t>LastOrders</t></h1>
</div>
<div id="actions">
<htk-button
image="image/dark/basket.svg"
tip="_ShoppingBasket"
on-click="onBasketClick"/>
<htk-button
id="pay-button"
image="image/dark/pay.svg"
tip="_MakePayment"
on-click="onPayButtonClick"/>
<div class="balance">
<span class="label">
<t>Balance:</t>
</span>
<span class="amount" id="balance">
<htk-text
format="%.2d€"
conditional-func="balanceConditionalFunc">
<db-calc-sum
property="param"
model="debt-model"
column-name="amount"
id="debt"/>
</htk-text>
</span>
<img
src="image/dark/info.svg"
title="_PaymentInfo"
class="info"
alt="Info"/>
</div>
</div>
<div id="balance-popup" class="balance-popup">
<htk-grid class="balance-grid" show-header="false">
<db-model id="balance" result-index="1">
CALL customer_get_debt_by_company ();
SELECT * FROM t_customer_debt;
DROP TEMPORARY TABLE t_customer_debt;
</db-model>
<htk-column-text title="_Company" column="abbreviation"/>
<htk-column-spin title="_Pending" column="amount" unit="€" digits="2"/>
<htk-column-button title="_Pay" image="image/pay.svg" tip="Pay" on-clicked="onCompanyPayClick"/>
</htk-grid>
<div id="form" class="orders">
<div class="box confirmed">
<htk-repeater form-id="iter" renderer="repeaterFunc">
<db-model property="model" id="tickets">
<custom>
CALL ticket_list ();
</custom>
</db-model>
<custom>
<a id="link" class="item" title="_SeeOrder">
<p class="important total">
<htk-text form="iter" column="total" format="%.2d€"/>
</p>
<p class="important">
<htk-text form="iter" column="date" format="%D"/>
</p>
<p>
<htk-text form="iter" column="consignee"/>
</p>
<p>
<htk-text form="iter" column="type"/>
</p>
<div class="clear"/>
</a>
</custom>
</htk-repeater>
</div>
</div>
<htk-popup id="error-dialog" modal="true">
<div property="child-node" class="dialog">
<div>
<img src="image/error.svg" alt="_Error"/>
<p><t>An error has been in the payment</t></p>
<div class="clear"/>
</div>
<button class="thin" on-click="onRetryPay">
<t>Retry</t>
</button>
<button class="thin" on-click="onCancelPay">
<t>Accept</t>
</button>
<div class="clear"/>
</div>
</htk-popup>
</vn>

View File

@ -1,18 +1,57 @@
.ticket
{
padding: 1em;
min-width: 50em;
}
.ticket .box
{
max-width: 70em;
max-width: 30em;
margin: 0 auto;
padding: 2em;
color: #333;
}
/* Data */
/* Header */
.ticket td.label
.ticket .head
{
width: 10em;
padding: 0;
padding-bottom: .2em;
border-bottom: 1px solid #DDD;
margin-bottom: 1em;
}
.ticket .head > div
{
padding-bottom: .8em;
}
.ticket .head p
{
margin: .2em;
}
.ticket .head p.important
{
font-size: 1.4em;
}
.ticket .total
{
text-align: right;
}
/* Lines */
.ticket .line
{
padding: .5em 0;
}
.ticket .line p
{
margin: .1em 0;
}
.ticket .amount
{
float: left;
}
.ticket .subtotal
{
float: right;
}

View File

@ -1,27 +1,24 @@
Vn.Ticket = new Class
({
Extends: Vn.Module
Extends: Vn.Form
,activate: function ()
,onPrintClick: function (event)
{
this.$('print').addEventListener ('click', this.printClicked.bind (this));
this.$('subtotal').renderer = this.subtotalRenderer.bind (this);
this.$('ticket-subtotal').func = this.subtotal;
}
,printClicked: function (event)
{
var report = window.open ('', 'report',
'resizable=yes,height=600,width=750,scrollbars=yes,menubar=no');
report.document.body.innerHTML = this.$('report').innerHTML;
report.print ();
var batch = new Sql.Batch ();
batch.addValue ('ticket', this.$('ticket-id').value);
this.gui.openReport ('delivery-note', batch);
}
,subtotalRenderer: function (column, form)
{
column.value = this.subtotal (form);
}
,repeaterFunc: function (res, form)
{
res.$('subtotal').value = this.subtotal (form);
}
,subtotal: function (form)
{

View File

@ -1,90 +1,75 @@
<vn>
<vn-group>
<vn-param id="ticket-id">
<vn-hash-param key="ticket"/>
</vn-param>
<vn-param id="ticket-id"/>
<vn-hash-param key="ticket" param="ticket-id"/>
<db-form id="ticket">
<db-model id="ticket-data">
SELECT t.id, date, a.Agencia, note, p.name province,
zip_code, city, c.name, consignee, invoice
FROM ticket_view t
JOIN address_view c ON t.address_id = c.id
JOIN vn2008.Agencias a ON t.agency_id = a.Id_Agencia
JOIN vn2008.province p ON c.province_id = p.province_id
WHERE t.id = #ticket
<db-model property="model" id="ticket-data">
<custom>
SELECT t.id, date, a.Agencia, note, p.name province,
zip_code, city, c.name, consignee, invoice, delivery
FROM ticket_view t
JOIN address_view c ON t.address_id = c.id
JOIN vn2008.Agencias a ON t.agency_id = a.Id_Agencia
JOIN vn2008.province p ON c.province_id = p.province_id
WHERE t.id = #ticket
</custom>
<sql-batch property="batch">
<item name="ticket" param="ticket-id"/>
<custom>
<item name="ticket" param="ticket-id"/>
</custom>
</sql-batch>
</db-model>
</db-form>
</vn-group>
<div id="title">
<h1><t>OrderDetail</t></h1>
</div>
<div id="actions" class="action-bar">
<htk-button
image="image/dark/print.svg"
tip="_Print delivery note"
on-click="onPrintClick"
show-text="true"/>
</div>
<div id="form" class="ticket">
<div class="box">
<div class="header">
<h1><t>OrderDetail</t></h1>
<div class="action-bar">
<button id="print">
<img src="image/dark/print.svg" alt=""/>
<t>Print</t>
</button>
<div class="head">
<div>
<p class="important ticket-id">
<htk-text column="id" form="ticket"/>
</p>
<p>
<htk-text form="ticket" column="delivery" format="%A, %e of %B %Y"/>
</p>
</div>
<div>
<p>
<t>Delivery</t> <htk-text form="ticket" column="Agencia"/>
</p>
<p>
<htk-text form="ticket" column="consignee"/>
</p>
<p>
<htk-text form="ticket" column="name"/>
</p>
<p>
<htk-text form="ticket" column="zip_code"/>
<htk-text form="ticket" column="city"/>
(<htk-text form="ticket" column="province"/>)
</p>
</div>
<div>
<p class="important total">
<t>Total</t>
<htk-text format="%.2d€">
<db-calc-sum property="param" func="subtotal" model="movements"/>
</htk-text>
</p>
</div>
</div>
<div id="report">
<table class="form">
<tbody>
<tr>
<td class="label">
<label><t>TicketNumber:</t></label>
</td>
<td>
<htk-text column="id" form="ticket"/>
</td>
</tr>
<tr>
<td class="label">
<label><t>DateExit:</t></label>
</td>
<td>
<htk-date-chooser column="date" form="ticket" editable="false"/>
</td>
</tr>
<tr>
<td class="label">
<label><t>SendMethod:</t></label>
</td>
<td>
<htk-text column="Agencia" form="ticket"/>
</td>
</tr>
<tr>
<td class="label">
<label><t>Notes:</t></label>
</td>
<td>
<htk-text column="note" form="ticket"/>
</td>
</tr>
<tr>
<td class="label">
<label for="total"><t>Subtotal:</t></label>
</td>
<td>
<htk-text format="%.2d€">
<db-calc-sum id="ticket-subtotal" model="movements"/>
</htk-text>
</td>
</tr>
</tbody>
</table>
<htk-grid model="ticket-data">
<htk-column-spin title="_PC" column="zip_code"/>
<htk-column-text title="_City" column="city"/>
<htk-column-text title="_Province" column="province"/>
<htk-column-text title="_Address" column="name"/>
<htk-column-text title="_Consignee" column="consignee"/>
</htk-grid>
<htk-grid>
<db-model id="movements">
<htk-repeater form-id="iter" renderer="repeaterFunc">
<db-model property="model" id="movements">
<custom>
SELECT m.item_id, amount, concept, Categoria, Medida, Tallos, Color,
Abreviatura, IF(fixed != FALSE, price, NULL) price, fixed, discount
FROM ticket_row_view m
@ -93,23 +78,31 @@
LEFT JOIN vn2008.Origen o
ON a.id_origen = o.id
ORDER BY concept
<sql-batch property="batch">
</custom>
<sql-batch property="batch">
<custom>
<item name="ticket" param="ticket-id"/>
</sql-batch>
</db-model>
<htk-column-spin title="_ItemNumber" column="item_id"/>
<htk-column-spin title="_Amount" column="amount"/>
<htk-column-text title="_Item" column="concept"/>
<htk-column-text title="_Category" column="Categoria"/>
<htk-column-text title="_S1" column="Medida"/>
<htk-column-text title="_Stems" column="Tallos"/>
<htk-column-text title="_Color" column="Color"/>
<htk-column-text title="_Origin" column="Abreviatura"/>
<htk-column-spin title="_Price" column="price" unit="€" digits="2"/>
<htk-column-spin title="_Desc" column="discount" unit="%"/>
<htk-column-spin title="_Subtotal" unit="€" digits="2" id="subtotal"/>
</htk-grid>
</div>
</custom>
</sql-batch>
</db-model>
<custom>
<div class="line">
<p class="concept">
<htk-text form="iter" column="concept"/>
<htk-text form="iter" column="Medida"/>
<htk-text form="iter" column="Categoria"/>
</p>
<p class="amount">
<htk-text form="iter" column="amount"/> x
<htk-text form="iter" column="price" format="%.2d€"/>
</p>
<p class="subtotal">
<htk-text id="subtotal" format="%.2d€"/>
</p>
<div class="clear"/>
</div>
</custom>
</htk-repeater>
</div>
</div>
</vn>

View File

@ -1,7 +1,10 @@
Vn.include ('js/misc/tinymce/tinymce.min');
Vn.define (function () {
Vn.New = new Class
({
Extends: Vn.Module
Extends: Vn.Form
,activate: function ()
{
@ -68,3 +71,5 @@ Vn.New = new Class
}
});
});

View File

@ -5,35 +5,18 @@
}
.new .box
{
max-width: 50em;
margin: 0 auto;
max-width: 35em;
padding: 2em;
}
/* Form */
.new .form
{
padding: 2em;
}
.new div.form-group
{
padding: 0.4em;
}
.new div.form-group label
{
display: block;
margin-bottom: 0.5em;
}
.new div.form-group input,
.new div.form-group textarea,
.new div.form-group select
{
margin: 0;
width: 100%;
}
.new textarea
{
min-height: 26em;
min-height: 20em;
}
.new .foot

View File

@ -1,46 +1,56 @@
<vn>
<vn-group>
<vn-param id="new-id">
<vn-hash-param key="new"/>
</vn-param>
<vn-param id="new-id"/>
<vn-hash-param key="new" param="new-id"/>
<db-form id="iter" on-status-changed="onStatusChange">
<db-param column="text" on-changed="onBodyChange"/>
<db-model id="model" updatable="true" on-operations-done="onOperationsDone">
SELECT id, title, text, tag
FROM news WHERE id = #new
<db-model
id="model"
property="model"
updatable="true"
on-operations-done="onOperationsDone">
<custom>
SELECT id, title, text, tag
FROM news WHERE id = #new
</custom>
<sql-batch property="batch">
<item name="new" param="new-id"/>
<custom>
<item name="new" param="new-id"/>
</custom>
</sql-batch>
</db-model>
</db-form>
<db-param form="iter" column="text" on-changed="onBodyChange"/>
</vn-group>
<div id="title">
<h1><t>AddEditNew</t></h1>
</div>
<div id="actions">
<htk-button
image="image/dark/ok.svg"
tip="_Accept"
on-click="onAcceptClick"
showText="true"/>
<htk-button
image="image/dark/close.svg"
tip="_Return"
on-click="onReturnClick"
showText="true"/>
</div>
<div id="form" class="new">
<div class="box">
<div class="header">
<h1><t>AddEditNew</t></h1>
<div class="action-bar">
<button on-click="onReturnClick">
<img src="image/dark/go-previous.svg" alt=""/>
<t>Return</t>
</button>
<button on-click="onAcceptClick">
<img src="image/dark/ok.svg" alt=""/>
<t>Accept</t>
</button>
</div>
<div class="clear"/>
</div>
<div class="form">
<div class="form-group">
<label><t>Title</t></label>
<htk-entry column="title" form="iter"/>
<htk-entry form="iter" column="title"/>
</div>
<div class="form-group">
<label><t>Tag</t></label>
<htk-combo column="tag" form="iter">
<htk-combo form="iter" column="tag">
<db-model property="model">
SELECT name, description FROM news_tag
ORDER BY description
<custom>
SELECT name, description FROM news_tag
ORDER BY description
</custom>
</db-model>
</htk-combo>
</div>

View File

@ -1,7 +1,7 @@
Vn.News = new Class
({
Extends: Vn.Module
Extends: Vn.Form
,editNew: function (newId)
{
@ -11,9 +11,15 @@ Vn.News = new Class
});
}
,onEditClick: function (column, newId)
,onEditClick: function (button, form)
{
this.editNew (newId);
this.editNew (button.value);
}
,onDeleteClick: function (button, form)
{
if (confirm (_('ReallyDelete')))
form.deleteRow ();
}
,onAddClick: function ()

View File

@ -1,10 +1,48 @@
.news
{
padding: 1em;
min-width: 35em;
}
.news .box
{
max-width: 60em;
max-width: 35em;
margin: 0 auto;
}
/* Items */
.news .item
{
padding: 1em;
border-bottom: 1px solid #DDD;
}
.news .item > p
{
margin: .1em 0;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.news .item > p.important
{
font-size: 1.2em;
}
.news .item > .photo
{
float: left;
margin-right: 1em;
height: 5em;
width: 5em;
}
.news .item > .photo > img
{
display: block;
margin: 0 auto;
height: 100%;
max-width: 100%;
border-radius: .3em;
}
.news .item > button
{
float: right;
margin: 0;
}

View File

@ -1,38 +1,61 @@
<vn>
<div id="title">
<h1><t>NewsManagement</t></h1>
</div>
<div id="actions">
<htk-button
image="image/dark/add.svg"
tip="_AddNew"
on-click="onAddClick"
showText="true"/>
</div>
<div id="form" class="news">
<div class="box">
<div class="header">
<h1><t>NewsManagement</t></h1>
<div class="action-bar">
<button on-click="onAddClick">
<img src="image/dark/add.svg" alt=""/>
<t>AddNew</t>
</button>
</div>
</div>
<htk-grid>
<db-model id="news-model" updatable="true">
SELECT n.id, c.Cliente, priority, image,
CONCAT(LEFT(n.title, 25), '...') title
FROM news n
JOIN vn2008.Clientes c ON n.user_id = c.Id_Cliente
ORDER BY priority, n.date_time DESC
<htk-repeater form-id="iter">
<db-model property="model" id="news-model" updatable="true">
<custom>
SELECT n.id, c.Cliente, priority, image, title
FROM news n
JOIN vn2008.Clientes c ON n.user_id = c.Id_Cliente
ORDER BY priority, n.date_time DESC
</custom>
</db-model>
<htk-column-button
column="id"
tip="_EditNew"
image="image/edit.svg"
on-clicked="onEditClick"/>
<htk-column-image
column="image"
directory="news"
subdir="50x50"
show-full="true"
editable="true"/>
<htk-column-text title="_Title" column="title"/>
<htk-column-text title="_Author" column="Cliente"/>
<htk-column-spin title="_Priority" column="priority"/>
</htk-grid>
<custom>
<div class="item">
<htk-button
form="iter"
column="id"
tip="_EditNew"
image="image/edit.svg"
on-click="onEditClick"/>
<htk-button
form="iter"
column="id"
tip="_Remove"
image="image/delete.svg"
on-click="onDeleteClick"/>
<div class="photo">
<htk-image
form="iter"
column="image"
class="photo"
directory="news"
subdir="200x200"
editable="true"/>
</div>
<p class="important">
<htk-text form="iter" column="title"/>
</p>
<p>
<htk-text form="iter" column="Cliente"/>
</p>
<p>
<t>Priority</t>
<htk-text form="iter" column="priority"/>
</p>
</div>
</custom>
</htk-repeater>
</div>
</div>
</vn>

View File

@ -1,124 +0,0 @@
/* Generic */
@media screen and (orientation: landscape)
{
* { font-size: 13pt; }
}
@media screen and (orientation: portrait)
{
* { font-size: 26pt; }
}
/* Smartphones (portrait and landscape) */
@media only screen and (min-device-width : 320px) and (max-device-width : 480px){
* { font-size: 26pt; }
}
/* Smartphones (landscape) */
@media only screen and (min-width : 321px){
* { font-size: 13pt; }
}
/* Smartphones (portrait) */
@media only screen and (max-width : 320px){
* { font-size: 26pt; }
}
/* iPads (portrait and landscape) */
@media only screen and (min-device-width : 768px) and (max-device-width : 1024px){
* { font-size: 13pt; }
}
/* iPads (landscape) */
@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : landscape){
* { font-size: 10pt; }
}
/* iPads (portrait) */
@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : portrait){
* { font-size: 13pt; }
}
/* iPad 3 */
@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : landscape) and (-webkit-min-device-pixel-ratio : 2){
* { font-size: 10pt; }
}
@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : portrait) and (-webkit-min-device-pixel-ratio : 2){
* { font-size: 13pt; }
}
/* Desktops and laptops */
@media only screen and (min-width : 1224px){
* { font-size: 13pt; }
}
/* Large screens */
@media only screen and (min-width : 1824px){
* { font-size: 13pt; }
}
/* iPhone 4 */
@media only screen and (min-device-width : 320px) and (max-device-width : 480px) and (orientation : landscape) and (-webkit-min-device-pixel-ratio : 2){
* { font-size: 13pt; }
}
@media only screen and (min-device-width : 320px) and (max-device-width : 480px) and (orientation : portrait) and (-webkit-min-device-pixel-ratio : 2){
* { font-size: 26pt; }
}
/* iPhone 5 */
@media only screen and (min-device-width: 320px) and (max-device-height: 568px) and (orientation : landscape) and (-webkit-device-pixel-ratio: 2){
* { font-size: 13pt; }
}
@media only screen and (min-device-width: 320px) and (max-device-height: 568px) and (orientation : portrait) and (-webkit-device-pixel-ratio: 2){
* { font-size: 26pt; }
}
/* iPhone 6 */
@media only screen and (min-device-width: 375px) and (max-device-height: 667px) and (orientation : landscape) and (-webkit-device-pixel-ratio: 2){
* { font-size: 13pt; }
}
@media only screen and (min-device-width: 375px) and (max-device-height: 667px) and (orientation : portrait) and (-webkit-device-pixel-ratio: 2){
* { font-size: 26pt; }
}
/* iPhone 6+ */
@media only screen and (min-device-width: 414px) and (max-device-height: 736px) and (orientation : landscape) and (-webkit-device-pixel-ratio: 2){
* { font-size: 13pt; }
}
@media only screen and (min-device-width: 414px) and (max-device-height: 736px) and (orientation : portrait) and (-webkit-device-pixel-ratio: 2){
* { font-size: 26pt; }
}
/* Samsung Galaxy S3 */
@media only screen and (min-device-width: 320px) and (max-device-height: 640px) and (orientation : landscape) and (-webkit-device-pixel-ratio: 2){
* { font-size: 13pt; }
}
@media only screen and (min-device-width: 320px) and (max-device-height: 640px) and (orientation : portrait) and (-webkit-device-pixel-ratio: 2){
* { font-size: 26pt; }
}
/* Samsung Galaxy S4 */
@media only screen and (min-device-width: 320px) and (max-device-height: 640px) and (orientation : landscape) and (-webkit-device-pixel-ratio: 3){
* { font-size: 13pt; }
}
@media only screen and (min-device-width: 320px) and (max-device-height: 640px) and (orientation : portrait) and (-webkit-device-pixel-ratio: 3){
* { font-size: 26pt; }
}
/* Samsung Galaxy S5 */
@media only screen and (min-device-width: 360px) and (max-device-height: 640px) and (orientation : landscape) and (-webkit-device-pixel-ratio: 3){
* { font-size: 13pt; }
}
@media only screen and (min-device-width: 360px) and (max-device-height: 640px) and (orientation : portrait) and (-webkit-device-pixel-ratio: 3){
* { font-size: 26pt; }
}

View File

@ -1,12 +0,0 @@
/* Global */
@font-face {
font-family: 'Open Sans';
src: url(opensans.ttf) format('truetype');
}
*
{
font-size: 13px;
font-family: 'Open Sans', 'Verdana', 'Sans';
}

77
web/image/add-photo.svg Normal file
View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
height="16"
viewBox="0 0 16 16"
width="16"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="add-photo.svg"
style="fill:#000000">
<metadata
id="metadata14">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1016"
id="namedview12"
showgrid="false"
inkscape:zoom="9.8333333"
inkscape:cx="12.20339"
inkscape:cy="12"
inkscape:window-x="1920"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<defs
id="defs4">
<path
d="M 24,24 0,24 0,0 24,0 24,24 Z"
id="a"
inkscape:connector-curvature="0" />
</defs>
<clipPath
id="b">
<use
overflow="visible"
xlink:href="#a"
id="use8"
style="overflow:visible"
x="0"
y="0"
width="100%"
height="100%" />
</clipPath>
<path
clip-path="url(#b)"
d="M 3,4 3,1 5,1 5,4 8,4 8,6 5,6 5,9 3,9 3,6 0,6 0,4 3,4 Z M 6,10 6,7 9,7 9,4 16,4 17.83,6 21,6 c 1.1,0 2,0.9 2,2 l 0,12 c 0,1.1 -0.9,2 -2,2 L 5,22 C 3.9,22 3,21.1 3,20 l 0,-10 3,0 z m 7,9 c 2.76,0 5,-2.24 5,-5 0,-2.76 -2.24,-5 -5,-5 -2.76,0 -5,2.24 -5,5 0,2.76 2.24,5 5,5 z M 9.8,14 c 0,1.77 1.43,3.2 3.2,3.2 1.77,0 3.2,-1.43 3.2,-3.2 0,-1.77 -1.43,-3.2 -3.2,-3.2 -1.77,0 -3.2,1.43 -3.2,3.2 z"
id="path10"
inkscape:connector-curvature="0"
transform="matrix(0.60869565,0,0,0.60869565,1,1)"
style="fill:#666666;fill-opacity:1" />
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

154
web/image/blog.svg Normal file
View File

@ -0,0 +1,154 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="24"
height="23.998131"
id="svg2"
sodipodi:version="0.32"
inkscape:version="0.91 r13725"
sodipodi:docname="blog.svg"
version="1.0"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs4">
<linearGradient
inkscape:collect="always"
id="linearGradient2555">
<stop
style="stop-color: rgb(255, 255, 255); stop-opacity: 1;"
offset="0"
id="stop2557" />
<stop
style="stop-color: rgb(255, 255, 255); stop-opacity: 0;"
offset="1"
id="stop2559" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2555"
id="linearGradient2449"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-0.5914583,0,0,0.5914584,210.0216,142.2324)"
x1="-344.15295"
y1="274.711"
x2="-395.84943"
y2="425.39993" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="34.461017"
inkscape:cx="12"
inkscape:cy="11.999065"
inkscape:document-units="px"
inkscape:current-layer="layer1"
inkscape:window-width="1920"
inkscape:window-height="1016"
inkscape:window-x="1920"
inkscape:window-y="27"
showgrid="false"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<dc:creator>
<cc:Agent>
<dc:title />
</cc:Agent>
</dc:creator>
<dc:subject>
<rdf:Bag />
</dc:subject>
<cc:license
rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
<dc:description />
<dc:contributor>
<cc:Agent>
<dc:title />
</cc:Agent>
</dc:contributor>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
</cc:License>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-384.13803,-539.84063)">
<rect
inkscape:export-ydpi="7.7063322"
inkscape:export-xdpi="7.7063322"
inkscape:export-filename="C:\Documents and Settings\Molumen\Desktop\path3511111.png"
transform="scale(-1,1)"
ry="3.6241345"
rx="3.6241345"
y="539.84064"
x="-408.13803"
height="23.998131"
width="24"
id="rect1942"
style="fill:#8ed300;fill-opacity:1;fill-rule:evenodd;stroke:none" />
<path
inkscape:connector-curvature="0"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:3.06372762;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 393.34458,546.3858 3.48268,-0.0536 c 1.5948,0.0441 2.48113,1.17454 2.46467,2.46428 0.15459,1.52402 -0.27455,3.24973 -2.67899,3.21427 l -3.4291,0 c -1.51194,0.0146 -2.71918,-0.87387 -2.62541,-2.62499 -0.0749,-1.45077 0.40414,-3.02091 2.78615,-2.99999 z"
id="path3778"
sodipodi:nodetypes="ccccccc" />
<path
inkscape:connector-curvature="0"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:3.06372762;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 398.97045,558.17147 -5.35798,0 c -2.23262,0.0286 -3.30805,-0.9892 -3.1612,-3.32141 0.0105,-2.09647 1.2266,-2.69508 3.05404,-2.73214 l 5.3044,0 c 3.60674,-0.0963 3.21282,-0.13119 3.26837,2.78571 -0.0227,2.1206 -1.18894,3.25161 -3.10763,3.26784 z"
id="path3780"
sodipodi:nodetypes="ccccccc" />
<path
inkscape:connector-curvature="0"
style="fill:none;stroke:#ffffff;stroke-width:3.06372762;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 390.45127,555.27863 0.10716,-6.42855"
id="path3782"
sodipodi:nodetypes="cc" />
<path
inkscape:connector-curvature="0"
style="fill:none;stroke:#8ed300;stroke-width:2.55310631;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 393.59928,549.13968 2.9913,0.0475"
id="path3786"
sodipodi:nodetypes="cc" />
<path
inkscape:connector-curvature="0"
style="fill:none;stroke:#8ed300;stroke-width:2.55310631;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 393.25946,554.98949 5.98261,0"
id="path3788"
sodipodi:nodetypes="cc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.7 KiB

61
web/image/dark/exit.svg Normal file
View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
height="16"
viewBox="0 0 16 16"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="exit.svg">
<metadata
id="metadata12">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs10" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1016"
id="namedview8"
showgrid="false"
inkscape:zoom="51.5"
inkscape:cx="7.8543689"
inkscape:cy="8"
inkscape:window-x="1920"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<path
d="m 0,-32 48,0 0,48 -48,0 z"
id="path4"
inkscape:connector-curvature="0"
style="fill:none" />
<path
d="M 6.7233333,10.39 7.6666664,11.333334 11,8 7.6666664,4.6666664 6.7233333,5.6099996 8.4466664,7.3333328 2,7.3333328 l 0,1.3333344 6.4466664,0 L 6.7233333,10.39 Z M 12.666667,2 3.3333333,2 C 2.5966666,2 2,2.5966664 2,3.3333332 l 0,2.6666664 1.3333333,0 0,-2.6666664 9.3333337,0 0,9.3333338 -9.3333337,0 0,-2.666667 L 2,10 2,12.666667 C 2,13.403334 2.5966666,14 3.3333333,14 l 9.3333337,0 C 13.403334,14 14,13.403334 14,12.666667 L 14,3.3333332 C 14,2.5966664 13.403334,2 12.666667,2 Z"
id="path6"
inkscape:connector-curvature="0"
style="fill:#ffffff;fill-opacity:0.94117647;stroke:none;stroke-opacity:1" />
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<!-- The icon can be used freely in both personal and commercial projects with no attribution required, but always appreciated.
You may NOT sub-license, resell, rent, redistribute or otherwise transfer the icon without express written permission from iconmonstr.com -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
@ -9,115 +10,41 @@
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg7384"
version="1.1"
inkscape:version="0.48.5 r10040"
x="0px"
y="0px"
width="16"
height="16"
sodipodi:docname="info.svg"
width="16">
<metadata
id="metadata90">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Gnome Symbolic Icon Theme</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
inkscape:cy="7.0274833"
inkscape:current-layer="layer9"
inkscape:window-width="1920"
pagecolor="#555753"
showborder="false"
showguides="true"
inkscape:snap-nodes="true"
objecttolerance="10"
showgrid="false"
inkscape:object-nodes="true"
inkscape:pageshadow="2"
inkscape:guide-bbox="true"
inkscape:window-x="1920"
inkscape:snap-bbox="true"
viewBox="0 0 16 16"
enable-background="new 0 0 512 512"
xml:space="preserve"
id="svg2"
inkscape:version="0.91 r13725"
sodipodi:docname="info.svg"><metadata
id="metadata9"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs7" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
id="namedview88"
inkscape:window-maximized="1"
inkscape:snap-global="true"
inkscape:window-y="27"
gridtolerance="10"
inkscape:zoom="45.078231"
inkscape:window-height="1014"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:cx="3.8262706"
inkscape:bbox-paths="false"
inkscape:snap-grids="true"
inkscape:pageopacity="1"
inkscape:snap-to-guides="true">
<inkscape:grid
visible="true"
spacingx="1px"
type="xygrid"
spacingy="1px"
id="grid4866"
empspacing="2"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<title
id="title9167">Gnome Symbolic Icon Theme</title>
<defs
id="defs7386" />
<g
transform="translate(-281.0002,-257)"
inkscape:groupmode="layer"
id="layer9"
inkscape:label="status"
style="display:inline">
<path
d="m 287.53551,259.96102 c -0.32661,0 -0.66541,0.12985 -0.91815,0.38255 l -5.20278,5.20277 c -0.50544,0.50543 -0.50544,1.33087 0,1.83629 l 5.20278,5.20279 c 0.50544,0.50541 1.33084,0.50541 1.83629,0 l 5.20277,-5.20279 c 0.50544,-0.50542 0.50544,-1.33086 0,-1.83629 l -5.20277,-5.20277 c -0.25273,-0.2527 -0.59154,-0.38255 -0.91814,-0.38255 z m -0.15302,2.42286 c 1.34042,-0.075 2.52629,0.95493 2.60138,2.29534 -8e-5,1.14368 -0.30825,1.56841 -1.30069,2.32085 -0.15583,0.11723 -0.26573,0.20453 -0.30604,0.25504 -0.0403,0.0507 -0.0254,0.0271 -0.0254,0.0254 0.006,0.43119 -0.38491,0.81613 -0.81612,0.81613 -0.43122,0 -0.82184,-0.38494 -0.81612,-0.81613 0,-0.41 0.183,-0.76994 0.38255,-1.02014 0.19955,-0.25025 0.40096,-0.42144 0.58659,-0.56109 0.16652,-0.13104 0.37609,-0.31383 0.56108,-0.53558 0.0763,-0.0915 0.10528,-0.25108 0.10202,-0.35706 l 0,-0.0255 c -0.0258,-0.45966 -0.40746,-0.7909 -0.86714,-0.76511 -0.45966,0.0258 -0.79089,0.35644 -0.7651,0.81613 l -1.63226,0 c -0.075,-1.34043 0.95494,-2.37322 2.29535,-2.44838 z m 0.15302,6.52899 c 0.45072,0 0.81612,0.36539 0.81612,0.81611 0,0.45073 -0.3654,0.81612 -0.81612,0.81612 -0.45072,0 -0.81612,-0.36539 -0.81612,-0.81612 0,-0.45072 0.3654,-0.81611 0.81612,-0.81611 z"
id="path19592"
style="color:#bebebe;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible"
inkscape:connector-curvature="0" />
</g>
<g
transform="translate(-281.0002,-257)"
inkscape:groupmode="layer"
id="layer10"
inkscape:label="devices" />
<g
transform="translate(-281.0002,-257)"
inkscape:groupmode="layer"
id="layer11"
inkscape:label="apps" />
<g
transform="translate(-281.0002,-257)"
inkscape:groupmode="layer"
id="layer12"
inkscape:label="actions" />
<g
transform="translate(-281.0002,-257)"
inkscape:groupmode="layer"
id="layer13"
inkscape:label="places" />
<g
transform="translate(-281.0002,-257)"
inkscape:groupmode="layer"
id="layer14"
inkscape:label="mimetypes" />
<g
transform="translate(-281.0002,-257)"
inkscape:groupmode="layer"
id="layer15"
inkscape:label="emblems"
style="display:inline" />
<g
transform="translate(-281.0002,-257)"
inkscape:groupmode="layer"
id="g4953"
inkscape:label="categories"
style="display:inline" />
</svg>
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1016"
id="namedview5"
showgrid="false"
inkscape:zoom="51.6875"
inkscape:cx="7.2631221"
inkscape:cy="7.9613059"
inkscape:window-x="1920"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" /><path
id="info-2-icon"
d="m 7.999935,2.762144 c 2.89471,0 5.237934,2.342561 5.237934,5.23783 0,2.894749 -2.342691,5.237882 -5.237934,5.237882 -2.89471,0 -5.237804,-2.342626 -5.237804,-5.237882 0,-2.894723 2.342626,-5.23783 5.237804,-5.23783 m 0,-1.262144 C 4.410141,1.5 1.5,4.410115 1.5,7.999974 1.5,11.589846 4.410141,14.5 7.999935,14.5 11.589794,14.5 14.5,11.589846 14.5,7.999974 14.5,4.410115 11.589833,1.5 7.999935,1.5 l 0,0 z m 0.941044,10.020335 -1.818921,0 0,-4.321798 1.818921,0 0,4.321798 z M 8.031551,6.304566 c -0.552877,0 -1.001156,-0.448253 -1.001156,-1.001195 0,-0.552877 0.448253,-1.001169 1.001156,-1.001169 0.552942,0 1.00113,0.448253 1.00113,1.001169 0,0.552942 -0.448188,1.001195 -1.00113,1.001195 z"
inkscape:connector-curvature="0"
style="fill:#ffffff;fill-opacity:1" /></svg>

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Layer_1"
x="0px"
y="0px"
width="16"
height="16"
viewBox="0 0 16 16"
enable-background="new 0 0 512 512"
xml:space="preserve"
inkscape:version="0.91 r13725"
sodipodi:docname="new-order.svg"><metadata
id="metadata11"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs9" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1016"
id="namedview7"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="51.6875"
inkscape:cx="7.544033"
inkscape:cy="7.9613059"
inkscape:window-x="1920"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="Layer_1" /><g
id="g2988"
transform="matrix(0.03325942,0,0,0.03325942,-0.51441152,-0.68070862)"
style="fill:#ffffff;fill-opacity:1"><path
id="path3"
d="m 461.5,222 h -411 c -11.046,0 -20,8.954 -20,20 l 40,207 c 0,11.046 8.954,20 20,20 h 331 c 11.046,0 20,-8.954 20,-20 l 40,-207 c 0,-11.046 -8.954,-20 -20,-20 z M 138,403.5 c 0,5.799 -4.701,10.5 -10.5,10.5 h 0 c -5.799,0 -10.5,-4.701 -10.5,-10.5 v -117 c 0,-5.799 4.701,-10.5 10.5,-10.5 h 0.001 c 5.799,0 10.5,4.701 10.5,10.5 v 117 z m 66,0 c 0,5.799 -4.701,10.5 -10.5,10.5 h 0 c -5.799,0 -10.5,-4.701 -10.5,-10.5 v -117 c 0,-5.799 4.701,-10.5 10.5,-10.5 h 0.001 c 5.798,0 10.5,4.701 10.5,10.5 v 117 z m 62,0 c 0,5.799 -4.701,10.5 -10.5,10.5 h 0 c -5.799,0 -10.5,-4.701 -10.5,-10.5 v -117 c 0,-5.799 4.701,-10.5 10.5,-10.5 h 0.001 c 5.798,0 10.5,4.701 10.5,10.5 v 117 z m 65,0 c 0,5.799 -4.701,10.5 -10.5,10.5 -5.799,0 -10.5,-4.701 -10.5,-10.5 v -117 c 0,-5.799 4.701,-10.5 10.5,-10.5 5.799,0 10.5,4.701 10.5,10.5 v 117 z m 65,0 c 0,5.799 -4.701,10.5 -10.5,10.5 -5.799,0 -10.5,-4.701 -10.5,-10.5 v -117 c 0,-5.799 4.701,-10.5 10.5,-10.5 5.799,0 10.5,4.701 10.5,10.5 v 117 z"
inkscape:connector-curvature="0"
style="fill:#ffffff;fill-opacity:1" /><path
id="path5"
d="M 319.9,71.008 C 318.899,60.897 310.373,53 300,53 l -87,0 c -10.387,0 -18.92,7.919 -19.901,18.049 -19.155,-0.169 -49.697,-0.793 -60.374,3.647 -19.07,7.12 -34.01,24.74 -37.04,44.99 -4.64,29.089 -9.399,58.169 -13.91,87.291 6.721,0.029 13.44,0.159 20.16,-0.021 4.53,-27.64 8.83,-55.31 13.34,-82.95 1.83,-16.4 15.96,-30.24 32.12,-32.61 C 154.332,90.778 178.309,91 193.67,91.053 195.911,99.648 203.703,106 213,106 l 87,0 c 9.31,0 17.11,-6.37 19.34,-14.982 1.40554,-6.929611 1.55505,-12.101213 0.56,-20.01 z"
inkscape:connector-curvature="0"
style="fill:#ffffff;fill-opacity:1"
sodipodi:nodetypes="cssccccccccsscc" /></g><path
style="color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;stroke:#ff0b0b;stroke-width:0;stroke-linejoin:round;stroke-miterlimit:26.89999962;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none"
d="m 12.193371,0.78469625 0,1.99999315 -1.999993,0 0,0.9999966 1.999993,0 0,1.9999934 0.999997,0 0,-1.9999934 1.999994,0 0,-0.9999966 -1.999994,0 0,-1.99999315 -0.999997,0 z"
id="rect31992"
inkscape:connector-curvature="0" /></svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -9,10 +9,10 @@
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
sodipodi:docname="ok-dark.svg"
height="13.21348"
sodipodi:docname="ok.svg"
height="16"
id="svg7384"
inkscape:version="0.48.5 r10040"
inkscape:version="0.91 r13725"
version="1.1"
width="16">
<metadata
@ -32,8 +32,8 @@
bordercolor="#666666"
borderopacity="1"
inkscape:current-layer="layer15"
inkscape:cx="8.032386"
inkscape:cy="6.60674"
inkscape:cx="8"
inkscape:cy="8"
gridtolerance="10"
inkscape:guide-bbox="true"
guidetolerance="10"
@ -54,12 +54,12 @@
inkscape:snap-nodes="false"
inkscape:snap-others="false"
inkscape:snap-to-guides="true"
inkscape:window-height="1014"
inkscape:window-height="1016"
inkscape:window-maximized="1"
inkscape:window-width="1920"
inkscape:window-x="1920"
inkscape:window-y="27"
inkscape:zoom="61.755117"
inkscape:zoom="51.6875"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
@ -85,55 +85,55 @@
id="layer9"
inkscape:label="status"
style="display:inline"
transform="translate(-463.9375,-400.91152)" />
transform="translate(-463.9375,-398.125)" />
<g
inkscape:groupmode="layer"
id="layer10"
inkscape:label="devices"
transform="translate(-463.9375,-400.91152)" />
transform="translate(-463.9375,-398.125)" />
<g
inkscape:groupmode="layer"
id="layer11"
inkscape:label="apps"
transform="translate(-463.9375,-400.91152)" />
transform="translate(-463.9375,-398.125)" />
<g
inkscape:groupmode="layer"
id="layer13"
inkscape:label="places"
transform="translate(-463.9375,-400.91152)" />
transform="translate(-463.9375,-398.125)" />
<g
inkscape:groupmode="layer"
id="layer14"
inkscape:label="mimetypes"
transform="translate(-463.9375,-400.91152)" />
transform="translate(-463.9375,-398.125)" />
<g
inkscape:groupmode="layer"
id="layer15"
inkscape:label="emblems"
style="display:inline"
transform="translate(-463.9375,-400.91152)">
transform="translate(-463.9375,-398.125)">
<path
inkscape:connector-curvature="0"
d="m 475.64536,402.5632 -5.32585,5.32584 -2.08987,-2.08989 -2.29214,2.29215 3.23595,3.23594 1.14606,1.14607 1.14607,-1.14607 6.47192,-6.47192 -2.29214,-2.29212 z"
d="m 475.64536,401.16994 -5.32585,5.32584 -2.08987,-2.08989 -2.29214,2.29215 3.23595,3.23594 1.14606,1.14608 1.14607,-1.14608 6.47192,-6.47192 -2.29214,-2.29212 z"
id="path5037"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" />
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:3;marker:none;enable-background:accumulate" />
</g>
<g
inkscape:groupmode="layer"
id="g71291"
inkscape:label="emotes"
style="display:inline"
transform="translate(-463.9375,-400.91152)" />
transform="translate(-463.9375,-398.125)" />
<g
inkscape:groupmode="layer"
id="g4953"
inkscape:label="categories"
style="display:inline"
transform="translate(-463.9375,-400.91152)" />
transform="translate(-463.9375,-398.125)" />
<g
inkscape:groupmode="layer"
id="layer12"
inkscape:label="actions"
style="display:inline"
transform="translate(-463.9375,-400.91152)" />
transform="translate(-463.9375,-398.125)" />
</svg>

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Some files were not shown because too many files have changed in this diff Show More