0
1
Fork 0

Diseño responsive, ahora se aprobecha mejor el espacio, imports usan Javascript, vista de rejilla en catalogo, mas...

This commit is contained in:
Juan Ferrer Toribio 2015-09-11 11:37:16 +02:00
parent 1d50d7b874
commit 49085f3597
82 changed files with 3660 additions and 770 deletions

View File

@ -10,7 +10,7 @@ class Js
static function includeFile ($fileName) 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) static function includeLib ($libName)
@ -28,7 +28,7 @@ class Js
static function includeCss ($fileName) 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 () static function isMobile ()

View File

@ -102,14 +102,14 @@ class Tpv
$folder = sprintf ('INBOX.%s', $folder); $folder = sprintf ('INBOX.%s', $folder);
if (!imap_mail_move ($imap, $msg, $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 ,$folder
,imap_last_error () ,imap_last_error ()
); ), E_USER_WARNING);
} }
if ($inbox && ($count = count ($inbox)) > 0) if ($inbox && ($count = count ($inbox)) > 0)
error_log ('TPV: %d mails processed.', $count); trigger_error (sprintf ('TPV: %d mails processed.', $count));
imap_expunge ($imap); imap_expunge ($imap);
@ -138,13 +138,13 @@ class Tpv
$deleted += count ($messages); $deleted += count ($messages);
} }
error_log ('TPV: Cleaner: %d mails deleted.', $deleted); trigger_error (sprintf ('TPV: Cleaner: %d mails deleted.', $deleted));
} }
imap_close ($imap); imap_close ($imap);
} }
else else
error_log ('TPV: IMAP: %s', imap_last_error ()); trigger_error (sprintf ('TPV: IMAP: %s', imap_last_error ()), E_USER_ERROR);
self::deinit (); self::deinit ();
} }
@ -207,7 +207,7 @@ class Tpv
} }
catch (\Exception $e) catch (\Exception $e)
{ {
error_log ("TPV: DB: %s", $e->getMessage ()); trigger_error (sprintf ("TPV: DB: %s", $e->getMessage ()), E_USER_WARNING);
} }
} }

View File

@ -14,22 +14,17 @@
WHERE active != FALSE WHERE active != FALSE
</db-model> </db-model>
</vn-group> </vn-group>
<div id="form" class="address-list"> <div id="title">
<div class="box">
<div class="header">
<h1><t>Addresses</t></h1> <h1><t>Addresses</t></h1>
<div class="action-bar"> </div>
<button on-click="onReturnClick"> <div id="actions" class="action-bar">
<img src="image/dark/go-previous.svg" alt=""/>
<t>Return</t>
</button>
<button on-click="onAddAddressClick"> <button on-click="onAddAddressClick">
<img src="image/dark/add.svg" alt=""/> <img src="image/dark/add.svg" alt=""/>
<t>AddAddress</t> <t>AddAddress</t>
</button> </button>
</div> </div>
<div class="clear"/> <div id="form" class="address-list">
</div> <div class="box">
<div class="form"> <div class="form">
<htk-radio-group <htk-radio-group
id="default-address" id="default-address"

View File

@ -17,11 +17,10 @@
</db-model> </db-model>
</db-form> </db-form>
</vn-group> </vn-group>
<div id="form" class="address"> <div id="title">
<div class="box">
<div class="header">
<h1><t>AddEditAddress</t></h1> <h1><t>AddEditAddress</t></h1>
<div class="action-bar"> </div>
<div id="actions" class="action-bar">
<button on-click="onReturnClick"> <button on-click="onReturnClick">
<img src="image/dark/go-previous.svg" alt=""/> <img src="image/dark/go-previous.svg" alt=""/>
<t>Return</t> <t>Return</t>
@ -30,8 +29,9 @@
<img src="image/dark/ok.svg" alt=""/> <img src="image/dark/ok.svg" alt=""/>
<t>Accept</t> <t>Accept</t>
</button> </button>
</div> </div>
</div> <div id="form" class="address">
<div class="box">
<div class="body"> <div class="body">
<div class="form-group"> <div class="form-group">
<label><t>Name</t></label> <label><t>Name</t></label>

View File

@ -16,18 +16,17 @@
WHERE active != FALSE WHERE active != FALSE
</db-model> </db-model>
</vn-group> </vn-group>
<div id="form" class="conf"> <div id="title">
<div class="box">
<div class="header">
<h1><t>Configuration</t></h1> <h1><t>Configuration</t></h1>
<div class="action-bar"> </div>
<div id="actions" class="action-bar">
<button on-click="onAddressesClick"> <button on-click="onAddressesClick">
<img src="image/dark/shipping.svg" alt=""/> <img src="image/dark/shipping.svg" alt=""/>
<t>Addresses</t> <t>Addresses</t>
</button> </button>
</div> </div>
<div class="clear"/> <div id="form" class="conf">
</div> <div class="box">
<div class="form"> <div class="form">
<div class="form-group"> <div class="form-group">
<label for="user-name"><t>UserName</t></label> <label for="user-name"><t>UserName</t></label>

View File

@ -13,11 +13,11 @@
</db-model> </db-model>
</db-form> </db-form>
</vn-group> </vn-group>
<div id="title">
<h1><t>AccessLog</t></h1>
</div>
<div id="form" class="access-log"> <div id="form" class="access-log">
<div class="box"> <div class="box">
<div class="header">
<h1><t>AccessLog</t></h1>
</div>
<table class="form"> <table class="form">
<tbody> <tbody>
<tr> <tr>

View File

@ -1,9 +1,9 @@
<vn> <vn>
<div id="title">
<h1><t>ControlPanel</t></h1>
</div>
<div id="form" class="cpanel"> <div id="form" class="cpanel">
<div class="box"> <div class="box">
<div class="header">
<h1><t>ControlPanel</t></h1>
</div>
<htk-grid show-header="false"> <htk-grid show-header="false">
<db-model> <db-model>
SELECT image, name, description, link FROM link SELECT image, name, description, link FROM link

View File

@ -1,9 +1,9 @@
<vn> <vn>
<div id="title">
<h1><t>Photos</t></h1>
</div>
<div id="form" class="photos"> <div id="form" class="photos">
<div class="box"> <div class="box">
<div class="header">
<h1><t>Photos</t></h1>
</div>
<div class="body"> <div class="body">
<form <form
method="post" method="post"

View File

@ -1,9 +1,9 @@
<vn> <vn>
<div id="title">
<h1><t>UserManagement</t></h1>
</div>
<div id="form" class="users"> <div id="form" class="users">
<div class="box"> <div class="box">
<div class="header">
<h1><t>UserManagement</t></h1>
</div>
<table class="form"> <table class="form">
<tbody> <tbody>
<tr> <tr>

View File

@ -1,9 +1,8 @@
<vn> <vn>
<div id="form" class="visits"> <div id="title">
<div class="box">
<div class="header">
<h1><t>VisitsManagement</t></h1> <h1><t>VisitsManagement</t></h1>
<div class="action-bar"> </div>
<div id="actions" class="action-bar">
<button on-click="onRefreshClick"> <button on-click="onRefreshClick">
<img src="image/dark/refresh.svg" alt=""/> <img src="image/dark/refresh.svg" alt=""/>
<t>Refresh</t> <t>Refresh</t>
@ -16,8 +15,9 @@
<img src="image/dark/graph.svg" alt=""/> <img src="image/dark/graph.svg" alt=""/>
<t>VisitsQuery</t> <t>VisitsQuery</t>
</button> </button>
</div> </div>
</div> <div id="form" class="visits">
<div class="box">
<div class="step" id="sessions-step"> <div class="step" id="sessions-step">
<table class="form"> <table class="form">
<tbody> <tbody>

View File

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

View File

@ -2,10 +2,5 @@
Vn.Provinces = new Class Vn.Provinces = new Class
({ ({
Extends: Vn.Module Extends: Vn.Module
,onReturnClick: function ()
{
window.history.back();
}
}); });

View File

@ -4,18 +4,11 @@
<vn-hash-param key="agency"/> <vn-hash-param key="agency"/>
</vn-param> </vn-param>
</vn-group> </vn-group>
<div id="title">
<h1><t>ByProvince</t></h1>
</div>
<div id="form" class="provinces"> <div id="form" class="provinces">
<div class="box"> <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> <htk-grid>
<db-model> <db-model>
CALL vn2008.desglose_volume (#agency) CALL vn2008.desglose_volume (#agency)

View File

@ -1,4 +1,7 @@
<vn> <vn>
<div id="title">
<h1><t>About</t></h1>
</div>
<div id="form" class="about"> <div id="form" class="about">
<div class="box"> <div class="box">
<div> <div>

View File

@ -1,9 +1,9 @@
<vn> <vn>
<div id="title">
<h1><t>IWantCustomer</t></h1>
</div>
<div id="form" class="contact"> <div id="form" class="contact">
<div class="box"> <div class="box">
<div class="header">
<h1><t>IWantCustomer</t></h1>
</div>
<div class="body"> <div class="body">
<p> <p>
<t>FillFormData</t> <t>FillFormData</t>

View File

@ -1,4 +1,7 @@
<vn> <vn>
<div id="title">
<h1><t>Home</t></h1>
</div>
<div id="form" class="home"> <div id="form" class="home">
<div class="column mansonry" id="news-column"> <div class="column mansonry" id="news-column">
<htk-repeater form-id="new"> <htk-repeater form-id="new">

View File

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

View File

@ -1,4 +1,7 @@
<vn> <vn>
<div id="title">
<h1><t>Training</t></h1>
</div>
<div id="form" class="training"> <div id="form" class="training">
<div class="column masonry" id="news-column"> <div class="column masonry" id="news-column">
<htk-repeater form-id="new"> <htk-repeater form-id="new">

View File

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

View File

@ -1,9 +1,8 @@
<vn> <vn>
<div id="form" class="basket"> <div id="title">
<div class="box">
<div class="header">
<h1><t>ShoppingBasket</t></h1> <h1><t>ShoppingBasket</t></h1>
<div class="action-bar"> </div>
<div id="actions" class="action-bar">
<button on-click="onConfigureClick" title="_ConfigureOrder"> <button on-click="onConfigureClick" title="_ConfigureOrder">
<img class="config" src="image/dark/preferences.svg" alt=""/> <img class="config" src="image/dark/preferences.svg" alt=""/>
</button> </button>
@ -15,9 +14,9 @@
<img src="image/dark/ok.svg" alt=""/> <img src="image/dark/ok.svg" alt=""/>
<t>Checkout</t> <t>Checkout</t>
</button> </button>
</div> </div>
<div class="clear"/> <div id="form" class="basket">
</div> <div class="box">
<div> <div>
<htk-grid show-header="false"> <htk-grid show-header="false">
<db-model id="items" updatable="true"> <db-model id="items" updatable="true">

View File

@ -23,6 +23,11 @@ Vn.Catalog = new Class
} }
} }
,deactivate: function ()
{
this.gui.$('top-bar').style.backgroundColor = '';
}
,onBasketForGuest: function () ,onBasketForGuest: function ()
{ {
this.onBasketCheck (true); this.onBasketCheck (true);
@ -82,14 +87,14 @@ Vn.Catalog = new Class
color = '#'+ realms.get (row, 'color'); color = '#'+ realms.get (row, 'color');
} }
this.$('header').style.backgroundColor = color; this.gui.$('top-bar').style.backgroundColor = color;
/*
var tr = this.$('items-grid').getNode () var tr = this.$('items-grid').getNode ()
.getElementsByTagName ('thead')[0] .getElementsByTagName ('thead')[0]
.getElementsByTagName ('tr')[0]; .getElementsByTagName ('tr')[0];
//.querySelector ('thead tr'); //.querySelector ('thead tr');
tr.style.backgroundColor = color; tr.style.backgroundColor = color;
} */ }
,refreshTitle: function (title) ,refreshTitle: function (title)
{ {
@ -110,7 +115,7 @@ Vn.Catalog = new Class
else if (this.$('search-entry').value) else if (this.$('search-entry').value)
title = _('SearchResults'); title = _('SearchResults');
Vn.Node.setText (this.$('title'), title); Vn.Node.setText (this.$('title-text'), title);
} }
,onSearch: function (event) ,onSearch: function (event)
@ -163,6 +168,11 @@ Vn.Catalog = new Class
Htk.Toast.showError (_('YouMustBeLoggedIn')); Htk.Toast.showError (_('YouMustBeLoggedIn'));
} }
,nameRenderer: function (renderer, form)
{
renderer.subtitle = form.get ('producer');
}
,featuresRender: function (renderer, form) ,featuresRender: function (renderer, form)
{ {
renderer.value = form.get ('Medida') +' '+ form.get ('Categoria') +' '+ form.get ('Color'); renderer.value = form.get ('Medida') +' '+ form.get ('Categoria') +' '+ form.get ('Color');
@ -200,7 +210,17 @@ Vn.Catalog = new Class
} }
} }
,onGridAddItemClick: function (button, form)
{
this.showAmountPopup (button, form.row);
}
,onAddItemClick: function (column, value, row, button) ,onAddItemClick: function (column, value, row, button)
{
this.showAmountPopup (button, row);
}
,showAmountPopup: function (button, row)
{ {
if (Vn.Url.getQuery ('guest')) if (Vn.Url.getQuery ('guest'))
{ {
@ -283,3 +303,30 @@ Vn.Catalog = new Class
} }
}); });
Htk.ColumnCheck = new Class
({
Extends: Htk.Column
,Tag: 'vn-column-item'
,render: function (tr)
{
var td = this.parent (tr);
td.style.textAlign = 'left';
if (this.value)
{
var node = document.createTextNode (
Vn.Value.format (this.value, this._format));
td.appendChild (node);
}
if (this.subtitle)
{
td.appendChild (document.createElement ('br'));
td.appendChild (document.createTextNode (this.subtitle));
}
return td;
}
});

View File

@ -1,13 +0,0 @@
.catalog button.menu
{
display: block;
}
.catalog div.menu
{
display: none;
}
.catalog div.center
{
right: 0;
}

View File

@ -24,9 +24,9 @@
left: 0; left: 0;
right: 0; right: 0;
overflow: auto; overflow: auto;
padding: 1em; padding: .4em;
} }
.catalog div.main .box .catalog div.main .list-view
{ {
margin: 0 auto; margin: 0 auto;
max-width: 50em; max-width: 50em;
@ -45,7 +45,7 @@
{ {
max-width: 15em; max-width: 15em;
} }
.catalog .search .search
{ {
float: left; float: left;
display: block; display: block;
@ -53,38 +53,23 @@
height: 2.2em; height: 2.2em;
padding: 0; padding: 0;
} }
.catalog .search > input .search > input
{ {
margin: 0; margin: 0;
border: none; border: none;
width: 10em; width: 10em;
box-shadow: none; box-shadow: none;
} }
.catalog .search > input:focus .search > input:focus
{ {
background-color: initial; background-color: initial;
} }
.catalog .search > img .search > img
{ {
margin: 0.4em; margin: 0.4em;
margin-top: 0; margin-top: 0;
vertical-align: middle; 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;
}
/* Menu */ /* Menu */
@ -160,46 +145,6 @@ button.basket:hover
background-color: rgba(1, 1, 1, .1); 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;
}
.item-box h2
{
font-weight: normal;
}
.item-box .amount
{
width: 3em;
}
.amount-p
{
text-align: right;
}
/* Lots popup*/ /* Lots popup*/
div.amount div.amount
@ -240,18 +185,17 @@ button.confirm > img
{ {
height: 6em; height: 6em;
} }
.items > tbody img
{
max-height: 6em;
max-width: 6em;
border-radius: 50%;
}
.items .icon .items .icon
{ {
width: 6em; width: 6em;
padding: .2em; padding: .2em;
padding-right: .5em; padding-right: .5em;
} }
.items .icon > img
{
max-height: 6em;
max-width: 6em;
}
td.second-category td.second-category
{ {
font-weight: bold; font-weight: bold;
@ -262,8 +206,99 @@ td.third-category
font-weight: bold; font-weight: bold;
color: red; color: red;
} }
td.price .catalog .price
{ {
color: green; color: green;
font-size: 1.1em;
}
/* Grid view */
.catalog .grid-view
{
text-align: center;
}
.item-box
{
text-align: left;
position: relative;
width: 22em;
display: inline-block;
padding: .8em;
margin: .4em;
margin-bottom: .1em;
height: 9em;
overflow: hidden;
}
.item-box > .image
{
width: 9em;
height: 100%;
float: left;
margin-right: 1em;
}
.item-box img
{
max-width: 9em;
max-height: 9em;
display: block;
margin: 0 auto;
}
.item-box > p
{
margin: 0;
padding: 0;
font-size: .9em;
}
.item-box > h2
{
font-size: 1.1em;
font-weight: normal;
}
.item-box > .aval-price
{
position: absolute;
bottom: 1em;
right: 4em;
}
.item-box > .add-button
{
position: absolute;
bottom: .5em;
right: .5em;
}
/* Mobile */
.catalog-actions button.menu
{
float: left;
display: none;
border: none;
background-color: transparent;
box-shadow: none;
padding: 0.3em;
padding-left: 0;
margin-left: 0;
}
.catalog-actions button.menu > img
{
height: 1.8em;
}
@media (max-width: 950px)
{
.catalog-actions button.menu
{
display: block;
}
.catalog div.menu
{
display: none;
}
.catalog div.center
{
right: 0;
}
} }

View File

@ -29,7 +29,7 @@
SELECT Id_Article item_id FROM vn2008.Articles SELECT Id_Article item_id FROM vn2008.Articles
WHERE #filter; WHERE #filter;
CALL bionic_calc (); CALL bionic_calc ();
SELECT t.item_id, t.available, t.price, SELECT t.item_id, t.available, t.price, t.producer,
a.Foto, a.Article, a.Categoria, a.Medida, a.Tallos, a.Color, o.Abreviatura a.Foto, a.Article, a.Categoria, a.Medida, a.Tallos, a.Color, o.Abreviatura
FROM tmp.bionic_item t FROM tmp.bionic_item t
JOIN vn2008.Articles a ON a.Id_Article = t.item_id JOIN vn2008.Articles a ON a.Id_Article = t.item_id
@ -59,24 +59,23 @@
<sql-batch property="batch" id="lots-batch"/> <sql-batch property="batch" id="lots-batch"/>
</db-model> </db-model>
</vn-group> </vn-group>
<div id="form" class="catalog"> <div id="title">
<div class="center"> <h1 id="title-text"><t>Catalog</t></h1>
<div class="main"> </div>
<div class="box"> <div id="actions" class="action-bar catalog-actions">
<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"> <div class="search">
<img src="image/search.svg" alt="_Search" class="icon"/> <img src="image/search.svg" alt="_Search" class="icon"/>
<input type="text" id="search-entry" on-change="onSearch"/> <input type="text" id="search-entry" on-change="onSearch"/>
</div> </div>
</div> <button class="menu" on-click="onShowMenuClick">
<div class="clear"/> <img src="image/dark/menu.svg" alt="_Menu"/>
</div> </button>
<htk-grid empty-message="_SelectSubtype" id="items-grid" class="items" model="items-model"> </div>
<div id="form" class="catalog">
<div class="center">
<div class="main">
<!-- <div class="box list-view">
<htk-grid empty-message="_SelectSubtype" show-header="false" id="items-grid" class="items" model="items-model">
<htk-column-image <htk-column-image
title="*" title="*"
class="icon" class="icon"
@ -86,7 +85,7 @@
show-full="true" show-full="true"
full-dir="900x900" full-dir="900x900"
editable="true"/> editable="true"/>
<htk-column-text title="_Name" column="Article"/> <vn-column-item title="_Name" column="Article" renderer="nameRenderer"/>
<htk-column-text title="_Cat" renderer="featuresRender"/> <htk-column-text title="_Cat" renderer="featuresRender"/>
<htk-column-spin title="_Aval" column="available"/> <htk-column-spin title="_Aval" column="available"/>
<htk-column-text <htk-column-text
@ -104,6 +103,43 @@
<t>IndicativePhotos</t> <t>IndicativePhotos</t>
</p> </p>
</div> </div>
--> <htk-repeater id="grid-view" class="grid-view" form-id="item" model="items-model">
<template>
<div class="box item-box">
<div class="image">
<htk-image form="item" column="Foto" directory="catalog/200x200"/>
</div>
<h2>
<htk-text form="item" column="Article"/>
</h2>
<p>
<htk-text form="item" column="producer"/>
</p>
<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>
<div class="aval-price">
<htk-text form="item" column="available"/>
<t>from</t>
<span class="price">
<htk-text form="item" column="price" format="%.2d€"/>
</span>
</div>
<htk-button
form="iter"
column="id"
tip="_AddToBasket"
image="image/add.svg"
on-click="onGridAddItemClick"
class="add-button"/>
<div class="clear"/>
</div>
</template>
</htk-repeater>
</div> </div>
</div> </div>
<div id="menu" class="menu" on-click="onMenuClick"> <div id="menu" class="menu" on-click="onMenuClick">
@ -170,41 +206,4 @@
<div class="clear"/> <div class="clear"/>
</div> </div>
</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>
</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>
</template>
</htk-repeater>
-->
</vn> </vn>

View File

@ -47,18 +47,17 @@
</sql-batch> </sql-batch>
</db-model> </db-model>
</vn-group> </vn-group>
<div id="form" class="checkout"> <div id="title">
<div class="box">
<div class="header">
<h1><t>ConfigureOrder</t></h1> <h1><t>ConfigureOrder</t></h1>
<div class="action-bar"> </div>
<div id="actions" class="action-bar">
<button on-click="onCancelClick"> <button on-click="onCancelClick">
<img src="image/dark/close.svg" alt=""/> <img src="image/dark/close.svg" alt=""/>
<t>Cancel</t> <t>Cancel</t>
</button> </button>
</div> </div>
<div class="clear"/> <div id="form" class="checkout">
</div> <div class="box">
<div class="form"> <div class="form">
<htk-assistant <htk-assistant
id="assistant" id="assistant"

View File

@ -27,11 +27,11 @@
SELECT customer_get_debt(); SELECT customer_get_debt();
</db-query> </db-query>
</vn-group> </vn-group>
<div id="title">
<h1><t>OrderSummary</t></h1>
</div>
<div id="form" class="confirm"> <div id="form" class="confirm">
<div class="box"> <div class="box">
<div class="header">
<h1><t>OrderSummary</t></h1>
</div>
<div class="form"> <div class="form">
<div class="section"> <div class="section">
<p> <p>

View File

@ -1,9 +1,9 @@
<vn> <vn>
<div id="title">
<h1><t>Invoices</t></h1>
</div>
<div id="form" class="invoices"> <div id="form" class="invoices">
<div class="box"> <div class="box">
<div class="header">
<h1><t>Invoices</t></h1>
</div>
<div> <div>
<htk-grid show-header="false"> <htk-grid show-header="false">
<db-model id="tickets"> <db-model id="tickets">

View File

@ -1,9 +1,8 @@
<vn> <vn>
<div id="form" class="orders"> <div id="title">
<div class="box confirmed">
<div class="header">
<h1><t>LastOrders</t></h1> <h1><t>LastOrders</t></h1>
<div class="action-bar"> </div>
<div id="actions" class="action-bar">
<div id="balance"> <div id="balance">
<t>PendingBalance:</t> <t>PendingBalance:</t>
<htk-label format="%.2d€" conditional-func="balanceConditionalFunc"> <htk-label format="%.2d€" conditional-func="balanceConditionalFunc">
@ -18,9 +17,9 @@
<img src="image/dark/basket.svg" alt=""/> <img src="image/dark/basket.svg" alt=""/>
<t>Basket</t> <t>Basket</t>
</button> </button>
</div> </div>
<div class="clear"/> <div id="form" class="orders">
</div> <div class="box confirmed">
<div> <div>
<htk-grid show-header="false"> <htk-grid show-header="false">
<db-model id="tickets"> <db-model id="tickets">

View File

@ -18,17 +18,17 @@
</db-model> </db-model>
</db-form> </db-form>
</vn-group> </vn-group>
<div id="form" class="ticket"> <div id="title">
<div class="box">
<div class="header">
<h1><t>OrderDetail</t></h1> <h1><t>OrderDetail</t></h1>
<div class="action-bar"> </div>
<div id="actions" class="action-bar">
<button id="print"> <button id="print">
<img src="image/dark/print.svg" alt=""/> <img src="image/dark/print.svg" alt=""/>
<t>Print</t> <t>Print</t>
</button> </button>
</div> </div>
</div> <div id="form" class="ticket">
<div class="box">
<div id="report"> <div id="report">
<table class="form"> <table class="form">
<tbody> <tbody>

View File

@ -33,7 +33,7 @@
} }
.new textarea .new textarea
{ {
min-height: 26em; min-height: 20em;
} }
.new .foot .new .foot

View File

@ -14,22 +14,17 @@
</db-model> </db-model>
</db-form> </db-form>
</vn-group> </vn-group>
<div id="form" class="new"> <div id="title">
<div class="box">
<div class="header">
<h1><t>AddEditNew</t></h1> <h1><t>AddEditNew</t></h1>
<div class="action-bar"> </div>
<button on-click="onReturnClick"> <div id="actions" class="action-bar">
<img src="image/dark/go-previous.svg" alt=""/>
<t>Return</t>
</button>
<button on-click="onAcceptClick"> <button on-click="onAcceptClick">
<img src="image/dark/ok.svg" alt=""/> <img src="image/dark/ok.svg" alt=""/>
<t>Accept</t> <t>Accept</t>
</button> </button>
</div> </div>
<div class="clear"/> <div id="form" class="new">
</div> <div class="box">
<div class="form"> <div class="form">
<div class="form-group"> <div class="form-group">
<label><t>Title</t></label> <label><t>Title</t></label>

View File

@ -1,16 +1,16 @@
<vn> <vn>
<div id="form" class="news"> <div id="title">
<div class="box">
<div class="header">
<h1><t>NewsManagement</t></h1> <h1><t>NewsManagement</t></h1>
<div class="action-bar"> </div>
<div id="actions" class="action-bar">
<button on-click="onAddClick"> <button on-click="onAddClick">
<img src="image/dark/add.svg" alt=""/> <img src="image/dark/add.svg" alt=""/>
<t>AddNew</t> <t>AddNew</t>
</button> </button>
</div> </div>
</div> <div id="form" class="news">
<htk-grid> <div class="box">
<htk-grid show-header="false">
<db-model id="news-model" updatable="true"> <db-model id="news-model" updatable="true">
SELECT n.id, c.Cliente, priority, image, SELECT n.id, c.Cliente, priority, image,
CONCAT(LEFT(n.title, 25), '...') title CONCAT(LEFT(n.title, 25), '...') title

View File

@ -4,10 +4,10 @@ use Vn\Hedera\Web;
if ($result = Web::$sysConn->query ('SELECT name, content FROM metatag')) if ($result = Web::$sysConn->query ('SELECT name, content FROM metatag'))
{ {
echo '<meta name="content-language" content="'.$_SESSION['lang'].'"/>'."\n\t"; echo '<meta name="content-language" content="'.$_SESSION['lang'].'"/>'."\n\t\t";
while ($row = $result->fetch_assoc ()) while ($row = $result->fetch_assoc ())
echo '<meta name="'.$row['name'].'" content="'.$row['content'].'"/>'."\n\t"; echo '<meta name="'.$row['name'].'" content="'.$row['content'].'"/>'."\n\t\t";
$result->free (); $result->free ();
} }

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="17.166667"
inkscape:cx="23.563107"
inkscape:cy="24"
inkscape:window-x="0"
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.9361111,9.991667 7.722222,10.777778 10.5,8 7.722222,5.222222 6.9361111,6.008333 8.372222,7.444444 3,7.444444 l 0,1.111112 5.372222,0 -1.4361109,1.436111 z M 11.888889,3 4.1111111,3 C 3.4972222,3 3,3.497222 3,4.111111 l 0,2.222222 1.1111111,0 0,-2.222222 7.7777779,0 0,7.777778 -7.7777779,0 0,-2.222222 -1.1111111,0 0,2.222222 C 3,12.502778 3.4972222,13 4.1111111,13 l 7.7777779,0 C 12.502778,13 13,12.502778 13,11.888889 L 13,4.111111 C 13,3.497222 12.502778,3 11.888889,3 Z"
id="path6"
inkscape:connector-curvature="0"
style="stroke:none;stroke-opacity:1;fill:#ffffff;fill-opacity:0.94117647" />
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

61
web/image/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="17.166667"
inkscape:cx="23.563107"
inkscape:cy="24"
inkscape:window-x="0"
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.9361111,9.991667 7.722222,10.777778 10.5,8 7.722222,5.222222 6.9361111,6.008333 8.372222,7.444444 3,7.444444 l 0,1.111112 5.372222,0 -1.4361109,1.436111 z M 11.888889,3 4.1111111,3 C 3.4972222,3 3,3.497222 3,4.111111 l 0,2.222222 1.1111111,0 0,-2.222222 7.7777779,0 0,7.777778 -7.7777779,0 0,-2.222222 -1.1111111,0 0,2.222222 C 3,12.502778 3.4972222,13 4.1111111,13 l 7.7777779,0 C 12.502778,13 13,12.502778 13,11.888889 L 13,4.111111 C 13,3.497222 12.502778,3 11.888889,3 Z"
id="path6"
inkscape:connector-curvature="0"
style="stroke:none;stroke-opacity:1;fill:#66666f;fill-opacity:0.94117647" />
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -78,12 +78,15 @@ Db.Conn.implement
if (success) if (success)
try { try {
var json = request.getJson (); var json = request.getJson ();
openSuccess = true /* json.data */; openSuccess = json.data == true;
} }
catch (e) {} catch (e) {}
if (openSuccess) if (openSuccess)
{
this.connected = true; this.connected = true;
this.signalEmit ('openned');
}
this.signalEmit ('loading-changed', false); this.signalEmit ('loading-changed', false);
@ -101,7 +104,7 @@ Db.Conn.implement
this.signalEmit ('loading-changed', true); this.signalEmit ('loading-changed', true);
var request = new Vn.HttpRequest (); var request = new Vn.HttpRequest ();
request.addValue ({'action': 'close'}); request.add ({'action': 'close'});
request.send ('rest.php', request.send ('rest.php',
this.closed.bind (this, closeCallback)); this.closed.bind (this, closeCallback));
} }

5
web/js/db/db.js Executable file
View File

@ -0,0 +1,5 @@
/**
* The namespace.
**/
var Db = {};

View File

@ -1,5 +1,17 @@
/**
* The namespace. Vn.includeJs ('js/sql/main.js');
**/ Vn.includeLib ('db',
var Db = {}; [
'db'
,'conn'
,'result'
,'result-set'
,'model'
,'iterator'
,'form'
,'param'
,'query'
,'calc'
,'calc-sum'
]);

View File

@ -3,7 +3,7 @@
require_once ('js/sql/main.php'); require_once ('js/sql/main.php');
Vn\Hedera\Js::includeLib ('db' Vn\Hedera\Js::includeLib ('db'
,'main' ,'db'
,'conn' ,'conn'
,'result' ,'result'
,'result-set' ,'result-set'

87
web/js/hedera/app.js Normal file
View File

@ -0,0 +1,87 @@
Vn.App = new Class
({
initialize: function ()
{
window.onerror = this.onWindowError.bind (this);
Vn.Hash.initialize ();
this.conn = new Db.Conn ();
this.login = new Vn.Login ({conn: this.conn});
}
,run: function ()
{
if (Vn.Cookie.check ('vn_pass'))
{
this.conn.open (null, null, null,
this.onAutoLogin.bind (this));
}
else
{
this.login.on ('login', this.onLogin, this);
this.login.show ();
}
}
,onAutoLogin: function (success)
{
if (!success)
{
Vn.Cookie.unset ('vn_pass');
this.run ();
}
else
this.onLogin ();
}
,onLogin: function ()
{
this.login.disconnectByInstance (this);
this.login.hide ();
var gui = new Vn.Gui ({conn: this.conn});
gui.on ('logout', this.onLogout, this);
gui.show ();
}
,onLogout: function (gui)
{
gui.hide ();
gui.unref ();
Vn.Cookie.unset ('vn_pass');
this.run ();
}
,onWindowError: function (message, file, line)
{
var error = new Error (message);
error.fileName = file;
error.lineNumber = line;
Htk.Toast.showError (_('InternalError'));
this.notifyError (error);
}
,notifyError: function (error)
{
if (error instanceof Error)
{
var httpRequest = new Vn.HttpRequest ()
httpRequest.add
({
'file': error.fileName
,'line': error.lineNumber
,'message': error.message
,'stack': error.stack
});
httpRequest.send ('log.php');
}
}
,_destroy: function ()
{
this.login.unref ();
this.conn.unref ();
}
});

332
web/js/hedera/gui.css Executable file
View File

@ -0,0 +1,332 @@
.vn-gui
{
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
/* Font */
.vn-gui .welcome,
.vn-gui .menu-title,
.vn-gui .main-menu a
{
font-size: 1.1em;
}
/* Header */
.vn-gui .top-bar,
.vn-gui .exit
{
height: 3.9em;
}
.vn-gui .top-bar
{
position: relative;
background-color: #009688;
width: 100%;
z-index: 1;
overflow: hidden;
box-shadow: 0 0.1em 0.1em #AAA;
}
.vn-gui .top-bar
{
color: white;
}
.vn-gui .menu-button
{
display: none;
float: left;
border: none;
background-color: transparent;
padding: 0 .4em;
margin: 0;
height: 100%;
}
.vn-gui .menu-button:hover
{
background-color: rgba(0, 0, 0, .2);
}
.vn-gui .menu-button img
{
margin-top: .2em;
height: 1.8em;
}
.vn-gui .title
{
float: left;
}
.vn-gui .title h1
{
font-weight: normal;
font-size: 1.4em;
padding: .7em .6em;
margin: 0;
}
.vn-gui .actions-holder
{
float: right;
padding: .5em 1em;
padding-left: 0;
}
.vn-gui .top-bar > .loader
{
float: right;
margin: 1.1em;
visibility: hidden;
}
.vn-gui .exit
{
float: right;
padding: 0 .4em;
}
.vn-gui .exit img
{
height: 2.2em;
display: block;
margin: .8em auto;
}
.vn-gui .exit:hover
{
background-color: rgba(0, 0, 0, .2);
}
/* Body */
.vn-gui > .body
{
position: absolute;
top: 0;
bottom: 0;
left: 15em;
right: 0;
}
.vn-gui .content
{
position: absolute;
top: 3.9em;
bottom: 0;
left: 0;
right: 0;
}
/* Left panel */
.vn-gui .menu-header
{
height: 5.5em;
background-color: #333;
}
.vn-gui .logo
{
width: 12em;
float: left;
margin: 1em;
margin-bottom: .2em;
}
.vn-gui .welcome
{
float: left;
color: white;
margin: .5em 1em;
}
.vn-gui .background
{
z-index: 10;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(10, 10, 10, 0.6);
display: none;
}
.vn-gui .left-panel,
.vn-gui .main-menu > li,
.vn-gui ul.submenu
{
width: 15em;
}
.vn-gui .left-panel
{
z-index: 20;
position: absolute;
left: 0;
bottom: 0;
top: 0;
background-color: white;
z-index: 20;
box-shadow: 0 0.2em 0.2em #AAA;
}
.vn-gui .menu-overflow
{
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 4em;
overflow: auto;
}
/* Test link */
.vn-gui .test-link
{
display: block;
margin: 1em auto;
max-width: 70%;
background-color: #3f51b5;
color: white;
padding: 0 1em;
line-height: 2em;
border-radius: 0.1em;
text-align: center;
}
.vn-gui .test-link:hover
{
background-color: #4f61c5;
}
/* Menu */
.vn-gui .main-menu
{
list-style-type: none;
padding: 0;
margin: 0;
}
.vn-gui .main-menu > li
{
display: block;
float: left;
clear: both;
padding: 0;
}
.vn-gui .main-menu > li > a
{
line-height: 2.8em;
width: 70%;
padding: 0 15%;
}
.vn-gui .main-menu a
{
float: left;
}
.vn-gui .main-menu a:hover
{
background-color: #DDD /* #AC6 */;
}
.vn-gui .main-menu a.selected
{
background-color: #EEE;
}
.vn-gui ul.submenu
{
display: none;
position: fixed;
border: none;
border-radius: 1px;
background-color: white;
box-shadow: 0 0.2em 0.2em #CCC;
z-index: 50;
list-style-type: none;
padding-left: 0;
}
.vn-gui ul.submenu a
{
width: 60%;
padding: 0.7em 20%;
}
/* Links */
.vn-gui .links
{
position: absolute;
bottom: 0;
right: 0;
padding: 0.8em;
}
.vn-gui .links a
{
padding: 0.1em;
display: block;
float: left;
max-width: 2.2em;
}
.vn-gui .links img
{
height: 1.8em;
}
/* Form holder */
.vn-gui .form-holder
{
position: absolute;
top: 0em;
bottom: 0;
right: 0;
left: 0;
overflow: auto;
}
/* Transitions */
.vn-gui > .left-panel,
.vn-gui > .body
{
transition: left .3s;
-webkit-transition: left .3s;
}
.vn-gui .top-bar
{
transition: background-color .3s;
-webkit-transition: background-color .3s;
}
/* Mobile */
@media (max-width: 950px)
{
.vn-gui > .body
{
left: 0;
}
.vn-gui .menu-button
{
display: block;
}
.vn-gui .left-panel
{
top: 0;
left: -15em;
box-shadow: 0 0.2em 0.2em #333;
}
.vn-gui .left-panel-show
{
left: 0;
}
.vn-gui .form-holder
{
left: 0;
}
.vn-gui ul.submenu
{
display: block;
position: relative;
border: none;
border-radius: 0;
background-color: white;
box-shadow: none;
}
.vn-gui .htk-toast
{
margin-left: -11em;
}
}

526
web/js/hedera/gui.js Executable file
View File

@ -0,0 +1,526 @@
Vn.Gui = new Class
({
Extends: Htk.Widget,
Properties:
{
conn:
{
set: function (x)
{
this.link ({_conn: x},
{
'error': this.onConnError
,'loading-changed': this.onConnLoading
});
var sql = 'SELECT default_form, image_dir FROM config;'
+'SELECT production_domain, test_domain FROM config;'
+'SELECT name FROM customer_view;'
+'CALL form_list ();';
this.conn.execQuery (sql, this.onMainQueryDone.bind (this));
},
get: function ()
{
return this._conn;
}
}
}
,forms: {}
,activeForm: null
,activeCss: null
,requestedForm: null
,menuShown: false
,menuOptions: {}
,choosedOption: null
,initialize: function (props)
{
this.parent (props);
this.builderInit ('js/hedera/gui.xml');
this.loadingCount = 0;
this.formHolder = this.$('form-holder');
this.hash = Vn.Hash;
this.hashParam = new Vn.HashParam ({key: 'form'});
this.hashParam.on ('changed', this.onFormChange, this);
this.$('background').onclick = function () {};
this.$('menu-button').addEventListener ('click', function (event)
{
event.stopPropagation ();
this.showMenu ();
}.bind (this));
this.$('left-panel').addEventListener ('click', function (event)
{
event.stopPropagation ();
});
if (!Vn.Cookie.check ('hedera_cookies'))
{
Vn.Cookie.set ('hedera_cookies', true);
Htk.Toast.showWarning (_('CookiesNotification'));
}
}
,show: function ()
{
document.body.appendChild (this.node);
}
,hide: function ()
{
Vn.Node.remove (this.node);
}
,onLogoutClick: function ()
{
this.conn.close (this.onConnClose.bind (this));
}
,onConnClose: function ()
{
this.signalEmit ('logout');
}
,showBackground: function ()
{
Vn.Node.show (this.$('background'));
}
,hideBackground: function ()
{
Vn.Node.hide (this.$('background'));
}
,showMenu: function ()
{
this.showBackground ();
Vn.Node.addClass (this.$('left-panel'), 'left-panel-show');
this.menuShown = true;
this.hideMenuCallback = this.hideMenu.bind (this);
document.addEventListener ('click', this.hideMenuCallback);
}
,hideMenu: function ()
{
if (!this.menuShown)
return;
this.hideBackground ();
Vn.Node.removeClass (this.$('left-panel'), 'left-panel-show');
this.menuShown = false;
document.removeEventListener ('click', this.hideMenuCallback);
this.hideMenuCallback = null;
}
,onMainQueryDone: function (resultSet)
{
// Retrieving configuration parameters
var res = resultSet.fetchResult ();
var columns = res.columns;
if (res.next ())
for (var i = 0; i < res.columns.length; i++)
Vn.Config[columns[i].name] = res.get (columns[i].name);
// Retrieving configuration parameters
var res = resultSet.fetchResult ();
if (res.next () && res.get ('test_domain'))
{
if (location.host != res.get ('production_domain'))
{
var linkText = 'ReturnToOldWebsite';
var linkField = 'production_domain';
}
else
{
var linkText = 'TestTheNewWebsite';
var linkField = 'test_domain';
}
Vn.Node.setText (this.$('test-link'), _(linkText));
this.$('test-link').href = '//'+ res.get (linkField);
}
else
Vn.Node.hide (this.$('test-link'));
// Retrieving the user name
var userName = resultSet.fetchValue ();
if (userName)
{
var span = this.$('user-name');
span.appendChild (document.createTextNode (userName));
}
// Retrieving menu sections
var res = resultSet.fetchResult ();
var sectionMap = {};
if (res)
for (var i = 0; res.next (); i++)
{
var parent = res.get ('parent');
if (!sectionMap[parent])
sectionMap[parent] = [];
sectionMap[parent].push (i);
}
this.createMenu (res, sectionMap, null, this.$('main-menu'));
// Loading the default form
this.onFormChange ();
}
,notifyError: function (error)
{
if (error instanceof Error)
{
var httpRequest = new Vn.HttpRequest ()
httpRequest.add
({
'file': error.fileName
,'line': error.lineNumber
,'message': error.message
,'stack': error.stack
});
httpRequest.send ('log.php');
}
}
,errorHandler: function (error)
{
if (error instanceof Vn.Error)
switch (error.domain)
{
case 'Auth':
Htk.Toast.showError (_('SessionExpired'));
this.signalEmit ('logout');
break;
case 'Version':
this.newVersion (error);
break;
case 'User':
Htk.Toast.showError (error.message);
break;
default:
console.error (error.message);
Htk.Toast.showError (_('InternalError'));
}
else
{
console.error (error);
Htk.Toast.showError (_('InternalError'));
this.notifyError (error);
}
}
,onConnError: function (conn, error)
{
this.errorHandler (error);
}
,onConnLoading: function (conn, isLoading)
{
if (isLoading)
this.loaderPush ();
else
this.loaderPop ();
}
,loaderPush: function ()
{
this.loadingCount++;
if (this.loadingCount == 1)
this.$('loader').style.visibility = 'visible';
}
,loaderPop: function ()
{
if (this.loadingCount == 0)
return;
this.loadingCount--;
if (this.loadingCount == 0)
this.$('loader').style.visibility = 'hidden';
}
,newVersion: function (error)
{
if (this.newVersionBlock || this.skipVersion)
return;
this.newVersionBlock = true;
var reload;
var message = _('NewVersionAvailable') +"\n\n"+ error.message;
if (error.code == 'criticalVersion')
{
alert (message)
reload = true;
}
else
{
reload = confirm (message);
this.skipVersion = true;
}
if (reload)
location.reload ();
this.newVersionBlock = false;
}
,createMenu: function (res, sectionMap, parent, ul)
{
var sections = sectionMap[parent];
for (var i = 0; i < sections.length; i++)
{
res.row = sections[i];
var li = document.createElement ('li');
ul.appendChild (li);
var a = document.createElement ('a');
a.href = Vn.Hash.make ({'form': res.get ('path')});
this.menuOptions[res.get ('path')] = a;
li.appendChild (a);
var text = document.createTextNode (_(res.get ('description')));
a.appendChild (text);
var formId = res.get ('id');
if (sectionMap[formId])
{
var submenu = document.createElement ('ul');
submenu.className = 'submenu';
li.appendChild (submenu);
li.addEventListener ('mouseover',
this.onLiMouseHover.bind (this, submenu, a));
li.addEventListener ('mouseout',
this.onLiMouseOut.bind (this));
this.createMenu (res, sectionMap, formId, submenu);
}
}
}
,onLiMouseHover: function (submenu, parent)
{
if (Vn.isMobile ())
return;
this.hideSubmenu ();
this.activeSubmenu = submenu;
var rect = parent.getBoundingClientRect ();
submenu.style.display = 'inline';
submenu.style.left = rect.right +'px';
submenu.style.top = rect.top +'px';
}
,onLiMouseOut: function ()
{
this.timeout = setTimeout (this.hideSubmenu.bind (this), 160);
}
,hideSubmenu: function ()
{
var submenu = this.activeSubmenu;
if (submenu)
{
submenu.style.display = 'none';
clearTimeout (this.timeout);
this.activeSubmenu = null;
this.timeout = 0;
}
}
,onFormChange: function ()
{
var formPath = this.hashParam.value;
this.openForm (formPath ? formPath : Vn.Config['default_form'], null);
}
,openForm: function (formPath, callback)
{
this.hideMenu ();
this.loaderPush ();
this.requestedForm = formPath;
var formInfo = this.forms[formPath];
var path = 'forms/'+ formPath;
if (this.activeForm)
{
this.setTitle (null);
this.setActions (null);
this.activeForm.deactivate ();
this.activeForm.close ();
this.activeForm.unref ();
this.activeForm = null;
}
if (this.activeCss)
{
Vn.excludeCss (this.activeCss +'/style.css');
if (Vn.isMobile ())
Vn.excludeCss (this.activeCss +'/mobile.css');
}
this.activeCss = path;
Vn.includeCss (this.activeCss +'/style.css');
if (Vn.isMobile ())
Vn.includeCss (this.activeCss +'/mobile.css');
if (!formInfo)
{
var aux = formPath.split ('/');
var formName = aux[aux.length - 1];
var klass = 'Vn.'+ formName.charAt (0).toUpperCase ();
klass += formName.substr (1).replace (/\w\-\w/g, function (token)
{
return token.charAt (0) + token.charAt (2).toUpperCase ();
});
formInfo = {
path: formPath
,klass: klass
,localeReady: false
,jsReady: false
,uiReady: false
,error: false
,ready: false
,callbacks: []
};
Vn.Locale.load (path,
this.onFormLocaleReady.bind (this, formInfo));
Vn.includeJs (path +'/'+ formName +'.js',
this.onFormJsReady.bind (this, formInfo));
Vn.loadXml ('forms/'+ formPath +'/ui.xml',
this.onFormUiReady.bind (this, formInfo));
this.forms[formPath] = formInfo;
}
var newChoosedOption = this.menuOptions[formInfo.path];
if (newChoosedOption)
{
if (this.choosedOption)
this.choosedOption.className = null;
newChoosedOption.className = 'selected';
this.choosedOption = newChoosedOption;
}
if (callback)
formInfo.callbacks.push (callback);
if (formInfo.ready)
this.onFormReady (formInfo);
}
,onFormLocaleReady: function (formInfo, success)
{
formInfo.localeReady = true;
this.onFormReady (formInfo);
}
,onFormJsReady: function (formInfo, success)
{
formInfo.jsReady = true;
formInfo.error = !success;
this.onFormReady (formInfo);
}
,onFormUiReady: function (formInfo, success)
{
formInfo.uiReady = true;
formInfo.error = !success;
this.onFormReady (formInfo);
}
,onFormReady: function (formInfo)
{
if (!(formInfo.localeReady && formInfo.jsReady && formInfo.uiReady))
return;
formInfo.ready = true;
if (!formInfo.error)
{
if (formInfo.path == this.requestedForm)
try {
var klass = eval (formInfo.klass);
this.activeForm = new klass (this, formInfo);
this.activeForm.open ();
this.activeForm.activate ();
}
catch (e) {
formInfo.error = true;
this.errorHandler (e);
}
}
else
Htk.Toast.showError (_('ErrorLoadingForm'));
var callbacks = formInfo.callbacks;
formInfo.callbacks = [];
for (var i = 0; i < callbacks.length; i++)
callbacks[i] (this.activeForm);
this.loaderPop ();
}
,setTitle: function (title)
{
Vn.Node.removeChilds (this.$('title'));
if (title)
this.$('title').appendChild (title);
}
,setActions: function (actions)
{
Vn.Node.removeChilds (this.$('actions-holder'));
if (actions)
this.$('actions-holder').appendChild (actions);
}
,_destroy: function ()
{
this.hashParam.unref ();
this.parent ();
}
});

49
web/js/hedera/gui.xml Executable file
View File

@ -0,0 +1,49 @@
<vn>
<div id="main" class="vn-gui">
<div id="left-panel" class="left-panel">
<div class="menu-overflow">
<div class="menu-header">
<img class="logo" src="image/dark/logo.svg" alt="Verdnatura"/>
<div class="welcome">
<span id="user-name"></span>
</div>
</div>
<a id="test-link" class="test-link" href="#"></a>
<ul id="main-menu" class="main-menu"></ul>
</div>
<div class="links">
<a target="_blank" href="http://verdnaturacomunicacion.blogspot.com.es/">
<img alt="Blogger" src="image/blogger.svg" title="Blogger"/>
</a>
<a target="_blank" href="https://plus.google.com/u/0/107516577801959283883/posts">
<img alt="Google+" src="image/google-plus.svg" title="Google+"/>
</a>
<a target="_blank" href="http://www.facebook.com/verdnatura">
<img alt="Facebook" src="image/facebook.svg" title="Facebook"/>
</a>
<a target="_blank" href="http://www.youtube.com/user/verdnatura">
<img alt="YouTube" src="image/youtube.svg" title="YouTube"/>
</a>
</div>
</div>
<div class="body">
<div id="top-bar" class="top-bar">
<button id="menu-button" class="menu-button">
<img src="image/dark/menu.svg" alt="_Menu"/>
</button>
<a class="exit" on-click="onLogoutClick" title="_Exit">
<img src="image/dark/exit.svg" alt="_Exit"/>
</a>
<div id="actions-holder" class="actions-holder"/>
<div id="loader" class="loader">
<htk-loader/>
</div>
<div id="title" class="title"/>
</div>
<div class="content">
<div id="form-holder" class="form-holder"/>
</div>
</div>
<div id="background" class="background"/>
</div>
</vn>

4
web/js/hedera/hedera.js Normal file
View File

@ -0,0 +1,4 @@
/**
* Namespace
**/
var Hedera = {};

162
web/js/hedera/login.css Executable file
View File

@ -0,0 +1,162 @@
.vn-login,
.vn-login label,
.vn-login button,
.vn-login input,
.vn-login textarea,
.vn-login p,
.vn-login a
{
font-size: 1.2em;
font-weight: normal;
color: #333;
/* text-shadow: 0 0.2em 0.2em #AAA; */
}
/* Header */
.vn-login .header
{
z-index: 10;
position: absolute;
background-color: #333;
width: 100%;
height: 3.5em;
}
.vn-login .header div
{
margin-top: 1em;
text-align: center;
}
.vn-login .header a
{
color: white;
}
/* Body */
.vn-login .body
{
position: absolute;
top: 3.5em;
left: 0;
right: 0;
bottom: 0;
/* background-image: url("background.png");
background-repeat: repeat;
*/
}
.vn-login .column
{
position: relative;
margin: 0 auto;
overflow: auto;
max-width: 40em;
height: 100%;
background-color: white;
box-shadow: 0 0.2em 0.2em #DDD;
}
/* Login */
.vn-login .login
{
position: absolute;
margin-top: -17em;
padding: 1em;
max-width: 45em;
top: 50%;
left: 0;
right: 0;
}
.vn-login .logo img
{
display: block;
margin: 0.5em auto;
min-width: 20em;
width: 75%;
}
.vn-login .version-code
{
color: red;
text-align: right;
margin: 0.2em auto;
font-weight: bold;
height: 1.6em;
}
.vn-login .form-inputs
{
margin: 0 auto;
max-width: 16em;
}
.vn-login label
{
margin: 0;
}
.vn-login div.form-group label
{
display: block;
}
.vn-login input
{
border-radius: 0.1em;
box-shadow: 0 0.1em 0.1em #AAA;
margin: 0.3em;
}
.vn-login input[type=text],
.vn-login input[type=password]
{
margin: 0.5em 0;
margin-bottom: 0.5em;
padding: 0.5em;
width: 100%;
border: 1px solid #AAA;
}
.vn-login td.entry
{
text-align: left;
}
.vn-login input[type=submit]
{
display: block;
margin: 0 auto;
background-color: #AD4;
border: 1px solid #8B2;
height: 2.4em;
width: 8em;
color: #250;
}
.vn-login input[type=submit]:hover
{
background-color: #9C3;
}
.vn-login .bottom
{
text-align: center;
padding: 1em;
}
/* Info */
.vn-login .info
{
margin-top: 2em;
text-align: center;
}
.vn-login .info p
{
margin: 0.5em;
}
.vn-login .links
{
margin: 0 auto;
margin-top: 2em;
text-align: center;
}
.vn-login .links img
{
height: 1.8em;
}

74
web/js/hedera/login.js Executable file
View File

@ -0,0 +1,74 @@
Vn.Login = new Class
({
Extends: Htk.Widget
,initialize: function (props)
{
this.parent (props);
this.builderInit ('js/hedera/login.xml');
var self = this;
this.$('form').onsubmit = function ()
{
self.onSubmit ();
return false;
};
}
,show: function ()
{
document.body.appendChild (this.node);
if (Vn.Cookie.check ('vn_user'))
this.$('user').value = Vn.Cookie.get ('vn_user');
this.focusUserInput ();
}
,hide: function ()
{
Vn.Node.remove (this.node);
}
,focusUserInput: function ()
{
var userEntry = this.$('user');
userEntry.focus ();
userEntry.select ();
}
,disableInputs: function (disabled)
{
this.$('user').disabled = disabled;
this.$('pass').disabled = disabled;
this.$('submit').disabled = disabled;
}
,onSubmit: function ()
{
this.disableInputs (true);
this.conn.open (
this.$('user').value,
this.$('pass').value,
this.$('remember').value,
this.onConnOpen.bind (this)
);
}
,onConnOpen: function (conn, success)
{
this.$('pass').value = '';
if (!success)
{
Htk.Toast.showError (_('InvalidLogin'));
}
else
this.signalEmit ('login');
this.disableInputs (false);
this.focusUserInput ();
}
});

57
web/js/hedera/login.xml Executable file
View File

@ -0,0 +1,57 @@
<vn>
<div id="main" class="vn-login">
<div class="header">
<div>
<a href="#!page=web&amp;guest=true&amp;form=cms/about"><t>IWantToKnowMore</t></a>
</div>
</div>
<div class="body">
<div class="column">
<div class="login">
<form id="form">
<div class="logo">
<img src="image/logo.svg" alt=""/>
</div>
<div class="version-code">
</div>
<div class="form-inputs">
<div class="form-group">
<label for="user"><t>User</t></label>
<input type="text" id="user" name="user"/>
</div>
<div class="form-group">
<label for="pass"><t>Password</t></label>
<input type="password" id="pass" name="password"/>
</div>
</div>
<div class="bottom">
<input type="checkbox" id="remember" name="remember"/>
<label for="remember"><t>NotCloseSession</t></label>
</div>
<div>
<input id="submit" type="submit" value="_Enter"/>
</div>
<div class="info">
<p><t>LoginMail</t></p>
<p><t>LoginPhone</t></p>
</div>
<div class="links">
<a target="_blank" href="http://verdnaturacomunicacion.blogspot.com.es/">
<img alt="Blogger" src="image/blogger.svg" title="Blogger"/>
</a>
<a target="_blank" href="https://plus.google.com/u/0/107516577801959283883/posts">
<img alt="Google+" src="image/google-plus.svg" title="Google+"/>
</a>
<a target="_blank" href="http://www.facebook.com/verdnatura">
<img alt="Facebook" src="image/facebook.svg" title="Facebook"/>
</a>
<a target="_blank" href="http://www.youtube.com/user/verdnatura">
<img alt="YouTube" src="image/youtube.svg" title="YouTube"/>
</a>
</div>
</form>
</div>
</div>
</div>
</div>
</vn>

19
web/js/hedera/main.js Normal file
View File

@ -0,0 +1,19 @@
Vn.includeCss ('js/hedera/style.css');
Vn.includeCss ('js/hedera/gui.css');
Vn.includeCss ('js/hedera/login.css');
Vn.loadXml ('js/hedera/login.xml');
Vn.loadXml ('js/hedera/gui.xml');
Vn.includeJs ('js/htk/main.js');
Vn.includeLib ('hedera',
[
'hedera'
,'login'
,'gui'
,'module'
,'app'
,'tpv'
]);

88
web/js/hedera/module.js Executable file
View File

@ -0,0 +1,88 @@
Vn.Module = new Class
({
Extends: Vn.Object
,initialize: function (gui, formInfo)
{
this.gui = gui;
this.conn = gui.conn;
this.hash = gui.hash;
this.formInfo = formInfo;
}
/**
* Gets an object from the builder associated to this form.
*
* @param {string} objectId The object identifier
* @return {Object} The object, or %null if not found
**/
,$: function (objectId)
{
if (this.builder)
return this.builder.get (objectId);
return null;
}
/**
* Called when the form is opened.
**/
,open: function ()
{
this.close ();
this.builder = new Vn.Builder ();
this.builder.signalData = this;
this.builder.loadXml (Vn.getXml ('forms/'+ this.formInfo.path +'/ui.xml'));
this.node = this.builder.get ('form');
var models = this.builder.getObjects ('db-model');
for (var i = 0; i < models.length; i++)
models[i].conn = this.conn;
var queries = this.builder.getObjects ('db-query');
for (var i = 0; i < queries.length; i++)
queries[i].conn = this.conn;
this.gui.formHolder.appendChild (this.node);
this.gui.setTitle (this.builder.$('title'));
this.gui.setActions (this.builder.$('actions'));
}
/**
* Called when the form is activated.
**/
,activate: function () {}
/**
* Called when the form is deactivated.
**/
,deactivate: function () {}
/**
* Called when the form is closed.
**/
,close: function ()
{
if (this.node)
{
Vn.Node.remove (this.node);
this.node = null;
}
if (this.builder)
{
this.builder.unref ();
this.builder = null;
}
}
,_destroy: function ()
{
this.close ();
this.parent ();
}
});

382
web/js/hedera/style.css Executable file
View File

@ -0,0 +1,382 @@
/* Responsive */
@media screen
{
* { font-size: 12pt; }
}
@media (min-resolution: 120dpi) and (orientation: portrait)
{
* { font-size: 11pt; }
}
@media (min-resolution: 120dpi) and (orientation: landscape)
{
* { font-size: 11pt; }
}
/* Global */
body
{
margin: 0;
}
body,
label,
button,
input,
textarea
{
font-size: 1em;
font-family: 'Open Sans', 'Verdana', 'Sans';
}
iframe
{
border: 0;
}
fieldset,
div
{
margin: 0;
}
form
{
padding: 0;
margin: 0;
}
table
{
width: 100%;
}
a:link,
a:visited,
a:active
{
color: #000;
text-decoration: none;
}
a:hover
{
text-decoration: none;
cursor: pointer;
}
a img
{
padding: 1px;
}
h1, h2, h3, h4, h5, h6
{
margin: 0;
padding: 0.2em;
}
h1
{
font-size: 1.5em;
}
h2
{
font-size: 1.3em;
}
p
{
margin: 0.8em 0;
}
/* Inputs */
input[type=text],
input[type=password],
input[type=file],
input[type=number],
textarea,
select
{
border: 1px solid #CCD;
margin: 0.2em;
border-radius: 0.1em;
box-shadow: 0 0.1em 0.1em #CCC;
}
input[type=text],
input[type=password],
input[type=file],
input[type=number],
textarea
{
padding: 0.3em;
}
select
{
background-color: white;
font-size: 1.1em;
height: 1.8em;
}
option
{
padding: 0.3em;
border-width: 0;
font-weight: normal;
font-size: 1em;
}
select,
option
{
cursor: pointer;
}
input[type=text],
input[type=password]
{
height: 1.6em;
}
textarea
{
height: 3.5em;
width: 20em;
}
input[type=text]:focus,
input[type=password]:focus,
textarea:focus
{
background-color: #EEF;
border-color: #BBC;
}
input[type=checkbox],
input[type=radio]
{
cursor: pointer;
margin: 0.2em;
padding: 0.3em;
width: 0.8em;
height: 0.8em;
}
/* Buttons */
button,
input[type=submit],
input[type=button]
{
border: none;
background-color: transparent;
color: white;
padding: 0.5em;
cursor: pointer;
border-radius: 0.1em;
}
button:hover,
input[type=submit]:hover,
input[type=button]:hover
{
background-color: rgba(1, 1, 1, 0.1);
}
/* Flat button */
button.flat,
input.button
{
border: none;
border-radius: 0.1em;
box-shadow: 0 0.2em 0.2em #DDD;
background-color: #AD4;
color: black;
}
button.flat:hover,
input.button:hover
{
background-color: #9C3;
cursor: pointer;
}
button.flat:disabled,
input.button:disabled
{
color: gray;
}
/* Thin button */
button.thin
{
background-color: transparent;
border: none;
color: #008D77;
text-transform: uppercase;
}
button.thin:hover
{
background-color: rgba(1,1,1,0.1);
}
button.thin:disabled
{
color: gray;
}
/* Image */
img.editable
{
cursor: pointer;
}
/* Button */
.htk-button img
{
height: 1.5em;
}
/* Float */
.clear
{
clear: both;
}
/* Box */
.box
{
background-color: white;
margin: 0 auto;
border-radius: 0.1em;
box-shadow: 0 0.2em 0.2em #CCC;
}
.box .header
{
padding: 0.6em 0.8em;
margin: 0;
background-color: #009688;
color: white;
}
.box .header > h1
{
color: white;
text-align: left;
font-size: 1.6em;
line-height: 2em;
font-weight: normal;
display: inline;
}
.box .body
{
padding: 2em;
}
/* Form */
.form
{
margin: 0 auto;
}
.form-group
{
padding: 0.4em;
}
.form-group > label
{
display: block;
margin-bottom: 0.5em;
}
.form-group > input[type=text],
.form-group > input[type=password],
.form-group > select,
.form-group > textarea
{
margin: 0;
width: 100%;
}
/* Action bar */
.action-bar
{
float: right;
padding: 0;
margin-top: 0.3em;
}
.action-bar > *
{
float: left;
padding: 0.4em;
}
.action-bar > button
{
border-left: 1px solid white;
}
.action-bar > button:first-child
{
border-left: none;
}
.action-bar > button:hover
{
background-color: rgba(1, 1, 1, 0.2);
}
.action-bar > button > img
{
vertical-align: middle;
margin-right: 0.4em;
height: 1.4em;
}
/* Form */
table.form
{
padding: 1em;
border-collapse: separate;
border-spacing: 0.3em;
}
table.form td.label
{
width: 45%;
text-align: right;
}
table.form tr
{
height: 2.8em;
}
/* Icon */
img.icon
{
height: 1.5em;
}
/* Masonry */
.masonry
{
margin: 0 auto;
text-align: left;
}
.masonry-box
{
width: 100%;
display: inline-block;
vertical-align: top;
}
@media screen and (min-width: 1000px) and (max-width: 1399px)
{
.masonry-box
{
width: 50%;
display: block;
float: left;
clear: left;
}
.masonry-box:nth-child(2n+0)
{
float: right;
clear: right;
}
}
@media screen and (min-width: 1400px)
{
.masonry-box { width: 33.3%; }
}
@media screen and (min-width: 2000px)
{
.masonry-box { width: 25%; }
}

124
web/js/hedera/tpv.js Executable file
View File

@ -0,0 +1,124 @@
Vn.Tpv =
{
check: function (conn)
{
var tpvStatus = Vn.Hash.get ('tpv_status');
if (tpvStatus)
{
var batch = new Sql.Batch ();
batch.addValue ('transaction', Vn.Hash.get ('tpv_order'));
batch.addValue ('status', tpvStatus);
var query = 'CALL transaction_end (#transaction, #status)';
conn.execQuery (query, null, batch);
}
}
,pay: function (conn, amount, company)
{
if (amount > 0)
{
var query = 'CALL transaction_start (#company, #amount)';
var batch = new Sql.Batch ();
batch.addValue ('company', company);
batch.addValue ('amount', parseInt (amount * 100));
conn.execQuery (query,
this._onTransactionStart.bind (this), batch);
}
else if (!isNaN (amount))
Htk.Toast.showError (_('AmountError'));
}
,_onTransactionStart: function (resultSet)
{
var res = resultSet.fetchResult ();
if (res && res.next ())
{
var form = document.createElement ('form');
form.method = 'post';
form.action = res.get ('url');
document.body.appendChild (form);
var fieldsMap =
{
'Ds_Merchant_Amount': 'amount'
,'Ds_Merchant_Order': 'ds_order'
,'Ds_Merchant_MerchantCode': 'id'
,'Ds_Merchant_Currency': 'currency'
,'Ds_Merchant_TransactionType': 'transaction_type'
,'Ds_Merchant_Terminal': 'terminal'
,'Ds_Merchant_MerchantURL': 'merchant_url'
,'Ds_Merchant_MerchantSignature': 'signature'
,'Ds_Merchant_UrlOK': null
,'Ds_Merchant_UrlKO': null
};
for (var field in fieldsMap)
{
var input = document.createElement ('input');
input.type = 'hidden';
input.name = field;
form.appendChild (input);
if (fieldsMap[field])
input.value = res.get (fieldsMap[field]);
}
var transactionId = res.get ('ds_order');
form['Ds_Merchant_UrlOK'].value = this._makeUrl ('ok', transactionId);
form['Ds_Merchant_UrlKO'].value = this._makeUrl ('ko', transactionId);
form.submit ();
}
else
Htk.Toast.showWarning (_('PayError'));
}
,_makeUrl: function (status, order)
{
var path = location.protocol +'//'+ location.host;
path += location.port ? ':'+ location.port : '';
path += location.pathname;
path += location.search ? location.search : '';
path += Vn.Hash.make ({
'form': 'ecomerce/orders',
'tpv_status': status,
'tpv_order': order
}, true);
return path;
}
};
Vn.BasketChecker =
{
check: function (conn, callback)
{
conn.execQuery ('CALL basket_check ()',
this._onBasketCheck.bind (this, callback));
}
,_onBasketCheck: function (callback, resultSet)
{
var status = resultSet.fetchValue ();
if (!status)
return;
var isOk = status == 'UPDATED' || status == 'OK';
if (status == 'UPDATED')
Htk.Toast.showWarning (_('OrderItemsUpdated'));
if (callback)
callback (isOk);
if (!isOk)
Vn.Hash.set ({'form': 'ecomerce/checkout'});
}
};

View File

@ -1,36 +1,4 @@
include ([ /**
'js/db/db.js', * The namespace.
'js/htk/js/htk/main', **/
'js/htk/widget', var Htk = {};
'js/htk/popup',
'js/htk/toast',
'js/htk/repeater',
'js/htk/grid',
'js/htk/full-image',
'js/htk/image-editor',
'js/htk/field',
'js/htk/field/text',
'js/htk/field/html',
'js/htk/field/entry',
'js/htk/field/radio-group',
'js/htk/field/radio',
'js/htk/field/label',
'js/htk/field/text-area',
'js/htk/field/spin',
'js/htk/field/check',
'js/htk/field/select',
'js/htk/field/calendar',
'js/htk/field/date-chooser',
'js/htk/field/image',
'js/htk/field/button',
'js/htk/field/table',
'js/htk/column',
'js/htk/column/button',
'js/htk/column/link',
'js/htk/column/date',
'js/htk/column/image',
'js/htk/column/radio',
'js/htk/column/spin',
'js/htk/column/text',
'js/htk/column/check'
]);

View File

@ -1,11 +1,15 @@
/**
* A form to handle the image database, it allows to add new images or replace it
**/
Htk.ImageEditor = new Class Htk.ImageEditor = new Class
({ ({
Extends: Htk.Widget Extends: Htk.Widget
,Xml: 'js/htk/image-editor.xml' ,Xml: 'js/htk/image-editor.xml'
,initialize: function () ,initialize: function (props)
{ {
this.builderInit (Htk.ImageEditor.Xml); this.parent (props)
this.builderInit (this.constructor.Xml);
this.$('max-size').value = 10 /* MB */ * 1048576; this.$('max-size').value = 10 /* MB */ * 1048576;
} }

74
web/js/htk/loader.css Normal file
View File

@ -0,0 +1,74 @@
.htk-loader
{
font-size: 10px;
margin: 50px auto;
text-indent: -9999em;
width: 11em;
height: 11em;
border-radius: 50%;
background: #ffffff;
background: -moz-linear-gradient(left, #ffffff 10%, rgba(255, 255, 255, 0) 42%);
background: -webkit-linear-gradient(left, #ffffff 10%, rgba(255, 255, 255, 0) 42%);
background: -o-linear-gradient(left, #ffffff 10%, rgba(255, 255, 255, 0) 42%);
background: -ms-linear-gradient(left, #ffffff 10%, rgba(255, 255, 255, 0) 42%);
background: linear-gradient(to right, #ffffff 10%, rgba(255, 255, 255, 0) 42%);
position: relative;
-webkit-animation: load3 1.4s infinite linear;
animation: load3 1.4s infinite linear;
-webkit-transform: translateZ(0);
-ms-transform: translateZ(0);
transform: translateZ(0);
}
.htk-loader:before
{
width: 50%;
height: 50%;
background: #ffffff;
border-radius: 100% 0 0 0;
position: absolute;
top: 0;
left: 0;
content: '';
}
.htk-loader:after
{
background: #0dc5c1;
width: 75%;
height: 75%;
border-radius: 50%;
content: '';
margin: auto;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
@-webkit-keyframes load3
{
0%
{
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100%
{
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes load3
{
0%
{
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100%
{
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}

12
web/js/htk/loader.js Executable file
View File

@ -0,0 +1,12 @@
Htk.Loader = new Class
({
Extends: Htk.Widget
,Tag: 'htk-loader'
,initialize: function (props)
{
this.parent (props);
var loader = this.createElement ('div');
loader.className = 'htk-loader';
}
});

View File

@ -1,4 +1,42 @@
/**
* The namespace. Vn.includeCss ('js/htk/style.css');
**/ Vn.includeJs ('js/db/main.js');
var Htk = {}; Vn.includeLib ('htk',
[
'htk'
,'widget'
,'popup'
,'toast'
,'repeater'
,'grid'
,'loader'
,'full-image'
,'image-editor'
,'assistant'
,'assistant-bar'
,'field'
,'field/text'
,'field/html'
,'field/entry'
,'field/radio-group'
,'field/radio'
,'field/label'
,'field/text-area'
,'field/spin'
,'field/check'
,'field/select'
,'field/calendar'
,'field/date-chooser'
,'field/image'
,'field/button'
,'field/table'
,'column'
,'column/button'
,'column/link'
,'column/date'
,'column/image'
,'column/radio'
,'column/spin'
,'column/text'
,'column/check'
]);

View File

@ -3,7 +3,7 @@
require_once ('js/db/main.php'); require_once ('js/db/main.php');
Vn\Hedera\Js::includeLib ('htk' Vn\Hedera\Js::includeLib ('htk'
,'main' ,'htk'
,'widget' ,'widget'
,'popup' ,'popup'
,'toast' ,'toast'

505
web/js/htk/style.css Executable file
View File

@ -0,0 +1,505 @@
/* Grid */
.htk-grid
{
margin: auto;
border-collapse: collapse;
text-align: center;
}
.htk-grid > thead > tr,
.htk-grid > tfoot > tr
{
background-color: #009688;
vertical-align: middle;
text-align: center;
height: 3em;
}
.htk-grid > thead th
{
color: white;
cursor: pointer;
font-weight: normal;
padding: 0 0.4em;
}
.htk-grid > thead th:hover
{
background-color: rgba(1, 1, 1, 0.2);
}
.htk-grid tr
{
height: 3.5em;
}
.htk-grid > tfoot a,
.htk-grid > thead a
{
color: black;
}
.htk-grid tr.pair-row
{
background-color: transparent;
}
.htk-grid .message
{
height: 5em;
}
.htk-grid .message img
{
vertical-align: middle;
padding: 0.8em;
height: 1.8em;
}
.htk-grid > tbody tr
{
border-top: 1px solid #DDD;
}
.htk-grid > tbody tr:first-child
{
border-top: none;
}
.htk-grid > tbody td
{
margin: 0;
padding: 0 0.5em;
}
.htk-grid > tbody td:first-child,
.htk-grid > thead th:first-child
{
padding-left: 1em;
}
.htk-grid > tbody td:last-child,
.htk-grid > thead th:last-child
{
padding-right: 1em;
}
.htk-grid .cell-spin
{
width: 2.5em;
text-align: right;
}
.htk-grid .cell-button
{
margin: 0;
padding: 0.5em;
border: none;
background-color: transparent;
border-radius: 0.1em;
}
.htk-grid .cell-button:hover
{
background-color: rgba(1, 1, 1, 0.1);
}
.htk-grid .cell-button img
{
height: 1.5em;
display: block;
margin: auto;
}
.htk-grid .cell-image > img
{
max-width: 2.5em;
max-height: 2.5em;
display: block;
margin: auto;
}
/* Repater */
.htk-repeater > .message
{
padding: 1em 0;
text-align: center;
}
.htk-repeater > .message > *
{
vertical-align: middle;
}
.htk-repeater > .message > img
{
padding: 0.8em;
padding-left: 0;
height: 1.8em;
}
/* Calendar */
.htk-calendar
{
width: 20em;
background-color: white;
border: none;
}
.htk-calendar table
{
border-collapse: collapse;
}
.htk-calendar thead tr,
.htk-calendar tfoot tr
{
background-color: #009688;
color: white;
font-weight: normal;
vertical-align: middle;
text-align: center;
height: 3em;
}
.htk-calendar thead span
{
color: white;
}
.htk-calendar thead tr
{
border-bottom: none;
}
.htk-calendar tfoot tr
{
border-top: none;
}
.htk-calendar th.button:hover
{
cursor: pointer;
background-color: rgba(1, 1, 1, 0.2);
}
.htk-calendar col
{
width: 14.2%;
}
.htk-calendar tr
{
height: 2em;
}
.htk-calendar tbody td
{
text-align: right;
}
.htk-calendar tbody td > div
{
height: 2em;
width: 2em;
line-height: 2em;
text-align: center;
border-radius: 2em;
padding: 0.3em;
margin: 0 auto;
color: #555;
}
.htk-calendar div.disabled
{
color: #999;
}
.htk-calendar div.today
{
font-weight: bold;
color: black;
}
.htk-calendar div.selected
{
color: white;
background-color: #009688;
}
.htk-calendar div.enabled:hover
{
cursor: pointer;
background-color: #008678;
color: white;
}
/* Date chooser */
.htk-date-chooser > button
{
margin: 0.2em;
padding: 0.3em;
background-color: white;
color: black;
text-align: left;
min-width: 9em;
min-height: 2.3em;
border: 1px solid #CCD;
border-radius: 0.1em;
box-shadow: 0 0.1em 0.1em #CCC;
}
/* Full image */
.htk-full-image
{
z-index: 100;
position: fixed;
background-color: #FFF;
text-align: center;
border: 1px solid #999;
border-radius: 2px;
}
.htk-full-image-loader
{
z-index: 110;
position: fixed;
background-color: #FFF;
border: 1px solid #999;
border-radius: 0.1em;
}
.htk-full-image-loader img
{
padding: 1em;
}
/* Toast */
.htk-toast
{
z-index: 210;
display: block;
position: fixed;
left: 50%;
top: 4em;
width: 21em;
margin-left: -11em;
text-align: center;
overflow: auto;
max-height: 40em;
}
.htk-toast > div
{
padding: .5em 2%;
margin: .5em 2%;
border-radius: 0.1em;
box-shadow: 0 0 0.4em #666;
width: 92%;
}
.htk-toast > .message
{
background-color: #BFB;
}
.htk-toast > .warning
{
background-color: #FFB;
}
.htk-toast > .error
{
background-color: #FBB;
}
/* Popup */
.htk-popup
{
z-index: 200;
display: block;
position: fixed;
background-color: white;
border-radius: 0.1em;
box-shadow: 0 0 0.4em #666;
}
.htk-background
{
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 190;
background-color: rgba(1, 1, 1, 0.7);
}
/* Image editor */
.htk-image-editor
{
width: 20em;
margin: 0 auto;
}
.htk-image-editor h2
{
color: white;
background-color: #009688;
text-align: left;
font-size: 1.3em;
line-height: 1.7em;
font-weight: normal;
padding: 0.6em 0.8em;
margin: 0;
}
.htk-image-editor iframe
{
display: none;
}
.htk-image-editor form
{
padding: 1.5em;
}
.htk-image-editor .form-group
{
margin-bottom: 0.5em;
}
.htk-image-editor .form-group label
{
display: block;
margin-bottom: 0.3em;
}
.htk-image-editor .form-group input
{
width: 95%;
height: 1.8em;
}
.htk-image-editor .footer
{
margin-top: 1em;
text-align: center;
}
.htk-image-editor .footer img
{
visibility: hidden;
vertical-align: middle;
padding-right: 1em;
}
.htk-image-editor .footer input
{
display: inline;
margin-left: 0.5em;
margin-right: 0.5em;
}
/* Assistant */
.htk-assistant > div
{
display: none;
margin-top: 1em;
margin-bottom: 4em;
}
.htk-assistant > div > h2
{
text-align: center;
font-style: italic;
font-weight: normal;
font-size: 1.5em;
margin: 0.5em;
margin-bottom: 1em;
}
.htk-assistant *
{
color: #555;
}
/* Assistant bar */
.htk-assistant-bar
{
margin: 0.5em auto;
max-width: 30em;
position: relative;
}
.htk-assistant-bar img
{
cursor: pointer;
}
.htk-assistant-bar > img
{
position: absolute;
width: 1.8em;
top: 0;
padding: 0.3em;
border-radius: 0.1em;
}
.htk-assistant-bar > img:hover
{
background-color: rgba(1,1,1,0.1);
}
.htk-assistant-bar > img.previous
{
left: 0;
}
.htk-assistant-bar > img.next
{
right: 0;
}
.htk-assistant-bar > div
{
margin: 0 auto;
padding-top: 0.2em;
}
.htk-assistant-bar > div > img
{
padding: 0.3em 0.2em;
width: 1.3em;
}
.htk-assistant-bar > div > img:hover
{
opacity: .7;
}
/* Loader */
/*
.htk-loader
{
margin: 0 auto;
width: 2em;
height: 2em;
text-indent: -9999em;
border-radius: 50%;
background: #FFF;
background: -moz-linear-gradient(left, #ffffff 10%, rgba(255, 255, 255, 0) 42%);
background: -webkit-linear-gradient(left, #ffffff 10%, rgba(255, 255, 255, 0) 42%);
background: -o-linear-gradient(left, #ffffff 10%, rgba(255, 255, 255, 0) 42%);
background: -ms-linear-gradient(left, #ffffff 10%, rgba(255, 255, 255, 0) 42%);
background: linear-gradient(to right, #ffffff 10%, rgba(255, 255, 255, 0) 42%);
position: relative;
-webkit-animation: load3 1.4s infinite linear;
animation: load3 1.4s infinite linear;
-webkit-transform: translateZ(0);
-ms-transform: translateZ(0);
transform: translateZ(0);
}
.htk-loader:before
{
width: 50%;
height: 50%;
background: #FFF;
border-radius: 100% 0 0 0;
position: absolute;
top: 0;
left: 0;
content: '';
}
.htk-loader:after
{
background: #009688;
width: 75%;
height: 75%;
border-radius: 50%;
content: '';
margin: auto;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
@-webkit-keyframes load3
{
0%
{
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100%
{
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes load3
{
0%
{
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100%
{
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
*/

View File

@ -52,4 +52,12 @@ Htk.Widget = new Class
{ {
Vn.Node.remove (this.node); Vn.Node.remove (this.node);
} }
,_destroy: function ()
{
if (this.builder)
this.builder.unref ();
this.parent ();
}
}); });

4
web/js/misc/main.js Executable file
View File

@ -0,0 +1,4 @@
Vn.includeJs ('js/misc/tinymce/tinymce.min.js');
Vn.includeJs ('js/misc/mootools');

View File

@ -1,5 +1,29 @@
/**
* The namespace. Vn.includeJs ('js/vn/main.js');
**/ Vn.includeLib ('sql',
var Sql = {}; [
'sql'
,'object'
,'holder'
,'batch'
,'list'
,'expr'
,'value'
,'field'
,'function'
,'operation'
,'target'
,'table'
,'stmt'
,'dml'
,'string'
,'delete'
,'insert'
,'select'
,'update'
,'multi-stmt'
,'filter'
,'filter-item'
,'search-tags'
]);

View File

@ -3,7 +3,7 @@
require_once ('js/vn/main.php'); require_once ('js/vn/main.php');
Vn\Hedera\Js::includeLib ('sql' Vn\Hedera\Js::includeLib ('sql'
,'main' ,'sql'
,'object' ,'object'
,'holder' ,'holder'
,'batch' ,'batch'

5
web/js/sql/sql.js Executable file
View File

@ -0,0 +1,5 @@
/**
* The namespace.
**/
var Sql = {};

View File

@ -7,13 +7,18 @@ Vn.Locale =
,language: null ,language: null
,load: function (path, callback) ,init: function ()
{ {
if (!this.language) if (!this.language)
{ {
var language = navigator.language.substr (0, 2); var language = navigator.language.substr (0, 2);
this.language = language ? language : 'es'; this.language = language ? language : 'es';
} }
}
,load: function (path, callback)
{
this.init ();
var file = 'locale/'+ this.language +'/'+ path +'.json' var file = 'locale/'+ this.language +'/'+ path +'.json'
+'?'+ Vn.Cookie.get ('hedera_version'); +'?'+ Vn.Cookie.get ('hedera_version');
@ -24,6 +29,12 @@ Vn.Locale =
request.send (); request.send ();
} }
,loadScript: function (path, callback)
{
this.init ();
Vn.includeJs ('locale/'+ this.language +'/'+ path, callback);
}
,loadDone: function (request, callback) ,loadDone: function (request, callback)
{ {
if (request.readyState != 4) if (request.readyState != 4)

203
web/js/vn/main.js Executable file → Normal file
View File

@ -1,187 +1,20 @@
/**
* The main namespace.
**/
var Vn =
{
Config: {}
,jsIncludes: {}
,cssIncludes: {}
,xmlIncludes: {}
,customTags: {}
,head: document.getElementsByTagName ('head')[0]
,isMobileCached: null
/** Vn.includeJs ('js/misc/main.js');
* Includes a new CSS stylesheet in the current document, if the stylesheet Vn.includeLib ('vn',
* its already included, does nothing. [
* 'browser'
* @param {string} fileName The stylesheet file name ,'date'
**/ ,'value'
,includeCss: function (fileName) ,'error'
{ ,'url'
var cssData = this.cssIncludes[fileName]; ,'mutators'
,'object'
if (!cssData) ,'param'
{ ,'hash-listener'
var link = document.createElement ('link'); ,'hash'
link.rel = 'stylesheet'; ,'hash-param'
link.type = 'text/css'; ,'node'
link.href = fileName +'?'+ Vn.Cookie.get ('hedera_version'); ,'builder'
this.head.appendChild (link); ,'http-request'
]);
this.cssIncludes[fileName] =
{
included: true
,link: link
};
}
else if (!cssData.included)
{
cssData.link.disabled = false;
cssData.included = true;
}
}
/**
* Excludes a CSS stylesheet from the current document.
*
* @param {string} fileName The stylesheet file name
**/
,excludeCss: function (fileName)
{
var cssData = this.cssIncludes[fileName];
if (cssData && cssData.included)
{
cssData.link.disabled = true;
cssData.included = false;
}
}
/**
* Includes a new Javascript in the current document, if the script
* its already included, does nothing.
*
* @param {string} fileName The script file name
* @param {Function} callback The function to call when script is
* downloaded and included
**/
,includeJs: function (fileName, callback, skipVersion)
{
var includeData = this.jsIncludes[fileName];
if (includeData === undefined)
{
var src = fileName;
if (!skipVersion)
src = src +'?'+ Vn.Cookie.get ('hedera_version');
var script = document.createElement ('script');
script.type = 'text/javascript';
script.src = src;
includeData = {
script: script
,callbacks: []
,loaded: false
};
if (callback)
includeData.callbacks.push (callback);
script.onload =
this.jsLoaded.bind (this, includeData, true);
script.onerror =
this.jsLoaded.bind (this, includeData, false);
script.onreadystatechange =
this.jsStateChanged.bind (this, includeData);
this.jsIncludes[fileName] = includeData;
this.head.appendChild (script);
}
else if (callback)
{
if (includeData.loaded)
callback ();
else
includeData.callbacks.push (callback);
}
}
,jsStateChanged: function (includeData)
{
console.log ('js: '+ includeData.script.readyState);
if (includeData.script.readyState == 'complete')
this.jsLoaded (includeData, true);
}
,jsLoaded: function (includeData, success)
{
if (includeData.loaded)
return;
for (var i = 0; i < includeData.callbacks.length; i++)
includeData.callbacks[i] (success);
includeData.loaded = true;
includeData.callbacks = null;
}
,loadXml: function (path, callback)
{
var includeData = this.xmlIncludes[path];
if (!includeData)
{
var request = new XMLHttpRequest ();
request.onreadystatechange =
this.onXmlReady.bind (this, request, path, callback);
request.open ('get', path +'?'+ Vn.Cookie.get ('hedera_version'), true);
request.send ();
}
else if (callback)
callback (true);
}
,onXmlReady: function (request, path, callback)
{
if (request.readyState != 4)
return;
if (request.status == 200)
this.xmlIncludes[path] = request.responseXML;
if (callback)
callback (request.status == 200);
}
,getXml: function (path)
{
return this.xmlIncludes[path];
}
/**
* Checks if user is using a mobile browser.
*
* return {boolean} %true if is mobile, %false otherwise.
**/
,isMobile: function ()
{
if (this.isMobileCached === null)
{
var regExp = /(Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone)/i;
this.isMobileCached = navigator.userAgent.match (regExp);
}
return this.isMobileCached;
}
,get: function (id)
{
return document.getElementById (id);
}
};

View File

@ -4,7 +4,7 @@ require_once ('js/misc/main.php');
use Vn\Hedera\Js; use Vn\Hedera\Js;
Js::includeFile ('js/vn/main.js'); Js::includeFile ('js/vn/vn.js');
Js::includeFile ('js/vn/locale.js'); Js::includeFile ('js/vn/locale.js');
if (strpos ($_SERVER['HTTP_USER_AGENT'], 'MSIE')) if (strpos ($_SERVER['HTTP_USER_AGENT'], 'MSIE'))

229
web/js/vn/vn.js Executable file
View File

@ -0,0 +1,229 @@
/**
* The main namespace.
**/
var Vn =
{
Config: {}
,jsIncludes: {}
,cssIncludes: {}
,xmlIncludes: {}
,customTags: {}
,head: document.getElementsByTagName ('head')[0]
,isMobileCached: null
,_registerIncludedScripts: function ()
{
var scripts = this.head.getElementsByTagName ('script');
var basePath = location.protocol +'//'+ location.host;
basePath += location.port ? ':'+ location.port : '';
basePath += location.pathname;
console.log (basePath);
for (var i = 0; i < scripts.length; i++)
{
var path = scripts[i].src.match (/^([\w\./:~-]+)[?#]?.*$/);
}
}
/**
* Includes a new Javascript in the current document, if the script
* is already included, does nothing and calls the callback.
*
* @param {string} fileName The script file name
* @param {Function} callback The function to call when script is
* downloaded and included
**/
,includeJs: function (fileName, callback, skipVersion)
{
var includeData = this.jsIncludes[fileName];
if (includeData === undefined)
{
var src = fileName;
if (!skipVersion)
src = src +'?'+ Vn.Cookie.get ('hedera_version');
var script = document.createElement ('script');
script.type = 'text/javascript';
script.async = false;
script.src = src;
includeData = {
script: script
,callbacks: []
,loaded: false
};
if (callback)
includeData.callbacks.push (callback);
script.onload =
this._jsLoaded.bind (this, includeData, true);
script.onerror =
this._jsLoaded.bind (this, includeData, false);
script.onreadystatechange =
this._jsStateChanged.bind (this, includeData);
this.jsIncludes[fileName] = includeData;
this.head.appendChild (script);
}
else if (callback)
{
if (includeData.loaded)
callback ();
else
includeData.callbacks.push (callback);
}
}
,_jsStateChanged: function (includeData)
{
console.log ('js: '+ includeData.script.readyState);
if (includeData.script.readyState == 'complete')
this._jsLoaded (includeData, true);
}
,_jsLoaded: function (includeData, success)
{
if (includeData.loaded)
return;
for (var i = 0; i < includeData.callbacks.length; i++)
includeData.callbacks[i] (success);
includeData.loaded = true;
includeData.callbacks = null;
}
/**
* Includes an entire Javascript library including it's localized file.
*
* @param {string} libName The folder of the library
* @param {Array<string>} files Array with every library file name
**/
,includeLib: function (libName, files)
{
Vn.Locale.loadScript ('js/'+ libName +'.js');
for (var i = 0; i < files.length; i++)
this.includeJs ('js/'+ libName +'/'+ files[i] +'.js');
}
/**
* Includes a new CSS stylesheet in the current document, if the stylesheet
* is already included, does nothing.
*
* @param {string} fileName The stylesheet file name
**/
,includeCss: function (fileName)
{
var cssData = this.cssIncludes[fileName];
if (!cssData)
{
var link = document.createElement ('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = fileName +'?'+ Vn.Cookie.get ('hedera_version');
this.head.appendChild (link);
this.cssIncludes[fileName] =
{
included: true
,link: link
};
}
else if (!cssData.included)
{
cssData.link.disabled = false;
cssData.included = true;
}
}
/**
* Excludes a CSS stylesheet from the current document.
*
* @param {string} fileName The stylesheet file name
**/
,excludeCss: function (fileName)
{
var cssData = this.cssIncludes[fileName];
if (cssData && cssData.included)
{
cssData.link.disabled = true;
cssData.included = false;
}
}
/**
* Request an XML file.
*
* @param {string} path The file path
* @param {Function} callback The function to call when file is downloaded
**/
,loadXml: function (path, callback)
{
var includeData = this.xmlIncludes[path];
if (true || !includeData)
{
var request = new XMLHttpRequest ();
request.onreadystatechange =
this._onXmlReady.bind (this, request, path, callback);
request.open ('get', path +'?'+ Vn.Cookie.get ('hedera_version'), true);
request.send ();
}
else if (callback)
callback (true);
}
,_onXmlReady: function (request, path, callback)
{
if (request.readyState != 4)
return;
if (request.status == 200)
this.xmlIncludes[path] = request.responseXML;
if (callback)
callback (request.status == 200);
}
/**
* Gets the DOM object from an included XML file.
*
* @param {string} path The file path
* @return {Object} The DOM object
**/
,getXml: function (path)
{
return this.xmlIncludes[path];
}
/**
* Checks if user is using a mobile browser.
*
* return {boolean} %true if is mobile, %false otherwise.
**/
,isMobile: function ()
{
if (this.isMobileCached === null)
{
var regExp = /(Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone)/i;
this.isMobileCached = navigator.userAgent.match (regExp);
}
return this.isMobileCached;
}
,get: function (id)
{
return document.getElementById (id);
}
};

49
web/locale/ca/js/hedera.js Executable file
View File

@ -0,0 +1,49 @@
Vn.Locale.add
({
"User": "Usuari"
,"Password": "Contrasenya"
,"Beta": "Beta"
,"NotCloseSession": "No tancar sessió"
,"IWantToKnowMore": "Vull saber-ne més!"
,"Enter": "Entrar"
,"LoginMail": "clientes@verdnatura.es"
,"LoginPhone": "+34 607 562 391"
,"SessionExpired": "Has estat massa temps inactiu i la sessió ha expirat."
,"InvalidLogin": "Usuari o contrasenya incorrectes. Recorda que s'hi distingeix entre majúscula i minúscula."
,"Menu": "Menú"
,"Exit": "Sortir"
,"TestTheNewWebsite": "Prova la nova web!"
,"ReturnToOldWebsite": "Web antiga"
,"ChangeLog": "Canvis recents"
,"ErrorLoadingForm": "Error al carregar formulari"
,"CookiesNotification": "En utilitzar aquest lloc web acceptes l'ús de cookies per a la personalització de continguts i anàlisi."
,"NewVersionAvailable": "Hi ha una nova actualització, la pàgina recargargará automàticament per descarregar-la"
,"AppName": "Verdnatura"
,"Home": "Inici"
,"Orders": "Encàrrecs"
,"Basket": "Cistella"
,"Last orders": "Últims comandes"
,"Invoices": "Factures"
,"Catalog": "Catàleg"
,"About": "Coneix-nos"
,"About us": "Quant a"
,"Why": "Per què?"
,"Location": "Localització"
,"Administration": "Administració"
,"Control panel": "Panell de control"
,"Users": "Usuaris"
,"Visits": "Visites"
,"News": "Noticies"
,"Photos": "Fotos"
,"Contact": "Vull ser client"
,"Training": "Formació"
,"Agencies": "Agències"
,"Configuration": "Configuració"
,"Account": "Compte"
,"Addresses": "Direccions"
});

View File

@ -41,47 +41,4 @@ Vn.Locale.add
,"Oct": "Oct" ,"Oct": "Oct"
,"Nov": "Nov" ,"Nov": "Nov"
,"Dec": "Des" ,"Dec": "Des"
,"AppName": "Verdnatura"
,"Beta": "Beta"
,"User": "Usuari"
,"Password": "Contrasenya"
,"Remember": "Recordar"
,"Enter": "Entrar"
,"Exit": "Sortir"
,"ErrorLoadingForm": "Error al carregar formulari"
,"YoureVisitor": "Solament estàs de visita?"
,"NewVersionAvailable": "Hi ha una nova actualització, la pàgina recargargará automàticament per descarregar-la"
,"ChangeLog": "Canvis recents"
,"CookiesNotification": "En utilitzar aquest lloc web acceptes l'ús de cookies per a la personalització de continguts i anàlisi."
,"ReturnToOldWebsite": "Web antiga"
,"TestTheNewWebsite": "Prova la nova web!"
,"Menu": "Menú"
,"Home": "Inici"
,"Orders": "Encàrrecs"
,"Basket": "Cistella"
,"Last orders": "Últims comandes"
,"Invoices": "Factures"
,"Catalog": "Catàleg"
,"About": "Coneix-nos"
,"About us": "Quant a"
,"Why": "Per què?"
,"Location": "Localització"
,"Administration": "Administració"
,"Control panel": "Panell de control"
,"Users": "Usuaris"
,"Visits": "Visites"
,"News": "Noticies"
,"Photos": "Fotos"
,"Contact": "Vull ser client"
,"Training": "Formació"
,"Agencies": "Agències"
,"Configuration": "Configuració"
,"Account": "Compte"
,"Addresses": "Direccions"
,"SessionExpired": "Has estat massa temps inactiu i la sessió ha expirat."
,"InvalidLogin": "Usuari o contrasenya incorrectes. Recorda que s'hi distingeix entre majúscula i minúscula."
}); });

49
web/locale/es/js/hedera.js Executable file
View File

@ -0,0 +1,49 @@
Vn.Locale.add
({
"User": "Usuario"
,"Password": "Contraseña"
,"Beta": "Beta"
,"NotCloseSession": "No cerrar sesión"
,"IWantToKnowMore": "¡Quiero saber más!"
,"Enter": "Entrar"
,"LoginMail": "clientes@verdnatura.es"
,"LoginPhone": "+34 963 242 100"
,"SessionExpired": "Has estado demasiado tiempo inactivo y la sesión ha expirado."
,"InvalidLogin": "Usuario o contraseña incorrectos. Recuerda que se hace distinción entre mayúsculas y minúsculas."
,"Menu": "Menú"
,"Exit": "Salir"
,"TestTheNewWebsite": "¡Prueba la nueva web!"
,"ReturnToOldWebsite": "Web antigua"
,"ChangeLog": "Cambios recientes"
,"ErrorLoadingForm": "Error al cargar formulario"
,"CookiesNotification": "Al utilizar este sitio web aceptas el uso de cookies para la personalización de contenidos y análisis."
,"NewVersionAvailable": "Hay una nueva actualización, la página se recargargará automaticamente para descargarla"
,"AppName": "Verdnatura"
,"Home": "Inicio"
,"Orders": "Pedidos"
,"Basket": "Cesta"
,"Last orders": "Últimos pedidos"
,"Invoices": "Facturas"
,"Catalog": "Catálogo"
,"About": "Conócenos"
,"About us": "Sobre nosotros"
,"Why": "¿Por qué?"
,"Location": "Localización"
,"Administration": "Administración"
,"Control panel": "Panel de control"
,"Users": "Usuarios"
,"Visits": "Visitas"
,"News": "Noticias"
,"Photos": "Fotos"
,"Contact": "Quiero ser cliente"
,"Training": "Formación"
,"Agencies": "Agencias"
,"Configuration": "Configuración"
,"Account": "Cuenta"
,"Addresses": "Direcciones"
});

View File

@ -41,47 +41,4 @@ Vn.Locale.add
,"Oct": "Oct" ,"Oct": "Oct"
,"Nov": "Nov" ,"Nov": "Nov"
,"Dec": "Dic" ,"Dec": "Dic"
,"AppName": "Verdnatura"
,"Beta": "Beta"
,"User": "Usuario"
,"Password": "Contraseña"
,"Remember": "Recordar"
,"Enter": "Entrar"
,"Exit": "Salir"
,"ErrorLoadingForm": "Error al cargar formulario"
,"YoureVisitor": "¿Solo estás de visita?"
,"NewVersionAvailable": "Hay una nueva actualización, la página se recargargará automaticamente para descargarla"
,"ChangeLog": "Cambios recientes"
,"CookiesNotification": "Al utilizar este sitio web aceptas el uso de cookies para la personalización de contenidos y análisis."
,"ReturnToOldWebsite": "Web antigua"
,"TestTheNewWebsite": "¡Prueba la nueva web!"
,"Menu": "Menú"
,"Home": "Inicio"
,"Orders": "Pedidos"
,"Basket": "Cesta"
,"Last orders": "Últimos pedidos"
,"Invoices": "Facturas"
,"Catalog": "Catálogo"
,"About": "Conócenos"
,"About us": "Sobre nosotros"
,"Why": "¿Por qué?"
,"Location": "Localización"
,"Administration": "Administración"
,"Control panel": "Panel de control"
,"Users": "Usuarios"
,"Visits": "Visitas"
,"News": "Noticias"
,"Photos": "Fotos"
,"Contact": "Quiero ser cliente"
,"Training": "Formación"
,"Agencies": "Agencias"
,"Configuration": "Configuración"
,"Account": "Cuenta"
,"Addresses": "Direcciones"
,"SessionExpired": "Has estado demasiado tiempo inactivo y la sesión ha expirado."
,"InvalidLogin": "Usuario o contraseña incorrectos. Recuerda que se hace distinción entre mayúsculas y minúsculas."
}); });

49
web/locale/fr/js/hedera.js Executable file
View File

@ -0,0 +1,49 @@
Vn.Locale.add
({
"User": "Utilisateur"
,"Password": "Mot de passe"
,"Beta": "Beta"
,"NotCloseSession": "Garder ma session active"
,"IWantToKnowMore": "En savoir plus!"
,"Enter": "Entrer"
,"LoginMail": "ruben@verdnatura.es"
,"LoginPhone": "+33 781 533 900"
,"SessionExpired": "Il a eu le temps de trop paresseux et votre session a expiré."
,"InvalidLogin": "Utilisateur ou mot de passe incorrect. N'oubliez pas de distinction entre majuscules et minuscules."
,"Menu": "Menu"
,"Exit": "Laisser"
,"TestTheNewWebsite": "Testez le nouveau site!"
,"ReturnToOldWebsite": "Ancien site web"
,"ChangeLog": "Modifications récentes"
,"ErrorLoadingForm": "Forme erreur de chargement"
,"CookiesNotification": "En utilisant ce site, vous acceptez l'utilisation de cookies pour personnaliser le contenu et l'analyse."
,"NewVersionAvailable": "Il ya une nouvelle mise à jour, la page sera automatiquement recargargará pour télécharger"
,"AppName": "Verdnatura"
,"Home": "Accueil"
,"Orders": "Commandes"
,"Basket": "Panier"
,"Last orders": "Dernières commandes"
,"Invoices": "Facturas"
,"Catalog": "Catalogue"
,"About": "Nous"
,"About us": "A propos de nous"
,"Why": "Pourquoi?"
,"Location": "Emplacement"
,"Administration": "Administration"
,"Control panel": "Panneau de contrôle"
,"Users": "Utilisateurs"
,"Visits": "Visites"
,"News": "Nouvelles"
,"Photos": "Photos"
,"Contact": "Je veux être client"
,"Training": "Formation"
,"Agencies": "Agences"
,"Configuration": "Configuration"
,"Account": "Compte"
,"Addresses": "Adresses"
});

View File

@ -41,47 +41,4 @@ Vn.Locale.add
,"Oct": "Oct" ,"Oct": "Oct"
,"Nov": "Nov" ,"Nov": "Nov"
,"Dec": "Déc" ,"Dec": "Déc"
,"AppName": "Verdnatura"
,"Beta": "Beta"
,"User": "Utilisateur"
,"Password": "Mot de passe"
,"Remember": "Rappeler"
,"Enter": "entrer"
,"Exit": "Laisser"
,"ErrorLoadingForm": "Forme erreur de chargement"
,"YoureVisitor": "¿Solo estás de visita?"
,"NewVersionAvailable": "Il ya une nouvelle mise à jour, la page sera automatiquement recargargará pour télécharger"
,"ChangeLog": "Modifications récentes"
,"CookiesNotification": "En utilisant ce site, vous acceptez l'utilisation de cookies pour personnaliser le contenu et l'analyse."
,"ReturnToOldWebsite": "Ancien site web"
,"TestTheNewWebsite": "Testez le nouveau site!"
,"Menu": "Menu"
,"Home": "Accueil"
,"Orders": "Commandes"
,"Basket": "Panier"
,"Last orders": "Dernières commandes"
,"Invoices": "Facturas"
,"Catalog": "Catalogue"
,"About": "Nous"
,"About us": "A propos de nous"
,"Why": "Pourquoi?"
,"Location": "Emplacement"
,"Administration": "Administration"
,"Control panel": "Panneau de contrôle"
,"Users": "Utilisateurs"
,"Visits": "Visites"
,"News": "Nouvelles"
,"Photos": "Photos"
,"Contact": "Je veux être client"
,"Training": "Formation"
,"Agencies": "Agences"
,"Configuration": "Configuration"
,"Account": "Compte"
,"Addresses": "Adresses"
,"SessionExpired": "Il a eu le temps de trop paresseux et votre session a expiré."
,"InvalidLogin": "Utilisateur ou mot de passe incorrect. N'oubliez pas de distinction entre majuscules et minuscules."
}); });

View File

@ -1,10 +1,13 @@
window.addEventListener ('load', window.addEventListener ('load', function () {
function () { Vn.Login.initialize (); }); var web = new Vn.Login ();
});
Vn.Login = Vn.Login = new Class
{ ({
initialize: function () Extends: Vn.Object
,initialize: function ()
{ {
Vn.Hash.initialize (); Vn.Hash.initialize ();
@ -26,5 +29,5 @@ Vn.Login =
userEntry.focus (); userEntry.focus ();
userEntry.select (); userEntry.select ();
} }
}; });

13
web/pages/main/head.php Executable file
View File

@ -0,0 +1,13 @@
<?php
use Vn\Hedera\Js;
require_once ('global/metatags.php');
Js::includeFile ('js/vn/vn.js');
Js::includeFile ('js/vn/cookie.js');
Js::includeFile ('pages/main/main.js');
Js::includeCss ('pages/main/style.css');
?>

15
web/pages/main/html.php Executable file
View File

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="user-scalable=no"/>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes"/>
<meta name="mobile-web-app-capable" content="yes">
<link rel="shortcut icon" type="image/x-icon" href="image/favicon.ico"/>
<?php include ('pages/main/head.php') ?>
<title>Verdnatura</title>
</head>
<body></body>
</html>

13
web/pages/main/main.js Executable file
View File

@ -0,0 +1,13 @@
Vn.includeJs ('js/misc/main.js');
Vn.includeJs ('js/vn/locale.js');
Vn.includeJs ('js/vn/main.js');
Vn.includeJs ('js/sql/main.js');
Vn.includeJs ('js/db/main.js');
Vn.includeJs ('js/htk/main.js');
Vn.includeJs ('js/hedera/main.js');
window.addEventListener ('load', function () {
var app = new Vn.App ();
app.run ();
});

BIN
web/pages/main/opensans.ttf Executable file

Binary file not shown.

17
web/pages/main/style.css Executable file
View File

@ -0,0 +1,17 @@
@font-face
{
font-family: 'Open Sans';
src: url('opensans.ttf') format('truetype');
}
body
{
position: absolute;
margin: 0;
height: 100%;
width: 100%;
z-index: -2;
background-color: #EEE;
}

View File

@ -1,18 +1,9 @@
/*
@media
(min-resolution: 120dpi) and (min-width: 800px),
(max-resolution: 119dpi) and (max-width: 800px)
{
} @media (min-resolution: 120dpi) and (orientation: portrait)
*/
@media
(min-resolution: 120dpi) and (orientation: portrait)
{ {
* { font-size: 18pt; } * { font-size: 18pt; }
} }
@media @media (min-resolution: 120dpi) and (orientation: landscape)
(min-resolution: 120dpi) and (orientation: landscape)
{ {
* { font-size: 10pt; } * { font-size: 10pt; }
} }

View File

@ -2,12 +2,14 @@
<html xmlns="http://www.w3.org/1999/xhtml"> <html xmlns="http://www.w3.org/1999/xhtml">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta charset="UTF-8">
<meta name="viewport" content="user-scalable=no"/> <meta name="viewport" content="user-scalable=no"/>
<?php include ('pages/web/head.php') ?> <!--<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes"/>-->
<meta name="mobile-web-app-capable" content="yes">
<link rel="shortcut icon" type="image/x-icon" href="image/favicon.ico"/> <link rel="shortcut icon" type="image/x-icon" href="image/favicon.ico"/>
<title>Verdnatura</title> <title>Verdnatura</title>
<?php include ('pages/web/head.php') ?>
</head> </head>
<body> <body>
<div id="header"> <div id="header">

15
web/pages/web/web.js Executable file → Normal file
View File

@ -1,10 +1,13 @@
window.addEventListener ('load', window.addEventListener ('load', function () {
function () { Vn.Web.initialize (); }); var web = new Vn.Web ();
});
Vn.Web = Vn.Web = new Class
{ ({
forms: {} Extends: Htk.Widget
,forms: {}
,activeForm: null ,activeForm: null
,activeCss: null ,activeCss: null
,requestedForm: null ,requestedForm: null
@ -489,5 +492,5 @@ Vn.Web =
this.conn.disconnect ('error', this.onConnError, this); this.conn.disconnect ('error', this.onConnError, this);
this.conn.disconnect ('loading-changed', this.onConnLoading, this); this.conn.disconnect ('loading-changed', this.onConnLoading, this);
} }
}; });