Merge branch 'master' of https://github.com/thelia/thelia into coupon

* 'master' of https://github.com/thelia/thelia: (87 commits)
  Missing ajax-loader icon
  don't use alternative Logger in debugbar if debug is disabled
  Remove debug bar
  Move temporarily fontawesome's font into the web folder
  Add loader css
  fix product visibility comparaison parameter
  Change this page on public page
  Bug : Remove close tag </a>
  decode url before searching if it's a rewritten url
  Modification font-size of price elements
  add page View All
  Add button "add product to cart"
  Footer : Static to dynamic content
  Add order on attribute_combination loop
  Fix bug in Content Loop with "current_folder" params
  Creation of Content page
  Change path /customer/account into /account
  Change path :  /customer/update into /account/update  /password into /account/password
  CustomerUpdateForm - Extend CustomerCreation
  Update profile - new method [Not finished yet]
  ...
This commit is contained in:
gmorel
2013-10-20 21:11:58 +02:00
105 changed files with 6129 additions and 4013 deletions

BIN
composer.phar Executable file

Binary file not shown.

View File

@@ -41,11 +41,12 @@ class Tax extends BaseAction implements EventSubscriberInterface
$tax $tax
->setDispatcher($this->getDispatcher()) ->setDispatcher($this->getDispatcher())
->setRequirements($event->getRequirements())
->setType($event->getType()) ->setType($event->getType())
->setLocale($event->getLocale()) ->setLocale($event->getLocale())
->setTitle($event->getTitle()) ->setTitle($event->getTitle())
->setDescription($event->getDescription()) ->setDescription($event->getDescription())
; ;
$tax->save(); $tax->save();
@@ -61,14 +62,14 @@ class Tax extends BaseAction implements EventSubscriberInterface
$tax $tax
->setDispatcher($this->getDispatcher()) ->setDispatcher($this->getDispatcher())
->setRequirements($event->getRequirements())
->setType($event->getType()) ->setType($event->getType())
->setLocale($event->getLocale()) ->setLocale($event->getLocale())
->setTitle($event->getTitle()) ->setTitle($event->getTitle())
->setDescription($event->getDescription()) ->setDescription($event->getDescription())
->save()
; ;
$tax->save();
$event->setTax($tax); $event->setTax($tax);
} }
@@ -98,7 +99,6 @@ class Tax extends BaseAction implements EventSubscriberInterface
TheliaEvents::TAX_CREATE => array("create", 128), TheliaEvents::TAX_CREATE => array("create", 128),
TheliaEvents::TAX_UPDATE => array("update", 128), TheliaEvents::TAX_UPDATE => array("update", 128),
TheliaEvents::TAX_DELETE => array("delete", 128), TheliaEvents::TAX_DELETE => array("delete", 128),
); );
} }
} }

View File

@@ -27,6 +27,7 @@ use Propel\Runtime\ActiveQuery\Criteria;
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Thelia\Core\Event\Tax\TaxRuleEvent; use Thelia\Core\Event\Tax\TaxRuleEvent;
use Thelia\Core\Event\TheliaEvents; use Thelia\Core\Event\TheliaEvents;
use Thelia\Model\Map\TaxRuleTableMap;
use Thelia\Model\TaxRuleCountry; use Thelia\Model\TaxRuleCountry;
use Thelia\Model\TaxRuleCountryQuery; use Thelia\Model\TaxRuleCountryQuery;
use Thelia\Model\TaxRule as TaxRuleModel; use Thelia\Model\TaxRule as TaxRuleModel;
@@ -134,6 +135,23 @@ class TaxRule extends BaseAction implements EventSubscriberInterface
} }
} }
/**
* @param TaxRuleEvent $event
*/
public function setDefault(TaxRuleEvent $event)
{
if (null !== $taxRule = TaxRuleQuery::create()->findPk($event->getId())) {
TaxRuleQuery::create()->update(array(
"IsDefault" => 0
));
$taxRule->setIsDefault(1)->save();
$event->setTaxRule($taxRule);
}
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@@ -144,7 +162,7 @@ class TaxRule extends BaseAction implements EventSubscriberInterface
TheliaEvents::TAX_RULE_UPDATE => array("update", 128), TheliaEvents::TAX_RULE_UPDATE => array("update", 128),
TheliaEvents::TAX_RULE_TAXES_UPDATE => array("updateTaxes", 128), TheliaEvents::TAX_RULE_TAXES_UPDATE => array("updateTaxes", 128),
TheliaEvents::TAX_RULE_DELETE => array("delete", 128), TheliaEvents::TAX_RULE_DELETE => array("delete", 128),
TheliaEvents::TAX_RULE_SET_DEFAULT => array("setDefault", 128),
); );
} }
} }

View File

@@ -55,6 +55,7 @@
<form name="thelia.install.step3" class="Thelia\Form\InstallStep3Form"/> <form name="thelia.install.step3" class="Thelia\Form\InstallStep3Form"/>
<form name="thelia.customer.creation" class="Thelia\Form\CustomerCreation"/> <form name="thelia.customer.creation" class="Thelia\Form\CustomerCreation"/>
<form name="thelia.customer.update" class="Thelia\Form\CustomerUpdateForm"/>
<form name="thelia.customer.modification" class="Thelia\Form\CustomerModification"/> <form name="thelia.customer.modification" class="Thelia\Form\CustomerModification"/>
<form name="thelia.customer.lostpassword" class="Thelia\Form\CustomerLostPasswordForm"/> <form name="thelia.customer.lostpassword" class="Thelia\Form\CustomerLostPasswordForm"/>
@@ -131,6 +132,10 @@
<form name="thelia.admin.country.modification" class="Thelia\Form\CountryModificationForm"/> <form name="thelia.admin.country.modification" class="Thelia\Form\CountryModificationForm"/>
<form name="thelia.admin.profile.modification" class="Thelia\Form\ProfileModificationForm"/> <form name="thelia.admin.profile.modification" class="Thelia\Form\ProfileModificationForm"/>
<form name="thelia.admin.language.creation" class="Thelia\Form\LanguageCreationForm"/>
<form name="thelia.admin.admin-profile.creation" class="Thelia\Form\AdminProfileCreationForm"/>
<form name="thelia.admin.area.create" class="Thelia\Form\Area\AreaCreateForm"/> <form name="thelia.admin.area.create" class="Thelia\Form\Area\AreaCreateForm"/>
<form name="thelia.admin.area.modification" class="Thelia\Form\Area\AreaModificationForm"/> <form name="thelia.admin.area.modification" class="Thelia\Form\Area\AreaModificationForm"/>

View File

@@ -4,22 +4,22 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd"> xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
<!-- Route to administration base --> <!-- Route to administration base -->
<route id="admin" path="/admin"> <route id="admin" path="/admin">
<default key="_controller">Thelia\Controller\Admin\AdminController::indexAction</default> <default key="_controller">Thelia\Controller\Admin\AdminController::indexAction</default>
</route> </route>
<!-- Route to the administration login page --> <!-- Route to the administration login page -->
<route id="admin.login" path="/admin/login"> <route id="admin.login" path="/admin/login">
<default key="_controller">Thelia\Controller\Admin\SessionController::showLoginAction</default> <default key="_controller">Thelia\Controller\Admin\SessionController::showLoginAction</default>
</route> </route>
<!-- Route to the administration logout page --> <!-- Route to the administration logout page -->
<route id="admin.logout" path="/admin/logout"> <route id="admin.logout" path="/admin/logout">
<default key="_controller">Thelia\Controller\Admin\SessionController::checkLogoutAction</default> <default key="_controller">Thelia\Controller\Admin\SessionController::checkLogoutAction</default>
</route> </route>
<!-- Route to the login check controller --> <!-- Route to the login check controller -->
<route id="admin.checklogin" path="/admin/checklogin"> <route id="admin.checklogin" path="/admin/checklogin">
<default key="_controller">Thelia\Controller\Admin\SessionController::checkLoginAction</default> <default key="_controller">Thelia\Controller\Admin\SessionController::checkLoginAction</default>
</route> </route>
@@ -31,7 +31,7 @@
<!-- Route to the catalog controller --> <!-- Route to the catalog controller -->
<route id="admin.catalog" path="/admin/catalog"> <route id="admin.catalog" path="/admin/catalog">
<default key="_controller">Thelia\Controller\Admin\CategoryController::defaultAction</default> <default key="_controller">Thelia\Controller\Admin\CategoryController::defaultAction</default>
@@ -870,10 +870,15 @@
<default key="_controller">Thelia\Controller\Admin\TaxRuleController::deleteAction</default> <default key="_controller">Thelia\Controller\Admin\TaxRuleController::deleteAction</default>
</route> </route>
<route id="admin.configuration.taxes-rules.set-default" path="/admin/configuration/taxes_rules/update/set_default/{tax_rule_id}">
<default key="_controller">Thelia\Controller\Admin\TaxRuleController::setDefaultAction</default>
<requirement key="tax_rule_id">\d+</requirement>
</route>
<!-- end tax rules management --> <!-- end tax rules management -->
<!-- The default route, to display a template --> <!-- The default route, to display a template -->
<route id="admin.processTemplate" path="/admin/{template}"> <route id="admin.processTemplate" path="/admin/{template}">
<default key="_controller">Thelia\Controller\Admin\AdminController::processTemplateAction</default> <default key="_controller">Thelia\Controller\Admin\AdminController::processTemplateAction</default>

View File

@@ -4,56 +4,75 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd"> xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
<route id="home" path="/" > <route id="home" path="/">
<default key="_controller">Thelia\Controller\Front\DefaultController::noAction</default> <default key="_controller">Thelia\Controller\Front\DefaultController::noAction</default>
<default key="_view">index</default> <default key="_view">index</default>
</route> </route>
<!-- Customer routes -->
<!-- Search routes -->
<route id="search" path="/search">
<default key="_controller">Thelia\Controller\Front\DefaultController::noAction</default>
<default key="_view">search</default>
</route>
<route id="view_all" path="/view_all" methods="get">
<default key="_controller">Thelia\Controller\Front\DefaultController::noAction</default>
<default key="_view">view_all</default>
</route>
<!-- Customer routes : Register -->
<route id="customer.create.process" path="/register" methods="post">
<default key="_controller">Thelia\Controller\Front\CustomerController::createAction</default>
<default key="_view">register</default>
</route>
<route id="customer.create.view" path="/register"> <route id="customer.create.view" path="/register">
<default key="_controller">Thelia\Controller\Front\DefaultController::noAction</default> <default key="_controller">Thelia\Controller\Front\DefaultController::noAction</default>
<default key="_view">register</default> <default key="_view">register</default>
</route> </route>
<!-- Customer routes : Login -->
<route id="customer.login.process" path="/login" methods="post">
<default key="_controller">Thelia\Controller\Front\CustomerController::loginAction</default>
<default key="_view">login</default>
</route>
<route id="customer.login.view" path="/login"> <route id="customer.login.view" path="/login">
<default key="_controller">Thelia\Controller\Front\DefaultController::noAction</default> <default key="_controller">Thelia\Controller\Front\DefaultController::noAction</default>
<default key="_view">login</default> <default key="_view">login</default>
</route> </route>
<!-- Customer routes : Logout -->
<route id="customer.logout.process" path="/logout"> <route id="customer.logout.process" path="/logout">
<default key="_controller">Thelia\Controller\Front\CustomerController::logoutAction</default> <default key="_controller">Thelia\Controller\Front\CustomerController::logoutAction</default>
</route> </route>
<route id="customer.account.view" path="/customer/account"> <!-- Customer routes : Account -->
<route id="customer.account.view" path="/account">
<default key="_controller">Thelia\Controller\Front\DefaultController::noAction</default> <default key="_controller">Thelia\Controller\Front\DefaultController::noAction</default>
<default key="_view">account</default> <default key="_view">account</default>
</route> </route>
<route id="customer.create.process" path="/customer/create" methods="post"> <route id="customer.update.view" path="/account/update" methods="get">
<default key="_controller">Thelia\Controller\Front\CustomerController::createAction</default> <default key="_controller">Thelia\Controller\Front\CustomerController::viewAction</default>
<default key="_view">register</default> <default key="_view">account-update</default>
</route> </route>
<route id="customer.update.process" path="/account/update" methods="post">
<route id="customer.update.process" path="/customer/update" methods="post">
<default key="_controller">Thelia\Controller\Front\CustomerController::updateAction</default> <default key="_controller">Thelia\Controller\Front\CustomerController::updateAction</default>
</route> <default key="_view">account-update</default>
<route id="customer.login.process" path="/customer/login" methods="post">
<default key="_controller">Thelia\Controller\Front\CustomerController::loginAction</default>
<default key="_view">login</default>
</route> </route>
<route id="customer.password.retrieve.view" path="/password" methods="get"> <route id="customer.password.retrieve.process" path="/account/password" methods="post">
<default key="_controller">Thelia\Controller\Front\DefaultController::noAction</default>
<default key="_view">password</default>
</route>
<route id="customer.password.retrieve.process" path="/password" methods="post">
<default key="_controller">Thelia\Controller\Front\CustomerController::newPasswordAction</default> <default key="_controller">Thelia\Controller\Front\CustomerController::newPasswordAction</default>
<default key="_view">password</default> <default key="_view">account-password</default>
</route>
<route id="customer.password.retrieve.view" path="account/password" methods="get">
<default key="_controller">Thelia\Controller\Front\DefaultController::noAction</default>
<default key="_view">account-password</default>
</route> </route>
<!-- end customer routes --> <!-- end customer routes -->

View File

@@ -392,8 +392,6 @@ abstract class AbstractCrudController extends BaseAdminController
// Get the form field values // Get the form field values
$data = $form->getData(); $data = $form->getData();
$dataType = $form->all();
$changeEvent = $this->getUpdateEvent($data); $changeEvent = $this->getUpdateEvent($data);
$this->dispatch($this->updateEventIdentifier, $changeEvent); $this->dispatch($this->updateEventIdentifier, $changeEvent);

View File

@@ -20,38 +20,20 @@
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */ /* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */ /* */
/*************************************************************************************/ /*************************************************************************************/
namespace Thelia\TaxEngine\TaxType;
use Thelia\Type\FloatToFloatArrayType; namespace Thelia\Controller\Admin;
use Thelia\Type\ModelValidIdType;
/** /**
* * Class AdminProfileController
* @author Etienne Roudeix <eroudeix@openstudio.fr> * @package Thelia\Controller\Admin
* * @author Manuel Raynaud <mraynaud@openstudio.fr>
*/ */
class featureSlicePercentTaxType extends BaseTaxType class AdminProfileController extends BaseAdminController
{ {
public function pricePercentRetriever() public function defaultAction()
{ {
if (null !== $response = $this->checkAuth("admin.admin-profile.view")) return $response;
return $this->render("admin-profiles", array("display_admin_profile" => 20));
} }
public function fixAmountRetriever(\Thelia\Model\Product $product) }
{
}
public function getRequirementsList()
{
return array(
'featureId' => new ModelValidIdType('Feature'),
'slices' => new FloatToFloatArrayType(),
);
}
public function getTitle()
{
return "% slice Tax depending on a feature";
}
}

View File

@@ -0,0 +1,39 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Controller\Admin;
/**
* Class LanguageController
* @package Thelia\Controller\Admin
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class LanguageController extends BaseAdminController
{
public function defaultAction()
{
if (null !== $response = $this->checkAuth("admin.configuration.languages.view")) return $response;
return $this->render("languages");
}
}

View File

@@ -0,0 +1,39 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Controller\Admin;
/**
* Class MailingSystemController
* @package Thelia\Controller\Admin
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class MailingSystemController extends BaseAdminController
{
public function defaultAction()
{
if (null !== $response = $this->checkAuth("admin.configuration.mailing-system.view")) return $response;
return $this->render("mailing-system");
}
}

View File

@@ -68,6 +68,7 @@ class TaxController extends AbstractCrudController
$event->setTitle($formData['title']); $event->setTitle($formData['title']);
$event->setDescription($formData['description']); $event->setDescription($formData['description']);
$event->setType($formData['type']); $event->setType($formData['type']);
$event->setRequirements($this->getRequirements($formData['type'], $formData));
return $event; return $event;
} }
@@ -76,16 +77,12 @@ class TaxController extends AbstractCrudController
{ {
$event = new TaxEvent(); $event = new TaxEvent();
/* check the requirements */
if(!$this->checkRequirements($formData)) {
}
$event->setLocale($formData['locale']); $event->setLocale($formData['locale']);
$event->setId($formData['id']); $event->setId($formData['id']);
$event->setTitle($formData['title']); $event->setTitle($formData['title']);
$event->setDescription($formData['description']); $event->setDescription($formData['description']);
$event->setType($formData['type']); $event->setType($formData['type']);
$event->setRequirements($this->getRequirements($formData['type'], $formData));
return $event; return $event;
} }
@@ -207,4 +204,24 @@ class TaxController extends AbstractCrudController
} }
protected function getRequirements($type, $formData)
{
$requirements = array();
foreach($formData as $data => $value) {
if(!strstr($data, ':')) {
continue;
}
$couple = explode(':', $data);
if(count($couple) != 2 || $couple[0] != $type) {
continue;
}
$requirements[$couple[1]] = $value;
}
return $requirements;
}
} }

View File

@@ -236,6 +236,23 @@ class TaxRuleController extends AbstractCrudController
return parent::updateAction(); return parent::updateAction();
} }
public function setDefaultAction()
{
if (null !== $response = $this->checkAuth($this->updatePermissionIdentifier)) return $response;
$setDefaultEvent = new TaxRuleEvent();
$taxRuleId = $this->getRequest()->attributes->get('tax_rule_id');
$setDefaultEvent->setId(
$taxRuleId
);
$this->dispatch(TheliaEvents::TAX_RULE_SET_DEFAULT, $setDefaultEvent);
$this->redirectToListTemplate();
}
public function processUpdateTaxesAction() public function processUpdateTaxesAction()
{ {
// Check current user authorization // Check current user authorization

View File

@@ -31,10 +31,11 @@ use Thelia\Core\Security\Exception\UsernameNotFoundException;
use Thelia\Form\CustomerCreation; use Thelia\Form\CustomerCreation;
use Thelia\Form\CustomerLogin; use Thelia\Form\CustomerLogin;
use Thelia\Form\CustomerLostPasswordForm; use Thelia\Form\CustomerLostPasswordForm;
use Thelia\Form\CustomerModification; use Thelia\Form\CustomerUpdateForm;
use Thelia\Form\Exception\FormValidationException; use Thelia\Form\Exception\FormValidationException;
use Thelia\Model\Customer; use Thelia\Model\Customer;
use Thelia\Core\Event\TheliaEvents; use Thelia\Core\Event\TheliaEvents;
use Thelia\Model\CustomerQuery;
use Thelia\Tools\URL; use Thelia\Tools\URL;
use Thelia\Log\Tlog; use Thelia\Log\Tlog;
use Thelia\Core\Security\Exception\WrongPasswordException; use Thelia\Core\Security\Exception\WrongPasswordException;
@@ -128,32 +129,56 @@ class CustomerController extends BaseFrontController
} }
} }
protected function getExistingCustomer($customer_id)
{
return CustomerQuery::create()
->findOneById($customer_id);
}
/** /**
* Update customer data. On success, redirect to success_url if exists. * Update customer data. On success, redirect to success_url if exists.
* Otherwise, display the same view again. * Otherwise, display the same view again.
*/ */
public function viewAction()
{
$this->checkAuth();
$customer = $this->getSecurityContext()->getCustomerUser();
$data = array(
'id' => $customer->getId(),
'title' => $customer->getTitleId(),
'firstname' => $customer->getFirstName(),
'lastname' => $customer->getLastName(),
'email' => $customer->getEmail(),
);
$customerUpdateForm = new CustomerUpdateForm($this->getRequest(), 'form', $data);
// Pass it to the parser
$this->getParserContext()->addForm($customerUpdateForm);
}
public function updateAction() public function updateAction()
{ {
if ($this->getSecurityContext()->hasCustomerUser()) { if ($this->getSecurityContext()->hasCustomerUser()) {
$message = false; $message = false;
$customerModification = new CustomerModification($this->getRequest()); $customerUpdateForm = new CustomerUpdateForm($this->getRequest());
try { try {
$customer = $this->getSecurityContext()->getCustomerUser(); $customer = $this->getSecurityContext()->getCustomerUser();
$form = $this->validateForm($customerModification, "post"); $form = $this->validateForm($customerUpdateForm, "post");
$customerChangeEvent = $this->createEventInstance($form->getData()); $customerChangeEvent = $this->createEventInstance($form->getData());
$customerChangeEvent->setCustomer($customer); $customerChangeEvent->setCustomer($customer);
$this->dispatch(TheliaEvents::CUSTOMER_UPDATEACCOUNT, $customerChangeEvent); $this->dispatch(TheliaEvents::CUSTOMER_UPDATEACCOUNT, $customerChangeEvent);
$this->processLogin($customerChangeEvent->getCustomer()); $this->processLogin($customerChangeEvent->getCustomer());
$this->redirectSuccess($customerModification); $this->redirectSuccess($customerUpdateForm);
} catch (FormValidationException $e) { } catch (FormValidationException $e) {
$message = sprintf("Please check your input: %s", $e->getMessage()); $message = sprintf("Please check your input: %s", $e->getMessage());
@@ -164,10 +189,10 @@ class CustomerController extends BaseFrontController
if ($message !== false) { if ($message !== false) {
Tlog::getInstance()->error(sprintf("Error during customer modification process : %s.", $message)); Tlog::getInstance()->error(sprintf("Error during customer modification process : %s.", $message));
$customerModification->setErrorMessage($message); $customerUpdateForm->setErrorMessage($message);
$this->getParserContext() $this->getParserContext()
->addForm($customerModification) ->addForm($customerUpdateForm)
->setGeneralError($message) ->setGeneralError($message)
; ;
} }
@@ -193,31 +218,33 @@ class CustomerController extends BaseFrontController
$form = $this->validateForm($customerLoginForm, "post"); $form = $this->validateForm($customerLoginForm, "post");
$authenticator = new CustomerUsernamePasswordFormAuthenticator($request, $customerLoginForm); // If User is a new customer
if ($form->get('account')->getData() == 0 && !$form->get("email")->getErrors()) {
$this->redirectToRoute("customer.create.view", array("email" => $form->get("email")->getData()));
} else {
$customer = $authenticator->getAuthentifiedUser(); try {
$this->processLogin($customer); $authenticator = new CustomerUsernamePasswordFormAuthenticator($request, $customerLoginForm);
$this->redirectSuccess($customerLoginForm); $customer = $authenticator->getAuthentifiedUser();
} catch (FormValidationException $e) { $this->processLogin($customer);
if ($request->request->has("account")) { $this->redirectSuccess($customerLoginForm);
$account = $request->request->get("account");
$form = $customerLoginForm->getForm(); } catch (UsernameNotFoundException $e) {
if ($account == 0 && $form->get("email")->getData() !== null) { $message = "Wrong email or password. Please try again";
$this->redirectToRoute("customer.create.view", array("email" => $form->get("email")->getData())); } catch (WrongPasswordException $e) {
$message = "Wrong email or password. Please try again";
} catch (AuthenticationException $e) {
$message = "Wrong email or password. Please try again";
} }
} }
} catch (FormValidationException $e) {
$message = sprintf("Please check your input: %s", $e->getMessage()); $message = sprintf("Please check your input: %s", $e->getMessage());
} catch (UsernameNotFoundException $e) {
$message = "Wrong email or password. Please try again";
} catch (WrongPasswordException $e) {
$message = "Wrong email or password. Please try again";
} catch (AuthenticationException $e) {
$message = "Wrong email or password. Please try again";
} catch (\Exception $e) { } catch (\Exception $e) {
$message = sprintf("Sorry, an error occured: %s", $e->getMessage()); $message = sprintf("Sorry, an error occured: %s", $e->getMessage());
} }
@@ -265,14 +292,14 @@ class CustomerController extends BaseFrontController
$data["title"], $data["title"],
$data["firstname"], $data["firstname"],
$data["lastname"], $data["lastname"],
$data["address1"], isset($data["address1"])?$data["address1"]:null,
$data["address2"], isset($data["address2"])?$data["address2"]:null,
$data["address3"], isset($data["address3"])?$data["address3"]:null,
$data["phone"], isset($data["phone"])?$data["phone"]:null,
$data["cellphone"], isset($data["cellphone"])?$data["cellphone"]:null,
$data["zipcode"], isset($data["zipcode"])?$data["zipcode"]:null,
$data["city"], isset($data["city"])?$data["city"]:null,
$data["country"], isset($data["country"])?$data["country"]:null,
isset($data["email"])?$data["email"]:null, isset($data["email"])?$data["email"]:null,
isset($data["password"]) ? $data["password"]:null, isset($data["password"]) ? $data["password"]:null,
$this->getRequest()->getSession()->getLang()->getId(), $this->getRequest()->getSession()->getLang()->getId(),

View File

@@ -34,6 +34,7 @@ class TaxEvent extends ActionEvent
protected $title; protected $title;
protected $description; protected $description;
protected $type; protected $type;
protected $requirements;
public function __construct(Tax $tax = null) public function __construct(Tax $tax = null)
{ {
@@ -106,4 +107,14 @@ class TaxEvent extends ActionEvent
{ {
return $this->type; return $this->type;
} }
public function setRequirements($requirements)
{
$this->requirements = $requirements;
}
public function getRequirements()
{
return $this->requirements;
}
} }

View File

@@ -11,13 +11,13 @@ class TheliaType extends AbstractType
public function setDefaultOptions(OptionsResolverInterface $resolver) public function setDefaultOptions(OptionsResolverInterface $resolver)
{ {
$resolver->setDefaults(array( $resolver->setDefaults(array(
'instance' => false, //'instance' => false,
'type' => false, 'type' => false,
'options' => false, 'options' => false,
)); ));
$resolver->setAllowedTypes(array( $resolver->setAllowedTypes(array(
'instance' => array('Thelia\Type\TypeInterface'), //'instance' => array('Thelia\Type\TypeInterface'),
)); ));
$resolver->setAllowedValues(array( $resolver->setAllowedValues(array(
@@ -31,7 +31,7 @@ class TheliaType extends AbstractType
public function buildView(FormView $view, FormInterface $form, array $options) public function buildView(FormView $view, FormInterface $form, array $options)
{ {
$view->vars = array_replace($view->vars, array( $view->vars = array_replace($view->vars, array(
'instance' => $options['instance'], //'instance' => $options['instance'],
'type' => $options['type'], 'type' => $options['type'],
'options' => $options['options'], 'options' => $options['options'],
)); ));

View File

@@ -102,6 +102,7 @@ class Cart extends BaseLoop
->set("TAXED_PRICE", $cartItem->getTaxedPrice($taxCountry)) ->set("TAXED_PRICE", $cartItem->getTaxedPrice($taxCountry))
->set("PROMO_TAXED_PRICE", $cartItem->getTaxedPromoPrice($taxCountry)) ->set("PROMO_TAXED_PRICE", $cartItem->getTaxedPromoPrice($taxCountry))
->set("IS_PROMO", $cartItem->getPromo() === 1 ? 1 : 0); ->set("IS_PROMO", $cartItem->getPromo() === 1 ? 1 : 0);
$loopResultRow->set("PRODUCT_SALE_ELEMENTS_ID", $productSaleElement->getId());
$result->addRow($loopResultRow); $result->addRow($loopResultRow);
} }

View File

@@ -86,6 +86,7 @@ class Content extends BaseI18nLoop
*/ */
public function exec(&$pagination) public function exec(&$pagination)
{ {
$search = ContentQuery::create(); $search = ContentQuery::create();
/* manage translations */ /* manage translations */
@@ -138,27 +139,15 @@ class Content extends BaseI18nLoop
$current_folder = $this->getCurrent_folder(); $current_folder = $this->getCurrent_folder();
if ($current_folder === true) { if ($current_folder === true) {
$search->filterByFolder( $current = ContentQuery::create()->findPk($this->request->get("content_id"));
FolderQuery::create()->filterByContent(
ContentFolderQuery::create()->filterByContentId( $search->filterByFolder($current->getFolders(), Criteria::IN);
$this->request->get("content_id"),
Criteria::EQUAL
)->find(),
Criteria::IN
)->find(),
Criteria::IN
);
} elseif ($current_folder === false) { } elseif ($current_folder === false) {
$search->filterByFolder(
FolderQuery::create()->filterByContent( $current = ContentQuery::create()->findPk($this->request->get("content_id"));
ContentFolderQuery::create()->filterByContentId(
$this->request->get("content_id"), $search->filterByFolder($current->getFolders(), Criteria::NOT_IN);
Criteria::EQUAL
)->find(),
Criteria::IN
)->find(),
Criteria::NOT_IN
);
} }
$visible = $this->getVisible(); $visible = $this->getVisible();

View File

@@ -87,6 +87,7 @@ class Product extends BaseI18nLoop
Argument::createIntTypeArgument('depth', 1), Argument::createIntTypeArgument('depth', 1),
Argument::createBooleanOrBothTypeArgument('visible', 1), Argument::createBooleanOrBothTypeArgument('visible', 1),
Argument::createIntTypeArgument('currency'), Argument::createIntTypeArgument('currency'),
Argument::createAnyTypeArgument('title'),
new Argument( new Argument(
'order', 'order',
new TypeCollection( new TypeCollection(
@@ -171,6 +172,17 @@ class Product extends BaseI18nLoop
$search->filterByRef($ref, Criteria::IN); $search->filterByRef($ref, Criteria::IN);
} }
$title = $this->getTitle();
if(!is_null($title)){
$search->where(" CASE WHEN NOT ISNULL(`requested_locale_i18n`.ID) THEN `requested_locale_i18n`.`TITLE` ELSE `default_locale_i18n`.`TITLE` END ".Criteria::LIKE." ?", "%".$title."%", \PDO::PARAM_STR);
}
$category = $this->getCategory(); $category = $this->getCategory();
$categoryDefault = $this->getCategoryDefault(); $categoryDefault = $this->getCategoryDefault();
@@ -461,7 +473,7 @@ class Product extends BaseI18nLoop
$visible = $this->getVisible(); $visible = $this->getVisible();
if ($visible != BooleanOrBothType::ANY) $search->filterByVisible($visible ? 1 : 0); if ($visible !== BooleanOrBothType::ANY) $search->filterByVisible($visible ? 1 : 0);
$exclude = $this->getExclude(); $exclude = $this->getExclude();

View File

@@ -151,12 +151,10 @@ class Tax extends BaseI18nLoop
$loopResultRow = new LoopResultRow($loopResult, $tax, $this->versionable, $this->timestampable, $this->countable); $loopResultRow = new LoopResultRow($loopResult, $tax, $this->versionable, $this->timestampable, $this->countable);
$requirements = json_decode( base64_decode( $tax->getSerializedRequirements() ), true );
$loopResultRow $loopResultRow
->set("ID" , $tax->getId()) ->set("ID" , $tax->getId())
->set("TYPE" , $tax->getType()) ->set("TYPE" , $tax->getType())
->set("REQUIREMENTS" , $requirements) ->set("REQUIREMENTS" , $tax->getRequirements())
->set("IS_TRANSLATED" , $tax->getVirtualColumn('IS_TRANSLATED')) ->set("IS_TRANSLATED" , $tax->getVirtualColumn('IS_TRANSLATED'))
->set("LOCALE" , $locale) ->set("LOCALE" , $locale)
->set("TITLE" , $tax->getVirtualColumn('i18n_TITLE')) ->set("TITLE" , $tax->getVirtualColumn('i18n_TITLE'))

View File

@@ -124,12 +124,8 @@ class Form extends AbstractSmartyPlugin
$template->assign("value", $fieldValue); $template->assign("value", $fieldValue);
$template->assign("options", $formFieldView->vars); $template->assign("checked", isset($fieldVars['checked']) ? $fieldVars['checked'] : false);
// If Checkbox input type
if ($fieldVars['checked'] !== null) {
$this->renderFormFieldCheckBox($template, $formFieldView['checked']);
}
//data //data
$template->assign("data", $fieldVars['data']); $template->assign("data", $fieldVars['data']);
@@ -137,6 +133,8 @@ class Form extends AbstractSmartyPlugin
$template->assign("label", $fieldVars["label"]); $template->assign("label", $fieldVars["label"]);
$template->assign("label_attr", $fieldVars["label_attr"]); $template->assign("label_attr", $fieldVars["label_attr"]);
$template->assign('required', isset($fieldVars['required']) ? $fieldVars['required'] : false);
$errors = $fieldVars["errors"]; $errors = $fieldVars["errors"];
$template->assign("error", empty($errors) ? false : true); $template->assign("error", empty($errors) ? false : true);
@@ -177,6 +175,7 @@ class Form extends AbstractSmartyPlugin
if($formFieldType instanceof TheliaType) { if($formFieldType instanceof TheliaType) {
$template->assign("formType", $formFieldView->vars['type']); $template->assign("formType", $formFieldView->vars['type']);
switch($formFieldView->vars['type']) { switch($formFieldView->vars['type']) {
case "choice": case "choice":
if(!isset($formFieldView->vars['options']['choices']) || !is_array($formFieldView->vars['options']['choices'])) { if(!isset($formFieldView->vars['options']['choices']) || !is_array($formFieldView->vars['options']['choices'])) {
@@ -429,17 +428,4 @@ $this->assignFieldValues($template, $formFieldView->vars["full_name"], $fieldVar
new SmartyPluginDescriptor("block", "form_error", $this, "formError") new SmartyPluginDescriptor("block", "form_error", $this, "formError")
); );
} }
/**
* @param \Smarty_Internal_Template $template
* @param $formFieldView
*/
public function renderFormFieldCheckBox(\Smarty_Internal_Template $template, $isChecked)
{
$template->assign("value", 0);
if ($isChecked) {
$template->assign("value", 1);
}
$template->assign("value", $isChecked);
}
} }

View File

@@ -0,0 +1,65 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Form;
use Symfony\Component\Validator\Constraints;
use Symfony\Component\Validator\Constraints\NotBlank;
use Thelia\Core\Translation\Translator;
class AdminProfileCreationForm extends BaseForm
{
protected function buildForm()
{
$this->formBuilder
->add("wording" , "text" , array(
"constraints" => array(
new NotBlank()
),
"label" => Translator::getInstance()->trans("Wording *"),
"label_attr" => array(
"for" => "wording"
))
)
->add("name" , "text" , array(
"constraints" => array(
new NotBlank()
),
"label" => Translator::getInstance()->trans("Name *"),
"label_attr" => array(
"for" => "name"
))
)
->add("description" , "text" , array(
"label" => Translator::getInstance()->trans("Description"),
"label_attr" => array(
"for" => "description"
))
)
;
}
public function getName()
{
return "thelia_admin_profile_creation";
}
}

View File

@@ -40,6 +40,16 @@ class CustomerCreation extends BaseForm
{ {
$this->formBuilder $this->formBuilder
->add("auto_login", "integer") ->add("auto_login", "integer")
// Personal Informations
->add("title", "text", array(
"constraints" => array(
new Constraints\NotBlank()
),
"label" => Translator::getInstance()->trans("Title"),
"label_attr" => array(
"for" => "title"
)
))
->add("firstname", "text", array( ->add("firstname", "text", array(
"constraints" => array( "constraints" => array(
new Constraints\NotBlank() new Constraints\NotBlank()
@@ -58,84 +68,6 @@ class CustomerCreation extends BaseForm
"for" => "lastname" "for" => "lastname"
) )
)) ))
->add("address1", "text", array(
"constraints" => array(
new Constraints\NotBlank()
),
"label_attr" => array(
"for" => "address"
),
"label" => Translator::getInstance()->trans("Street Address"),
"label_attr" => array(
"for" => "address1"
)
))
->add("address2", "text", array(
"label" => Translator::getInstance()->trans("Address Line 2"),
"label_attr" => array(
"for" => "address2"
)
))
->add("address3", "text", array(
"label" => Translator::getInstance()->trans("Address Line 3"),
"label_attr" => array(
"for" => "address3"
)
))
->add("company", "text", array(
"label" => Translator::getInstance()->trans("Company Name"),
"label_attr" => array(
"for" => "company"
)
))
->add("phone", "text", array(
"label" => Translator::getInstance()->trans("Phone"),
"label_attr" => array(
"for" => "phone"
)
))
->add("cellphone", "text", array(
"label" => Translator::getInstance()->trans("Cellphone"),
"label_attr" => array(
"for" => "cellphone"
)
))
->add("zipcode", "text", array(
"constraints" => array(
new Constraints\NotBlank()
),
"label" => Translator::getInstance()->trans("Zip code"),
"label_attr" => array(
"for" => "zipcode"
)
))
->add("city", "text", array(
"constraints" => array(
new Constraints\NotBlank()
),
"label" => Translator::getInstance()->trans("City"),
"label_attr" => array(
"for" => "city"
)
))
->add("country", "text", array(
"constraints" => array(
new Constraints\NotBlank()
),
"label" => Translator::getInstance()->trans("Country"),
"label_attr" => array(
"for" => "country"
)
))
->add("title", "text", array(
"constraints" => array(
new Constraints\NotBlank()
),
"label" => Translator::getInstance()->trans("Title"),
"label_attr" => array(
"for" => "title"
)
))
->add("email", "email", array( ->add("email", "email", array(
"constraints" => array( "constraints" => array(
new Constraints\NotBlank(), new Constraints\NotBlank(),
@@ -143,7 +75,7 @@ class CustomerCreation extends BaseForm
new Constraints\Callback(array( new Constraints\Callback(array(
"methods" => array( "methods" => array(
array($this, array($this,
"verifyExistingEmail") "verifyExistingEmail")
) )
)) ))
), ),
@@ -163,6 +95,79 @@ class CustomerCreation extends BaseForm
), ),
"label" => "email confirmation" "label" => "email confirmation"
))*/ ))*/
->add("phone", "text", array(
"label" => Translator::getInstance()->trans("Phone"),
"label_attr" => array(
"for" => "phone"
),
"required" => false
))
->add("cellphone", "text", array(
"label" => Translator::getInstance()->trans("Cellphone"),
"label_attr" => array(
"for" => "cellphone"
),
"required" => false
))
// Delivery Informations
->add("company", "text", array(
"label" => Translator::getInstance()->trans("Company Name"),
"label_attr" => array(
"for" => "company"
),
"required" => false
))
->add("address1", "text", array(
"constraints" => array(
new Constraints\NotBlank()
),
"label" => Translator::getInstance()->trans("Street Address"),
"label_attr" => array(
"for" => "address1"
)
))
->add("address2", "text", array(
"label" => Translator::getInstance()->trans("Address Line 2"),
"label_attr" => array(
"for" => "address2"
),
"required" => false
))
->add("address3", "text", array(
"label" => Translator::getInstance()->trans("Address Line 3"),
"label_attr" => array(
"for" => "address3"
),
"required" => false
))
->add("city", "text", array(
"constraints" => array(
new Constraints\NotBlank()
),
"label" => Translator::getInstance()->trans("City"),
"label_attr" => array(
"for" => "city"
)
))
->add("zipcode", "text", array(
"constraints" => array(
new Constraints\NotBlank()
),
"label" => Translator::getInstance()->trans("Zip code"),
"label_attr" => array(
"for" => "zipcode"
)
))
->add("country", "text", array(
"constraints" => array(
new Constraints\NotBlank()
),
"label" => Translator::getInstance()->trans("Country"),
"label_attr" => array(
"for" => "country"
)
))
// Login Information
->add("password", "password", array( ->add("password", "password", array(
"constraints" => array( "constraints" => array(
new Constraints\NotBlank(), new Constraints\NotBlank(),
@@ -186,8 +191,14 @@ class CustomerCreation extends BaseForm
"for" => "password_confirmation" "for" => "password_confirmation"
) )
)) ))
->add("agreed", "checkbox", array(
; "constraints" => array(
new Constraints\True(array("message" => "Please accept the Terms and conditions in order to register."))
),
"label_attr" => array(
"for" => "agreed"
)
));
} }
public function verifyPasswordField($value, ExecutionContextInterface $context) public function verifyPasswordField($value, ExecutionContextInterface $context)

View File

@@ -22,10 +22,19 @@
/*************************************************************************************/ /*************************************************************************************/
namespace Thelia\Form; namespace Thelia\Form;
use Symfony\Component\Validator\Constraints;
use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Email; use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\ExecutionContextInterface;
use Thelia\Core\Translation\Translator; use Thelia\Core\Translation\Translator;
use Thelia\Model\Base\CustomerQuery;
/**
* Class CustomerLogin
* @package Thelia\Form
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class CustomerLogin extends BaseForm class CustomerLogin extends BaseForm
{ {
protected function buildForm() protected function buildForm()
@@ -33,27 +42,82 @@ class CustomerLogin extends BaseForm
$this->formBuilder $this->formBuilder
->add("email", "email", array( ->add("email", "email", array(
"constraints" => array( "constraints" => array(
new NotBlank(), new Constraints\NotBlank(),
new Email() new Constraints\Email(),
new Constraints\Callback(array(
"methods" => array(
array($this, "verifyExistingEmail")
)
))
), ),
"label" => Translator::getInstance()->trans("Please enter your email address"), "label" => Translator::getInstance()->trans("Please enter your email address"),
"label_attr" => array( "label_attr" => array(
"for" => "email" "for" => "email"
)
))
->add("account", "choice", array(
"constraints" => array(
new Constraints\Callback(array(
"methods" => array(
array($this, "verifyAccount")
)
))
), ),
"required" => true "choices" => array(
0 => Translator::getInstance()->trans("No, I am a new customer."),
1 => Translator::getInstance()->trans("Yes, I have a password :")
),
"label_attr" => array(
"for" => "account"
),
"data" => 0
)) ))
->add("password", "password", array( ->add("password", "password", array(
"constraints" => array( /*"constraints" => array(
new NotBlank() new Constraints\NotBlank()
), ),*/
"label" => Translator::getInstance()->trans("Please enter your password"), "label" => Translator::getInstance()->trans("Please enter your password"),
"label_attr" => array( "label_attr" => array(
"for" => "password" "for" => "password"
), ),
"required" => true "required" => false
)) ));
->add("remember_me", "checkbox") }
;
/**
* If the user select "Yes, I have a password", we check the password.
*/
public function verifyAccount($value, ExecutionContextInterface $context)
{
if ($value == 1) {
$data = $context->getRoot()->getData();
if (false === $data['password'] || (empty($data['password']) && '0' != $data['password'])) {
$context->getViolations()->add(new ConstraintViolation(
'This value should not be blank.',
'account_password',
array(),
$context->getRoot(),
'children[password].data',
'propertyPath'
));
}
}
}
/**
* If the user select "I'am a new customer", we make sure is email address does not exit in the database.
*/
public function verifyExistingEmail($value, ExecutionContextInterface $context)
{
$data = $context->getRoot()->getData();
if ($data["account"] == 0) {
$customer = CustomerQuery::create()->findOneByEmail($value);
if ($customer) {
$context->addViolation("A user already exists with this email address. Please login or if you've forgotten your password, go to Reset Your Password.");
}
}
} }
public function getName() public function getName()

View File

@@ -82,7 +82,7 @@ class CustomerLostPasswordForm extends BaseForm
{ {
$customer = CustomerQuery::create()->findOneByEmail($value); $customer = CustomerQuery::create()->findOneByEmail($value);
if (null === $customer) { if (null === $customer) {
$context->addViolation("This email does not exists exists"); $context->addViolation("This email does not exists");
} }
} }

View File

@@ -0,0 +1,75 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Form;
use Symfony\Component\Validator\Constraints;
use Thelia\Model\ConfigQuery;
use Thelia\Core\Translation\Translator;
/**
* Class CustomerUpdateForm
* @package Thelia\Form
* @author Christophe Laffont <claffont@openstudio.fr>
*/
class CustomerUpdateForm extends CustomerCreation
{
protected function buildForm()
{
parent::buildForm();
$this->formBuilder
->remove("auto_login")
// Remove From Personal Informations
->remove("phone")
->remove("cellphone")
// Remove Delivery Informations
->remove("company")
->remove("address1")
->remove("address2")
->remove("address3")
->remove("city")
->remove("zipcode")
->remove("country")
// Remove Login Information
->remove("password")
->remove("password_confirm")
// Remove Terms & conditions
->remove("agreed")
// Add Newsletter
->add("newsletter", "checkbox", array(
"label" => "I would like to receive the newsletter our the latest news.",
"label_attr" => array(
"for" => "newsletter"
),
"required" => false
));
}
public function getName()
{
return "thelia_customer_update";
}
}

View File

@@ -0,0 +1,58 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Form;
use Symfony\Component\Validator\Constraints\NotBlank;
use Thelia\Core\Translation\Translator;
class LanguageCreationForm extends BaseForm
{
protected function buildForm()
{
$this->formBuilder
->add("title", "text", array(
"constraints" => array(
new NotBlank()
),
"label" => Translator::getInstance()->trans("Language title *"),
"label_attr" => array(
"for" => "title"
)
))
->add("isocode", "text", array(
"constraints" => array(
new NotBlank()
),
"label" => Translator::getInstance()->trans("ISO Code *"),
"label_attr" => array(
"for" => "isocode"
)
))
;
}
public function getName()
{
return "thelia_language_creation";
}
}

View File

@@ -64,8 +64,8 @@ class TaxCreationForm extends BaseForm
foreach($requirementList as $type => $requirements) { foreach($requirementList as $type => $requirements) {
foreach($requirements as $name => $requirementType) { foreach($requirements as $name => $requirementType) {
$this->formBuilder $this->formBuilder
->add($type . '_' . $name, new TheliaType(), array( ->add($type . ':' . $name, new TheliaType(), array(
"instance" => $requirementType, //"instance" => $requirementType,
"constraints" => array( "constraints" => array(
new Constraints\Callback( new Constraints\Callback(
array( array(
@@ -77,8 +77,6 @@ class TaxCreationForm extends BaseForm
), ),
"attr" => array( "attr" => array(
"tag" => "requirements", "tag" => "requirements",
),
"data" => array(
"tax_type" => $type, "tax_type" => $type,
), ),
"label" => Translator::getInstance()->trans($name), "label" => Translator::getInstance()->trans($name),
@@ -96,11 +94,4 @@ class TaxCreationForm extends BaseForm
{ {
return "thelia_tax_creation"; return "thelia_tax_creation";
} }
public function verifyForm($value, ExecutionContextInterface $context)
{
$in = true;
//$this->getForm()->getChildren()
}
} }

View File

@@ -36,7 +36,11 @@ trait ModelEventDispatcherTrait {
*/ */
protected $dispatcher = null; protected $dispatcher = null;
/**
* @param EventDispatcherInterface $dispatcher
*
* @return $this
*/
public function setDispatcher(EventDispatcherInterface $dispatcher) public function setDispatcher(EventDispatcherInterface $dispatcher)
{ {
$this->dispatcher = $dispatcher; $this->dispatcher = $dispatcher;

View File

@@ -59,7 +59,7 @@ class RewritingResolver
public function load($rewrittenUrl) public function load($rewrittenUrl)
{ {
$rewrittenUrl = ltrim($rewrittenUrl, '/'); $rewrittenUrl = ltrim($rewrittenUrl, '/');
$rewrittenUrl = urldecode($rewrittenUrl);
$this->search = $this->rewritingUrlQuery->getResolverSearch($rewrittenUrl); $this->search = $this->rewritingUrlQuery->getResolverSearch($rewrittenUrl);
if($this->search->count() == 0) { if($this->search->count() == 0) {

View File

@@ -40,7 +40,7 @@ abstract class BaseType implements TypeInterface
public function verifyForm($value, ExecutionContextInterface $context) public function verifyForm($value, ExecutionContextInterface $context)
{ {
if( ! $this->isValid($value) ) { if( ! $this->isValid($value) ) {
$context->addViolation("Thelia Type not matched"); $context->addViolation(sprintf("received value `%s` does not match `%s` type", $value, $this->getType()));
} }
} }
} }

View File

@@ -45,13 +45,17 @@ class DebugBarListeners extends BaseAction implements EventSubscriberInterface {
{ {
$debugBar = $this->container->get("debugBar"); $debugBar = $this->container->get("debugBar");
$alternativelogger = null;
if($this->container->getParameter('kernel.debug')) {
$alternativelogger = \Thelia\Log\Tlog::getInstance();
}
$debugBar->addCollector(new PhpInfoCollector()); $debugBar->addCollector(new PhpInfoCollector());
//$debugBar->addCollector(new MessagesCollector()); //$debugBar->addCollector(new MessagesCollector());
//$debugBar->addCollector(new RequestDataCollector()); //$debugBar->addCollector(new RequestDataCollector());
$debugBar->addCollector(new TimeDataCollector()); $debugBar->addCollector(new TimeDataCollector());
$debugBar->addCollector(new MemoryCollector()); $debugBar->addCollector(new MemoryCollector());
$debugBar->addCollector(new PropelCollector(\Thelia\Log\Tlog::getInstance())); $debugBar->addCollector(new PropelCollector($alternativelogger));
} }
/** /**

View File

@@ -56,7 +56,7 @@
<div class="row"> <div class="row">
<div class="col-md-12 clearfix"> <div class="col-md-12 clearfix">
<div class="version-info pull-left">{intl l='Version %ver' ver="{$THELIA_VERSION}"}</div> <div class="version-info pull-left">{intl l='Version %ver' ver="{$THELIA_VERSION}"}</div>
<div class="clearfix pull-right hidden-xs"> <div class="clearfix pull-right hidden-xs">
<div class="btn-group pull-right"> <div class="btn-group pull-right">
<a href="{navigate to="index"}" title="{intl l='View site'}" target="_blank" class="btn btn-default"><span class="glyphicon glyphicon-eye-open"></span> {intl l="View shop"}</a> <a href="{navigate to="index"}" title="{intl l='View site'}" target="_blank" class="btn btn-default"><span class="glyphicon glyphicon-eye-open"></span> {intl l="View shop"}</a>
@@ -74,7 +74,7 @@
</div> </div>
{module_include location='inside_topbar'} {module_include location='inside_topbar'}
</div> </div>
</div> </div>
@@ -89,7 +89,7 @@
<nav class="navbar navbar-default" role="navigation"> <nav class="navbar navbar-default" role="navigation">
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="navbar-header"> <div class="navbar-header">
<button type="button" class="btn navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <button type="button" class="btn navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">

View File

@@ -0,0 +1,219 @@
{extends file="admin-layout.tpl"}
{block name="page-title"}{intl l='Admin profiles'}{/block}
{block name="check-permissions"}admin.admin-profiles.view{/block}
{block name="main-content"}
<div class="admin-profiles">
<div id="wrapper" class="container">
<div class="clearfix">
<ul class="breadcrumb pull-left">
<li><a href="{url path='/admin/home'}">{intl l="Home"}</a></li>
<li><a href="{url path='/admin/configuration'}">{intl l="Configuration"}</a></li>
<li><a href="{url path='/admin/configuration/admin_profiles'}">{intl l="Admin profiles"}</a></li>
</ul>
{loop type="auth" name="can_create" roles="ADMIN" permissions="admin.admin-profiles.create"}
<a class="btn btn-default btn-primary pull-right" title="{intl l='Create a new admin profile'}" href="#creation_dialog" data-toggle="modal">
<span class="glyphicon glyphicon-plus"></span>
</a>
{/loop}
</div>
{module_include location='admin_profiles_top'}
<div class="row">
<div class="col-md-12">
<div class="general-block-decorator">
<div class="table-responsive">
<form action="">
<table class="table table-striped table-condensed table-left-aligned">
<caption>
{intl l="Profile"}
</caption>
<tbody>
<tr>
<td><label for="" class="label-control">{intl l="Profile"}</label></td>
<td>
<select name="" id="" data-toggle="selectpicker">
<option value="">1</option>
<option value="">2</option>
<option value="">3</option>
</select>
</td>
</tr>
<tr>
<td><label for="" class="label-control">{intl l="Wording"}</label></td>
<td><input type="text" class="form-control" name="" value="gestionnairecommande" readonly></td>
</tr>
<tr>
<td><label for="" class="label-control">{intl l="Name"}</label></td>
<td><input type="text" class="form-control" name="" value=""></td>
</tr>
<tr>
<td><label for="" class="label-control">{intl l="Description"}</label></td>
<td><textarea type="text" class="form-control" name=""></textarea></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2">
<div class="btn-group pull-right">
<button type="submit" class="btn btn-default btn-primary"><span class="glyphicon glyphicon-check"></span> {intl l="Save"}</button>
<button class="btn btn-default"><span class="glyphicon glyphicon-trash"></span> {intl l="Delete"}</button>
</div>
</td>
</tr>
</tfoot>
</table>
</form>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="general-block-decorator">
<div class="table-responsive">
<form action="">
<table class="table table-striped table-condensed table-left-aligned">
<caption>
{intl l="General rights"}
</caption>
<thead>
<tr>
<th>{intl l="Authorization"}</th>
<th>{intl l="Description"}</th>
<th>{intl l="Access"}</th>
</tr>
</thead>
<tbody>
<tr>
<td>Access to customers</td>
<td>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aspernatur, saepe, libero, veniam ab quod.
</td>
<td>
<div class="make-switch switch-small" data-on="success" data-off="danger" data-on-label="<i class='glyphicon glyphicon-ok'></i>" data-off-label="<i class='glyphicon glyphicon-remove'></i>">
<input type="checkbox" checked>
</div>
</td>
</tr>
<tr>
<td>Access to orders</td>
<td>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aspernatur, saepe, libero, veniam ab quod.
</td>
<td>
<div class="make-switch switch-small" data-on="success" data-off="danger" data-on-label="<i class='glyphicon glyphicon-ok'></i>" data-off-label="<i class='glyphicon glyphicon-remove'></i>">
<input type="checkbox">
</div>
</td>
</tr>
<tr>
<td>Access to catalog</td>
<td>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aspernatur, saepe, libero, veniam ab quod.
</td>
<td>
<div class="make-switch switch-small" data-on="success" data-off="danger" data-on-label="<i class='glyphicon glyphicon-ok'></i>" data-off-label="<i class='glyphicon glyphicon-remove'></i>">
<input type="checkbox">
</div>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="3">
<button type="submit" class="btn btn-default btn-primary pull-right"><span class="glyphicon glyphicon-check"></span> {intl l="Save"}</button>
</td>
</tr>
</tfoot>
</table>
</form>
</div>
</div>
</div>
</div>
{module_include location='admin_profiles_bottom'}
</div>
</div>
{* Creation dialog *}
{form name="thelia.admin.admin-profile.creation"}
{* Capture the dialog body, to pass it to the generic dialog *}
{capture "creation_dialog"}
{form_hidden_fields form=$form}
{* Be sure to get the language_id, even if the form could not be validated *}
<input type="hidden" name="language_id" value="{$language_id}" />
{form_field form=$form field='success_url'}
{* on success, redirect to the edition page, _ID_ is replaced with the created object ID, see controller *}
<input type="hidden" name="{$name}" value="{url path='/admin/configuration/admin_profile/update' admin_profile_id='_ID_'}" />
{/form_field}
{form_field form=$form field='wording'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l="{$label}"} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" title="{intl l="{$label}"}" placeholder="{intl l='Wording'}">
</div>
{/form_field}
{form_field form=$form field='name'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l="{$label}"} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" title="{intl l="{$label}"}" placeholder="{intl l='Name'}">
</div>
{/form_field}
{form_field form=$form field='description'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l="{$label}"} : </label>
<textarea id="{$label_attr.for}" name="{$name}" class="form-control" title="{intl l="{$label}"}" placeholder="{intl l='Description'}"></textarea>
</div>
{/form_field}
{module_include location='admin_profile_create_form'}
{/capture}
{include
file = "includes/generic-create-dialog.html"
dialog_id = "creation_dialog"
dialog_title = {intl l="Create a new admin profile"}
dialog_body = {$smarty.capture.creation_dialog nofilter}
dialog_ok_label = {intl l="Create this admin profile"}
form_action = {url path='/admin/configuration/admin_profile/create'}
form_enctype = {form_enctype form=$form}
form_error_message = $form_error_message
}
{/form}
{/block}
{block name="javascript-initialization"}
{javascripts file='assets/js/bootstrap-switch/bootstrap-switch.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap-select/bootstrap-select.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/main.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{/block}

View File

@@ -17,6 +17,9 @@
} }
} }
.navbar-nav > li:hover{
background-color: @active-menu;
}
} }
// Inner for background effects // Inner for background effects
@@ -33,7 +36,7 @@
// Navbar button for toggling navbar items in responsive layouts // Navbar button for toggling navbar items in responsive layouts
// These definitions need to come after '.navbar .btn' // These definitions need to come after '.navbar .btn'
.navbar .btn { .navbar .btn {
.button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border); .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border);
} }
.navbar-default .navbar-toggle .icon-bar{ .navbar-default .navbar-toggle .icon-bar{

View File

@@ -13,6 +13,9 @@
@brand-primary: #f39922; @brand-primary: #f39922;
// Nav
// -------------------------
@active-menu: #eeeeee;
// Links // Links
// ------------------------- // -------------------------

View File

@@ -5,180 +5,180 @@
{block name="check-permissions"}admin.configuration.view{/block} {block name="check-permissions"}admin.configuration.view{/block}
{block name="main-content"} {block name="main-content"}
<div class="configuration"> <div class="configuration">
<div id="wrapper" class="container"> <div id="wrapper" class="container">
{module_include location='configuration_top'} {module_include location='configuration_top'}
<h2>{intl l="Thelia configuration"}</h2> <h2>{intl l="Thelia configuration"}</h2>
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-4">
<div class="menu-list-table general-block-decorator"> <div class="menu-list-table general-block-decorator">
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-striped table-condensed"> <table class="table table-striped table-condensed">
<caption>{intl l='Product catalog configuration'}</caption> <caption>{intl l='Product catalog configuration'}</caption>
{module_include location='catalog_configuration_top'} {module_include location='catalog_configuration_top'}
{loop type="auth" name="pcc1" roles="ADMIN" permissions="admin.configuration.templates"} {loop type="auth" name="pcc1" roles="ADMIN" permissions="admin.configuration.templates"}
<tr> <tr>
<td><a href="{url path='/admin/configuration/templates'}">{intl l='Product templates'}</a></td> <td><a href="{url path='/admin/configuration/templates'}">{intl l='Product templates'}</a></td>
<td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/templates'}"><i class="glyphicon glyphicon-edit"></i></a></td> <td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/templates'}"><i class="glyphicon glyphicon-edit"></i></a></td>
</tr> </tr>
{/loop} {/loop}
{loop type="auth" name="pcc2" roles="ADMIN" permissions="admin.configuration.attributes"} {loop type="auth" name="pcc2" roles="ADMIN" permissions="admin.configuration.attributes"}
<tr> <tr>
<td><a href="{url path='/admin/configuration/attributes'}">{intl l='Product attributes'}</a></td> <td><a href="{url path='/admin/configuration/attributes'}">{intl l='Product attributes'}</a></td>
<td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/attributes'}"><i class="glyphicon glyphicon-edit"></i></a></td> <td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/attributes'}"><i class="glyphicon glyphicon-edit"></i></a></td>
</tr> </tr>
{/loop} {/loop}
{loop type="auth" name="pcc3" roles="ADMIN" permissions="admin.configuration.features"} {loop type="auth" name="pcc3" roles="ADMIN" permissions="admin.configuration.features"}
<tr> <tr>
<td><a href="{url path='/admin/configuration/features'}">{intl l='Product features'}</a></td> <td><a href="{url path='/admin/configuration/features'}">{intl l='Product features'}</a></td>
<td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/features'}"><i class="glyphicon glyphicon-edit"></i></a></td> <td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/features'}"><i class="glyphicon glyphicon-edit"></i></a></td>
</tr> </tr>
{/loop} {/loop}
{loop type="auth" name="pcc4" roles="ADMIN" permissions="admin.configuration.messages"} {loop type="auth" name="pcc4" roles="ADMIN" permissions="admin.configuration.messages"}
<tr> <tr>
<td><a href="{url path='/admin/configuration/messages'}">{intl l='Mailing templates'}</a></td> <td><a href="{url path='/admin/configuration/messages'}">{intl l='Mailing templates'}</a></td>
<td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/messages'}"><i class="glyphicon glyphicon-edit"></i></a></td> <td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/messages'}"><i class="glyphicon glyphicon-edit"></i></a></td>
</tr> </tr>
{/loop} {/loop}
{loop type="auth" name="pcc5" roles="ADMIN" permissions="admin.configuration.currencies"} {loop type="auth" name="pcc5" roles="ADMIN" permissions="admin.configuration.currencies"}
<tr> <tr>
<td><a href="{url path='/admin/configuration/currencies'}">{intl l='Currencies'}</a></td> <td><a href="{url path='/admin/configuration/currencies'}">{intl l='Currencies'}</a></td>
<td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/currencies'}"><i class="glyphicon glyphicon-edit"></i></a></td> <td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/currencies'}"><i class="glyphicon glyphicon-edit"></i></a></td>
</tr> </tr>
{/loop} {/loop}
{loop type="auth" name="pcc6" roles="ADMIN" permissions="admin.configuration.taxe-rules"} {loop type="auth" name="pcc6" roles="ADMIN" permissions="admin.configuration.taxe-rules"}
<tr> <tr>
<td><a href="{url path='/admin/configuration/taxes_rules'}">{intl l='Taxes rules'}</a></td> <td><a href="{url path='/admin/configuration/taxes_rules'}">{intl l='Taxes rules'}</a></td>
<td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/taxes_rules'}"><i class="glyphicon glyphicon-edit"></i></a></td> <td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/taxes_rules'}"><i class="glyphicon glyphicon-edit"></i></a></td>
</tr> </tr>
{/loop} {/loop}
{module_include location='catalog_configuration_bottom'} {module_include location='catalog_configuration_bottom'}
</table> </table>
</div> </div>
</div> </div>
</div> </div>
<div class="col-md-4"> <div class="col-md-4">
<div class="menu-list-table general-block-decorator"> <div class="menu-list-table general-block-decorator">
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-striped table-condensed"> <table class="table table-striped table-condensed">
<caption>{intl l='Shipping configuration'}</caption> <caption>{intl l='Shipping configuration'}</caption>
{module_include location='shipping_configuration_top'} {module_include location='shipping_configuration_top'}
{loop type="auth" name="pcc1" roles="ADMIN" permissions="admin.configuration.contries"} {loop type="auth" name="pcc1" roles="ADMIN" permissions="admin.configuration.contries"}
<tr> <tr>
<td><a href="{url path='/admin/configuration/countries'}">{intl l='Countries'}</a></td> <td><a href="{url path='/admin/configuration/countries'}">{intl l='Countries'}</a></td>
<td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/countries'}"><i class="glyphicon glyphicon-edit"></i></a></td> <td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/countries'}"><i class="glyphicon glyphicon-edit"></i></a></td>
</tr> </tr>
{/loop} {/loop}
{loop type="auth" name="pcc2" roles="ADMIN" permissions="admin.configuration.shipping_zones"} {loop type="auth" name="pcc2" roles="ADMIN" permissions="admin.configuration.shipping_zones"}
<tr> <tr>
<td><a href="{url path='/admin/configuration/shipping_zones'}">{intl l='Shipping zones'}</a></td> <td><a href="{url path='/admin/configuration/shipping_zones'}">{intl l='Shipping zones'}</a></td>
<td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/shipping_zones'}"><i class="glyphicon glyphicon-edit"></i></a></td> <td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/shipping_zones'}"><i class="glyphicon glyphicon-edit"></i></a></td>
</tr> </tr>
{/loop} {/loop}
{loop type="auth" name="pcc3" roles="ADMIN" permissions="admin.configuration.shipping_configuration"} {loop type="auth" name="pcc3" roles="ADMIN" permissions="admin.configuration.shipping_configuration"}
<tr> <tr>
<td><a href="{url path='/admin/configuration/shipping_configuration'}">{intl l='Shipping configuration'}</a></td> <td><a href="{url path='/admin/configuration/shipping_configuration'}">{intl l='Shipping configuration'}</a></td>
<td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/shipping_configuration'}"><i class="glyphicon glyphicon-edit"></i></a></td> <td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/shipping_configuration'}"><i class="glyphicon glyphicon-edit"></i></a></td>
</tr> </tr>
{/loop} {/loop}
{module_include location='shipping_configuration_bottom'} {module_include location='shipping_configuration_bottom'}
</table> </table>
</div> </div>
</div> </div>
</div> </div>
<div class="col-md-4"> <div class="col-md-4">
<div class="menu-list-table general-block-decorator"> <div class="menu-list-table general-block-decorator">
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-striped table-condensed"> <table class="table table-striped table-condensed">
<caption>{intl l='System parameters'}</caption> <caption>{intl l='System parameters'}</caption>
{module_include location='system_configuration_top'} {module_include location='system_configuration_top'}
{loop type="auth" name="pcc1" roles="ADMIN" permissions="admin.configuration.modules"} {loop type="auth" name="pcc1" roles="ADMIN" permissions="admin.configuration.modules"}
<tr> <tr>
<td><a href="{url path='/admin/configuration/modules'}">{intl l='Modules activation'}</a></td> <td><a href="{url path='/admin/configuration/modules'}">{intl l='Modules activation'}</a></td>
<td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/modules'}"><i class="glyphicon glyphicon-edit"></i></a></td> <td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/modules'}"><i class="glyphicon glyphicon-edit"></i></a></td>
</tr> </tr>
{/loop} {/loop}
{loop type="auth" name="pcc2" roles="ADMIN" permissions="admin.configuration.variables"} {loop type="auth" name="pcc2" roles="ADMIN" permissions="admin.configuration.variables"}
<tr> <tr>
<td><a href="{url path='/admin/configuration/variables'}">{intl l='System variables'}</a></td> <td><a href="{url path='/admin/configuration/variables'}">{intl l='System variables'}</a></td>
<td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/variables'}"><i class="glyphicon glyphicon-edit"></i></a></td> <td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/variables'}"><i class="glyphicon glyphicon-edit"></i></a></td>
</tr> </tr>
{/loop} {/loop}
{loop type="auth" name="pcc3" roles="ADMIN" permissions="admin.configuration.admin_profiles"} {loop type="auth" name="pcc3" roles="ADMIN" permissions="admin.configuration.admin_profiles"}
<tr> <tr>
<td><a href="{url path='/admin/configuration/admin_profiles'}">{intl l='Back-office profiles'}</a></td> <td><a href="{url path='/admin/configuration/admin_profiles'}">{intl l='Back-office profiles'}</a></td>
<td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/admin_profiles'}"><i class="glyphicon glyphicon-edit"></i></a></td> <td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/admin_profiles'}"><i class="glyphicon glyphicon-edit"></i></a></td>
</tr> </tr>
{/loop} {/loop}
{loop type="auth" name="pcc4" roles="ADMIN" permissions="admin.configuration.admin_users"} {loop type="auth" name="pcc4" roles="ADMIN" permissions="admin.configuration.admin_users"}
<tr> <tr>
<td><a href="{url path='/admin/configuration/admin_users'}">{intl l='Back-office users'}</a></td> <td><a href="{url path='/admin/configuration/admin_users'}">{intl l='Back-office users'}</a></td>
<td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/admin_users'}"><i class="glyphicon glyphicon-edit"></i></a></td> <td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/admin_users'}"><i class="glyphicon glyphicon-edit"></i></a></td>
</tr> </tr>
{/loop} {/loop}
{loop type="auth" name="pcc5" roles="ADMIN" permissions="admin.configuration.languages"} {loop type="auth" name="pcc5" roles="ADMIN" permissions="admin.configuration.languages"}
<tr> <tr>
<td><a href="{url path='/admin/configuration/languages'}">{intl l='Languages &amp; URLs'}</a></td> <td><a href="{url path='/admin/configuration/languages'}">{intl l='Languages &amp; URLs'}</a></td>
<td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/languages'}"><i class="glyphicon glyphicon-edit"></i></a></td> <td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/languages'}"><i class="glyphicon glyphicon-edit"></i></a></td>
</tr> </tr>
{/loop} {/loop}
{loop type="auth" name="pcc6" roles="ADMIN" permissions="admin.configuration.mailing_system"} {loop type="auth" name="pcc6" roles="ADMIN" permissions="admin.configuration.mailing_system"}
<tr> <tr>
<td><a href="{url path='/admin/configuration/mailing_system'}">{intl l='Mailing system'}</a></td> <td><a href="{url path='/admin/configuration/mailing_system'}">{intl l='Mailing system'}</a></td>
<td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/mailing_system'}"><i class="glyphicon glyphicon-edit"></i></a></td> <td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/mailing_system'}"><i class="glyphicon glyphicon-edit"></i></a></td>
</tr> </tr>
{/loop} {/loop}
{loop type="auth" name="pcc7" roles="ADMIN" permissions="admin.configuration.admin_logs"} {loop type="auth" name="pcc7" roles="ADMIN" permissions="admin.configuration.admin_logs"}
<tr> <tr>
<td><a href="{url path='/admin/configuration/admin_logs'}">{intl l='Administration logs'}</a></td> <td><a href="{url path='/admin/configuration/admin_logs'}">{intl l='Administration logs'}</a></td>
<td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/admin_logs'}"><i class="glyphicon glyphicon-edit"></i></a></td> <td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/admin_logs'}"><i class="glyphicon glyphicon-edit"></i></a></td>
</tr> </tr>
{/loop} {/loop}
{loop type="auth" name="pcc8" roles="ADMIN" permissions="admin.configuration.system_logs"} {loop type="auth" name="pcc8" roles="ADMIN" permissions="admin.configuration.system_logs"}
<tr> <tr>
<td><a href="{url path='/admin/configuration/system_logs'}">{intl l='System logs'}</a></td> <td><a href="{url path='/admin/configuration/system_logs'}">{intl l='System logs'}</a></td>
<td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/system_logs'}"><i class="glyphicon glyphicon-edit"></i></a></td> <td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/system_logs'}"><i class="glyphicon glyphicon-edit"></i></a></td>
</tr> </tr>
{/loop} {/loop}
{module_include location='system_configuration_bottom'} {module_include location='system_configuration_bottom'}
</table> </table>
</div> </div>
</div> </div>
</div> </div>
{module_include location='configuration_bottom'} {module_include location='configuration_bottom'}
</div> </div>
</div> </div>
</div> </div>
{/block} {/block}

View File

@@ -0,0 +1,272 @@
{extends file="admin-layout.tpl"}
{block name="page-title"}{intl l='Thelia Languages'}{/block}
{block name="check-permissions"}admin.configuration.languages.view{/block}
{block name="main-content"}
<div class="languages">
<div id="wrapper" class="container">
<ul class="breadcrumb">
<li><a href="{url path='/admin/home'}">{intl l="Home"}</a></li>
<li><a href="{url path='/admin/configuration'}">{intl l="Configuration"}</a></li>
<li><a href="{url path='/admin/configuration/languages'}">{intl l="Languages"}</a></li>
</ul>
{module_include location='languages_top'}
<div class="row">
<div class="col-md-6">
<div class="general-block-decorator">
<form action="" method="">
<table class="table table-striped table-condensed table-left-aligned">
<caption>
{intl l="Languages management"}
{loop type="auth" name="can_create" roles="ADMIN" permissions="admin.configuration.languages.create"}
<a class="btn btn-default btn-primary action-btn" title="{intl l='Add a new language'}" href="#creation_dialog" data-toggle="modal">
<span class="glyphicon glyphicon-plus-sign"></span>
</a>
{/loop}
</caption>
<thead>
<tr>
<th>{intl l="Language name"}</th>
<th>{intl l="ISO 639 Code"}</th>
<th>{intl l="Default"}</th>
<th>{intl l="Actions"}</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text" class="form-control" name="" value="France"></td>
<td><input type="text" class="form-control" name="" value="fr"></td>
<td>
<div class="make-switch switch-small switch-radio" data-on="success" data-off="danger" data-on-label="<i class='glyphicon glyphicon-ok'></i>" data-off-label="<i class='glyphicon glyphicon-remove'></i>">
<input type="radio" name="" checked>
</div>
</td>
<td>
<div class="btn-group">
<a href="#delete_dialog" data-toggle="modal" class="btn btn-default btn-xs" title="{intl l="Delete this language"}"><span class="glyphicon glyphicon-trash"></span></a>
</div>
</td>
</tr>
<tr>
<td><input type="text" class="form-control" name="" value="English"></td>
<td><input type="text" class="form-control" name="" value="en"></td>
<td>
<div class="make-switch switch-small switch-radio" data-on="success" data-off="danger" data-on-label="<i class='glyphicon glyphicon-ok'></i>" data-off-label="<i class='glyphicon glyphicon-remove'></i>">
<input type="radio" name="">
</div>
</td>
<td>
<div class="btn-group">
<a href="#delete_dialog" data-toggle="modal" class="btn btn-default btn-xs" title="{intl l="Delete this language"}"><span class="glyphicon glyphicon-trash"></span></a>
</div>
</td>
</tr>
<tr>
<td><input type="text" class="form-control" name="" value="Spanish"></td>
<td><input type="text" class="form-control" name="" value="es"></td>
<td>
<div class="make-switch switch-small switch-radio" data-on="success" data-off="danger" data-on-label="<i class='glyphicon glyphicon-ok'></i>" data-off-label="<i class='glyphicon glyphicon-remove'></i>">
<input type="radio" name="">
</div>
</td>
<td>
<div class="btn-group">
<a href="#delete_dialog" data-toggle="modal" class="btn btn-default btn-xs" title="{intl l="Delete this language"}"><span class="glyphicon glyphicon-trash"></span></a>
</div>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="4">
<button type="submit" class="btn btn-default btn-primary pull-right"><span class="glyphicon glyphicon-check"></span> {intl l="Save"}</button>
</td>
</tr>
</tfoot>
</table>
</form>
</div>
</div>
<div class="col-md-6">
<div class="general-block-decorator">
<div class="title title-without-tabs">{intl l="Parameters"}</div>
<form action="" method="post">
<div class="form-group">
<label for="" class="label-control">{intl l="If a translation is missing or incomplete :"}</label>
<div class="input-group">
<select name="" id="" data-toggle="selectpicker">
<option value="">Replace by the default language</option>
<option value="">Strictly use the requested language</option>
</select>
<div class="input-group-btn">
<button type="submit" class="btn btn-default btn-primary"><span class="glyphicon glyphicon-check"></span></button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="general-block-decorator clearfix">
<div class="title title-without-tabs">{intl l="Association language/URL"}</div>
<form action="" method="post">
<div class="col-md-6">
<div class="form-group">
<label for="" class="label-control"><input type="radio" name="" checked> {intl l="Using a same domain for all languages"}</label>
<input type="url" class="form-control" name="" placeholder="http://www.domain.com">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="" class="label-control"><input type="radio" name=""> {intl l="Using a domain or subdomain for each language"}</label>
</div>
<table class="table table-striped table-condensed table-left-aligned">
<tbody>
<tr>
<th>{intl l="France"}</th>
<td><input type="text" class="form-control" name="" placeholder="http://www.domain.com" readonly></td>
</tr>
<tr>
<th>{intl l="English"}</th>
<td><input type="text" class="form-control" name="" placeholder="http://www.domain.com" readonly></td>
</tr>
<tr>
<th>{intl l="Spanish"}</th>
<td><input type="text" class="form-control" name="" placeholder="http://www.domain.com" readonly></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2">
<button type="submit" disabled class="btn btn-default btn-primary pull-right"><span class="glyphicon glyphicon-check"></span> {intl l="Save"}</button>
</td>
</tr>
</tfoot>
</table>
</div>
</form>
</div>
</div>
</div>
{module_include location='languages_bottom'}
</div>
</div>
{form name="thelia.admin.language.creation"}
{* Capture the dialog body, to pass it to the generic dialog *}
{capture "creation_dialog"}
{form_hidden_fields form=$form}
{* Be sure to get the language_id, even if the form could not be validated *}
<input type="hidden" name="language_id" value="{$language_id}" />
{form_field form=$form field='success_url'}
{* on success, redirect to the edition page, _ID_ is replaced with the created object ID, see controller *}
<input type="hidden" name="{$name}" value="{url path='/admin/configuration/languages/update' language_id='_ID_'}" />
{/form_field}
{form_field form=$form field='title'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l="{$label}"} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l="{$label}"}" placeholder="{intl l='Language title'}">
</div>
{/form_field}
{form_field form=$form field='isocode'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l="{$label}"} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l="{$label}"}" placeholder="{intl l='ISO Code'}">
</div>
{/form_field}
{module_include location='language_create_form'}
{/capture}
{include
file = "includes/generic-create-dialog.html"
dialog_id = "creation_dialog"
dialog_title = {intl l="Create a new language"}
dialog_body = {$smarty.capture.creation_dialog nofilter}
dialog_ok_label = {intl l="Create this language"}
form_action = {url path='/admin/configuration/languages/create'}
form_enctype = {form_enctype form=$form}
form_error_message = $form_error_message
}
{/form}
{* Delete confirmation dialog *}
{capture "delete_dialog"}
<input type="hidden" name="message_id" id="language_delete_id" value="" />
{module_include location='languages_delete_form'}
{/capture}
{include
file = "includes/generic-confirm-dialog.html"
dialog_id = "delete_dialog"
dialog_title = {intl l="Delete language"}
dialog_message = {intl l="Do you really want to delete this language ?"}
form_action = {url path='/admin/configuration/languages/delete'}
form_content = {$smarty.capture.delete_dialog nofilter}
}
{/block}
{block name="javascript-initialization"}
{javascripts file='assets/js/bootstrap-switch/bootstrap-switch.js'}
<script src="{$asset_url}"></script>
<script>
// Toogle switch on input radio
$('.switch-radio').on('switch-change', function () {
$('.switch-radio').bootstrapSwitch('toggleRadioState');
});
</script>
{/javascripts}
{javascripts file='assets/js/main.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap-select/bootstrap-select.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{/block}

View File

@@ -0,0 +1,102 @@
{extends file="admin-layout.tpl"}
{block name="page-title"}{intl l='Thelia Mailing System'}{/block}
{block name="check-permissions"}admin.configuration.mailing-system.view{/block}
{block name="main-content"}
<div class="mailing-system">
<div id="wrapper" class="container">
<ul class="breadcrumb">
<li><a href="{url path='/admin/home'}">{intl l="Home"}</a></li>
<li><a href="{url path='/admin/configuration'}">{intl l="Configuration"}</a></li>
<li><a href="{url path='/admin/configuration/mailing_system'}">{intl l="Mailing system"}</a></li>
</ul>
{module_include location='mailing_system_top'}
<div class="row">
<div class="col-md-12">
<div class="general-block-decorator">
<div class="title title-without-tabs">{intl l="Configuration variables"}</div>
<form action="" method="">
<div class="form-group">
<label for="" class="label-control">{intl l="SMTP Server"}</label>
<div class="input-group">
<input type="text" class="form-control" name="" placeholder="{intl l="SMTP Server"}">
<span class="input-group-btn">
<button class="btn btn-default btn-primary"><span class="glyphicon glyphicon-remove"></span></button>
</span>
</div>
</div>
<div class="form-group">
<label for="" class="label-control">{intl l="Port"}</label>
<div class="input-group">
<input type="text" class="form-control" name="" placeholder="{intl l="port"}">
<span class="input-group-btn">
<button class="btn btn-default btn-primary"><span class="glyphicon glyphicon-remove"></span></button>
</span>
</div>
</div>
<div class="form-group">
<label for="" class="label-control">{intl l="Username"}</label>
<div class="input-group">
<input type="text" class="form-control" name="" placeholder="{intl l="username"}">
<span class="input-group-btn">
<button class="btn btn-default btn-primary"><span class="glyphicon glyphicon-remove"></span></button>
</span>
</div>
</div>
<div class="form-group">
<label for="" class="label-control">{intl l="Password"}</label>
<div class="input-group">
<input type="password" class="form-control" name="" placeholder="{intl l="password"}">
<span class="input-group-btn">
<button class="btn btn-default btn-primary"><span class="glyphicon glyphicon-remove"></span></button>
</span>
</div>
</div>
<div class="form-group">
<label for="" class="label-control">{intl l="Protocol"}</label>
<div class="input-group">
<input type="text" class="form-control" name="" placeholder="{intl l="protocol"}">
<span class="input-group-btn">
<button class="btn btn-default btn-primary"><span class="glyphicon glyphicon-remove"></span></button>
</span>
</div>
</div>
<div class="form-group">
<label for="" class="label-control">{intl l="Active ?"}</label>
<div class="make-switch switch-small" data-on="success" data-off="danger" data-on-label="<i class='glyphicon glyphicon-ok'></i>" data-off-label="<i class='glyphicon glyphicon-remove'></i>">
<input type="checkbox" name="" id="" checked>
</div>
</div>
</form>
</div>
</div>
</div>
{module_include location='mailing_system_bottom'}
</div>
</div>
{/block}
{block name="javascript-initialization"}
{javascripts file='assets/js/bootstrap-switch/bootstrap-switch.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{/block}

View File

@@ -54,7 +54,7 @@
{form_field form=$form field='title'} {form_field form=$form field='title'}
<div class="form-group {if $error}has-error{/if}"> <div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l=$label} : </label> <label for="{$label_attr.for}" class="control-label">{intl l=$label} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" required="required" title="{intl l='Title'}" placeholder="{intl l='Title'}" class="form-control" value="{if $error}{$value}{else}{if $IS_TRANSLATED == 1}{$TITLE}{/if}{/if}"> <input type="text" id="{$label_attr.for}" name="{$name}" required="required" title="{intl l='Title'}" placeholder="{intl l='Title'}" class="form-control" value="{if $form_error}{$value}{else}{if $IS_TRANSLATED == 1}{$TITLE}{/if}{/if}">
</div> </div>
{/form_field} {/form_field}
@@ -65,7 +65,7 @@
<span class="label-help-block">{intl l="The detailed description."}</span> <span class="label-help-block">{intl l="The detailed description."}</span>
</label> </label>
<textarea name="{$name}" id="{$label_attr.for}" rows="10" class="form-control wysiwyg">{if $error}{$value}{else}{if $IS_TRANSLATED == 1}{$DESCRIPTION}{/if}{/if}</textarea> <textarea name="{$name}" id="{$label_attr.for}" rows="10" class="form-control wysiwyg">{if $form_error}{$value}{else}{if $IS_TRANSLATED == 1}{$DESCRIPTION}{/if}{/if}</textarea>
</div> </div>
{/form_field} {/form_field}
@@ -78,27 +78,29 @@
<div class="form-group"> <div class="form-group">
<select name="{$name}" class="js-change-tax-type" data-toggle="selectpicker"> <select name="{$name}" class="js-change-tax-type" data-toggle="selectpicker">
{foreach $choices as $choice} {foreach $choices as $choice}
<option value="{$choice->value}" {if $choice->value == $TYPE}selected="selected" {/if}>{$choice->label}</option> <option value="{$choice->value}" {if !$form_error && $choice->value == $TYPE || $form_error && $choice->value == $value}selected="selected" {/if}>{$choice->label}</option>
{/foreach} {/foreach}
</select> </select>
</div> </div>
</div> </div>
{$typeValue = $value}
{/form_field} {/form_field}
{form_tagged_fields form=$form tag='requirements'} {form_tagged_fields form=$form tag='requirements'}
<div class="form-group {if $error}has-error{/if} js-tax-requirements" data-tax-type="{$data.tax_type}" {if $data.tax_type != $TYPE}style="display: none"{/if}> <div class="form-group {if $error}has-error{/if} js-tax-requirements" data-tax-type="{$attr_list.tax_type}" {if !$form_error && $attr_list.tax_type != $TYPE || $form_error && $attr_list.tax_type != $typeValue}style="display: none"{/if}>
<label for="{$label_attr.for}" class="control-label"> <label for="{$label_attr.for}" class="control-label">
{intl l=$label} : {$formType} {intl l=$label}
</label> </label>
{if $formType == 'choice'} {if $formType == 'choice'}
<select name="{$name}"> <select name="{$name}" data-toggle="selectpicker" {if !$form_error && $attr_list.tax_type != $TYPE || $form_error && $attr_list.tax_type != $typeValue}disabled="disabled"{/if}>
{foreach $choices as $choice} {foreach $choices as $choice}
<option value="{$choice->value}" {if $REQUIREMENTS.$label == $choice->value}selected="selected" {/if}>{$choice->label}</option> <option value="{$choice->value}" {if !$form_error && $REQUIREMENTS.$label == $choice->value || $form_error && $value == $choice->value}selected="selected" {/if}>{$choice->label}</option>
{/foreach} {/foreach}
</select> </select>
{/if} {/if}
{if $formType == 'text'} {if $formType == 'text'}
<input type="text" name="{$name}" value="{$REQUIREMENTS.$label}"> <input type="text" {if !$form_error && $attr_list.tax_type != $TYPE || $form_error && $attr_list.tax_type != $typeValue}disabled="disabled"{/if} id="{$label_attr.for}" name="{$name}" required="required" class="form-control" value="{if $form_error}{$value}{else}{$REQUIREMENTS.$label}{/if}">
{/if} {/if}
</div> </div>
{/form_tagged_fields} {/form_tagged_fields}
@@ -142,7 +144,10 @@
<script> <script>
$(function() { $(function() {
$('.js-change-tax-type').change(function(e){ $('.js-change-tax-type').change(function(e){
$('.js-tax-requirements').children('select, input').attr('disabled', true);
$('.js-tax-requirements').hide(); $('.js-tax-requirements').hide();
$('.js-tax-requirements[data-tax-type="' + $(this).val() + '"]').children('select, input').attr('disabled', false);
$('.js-tax-requirements[data-tax-type="' + $(this).val() + '"]').children('select').selectpicker("refresh");
$('.js-tax-requirements[data-tax-type="' + $(this).val() + '"]').show(); $('.js-tax-requirements[data-tax-type="' + $(this).val() + '"]').show();
}); });
}); });

View File

@@ -6,10 +6,10 @@
{block name="main-content"} {block name="main-content"}
{assign oder_tab {$smarty.get.tab|default:$smarty.post.tab|default:'data'}} {assign oder_tab {$smarty.get.tab|default:$smarty.post.tab|default:'data'}}
{assign asked_country {$smarty.get.country|default:{country ask="default" attr="id"}}} {assign asked_country {$smarty.get.country|default:{country ask="default" attr="id"}}}
<div class="taxes-rules edit-taxes-rules"> <div class="taxes-rules edit-taxes-rules">
<div id="wrapper" class="container"> <div id="wrapper" class="container">
@@ -35,63 +35,63 @@
<div class="form-container"> <div class="form-container">
{form name="thelia.admin.taxrule.modification"} {form name="thelia.admin.taxrule.modification"}
<form method="POST" action="{url path="/admin/configuration/taxes_rules/save"}" {form_enctype form=$form} > <form method="POST" action="{url path="/admin/configuration/taxes_rules/save"}" {form_enctype form=$form} >
{include {include
file = "includes/inner-form-toolbar.html" file = "includes/inner-form-toolbar.html"
hide_submit_buttons = false hide_submit_buttons = false
page_url = {url path="/admin/configuration/taxes_rules/update/$tax_rule_id" tab=data} page_url = {url path="/admin/configuration/taxes_rules/update/$tax_rule_id" tab=data}
close_url = {url path="/admin/configuration/taxes_rules"} close_url = {url path="/admin/configuration/taxes_rules"}
} }
{* Be sure to get the product ID, even if the form could not be validated *} {* Be sure to get the product ID, even if the form could not be validated *}
<input type="hidden" name="tax_rule_id" value="{$ID}" /> <input type="hidden" name="tax_rule_id" value="{$ID}" />
{form_hidden_fields form=$form} {form_hidden_fields form=$form}
{form_field form=$form field='success_url'} {form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{url path="/admin/configuration/taxes_rules"}" /> <input type="hidden" name="{$name}" value="{url path="/admin/configuration/taxes_rules"}" />
{/form_field} {/form_field}
{form_field form=$form field='locale'} {form_field form=$form field='locale'}
<input type="hidden" name="{$name}" value="{$edit_language_locale}" /> <input type="hidden" name="{$name}" value="{$edit_language_locale}" />
{/form_field} {/form_field}
{if $form_error}<div class="alert alert-danger">{$form_error_message}</div>{/if} {if $form_error}<div class="alert alert-danger">{$form_error_message}</div>{/if}
{form_field form=$form field='title'} {form_field form=$form field='title'}
<div class="form-group {if $error}has-error{/if}"> <div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l=$label} : </label> <label for="{$label_attr.for}" class="control-label">{intl l=$label} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" required="required" title="{intl l='Title'}" placeholder="{intl l='Title'}" class="form-control" value="{if $error}{$value}{else}{if $IS_TRANSLATED == 1}{$TITLE}{/if}{/if}"> <input type="text" id="{$label_attr.for}" name="{$name}" required="required" title="{intl l='Title'}" placeholder="{intl l='Title'}" class="form-control" value="{if $error}{$value}{else}{if $IS_TRANSLATED == 1}{$TITLE}{/if}{/if}">
</div>
{/form_field}
{form_field form=$form field='description'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">
{intl l=$label} :
<span class="label-help-block">{intl l="The detailed description."}</span>
</label>
<textarea name="{$name}" id="{$label_attr.for}" rows="10" class="form-control wysiwyg">{if $error}{$value}{else}{if $IS_TRANSLATED == 1}{$DESCRIPTION}{/if}{/if}</textarea>
</div>
{/form_field}
<div class="row">
<div class="col-md-12">
<div class="control-group">
<label>&nbsp;</label>
<div class="controls">
<p>{intl l='Tax rule created on %date_create. Last modification: %date_change' date_create={format_date date=$CREATE_DATE} date_change={format_date date=$UPDATE_DATE}}</p>
</div> </div>
</div> {/form_field}
</div>
</div>
</form> {form_field form=$form field='description'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">
{intl l=$label} :
<span class="label-help-block">{intl l="The detailed description."}</span>
</label>
<textarea name="{$name}" id="{$label_attr.for}" rows="10" class="form-control wysiwyg">{if $error}{$value}{else}{if $IS_TRANSLATED == 1}{$DESCRIPTION}{/if}{/if}</textarea>
</div>
{/form_field}
<div class="row">
<div class="col-md-12">
<div class="control-group">
<label>&nbsp;</label>
<div class="controls">
<p>{intl l='Tax rule created on %date_create. Last modification: %date_change' date_create={format_date date=$CREATE_DATE} date_change={format_date date=$UPDATE_DATE}}</p>
</div>
</div>
</div>
</div>
</form>
{/form} {/form}
</div> </div>
@@ -121,7 +121,7 @@
{$matchedCountries.first=$asked_country} {$matchedCountries.first=$asked_country}
{loop type="tax-rule-country" name="same-country-list" tax_rule=$ID ask="countries" country=$asked_country} {loop type="tax-rule-country" name="same-country-list" tax_rule=$ID ask="countries" country=$asked_country}
{$matchedCountries[]=$COUNTRY} {$matchedCountries[]=$COUNTRY}
<span class="label label-info">{$COUNTRY_TITLE}</span> <span class="label label-info">{$COUNTRY_TITLE}</span>
{/loop} {/loop}
@@ -141,104 +141,104 @@
<div class="panel-body"> <div class="panel-body">
{assign lastPosition 0} {assign lastPosition 0}
{loop type="tax-rule-country" name="existing-tax-list" tax_rule=$ID country=$asked_country} {loop type="tax-rule-country" name="existing-tax-list" tax_rule=$ID country=$asked_country}
{if $POSITION != $lastPosition} {if $POSITION != $lastPosition}
{assign lastPosition $POSITION} {assign lastPosition $POSITION}
{if $LOOP_COUNT > 1} {if $LOOP_COUNT > 1}
</div>
{/if}
<div class="drop-group droppable add-to-group">
<p class="drop-message">
<span class="glyphicon glyphicon-plus"></span>
<span class="message">{intl l="Add tax to this group"}</span>
</p>
{/if}
<div class="drag" data-id="{$TAX}">{$TAX_TITLE}</div>
{if $LOOP_COUNT == $LOOP_TOTAL}
</div>
{/if}
{/loop}
{elseloop rel="existing-tax-list"}
<div class="drop-group droppable add-to-group">
<p class="drop-message">
<span class="glyphicon glyphicon-plus"></span>
<span class="message">{intl l="Add tax to this group"}</span>
</p>
</div>
{/elseloop}
</div> </div>
<div class="panel-footer droppable create-group"> {/if}
<div class="drop-group droppable add-to-group">
<p class="drop-message"> <p class="drop-message">
<span class="glyphicon glyphicon-plus"></span> <span class="glyphicon glyphicon-plus"></span>
<span class="message">{intl l="Drop tax here to create a tax group"}</span> <span class="message">{intl l="Add tax to this group"}</span>
</p> </p>
{/if}
<div class="drag" data-id="{$TAX}">{$TAX_TITLE}</div>
{if $LOOP_COUNT == $LOOP_TOTAL}
</div> </div>
{/if}
{/loop}
{elseloop rel="existing-tax-list"}
<div class="drop-group droppable add-to-group">
<p class="drop-message">
<span class="glyphicon glyphicon-plus"></span>
<span class="message">{intl l="Add tax to this group"}</span>
</p>
</div>
{/elseloop}
</div> </div>
<div class="panel-footer droppable create-group">
<a href="#tax_list_update_dialog" data-toggle="modal" id="apply-taxes-rules" class="btn btn-default btn-primary btn-block"><span class="glyphicon glyphicon-check"></span> {intl l="Apply"}</a> <p class="drop-message">
<span class="glyphicon glyphicon-plus"></span>
</div> <span class="message">{intl l="Drop tax here to create a tax group"}</span>
<div class="col-md-6"> </p>
<div id="panel-list" class="panel panel-default take">
<div class="panel-heading">
<h3 class="panel-title">Available taxes</h3>
</div>
<div class="panel-body">
{loop type="tax" name="tax-list" exclude_tax_rule=$ID country=$asked_country}
<div class="draggable" data-id="{$ID}">{$TITLE}</div>
{/loop}
</div>
<div class="panel-footer droppable remove-from-group">
<p class="drop-message">
<span class="glyphicon glyphicon-minus"></span>
<span class="message">{intl l="Drop tax here to delete from group"}</span>
</p>
</div>
</div> </div>
</div> </div>
<a href="#tax_list_update_dialog" data-toggle="modal" id="apply-taxes-rules" class="btn btn-default btn-primary btn-block"><span class="glyphicon glyphicon-check"></span> {intl l="Apply"}</a>
</div> </div>
<div class="col-md-6">
<div id="panel-list" class="panel panel-default take">
<div class="panel-heading">
<h3 class="panel-title">Available taxes</h3>
</div>
<div class="panel-body">
{loop type="tax" name="tax-list" exclude_tax_rule=$ID country=$asked_country}
<div class="draggable" data-id="{$ID}">{$TITLE}</div>
{/loop}
</div>
<div class="panel-footer droppable remove-from-group">
<p class="drop-message">
<span class="glyphicon glyphicon-minus"></span>
<span class="message">{intl l="Drop tax here to delete from group"}</span>
</p>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
</div>
{/loop} </div>
</div>
{/loop}
</div> </div>
{* Confirmation dialog *} {* Confirmation dialog *}
{form name="thelia.admin.taxrule.taxlistupdate"} {form name="thelia.admin.taxrule.taxlistupdate"}
{if $form_error_message} {if $form_error_message}
{$taxUpdateError = true} {$taxUpdateError = true}
{else} {else}
{$taxUpdateError = false} {$taxUpdateError = false}
{/if} {/if}
{* Capture the dialog body, to pass it to the generic dialog *} {* Capture the dialog body, to pass it to the generic dialog *}
{capture "tax_list_update_dialog"} {capture "tax_list_update_dialog"}
<input type="hidden" name="tax_rule_id" value="{$tax_rule_id}"> <input type="hidden" name="tax_rule_id" value="{$tax_rule_id}">
<input type="hidden" name="tab" value="taxes"> <input type="hidden" name="tab" value="taxes">
{form_hidden_fields form=$form} {form_hidden_fields form=$form}
{form_field form=$form field='country_list'} {form_field form=$form field='country_list'}
<p>{intl l="Tax rule taxes will be update for the following countries :"}</p> <p>{intl l="Tax rule taxes will be update for the following countries :"}</p>
<div class="form-group"> <div class="form-group">
<div class="input-group"> <div class="input-group">
<select id="countries-select" class="" name="{$name}" data-toggle="selectpicker" multiple> <select id="countries-select" class="" name="{$name}" data-toggle="selectpicker" multiple>
{loop type="country" name="country-list"} {loop type="country" name="country-list"}
<option value='{$ID}' {if (!$value AND in_array($ID, $matchedCountries)) OR ($value AND in_array($ID, $value))}selected="selected"{/if}>{$TITLE}</option> <option value='{$ID}' {if (!$value AND in_array($ID, $matchedCountries)) OR ($value AND in_array($ID, $value))}selected="selected"{/if}>{$TITLE}</option>
{/loop} {/loop}
</select> </select>
<span class="input-group-btn"> <span class="input-group-btn">
@@ -247,24 +247,24 @@
</div> </div>
</div> </div>
{/form_field} {/form_field}
{/capture} {/capture}
{include {include
file = "includes/generic-create-dialog.html" file = "includes/generic-create-dialog.html"
dialog_id = "tax_list_update_dialog" dialog_id = "tax_list_update_dialog"
dialog_title = {intl l="Update tax rule taxes"} dialog_title = {intl l="Update tax rule taxes"}
dialog_body = {$smarty.capture.tax_list_update_dialog nofilter} dialog_body = {$smarty.capture.tax_list_update_dialog nofilter}
dialog_ok_label = {intl l="Edit tax rule taxes"} dialog_ok_label = {intl l="Edit tax rule taxes"}
dialog_cancel_label = {intl l="Cancel"} dialog_cancel_label = {intl l="Cancel"}
form_action = {url path="/admin/configuration/taxes_rules/saveTaxes"} form_action = {url path="/admin/configuration/taxes_rules/saveTaxes"}
form_enctype = {form_enctype form=$form} form_enctype = {form_enctype form=$form}
form_error_message = $form_error_message form_error_message = $form_error_message
} }
{/form} {/form}
@@ -285,34 +285,34 @@
<script> <script>
$(function() { $(function() {
{if $taxUpdateError == true} {if $taxUpdateError == true}
$('#tax_list_update_dialog').modal(); $('#tax_list_update_dialog').modal();
{/if} {/if}
$('.js-collapse').each(function(k, v) { $('.js-collapse').each(function(k, v) {
var h = $(v).data('collapse-height'); var h = $(v).data('collapse-height');
if( $(v).height() > h ) { if( $(v).height() > h ) {
$(v).css('overflow', 'hidden').css('height', h + 'px'); $(v).css('overflow', 'hidden').css('height', h + 'px');
} else { } else {
$('[data-collapse-block=' + $(v).attr('id') + ']').hide(); $('[data-collapse-block=' + $(v).attr('id') + ']').hide();
} }
}); });
$('.js-collapse-btn').click(function(e) { $('.js-collapse-btn').click(function(e) {
e.preventDefault(); e.preventDefault();
var block = $(this).data('collapseBlock'); var block = $(this).data('collapseBlock');
$('#' + block).css('overflow', 'initial').css('height', 'initial'); $('#' + block).css('overflow', 'initial').css('height', 'initial');
$(this).unbind().remove(); $(this).unbind().remove();
}); });
$('.js-uncheck-all').click(function(e) { $('.js-uncheck-all').click(function(e) {
e.preventDefault(); e.preventDefault();
var selectId = $(this).data('uncheckSelect'); var selectId = $(this).data('uncheckSelect');
$('#' + selectId).selectpicker('deselectAll'); $('#' + selectId).selectpicker('deselectAll');
}); });
{literal} {literal}
$('#country-selector').change(function(e) { $('#country-selector').change(function(e) {
$('#country-selector-form').submit(); $('#country-selector-form').submit();
}); });
@@ -324,7 +324,7 @@
// Build array of taxes rules // Build array of taxes rules
$('#apply-taxes-rules').click(function(){ $('#apply-taxes-rules').click(function(){
var taxesRules = [], var taxesRules = [],
index; index;
$('.drop-group', $group).each(function(i){ $('.drop-group', $group).each(function(i){
var $this = $(this); var $this = $(this);
@@ -382,13 +382,13 @@
// Make the new group droppable // Make the new group droppable
$drop $drop
.droppable(dropOptions) .droppable(dropOptions)
.sortable(sortOptions); .sortable(sortOptions);
} }
} }
$("<div></div>").addClass('drag').attr('data-id', ui.draggable.data('id')).text( ui.draggable.text()).appendTo( $drop ); $("<div></div>").addClass('drag').attr('data-id', ui.draggable.data('id')).text( ui.draggable.text()).appendTo( $drop );
ui.draggable.remove(); ui.draggable.remove();
} }
}; };
@@ -399,24 +399,24 @@
// let the drop-group be droppable & sortable, accepting the tax items // let the drop-group be droppable & sortable, accepting the tax items
$('.droppable', $group) $('.droppable', $group)
.droppable(dropOptions) .droppable(dropOptions)
.sortable(sortOptions); .sortable(sortOptions);
$('.place .panel-body').sortable(sortOptions); $('.place .panel-body').sortable(sortOptions);
// let the gallery be droppable as well, accepting items from the trash // let the gallery be droppable as well, accepting items from the trash
$('.remove-from-group', $list) $('.remove-from-group', $list)
.droppable({ .droppable({
accept: "#panel .drag", accept: "#panel .drag",
hoverClass: 'over', hoverClass: 'over',
drop: function( event, ui ) { drop: function( event, ui ) {
$("<div></div>").addClass('draggable').text( ui.draggable.text() ).attr('data-id', ui.draggable.data('id')).draggable(dragOptions).appendTo( $list.find('.panel-body') ); $("<div></div>").addClass('draggable').text( ui.draggable.text() ).attr('data-id', ui.draggable.data('id')).draggable(dragOptions).appendTo( $list.find('.panel-body') );
ui.draggable.remove(); ui.draggable.remove();
} }
}); });
{/literal} {/literal}
}); });

View File

@@ -5,339 +5,376 @@
{block name="check-permissions"}admin.taxes-rules.view{/block} {block name="check-permissions"}admin.taxes-rules.view{/block}
{block name="main-content"} {block name="main-content"}
<div class="taxes-rules"> <div class="taxes-rules">
<div id="wrapper" class="container"> <div id="wrapper" class="container">
<div class="clearfix">
<ul class="breadcrumb">
<li><a href="{url path='/admin/home'}">{intl l="Home"}</a></li>
<li><a href="{url path='/admin/configuration'}">{intl l="Configuration"}</a></li>
<li><a href="{url path='/admin/configuration/taxes_rules'}">{intl l="Taxes rules"}</a></li>
</ul>
</div>
{module_include location='taxes_rules_top'} <div class="clearfix">
<ul class="breadcrumb">
<li><a href="{url path='/admin/home'}">{intl l="Home"}</a></li>
<li><a href="{url path='/admin/configuration'}">{intl l="Configuration"}</a></li>
<li><a href="{url path='/admin/configuration/taxes_rules'}">{intl l="Taxes rules"}</a></li>
</ul>
</div>
<div class="row"> {module_include location='taxes_rules_top'}
<div class="col-md-12">
<div class="alert alert-info"> <div class="row">
<p>{intl l="In order to manges your shop taxes you can manage"} <strong>{intl l="taxes"}</strong> {intl l="and"} <strong>{intl l="tax rules"}</strong>.</p> <div class="col-md-12">
<p>{intl l="Taxes define the amount of money which is add to a bought product."}</p>
<p>
{intl l="Example :"}
<ul>
<li>{intl l="French 19.6% VAT is a tax which add a 19.6% tax to the product price."}</li>
<li>{intl l="Ecotax is a tax wich add a defined amount (throug a product feature) to the product price."}</li>
</ul>
</p>
<p>{intl l="Tax rules are combination of different taxes."}</p>
<p>
{intl l="Example :"}
<ul>
<li>{intl l="French 19.6% VAT with ecotax is the applicance of the ecotax (on the product price) then the applicance of the 19.6% tax (on the product price + the ecotax amount)."}</li>
</ul>
</p>
<p>{intl l="you can combine taxes in tax rules and chose if they are applied one after the other or at the same time : it allows to apply taxes on an already taxed price or not."}</p>
</div>
<div class="general-block-decorator"> <div class="alert alert-info">
<div class="table-responsive"> <p>{intl l="In order to manges your shop taxes you can manage"} <strong>{intl l="taxes"}</strong> {intl l="and"} <strong>{intl l="tax rules"}</strong>.</p>
<table class="table table-striped table-condensed table-left-aligned"> <p>{intl l="Taxes define the amount of money which is add to a bought product."}</p>
<caption class="clearfix"> <p>
{intl l="Taxes"} {intl l="Example :"}
{loop type="auth" name="can_create" roles="ADMIN" permissions="admin.taxes.create"} <ul>
<a class="btn btn-default btn-primary pull-right" title="{intl l='Create a new tax'}" href="#tax_create_dialog" data-toggle="modal"> <li>{intl l="French 19.6% VAT is a tax which add a 19.6% tax to the product price."}</li>
<span class="glyphicon glyphicon-plus"></span> <li>{intl l="Ecotax is a tax wich add a defined amount (throug a product feature) to the product price."}</li>
</a> </ul>
{/loop} </p>
</caption> <p>{intl l="Tax rules are combination of different taxes."}</p>
<thead> <p>
{intl l="Example :"}
<ul>
<li>{intl l="French 19.6% VAT with ecotax is the applicance of the ecotax (on the product price) then the applicance of the 19.6% tax (on the product price + the ecotax amount)."}</li>
</ul>
</p>
<p>{intl l="you can combine taxes in tax rules and chose if they are applied one after the other or at the same time : it allows to apply taxes on an already taxed price or not."}</p>
</div>
<div class="general-block-decorator">
<div class="table-responsive">
<table class="table table-striped table-condensed table-left-aligned">
<caption class="clearfix">
{intl l="Taxes"}
{loop type="auth" name="can_create" roles="ADMIN" permissions="admin.taxes.create"}
<a class="btn btn-default btn-primary pull-right" title="{intl l='Create a new tax'}" href="#tax_create_dialog" data-toggle="modal">
<span class="glyphicon glyphicon-plus"></span>
</a>
{/loop}
</caption>
<thead>
<tr> <tr>
<th>{intl l="Name"}</th> <th class="col-md-3">{intl l="Name"}</th>
<th>{intl l="Description"}</th> <th class="col-md-5">{intl l="Description"}</th>
<th>{intl l="Actions"}</th> <th class="col-md-1">{intl l="Actions"}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{loop type="tax" name="taxes" backend_context="1"} {loop type="tax" name="taxes" backend_context="1"}
<tr> <tr>
<td>{$TITLE}</td> <td>{$TITLE}</td>
<td>{$DESCRIPTION}</td> <td>{$DESCRIPTION}</td>
<td> <td>
<div class="btn-group"> <div class="btn-group">
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.taxes.change"} {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.taxes.change"}
<a class="btn btn-default btn-xs" title="{intl l='Change this tax'}" href="{url path="/admin/configuration/taxes/update/$ID"}"><span class="glyphicon glyphicon-edit"></span></a> <a class="btn btn-default btn-xs" title="{intl l='Change this tax'}" href="{url path="/admin/configuration/taxes/update/$ID"}"><span class="glyphicon glyphicon-edit"></span></a>
{/loop} {/loop}
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.taxes.change"} {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.taxes.change"}
<a class="btn btn-default btn-xs js-delete-tax" title="{intl l='Delete this tax'}" href="#tax_delete_dialog" data-id="{$ID}" data-toggle="modal"><span class="glyphicon glyphicon-trash"></span></a> <a class="btn btn-default btn-xs js-delete-tax" title="{intl l='Delete this tax'}" href="#tax_delete_dialog" data-id="{$ID}" data-toggle="modal"><span class="glyphicon glyphicon-trash"></span></a>
{/loop} {/loop}
</div> </div>
</td> </td>
</tr> </tr>
{/loop} {/loop}
</tbody> </tbody>
</table> </table>
</div>
</div> </div>
</div>
<div class="general-block-decorator"> <div class="general-block-decorator">
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-striped table-condensed table-left-aligned"> <table class="table table-striped table-condensed table-left-aligned">
<caption class="clearfix"> <caption class="clearfix">
{intl l="Taxes rules"} {intl l="Taxes rules"}
{loop type="auth" name="can_create" roles="ADMIN" permissions="admin.taxes-rules.create"} {loop type="auth" name="can_create" roles="ADMIN" permissions="admin.taxes-rules.create"}
<a class="btn btn-default btn-primary pull-right" title="{intl l='Create a new tax rule'}" href="#tax_rule_create_dialog" data-toggle="modal"> <a class="btn btn-default btn-primary pull-right" title="{intl l='Create a new tax rule'}" href="#tax_rule_create_dialog" data-toggle="modal">
<span class="glyphicon glyphicon-plus"></span> <span class="glyphicon glyphicon-plus"></span>
</a> </a>
{/loop} {/loop}
</caption> </caption>
<thead> <thead>
<tr> <tr>
<th>{intl l="Name"}</th> <th class="col-md-3">{intl l="Name"}</th>
<th>{intl l="Description"}</th> <th class="col-md-4">{intl l="Description"}</th>
<th>{intl l="Actions"}</th> <th class="col-md-1">{intl l="Default"}</th>
<th class="col-md-1">{intl l="Actions"}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{loop type="tax-rule" name="taxes-rules" backend_context="1"} {loop type="tax-rule" name="taxes-rules" backend_context="1"}
<tr> <tr>
<td>{$TITLE}</td> <td>{$TITLE}</td>
<td>{$DESCRIPTION}</td> <td>{$DESCRIPTION}</td>
<td> <td>
<div class="btn-group"> {if $IS_DEFAULT == 1}
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.taxes-rules.change"} <span class="glyphicon glyphicon-ok"></span>
<a class="btn btn-default btn-xs" title="{intl l='Change this tax rule'}" href="{url path="/admin/configuration/taxes_rules/update/$ID"}"><span class="glyphicon glyphicon-edit"></span></a> {/if}
{/loop} </td>
<td>
<div class="btn-group">
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.taxes-rules.change"}
<a class="btn btn-default btn-xs" title="{intl l='Change this tax rule'}" href="{url path="/admin/configuration/taxes_rules/update/$ID"}"><span class="glyphicon glyphicon-edit"></span></a>
<a class="btn btn-default btn-xs" title="{intl l='Set as default tax rule'}" href="{url path="/admin/configuration/taxes_rules/update/set_default/$ID"}" {if $IS_DEFAULT == 1}disabled{/if}><span class="glyphicon glyphicon-star"></span></a>
{/loop}
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.taxes-rules.change"} {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.taxes-rules.dele"}
<a class="btn btn-default btn-xs js-delete-tax-rule" title="{intl l='Delete this tax rule'}" href="#tax_rule_delete_dialog" data-id="{$ID}" data-toggle="modal"><span class="glyphicon glyphicon-trash"></span></a> <a class="btn btn-default btn-xs js-delete-tax-rule" title="{intl l='Delete this tax rule'}" href="#tax_rule_delete_dialog" data-id="{$ID}" data-toggle="modal"><span class="glyphicon glyphicon-trash"></span></a>
{/loop} {/loop}
</div> </div>
</td> </td>
</tr> </tr>
{/loop} {/loop}
</tbody> </tbody>
</table> </table>
</div>
</div> </div>
</div> </div>
</div> </div>
{module_include location='taxes_rules_bottom'}
</div> </div>
{module_include location='taxes_rules_bottom'}
</div> </div>
</div>
{* -- Add tax confirmation dialog ----------------------------------- *} {* -- Add tax confirmation dialog ----------------------------------- *}
{form name="thelia.admin.tax.add"} {form name="thelia.admin.tax.add"}
{if $form_error_message} {if $form_error_message}
{$taxCreateError = true} {$taxCreateError = true}
{else} {else}
{$taxCreateError = false} {$taxCreateError = false}
{/if} {/if}
{* Capture the dialog body, to pass it to the generic dialog *} {* Capture the dialog body, to pass it to the generic dialog *}
{capture "tax_create_dialog"} {capture "tax_create_dialog"}
{form_hidden_fields form=$form} {form_hidden_fields form=$form}
{form_field form=$form field='locale'} {form_field form=$form field='locale'}
<input type="hidden" name="{$name}" value="{$edit_language_locale}" /> <input type="hidden" name="{$name}" value="{$edit_language_locale}" />
{/form_field} {/form_field}
{if $form_error}<div class="alert alert-danger">{$form_error_message}</div>{/if} {form_field form=$form field='title'}
<div class="form-group {if $error}has-error{/if}">
{form_field form=$form field='title'} <label for="{$label_attr.for}" class="control-label">{intl l=$label} : </label>
<div class="form-group {if $error}has-error{/if}"> <input type="text" id="{$label_attr.for}" name="{$name}" required="required" title="{intl l='Title'}" placeholder="{intl l='Title'}" class="form-control" value="{if $form_error}{$value}{else}{if $IS_TRANSLATED == 1}{$TITLE}{/if}{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l=$label} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" required="required" title="{intl l='Title'}" placeholder="{intl l='Title'}" class="form-control" value="{if $error}{$value}{else}{if $IS_TRANSLATED == 1}{$TITLE}{/if}{/if}">
</div>
{/form_field}
{form_field form=$form field='description'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">
{intl l=$label} :
<span class="label-help-block">{intl l="The detailed description."}</span>
</label>
<textarea name="{$name}" id="{$label_attr.for}" rows="10" class="form-control wysiwyg">{if $error}{$value}{else}{if $IS_TRANSLATED == 1}{$DESCRIPTION}{/if}{/if}</textarea>
</div>
{/form_field}
{form_field form=$form field='type'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">
{intl l=$label} :
</label>
<div class="form-group">
<select name="{$name}" data-toggle="selectpicker">
{foreach $choices as $choice}
<option value="{$choice->value}" {if $choice->value == $TYPE}selected="selected" {/if}>{$choice->label}</option>
{/foreach}
</select>
</div> </div>
</div> {/form_field}
{/form_field}
{/capture} {form_field form=$form field='description'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">
{intl l=$label} :
<span class="label-help-block">{intl l="The detailed description."}</span>
</label>
{include <textarea name="{$name}" id="{$label_attr.for}" rows="10" class="form-control wysiwyg">{if $form_error}{$value}{else}{if $IS_TRANSLATED == 1}{$DESCRIPTION}{/if}{/if}</textarea>
</div>
{/form_field}
{form_field form=$form field='type'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">
{intl l=$label} :
</label>
<div class="form-group">
<select name="{$name}" class="js-change-tax-type" data-toggle="selectpicker">
{$typeValueWithError = $value}
{foreach from=$choices key=key item=choice}
{if $key == 0}
{$typeValue = $choice->value}
{/if}
<option value="{$choice->value}" {if $form_error && $choice->value == $value || !$form_error && $key == 0}selected="selected" {/if}>{$choice->label}</option>
{/foreach}
</select>
</div>
</div>
{/form_field}
{form_tagged_fields form=$form tag='requirements'}
<div class="form-group {if $error}has-error{/if} js-tax-requirements" data-tax-type="{$attr_list.tax_type}" {if !$form_error && $attr_list.tax_type != $typeValue || $form_error && $attr_list.tax_type != $typeValueWithError}style="display: none"{/if}>
<label for="{$label_attr.for}" class="control-label">
{intl l=$label}
</label>
{if $formType == 'choice'}
<select name="{$name}" data-toggle="selectpicker" {if !$form_error && $attr_list.tax_type != $typeValue || $form_error && $attr_list.tax_type != $typeValueWithError}disabled="disabled"{/if}>
{foreach $choices as $choice}
<option value="{$choice->value}" {if !$form_error && $REQUIREMENTS.$label == $choice->value || $form_error && $value == $choice->value}selected="selected" {/if}>{$choice->label}</option>
{/foreach}
</select>
{/if}
{if $formType == 'text'}
<input type="text" {if !$form_error && $attr_list.tax_type != $typeValue || $form_error && $attr_list.tax_type != $typeValueWithError}disabled="disabled"{/if} id="{$label_attr.for}" name="{$name}" required="required" class="form-control" value="{if $form_error}{$value}{else}{$REQUIREMENTS.$label}{/if}">
{/if}
</div>
{/form_tagged_fields}
{/capture}
{include
file = "includes/generic-create-dialog.html" file = "includes/generic-create-dialog.html"
dialog_id = "tax_create_dialog" dialog_id = "tax_create_dialog"
dialog_title = {intl l="Create a new tax"} dialog_title = {intl l="Create a new tax"}
dialog_body = {$smarty.capture.tax_create_dialog nofilter} dialog_body = {$smarty.capture.tax_create_dialog nofilter}
dialog_ok_label = {intl l="Create"} dialog_ok_label = {intl l="Create"}
dialog_cancel_label = {intl l="Cancel"} dialog_cancel_label = {intl l="Cancel"}
form_action = {url path="/admin/configuration/taxes/add"} form_action = {url path="/admin/configuration/taxes/add"}
form_enctype = {form_enctype form=$form} form_enctype = {form_enctype form=$form}
form_error_message = $form_error_message form_error_message = $form_error_message
} }
{/form} {/form}
{* -- Delete tax confirmation dialog ----------------------------------- *} {* -- Delete tax confirmation dialog ----------------------------------- *}
{capture "tax_delete_dialog"} {capture "tax_delete_dialog"}
<input type="hidden" name="tax_id" id="tax_delete_id" value="" /> <input type="hidden" name="tax_id" id="tax_delete_id" value="" />
{module_include location='tax_delete_form'} {module_include location='tax_delete_form'}
{/capture} {/capture}
{include {include
file = "includes/generic-confirm-dialog.html" file = "includes/generic-confirm-dialog.html"
dialog_id = "tax_delete_dialog" dialog_id = "tax_delete_dialog"
dialog_title = {intl l="Delete tax"} dialog_title = {intl l="Delete tax"}
dialog_message = {intl l="Do you really want to delete this tax ?"} dialog_message = {intl l="Do you really want to delete this tax ?"}
form_action = {url path='/admin/configuration/taxes/delete'} form_action = {url path='/admin/configuration/taxes/delete'}
form_content = {$smarty.capture.tax_delete_dialog nofilter} form_content = {$smarty.capture.tax_delete_dialog nofilter}
} }
{* -- Add tax rule confirmation dialog ----------------------------------- *} {* -- Add tax rule confirmation dialog ----------------------------------- *}
{form name="thelia.admin.taxrule.add"} {form name="thelia.admin.taxrule.add"}
{if $form_error_message} {if $form_error_message}
{$taxRuleCreateError = true} {$taxRuleCreateError = true}
{else} {else}
{$taxRuleCreateError = false} {$taxRuleCreateError = false}
{/if} {/if}
{* Capture the dialog body, to pass it to the generic dialog *} {* Capture the dialog body, to pass it to the generic dialog *}
{capture "tax_rule_create_dialog"} {capture "tax_rule_create_dialog"}
{form_hidden_fields form=$form} {form_hidden_fields form=$form}
{form_field form=$form field='locale'} {form_field form=$form field='locale'}
<input type="hidden" name="{$name}" value="{$edit_language_locale}" /> <input type="hidden" name="{$name}" value="{$edit_language_locale}" />
{/form_field} {/form_field}
{if $form_error}<div class="alert alert-danger">{$form_error_message}</div>{/if} {if $form_error}<div class="alert alert-danger">{$form_error_message}</div>{/if}
{form_field form=$form field='title'} {form_field form=$form field='title'}
<div class="form-group {if $error}has-error{/if}"> <div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l=$label} : </label> <label for="{$label_attr.for}" class="control-label">{intl l=$label} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" required="required" title="{intl l='Title'}" placeholder="{intl l='Title'}" class="form-control" value="{if $error}{$value}{else}{if $IS_TRANSLATED == 1}{$TITLE}{/if}{/if}"> <input type="text" id="{$label_attr.for}" name="{$name}" required="required" title="{intl l='Title'}" placeholder="{intl l='Title'}" class="form-control" value="{if $error}{$value}{else}{if $IS_TRANSLATED == 1}{$TITLE}{/if}{/if}">
</div> </div>
{/form_field} {/form_field}
{form_field form=$form field='description'} {form_field form=$form field='description'}
<div class="form-group {if $error}has-error{/if}"> <div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label"> <label for="{$label_attr.for}" class="control-label">
{intl l=$label} : {intl l=$label} :
<span class="label-help-block">{intl l="The detailed description."}</span> <span class="label-help-block">{intl l="The detailed description."}</span>
</label> </label>
<textarea name="{$name}" id="{$label_attr.for}" rows="10" class="form-control wysiwyg">{if $error}{$value}{else}{if $IS_TRANSLATED == 1}{$DESCRIPTION}{/if}{/if}</textarea> <textarea name="{$name}" id="{$label_attr.for}" rows="10" class="form-control wysiwyg">{if $error}{$value}{else}{if $IS_TRANSLATED == 1}{$DESCRIPTION}{/if}{/if}</textarea>
</div> </div>
{/form_field} {/form_field}
{/capture} {/capture}
{include {include
file = "includes/generic-create-dialog.html" file = "includes/generic-create-dialog.html"
dialog_id = "tax_rule_create_dialog" dialog_id = "tax_rule_create_dialog"
dialog_title = {intl l="Create a new tax rule"} dialog_title = {intl l="Create a new tax rule"}
dialog_body = {$smarty.capture.tax_rule_create_dialog nofilter} dialog_body = {$smarty.capture.tax_rule_create_dialog nofilter}
dialog_ok_label = {intl l="Create"} dialog_ok_label = {intl l="Create"}
dialog_cancel_label = {intl l="Cancel"} dialog_cancel_label = {intl l="Cancel"}
form_action = {url path="/admin/configuration/taxes_rules/add"} form_action = {url path="/admin/configuration/taxes_rules/add"}
form_enctype = {form_enctype form=$form} form_enctype = {form_enctype form=$form}
form_error_message = $form_error_message form_error_message = $form_error_message
} }
{/form} {/form}
{* -- Delete tax rule confirmation dialog ----------------------------------- *} {* -- Delete tax rule confirmation dialog ----------------------------------- *}
{capture "tax_rule_delete_dialog"} {capture "tax_rule_delete_dialog"}
<input type="hidden" name="tax_rule_id" id="tax_rule_delete_id" value="" /> <input type="hidden" name="tax_rule_id" id="tax_rule_delete_id" value="" />
{module_include location='tax_rule_delete_form'} {module_include location='tax_rule_delete_form'}
{/capture} {/capture}
{include {include
file = "includes/generic-confirm-dialog.html" file = "includes/generic-confirm-dialog.html"
dialog_id = "tax_rule_delete_dialog" dialog_id = "tax_rule_delete_dialog"
dialog_title = {intl l="Delete tax rule"} dialog_title = {intl l="Delete tax rule"}
dialog_message = {intl l="Do you really want to delete this tax rule ?"} dialog_message = {intl l="Do you really want to delete this tax rule ?"}
form_action = {url path='/admin/configuration/taxes_rules/delete'} form_action = {url path='/admin/configuration/taxes_rules/delete'}
form_content = {$smarty.capture.tax_rule_delete_dialog nofilter} form_content = {$smarty.capture.tax_rule_delete_dialog nofilter}
} }
{/block} {/block}
{block name="javascript-initialization"} {block name="javascript-initialization"}
{javascripts file='assets/js/bootstrap-select/bootstrap-select.js'} {javascripts file='assets/js/bootstrap-select/bootstrap-select.js'}
<script src='{$asset_url}'></script> <script src='{$asset_url}'></script>
{/javascripts} {/javascripts}
{javascripts file='assets/js/main.js'} {javascripts file='assets/js/main.js'}
<script src='{$asset_url}'></script> <script src='{$asset_url}'></script>
{/javascripts} {/javascripts}
<script type="text/javascript"> <script type="text/javascript">
jQuery(function($) {
{if $taxRuleCreateError == true} {if $taxRuleCreateError == true}
$('#tax_rule_create_dialog').modal(); $('#tax_rule_create_dialog').modal();
{/if} {/if}
{if $taxCreateError == true} {if $taxCreateError == true}
$('#tax_create_dialog').modal(); $('#tax_create_dialog').modal();
{/if} {/if}
$(".js-delete-tax-rule").click(function(e){ $(".js-delete-tax-rule").click(function(e){
$('#tax_rule_delete_id').val($(this).data('id')) $('#tax_rule_delete_id').val($(this).data('id'))
}); });
$(".js-delete-tax").click(function(e){ $(".js-delete-tax").click(function(e){
$('#tax_delete_id').val($(this).data('id')) $('#tax_delete_id').val($(this).data('id'))
}); });
</script>
$('.js-change-tax-type').change(function(e){
$('.js-tax-requirements').children('select, input').attr('disabled', true);
$('.js-tax-requirements').hide();
$('.js-tax-requirements[data-tax-type="' + $(this).val() + '"]').children('select, input').attr('disabled', false);
$('.js-tax-requirements[data-tax-type="' + $(this).val() + '"]').children('select').selectpicker("refresh");
$('.js-tax-requirements[data-tax-type="' + $(this).val() + '"]').show();
});
})
</script>
{/block} {/block}

View File

@@ -0,0 +1,131 @@
{extends file="layout.tpl"}
{* Body Class *}
{block name="body-class"}page-account-update{/block}
{* Breadcrumb *}
{block name='no-return-functions' append}
{$breadcrumbs = [['title' => {intl l="Account"}, 'url'=>{url path="/account"}]]}
{$breadcrumbs = [
['title' => {intl l="Account"}, 'url'=>{url path="/account"}],
['title' => {intl l="Update Profil"}, 'url'=>{url path="/account/update"}]
]}
{/block}
{block name="main-content"}
<div class="main">
<article class="col-main" role="main" aria-labelledby="main-label">
<h1 id="main-label" class="page-header">{intl l="Update Profil"}</h1>
{form name="thelia.customer.update"}
{assign var="isPost" value="{$smarty.post|count}"}
<form id="form-register" class="form-horizontal" action="{url path="/account/update"}" method="post" role="form">
{form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{url path="/account"}" />
{/form_field}
{form_hidden_fields form=$form}
{if $form_error}<div class="alert alert-danger">{$form_error_message}</div>{/if}
<fieldset id="register-info" class="panel panel">
<div class="panel-heading">
{intl l="Personal Informations"}
</div>
<div class="panel-body">
{form_field form=$form field="title"}
<div class="form-group group-title {if $error}has-error{elseif $isPost && $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input">
<select name="{$name}" id="{$label_attr.for}" class="form-control"{if $required} aria-required="true" required{/if}{if !$value || $error} autofocus{/if}>
<option value="">-- {intl l="Select Title"} --</option>
{loop type="title" name="country.list"}
<option value="{$ID}" {if $value == $ID}selected{/if} >{$LONG}</option>
{/loop}
</select>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif !$value}
{assign var="error_focus" value="true"}
{elseif $isPost && $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span>
{/if}
</div>
</div><!--/.form-group-->
{/form_field}
{form_field form=$form field="firstname"}
<div class="form-group group-firstname {if $error}has-error{elseif $isPost && $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input">
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="John" value="{$value}" {if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $isPost && $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span>
{/if}
</div>
</div><!--/.form-group-->
{/form_field}
{form_field form=$form field="lastname"}
<div class="form-group group-lastname {if $error}has-error{elseif $isPost && $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input">
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="Doe" value="{$value}" {if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $isPost && $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span>
{/if}
</div>
</div><!--/.form-group-->
{/form_field}
{form_field form=$form field="email"}
<div class="form-group group-email {if $error}has-error{elseif $isPost && $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input">
<input type="email" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="johndoe@domain.com" value="{$smarty.get.email|default:$value}"{if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $isPost && $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span>
{/if}
</div>
</div><!--/.form-group-->
{/form_field}
</div>
</fieldset>
{form_field form=$form field="newsletter"}
<div class="form-group group-newsletter{if $error} has-error{/if}">
<div class="control-input">
<div class="checkbox">
<label class="control-label" for="{$label_attr.for}">
<input type="checkbox" name="{$name}" id="{$label_attr.for}" value="{$value}"{if $checked} checked{/if} {if $required} aria-required="true" required{/if}>{$label}
</label>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{/if}
</div>
</div>
</div><!--/.form-group-->
{/form_field}
<div class="form-group group-btn">
<div class="control-btn">
<button type="submit" class="btn btn-register">{intl l="Update"}</button>
</div>
</div><!--/.form-group-->
</form>
{/form}
</article>
</div><!-- /.layout -->
{/block}

View File

@@ -1,19 +1,18 @@
{extends file="layout.tpl"} {extends file="layout.tpl"}
{block name="no-return-functions"} {block name="no-return-functions" prepend}
{check_auth context="front" roles="CUSTOMER" login_tpl="login"} {check_auth context="front" roles="CUSTOMER" login_tpl="login"}
{/block} {/block}
{block name="breadcrumb"} {* Breadcrumb *}
<nav class="nav-breadcrumb" role="navigation" aria-labelledby="breadcrumb-label"> {block name='no-return-functions' append}
<strong id="breadcrumb-label">{intl l="You are here"}: </strong> {$breadcrumbs = [
<ul class="breadcrumb" itemprop="breadcrumb"> ['title' => {intl l="Account"}, 'url'=>{url path="/account"}]
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{navigate to="index"}" itemprop="url"><span itemprop="title">{intl l="Home"}</span></a></li> ]}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="active"><span itemprop="title">{intl l="Account"}</span></li>
</ul>
</nav><!-- /.nav-breadcrumb -->
{/block} {/block}
{block name="body-class"}page-account{/block}
{block name="main-content"} {block name="main-content"}
<div class="main"> <div class="main">
@@ -40,13 +39,13 @@
<address class="adr"> <address class="adr">
<span class="street-address">{$ADDRESS1}</span><br> <span class="street-address">{$ADDRESS1}</span><br>
{if $ADDRESS2 != ""} {if $ADDRESS2 != ""}
<span class="street-address">{$ADDRESS2}</span><br> <span class="extended-address">{$ADDRESS2}</span><br>
{/if} {/if}
{if $ADDRESS3 != ""} {if $ADDRESS3 != ""}
<span class="street-address">{$ADDRESS3}</span><br> <span class="extended-address">{$ADDRESS3}</span><br>
{/if} {/if}
<span class="postal-code">{$ZIPCODE}</span> <span class="postal-code">{$ZIPCODE}</span>
<span class="locality">{$CITY}, <span class="country-name">{loop type="country" name="customer.country.info" id=$COUNTRY}{$TITLE}{/loop}</span></span> <span class="locality">{$CITY}<br><span class="country-name">{loop type="country" name="customer.country.info" id=$COUNTRY}{$TITLE}{/loop}</span></span>
</address> </address>
</li> </li>
<li> <li>
@@ -56,11 +55,11 @@
{if $PHONE != ""} {if $PHONE != ""}
<span class="tel">{$PHONE}</span> <span class="tel">{$PHONE}</span>
{/if} {/if}
<span class="email"><a href="mailto:{$EMAIL}">{$EMAIL}</a></span> <span class="email">{mailto address="{$EMAIL}" encode="hex"}</span>
</li> </li>
<li class="group-btn"> <li class="group-btn">
<a href="#" class="btn btn-change-account"><i class="icon-pencil"></i> Change my account informations</a> <a href="{url path="/account/update"}" class="btn btn-change-account"><i class="icon-pencil"></i> {intl l="Change my account informations"}</a>
<a href="#" class="btn btn-change-password"><i class="icon-lock"></i> Change my password</a> <a href="{url path="/account/password"}" class="btn btn-change-password"><i class="icon-lock"></i> {intl l="Change my password"}</a>
</li> </li>
</ul> </ul>
{/loop} {/loop}
@@ -83,7 +82,7 @@
<tbody> <tbody>
{loop type="address" name="customer.addresses" customer="current"} {loop type="address" name="customer.addresses" customer="current"}
<tr class="{if $DEFAULT == 1}address-primary{else}address-additional{/if}" id="customer-address-{$ID}"> <tr class="{if $DEFAULT == 1}address-primary{else}address-additional{/if}" id="customer-address-{$ID}">
<th>{$LABEL}</th> <th>{$LABEL|default:"{intl l='Address %nb' nb={$LOOP_COUNT}}"}</th>
<td> <td>
<ul class="list-address"> <ul class="list-address">
<li> <li>
@@ -117,9 +116,9 @@
</td> </td>
<td> <td>
<div class="group-btn"> <div class="group-btn">
<a href="{url path="/address/update/{$ID}"}" class="btn btn-edit-address" data-toggle="tooltip" title="Edit this address"><i class="icon-pencil"></i> <span>{intl l="Edit"}</span></a> <a href="{url path="/address/update/{$ID}"}" class="btn btn-edit-address" data-toggle="tooltip" title="{intl l="Edit this address"}"><i class="icon-pencil"></i> <span>{intl l="Edit"}</span></a>
{if $DEFAULT != 1} {if $DEFAULT != 1}
<a href="{url path="/address/delete/{$ID}"}" class="btn btn-remove-address remove-address" title="{intl l="Remove this address"}" data-toggle="tooltip"><i class="icon-remove"></i> <span>{intl l="Cancel"}</span></a> <a href="{url path="/address/delete/s{$ID}"}" class="btn btn-remove-address" data-toggle="popover" title="Do you really want to delete this address ?" data-content="And here's some amazing content. It's very engaging. right?" title="{intl l="Remove this address"}" ><i class="icon-remove"></i> <span>{intl l="Cancel"}</span></a>
{/if} {/if}
</div> </div>
</td> </td>
@@ -140,6 +139,7 @@
</div> </div>
<div id="account-orders" class="panel-collapse collapse"> <div id="account-orders" class="panel-collapse collapse">
<div class="panel-body table-responsive"> <div class="panel-body table-responsive">
{ifloop rel="customer.orders"}
<table class="table table-orders" summary="{intl l="List of orders"}"> <table class="table table-orders" summary="{intl l="List of orders"}">
<thead> <thead>
<tr> <tr>
@@ -163,9 +163,10 @@
</tbody> </tbody>
</table> </table>
{/ifloop}
{elseloop rel="customer.orders"} {elseloop rel="customer.orders"}
<div class="orders-warning"> <div class="orders-warning">
<strong>{intl l="Warning"}!</strong> {intl l="You don't have orders yet"} <strong>{intl l="Warning"}!</strong> {intl l="You don't have orders yet."}
</div> </div>
{/elseloop} {/elseloop}
</div> </div>
@@ -175,38 +176,6 @@
</article> </article>
</div><!-- /.layout --> </div><!-- /.layout -->
<div class="modal fade" id="address-delete-modal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h3>{intl l="Delete address"}</h3>
</div>
<div class="modal-body">
{intl l="Do you really want to delete this address ?"}
</div>
<div class="modal-footer">
<a href="#" type="button" class="btn btn-default" data-dismiss="modal" aria-hidden="true"><span class="glyphicon glyphicon-remove"></span> {intl l="No"}</a>
<a href="#" id="address-delete-link" type="submit" class="btn btn-default btn-primary"><span class="glyphicon glyphicon-check"></span> {intl l="Yes"}</a>
</div>
</div>
</div>
</div>
{/block} {/block}
{block name="after-javascript-include"} {block name="after-javascript-include"}{/block}
<script type="text/javascript">
$(document).ready(function(){
$(".remove-address").click(function(e){
e.preventDefault();
$("#address-delete-link").attr("href", $(this).attr("href"));
$('#address-delete-modal').modal('show');
})
})
</script>
{/block}

View File

@@ -4,15 +4,15 @@
{check_auth context="front" roles="CUSTOMER" login_tpl="login"} {check_auth context="front" roles="CUSTOMER" login_tpl="login"}
{/block} {/block}
{block name="breadcrumb"} {* Body Class *}
<nav class="nav-breadcrumb" role="navigation" aria-labelledby="breadcrumb-label"> {block name="body-class"}page-address{/block}
<strong id="breadcrumb-label">{intl l="You are here"}: </strong>
<ul class="breadcrumb" itemprop="breadcrumb"> {* Breadcrumb *}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{navigate to="index"}" itemprop="url"><span itemprop="title">{intl l="Home"}</span></a></li> {block name='no-return-functions' append}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><span itemprop="title">{intl l="Account"}</span></li> {$breadcrumbs = [
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="active"><span itemprop="title">{intl l="Address"}</span></li> ['title' => {intl l="Account"}, 'url'=>{url path="/account"}],
</ul> ['title' => {intl l="Address Update"}, 'url'=>{url path="/address"}]
</nav><!-- /.nav-breadcrumb --> ]}
{/block} {/block}
{block name="main-content"} {block name="main-content"}
@@ -25,7 +25,7 @@
{loop name="customer.update" type="address" customer="current" id="{$address_id}"} {loop name="customer.update" type="address" customer="current" id="{$address_id}"}
<form id="form-address" class="form-horizontal" action="{url path="/address/update/{$address_id}"}" method="post" role="form"> <form id="form-address" class="form-horizontal" action="{url path="/address/update/{$address_id}"}" method="post" role="form">
{form_field form=$form field='success_url'} {form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{url path="/customer/account"}" /> {* the url the user is redirected to on login success *} <input type="hidden" name="{$name}" value="{url path="/account"}" /> {* the url the user is redirected to on login success *}
{/form_field} {/form_field}
{form_field form=$form field='error_message'} {form_field form=$form field='error_message'}

View File

@@ -4,15 +4,15 @@
{check_auth context="front" roles="CUSTOMER" login_tpl="login"} {check_auth context="front" roles="CUSTOMER" login_tpl="login"}
{/block} {/block}
{block name="breadcrumb"} {* Body Class *}
<nav class="nav-breadcrumb" role="navigation" aria-labelledby="breadcrumb-label"> {block name="body-class"}page-address{/block}
<strong id="breadcrumb-label">You are here: </strong>
<ul class="breadcrumb" itemprop="breadcrumb"> {* Breadcrumb *}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{navigate to="index"}" itemprop="url"><span itemprop="title">Home</span></a></li> {block name='no-return-functions' append}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{url path="/customer/account"}" itemprop="url"><span itemprop="title">Account</span></a></li> {$breadcrumbs = [
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="active"><span itemprop="title">{intl l="Address"}</span></li> ['title' => {intl l="Account"}, 'url'=>{url path="/account"}],
</ul> ['title' => {intl l="Address"}, 'url'=>{url path="/address"}]
</nav><!-- /.nav-breadcrumb --> ]}
{/block} {/block}
{block name="main-content"} {block name="main-content"}
@@ -24,7 +24,7 @@
{form name="thelia.address.create"} {form name="thelia.address.create"}
<form id="form-address" class="form-horizontal" action="{url path="/address/create"}" method="post" role="form"> <form id="form-address" class="form-horizontal" action="{url path="/address/create"}" method="post" role="form">
{form_field form=$form field='success_url'} {form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{url path="/customer/account"}" /> {* the url the user is redirected to on login success *} <input type="hidden" name="{$name}" value="{url path="/account"}" /> {* the url the user is redirected to on login success *}
{/form_field} {/form_field}
{form_field form=$form field='error_message'} {form_field form=$form field='error_message'}

View File

@@ -1,19 +0,0 @@
.magnify {
position: relative;
cursor: none
}
.magnify-large {
position: absolute;
display: none;
width: 175px;
height: 175px;
-webkit-box-shadow: 0 0 0 7px rgba(255, 255, 255, 0.85), 0 0 7px 7px rgba(0, 0, 0, 0.25), inset 0 0 40px 2px rgba(0, 0, 0, 0.25);
-moz-box-shadow: 0 0 0 7px rgba(255, 255, 255, 0.85), 0 0 7px 7px rgba(0, 0, 0, 0.25), inset 0 0 40px 2px rgba(0, 0, 0, 0.25);
box-shadow: 0 0 0 7px rgba(255, 255, 255, 0.85), 0 0 7px 7px rgba(0, 0, 0, 0.25), inset 0 0 40px 2px rgba(0, 0, 0, 0.25);
-webkit-border-radius: 100%;
-moz-border-radius: 100%;
border-radius: 100%
}

View File

@@ -1 +0,0 @@
.magnify{position:relative;cursor:none}.magnify-large{position:absolute;display:none;width:175px;height:175px;-webkit-box-shadow:0 0 0 7px rgba(255,255,255,0.85),0 0 7px 7px rgba(0,0,0,0.25),inset 0 0 40px 2px rgba(0,0,0,0.25);-moz-box-shadow:0 0 0 7px rgba(255,255,255,0.85),0 0 7px 7px rgba(0,0,0,0.25),inset 0 0 40px 2px rgba(0,0,0,0.25);box-shadow:0 0 0 7px rgba(255,255,255,0.85),0 0 7px 7px rgba(0,0,0,0.25),inset 0 0 40px 2px rgba(0,0,0,0.25);-webkit-border-radius:100%;-moz-border-radius:100%;border-radius:100%}

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -1,126 +0,0 @@
/* ========================================================================
* Bootstrap: affix.js v3.0.0
* http://twbs.github.com/bootstrap/javascript.html#affix
* ========================================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================================== */
+function ($) { "use strict";
// AFFIX CLASS DEFINITION
// ======================
var Affix = function (element, options) {
this.options = $.extend({}, Affix.DEFAULTS, options)
this.$window = $(window)
.on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
.on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
this.$element = $(element)
this.affixed =
this.unpin = null
this.checkPosition()
}
Affix.RESET = 'affix affix-top affix-bottom'
Affix.DEFAULTS = {
offset: 0
}
Affix.prototype.checkPositionWithEventLoop = function () {
setTimeout($.proxy(this.checkPosition, this), 1)
}
Affix.prototype.checkPosition = function () {
if (!this.$element.is(':visible')) return
var scrollHeight = $(document).height()
var scrollTop = this.$window.scrollTop()
var position = this.$element.offset()
var offset = this.options.offset
var offsetTop = offset.top
var offsetBottom = offset.bottom
if (typeof offset != 'object') offsetBottom = offsetTop = offset
if (typeof offsetTop == 'function') offsetTop = offset.top()
if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()
var affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ? false :
offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 'bottom' :
offsetTop != null && (scrollTop <= offsetTop) ? 'top' : false
if (this.affixed === affix) return
if (this.unpin) this.$element.css('top', '')
this.affixed = affix
this.unpin = affix == 'bottom' ? position.top - scrollTop : null
this.$element.removeClass(Affix.RESET).addClass('affix' + (affix ? '-' + affix : ''))
if (affix == 'bottom') {
this.$element.offset({ top: document.body.offsetHeight - offsetBottom - this.$element.height() })
}
}
// AFFIX PLUGIN DEFINITION
// =======================
var old = $.fn.affix
$.fn.affix = function (option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.affix')
var options = typeof option == 'object' && option
if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.affix.Constructor = Affix
// AFFIX NO CONFLICT
// =================
$.fn.affix.noConflict = function () {
$.fn.affix = old
return this
}
// AFFIX DATA-API
// ==============
$(window).on('load', function () {
$('[data-spy="affix"]').each(function () {
var $spy = $(this)
var data = $spy.data()
data.offset = data.offset || {}
if (data.offsetBottom) data.offset.bottom = data.offsetBottom
if (data.offsetTop) data.offset.top = data.offsetTop
$spy.affix(data)
})
})
}(window.jQuery);

View File

@@ -1,98 +0,0 @@
/* ========================================================================
* Bootstrap: alert.js v3.0.0
* http://twbs.github.com/bootstrap/javascript.html#alerts
* ========================================================================
* Copyright 2013 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================================== */
+function ($) { "use strict";
// ALERT CLASS DEFINITION
// ======================
var dismiss = '[data-dismiss="alert"]'
var Alert = function (el) {
$(el).on('click', dismiss, this.close)
}
Alert.prototype.close = function (e) {
var $this = $(this)
var selector = $this.attr('data-target')
if (!selector) {
selector = $this.attr('href')
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
}
var $parent = $(selector)
if (e) e.preventDefault()
if (!$parent.length) {
$parent = $this.hasClass('alert') ? $this : $this.parent()
}
$parent.trigger(e = $.Event('close.bs.alert'))
if (e.isDefaultPrevented()) return
$parent.removeClass('in')
function removeElement() {
$parent.trigger('closed.bs.alert').remove()
}
$.support.transition && $parent.hasClass('fade') ?
$parent
.one($.support.transition.end, removeElement)
.emulateTransitionEnd(150) :
removeElement()
}
// ALERT PLUGIN DEFINITION
// =======================
var old = $.fn.alert
$.fn.alert = function (option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.alert')
if (!data) $this.data('bs.alert', (data = new Alert(this)))
if (typeof option == 'string') data[option].call($this)
})
}
$.fn.alert.Constructor = Alert
// ALERT NO CONFLICT
// =================
$.fn.alert.noConflict = function () {
$.fn.alert = old
return this
}
// ALERT DATA-API
// ==============
$(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
}(window.jQuery);

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -1,109 +0,0 @@
/* ========================================================================
* Bootstrap: button.js v3.0.0
* http://twbs.github.com/bootstrap/javascript.html#buttons
* ========================================================================
* Copyright 2013 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================================== */
+function ($) { "use strict";
// BUTTON PUBLIC CLASS DEFINITION
// ==============================
var Button = function (element, options) {
this.$element = $(element)
this.options = $.extend({}, Button.DEFAULTS, options)
}
Button.DEFAULTS = {
loadingText: 'loading...'
}
Button.prototype.setState = function (state) {
var d = 'disabled'
var $el = this.$element
var val = $el.is('input') ? 'val' : 'html'
var data = $el.data()
state = state + 'Text'
if (!data.resetText) $el.data('resetText', $el[val]())
$el[val](data[state] || this.options[state])
// push to event loop to allow forms to submit
setTimeout(function () {
state == 'loadingText' ?
$el.addClass(d).attr(d, d) :
$el.removeClass(d).removeAttr(d);
}, 0)
}
Button.prototype.toggle = function () {
var $parent = this.$element.closest('[data-toggle="buttons"]')
if ($parent.length) {
var $input = this.$element.find('input')
.prop('checked', !this.$element.hasClass('active'))
.trigger('change')
if ($input.prop('type') === 'radio') $parent.find('.active').removeClass('active')
}
this.$element.toggleClass('active')
}
// BUTTON PLUGIN DEFINITION
// ========================
var old = $.fn.button
$.fn.button = function (option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.button')
var options = typeof option == 'object' && option
if (!data) $this.data('bs.button', (data = new Button(this, options)))
if (option == 'toggle') data.toggle()
else if (option) data.setState(option)
})
}
$.fn.button.Constructor = Button
// BUTTON NO CONFLICT
// ==================
$.fn.button.noConflict = function () {
$.fn.button = old
return this
}
// BUTTON DATA-API
// ===============
$(document).on('click.bs.button.data-api', '[data-toggle^=button]', function (e) {
var $btn = $(e.target)
if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
$btn.button('toggle')
e.preventDefault()
})
}(window.jQuery);

View File

@@ -1,217 +0,0 @@
/* ========================================================================
* Bootstrap: carousel.js v3.0.0
* http://twbs.github.com/bootstrap/javascript.html#carousel
* ========================================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================================== */
+function ($) { "use strict";
// CAROUSEL CLASS DEFINITION
// =========================
var Carousel = function (element, options) {
this.$element = $(element)
this.$indicators = this.$element.find('.carousel-indicators')
this.options = options
this.paused =
this.sliding =
this.interval =
this.$active =
this.$items = null
this.options.pause == 'hover' && this.$element
.on('mouseenter', $.proxy(this.pause, this))
.on('mouseleave', $.proxy(this.cycle, this))
}
Carousel.DEFAULTS = {
interval: 5000
, pause: 'hover'
, wrap: true
}
Carousel.prototype.cycle = function (e) {
e || (this.paused = false)
this.interval && clearInterval(this.interval)
this.options.interval
&& !this.paused
&& (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
return this
}
Carousel.prototype.getActiveIndex = function () {
this.$active = this.$element.find('.item.active')
this.$items = this.$active.parent().children()
return this.$items.index(this.$active)
}
Carousel.prototype.to = function (pos) {
var that = this
var activeIndex = this.getActiveIndex()
if (pos > (this.$items.length - 1) || pos < 0) return
if (this.sliding) return this.$element.one('slid', function () { that.to(pos) })
if (activeIndex == pos) return this.pause().cycle()
return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))
}
Carousel.prototype.pause = function (e) {
e || (this.paused = true)
if (this.$element.find('.next, .prev').length && $.support.transition.end) {
this.$element.trigger($.support.transition.end)
this.cycle(true)
}
this.interval = clearInterval(this.interval)
return this
}
Carousel.prototype.next = function () {
if (this.sliding) return
return this.slide('next')
}
Carousel.prototype.prev = function () {
if (this.sliding) return
return this.slide('prev')
}
Carousel.prototype.slide = function (type, next) {
var $active = this.$element.find('.item.active')
var $next = next || $active[type]()
var isCycling = this.interval
var direction = type == 'next' ? 'left' : 'right'
var fallback = type == 'next' ? 'first' : 'last'
var that = this
if (!$next.length) {
if (!this.options.wrap) return
$next = this.$element.find('.item')[fallback]()
}
this.sliding = true
isCycling && this.pause()
var e = $.Event('slide.bs.carousel', { relatedTarget: $next[0], direction: direction })
if ($next.hasClass('active')) return
if (this.$indicators.length) {
this.$indicators.find('.active').removeClass('active')
this.$element.one('slid', function () {
var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()])
$nextIndicator && $nextIndicator.addClass('active')
})
}
if ($.support.transition && this.$element.hasClass('slide')) {
this.$element.trigger(e)
if (e.isDefaultPrevented()) return
$next.addClass(type)
$next[0].offsetWidth // force reflow
$active.addClass(direction)
$next.addClass(direction)
$active
.one($.support.transition.end, function () {
$next.removeClass([type, direction].join(' ')).addClass('active')
$active.removeClass(['active', direction].join(' '))
that.sliding = false
setTimeout(function () { that.$element.trigger('slid') }, 0)
})
.emulateTransitionEnd(600)
} else {
this.$element.trigger(e)
if (e.isDefaultPrevented()) return
$active.removeClass('active')
$next.addClass('active')
this.sliding = false
this.$element.trigger('slid')
}
isCycling && this.cycle()
return this
}
// CAROUSEL PLUGIN DEFINITION
// ==========================
var old = $.fn.carousel
$.fn.carousel = function (option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.carousel')
var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
var action = typeof option == 'string' ? option : options.slide
if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
if (typeof option == 'number') data.to(option)
else if (action) data[action]()
else if (options.interval) data.pause().cycle()
})
}
$.fn.carousel.Constructor = Carousel
// CAROUSEL NO CONFLICT
// ====================
$.fn.carousel.noConflict = function () {
$.fn.carousel = old
return this
}
// CAROUSEL DATA-API
// =================
$(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {
var $this = $(this), href
var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
var options = $.extend({}, $target.data(), $this.data())
var slideIndex = $this.attr('data-slide-to')
if (slideIndex) options.interval = false
$target.carousel(options)
if (slideIndex = $this.attr('data-slide-to')) {
$target.data('bs.carousel').to(slideIndex)
}
e.preventDefault()
})
$(window).on('load', function () {
$('[data-ride="carousel"]').each(function () {
var $carousel = $(this)
$carousel.carousel($carousel.data())
})
})
}(window.jQuery);

View File

@@ -1,179 +0,0 @@
/* ========================================================================
* Bootstrap: collapse.js v3.0.0
* http://twbs.github.com/bootstrap/javascript.html#collapse
* ========================================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================================== */
+function ($) { "use strict";
// COLLAPSE PUBLIC CLASS DEFINITION
// ================================
var Collapse = function (element, options) {
this.$element = $(element)
this.options = $.extend({}, Collapse.DEFAULTS, options)
this.transitioning = null
if (this.options.parent) this.$parent = $(this.options.parent)
if (this.options.toggle) this.toggle()
}
Collapse.DEFAULTS = {
toggle: true
}
Collapse.prototype.dimension = function () {
var hasWidth = this.$element.hasClass('width')
return hasWidth ? 'width' : 'height'
}
Collapse.prototype.show = function () {
if (this.transitioning || this.$element.hasClass('in')) return
var startEvent = $.Event('show.bs.collapse')
this.$element.trigger(startEvent)
if (startEvent.isDefaultPrevented()) return
var actives = this.$parent && this.$parent.find('> .panel > .in')
if (actives && actives.length) {
var hasData = actives.data('bs.collapse')
if (hasData && hasData.transitioning) return
actives.collapse('hide')
hasData || actives.data('bs.collapse', null)
}
var dimension = this.dimension()
this.$element
.removeClass('collapse')
.addClass('collapsing')
[dimension](0)
this.transitioning = 1
var complete = function () {
this.$element
.removeClass('collapsing')
.addClass('in')
[dimension]('auto')
this.transitioning = 0
this.$element.trigger('shown.bs.collapse')
}
if (!$.support.transition) return complete.call(this)
var scrollSize = $.camelCase(['scroll', dimension].join('-'))
this.$element
.one($.support.transition.end, $.proxy(complete, this))
.emulateTransitionEnd(350)
[dimension](this.$element[0][scrollSize])
}
Collapse.prototype.hide = function () {
if (this.transitioning || !this.$element.hasClass('in')) return
var startEvent = $.Event('hide.bs.collapse')
this.$element.trigger(startEvent)
if (startEvent.isDefaultPrevented()) return
var dimension = this.dimension()
this.$element
[dimension](this.$element[dimension]())
[0].offsetHeight
this.$element
.addClass('collapsing')
.removeClass('collapse')
.removeClass('in')
this.transitioning = 1
var complete = function () {
this.transitioning = 0
this.$element
.trigger('hidden.bs.collapse')
.removeClass('collapsing')
.addClass('collapse')
}
if (!$.support.transition) return complete.call(this)
this.$element
[dimension](0)
.one($.support.transition.end, $.proxy(complete, this))
.emulateTransitionEnd(350)
}
Collapse.prototype.toggle = function () {
this[this.$element.hasClass('in') ? 'hide' : 'show']()
}
// COLLAPSE PLUGIN DEFINITION
// ==========================
var old = $.fn.collapse
$.fn.collapse = function (option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.collapse')
var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.collapse.Constructor = Collapse
// COLLAPSE NO CONFLICT
// ====================
$.fn.collapse.noConflict = function () {
$.fn.collapse = old
return this
}
// COLLAPSE DATA-API
// =================
$(document).on('click.bs.collapse.data-api', '[data-toggle=collapse]', function (e) {
var $this = $(this), href
var target = $this.attr('data-target')
|| e.preventDefault()
|| (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
var $target = $(target)
var data = $target.data('bs.collapse')
var option = data ? 'toggle' : $this.data()
var parent = $this.attr('data-parent')
var $parent = parent && $(parent)
if (!data || !data.transitioning) {
if ($parent) $parent.find('[data-toggle=collapse][data-parent="' + parent + '"]').not($this).addClass('collapsed')
$this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
}
$target.collapse(option)
})
}(window.jQuery);

View File

@@ -1,154 +0,0 @@
/* ========================================================================
* Bootstrap: dropdown.js v3.0.0
* http://twbs.github.com/bootstrap/javascript.html#dropdowns
* ========================================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================================== */
+function ($) { "use strict";
// DROPDOWN CLASS DEFINITION
// =========================
var backdrop = '.dropdown-backdrop'
var toggle = '[data-toggle=dropdown]'
var Dropdown = function (element) {
var $el = $(element).on('click.bs.dropdown', this.toggle)
}
Dropdown.prototype.toggle = function (e) {
var $this = $(this)
if ($this.is('.disabled, :disabled')) return
var $parent = getParent($this)
var isActive = $parent.hasClass('open')
clearMenus()
if (!isActive) {
if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
// if mobile we we use a backdrop because click events don't delegate
$('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
}
$parent.trigger(e = $.Event('show.bs.dropdown'))
if (e.isDefaultPrevented()) return
$parent
.toggleClass('open')
.trigger('shown.bs.dropdown')
$this.focus()
}
return false
}
Dropdown.prototype.keydown = function (e) {
if (!/(38|40|27)/.test(e.keyCode)) return
var $this = $(this)
e.preventDefault()
e.stopPropagation()
if ($this.is('.disabled, :disabled')) return
var $parent = getParent($this)
var isActive = $parent.hasClass('open')
if (!isActive || (isActive && e.keyCode == 27)) {
if (e.which == 27) $parent.find(toggle).focus()
return $this.click()
}
var $items = $('[role=menu] li:not(.divider):visible a', $parent)
if (!$items.length) return
var index = $items.index($items.filter(':focus'))
if (e.keyCode == 38 && index > 0) index-- // up
if (e.keyCode == 40 && index < $items.length - 1) index++ // down
if (!~index) index=0
$items.eq(index).focus()
}
function clearMenus() {
$(backdrop).remove()
$(toggle).each(function (e) {
var $parent = getParent($(this))
if (!$parent.hasClass('open')) return
$parent.trigger(e = $.Event('hide.bs.dropdown'))
if (e.isDefaultPrevented()) return
$parent.removeClass('open').trigger('hidden.bs.dropdown')
})
}
function getParent($this) {
var selector = $this.attr('data-target')
if (!selector) {
selector = $this.attr('href')
selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
}
var $parent = selector && $(selector)
return $parent && $parent.length ? $parent : $this.parent()
}
// DROPDOWN PLUGIN DEFINITION
// ==========================
var old = $.fn.dropdown
$.fn.dropdown = function (option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('dropdown')
if (!data) $this.data('dropdown', (data = new Dropdown(this)))
if (typeof option == 'string') data[option].call($this)
})
}
$.fn.dropdown.Constructor = Dropdown
// DROPDOWN NO CONFLICT
// ====================
$.fn.dropdown.noConflict = function () {
$.fn.dropdown = old
return this
}
// APPLY TO STANDARD DROPDOWN ELEMENTS
// ===================================
$(document)
.on('click.bs.dropdown.data-api', clearMenus)
.on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
.on('click.bs.dropdown.data-api' , toggle, Dropdown.prototype.toggle)
.on('keydown.bs.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)
}(window.jQuery);

View File

@@ -1,246 +0,0 @@
/* ========================================================================
* Bootstrap: modal.js v3.0.0
* http://twbs.github.com/bootstrap/javascript.html#modals
* ========================================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================================== */
+function ($) { "use strict";
// MODAL CLASS DEFINITION
// ======================
var Modal = function (element, options) {
this.options = options
this.$element = $(element)
this.$backdrop =
this.isShown = null
if (this.options.remote) this.$element.load(this.options.remote)
}
Modal.DEFAULTS = {
backdrop: true
, keyboard: true
, show: true
}
Modal.prototype.toggle = function (_relatedTarget) {
return this[!this.isShown ? 'show' : 'hide'](_relatedTarget)
}
Modal.prototype.show = function (_relatedTarget) {
var that = this
var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
this.$element.trigger(e)
if (this.isShown || e.isDefaultPrevented()) return
this.isShown = true
this.escape()
this.$element.on('click.dismiss.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
this.backdrop(function () {
var transition = $.support.transition && that.$element.hasClass('fade')
if (!that.$element.parent().length) {
that.$element.appendTo(document.body) // don't move modals dom position
}
that.$element.show()
if (transition) {
that.$element[0].offsetWidth // force reflow
}
that.$element
.addClass('in')
.attr('aria-hidden', false)
that.enforceFocus()
var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
transition ?
that.$element.find('.modal-dialog') // wait for modal to slide in
.one($.support.transition.end, function () {
that.$element.focus().trigger(e)
})
.emulateTransitionEnd(300) :
that.$element.focus().trigger(e)
})
}
Modal.prototype.hide = function (e) {
if (e) e.preventDefault()
e = $.Event('hide.bs.modal')
this.$element.trigger(e)
if (!this.isShown || e.isDefaultPrevented()) return
this.isShown = false
this.escape()
$(document).off('focusin.bs.modal')
this.$element
.removeClass('in')
.attr('aria-hidden', true)
.off('click.dismiss.modal')
$.support.transition && this.$element.hasClass('fade') ?
this.$element
.one($.support.transition.end, $.proxy(this.hideModal, this))
.emulateTransitionEnd(300) :
this.hideModal()
}
Modal.prototype.enforceFocus = function () {
$(document)
.off('focusin.bs.modal') // guard against infinite focus loop
.on('focusin.bs.modal', $.proxy(function (e) {
if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
this.$element.focus()
}
}, this))
}
Modal.prototype.escape = function () {
if (this.isShown && this.options.keyboard) {
this.$element.on('keyup.dismiss.bs.modal', $.proxy(function (e) {
e.which == 27 && this.hide()
}, this))
} else if (!this.isShown) {
this.$element.off('keyup.dismiss.bs.modal')
}
}
Modal.prototype.hideModal = function () {
var that = this
this.$element.hide()
this.backdrop(function () {
that.removeBackdrop()
that.$element.trigger('hidden.bs.modal')
})
}
Modal.prototype.removeBackdrop = function () {
this.$backdrop && this.$backdrop.remove()
this.$backdrop = null
}
Modal.prototype.backdrop = function (callback) {
var that = this
var animate = this.$element.hasClass('fade') ? 'fade' : ''
if (this.isShown && this.options.backdrop) {
var doAnimate = $.support.transition && animate
this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
.appendTo(document.body)
this.$element.on('click.dismiss.modal', $.proxy(function (e) {
if (e.target !== e.currentTarget) return
this.options.backdrop == 'static'
? this.$element[0].focus.call(this.$element[0])
: this.hide.call(this)
}, this))
if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
this.$backdrop.addClass('in')
if (!callback) return
doAnimate ?
this.$backdrop
.one($.support.transition.end, callback)
.emulateTransitionEnd(150) :
callback()
} else if (!this.isShown && this.$backdrop) {
this.$backdrop.removeClass('in')
$.support.transition && this.$element.hasClass('fade')?
this.$backdrop
.one($.support.transition.end, callback)
.emulateTransitionEnd(150) :
callback()
} else if (callback) {
callback()
}
}
// MODAL PLUGIN DEFINITION
// =======================
var old = $.fn.modal
$.fn.modal = function (option, _relatedTarget) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.modal')
var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
if (typeof option == 'string') data[option](_relatedTarget)
else if (options.show) data.show(_relatedTarget)
})
}
$.fn.modal.Constructor = Modal
// MODAL NO CONFLICT
// =================
$.fn.modal.noConflict = function () {
$.fn.modal = old
return this
}
// MODAL DATA-API
// ==============
$(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
var $this = $(this)
var href = $this.attr('href')
var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
var option = $target.data('modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
e.preventDefault()
$target
.modal(option, this)
.one('hide', function () {
$this.is(':visible') && $this.focus()
})
})
$(document)
.on('show.bs.modal', '.modal', function () { $(document.body).addClass('modal-open') })
.on('hidden.bs.modal', '.modal', function () { $(document.body).removeClass('modal-open') })
}(window.jQuery);

View File

@@ -1,117 +0,0 @@
/* ========================================================================
* Bootstrap: popover.js v3.0.0
* http://twbs.github.com/bootstrap/javascript.html#popovers
* ========================================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================================== */
+function ($) { "use strict";
// POPOVER PUBLIC CLASS DEFINITION
// ===============================
var Popover = function (element, options) {
this.init('popover', element, options)
}
if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
Popover.DEFAULTS = $.extend({} , $.fn.tooltip.Constructor.DEFAULTS, {
placement: 'right'
, trigger: 'click'
, content: ''
, template: '<div class="popover"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
})
// NOTE: POPOVER EXTENDS tooltip.js
// ================================
Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
Popover.prototype.constructor = Popover
Popover.prototype.getDefaults = function () {
return Popover.DEFAULTS
}
Popover.prototype.setContent = function () {
var $tip = this.tip()
var title = this.getTitle()
var content = this.getContent()
$tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
$tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content)
$tip.removeClass('fade top bottom left right in')
// IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
// this manually by checking the contents.
if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
}
Popover.prototype.hasContent = function () {
return this.getTitle() || this.getContent()
}
Popover.prototype.getContent = function () {
var $e = this.$element
var o = this.options
return $e.attr('data-content')
|| (typeof o.content == 'function' ?
o.content.call($e[0]) :
o.content)
}
Popover.prototype.arrow = function () {
return this.$arrow = this.$arrow || this.tip().find('.arrow')
}
Popover.prototype.tip = function () {
if (!this.$tip) this.$tip = $(this.options.template)
return this.$tip
}
// POPOVER PLUGIN DEFINITION
// =========================
var old = $.fn.popover
$.fn.popover = function (option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.popover')
var options = typeof option == 'object' && option
if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.popover.Constructor = Popover
// POPOVER NO CONFLICT
// ===================
$.fn.popover.noConflict = function () {
$.fn.popover = old
return this
}
}(window.jQuery);

View File

@@ -1,158 +0,0 @@
/* ========================================================================
* Bootstrap: scrollspy.js v3.0.0
* http://twbs.github.com/bootstrap/javascript.html#scrollspy
* ========================================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================================== */
+function ($) { "use strict";
// SCROLLSPY CLASS DEFINITION
// ==========================
function ScrollSpy(element, options) {
var href
var process = $.proxy(this.process, this)
this.$element = $(element).is('body') ? $(window) : $(element)
this.$body = $('body')
this.$scrollElement = this.$element.on('scroll.bs.scroll-spy.data-api', process)
this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
this.selector = (this.options.target
|| ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
|| '') + ' .nav li > a'
this.offsets = $([])
this.targets = $([])
this.activeTarget = null
this.refresh()
this.process()
}
ScrollSpy.DEFAULTS = {
offset: 10
}
ScrollSpy.prototype.refresh = function () {
var offsetMethod = this.$element[0] == window ? 'offset' : 'position'
this.offsets = $([])
this.targets = $([])
var self = this
var $targets = this.$body
.find(this.selector)
.map(function () {
var $el = $(this)
var href = $el.data('target') || $el.attr('href')
var $href = /^#\w/.test(href) && $(href)
return ($href
&& $href.length
&& [[ $href[offsetMethod]().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]]) || null
})
.sort(function (a, b) { return a[0] - b[0] })
.each(function () {
self.offsets.push(this[0])
self.targets.push(this[1])
})
}
ScrollSpy.prototype.process = function () {
var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
var scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
var maxScroll = scrollHeight - this.$scrollElement.height()
var offsets = this.offsets
var targets = this.targets
var activeTarget = this.activeTarget
var i
if (scrollTop >= maxScroll) {
return activeTarget != (i = targets.last()[0]) && this.activate(i)
}
for (i = offsets.length; i--;) {
activeTarget != targets[i]
&& scrollTop >= offsets[i]
&& (!offsets[i + 1] || scrollTop <= offsets[i + 1])
&& this.activate( targets[i] )
}
}
ScrollSpy.prototype.activate = function (target) {
this.activeTarget = target
$(this.selector)
.parents('.active')
.removeClass('active')
var selector = this.selector
+ '[data-target="' + target + '"],'
+ this.selector + '[href="' + target + '"]'
var active = $(selector)
.parents('li')
.addClass('active')
if (active.parent('.dropdown-menu').length) {
active = active
.closest('li.dropdown')
.addClass('active')
}
active.trigger('activate')
}
// SCROLLSPY PLUGIN DEFINITION
// ===========================
var old = $.fn.scrollspy
$.fn.scrollspy = function (option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.scrollspy')
var options = typeof option == 'object' && option
if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.scrollspy.Constructor = ScrollSpy
// SCROLLSPY NO CONFLICT
// =====================
$.fn.scrollspy.noConflict = function () {
$.fn.scrollspy = old
return this
}
// SCROLLSPY DATA-API
// ==================
$(window).on('load', function () {
$('[data-spy="scroll"]').each(function () {
var $spy = $(this)
$spy.scrollspy($spy.data())
})
})
}(window.jQuery);

View File

@@ -1,135 +0,0 @@
/* ========================================================================
* Bootstrap: tab.js v3.0.0
* http://twbs.github.com/bootstrap/javascript.html#tabs
* ========================================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================================== */
+function ($) { "use strict";
// TAB CLASS DEFINITION
// ====================
var Tab = function (element) {
this.element = $(element)
}
Tab.prototype.show = function () {
var $this = this.element
var $ul = $this.closest('ul:not(.dropdown-menu)')
var selector = $this.attr('data-target')
if (!selector) {
selector = $this.attr('href')
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
}
if ($this.parent('li').hasClass('active')) return
var previous = $ul.find('.active:last a')[0]
var e = $.Event('show.bs.tab', {
relatedTarget: previous
})
$this.trigger(e)
if (e.isDefaultPrevented()) return
var $target = $(selector)
this.activate($this.parent('li'), $ul)
this.activate($target, $target.parent(), function () {
$this.trigger({
type: 'shown.bs.tab'
, relatedTarget: previous
})
})
}
Tab.prototype.activate = function (element, container, callback) {
var $active = container.find('> .active')
var transition = callback
&& $.support.transition
&& $active.hasClass('fade')
function next() {
$active
.removeClass('active')
.find('> .dropdown-menu > .active')
.removeClass('active')
element.addClass('active')
if (transition) {
element[0].offsetWidth // reflow for transition
element.addClass('in')
} else {
element.removeClass('fade')
}
if (element.parent('.dropdown-menu')) {
element.closest('li.dropdown').addClass('active')
}
callback && callback()
}
transition ?
$active
.one($.support.transition.end, next)
.emulateTransitionEnd(150) :
next()
$active.removeClass('in')
}
// TAB PLUGIN DEFINITION
// =====================
var old = $.fn.tab
$.fn.tab = function ( option ) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.tab')
if (!data) $this.data('bs.tab', (data = new Tab(this)))
if (typeof option == 'string') data[option]()
})
}
$.fn.tab.Constructor = Tab
// TAB NO CONFLICT
// ===============
$.fn.tab.noConflict = function () {
$.fn.tab = old
return this
}
// TAB DATA-API
// ============
$(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
e.preventDefault()
$(this).tab('show')
})
}(window.jQuery);

View File

@@ -1,386 +0,0 @@
/* ========================================================================
* Bootstrap: tooltip.js v3.0.0
* http://twbs.github.com/bootstrap/javascript.html#tooltip
* Inspired by the original jQuery.tipsy by Jason Frame
* ========================================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================================== */
+function ($) { "use strict";
// TOOLTIP PUBLIC CLASS DEFINITION
// ===============================
var Tooltip = function (element, options) {
this.type =
this.options =
this.enabled =
this.timeout =
this.hoverState =
this.$element = null
this.init('tooltip', element, options)
}
Tooltip.DEFAULTS = {
animation: true
, placement: 'top'
, selector: false
, template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
, trigger: 'hover focus'
, title: ''
, delay: 0
, html: false
, container: false
}
Tooltip.prototype.init = function (type, element, options) {
this.enabled = true
this.type = type
this.$element = $(element)
this.options = this.getOptions(options)
var triggers = this.options.trigger.split(' ')
for (var i = triggers.length; i--;) {
var trigger = triggers[i]
if (trigger == 'click') {
this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
} else if (trigger != 'manual') {
var eventIn = trigger == 'hover' ? 'mouseenter' : 'focus'
var eventOut = trigger == 'hover' ? 'mouseleave' : 'blur'
this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
}
}
this.options.selector ?
(this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
this.fixTitle()
}
Tooltip.prototype.getDefaults = function () {
return Tooltip.DEFAULTS
}
Tooltip.prototype.getOptions = function (options) {
options = $.extend({}, this.getDefaults(), this.$element.data(), options)
if (options.delay && typeof options.delay == 'number') {
options.delay = {
show: options.delay
, hide: options.delay
}
}
return options
}
Tooltip.prototype.getDelegateOptions = function () {
var options = {}
var defaults = this.getDefaults()
this._options && $.each(this._options, function (key, value) {
if (defaults[key] != value) options[key] = value
})
return options
}
Tooltip.prototype.enter = function (obj) {
var self = obj instanceof this.constructor ?
obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)
clearTimeout(self.timeout)
self.hoverState = 'in'
if (!self.options.delay || !self.options.delay.show) return self.show()
self.timeout = setTimeout(function () {
if (self.hoverState == 'in') self.show()
}, self.options.delay.show)
}
Tooltip.prototype.leave = function (obj) {
var self = obj instanceof this.constructor ?
obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)
clearTimeout(self.timeout)
self.hoverState = 'out'
if (!self.options.delay || !self.options.delay.hide) return self.hide()
self.timeout = setTimeout(function () {
if (self.hoverState == 'out') self.hide()
}, self.options.delay.hide)
}
Tooltip.prototype.show = function () {
var e = $.Event('show.bs.'+ this.type)
if (this.hasContent() && this.enabled) {
this.$element.trigger(e)
if (e.isDefaultPrevented()) return
var $tip = this.tip()
this.setContent()
if (this.options.animation) $tip.addClass('fade')
var placement = typeof this.options.placement == 'function' ?
this.options.placement.call(this, $tip[0], this.$element[0]) :
this.options.placement
var autoToken = /\s?auto?\s?/i
var autoPlace = autoToken.test(placement)
if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
$tip
.detach()
.css({ top: 0, left: 0, display: 'block' })
.addClass(placement)
this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
var pos = this.getPosition()
var actualWidth = $tip[0].offsetWidth
var actualHeight = $tip[0].offsetHeight
if (autoPlace) {
var $parent = this.$element.parent()
var orgPlacement = placement
var docScroll = document.documentElement.scrollTop || document.body.scrollTop
var parentWidth = this.options.container == 'body' ? window.innerWidth : $parent.outerWidth()
var parentHeight = this.options.container == 'body' ? window.innerHeight : $parent.outerHeight()
var parentLeft = this.options.container == 'body' ? 0 : $parent.offset().left
placement = placement == 'bottom' && pos.top + pos.height + actualHeight - docScroll > parentHeight ? 'top' :
placement == 'top' && pos.top - docScroll - actualHeight < 0 ? 'bottom' :
placement == 'right' && pos.right + actualWidth > parentWidth ? 'left' :
placement == 'left' && pos.left - actualWidth < parentLeft ? 'right' :
placement
$tip
.removeClass(orgPlacement)
.addClass(placement)
}
var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
this.applyPlacement(calculatedOffset, placement)
this.$element.trigger('shown.bs.' + this.type)
}
}
Tooltip.prototype.applyPlacement = function(offset, placement) {
var replace
var $tip = this.tip()
var width = $tip[0].offsetWidth
var height = $tip[0].offsetHeight
// manually read margins because getBoundingClientRect includes difference
var marginTop = parseInt($tip.css('margin-top'), 10)
var marginLeft = parseInt($tip.css('margin-left'), 10)
// we must check for NaN for ie 8/9
if (isNaN(marginTop)) marginTop = 0
if (isNaN(marginLeft)) marginLeft = 0
offset.top = offset.top + marginTop
offset.left = offset.left + marginLeft
$tip
.offset(offset)
.addClass('in')
// check to see if placing tip in new offset caused the tip to resize itself
var actualWidth = $tip[0].offsetWidth
var actualHeight = $tip[0].offsetHeight
if (placement == 'top' && actualHeight != height) {
replace = true
offset.top = offset.top + height - actualHeight
}
if (/bottom|top/.test(placement)) {
var delta = 0
if (offset.left < 0) {
delta = offset.left * -2
offset.left = 0
$tip.offset(offset)
actualWidth = $tip[0].offsetWidth
actualHeight = $tip[0].offsetHeight
}
this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')
} else {
this.replaceArrow(actualHeight - height, actualHeight, 'top')
}
if (replace) $tip.offset(offset)
}
Tooltip.prototype.replaceArrow = function(delta, dimension, position) {
this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + "%") : '')
}
Tooltip.prototype.setContent = function () {
var $tip = this.tip()
var title = this.getTitle()
$tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
$tip.removeClass('fade in top bottom left right')
}
Tooltip.prototype.hide = function () {
var that = this
var $tip = this.tip()
var e = $.Event('hide.bs.' + this.type)
function complete() {
if (that.hoverState != 'in') $tip.detach()
}
this.$element.trigger(e)
if (e.isDefaultPrevented()) return
$tip.removeClass('in')
$.support.transition && this.$tip.hasClass('fade') ?
$tip
.one($.support.transition.end, complete)
.emulateTransitionEnd(150) :
complete()
this.$element.trigger('hidden.bs.' + this.type)
return this
}
Tooltip.prototype.fixTitle = function () {
var $e = this.$element
if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
$e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
}
}
Tooltip.prototype.hasContent = function () {
return this.getTitle()
}
Tooltip.prototype.getPosition = function () {
var el = this.$element[0]
return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {
width: el.offsetWidth
, height: el.offsetHeight
}, this.$element.offset())
}
Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
/* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
}
Tooltip.prototype.getTitle = function () {
var title
var $e = this.$element
var o = this.options
title = $e.attr('data-original-title')
|| (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
return title
}
Tooltip.prototype.tip = function () {
return this.$tip = this.$tip || $(this.options.template)
}
Tooltip.prototype.arrow = function () {
return this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')
}
Tooltip.prototype.validate = function () {
if (!this.$element[0].parentNode) {
this.hide()
this.$element = null
this.options = null
}
}
Tooltip.prototype.enable = function () {
this.enabled = true
}
Tooltip.prototype.disable = function () {
this.enabled = false
}
Tooltip.prototype.toggleEnabled = function () {
this.enabled = !this.enabled
}
Tooltip.prototype.toggle = function (e) {
var self = e ? $(e.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) : this
self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
}
Tooltip.prototype.destroy = function () {
this.hide().$element.off('.' + this.type).removeData('bs.' + this.type)
}
// TOOLTIP PLUGIN DEFINITION
// =========================
var old = $.fn.tooltip
$.fn.tooltip = function (option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.tooltip')
var options = typeof option == 'object' && option
if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.tooltip.Constructor = Tooltip
// TOOLTIP NO CONFLICT
// ===================
$.fn.tooltip.noConflict = function () {
$.fn.tooltip = old
return this
}
}(window.jQuery);

View File

@@ -1,56 +0,0 @@
/* ========================================================================
* Bootstrap: transition.js v3.0.0
* http://twbs.github.com/bootstrap/javascript.html#transitions
* ========================================================================
* Copyright 2013 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================================== */
+function ($) { "use strict";
// CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
// ============================================================
function transitionEnd() {
var el = document.createElement('bootstrap')
var transEndEventNames = {
'WebkitTransition' : 'webkitTransitionEnd'
, 'MozTransition' : 'transitionend'
, 'OTransition' : 'oTransitionEnd otransitionend'
, 'transition' : 'transitionend'
}
for (var name in transEndEventNames) {
if (el.style[name] !== undefined) {
return { end: transEndEventNames[name] }
}
}
}
// http://blog.alexmaccaw.com/css-transitions
$.fn.emulateTransitionEnd = function (duration) {
var called = false, $el = this
$(this).one($.support.transition.end, function () { called = true })
var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
setTimeout(callback, duration)
return this
}
$(function () {
$.support.transition = transitionEnd()
})
}(window.jQuery);

View File

@@ -0,0 +1,604 @@
/**
* bootbox.js v4.0.0
*
* http://bootboxjs.com/license.txt
*/
// @see https://github.com/makeusabrew/bootbox/issues/71
window.bootbox = window.bootbox || (function init($, undefined) {
"use strict";
// the base DOM structure needed to create a modal
var templates = {
dialog:
"<div class='bootbox modal' tabindex='-1' role='dialog'>" +
"<div class='modal-dialog'>" +
"<div class='modal-content'>" +
"<div class='modal-body'><div class='bootbox-body'></div></div>" +
"</div>" +
"</div>" +
"</div>",
header:
"<div class='modal-header'>" +
"<h4 class='modal-title'></h4>" +
"</div>",
footer:
"<div class='modal-footer'></div>",
closeButton:
"<button type='button' class='bootbox-close-button close'>&times;</button>",
form:
"<form class='bootbox-form'></form>",
inputs: {
text:
"<input class='bootbox-input form-control' autocomplete=off type=text />"
}
};
// cache a reference to the jQueryfied body element
var appendTo = $("body");
var defaults = {
// default language
locale: "en",
// show backdrop or not
backdrop: true,
// animate the modal in/out
animate: true,
// additional class string applied to the top level dialog
className: null,
// whether or not to include a close button
closeButton: true,
// show the dialog immediately by default
show: true
};
// our public object; augmented after our private API
var exports = {};
/**
* @private
*/
function _t(key) {
var locale = locales[defaults.locale];
return locale ? locale[key] : locales.en[key];
}
function processCallback(e, dialog, callback) {
e.preventDefault();
// by default we assume a callback will get rid of the dialog,
// although it is given the opportunity to override this
// so, if the callback can be invoked and it *explicitly returns false*
// then we'll set a flag to keep the dialog active...
var preserveDialog = $.isFunction(callback) && callback(e) === false;
// ... otherwise we'll bin it
if (!preserveDialog) {
dialog.modal("hide");
}
}
function getKeyLength(obj) {
// @TODO defer to Object.keys(x).length if available?
var k, t = 0;
for (k in obj) {
t ++;
}
return t;
}
function each(collection, iterator) {
var index = 0;
$.each(collection, function(key, value) {
iterator(key, value, index++);
});
}
function sanitize(options) {
var buttons;
var total;
if (typeof options !== "object") {
throw new Error("Please supply an object of options");
}
if (!options.message) {
throw new Error("Please specify a message");
}
// make sure any supplied options take precedence over defaults
options = $.extend({}, defaults, options);
if (!options.buttons) {
options.buttons = {};
}
// we only support Bootstrap's "static" and false backdrop args
// supporting true would mean you could dismiss the dialog without
// explicitly interacting with it
options.backdrop = options.backdrop ? "static" : false;
buttons = options.buttons;
total = getKeyLength(buttons);
each(buttons, function(key, button, index) {
if ($.isFunction(button)) {
// short form, assume value is our callback. Since button
// isn't an object it isn't a reference either so re-assign it
button = buttons[key] = {
callback: button
};
}
// before any further checks make sure by now button is the correct type
if ($.type(button) !== "object") {
throw new Error("button with key " + key + " must be an object");
}
if (!button.label) {
// the lack of an explicit label means we'll assume the key is good enough
button.label = key;
}
if (!button.className) {
if (total <= 2 && index === total-1) {
// always add a primary to the main option in a two-button dialog
button.className = "btn-primary";
} else {
button.className = "btn-default";
}
}
});
return options;
}
function mapArguments(args, properties) {
var argn = args.length;
var options = {};
if (argn < 1 || argn > 2) {
throw new Error("Invalid argument length");
}
if (argn === 2 || typeof args[0] === "string") {
options[properties[0]] = args[0];
options[properties[1]] = args[1];
} else {
options = args[0];
}
return options;
}
function mergeArguments(defaults, args, properties) {
return $.extend(true, {}, defaults, mapArguments(args, properties));
}
function mergeButtons(labels, args, properties) {
return validateButtons(
mergeArguments(createButtons.apply(null, labels), args, properties),
labels
);
}
function createLabels() {
var buttons = {};
for (var i = 0, j = arguments.length; i < j; i++) {
var argument = arguments[i];
var key = argument.toLowerCase();
var value = argument.toUpperCase();
buttons[key] = {
label: _t(value)
};
}
return buttons;
}
function createButtons() {
return {
buttons: createLabels.apply(null, arguments)
};
}
function validateButtons(options, buttons) {
var allowedButtons = {};
each(buttons, function(key, value) {
allowedButtons[value] = true;
});
each(options.buttons, function(key) {
if (allowedButtons[key] === undefined) {
throw new Error("button key " + key + " is not allowed (options are " + buttons.join("\n") + ")");
}
});
return options;
}
exports.alert = function() {
var options;
options = mergeButtons(["ok"], arguments, ["message", "callback"]);
if (options.callback && !$.isFunction(options.callback)) {
throw new Error("alert requires callback property to be a function when provided");
}
/**
* overrides
*/
options.buttons.ok.callback = options.onEscape = function() {
if ($.isFunction(options.callback)) {
return options.callback();
}
return true;
};
return exports.dialog(options);
};
exports.confirm = function() {
var options;
options = mergeButtons(["cancel", "confirm"], arguments, ["message", "callback"]);
/**
* overrides; undo anything the user tried to set they shouldn't have
*/
options.buttons.cancel.callback = options.onEscape = function() {
return options.callback(false);
};
options.buttons.confirm.callback = function() {
return options.callback(true);
};
// confirm specific validation
if (!$.isFunction(options.callback)) {
throw new Error("confirm requires a callback");
}
return exports.dialog(options);
};
exports.prompt = function() {
var options;
var defaults;
var dialog;
var form;
var input;
var shouldShow;
// we have to create our form first otherwise
// its value is undefined when gearing up our options
// @TODO this could be solved by allowing message to
// be a function instead...
form = $(templates.form);
defaults = {
buttons: createLabels("cancel", "confirm"),
value: ""
};
options = validateButtons(
mergeArguments(defaults, arguments, ["title", "callback"]),
["cancel", "confirm"]
);
// capture the user's show value; we always set this to false before
// spawning the dialog to give us a chance to attach some handlers to
// it, but we need to make sure we respect a preference not to show it
shouldShow = (options.show === undefined) ? true : options.show;
/**
* overrides; undo anything the user tried to set they shouldn't have
*/
options.message = form;
options.buttons.cancel.callback = options.onEscape = function() {
return options.callback(null);
};
options.buttons.confirm.callback = function() {
return options.callback(input.val());
};
options.show = false;
// prompt specific validation
if (!options.title) {
throw new Error("prompt requires a title");
}
if (!$.isFunction(options.callback)) {
throw new Error("prompt requires a callback");
}
// create the input
input = $(templates.inputs.text);
input.val(options.value);
// now place it in our form
form.append(input);
form.on("submit", function(e) {
e.preventDefault();
// @TODO can we actually click *the* button object instead?
// e.g. buttons.confirm.click() or similar
dialog.find(".btn-primary").click();
});
dialog = exports.dialog(options);
// clear the existing handler focusing the submit button...
dialog.off("shown.bs.modal");
// ...and replace it with one focusing our input, if possible
dialog.on("shown.bs.modal", function() {
input.focus();
});
if (shouldShow === true) {
dialog.modal("show");
}
return dialog;
};
exports.dialog = function(options) {
options = sanitize(options);
var dialog = $(templates.dialog);
var body = dialog.find(".modal-body");
var buttons = options.buttons;
var buttonStr = "";
var callbacks = {
onEscape: options.onEscape
};
each(buttons, function(key, button) {
// @TODO I don't like this string appending to itself; bit dirty. Needs reworking
// can we just build up button elements instead? slower but neater. Then button
// can just become a template too
buttonStr += "<button data-bb-handler='" + key + "' type='button' class='btn " + button.className + "'>" + button.label + "</button>";
callbacks[key] = button.callback;
});
body.find(".bootbox-body").html(options.message);
if (options.animate === true) {
dialog.addClass("fade");
}
if (options.className) {
dialog.addClass(options.className);
}
if (options.title) {
body.before(templates.header);
}
if (options.closeButton) {
var closeButton = $(templates.closeButton);
if (options.title) {
dialog.find(".modal-header").prepend(closeButton);
} else {
closeButton.css("margin-top", "-10px").prependTo(body);
}
}
if (options.title) {
dialog.find(".modal-title").html(options.title);
}
if (buttonStr.length) {
body.after(templates.footer);
dialog.find(".modal-footer").html(buttonStr);
}
/**
* Bootstrap event listeners; used handle extra
* setup & teardown required after the underlying
* modal has performed certain actions
*/
dialog.on("hidden.bs.modal", function(e) {
// ensure we don't accidentally intercept hidden events triggered
// by children of the current dialog. We shouldn't anymore now BS
// namespaces its events; but still worth doing
if (e.target === this) {
dialog.remove();
}
});
/*
dialog.on("show.bs.modal", function() {
// sadly this doesn't work; show is called *just* before
// the backdrop is added so we'd need a setTimeout hack or
// otherwise... leaving in as would be nice
if (options.backdrop) {
dialog.next(".modal-backdrop").addClass("bootbox-backdrop");
}
});
*/
dialog.on("shown.bs.modal", function() {
dialog.find(".btn-primary:first").focus();
});
/**
* Bootbox event listeners; experimental and may not last
* just an attempt to decouple some behaviours from their
* respective triggers
*/
dialog.on("escape.close.bb", function(e) {
if (callbacks.onEscape) {
processCallback(e, dialog, callbacks.onEscape);
}
});
/**
* Standard jQuery event listeners; used to handle user
* interaction with our dialog
*/
dialog.on("click", ".modal-footer button", function(e) {
var callbackKey = $(this).data("bb-handler");
processCallback(e, dialog, callbacks[callbackKey]);
});
dialog.on("click", ".bootbox-close-button", function(e) {
// onEscape might be falsy but that's fine; the fact is
// if the user has managed to click the close button we
// have to close the dialog, callback or not
processCallback(e, dialog, callbacks.onEscape);
});
dialog.on("keyup", function(e) {
if (e.which === 27) {
dialog.trigger("escape.close.bb");
}
});
// the remainder of this method simply deals with adding our
// dialogent to the DOM, augmenting it with Bootstrap's modal
// functionality and then giving the resulting object back
// to our caller
appendTo.append(dialog);
dialog.modal({
backdrop: options.backdrop,
keyboard: false,
show: false
});
if (options.show) {
dialog.modal("show");
}
// @TODO should we return the raw element here or should
// we wrap it in an object on which we can expose some neater
// methods, e.g. var d = bootbox.alert(); d.hide(); instead
// of d.modal("hide");
/*
function BBDialog(elem) {
this.elem = elem;
}
BBDialog.prototype = {
hide: function() {
return this.elem.modal("hide");
},
show: function() {
return this.elem.modal("show");
}
};
*/
return dialog;
};
exports.setDefaults = function(values) {
$.extend(defaults, values);
};
exports.hideAll = function() {
$(".bootbox").modal("hide");
};
/**
* standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
* unlikely to be required. If this gets too large it can be split out into separate JS files.
*/
var locales = {
br : {
OK : "OK",
CANCEL : "Cancelar",
CONFIRM : "Sim"
},
da : {
OK : "OK",
CANCEL : "Annuller",
CONFIRM : "Accepter"
},
de : {
OK : "OK",
CANCEL : "Abbrechen",
CONFIRM : "Akzeptieren"
},
en : {
OK : "OK",
CANCEL : "Cancel",
CONFIRM : "OK"
},
es : {
OK : "OK",
CANCEL : "Cancelar",
CONFIRM : "Aceptar"
},
fi : {
OK : "OK",
CANCEL : "Peruuta",
CONFIRM : "OK"
},
fr : {
OK : "OK",
CANCEL : "Annuler",
CONFIRM : "D'accord"
},
it : {
OK : "OK",
CANCEL : "Annulla",
CONFIRM : "Conferma"
},
nl : {
OK : "OK",
CANCEL : "Annuleren",
CONFIRM : "Accepteren"
},
pl : {
OK : "OK",
CANCEL : "Anuluj",
CONFIRM : "Potwierdź"
},
ru : {
OK : "OK",
CANCEL : "Отмена",
CONFIRM : "Применить"
},
zh_CN : {
OK : "OK",
CANCEL : "取消",
CONFIRM : "确认"
},
zh_TW : {
OK : "OK",
CANCEL : "取消",
CONFIRM : "確認"
}
};
exports.init = function(_$) {
window.bootbox = init(_$ || $);
};
return exports;
}(window.jQuery));

File diff suppressed because one or more lines are too long

View File

@@ -1,120 +0,0 @@
!function ($) {
"use strict"; // jshint ;_;
/* MAGNIFY PUBLIC CLASS DEFINITION
* =============================== */
var Magnify = function (element, options) {
this.init('magnify', element, options)
}
Magnify.prototype = {
constructor: Magnify
, init: function (type, element, options) {
var event = 'mousemove'
, eventOut = 'mouseleave';
this.type = type
this.$element = $(element)
this.options = this.getOptions(options)
this.nativeWidth = 0
this.nativeHeight = 0
this.$element.wrap('<div class="magnify" \>');
this.$element.parent('.magnify').append('<div class="magnify-large" \>');
this.$element.siblings(".magnify-large").css("background","url('" + this.$element.attr("src") + "') no-repeat");
this.$element.parent('.magnify').on(event + '.' + this.type, $.proxy(this.check, this));
this.$element.parent('.magnify').on(eventOut + '.' + this.type, $.proxy(this.check, this));
}
, getOptions: function (options) {
options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data())
if (options.delay && typeof options.delay == 'number') {
options.delay = {
show: options.delay
, hide: options.delay
}
}
return options
}
, check: function (e) {
var container = $(e.currentTarget);
var self = container.children('img');
var mag = container.children(".magnify-large");
// Get the native dimensions of the image
if(!this.nativeWidth && !this.nativeHeight) {
var image = new Image();
image.src = self.attr("src");
this.nativeWidth = image.width;
this.nativeHeight = image.height;
} else {
var magnifyOffset = container.offset();
var mx = e.pageX - magnifyOffset.left;
var my = e.pageY - magnifyOffset.top;
if (mx < container.width() && my < container.height() && mx > 0 && my > 0) {
mag.fadeIn(100);
} else {
mag.fadeOut(100);
}
if(mag.is(":visible"))
{
var rx = Math.round(mx/container.width()*this.nativeWidth - mag.width()/2)*-1;
var ry = Math.round(my/container.height()*this.nativeHeight - mag.height()/2)*-1;
var bgp = rx + "px " + ry + "px";
var px = mx - mag.width()/2;
var py = my - mag.height()/2;
mag.css({left: px, top: py, backgroundPosition: bgp});
}
}
}
}
/* MAGNIFY PLUGIN DEFINITION
* ========================= */
$.fn.magnify = function ( option ) {
return this.each(function () {
var $this = $(this)
, data = $this.data('magnify')
, options = typeof option == 'object' && option
if (!data) $this.data('tooltip', (data = new Magnify(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.magnify.Constructor = Magnify
$.fn.magnify.defaults = {
delay: 0
}
/* MAGNIFY DATA-API
* ================ */
$(window).on('load', function () {
$('[data-toggle="magnify"]').each(function () {
var $mag = $(this);
$mag.magnify()
})
})
} ( window.jQuery );

View File

@@ -1 +0,0 @@
!function(e){"use strict";var t=function(e,t){this.init("magnify",e,t)};t.prototype={constructor:t,init:function(t,n,r){var i="mousemove",s="mouseleave";this.type=t;this.$element=e(n);this.options=this.getOptions(r);this.nativeWidth=0;this.nativeHeight=0;this.$element.wrap('<div class="magnify" >');this.$element.parent(".magnify").append('<div class="magnify-large" >');this.$element.siblings(".magnify-large").css("background","url('"+this.$element.attr("src")+"') no-repeat");this.$element.parent(".magnify").on(i+"."+this.type,e.proxy(this.check,this));this.$element.parent(".magnify").on(s+"."+this.type,e.proxy(this.check,this))},getOptions:function(t){t=e.extend({},e.fn[this.type].defaults,t,this.$element.data());t.delay&&typeof t.delay=="number"&&(t.delay={show:t.delay,hide:t.delay});return t},check:function(t){var n=e(t.currentTarget),r=n.children("img"),i=n.children(".magnify-large");if(!this.nativeWidth&&!this.nativeHeight){var s=new Image;s.src=r.attr("src");this.nativeWidth=s.width;this.nativeHeight=s.height}else{var o=n.offset(),u=t.pageX-o.left,a=t.pageY-o.top;u<n.width()&&a<n.height()&&u>0&&a>0?i.fadeIn(100):i.fadeOut(100);if(i.is(":visible")){var f=Math.round(u/n.width()*this.nativeWidth-i.width()/2)*-1,l=Math.round(a/n.height()*this.nativeHeight-i.height()/2)*-1,c=f+"px "+l+"px",h=u-i.width()/2,p=a-i.height()/2;i.css({left:h,top:p,backgroundPosition:c})}}}};e.fn.magnify=function(n){return this.each(function(){var r=e(this),i=r.data("magnify"),s=typeof n=="object"&&n;i||r.data("tooltip",i=new t(this,s));typeof n=="string"&&i[n]()})};e.fn.magnify.Constructor=t;e.fn.magnify.defaults={delay:0};e(window).on("load",function(){e('[data-toggle="magnify"]').each(function(){var t=e(this);t.magnify()})})}(window.jQuery);

View File

@@ -1,323 +0,0 @@
/**
* menu-aim is a jQuery plugin for dropdown menus that can differentiate
* between a user trying hover over a dropdown item vs trying to navigate into
* a submenu's contents.
*
* menu-aim assumes that you have are using a menu with submenus that expand
* to the menu's right. It will fire events when the user's mouse enters a new
* dropdown item *and* when that item is being intentionally hovered over.
*
* __________________________
* | Monkeys >| Gorilla |
* | Gorillas >| Content |
* | Chimps >| Here |
* |___________|____________|
*
* In the above example, "Gorillas" is selected and its submenu content is
* being shown on the right. Imagine that the user's cursor is hovering over
* "Gorillas." When they move their mouse into the "Gorilla Content" area, they
* may briefly hover over "Chimps." This shouldn't close the "Gorilla Content"
* area.
*
* This problem is normally solved using timeouts and delays. menu-aim tries to
* solve this by detecting the direction of the user's mouse movement. This can
* make for quicker transitions when navigating up and down the menu. The
* experience is hopefully similar to amazon.com/'s "Shop by Department"
* dropdown.
*
* Use like so:
*
* $("#menu").menuAim({
* activate: $.noop, // fired on row activation
* deactivate: $.noop // fired on row deactivation
* });
*
* ...to receive events when a menu's row has been purposefully (de)activated.
*
* The following options can be passed to menuAim. All functions execute with
* the relevant row's HTML element as the execution context ('this'):
*
* .menuAim({
* // Function to call when a row is purposefully activated. Use this
* // to show a submenu's content for the activated row.
* activate: function() {},
*
* // Function to call when a row is deactivated.
* deactivate: function() {},
*
* // Function to call when mouse enters a menu row. Entering a row
* // does not mean the row has been activated, as the user may be
* // mousing over to a submenu.
* enter: function() {},
*
* // Function to call when mouse exits a menu row.
* exit: function() {},
*
* // Selector for identifying which elements in the menu are rows
* // that can trigger the above events. Defaults to "> li".
* rowSelector: "> li",
*
* // You may have some menu rows that aren't submenus and therefore
* // shouldn't ever need to "activate." If so, filter submenu rows w/
* // this selector. Defaults to "*" (all elements).
* submenuSelector: "*",
*
* // Direction the submenu opens relative to the main menu. Can be
* // left, right, above, or below. Defaults to "right".
* submenuDirection: "right"
* });
*
* https://github.com/kamens/jQuery-menu-aim
*/
(function($) {
$.fn.menuAim = function(opts) {
// Initialize menu-aim for all elements in jQuery collection
this.each(function() {
init.call(this, opts);
});
return this;
};
function init(opts) {
var $menu = $(this),
activeRow = null,
mouseLocs = [],
lastDelayLoc = null,
timeoutId = null,
options = $.extend({
rowSelector: "> li",
submenuSelector: "*",
submenuDirection: "right",
tolerance: 75, // bigger = more forgivey when entering submenu
enter: $.noop,
exit: $.noop,
activate: $.noop,
deactivate: $.noop,
exitMenu: $.noop
}, opts);
var MOUSE_LOCS_TRACKED = 3, // number of past mouse locations to track
DELAY = 300; // ms delay when user appears to be entering submenu
/**
* Keep track of the last few locations of the mouse.
*/
var mousemoveDocument = function(e) {
mouseLocs.push({x: e.pageX, y: e.pageY});
if (mouseLocs.length > MOUSE_LOCS_TRACKED) {
mouseLocs.shift();
}
};
/**
* Cancel possible row activations when leaving the menu entirely
*/
var mouseleaveMenu = function() {
if (timeoutId) {
clearTimeout(timeoutId);
}
// If exitMenu is supplied and returns true, deactivate the
// currently active row on menu exit.
if (options.exitMenu(this)) {
if (activeRow) {
options.deactivate(activeRow);
}
activeRow = null;
}
};
/**
* Trigger a possible row activation whenever entering a new row.
*/
var mouseenterRow = function() {
if (timeoutId) {
// Cancel any previous activation delays
clearTimeout(timeoutId);
}
options.enter(this);
possiblyActivate(this);
},
mouseleaveRow = function() {
options.exit(this);
};
/*
* Immediately activate a row if the user clicks on it.
*/
var clickRow = function() {
activate(this);
};
/**
* Activate a menu row.
*/
var activate = function(row) {
if (row == activeRow) {
return;
}
if (activeRow) {
options.deactivate(activeRow);
}
options.activate(row);
activeRow = row;
};
/**
* Possibly activate a menu row. If mouse movement indicates that we
* shouldn't activate yet because user may be trying to enter
* a submenu's content, then delay and check again later.
*/
var possiblyActivate = function(row) {
var delay = activationDelay();
if (delay) {
timeoutId = setTimeout(function() {
possiblyActivate(row);
}, delay);
} else {
activate(row);
}
};
/**
* Return the amount of time that should be used as a delay before the
* currently hovered row is activated.
*
* Returns 0 if the activation should happen immediately. Otherwise,
* returns the number of milliseconds that should be delayed before
* checking again to see if the row should be activated.
*/
var activationDelay = function() {
if (!activeRow || !$(activeRow).is(options.submenuSelector)) {
// If there is no other submenu row already active, then
// go ahead and activate immediately.
return 0;
}
var offset = $menu.offset(),
upperLeft = {
x: offset.left,
y: offset.top - options.tolerance
},
upperRight = {
x: offset.left + $menu.outerWidth(),
y: upperLeft.y
},
lowerLeft = {
x: offset.left,
y: offset.top + $menu.outerHeight() + options.tolerance
},
lowerRight = {
x: offset.left + $menu.outerWidth(),
y: lowerLeft.y
},
loc = mouseLocs[mouseLocs.length - 1],
prevLoc = mouseLocs[0];
if (!loc) {
return 0;
}
if (!prevLoc) {
prevLoc = loc;
}
if (prevLoc.x < offset.left || prevLoc.x > lowerRight.x ||
prevLoc.y < offset.top || prevLoc.y > lowerRight.y) {
// If the previous mouse location was outside of the entire
// menu's bounds, immediately activate.
return 0;
}
if (lastDelayLoc &&
loc.x == lastDelayLoc.x && loc.y == lastDelayLoc.y) {
// If the mouse hasn't moved since the last time we checked
// for activation status, immediately activate.
return 0;
}
// Detect if the user is moving towards the currently activated
// submenu.
//
// If the mouse is heading relatively clearly towards
// the submenu's content, we should wait and give the user more
// time before activating a new row. If the mouse is heading
// elsewhere, we can immediately activate a new row.
//
// We detect this by calculating the slope formed between the
// current mouse location and the upper/lower right points of
// the menu. We do the same for the previous mouse location.
// If the current mouse location's slopes are
// increasing/decreasing appropriately compared to the
// previous's, we know the user is moving toward the submenu.
//
// Note that since the y-axis increases as the cursor moves
// down the screen, we are looking for the slope between the
// cursor and the upper right corner to decrease over time, not
// increase (somewhat counterintuitively).
function slope(a, b) {
return (b.y - a.y) / (b.x - a.x);
};
var decreasingCorner = upperRight,
increasingCorner = lowerRight;
// Our expectations for decreasing or increasing slope values
// depends on which direction the submenu opens relative to the
// main menu. By default, if the menu opens on the right, we
// expect the slope between the cursor and the upper right
// corner to decrease over time, as explained above. If the
// submenu opens in a different direction, we change our slope
// expectations.
if (options.submenuDirection == "left") {
decreasingCorner = lowerLeft;
increasingCorner = upperLeft;
} else if (options.submenuDirection == "below") {
decreasingCorner = lowerRight;
increasingCorner = lowerLeft;
} else if (options.submenuDirection == "above") {
decreasingCorner = upperLeft;
increasingCorner = upperRight;
}
var decreasingSlope = slope(loc, decreasingCorner),
increasingSlope = slope(loc, increasingCorner),
prevDecreasingSlope = slope(prevLoc, decreasingCorner),
prevIncreasingSlope = slope(prevLoc, increasingCorner);
if (decreasingSlope < prevDecreasingSlope &&
increasingSlope > prevIncreasingSlope) {
// Mouse is moving from previous location towards the
// currently activated submenu. Delay before activating a
// new menu row, because user may be moving into submenu.
lastDelayLoc = loc;
return DELAY;
}
lastDelayLoc = null;
return 0;
};
/**
* Hook up initial menu events
*/
$menu
.mouseleave(mouseleaveMenu)
.find(options.rowSelector)
.mouseenter(mouseenterRow)
.mouseleave(mouseleaveRow)
.click(clickRow);
$(document).mousemove(mousemoveDocument);
};
})(jQuery);

View File

@@ -1,11 +1,18 @@
/* JQUERY PREVENT CONFLICT */ /* JQUERY PREVENT CONFLICT */
(function($) { (function($) {
/* ------------------------------------------------------------------ /* ------------------------------------------------------------------
onLoad Function -------------------------------------------------- */ onLoad Function -------------------------------------------------- */
$(document).ready(function(){ $(document).ready(function(){
// Loader
var $loader = $('<div class="loader"></div>');
$('body').append($loader);
// Display loader if we do ajax call
$(document)
.ajaxStart(function() { $loader.show(); })
.ajaxStop(function(){ $loader.hide(); });
// Main Navigation Hover // Main Navigation Hover
$('.nav-main') $('.nav-main')
@@ -30,6 +37,29 @@
selector: '[data-toggle=tooltip]' selector: '[data-toggle=tooltip]'
}); });
// Confirm Dialog
$(document).on('click.confirm', '[data-toggle="confirm"]', function (e) {
var $this = $(this),
href = $this.attr('href'),
title = $this.attr('data-confirm-title') ? $this.attr('data-confirm-title') : 'Are you sure?';
bootbox.confirm(title, function(confirm) {
if(confirm){
if(href){
window.location.href = href;
} else {
// If forms
var $form = $this.closest("form");
if($form.size() > 0){
$form.submit();
}
}
}
});
return false;
});
// Toolbar // Toolbar
var $category_products = $('#category-products'); var $category_products = $('#category-products');
if($category_products.size() > 0){ if($category_products.size() > 0){
@@ -40,7 +70,9 @@
if( ($(this).hasClass('btn-grid') && $parent.hasClass('grid')) || ($(this).hasClass('btn-list') && $parent.hasClass('list'))) if( ($(this).hasClass('btn-grid') && $parent.hasClass('grid')) || ($(this).hasClass('btn-list') && $parent.hasClass('list')))
return; return;
$parent.toggleClass('grid').toggleClass('list'); // Add loader effect
$loader.show();
setTimeout(function(){ $parent.toggleClass('grid').toggleClass('list'); $loader.hide(); }, 400);
return false; return false;
}); });
@@ -89,6 +121,7 @@
$form $form
.on('change.filter', ':checkbox', function(){ .on('change.filter', ':checkbox', function(){
$loader.show();
$form.submit(); $form.submit();
}) })
.find('.group-btn > .btn').addClass('sr-only'); .find('.group-btn > .btn').addClass('sr-only');
@@ -126,6 +159,78 @@
}).filter(':has(:checked)').addClass('active'); }).filter(':has(:checked)').addClass('active');
}); });
if($("body").is(".page-product")){
var $quantityInput = $("#quantity");
var $btnAddToCart = $(".btn_add_to_cart", $("#form-product-details"));
var $productMeta = $("#stockInformations");
var $inStock = $(".in",$productMeta);
var $outOfStock = $(".out",$productMeta);
var $old_price_container = $(".old-price", $("#product-details"));
// Switch Quantity in product page
$("select", $(".product-options")).change(function(){
var $select_quantity = $(this).find(":selected").attr("data-quantity");
var $old_price = $(this).find(":selected").attr("data-old-price");
var $best_price = $(this).find(":selected").attr("data-price");
$quantityInput.attr("max", $select_quantity);
// Show Out Of Stock OR In Stock
if($select_quantity == 0){
$btnAddToCart.attr("disabled", true);
$productMeta.removeClass("in-stock");
$productMeta.addClass("out-of-stock");
$productMeta.attr("href", "http://schema.org/OutOfStock");
$outOfStock.show();
$inStock.hide();
}else{
$btnAddToCart.attr("disabled", false);
$productMeta.removeClass("out-of-stock");
$productMeta.addClass("in-stock");
$productMeta.attr("href", "http://schema.org/InStock");
$inStock.show();
$outOfStock.hide();
}
if(parseInt($quantityInput.val()) > parseInt($select_quantity)){
$quantityInput.val($select_quantity);
}
if($old_price_container.size() > 0 ){
$(".price", $old_price_container).html($old_price);
$(".price", $(".special-price")).html($best_price);
}else{
$(".price", $(".regular-price")).html($best_price);
}
}).change();
$quantityInput.focusout(function() {
$quantityInput.attr("max", $select_quantity);
if(parseInt($quantityInput.val()) > parseInt($select_quantity)){
$quantityInput.val($select_quantity);
}
});
}
$('#limit-top').change(function(e){ $('#limit-top').change(function(e){
window.location = $(this).val() window.location = $(this).val()
}); });

View File

@@ -1,6 +1,7 @@
/* FONT PATH /* FONT PATH
* -------------------------- */ * -------------------------- */
/*
@font-face { @font-face {
font-family: 'FontAwesome'; font-family: 'FontAwesome';
src: url('@{FontAwesomePath}/fontawesome-webfont.eot?v=@{FontAwesomeVersion}'); src: url('@{FontAwesomePath}/fontawesome-webfont.eot?v=@{FontAwesomeVersion}');
@@ -11,4 +12,15 @@
// src: url('@{FontAwesomePath}/FontAwesome.otf') format('opentype'); // used when developing fonts // src: url('@{FontAwesomePath}/FontAwesome.otf') format('opentype'); // used when developing fonts
font-weight: normal; font-weight: normal;
font-style: normal; font-style: normal;
}*/
@font-face {
font-family: 'FontAwesome';
src: url('@{FontAwesomePath}/fontawesome-webfont.eot?v=3');
src: url('@{FontAwesomePath}/fontawesome-webfont.eot?#iefix&v=3') format('embedded-opentype'),
url('@{FontAwesomePath}/fontawesome-webfont.woff?v=3') format('woff'),
url('@{FontAwesomePath}/fontawesome-webfont.ttf?v=3') format('truetype'),
url('@{FontAwesomePath}/fontawesome-webfont.svg?v=3#fontawesomeregular') format('svg');
// src: url('@{FontAwesomePath}/FontAwesome.otf') format('opentype'); // used when developing fonts
font-weight: normal;
font-style: normal;
} }

View File

@@ -1,20 +0,0 @@
//
// Magnifier
// ---------------------------------------------------------------------------------------------------------------------
// Parent container
.magnify {
position: relative;
cursor:none;
}
// Magnifying glass
.magnify-large {
position: absolute;
display: none;
width: 175px; height: 175px;
@shadow: 0 0 0 7px rgba(255, 255, 255, 0.85), 0 0 7px 7px rgba(0, 0, 0, 0.25), inset 0 0 40px 2px rgba(0, 0, 0, 0.25);
.box-shadow(@shadow);
.border-radius(100%);
z-index:10;
}

View File

@@ -2,9 +2,6 @@
/* Bootstrap */ /* Bootstrap */
@import "bootstrap/bootstrap.less"; @import "bootstrap/bootstrap.less";
// Magnifying glass
@import "plugins/bootstrap-magnify/bootstrap-magnify.less";
/* FontAwesome */ /* FontAwesome */
@import "fontawesome/font-awesome.less"; @import "fontawesome/font-awesome.less";

View File

@@ -9,32 +9,31 @@
// Buttons // Buttons
.btn { .btn {
// Remove Box Shadow // Remove Box Shadow
&:active, &:active,
&.active { &.active {
.box-shadow(none); .box-shadow(none);
} }
// Primary Buttons // Primary Buttons
&.btn_add_to_cart, &.btn_add_to_cart,
&.btn-cart, &.btn-cart,
&.btn-checkout, &.btn-checkout,
&.btn-checkout-next, &.btn-checkout-next,
&.btn-checkout-home, &.btn-checkout-home,
&.btn-filter,
&.btn-forgot, &.btn-forgot,
&.btn-login, &.btn-login,
&.btn-proceed-checkout, &.btn-proceed-checkout,
&.btn-register, &.btn-register,
&.btn-submit { .btn-primary; } &.btn-submit { .btn-primary; }
&.btn-add-address, &.btn-add-address,
&.btn-checkout, &.btn-checkout,
&.btn-checkout-next, &.btn-checkout-next,
&.btn-checkout-home { float: right; } &.btn-checkout-home { float: right; }
// Secondary Buttons // Secondary Buttons
&.btn-back, &.btn-back,
&.btn-continue-shopping { &.btn-continue-shopping {
@@ -44,11 +43,13 @@
// Keep old style button // Keep old style button
&.btn-add-address, &.btn-add-address,
&.btn-coupon, &.btn-coupon,
&.btn-filter,
&.btn-grid, &.btn-grid,
&.btn-list, &.btn-list,
&.btn-login-mini,
&.btn-search, &.btn-search,
&.btn-subscribe { .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border); } &.btn-subscribe { .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border); }
// Account Info // Account Info
&.btn-change-account, &.btn-change-account,
&.btn-change-password { padding: 0; } &.btn-change-password { padding: 0; }
@@ -57,7 +58,7 @@
&.btn-edit-address, &.btn-edit-address,
&.btn-order-details, &.btn-order-details,
&.btn-remove-address { &.btn-remove-address {
border: 1px solid @btn-primary-border; border: 1px solid @btn-primary-border;
margin-bottom: 10px; padding: 4px 9px; margin-bottom: 10px; padding: 4px 9px;
&:hover, &:hover,
@@ -66,9 +67,9 @@
color: @text-color; color: @text-color;
} }
} }
// Checkout Step 3 // Checkout Step 3
&.btn-change-address { &.btn-change-address {
padding: 0; padding: 0;
&:before { &:before {
.icon(@pencil); .icon(@pencil);
@@ -85,8 +86,8 @@
} }
} }
} }
// Not styled // Not styled
&.btn-cancel { padding-left: 0; } &.btn-cancel { padding-left: 0; }
&.btn-compare {} &.btn-compare {}

View File

@@ -1,9 +1,17 @@
// Thelia : Shopping Cart // Thelia : Shopping Cart
// Cart Empty
.cart-empty { margin: 0; padding: 40px; }
// Cart Mini
.table-cart-mini { margin-bottom: 0; }
// Cart // Cart
.table-cart { .table-cart {
.table-bordered; .table-bordered;
thead, thead,
tbody, tbody,
tfooter { tfooter {
@@ -70,3 +78,18 @@
} }
} }
// Message if no product in the cart
.cart-warning {
clear: both;
.alert; .alert-warning;
margin-bottom: 0;
text-align: center;
> a { color: inherit; }
&:before {
.icon(@warning-sign);
display: block;
font-size: 2.2em;
}
}

View File

@@ -9,10 +9,18 @@
} }
// Form Login Mini
#form-login-mini {
.form-control { .input-sm; }
.btn { .btn-sm; }
width: 200px;
}
// Form Login // Form Login
#form-login, #form-login,
#form-forgotpassword { #form-forgotpassword {
background: #f5f5f5;; background: #f5f5f5;
padding: 45px; padding: 45px;
legend { legend {
@@ -48,7 +56,8 @@
.control-input { .make-sm-column(5); } .control-input { .make-sm-column(5); }
} }
.group-primary, .group-primary,
.group-agreed { .group-agreed,
.group-newsletter {
.control-input { .make-sm-column-offset(3); .make-sm-column(5); } .control-input { .make-sm-column-offset(3); .make-sm-column(5); }
} }
.group-btn { .group-btn {

View File

@@ -6,6 +6,18 @@
// Collapse // Collapse
.no-js .collapse { display: block!important; } .no-js .collapse { display: block!important; }
// Loader (Overlay)
.loader {
position: fixed;
background: #fff url(../img/ajax-loader.gif) no-repeat center center;
background-color: rgba(255,255,255,.5);
display: none;
left: 0; top: 0;
width: 100%;height: 100%;
z-index: 100;
}
.oldie { position: absolute; }
// thumbnail // thumbnail
.thumbnail { .thumbnail {
&.active, &.active,

View File

@@ -1,6 +1,5 @@
// Thelia // Thelia
@import "variables.less"; @import "variables.less";
@import "path.less";
// Thelia : Layout // Thelia : Layout
@import "global.less"; @import "global.less";

View File

@@ -3,35 +3,26 @@
.navbar { .navbar {
.navbar-default; .navbar-default;
.navbar-brand { .visible-xs; } // Visible only Small screen .navbar-brand { .visible-xs; } // Visible only Small screen
/*.nav-main {
font-size: @navbar-font-size;
li > a { .navbar-cart {
color: @navbar-default-link-color; @media (min-width: @grid-float-breakpoint) {
padding: @navbar-link-padding; .dropdown > a {
.dropdown-toggle;
&:hover, &:after {
&:focus { float: none;
color: @navbar-default-link-hover-color; }
background-color: @navbar-default-link-hover-bg;
}
// Uncollapse the nav
@media (min-width: @grid-float-breakpoint) {
padding-top: ((@navbar-height - @line-height-computed) / 2);
padding-bottom: ((@navbar-height - @line-height-computed) / 2);
} }
} }
.active > a { .dropdown-menu {
color: @navbar-default-link-active-color; @media (max-width: @grid-float-breakpoint) { display: none; }
background-color: @navbar-default-link-active-bg; margin: 0; padding: 20px;
&.cart-content {
width: 350px;
> p { margin: 0; }
}
} }
.cart-not-empty .cart-content { border-top: none; padding: 0; }
.open > a { }
color: @navbar-default-link-hover-color!important;
background-color: @navbar-default-link-hover-bg!important;
}
}*/
// Subnav Links // Subnav Links
@media (min-width: @grid-float-breakpoint) { @media (min-width: @grid-float-breakpoint) {
@@ -40,13 +31,6 @@ li > a {
border: 1px solid @navbar-subnav-border; border: 1px solid @navbar-subnav-border;
border-radius: @navbar-subnav-border-radius; border-radius: @navbar-subnav-border-radius;
.box-shadow(@navbar-subnav-shadow); .box-shadow(@navbar-subnav-shadow);
/*
float: left;
min-width: 160px;
position: absolute;
top: 100%; left: 0;
z-index: @zindex-dropdown;
*/
// Links within the sub navigation // Links within the sub navigation
> li > a { > li > a {
@@ -89,106 +73,6 @@ li > a {
} }
} }
} }
/*
.subnav {
position: relative;
> ul {
//display: none; // none by default, but block on "open" of the menu
font-size: @font-size-base;
list-style: none;
margin: 0; padding: 0;
// Links within the sub navigation
> li > a {
clear: both;
display: block;
font-weight: normal;
line-height: @line-height-base;
white-space: nowrap; // prevent links from randomly breaking onto new lines
&:hover,
&:focus {
text-decoration: none;
}
}
// Active state
> .active > a {
&,
&:hover,
&:focus {
outline: 0;
text-decoration: none;
}
}
@media (min-width: @grid-float-breakpoint) {
background-color: @navbar-subnav-bg;
background-clip: padding-box;
border: 1px solid @navbar-subnav-border;
border-radius: @navbar-subnav-border-radius;
.box-shadow(@navbar-subnav-shadow);
float: left;
min-width: 160px;
position: absolute;
top: 100%; left: 0;
z-index: @zindex-dropdown;
// Links within the sub navigation
> li > a {
color: @navbar-subnav-link-color;
padding: @navbar-subnav-link-padding;
// Hover/Focus state
&:hover,
&:focus {
color: @navbar-subnav-link-hover-color;
background-color: @navbar-subnav-link-hover-bg;
}
}
// Active state
> .active > a {
&,
&:hover,
&:focus {
background-color: @navbar-subnav-link-hover-bg;
color: @navbar-subnav-link-hover-color;
}
}
}
}
/* Add support for multilevel dropdown menus
.subnav {
> ul {
top:0; left: 100%;
}
.accordion-toggle:after {
float:right;
padding-left: .3em;
.icon(@chevron-down);
@media (min-width: @screen-desktop) { .icon(@chevron-right); margin-right: -14px; padding-left: 0; }
}
}*/
// Sub
/*
> .active > a,
> .open > a {
&,
&:hover,
&:focus {
background-color: @navbar-subnav-link-hover-bg;
color: @navbar-subnav-link-hover-color;
}
}
*//*
}
.navbar-nav > .subnav > ul { border-top-color: @navbar-default-link-hover-bg; }
*/
} }

View File

@@ -1,14 +0,0 @@
/* FONT PATH
* -------------------------- */
@font-face {
font-family: 'FontAwesome';
src: url('@{FontAwesomePath}/fontawesome-webfont.eot');
src: url('@{FontAwesomePath}/fontawesome-webfont.eot?#iefix') format('embedded-opentype'),
url('@{FontAwesomePath}/fontawesome-webfont.woff') format('woff'),
url('@{FontAwesomePath}/fontawesome-webfont.ttf') format('truetype'),
url('@{FontAwesomePath}/fontawesome-webfont.svg#fontawesomeregular') format('svg');
// src: url('@{FontAwesomePath}/FontAwesome.otf') format('opentype'); // used when developing fonts
font-weight: normal;
font-style: normal;
}

View File

@@ -6,9 +6,10 @@
.price { .price {
color: @brand-primary; color: @brand-primary;
font-size: ceil(@font-size-base * 1.5); font-size: ceil(@font-size-base * 1.4);
font-weight: bold; font-weight: bold;
font-style: italic; font-style: italic;
white-space: nowrap;
} }
// Regular price // Regular price

View File

@@ -15,10 +15,20 @@
.in-stock { .in-stock {
font-style: italic; font-style: italic;
text-transform: uppercase; text-transform: uppercase;
.quantity{
font-style: italic;
}
}
// Out of Stock
.out-of-stock {
font-style: italic; font-weight: bold;
text-transform: uppercase;
} }
// Out of Stock #stockInformations{
.out-of-stock {}
}
} }

View File

@@ -5,7 +5,7 @@
@FontAwesomePath: "../font/fontawesome"; @FontAwesomePath: "../font/fontawesome";
//bootstrap font //bootstrap font
@icon-font-path: "../font/bootstrap/"; @icon-font-path: "../font/bootstrap/";
// Grid system // Grid system
@grid-float-breakpoint: @screen-desktop; @grid-float-breakpoint: @screen-desktop;

View File

@@ -1,9 +1,11 @@
// Body padding required with the fixed navbar (By default, the navbar is 50px high.) // Body padding required with the fixed navbar (By default, the navbar is 50px high.)
/*
body { padding-top: 80px; } body { padding-top: 80px; }
.navbar { .navbar {
.navbar-fixed-top; .navbar-fixed-top;
} }
*/
.page-header { .page-header {
border: none; border: none;
@@ -64,25 +66,36 @@ label { font-weight: 600; }
} }
} }
> a.cart { > a.cart {
background-color: @brand-primary;
color: #fff;
> .badge {
background-color: #fff;
color: @brand-primary;
}
&:hover, &:hover,
&:focus { &:focus {
> .badge {
background-color: #fff;
color: @brand-primary;
}
}
}
&.cart-not-empty {
> a.cart {
background-color: @brand-primary; background-color: @brand-primary;
color: #fff; color: #fff;
}
&:before { > .badge {
.icon(@shopping-cart); background-color: #fff;
color: #fff; color: @brand-primary;
font-size: 24px; line-height: 0; }
margin-right: .4em;
&:hover,
&:focus {
background-color: @brand-primary;
color: #fff;
}
&:before {
.icon(@shopping-cart);
color: #fff;
font-size: 24px; line-height: 0;
margin-right: .4em;
}
} }
} }
} }
@@ -151,7 +164,7 @@ header {
/* Custom button */ /* Custom button */
.btn-primary { .page .btn-primary {
border-left: 3px solid lighten(@brand-primary, 20%); border-left: 3px solid lighten(@brand-primary, 20%);
.border-radius(0); .border-radius(0);
color: #fff; color: #fff;
@@ -247,6 +260,7 @@ header {
content: @shopping-cart; content: @shopping-cart;
font-size: 1.3em; font-size: 1.3em;
} }
} }
// Cart - Remove button // Cart - Remove button
@@ -309,7 +323,7 @@ td.product,
.special-price { .special-price {
.price { .price {
display: block; display: block;
font-size: 25px; line-height: 25px; font-size: 20px; line-height: 25px;
font-style: italic; font-style: italic;
} }
} }
@@ -410,6 +424,7 @@ td.product,
@media (min-width: @screen-desktop) { @media (min-width: @screen-desktop) {
.product-image { padding-bottom: 40px; } .product-image { padding-bottom: 40px; }
.product-info { .product-info {
.transition(height 300ms linear);
position: absolute; position: absolute;
bottom: 0; bottom: 0;
width: 100%; height: 50px; width: 100%; height: 50px;
@@ -419,7 +434,6 @@ td.product,
&:focus { &:focus {
cursor: pointer; cursor: pointer;
height: 140px; height: 140px;
.transition(height 300ms linear);
} }
} }
} }
@@ -499,6 +513,7 @@ td.product,
} }
.product-btn { .product-btn {
min-height: 26px;
.btn-cart { .btn-cart {
.btn-block; .btn-block;
} }
@@ -1124,7 +1139,6 @@ td.product,
> tr { > tr {
> td { > td {
&.price, &.price,
&.unitprice,
&.qty, &.qty,
&.subprice { padding: 35px 10px; } &.subprice { padding: 35px 10px; }
} }

View File

@@ -1,13 +1,13 @@
{extends file="layout.tpl"} {extends file="layout.tpl"}
{block name="breadcrumb"} {* Body Class *}
<nav class="nav-breadcrumb" role="navigation" aria-labelledby="breadcrumb-label"> {block name="body-class"}page-cart{/block}
<strong id="breadcrumb-label">{intl l="You are here"} : </strong>
<ul class="breadcrumb" itemprop="breadcrumb"> {* Breadcrumb *}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{navigate to="index"}" itemprop="url"><span itemprop="title">{intl l="Home"}</span></a></li> {block name='no-return-functions' append}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="active"><span itemprop="title">{intl l="Cart"}</span></li> {$breadcrumbs = [
</ul> ['title' => {intl l="Cart"}, 'url'=>{url path="/cart"}]
</nav><!-- /.nav-breadcrumb --> ]}
{/block} {/block}
{block name="main-content"} {block name="main-content"}
@@ -16,6 +16,8 @@
<h1 id="main-label" class="page-header">{intl l="Your Cart"}</h1> <h1 id="main-label" class="page-header">{intl l="Your Cart"}</h1>
{nocache}
{ifloop rel="cartloop"}
<div class="btn-group checkout-progress"> <div class="btn-group checkout-progress">
<a href="#" role="button" class="btn btn-step active"><span class="step-nb">1</span> <span class="step-label">{intl l="Your Cart"}</span></a> <a href="#" role="button" class="btn btn-step active"><span class="step-nb">1</span> <span class="step-label">{intl l="Your Cart"}</span></a>
<a href="#" role="button" class="btn btn-step disabled"><span class="step-nb">2</span> <span class="step-label">{intl l="Billing and delivery"}</span></a> <a href="#" role="button" class="btn btn-step disabled"><span class="step-nb">2</span> <span class="step-label">{intl l="Billing and delivery"}</span></a>
@@ -53,71 +55,70 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{loop type="cart" name="cartloop"}
<tr>
<td class="image">
<a href="{$PRODUCT_URL}" class="thumbnail">
{assign "cart_count" $LOOP_COUNT}
{ifloop rel='product-image'}
{loop type="image" name="product-image" product=$PRODUCT_ID limit="1" width="118" height="85" force_return="true"}
<img src="{$IMAGE_URL}" alt="Product #{$cart_count}"></a>
{/loop}
{/ifloop}
{elseloop rel="product-image"}
{images file='assets/img/product/1/118x85.png'}<img itemprop="image" src="{$asset_url}" alt="Product #{$cart_count}">{/images}
{/elseloop}
</td>
<td class="product" >
<h3 class="name"><a href="{$URL}">
{$TITLE}
</a></h3>
<div class="product-options">
<dl class="dl-horizontal">
<dt>{intl l="Available"} :</dt>
{if $STOCK > 0}
<dd>{intl l="In Stock"}</dd>
{else}
<dd>{intl l="Out of Stock"}</dd>
{/if}
<dt>{intl l="No."}</dt>
<dd>{$REF}</dd>
{loop type="attribute_combination" name="product_options" product_sale_elements="$PRODUCT_SALE_ELEMENTS_ID"}
<dt>{$ATTRIBUTE_TITLE}</dt>
<dd>{$ATTRIBUTE_AVAILABILITY_TITLE}</dd>
{/loop}
</dl>
</div>
<a href="{url path="/cart/delete/{$ITEM_ID}"}" class="btn btn-remove"><i class="icon-trash"></i> {intl l="Remove"}</a>
</td>
<td class="unitprice">
{if $IS_PROMO == 1}
{assign "real_price" $PROMO_TAXED_PRICE}
<div class="special-price"><span class="price">{currency attr="symbol"} {$PROMO_TAXED_PRICE}</span></div>
<small class="old-price">{intl l="instead of"} <span class="price">{currency attr="symbol"} {$TAXED_PRICE}</span></small>
{else}
{assign "real_price" $TAXED_PRICE}
<div class="special-price"><span class="price">{currency attr="symbol"} {$TAXED_PRICE}</span></div>
{/if}
</td>
<td class="qty">
<div class="form-group group-qty">
<form action="{url path="/cart/update"}" method="post" role="form">
<input type="hidden" name="cart_item" value="{$ITEM_ID}">
<select name="quantity" class="form-control js-update-quantity">
{for $will=1 to $STOCK}
<option {if $QUANTITY == $will}selected="selected"{/if}>{$will}</option>
{/for}
</select>
</form>
</div>
</td>
<td class="subprice">
<span class="price">{currency attr="symbol"} {$real_price * $QUANTITY}</span>
</td>
</tr>
{loop type="cart" name="cartloop"} {/loop}
<tr>
<td class="image">
<a href="{$PRODUCT_URL}" class="thumbnail">
{assign "cart_count" $LOOP_COUNT}
{ifloop rel='product-image'}
{loop type="image" name="product-image" product=$PRODUCT_ID limit="1" width="118" height="85" force_return="true"}
<img src="{$IMAGE_URL}" alt="Product #{$cart_count}"></a>
{/loop}
{/ifloop}
{elseloop rel="product-image"}
{images file='assets/img/product/1/118x85.png'}<img itemprop="image" src="{$asset_url}" alt="Product #{$cart_count}">{/images}
{/elseloop}
</td>
<td class="product" >
<h3 class="name"><a href="product-details.php">
Product #{$LOOP_COUNT}
</a></h3>
<div class="product-options">
<dl class="dl-horizontal">
<dt>{intl l="Available"} :</dt>
<dd>{intl l="In Stock"}</dd>
<dt>{intl l="No."}</dt>
<dd>{$REF}</dd>
{*<dt>Select Size</dt>
<dd>Large</dd>
<dt>Select Delivery Date</dt>
<dd>Jan 2, 2013</dd>
<dt>Additional Option</dt>
<dd>Option 1</dd>*}
</dl>
</div>
<a href="{url path="/cart/delete/{$ITEM_ID}"}" class="btn btn-remove">{intl l="Remove"}</a>
</td>
<td class="unitprice">
{if $IS_PROMO == 1}
{assign "real_price" $PROMO_TAXED_PRICE}
<div class="special-price"><span class="price">{currency attr="symbol"} {$PROMO_TAXED_PRICE}</span></div>
<small class="old-price">{intl l="instead of"} <span class="price">{currency attr="symbol"} {$TAXED_PRICE}</span></small>
{else}
{assign "real_price" $TAXED_PRICE}
<div class="special-price"><span class="price">{currency attr="symbol"} {$TAXED_PRICE}</span></div>
{/if}
</td>
<td class="qty">
<div class="form-group group-qty">
<form action="{url path="/cart/update"}" method="post" role="form">
<input type="hidden" name="cart_item" value="{$ITEM_ID}">
<select name="quantity" class="form-control js-update-quantity">
{for $will=1 to $STOCK}
<option {if $QUANTITY == $will}selected="selected"{/if}>{$will}</option>
{/for}
</select>
</form>
</div>
</td>
<td class="subprice">
<span class="price">{currency attr="symbol"} {$real_price * $QUANTITY}</span>
</td>
</tr>
{/loop}
</tbody> </tbody>
<tfoot> <tfoot>
<tr > <tr >
@@ -135,40 +136,43 @@
<a href="{navigate to="index"}" role="button" class="btn btn-continue-shopping"><span>{intl l="Continue Shopping"}</span></a> <a href="{navigate to="index"}" role="button" class="btn btn-continue-shopping"><span>{intl l="Continue Shopping"}</span></a>
<a href="{url path="/order/delivery"}" class="btn btn-checkout">{intl l="Proceed checkout"}</a> <a href="{url path="/order/delivery"}" class="btn btn-checkout">{intl l="Proceed checkout"}</a>
{/ifloop}
{elseloop rel="cartloop"}
<div class="cart-warning">
<strong>{intl l="Warning"}!</strong> {intl l="You have no items in your shopping cart."}
</div>
{/elseloop}
{/nocache}
</article> </article>
<aside id="products-upsell" role="complementary" aria-labelledby="products-upsell-label"> {ifloop rel="product_upsell"}
<div class="products-heading"> <aside id="products-upsell" role="complementary" aria-labelledby="products-upsell-label">
<h3 id="products-upsell-label">{intl l="Upsell Products"}</h3> <div class="products-heading">
</div> <h3 id="products-upsell-label">{intl l="Upsell Products"}</h3>
</div>
<div class="products-content"> <div class="products-content">
<ul class="products-grid product-col-<?php echo $product_upsell; ?> hover-effect"> <ul class="products-grid product-col-5 hover-effect">
<?php {loop name="product_upsell" type="product" promo="yes" limit="5"}
// Product Parameters {include file="includes/single-product.html" product_id=$ID hasBtn=true hasDescription=true width="218" height="146"}
$has_description = false; // Product without description {/loop}
$has_btn = false; // Product without button (Add to Cart)
for ($count = 1; $count <= $product_upsell; $count++) { ?> </ul>
<li class="item"> </div>
<?php include('inc/inc-product.php') ?> </aside><!-- #products-upsell -->
</li> {/ifloop}
<?php } ?>
</ul>
</div>
</aside><!-- #products-upsell -->
</div> </div>
{/block} {/block}
{block name="javascript-initialization"} {block name="javascript-initialization"}
<script type="text/javascript"> <script type="text/javascript">
jQuery(function($cart) { jQuery(function($cart) {
$cart('.js-update-quantity').on('change', function(e) { $cart('.js-update-quantity').on('change', function(e) {
var newQuantity = $cart(this).val(); var newQuantity = $cart(this).val();
$cart(this).parent().submit(); $cart(this).parent().submit();
}) })
}); });
</script> </script>
{/block} {/block}

View File

@@ -1,30 +1,24 @@
{extends file='layout.tpl'} {extends file='layout.tpl'}
{block name="breadcrumb"} {* Body Class *}
<nav class="nav-breadcrumb" role="navigation" aria-labelledby="breadcrumb-label"> {block name="body-class"}page-category{/block}
<strong id="breadcrumb-label">You are here: </strong>
<ul class="breadcrumb" itemprop="breadcrumb"> {* Breadcrumb *}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{navigate to="index"}" itemprop="url"><span itemprop="title">{intl l="Home"}</span></a></li> {block name='no-return-functions' append}
{loop name="category_path" type="category-path" category="{category attr="id"}"} {$sBreadcrumb = []}
{if $ID == {category attr="id"}} {loop name="category_path" type="category-path" category="{category attr="id"}"}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="active"> {$breadcrumbs[] = ['title' => {$TITLE}, 'url'=> {$URL nofilter}]}
<span itemprop="title">{$TITLE}</span> {/loop}
</li>
{else}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{$URL}" itemprop="url"><span itemprop="title">{$TITLE}</span></a></li>
{/if}
{/loop}
</ul>
</nav><!-- /.nav-breadcrumb -->
{/block} {/block}
{block name="main-content"} {block name="main-content"}
<div class="main layout-col-2-left"> <div class="main layout-col-2-left">
{$limit={$smarty.get.limit|default:8}} {$limit={$smarty.get.limit|default:8}}
{$product_page={$smarty.get.page|default:1}} {$product_page={$smarty.get.page|default:1}}
{$product_order={$smarty.get.order|default:'alpha'}} {$product_order={$smarty.get.order|default:'alpha'}}
<article class="col-main {$smarty.get.mode|default:"grid"}" role="main"> <article class="col-main {$smarty.get.mode|default:"grid"}" role="main">
{include file="includes/category-toolbar.html" toolbar="top" limit=$limit order=$product_order} {include file="includes/toolbar.html" toolbar="top" limit=$limit order=$product_order}
<div id="category-products"> <div id="category-products">
<div class="products-content"> <div class="products-content">
<ul class="product-col-4"> <ul class="product-col-4">
@@ -34,7 +28,7 @@
</ul> </ul>
</div> </div>
</div><!-- /#category-products --> </div><!-- /#category-products -->
{include file="includes/category-toolbar.html" toolbar="bottom"} {include file="includes/toolbar.html" toolbar="bottom"}
</article> </article>
<aside class="col-left" role="complementary" itemscope itemtype="http://schema.org/WPSideBar"> <aside class="col-left" role="complementary" itemscope itemtype="http://schema.org/WPSideBar">

View File

@@ -0,0 +1,36 @@
{extends file="layout.tpl"}
{block name="no-return-functions"}
{/block}
{block name="body-class"}page-content{/block}
{* Breadcrumb *}
{block name='no-return-functions' append}
{/block}
{block name="main-content"}
<div class="main layout-col-2-left" <!-- class="mainlayout-col-2-left -->">
<article class="col-main" role="main" aria-labelledby="main-label">
{loop name="blog.article" type="content" current="yes"}
<h1>{$TITLE}</h1>
<p class="chapo">
{$CHAPO}
</p>
<p>{$DESCRIPTION nofilter}</p>
{/loop}
</article>
<aside class="col-left" role="complementary" itemscope itemtype="http://schema.org/WPSideBar">
{include file="includes/asides/articles.html"}
</aside>
</div><!-- /.layout -->
{/block}
{block name="after-javascript-include"}{/block}

View File

@@ -0,0 +1,16 @@
<section id="categories" class="block block-nav" role="navigation" aria-labelledby="categories-label">
<div class="block-heading"><h3 class="block-title" >{intl l="Related"}</h3></div>
<div class="block-content">
<nav class="nav-categories">
<ul id="category" class="accordion">
{loop name="current_article" type="content" current="yes"}
{assign var="current_id" value={$ID}}
{/loop}
{loop name="blog.article" type="content" current_folder="yes" exclude="$current_id"}
<li><a href="{$URL}">{$TITLE}</a></li>
{/loop}
</ul>
</nav>
</div>
</section>

View File

@@ -0,0 +1,71 @@
{ifloop rel="cartloop"}
<li class="dropdown pull-right cart-not-empty">
<a href="{url path="/cart"}" rel="nofollow" class="cart">
{intl l="Cart"} <span class="badge">{cart attr="count_item"}</span>
</a>
<div class="dropdown-menu cart-content">
<form id="form-cart-mini" action="{url path="/order/delivery"}" method="post" role="form">
<table class="table table-cart-mini">
<colgroup>
<col width="70">
<col>
<col width="100">
</colgroup>
<tbody>
{assign "total_price" 0}
{loop type="cart" name="cartloop"}
<tr>
<td class="image">
{ifloop rel="product-image"}
{loop type="image" name="product-image" product=$PRODUCT_ID limit="1" width="118" height="60"}
<img src="{$IMAGE_URL}" alt="{$TITLE}">
{/loop}
{/ifloop}
</td>
<td class="product">
<h3 class="name" style="margin:0"><a href="{$URL}">
{$TITLE}
</a></h3>
<a href="{url path="/cart/delete/{$ITEM_ID}"}" class="btn btn-remove" data-tip="tooltip" data-title="Delete" data-original-title=""><i class="icon-trash"></i> <span>Remove</span></a>
</td>
<td class="unitprice text-center">
{if $IS_PROMO == 1}
{assign "real_price" $PROMO_TAXED_PRICE}
{else}
{assign "real_price" $TAXED_PRICE}
{/if}
<span class="qty">{$QUANTITY}</span> X <span class="price" style="font-size:1em;">{currency attr="symbol"}{$real_price}</span></div>
{assign "total_price" $total_price + ($QUANTITY * $real_price)}
</td>
</tr>
{/loop}
</tbody>
<tfoot>
<tr>
<td colspan="2" class="empty">
<a href="{url path="/cart"}" role="button" class="btn btn-default btn-sm"><span>{intl l="View Cart"}</span></a>
<button type="submit" name="checkout" class="btn btn-warning btn-sm"><span>{intl l="Checkout"}</span></button>
</td>
<td class="total">
<div class="total-price">
<span class="price">{currency attr="symbol"}{$total_price}</span>
</div>
</td>
</tr>
</tfoot>
</table>
</form>
</div>
</li>
{/ifloop}
{elseloop rel="cartloop"}
<li class="dropdown pull-right">
<a href="{url path="/cart"}" rel="nofollow" class="cart">
{intl l="Cart"} <span class="badge">0</span>
</a>
<div class="dropdown-menu cart-content">
<p>{intl l="You have no items in your shopping cart."}</p>
</div>
</li>
{/elseloop}

View File

@@ -1,65 +1,133 @@
<li class="item"> <li class="item">
<article itemscope itemtype="http://schema.org/Product"> {assign var="hasSubmit" value = false}
<!-- Use the meta tag to specify content that is not visible on the page in any way --> <article itemscope itemtype="http://schema.org/Product">
{loop name="brand.feature" type="feature" product=$ID title="brand"} <!-- Use the meta tag to specify content that is not visible on the page in any way -->
{loop name="brand.value" type="feature_value" feature=$ID product=$product_id} {loop name="brand.feature" type="feature" product=$ID title="brand"}
<meta itemprop="brand" content="{$TITLE}"> {loop name="brand.value" type="feature_value" feature=$ID product=$product_id}
{/loop} <meta itemprop="brand" content="{$TITLE}">
{/loop} {/loop}
{loop name="brand.feature" type="feature" product=$ID title="isbn"} {/loop}
{loop name="brand.value" type="feature_value" feature=$ID product=$product_id} {loop name="brand.feature" type="feature" product=$ID title="isbn"}
<meta itemprop="productID" content="isbn:{$TITLE}"> {loop name="brand.value" type="feature_value" feature=$ID product=$product_id}
{/loop} <meta itemprop="productID" content="isbn:{$TITLE}">
{/loop} {/loop}
<a href="{$URL}" itemprop="url" tabindex="-1" class="product-image">
{loop name="product_thumbnail" type="image" product=$ID width="{$width}" height="{$height}" resize_mode="borders" limit="1"}
<img itemprop="image" src="{$IMAGE_URL}" alt="Product #{$LOOP_COUNT}">
{/loop} {/loop}
{elseloop rel="product_thumbnail"}
{images file="../assets/img/{$width}x{$height}.png"}<img itemprop="image" src="{$asset_url}" alt="Product #{$LOOP_COUNT}">{/images}
{/elseloop}
<span class="mask"></span>
</a>
<div class="product-info"> <a href="{$URL}" itemprop="url" tabindex="-1" class="product-image">
<h3 class="name"><a href="{$URL}"><span itemprop="name">{$TITLE}</span></a></h3> {loop name="product_thumbnail" type="image" product=$ID width="{$width}" height="{$height}" resize_mode="borders" limit="1"}
{if $hasDescription} <img itemprop="image" src="{$IMAGE_URL}" alt="Product #{$LOOP_COUNT}">
<div class="description" itemprop="description"> {/loop}
<p>{$DESCRIPTION}</p> {elseloop rel="product_thumbnail"}
</div> {images file="../assets/img/{$width}x{$height}.png"}<img itemprop="image" src="{$asset_url}" alt="Product #{$LOOP_COUNT}">{/images}
{/if} {/elseloop}
</div> <span class="mask"></span>
</a>
<div class="product-price"> <div class="product-info">
<div class="price-container" itemprop="offers" itemscope itemtype="http://schema.org/Offer"> <h3 class="name"><a href="{$URL}"><span itemprop="name">{$TITLE}</span></a></h3>
<meta itemprop="category" content="{category attr="title"}"> {if $hasDescription}
<meta itemprop="itemCondition" itemscope itemtype="http://schema.org/NewCondition"> <!-- List of condition : NewCondition, DamagedCondition, UsedCondition, RefurbishedCondition --> <div class="description" itemprop="description">
<meta itemprop="priceCurrency" content="{currency attr="symbol"}"> <!-- List of currency : The currency used to describe the product price, in three-letter ISO format. --> <p>{$DESCRIPTION}</p>
<link itemprop="availability" href="http://schema.org/InStock" content="in_stock" /> </div>
<!-- List of availibility :
out_of_stock : http://schema.org/OutOfStock
in_stock : http://schema.org/InStock
instore_only : http://schema.org/InStoreOnly
preorder : http://schema.org/PreOrder
online_only : http://schema.org/OnlineOnly
-->
{if $IS_PROMO }
{loop name="productSaleElements_promo" type="product_sale_elements" product=$ID limit="1" order="min_price"}
{assign var="default_product_sale_elements" value=$ID}
<span class="special-price"><span itemprop="price" class="price-label">{intl l="Special Price:"} </span><span class="price">{format_number number=$TAXED_PROMO_PRICE} {currency attr="symbol"}</span></span>
<span class="old-price"><span class="price-label">{intl l="Regular Price:"} </span><span class="price">{format_number number=$TAXED_PRICE} {currency attr="symbol"}</span></span>
{/loop}
{else}
<span class="regular-price"><span itemprop="price" class="price">{format_number number=$BEST_TAXED_PRICE} {currency attr="symbol"}</span></span>
{/if} {/if}
</div>
<div class="product-price">
<div class="price-container" itemprop="offers" itemscope itemtype="http://schema.org/Offer">
<meta itemprop="category" content="{category attr="title"}">
<meta itemprop="itemCondition" itemscope itemtype="http://schema.org/NewCondition"> <!-- List of condition : NewCondition, DamagedCondition, UsedCondition, RefurbishedCondition -->
<meta itemprop="priceCurrency" content="{currency attr="symbol"}"> <!-- List of currency : The currency used to describe the product price, in three-letter ISO format. -->
<link itemprop="availability" href="http://schema.org/InStock" content="in_stock" />
<!-- List of availibility :
out_of_stock : http://schema.org/OutOfStock
in_stock : http://schema.org/InStock
instore_only : http://schema.org/InStoreOnly
preorder : http://schema.org/PreOrder
online_only : http://schema.org/OnlineOnly
-->
{if $IS_PROMO }
{loop name="productSaleElements_promo" type="product_sale_elements" product=$ID limit="1" order="min_price"}
{assign var="default_product_sale_elements" value=$ID}
<span class="special-price"><span itemprop="price" class="price-label">{intl l="Special Price:"} </span><span class="price">{format_number number=$TAXED_PROMO_PRICE} {currency attr="symbol"}</span></span>
<span class="old-price"><span class="price-label">{intl l="Regular Price:"} </span><span class="price">{format_number number=$TAXED_PRICE} {currency attr="symbol"}</span></span>
{/loop}
{else}
<span class="regular-price"><span itemprop="price" class="price">{format_number number=$BEST_TAXED_PRICE} {currency attr="symbol"}</span></span>
{/if}
</div>
{form name="thelia.cart.add" }
<form id="form-product-details" action="{url path="/cart/add" }" method="post" role="form">
{form_hidden_fields form=$form}
<input type="hidden" name="view" value="product">
<input type="hidden" name="product_id" value="{$ID}">
{if $form_error}<div class="alert alert-error">{$form_error_message}</div>{/if}
{form_field form=$form field='product_sale_elements_id'}
{if $default_product_sale_elements }
<input type="hidden" name="{$name}" value="{$default_product_sale_elements}" {$attr}>
{else}
{loop name="productSaleElements_promo" type="product_sale_elements" product="{$ID}" limit="1"}
<input type="hidden" name="{$name}" value="{$ID}" {$attr}>
{/loop}
{/if}
{/form_field}
{form_field form=$form field="product"}
<input id="{$label_attr.for}" type="hidden" name="{$name}" value="{$ID}" {$attr} >
{/form_field}
<fieldset class="product-options hide">
{ifloop rel="stock"}
<div class="option">
<label for="options" class="option-heading">Options</label>
<div class="option-content">
<select name="options" class="form-control">
{loop name="stock" type="product_sale_elements" product="$ID" order="min_price"}
{if $LOOP_TOTAL == 1}
{assign var="hasSubmit" value = true}
{/if}
{loop name="combi" type="attribute_combination" product_sale_elements="$ID" order="alpha"}
<option value="{$ID}" data-quantity="{$QUANTITY}" data-price="{format_number number="{$BEST_TAXED_PRICE}"} {currency attr="symbol"}" data-old-price="{format_number number="{$TAXED_PRICE}"} {currency attr="symbol"}">{$ATTRIBUTE_AVAILABILITY_TITLE}</small></option>
{/loop}
{/loop}
</select>
</div>
</div>
{/ifloop}
</fieldset>
<fieldset class="product-cart form-inline">
{form_field form=$form field='quantity'}
<div class="form-group group-qty hide {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label for="{$label_attr.for}">{$label}</label>
<input type="number" name="{$name}" id="{$label_attr.for}" class="form-control" value="{$value|default:1}" min="0" required>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span>
{/if}
</div>
{/form_field}
<div class="form-group group-btn">
</div>
<div>
<div class="product-btn">
{if $hasSubmit == true}
<button type="submit" class="btn btn-cart">{intl l="Add to cart"}</button>
{else}
<a href="{$URL}" class="btn btn-cart">{intl l="View product"}</a>
{/if}
</div>
</div>
</fieldset>
</form>
{/form}
</div> </div>
{if $hasBtn} </article><!-- /product -->
<div class="product-btn">
<button class="btn btn-cart">Add to cart</button>
</div>
{/if}
</div>
</article><!-- /product -->
</li> </li>

View File

@@ -6,11 +6,11 @@
<span class="limiter"> <span class="limiter">
<label for="limit-top">{intl l="Show"}</label> <label for="limit-top">{intl l="Show"}</label>
<select id="limit-top" name="limit"> <select id="limit-top" name="limit">
<option value="{url path="{category attr="url"}" limit="4"}" {if $limit==4}selected{/if}>4</option> <option value="{url path={navigate to="current"} limit="4"}" {if $limit==4}selected{/if}>4</option>
<option value="{url path="{category attr="url"}" limit="8"}" {if $limit==8}selected{/if}>8</option> <option value="{url path={navigate to="current"} limit="8"}" {if $limit==8}selected{/if}>8</option>
<option value="{url path="{category attr="url"}" limit="12"}" {if $limit==12}selected{/if}>12</option> <option value="{url path={navigate to="current"} limit="12"}" {if $limit==12}selected{/if}>12</option>
<option value="{url path="{category attr="url"}" limit="50"}"{if $limit==50}selected{/if}>50</option> <option value="{url path={navigate to="current"} limit="50"}"{if $limit==50}selected{/if}>50</option>
<option value="{url path="{category attr="url"}" limit="9999999999"}" {if $limit==9999999999}selected{/if}>All</option> <option value="{url path={navigate to="current"} limit="9999999999"}" {if $limit==9999999999}selected{/if}>All</option>
</select> </select>
<span class="per-page">{intl l="per page"}</span> <span class="per-page">{intl l="per page"}</span>
</span><!-- /.limiter --> </span><!-- /.limiter -->
@@ -19,10 +19,10 @@
<label for="sortby-top">{intl l="Sort By"}</label> <label for="sortby-top">{intl l="Sort By"}</label>
<select id="sortby-top" name="sortby"> <select id="sortby-top" name="sortby">
{*<option value="{url path="{category attr="url"}" order="manual"}">{intl l="Position"}</option>*} {*<option value="{url path="{category attr="url"}" order="manual"}">{intl l="Position"}</option>*}
<option value="{url path="{category attr="url"}" limit=$limit order="alpha"}" {if $order=="alpha"}selected{/if}>{intl l="Name ascending"}</option> <option value="{url path={navigate to="current"} limit=$limit order="alpha"}" {if $order=="alpha"}selected{/if}>{intl l="Name ascending"}</option>
<option value="{url path="{category attr="url"}" limit=$limit order="alpha_reverse"}" {if $order=="alpha_reverse"}selected{/if}>{intl l="Name descending"}</option> <option value="{url path={navigate to="current"} limit=$limit order="alpha_reverse"}" {if $order=="alpha_reverse"}selected{/if}>{intl l="Name descending"}</option>
<option value="{url path="{category attr="url"}" limit=$limit order="min_price"}" {if $order=="min_price"}selected{/if}>{intl l="Price ascending"}</option> <option value="{url path={navigate to="current"} limit=$limit order="min_price"}" {if $order=="min_price"}selected{/if}>{intl l="Price ascending"}</option>
<option value="{url path="{category attr="url"}" limit=$limit order="max_price"}" {if $order=="max_price"}selected{/if}>{intl l="Price descending"}</option> <option value="{url path={navigate to="current"} limit=$limit order="max_price"}" {if $order=="max_price"}selected{/if}>{intl l="Price descending"}</option>
{*<option value="{url path="{category attr="url"}" order="rating"}">{intl l="Rating"}</option>*} {*<option value="{url path="{category attr="url"}" order="rating"}">{intl l="Rating"}</option>*}
</select> </select>
</span><!-- /.sort-by --> </span><!-- /.sort-by -->
@@ -30,7 +30,7 @@
<span class="view-mode"> <span class="view-mode">
<span class="view-mode-label">{intl l="View as"}:</span> <span class="view-mode-label">{intl l="View as"}:</span>
<span class="view-mode-btn"> <span class="view-mode-btn">
<a href="{url path="{navigate to="current"}" mode="grid"}" data-toggle="view" role="button" class="btn btn-grid"><i class="icon-grid"></i></a> <a href="{url path="{navigate to="current"}" mode='grid'}" data-toggle="view" role="button" class="btn btn-grid"><i class="icon-grid"></i></a>
<a href="{url path="{navigate to="current"}" mode="list"}" data-toggle="view" role="button" class="btn btn-list "><i class="icon-list"></i></a> <a href="{url path="{navigate to="current"}" mode="list"}" data-toggle="view" role="button" class="btn btn-list "><i class="icon-list"></i></a>
</span> </span>
</span><!-- /.view-mode --> </span><!-- /.view-mode -->

View File

@@ -1,5 +1,10 @@
{extends file="layout.tpl"} {extends file="layout.tpl"}
{* Body Class *}
{block name="body-class"}page-home{/block}
{* Hide breadcrumb *}
{block name='breadcrumb'}{/block}
{block name="main-content"} {block name="main-content"}
<section class="carousel-container"> <section class="carousel-container">
@@ -25,7 +30,7 @@
<section id="products-new"> <section id="products-new">
<div class="products-heading"> <div class="products-heading">
<h2>Latest <a href="#latest" class="btn-all">+ View All</a></h2> <h2>{intl l="Latest"} <a href="{url path="/view_all" type="new"}" class="btn-all">{intl l="+ View All"}</a></h2>
</div> </div>
<div class="products-content"> <div class="products-content">
@@ -94,7 +99,7 @@
<section id="products-offer"> <section id="products-offer">
<div class="products-heading"> <div class="products-heading">
<h2>Offers <a href="#offer" class="btn-all">+ View All</a></h2> <h2>{intl l="Offers"} <a href="{url path="/view_all" type="offers"}" class="btn-all">{intl l="+ View All"}</a></h2>
</div> </div>
<div class="products-content"> <div class="products-content">

View File

@@ -11,34 +11,39 @@
Author: Christophe Laffont Author: Christophe Laffont
URL: http://www.thelia.net URL: http://www.thelia.net
--> -->
<!--[if lt IE 7 ]><html class="no-js oldie ie6" lang="fr"> <![endif]--> {* paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither *}
<!--[if IE 7 ]><html class="no-js oldie ie7" lang="fr"> <![endif]--> <!--[if lt IE 7 ]><html class="no-js oldie ie6" lang="{lang attr="code"}"> <![endif]-->
<!--[if IE 8 ]><html class="no-js oldie ie8" lang="fr"> <![endif]--> <!--[if IE 7 ]><html class="no-js oldie ie7" lang="{lang attr="code"}"> <![endif]-->
<!--[if (gte IE 9)|!(IE)]><!--><html lang="fr" class="no-js"> <!--<![endif]--> <!--[if IE 8 ]><html class="no-js oldie ie8" lang="{lang attr="code"}"> <![endif]-->
<!--[if (gte IE 9)|!(IE)]><!--><html lang="{lang attr="code"}" class="no-js"> <!--<![endif]-->
<head> <head>
{* Test if javascript is enabled *}
<script>(function(H) { H.className=H.className.replace(/\bno-js\b/,'js') } )(document.documentElement);</script> <script>(function(H) { H.className=H.className.replace(/\bno-js\b/,'js') } )(document.documentElement);</script>
<meta charset="utf-8">
<title>{block name="page-title"}Thelia - E-commerce plateform{/block}</title>
<meta charset="utf-8">
{* Page Title *}
<title>{block name="page-title"}{strip}{if $breadcrumbs}{foreach from=$breadcrumbs|array_reverse item=breadcrumb}{$breadcrumb.title} | {/foreach}{/if}{config key="company_name"}{/strip}{/block}</title>
{* Meta Tags *}
<meta name="description" content=""> <meta name="description" content="">
<meta name="generator" content="THELIA V2"> <meta name="generator" content="{intl l='Thelia V2'}">
<meta name="robots" content="index,follow"> <meta name="robots" content="index,follow">
<meta name="viewport" content="width=device-width,initial-scale=1.0"> <meta name="viewport" content="width=device-width,initial-scale=1.0">
{block name="meta"}{/block} {block name="meta"}{/block}
<!-- StyleSheet --> {* Stylesheets *}
{stylesheets file='assets/less/styles.less' filters='less,cssembed,cssrewrite'} {stylesheets file='assets/less/styles.less' filters='less,cssembed'}
<link rel="stylesheet" href="{$asset_url}"> <link rel="stylesheet" href="{$asset_url}">
{/stylesheets} {/stylesheets}
{debugbar_rendercss}
{block name="stylesheet"}{/block} {block name="stylesheet"}{/block}
</head> </head>
<body class="page-home" itemscope itemtype="http://schema.org/WebPage"> <body class="{block name="body-class"}{/block}" itemscope itemtype="http://schema.org/WebPage">
<!-- Accessibility --> <!-- Accessibility -->
<a class="sr-only" href="#content">Skip to content</a> <a class="sr-only" href="#content">{intl l="Skip to content"}</a>
<div class="page" role="document"> <div class="page" role="document">
@@ -50,38 +55,63 @@ URL: http://www.thelia.net
<div class="navbar-header"> <div class="navbar-header">
<!-- .navbar-toggle is used as the toggle for collapsed navbar content --> <!-- .navbar-toggle is used as the toggle for collapsed navbar content -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".nav-main"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".nav-main">
<span class="sr-only">Toggle navigation</span> <span class="sr-only">{intl l="Toggle navigation"}</span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
</button> </button>
<a class="navbar-brand" href="#">Thelia</a> <a class="navbar-brand" href="{navigate to="index"}">{config key="company_name"}</a>
</div> </div>
<!-- Place everything within .nav-collapse to hide it until above 768px --> <!-- Place everything within .nav-collapse to hide it until above 768px -->
<nav class="navbar-collapse collapse nav-main" role="navigation" aria-label="Main Navigation"> <nav class="navbar-collapse collapse nav-main" role="navigation" aria-label="{intl l="Main Navigation"}">
{nocache}
<ul class="nav navbar-nav navbar-cart navbar-right">
{loop type="auth" name="customer_info_block" roles="CUSTOMER" context="front"}
<li><a href="{url path="/logout"}" class="logout">{intl l="Log out!"}</a></li>
<li><a href="{url path="/account"}" class="account">{intl l="My Account"}</a></li>
{/loop}
{elseloop rel="customer_info_block"}
<li><a href="{url path="/register"}" class="register">{intl l="Register!"}</a></li>
<li class="dropdown">
<a href="{url path="/login"}" class="login">{intl l="Log In!"}</a>
<div class="dropdown-menu">
{form name="thelia.customer.login"}
<form id="form-login-mini" action="{url path="/login"}" method="post" role="form" {form_enctype form=$form}>
{form_hidden_fields form=$form}
{form_field form=$form field="email"}
<div class="form-group group-email">
<label for="{$label_attr.for}-mini">Email address</label>
<input type="email" name="{$name}" id="{$label_attr.for}-mini" class="form-control" aria-required="true" required>
</div>
{/form_field}
{form_field form=$form field="password"}
<div class="form-group group-password">
<label for="{$label_attr.for}-mini">Password</label>
<input type="password" name="{$name}" id="{$label_attr.for}-mini" class="form-control" aria-required="true" required>
</div>
{/form_field}
{form_field form=$form field="account"}
<input type="hidden" name="{$name}" value="1">
{/form_field}
<div class="group-btn">
<button type="submit" class="btn btn-login-mini">{intl l="Sign In"}</button>
<a href="{url path="/register"}" class="btn btn-register-mini">{intl l="Register"}</a>
</div>
</form>
{/form}
</div>
</li>
{/elseloop}
{include file="includes/mini-cart.html" nocache}
</ul>
{/nocache}
<ul class="nav navbar-nav navbar-categories"> <ul class="nav navbar-nav navbar-categories">
<li class="active"><a href="{url path="/"}" class="home" tabindex="-1">Home</a></li> <li><a href="{navigate to="index"}" class="home">{intl l="Home"}</a></li>
{loop type="category" name="category.navigation" parent="0"} {loop type="category" name="category.navigation" parent="0"}
<li><a href="{$URL}">{$TITLE}</a></li> <li><a href="{$URL}">{$TITLE}</a></li>
{/loop} {/loop}
</ul> </ul>
<ul class="nav navbar-nav navbar-cart navbar-right">
{loop type="auth" name="customer_info_block" roles="CUSTOMER" context="front"}
<li><a href="{url path="/logout"}" class="register">{intl l="Log out!"}</a></li>
<li><a href="{url path="/customer/account"}" class="login">{intl l="My Account"}</a></li>
{/loop}
{elseloop rel="customer_info_block"}
<li><a href="{url path="/register"}" class="register">{intl l="Register"}!</a></li>
<li><a href="{url path="/login"}" class="login">{intl l="Log In!"}</a></li>
{/elseloop}
<li class="dropdown">
<a href="{url path="/cart"}" class="dropdown-toggle cart" {*data-toggle="dropdown"*}>
Cart <span class="badge">{cart attr="count_item"}</span>
</a>
</li>
</ul>
</nav> </nav>
</div> </div>
</div> </div>
@@ -90,28 +120,28 @@ URL: http://www.thelia.net
<header class="container" role="banner"> <header class="container" role="banner">
<div class="header"> <div class="header">
<h1 class="logo"> <h1 class="logo">
<a href="{url path="/"}" class="Thelia * Since 2006 *"> <a href="{navigate to="index"}" title="{config key="company_name"}">
{images file='assets/img/logo.gif'}<img src="{$asset_url}" alt="Thelia">{/images} {images file='assets/img/logo.gif'}<img src="{$asset_url}" alt="{config key="company_name"}">{/images}
</a> </a>
</h1> </h1>
<div class="language-container"> <div class="language-container">
<div class="search-container"> <div class="search-container">
<form id="form-search" action="search.html" method="get" role="search" aria-labelledby="search-label"> <form id="form-search" action="{url path="/search"}" method="get" role="search" aria-labelledby="search-label">
<label id="search-label" for="q">Search a product</label> <label id="search-label" for="q">{intl l="Search a product"}</label>
<div class="input-group"> <div class="input-group">
<input type="search" name="q" id="q" placeholder="Search..." class="form-control" aria-required="true" required pattern=". { 2,}" title="Minmimum 2 characters."> <input type="search" name="q" id="q" placeholder="{intl l="Search..."}" class="form-control" autocomplete="off" aria-required="true" required pattern=".{ldelim}2,{rdelim}" title="{intl l="Minimum 2 characters."}">
<div class="input-group-btn"> <div class="input-group-btn">
<button type="submit" class="btn btn-search"><i class="icon-search"></i> <span>Search</span></button> <button type="submit" class="btn btn-search"><i class="icon-search"></i> <span>{intl l="Search"}</span></button>
</div> </div>
</div> </div>
</form> </form>
</div> </div>
<div class="language-switch" aria-labelledby="language-label"> <div class="language-switch" aria-labelledby="language-label">
<span id="language-label" class="dropdown-label">Language:</span> <span id="language-label" class="dropdown-label">{intl l="Language:"}</span>
<a class="current dropdown-toggle" data-toggle="dropdown" href="language.html">{lang attr="title"}</a> <a class="current dropdown-toggle" data-toggle="dropdown" href="{url path="/language"}">{lang attr="title"}</a>
<ul class="select dropdown-menu"> <ul class="select dropdown-menu">
{loop type="lang" name="lang_available" exclude="{lang attr="id"}"} {loop type="lang" name="lang_available" exclude="{lang attr="id"}"}
<li><a href="?lang={$CODE}">{$TITLE}</a></li> <li><a href="?lang={$CODE}">{$TITLE}</a></li>
@@ -120,8 +150,8 @@ URL: http://www.thelia.net
</div> </div>
<div class="currency-switch" aria-labelledby="currency-label"> <div class="currency-switch" aria-labelledby="currency-label">
<span id="currency-label" class="dropdown-label">{intl l="Currency"}:</span> <span id="currency-label" class="dropdown-label">{intl l="Currency:"}</span>
<a class="current dropdown-toggle" data-toggle="dropdown" href="currency.html">{currency attr="code"}</a> <a class="current dropdown-toggle" data-toggle="dropdown" href="{url path="/currency"}">{currency attr="code"}</a>
<ul class="select dropdown-menu"> <ul class="select dropdown-menu">
{loop type="currency" name="currency_available" exclude="{currency attr="id"}" } {loop type="currency" name="currency_available" exclude="{currency attr="id"}" }
<li><a href="?currency={$ISOCODE}">{$SYMBOL} - {$NAME}</a></li> <li><a href="?currency={$ISOCODE}">{$SYMBOL} - {$NAME}</a></li>
@@ -137,7 +167,7 @@ URL: http://www.thelia.net
<main class="main-container" role="main"> <main class="main-container" role="main">
<div class="container"> <div class="container">
{block name="breadcrumb"}{/block} {block name="breadcrumb"}{include file="misc/breadcrumb.tpl"}{/block}
{block name="main-content"}{/block} {block name="main-content"}{/block}
</div><!-- /.container --> </div><!-- /.container -->
</main><!-- /.main-container --> </main><!-- /.main-container -->
@@ -170,26 +200,23 @@ URL: http://www.thelia.net
<section class="block block-links"> <section class="block block-links">
<div class="block-heading"><h3 class="block-title">Latest articles</h3></div> <div class="block-heading"><h3 class="block-title">Latest articles</h3></div>
<div class="block-content"> <div class="block-content">
<ul> {ifloop rel="blog.articles"}
<li> <ul>
<a href="#"> {loop type="content" name="blog.articles" folder="1" limit="3"}
<h4 class="block-subtitle">Heading</h4> <li>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit...</p> <a href="{$URL}">
</a> <h4 class="block-subtitle">{$TITLE}</h4>
</li> <p>{$CHAPO}</p>
<li> </a>
<a href="#"> </li>
<h4 class="block-subtitle">Heading</h4> {/loop}
<p>Lorem ipsum dolor sit amet...</p> </ul>
</a> {/ifloop}
</li> {elseloop rel="blog.articles"}
<li> <ul>
<a href="#"> <li>{intl l="No articles currently"}</li>
<h4 class="block-subtitle">Heading</h4> </ul>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit...</p> {/elseloop}
</a>
</li>
</ul>
</div> </div>
</section> </section>
</div> </div>
@@ -198,13 +225,12 @@ URL: http://www.thelia.net
<div class="block-heading"><h3 class="block-title">Usefull links</h3></div> <div class="block-heading"><h3 class="block-title">Usefull links</h3></div>
<div class="block-content"> <div class="block-content">
<ul> <ul>
<li class="active"><a href="#" tabindex="-1">About Us </a></li> {loop name="footer_links" type="content" folder="2"}
<li><a href="#">Delivery & Returns</a></li> <li><a href="{$URL}">{$TITLE}</a></li>
<li><a href="#">Terms & Conditions </a></li> {/loop}
<li><a href="contact.html">Contact Us</a></li>
<li><a href="{url path="/login"}">Login</a></li> <li><a href="{url path="/login"}">Login</a></li>
<li><a href="{url path="/register"}">Register</a></li> <li><a href="{url path="/register"}">Register</a></li>
<li><a href="checkout.html">Checkout</a></li> <li><a href="{url path="/order/delivery"}">Checkout</a></li>
</ul> </ul>
</div> </div>
</section> </section>
@@ -217,50 +243,50 @@ URL: http://www.thelia.net
<ul role="presentation"> <ul role="presentation">
<li> <li>
<a href="http://facebook.com" class="facebook" data-toggle="tooltip" data-placement="top" title="facebook" target="_blank"> <a href="http://facebook.com" class="facebook" data-toggle="tooltip" data-placement="top" title="facebook" target="_blank">
<span class="icon-stack"> <span class="icon-stack">
<span class="icon-circle icon-stack-base"></span> <span class="icon-circle icon-stack-base"></span>
<span class="icon-facebook icon-light"></span> <span class="icon-facebook icon-light"></span>
</span> </span>
</a> </a>
</li> </li>
<li> <li>
<a href="http://twitter.com" class="twitter" data-toggle="tooltip" data-placement="top" title="twitter" target="_blank"> <a href="http://twitter.com" class="twitter" data-toggle="tooltip" data-placement="top" title="twitter" target="_blank">
<span class="icon-stack"> <span class="icon-stack">
<span class="icon-circle icon-stack-base"></span> <span class="icon-circle icon-stack-base"></span>
<span class="icon-twitter icon-light"></span> <span class="icon-twitter icon-light"></span>
</span> </span>
</a> </a>
</li> </li>
<li> <li>
<a href="http://instagram.com" class="instagram" data-toggle="tooltip" data-placement="top" title="instagram" target="_blank"> <a href="http://instagram.com" class="instagram" data-toggle="tooltip" data-placement="top" title="instagram" target="_blank">
<span class="icon-stack"> <span class="icon-stack">
<span class="icon-circle icon-stack-base"></span> <span class="icon-circle icon-stack-base"></span>
<span class="icon-instagram icon-light"></span> <span class="icon-instagram icon-light"></span>
</span> </span>
</a> </a>
</li> </li>
<li> <li>
<a href="http://google.com" class="google-plus" data-toggle="tooltip" data-placement="top" title="google+" target="_blank"> <a href="http://google.com" class="google-plus" data-toggle="tooltip" data-placement="top" title="google+" target="_blank">
<span class="icon-stack"> <span class="icon-stack">
<span class="icon-circle icon-stack-base"></span> <span class="icon-circle icon-stack-base"></span>
<span class="icon-google-plus icon-light"></span> <span class="icon-google-plus icon-light"></span>
</span> </span>
</a> </a>
</li> </li>
<li> <li>
<a href="http://youtube.com" class="youtube" data-toggle="tooltip" data-placement="top" title="youtube" target="_blank"> <a href="http://youtube.com" class="youtube" data-toggle="tooltip" data-placement="top" title="youtube" target="_blank">
<span class="icon-stack"> <span class="icon-stack">
<span class="icon-circle icon-stack-base"></span> <span class="icon-circle icon-stack-base"></span>
<span class="icon-youtube icon-light"></span> <span class="icon-youtube icon-light"></span>
</span> </span>
</a> </a>
</li> </li>
<li> <li>
<a href="#rss" class="rss" data-toggle="tooltip" data-placement="top" title="rss" target="_blank"> <a href="#rss" class="rss" data-toggle="tooltip" data-placement="top" title="rss" target="_blank">
<span class="icon-stack"> <span class="icon-stack">
<span class="icon-circle icon-stack-base"></span> <span class="icon-circle icon-stack-base"></span>
<span class="icon-rss icon-light"></span> <span class="icon-rss icon-light"></span>
</span> </span>
</a> </a>
</li> </li>
</ul> </ul>
@@ -268,15 +294,15 @@ URL: http://www.thelia.net
</section> </section>
<section class="block block-newsletter"> <section class="block block-newsletter">
<div class="block-heading"><h3 class="block-title">Newsletter</h3></div> <div class="block-heading"><h3 class="block-title">{intl l="Newsletter"}</h3></div>
<div class="block-content"> <div class="block-content">
<p id="newletter-describe">Sign up to receive our latest news.</p> <p id="newletter-describe">{intl l="Sign up to receive our latest news."}</p>
<form id="form-newsletter" action="" method="post" role="form"> <form id="form-newsletter" action="{url path="/newsletter"}" method="post" role="form">
<div class="form-group"> <div class="form-group">
<label for="email">Email address</label> <label for="email">{intl l="Email address"}</label>
<input type="email" name="email" id="email" class="form-control" placeholder="Your email address" aria-describedby="newletter-describe" aria-required="true" required autocomplete="off"> <input type="email" name="email" id="email" class="form-control" placeholder="{intl l="Your email address"}" aria-describedby="newletter-describe" aria-required="true" required autocomplete="off">
</div> </div>
<button type="submit" class="btn btn-subscribe">Subscribe</button> <button type="submit" class="btn btn-subscribe">{intl l="Subscribe"}</button>
</form> </form>
</div> </div>
</section> </section>
@@ -286,7 +312,7 @@ URL: http://www.thelia.net
<section class="block block-contact" itemscope itemtype="http://schema.org/Organization"> <section class="block block-contact" itemscope itemtype="http://schema.org/Organization">
<div class="block-heading"><h3 class="block-title">Contact Us</h3></div> <div class="block-heading"><h3 class="block-title">Contact Us</h3></div>
<div class="block-content"> <div class="block-content">
<meta itemprop="name" content="Thelia V2"> <meta itemprop="name" content="{config key="company_name"}">
<ul> <ul>
<li class="contact-address"> <li class="contact-address">
<address class="adr" itemprop="address" itemscope itemtype="http://schema.org/PostalAddress"> <address class="adr" itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">
@@ -299,7 +325,7 @@ URL: http://www.thelia.net
<span class="tel" itemprop="telephone">+33 04 44 05 31 00</span> <span class="tel" itemprop="telephone">+33 04 44 05 31 00</span>
</li> </li>
<li class="contact-email"> <li class="contact-email">
<a href="mailto:demo@thelia.net" class="email" itemprop="email">info@thelia.net</a> {mailto address="info@thelia.net" encode="hex" extra='class="email" itemprop="email"'}
</li> </li>
</ul> </ul>
</div> </div>
@@ -315,8 +341,9 @@ URL: http://www.thelia.net
<div class="info"> <div class="info">
<nav class="nav-footer" role="navigation"> <nav class="nav-footer" role="navigation">
<ul> <ul>
<li class="active"><a href="#" tabindex="-1">About Us </a></li> {loop name="footer_links" type="content" folder="2"}
<li><a href="#">Delivery & Returns</a></li> <li><a href="{$URL}">{$TITLE}</a></li>
{/loop}
<li><a href="#">Site Map</a></li> <li><a href="#">Site Map</a></li>
<li><a href="#">Terms & Conditions</a></li> <li><a href="#">Terms & Conditions</a></li>
<li><a href="#">Contact Us</a></li> <li><a href="#">Contact Us</a></li>
@@ -344,59 +371,28 @@ URL: http://www.thelia.net
} }
</script> </script>
<!-- Bootstrap --> {javascripts file='assets/js/bootstrap/bootstrap.js'}
{javascripts file='assets/js/bootstrap/affix.js'}
<script src="{$asset_url}"></script> <script src="{$asset_url}"></script>
{/javascripts} {/javascripts}
{javascripts file='assets/js/bootstrap/tooltip.js'}
<script src="{$asset_url}"></script> {javascripts file='assets/js/plugins/bootbox/bootbox.js'}
{/javascripts}
{javascripts file='assets/js/bootstrap/popover.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap/tab.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap/scrollspy.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap/transition.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap/alert.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap/button.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap/carousel.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap/collapse.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap/dropdown.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap/modal.js'}
<script src="{$asset_url}"></script> <script src="{$asset_url}"></script>
{/javascripts} {/javascripts}
{block name="after-javascript-include"}{/block}
{block name="javascript-initialization"}{/block}
<!-- Custom scripts --> <!-- Custom scripts -->
{javascripts file='assets/js/script.js'} {javascripts file='assets/js/script.js'}
<script src="{$asset_url}"></script> <script src="{$asset_url}"></script>
{/javascripts} {/javascripts}
{debugbar_renderjs}
{debugbar_renderresult}
{* HTML5 shim, for IE6-8 support of HTML5 elements *}
<!--[if lt IE 9]> <!--[if lt IE 9]>
<script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script> <script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]--> <![endif]-->
{block name="after-javascript-include"}{/block}
{block name="javascript-initialization"}{/block}
</body> </body>
</html> </html>

View File

@@ -1,62 +1,63 @@
{extends file="layout.tpl"} {extends file="layout.tpl"}
{block name="breadcrumb"} {* Body Class *}
<nav class="nav-breadcrumb" role="navigation" aria-labelledby="breadcrumb-label"> {block name="body-class"}page-login{/block}
<strong id="breadcrumb-label">{intl l="You are here"}: </strong>
<ul class="breadcrumb" itemprop="breadcrumb"> {* Breadcrumb *}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{navigate to="index"}" itemprop="url"><span itemprop="title">{intl l="Home"}</span></a></li> {block name='no-return-functions' append}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="active"><span itemprop="title">{intl l="Login"}</span></li> {$breadcrumbs = [
</ul> ['title' => {intl l="Login"}, 'url'=>{url path="/login"}]
</nav><!-- /.nav-breadcrumb --> ]}
{/block} {/block}
{block name="main-content"} {block name="main-content"}
<div class="main"> <div class="main">
<article class="col-main" role="main" aria-labelledby="main-label"> <article class="col-main" role="main" aria-labelledby="main-label">
<h1 id="main-label" class="page-header">{intl l="Login"}</h1> <h1 id="main-label" class="page-header">{intl l="Login"}</h1>
{form name="thelia.customer.login"} {form name="thelia.customer.login"}
<form id="form-login" action="{url path="/customer/login"}" method="post" role="form" {form_enctype form=$form}> <form id="form-login" action="{url path="/login"}" method="post" role="form" {form_enctype form=$form}>
{if $form_error}<div class="alert alert-danger">{$form_error_message}</div>{/if} {if $form_error}<div class="alert alert-danger">{$form_error_message}</div>{/if}
{form_field form=$form field='success_url'} {form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{navigate to="return_to"}" /> {* the url the user is redirected to on login success *} <input type="hidden" name="{$name}" value="{navigate to="return_to"}"> {* the url the user is redirected to on login success *}
{/form_field} {/form_field}
{form_field form=$form field='error_message'} {form_field form=$form field='error_message'}
<input type="hidden" name="{$name}" value="{intl l="missing or invalid data"}" /> {* the url the user is redirected to on login success *} <input type="hidden" name="{$name}" value="{intl l="missing or invalid data"}"> {* the url the user is redirected to on login success *}
{/form_field} {/form_field}
{form_hidden_fields form=$form} {form_hidden_fields form=$form}
<fieldset> <fieldset>
{form_field form=$form field="email"} {form_field form=$form field="email"}
<div class="form-group group-email {if $error}has-error{/if} "> <div class="form-group group-email{if $error} has-error{/if}">
<label for="{$label_attr.for}">{$label}</label> <label for="{$label_attr.for}">{$label}</label>
<div class="control-input"> <div class="control-input">
<input type="email" name="{$name}" id="{$label_attr.for}" value="{$value}" class="form-control" {$attr} aria-required="true" autofocus required> <input type="email" name="{$name}" id="{$label_attr.for}" value="{$value}" class="form-control" {$attr} {if $required}aria-required="true" required{/if}{if !$value || $error} autofocus{/if}>
{if $error} {if $error}
<span class="help-block"><span class="icon-remove"></span> {$message}</span> <span class="help-block"><span class="icon-remove"></span> {$message}</span>
{assign var="error_focus" value="true"}
{elseif !$value}
{assign var="error_focus" value="true"}
{/if} {/if}
</div> </div>
</div> </div>
{/form_field} {/form_field}
<fieldset> <fieldset>
{form_field form=$form field="account"}
<legend>{intl l="Do you have an account?"}</legend> <legend>{intl l="Do you have an account?"}</legend>
<div class="radio radio-account0" > {foreach $choices as $choice}
<label for="account0"> <div class="radio radio-account{$choice->value}">
<input type="radio" name="account" id="account0" data-toggle="password" value="0" > {intl l="No, I am a new customer."} <label for="{$label_attr.for}{$choice->value}">
</label> <input type="radio" name="{$name}" id="{$label_attr.for}{$choice->value}" data-toggle="password" value="{$choice->value}"{if $value === {$choice->value}} checked{/if}> {$choice->label}
</div> </label>
<div class="radio radio-account1"> </div>
<label for="account1"> {/foreach}
<input type="radio" name="account" id="account1" data-toggle="password" value="1" checked> {intl l="Yes, I have a password :"} {/form_field}
</label>
</div>
{form_field form=$form field="password"} {form_field form=$form field="password"}
<div class="form-group group-password {if $error}has-error{/if} "> <div class="form-group group-password{if $error} has-error{/if}">
<label for="{$label_attr.for}" class="sr-only">{$label}</label> <label for="{$label_attr.for}" class="sr-only">{$label}</label>
<div class="control-input"> <div class="control-input">
<input type="password" name="{$name}" id="{$label_attr.for}" class="form-control" autocomplete="off"> <input type="password" name="{$name}" id="{$label_attr.for}" class="form-control" autocomplete="off"{if !isset($error_focus)} autofocus{/if}>
{if $error} {if $error}
<span class="help-block"><span class="icon-remove"></span> {$message}</span> <span class="help-block"><span class="icon-remove"></span> {$message}</span>
{/if} {/if}
@@ -67,7 +68,7 @@
</fieldset> </fieldset>
<div class="group-btn"> <div class="group-btn">
<a href="{url path="/password"}" class="forgot-password">{intl l="Forgot your Password ?"}</a> <a href="{url path="/password"}" data-toggle="confirmation" class="forgot-password">{intl l="Forgot your Password?"}</a>
<button type="submit" class="btn btn-login">{intl l="Next"}</button> <button type="submit" class="btn btn-login">{intl l="Next"}</button>
</div> </div>
</form> </form>

View File

@@ -0,0 +1,16 @@
<nav class="nav-breadcrumb" role="navigation" aria-labelledby="breadcrumb-label">
<strong id="breadcrumb-label">{intl l="You are here:"}</strong>
<ul class="breadcrumb" itemprop="breadcrumb">
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{navigate to="index"}" itemprop="url"><span itemprop="title">{intl l="Home"}</span></a></li>
{foreach $breadcrumbs as $breadcrumb}
{if $breadcrumb.title}
{if $breadcrumb@last}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="active"><span itemprop="title">{$breadcrumb.title}</span></li>
{else}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{$breadcrumb.url|default:'#' nofilter}" title="{$breadcrumb.title}" itemprop="url"><span itemprop="title">{$breadcrumb.title}</span></a></li>
{/if}
{/if}
{/foreach}
</ul>
</nav><!-- /.nav-breadcrumb -->

View File

@@ -5,17 +5,18 @@
{check_cart_not_empty} {check_cart_not_empty}
{/block} {/block}
{block name="breadcrumb"} {* Body Class *}
<nav class="nav-breadcrumb" role="navigation" aria-labelledby="breadcrumb-label"> {block name="body-class"}page-order-delivery{/block}
<strong id="breadcrumb-label">{intl l="You are here"} : </strong>
<ul class="breadcrumb" itemprop="breadcrumb"> {* Breadcrumb *}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{navigate to="index"}" itemprop="url"><span itemprop="title">{intl l="Home"}</span></a></li> {block name='no-return-functions' append}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{url path="/cart"}" itemprop="url"><span itemprop="title">{intl l="Cart"}</span></a></li> {$breadcrumbs = [
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="active"><span itemprop="title">{intl l="Billing and delivery"}</span></li> ['title' => {intl l="Cart"}, 'url'=>{url path="/cart"}],
</ul> ['title' => {intl l="Billing and delivery"}, 'url'=>{url path="/order/delivery"}]
</nav><!-- /.nav-breadcrumb --> ]}
{/block} {/block}
{block name="main-content"} {block name="main-content"}
<div class="main"> <div class="main">
<article id="cart" class="col-main" role="main" aria-labelledby="main-label"> <article id="cart" class="col-main" role="main" aria-labelledby="main-label">

View File

@@ -6,17 +6,18 @@
{check_valid_delivery} {check_valid_delivery}
{/block} {/block}
{block name="breadcrumb"} {* Body Class *}
<nav class="nav-breadcrumb" role="navigation" aria-labelledby="breadcrumb-label"> {block name="body-class"}page-order-invoice{/block}
<strong id="breadcrumb-label">{intl l="You are here"} : </strong>
<ul class="breadcrumb" itemprop="breadcrumb"> {* Breadcrumb *}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{navigate to="index"}" itemprop="url"><span itemprop="title">{intl l="Home"}</span></a></li> {block name='no-return-functions' append}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{url path="/cart"}" itemprop="url"><span itemprop="title">{intl l="Cart"}</span></a></li> {$breadcrumbs = [
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="active"><span itemprop="title">{intl l="My order"}</span></li> ['title' => {intl l="Cart"}, 'url'=>{url path="/cart"}],
</ul> ['title' => {intl l="My order"}, 'url'=>{url path="/order/invoice"}]
</nav><!-- /.nav-breadcrumb --> ]}
{/block} {/block}
{block name="main-content"} {block name="main-content"}
<div class="main"> <div class="main">
<article class="col-main" role="main" aria-labelledby="main-label"> <article class="col-main" role="main" aria-labelledby="main-label">

View File

@@ -1,16 +1,17 @@
{extends file="layout.tpl"} {extends file="layout.tpl"}
{block name="breadcrumb"} {* Body Class *}
<nav class="nav-breadcrumb" role="navigation" aria-labelledby="breadcrumb-label"> {block name="body-class"}page-order-payment{/block}
<strong id="breadcrumb-label">{intl l="You are here"} : </strong>
<ul class="breadcrumb" itemprop="breadcrumb"> {* Breadcrumb *}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{navigate to="index"}" itemprop="url"><span itemprop="title">{intl l="Home"}</span></a></li> {block name='no-return-functions' append}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{url path="/cart"}" itemprop="url"><span itemprop="title">{intl l="Cart"}</span></a></li> {$breadcrumbs = [
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="active"><span itemprop="title">{intl l="Secure Payment"}</span></li> ['title' => {intl l="Cart"}, 'url'=>{url path="/cart"}],
</ul> ['title' => {intl l="Secure Payment"}, 'url'=>{url path="/order/pay"}]
</nav><!-- /.nav-breadcrumb --> ]}
{/block} {/block}
{block name="main-content"} {block name="main-content"}
<div class="main"> <div class="main">
<article class="col-main clearfix" role="main" aria-labelledby="main-label"> <article class="col-main clearfix" role="main" aria-labelledby="main-label">

View File

@@ -1,15 +1,16 @@
{extends file="layout.tpl"} {extends file="layout.tpl"}
{block name="breadcrumb"} {* Body Class *}
<nav class="nav-breadcrumb" role="navigation" aria-labelledby="breadcrumb-label"> {block name="body-class"}page-password{/block}
<strong id="breadcrumb-label">{intl l="You are here"} </strong>
<ul class="breadcrumb" itemprop="breadcrumb"> {* Breadcrumb *}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{navigate to="index"}" itemprop="url"><span itemprop="title">{intl l="Home"}</span></a></li> {block name='no-return-functions' append}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="active"><span itemprop="title">{intl l="Password"}</span></li> {$breadcrumbs = [
</ul> ['title' => {intl l="Password"}, 'url'=>{url path="/password"}]
</nav><!-- /.nav-breadcrumb --> ]}
{/block} {/block}
{block name="main-content"} {block name="main-content"}
<div class="main"> <div class="main">
<article class="col-main" role="main" aria-labelledby="main-label"> <article class="col-main" role="main" aria-labelledby="main-label">

View File

@@ -1,20 +1,20 @@
{extends file="layout.tpl"} {extends file="layout.tpl"}
{block name="breadcrumb"} {* Body Class *}
<nav class="nav-breadcrumb" role="navigation" aria-labelledby="breadcrumb-label"> {block name="body-class"}page-product{/block}
<strong id="breadcrumb-label">{intl l="You are here"}: </strong>
<ul class="breadcrumb" itemprop="breadcrumb"> {* Breadcrumb *}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{navigate to="index"}" itemprop="url"><span itemprop="title">{intl l="Home"}</span></a></li> {block name='no-return-functions' append}
{loop type="product" name="product_breadcrumb" id="{product attr="id"}"} {$sBreadcrumb = []}
{loop name="category_path" type="category-path" category="{$DEFAULT_CATEGORY}"} {loop type="product" name="product_breadcrumb" id="{product attr="id"}"}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{$URL}" itemprop="url"><span itemprop="title">{$TITLE}</span></a></li> {loop name="category_path" type="category-path" category="{$DEFAULT_CATEGORY}"}
{/loop} {$breadcrumbs[] = ['title' => {$TITLE}, 'url'=> {$URL}]}
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="active"><span itemprop="title">{$TITLE}</span></li> {/loop}
{/loop} {$breadcrumbs[] = ['title' => {$TITLE}, 'url'=> {$URL}]}
</ul> {/loop}
</nav><!-- /.nav-breadcrumb -->
{/block} {/block}
{block name="main-content"} {block name="main-content"}
<div class="main"> <div class="main">
{loop name="product.details" type="product" id="{product attr="id"}"} {loop name="product.details" type="product" id="{product attr="id"}"}
@@ -26,8 +26,8 @@
<meta itemprop="brand" content="{$TITLE}"> <meta itemprop="brand" content="{$TITLE}">
{/loop} {/loop}
{/loop} {/loop}
{loop name="isbn.feature" type="feature" product=$ID title="isbn"} {loop name="brand.feature" type="feature" product="{$ID}" title="isbn"}
{loop name="brand.value" type="feature_value" feature=$ID product=$product_id} {loop name="brand.value" type="feature_value" feature="{$ID}" product=$product_id}
<meta itemprop="productID" content="isbn:{$TITLE}"> <meta itemprop="productID" content="isbn:{$TITLE}">
{/loop} {/loop}
{/loop} {/loop}
@@ -88,9 +88,32 @@
</div> </div>
</div> </div>
{loop name="stock_meta" type="product_sale_elements" product="$ID"}
{loop name="combi_meta" type="attribute_combination" product_sale_elements="$ID"}
{if $LOOP_COUNT == 0}
{if $QUANTITY == 0}
{assign var="current_stock_class" value = "out-of-stock"}
{assign var="current_stock_href" value = "http://schema.org/OutOfStock"}
{else}
{assign var="current_stock_class" value = "out-of-stock"}
{assign var="current_stock_href" value = "http://schema.org/OutOfStock"}
{/if}
{/if}
{/loop}
{/loop}
<div class="product-price" itemprop="offers" itemscope itemtype="http://schema.org/Offer"> <div class="product-price" itemprop="offers" itemscope itemtype="http://schema.org/Offer">
<div class="availability"><span class="availibity-label">{intl l="Availability"}: </span><span itemprop="availability" href="http://schema.org/InStock" class="in-stock">In stock</span></div> <div class="availability">
<span class="availibity-label">{intl l="Availability"}: </span>
<span itemprop="availability" href="{$current_stock_href}" class="{$current_stock_class}" id="stockInformations">
<span class="in">{intl l='In stock'}</span><span class="out">{intl l='Out of stock'}</span>
</span>
</div>
<div class="price-container"> <div class="price-container">
{loop type="category" name="category_tag" id=$DEFAULT_CATEGORY} {loop type="category" name="category_tag" id=$DEFAULT_CATEGORY}
@@ -98,14 +121,6 @@
{/loop} {/loop}
<meta itemprop="itemCondition" itemscope itemtype="http://schema.org/NewCondition"> <!-- List of condition : NewCondition, DamagedCondition, UsedCondition, RefurbishedCondition --> <meta itemprop="itemCondition" itemscope itemtype="http://schema.org/NewCondition"> <!-- List of condition : NewCondition, DamagedCondition, UsedCondition, RefurbishedCondition -->
<meta itemprop="priceCurrency" content="{currency attr="symbol"}"> <!-- List of currency : The currency used to describe the product price, in three-letter ISO format. --> <meta itemprop="priceCurrency" content="{currency attr="symbol"}"> <!-- List of currency : The currency used to describe the product price, in three-letter ISO format. -->
<link itemprop="availability" href="http://schema.org/InStock" content="in_stock" />
<!-- List of availibility :
out_of_stock : http://schema.org/OutOfStock
in_stock : http://schema.org/InStock
instore_only : http://schema.org/InStoreOnly
preorder : http://schema.org/PreOrder
online_only : http://schema.org/OnlineOnly
-->
{if $IS_PROMO } {if $IS_PROMO }
{loop name="productSaleElements_promo" type="product_sale_elements" product="{$ID}" limit="1" order="min_price"} {loop name="productSaleElements_promo" type="product_sale_elements" product="{$ID}" limit="1" order="min_price"}
{assign var="default_product_sale_elements" value="$ID"} {assign var="default_product_sale_elements" value="$ID"}
@@ -136,36 +151,24 @@
{/if} {/if}
{/form_field} {/form_field}
{form_field form=$form field="product"} {form_field form=$form field="product"}
<input id="{$label_attr.for}" type="hidden" name="{$name}" value="{$ID}" {$attr} > <input id="{$label_attr.for}" type="hidden" name="{$name}" value="{$ID}" {$attr} >
{/form_field} {/form_field}
<fieldset class="product-options"> <fieldset class="product-options">
<div class="option option-color"> {ifloop rel="stock"}
<label for="option-color" class="option-heading">Show</label> <div class="option">
<label for="options" class="option-heading">Options</label>
<div class="option-content"> <div class="option-content">
<select id="option-color" name="option-color" class="form-control"> <select name="options" class="form-control">
<option value="0">Blue</option> {loop name="stock" type="product_sale_elements" product="$ID" order="min_price"}
<option value="1">Red</option> {loop name="combi" type="attribute_combination" product_sale_elements="$ID" order="alpha"}
<option value="2">Purple</option> <option value="{$ID}" data-quantity="{$QUANTITY}" data-price="{format_number number="{$BEST_TAXED_PRICE}"} {currency attr="symbol"}" data-old-price="{format_number number="{$TAXED_PRICE}"} {currency attr="symbol"}">{$ATTRIBUTE_AVAILABILITY_TITLE}</small></option>
{/loop}
{/loop}
</select> </select>
</div> </div>
</div> </div>
{/ifloop}
<div class="option option-size">
<fieldset>
<legend class="option-heading">Size</legend>
<div class="option-content">
<label class="checkbox-inline" for="size1">
<input type="checkbox" name="size1" id="size1" value="1"> Large
</label>
<label class="checkbox-inline" for="size2">
<input type="checkbox" name="size2" id="size2" value="2"> Medium
</label>
<label class="checkbox-inline" for="size3">
<input type="checkbox" name="size3" id="size3" value="3"> Small
</label>
</div>
</fieldset>
</div>
</fieldset> </fieldset>
<fieldset class="product-cart form-inline"> <fieldset class="product-cart form-inline">
{form_field form=$form field='quantity'} {form_field form=$form field='quantity'}
@@ -201,10 +204,11 @@
{ifloop rel="feature_value_info"} {ifloop rel="feature_value_info"}
<ul> <ul>
{loop name="feature_info" type="feature" product="{$ID}"} {loop name="feature_info" type="feature" product="{$ID}"}
<li> <strong>{$TITLE}</strong> : <li>
{loop name="feature_value_info" type="feature_value" feature="{$ID}" product="{product attr="id"}"} <strong>{$TITLE}</strong> :
{$TITLE} {loop name="feature_value_info" type="feature_value" feature="{$ID}" product="{product attr="id"}"}
{/loop} {$TITLE}
{/loop}
</li> </li>
{/loop} {/loop}
</ul> </ul>

View File

@@ -1,15 +1,12 @@
{extends file="layout.tpl"} {extends file="layout.tpl"}
{block name="breadcrumb"} {* Body Class *}
<nav class="nav-breadcrumb" role="navigation" aria-labelledby="breadcrumb-label"> {block name="body-class"}page-register{/block}
<strong id="breadcrumb-label">{intl l="You are here"}: </strong>
<ul class="breadcrumb" itemprop="breadcrumb">
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="{navigate to="index"}" itemprop="url"><span itemprop="title">{intl l="Home"}</span></a></li>
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="active"><span itemprop="title">{intl l="Register"}</span></li>
</ul>
</nav><!-- /.nav-breadcrumb -->
{/block}
{* Breadcrumb *}
{block name='no-return-functions' append}
{$breadcrumbs = [['title' => {intl l="Register"}, 'url'=>{url path="/register"}]]}
{/block}
{block name="main-content"} {block name="main-content"}
<div class="main"> <div class="main">
@@ -18,13 +15,13 @@
<h1 id="main-label" class="page-header">{intl l="Create New Account"}</h1> <h1 id="main-label" class="page-header">{intl l="Create New Account"}</h1>
{form name="thelia.customer.creation"} {form name="thelia.customer.creation"}
<form id="form-register" class="form-horizontal" action="{url path="/customer/create"}" method="post" role="form"> <form id="form-register" class="form-horizontal" action="{url path="/register"}" method="post" role="form">
{form_field form=$form field='success_url'} {form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{navigate to="return_to"}" /> {* the url the user is redirected to on login success *} <input type="hidden" name="{$name}" value="{url path="/account"}" /> {* the url the user is redirected to on registration success *}
{/form_field} {/form_field}
{form_field form=$form field='error_message'} {form_field form=$form field='error_message'}
<input type="hidden" name="{$name}" value="{intl l="missing or invalid data"}" /> {* the url the user is redirected to on login success *} <input type="hidden" name="{$name}" value="{intl l="missing or invalid data"}" />
{/form_field} {/form_field}
{form_hidden_fields form=$form} {form_hidden_fields form=$form}
{if $form_error}<div class="alert alert-danger">{$form_error_message}</div>{/if} {if $form_error}<div class="alert alert-danger">{$form_error_message}</div>{/if}
@@ -36,9 +33,9 @@
<div class="panel-body"> <div class="panel-body">
{form_field form=$form field="title"} {form_field form=$form field="title"}
<div class="form-group group-title {if $error}has-error{elseif $value != "" && !$error}has-success{/if}"> <div class="form-group group-title {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label} <span class="required">*</span></label> <label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input"> <div class="control-input">
<select name="{$name}" id="{$label_attr.for}" class="form-control" required autofocus> <select name="{$name}" id="{$label_attr.for}" class="form-control"{if $required} aria-required="true" required{/if}{if !$value || $error} autofocus{/if}>
<option value="">-- {intl l="Select Title"} --</option> <option value="">-- {intl l="Select Title"} --</option>
{loop type="title" name="country.list"} {loop type="title" name="country.list"}
<option value="{$ID}" {if $value == $ID}selected{/if} >{$LONG}</option> <option value="{$ID}" {if $value == $ID}selected{/if} >{$LONG}</option>
@@ -46,6 +43,9 @@
</select> </select>
{if $error } {if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span> <span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif !$value}
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error} {elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span> <span class="help-block"><i class="icon-ok"></i></span>
{/if} {/if}
@@ -54,11 +54,12 @@
{/form_field} {/form_field}
{form_field form=$form field="firstname"} {form_field form=$form field="firstname"}
<div class="form-group group-firstname {if $error}has-error{elseif $value != "" && !$error}has-success{/if}"> <div class="form-group group-firstname {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label} <span class="required">*</span></label> <label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input"> <div class="control-input">
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="John" value="{$value}" required> <input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="John" value="{$value}" {if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error } {if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span> <span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error} {elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span> <span class="help-block"><i class="icon-ok"></i></span>
{/if} {/if}
@@ -67,11 +68,12 @@
{/form_field} {/form_field}
{form_field form=$form field="lastname"} {form_field form=$form field="lastname"}
<div class="form-group group-lastname {if $error}has-error{elseif $value != "" && !$error}has-success{/if}"> <div class="form-group group-lastname {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label} <span class="required">*</span></label> <label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input"> <div class="control-input">
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="John" value="{$value}" autofocus required> <input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="Doe" value="{$value}" {if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error } {if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span> <span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error} {elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span> <span class="help-block"><i class="icon-ok"></i></span>
{/if} {/if}
@@ -80,12 +82,13 @@
{/form_field} {/form_field}
{form_field form=$form field="email"} {form_field form=$form field="email"}
<div class="form-group group-email {if $error}has-error{elseif $value != "" && !$error}has-success{/if}"> <div class="form-group group-email {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label} <span class="required">*</span></label> <label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input"> <div class="control-input">
<input type="email" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="johndoe@domain.com" required value="{$smarty.get.email|default:$value}"> <input type="email" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="johndoe@domain.com" value="{$smarty.get.email|default:$value}"{if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error } {if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span> <span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error} {elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span> <span class="help-block"><i class="icon-ok"></i></span>
{/if} {/if}
@@ -94,11 +97,12 @@
{/form_field} {/form_field}
{form_field form=$form field="phone"} {form_field form=$form field="phone"}
<div class="form-group group-phone {if $error}has-error{elseif $value != "" && !$error}has-success{/if}"> <div class="form-group group-phone {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label}</label> <label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input"> <div class="control-input">
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="" value="{$value}" autofocus> <input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="" value="{$value}"{if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error } {if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span> <span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error} {elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span> <span class="help-block"><i class="icon-ok"></i></span>
{/if} {/if}
@@ -107,11 +111,12 @@
{/form_field} {/form_field}
{form_field form=$form field="cellphone"} {form_field form=$form field="cellphone"}
<div class="form-group group-cellphone {if $error}has-error{elseif $value != "" && !$error}has-success{/if}"> <div class="form-group group-cellphone {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label}</label> <label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input"> <div class="control-input">
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="" value="{$value}" autofocus> <input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="" value="{$value}"{if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error } {if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span> <span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error} {elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span> <span class="help-block"><i class="icon-ok"></i></span>
{/if} {/if}
@@ -129,11 +134,12 @@
<div class="panel-body"> <div class="panel-body">
{form_field form=$form field="company"} {form_field form=$form field="company"}
<div class="form-group group-company {if $error}has-error{elseif $value != "" && !$error}has-success{/if}"> <div class="form-group group-company {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label}</label> <label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input"> <div class="control-input">
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="Thelia" value="{$value}" autofocus> <input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="Google" value="{$value}"{if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error } {if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span> <span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error} {elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span> <span class="help-block"><i class="icon-ok"></i></span>
{/if} {/if}
@@ -143,11 +149,12 @@
{form_field form=$form field="address1"} {form_field form=$form field="address1"}
<div class="form-group group-address1 {if $error}has-error{elseif $value != "" && !$error}has-success{/if}"> <div class="form-group group-address1 {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label} <span class="required">*</span></label> <label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input"> <div class="control-input">
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="{$label}" value="{$value}" autofocus required> <input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="76 Ninth Avenue" value="{$value}"{if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error } {if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span> <span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error} {elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span> <span class="help-block"><i class="icon-ok"></i></span>
{/if} {/if}
@@ -157,11 +164,12 @@
{form_field form=$form field="address2"} {form_field form=$form field="address2"}
<div class="form-group group-address2 {if $error}has-error{elseif $value != "" && !$error}has-success{/if}"> <div class="form-group group-address2 {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label}</label> <label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input"> <div class="control-input">
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="" value="{$value}" autofocus> <input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="" value="{$value}"{if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error } {if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span> <span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error} {elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span> <span class="help-block"><i class="icon-ok"></i></span>
{/if} {/if}
@@ -171,11 +179,12 @@
{form_field form=$form field="city"} {form_field form=$form field="city"}
<div class="form-group group-city {if $error}has-error{elseif $value != "" && !$error}has-success{/if}"> <div class="form-group group-city {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label} <span class="required">*</span></label> <label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input"> <div class="control-input">
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="New York" value="{$value}" autofocus required> <input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="New York" value="{$value}"{if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error } {if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span> <span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error} {elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span> <span class="help-block"><i class="icon-ok"></i></span>
{/if} {/if}
@@ -185,11 +194,12 @@
{form_field form=$form field="zipcode"} {form_field form=$form field="zipcode"}
<div class="form-group group-zip {if $error}has-error{elseif $value != "" && !$error}has-success{/if}"> <div class="form-group group-zip {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label} <span class="required">*</span></label> <label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input"> <div class="control-input">
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="H2T 2V6" value="{$value}" autofocus required> <input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" placeholder="NY 10011" value="{$value}"{if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error } {if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span> <span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error} {elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span> <span class="help-block"><i class="icon-ok"></i></span>
{/if} {/if}
@@ -199,9 +209,9 @@
{form_field form=$form field="country"} {form_field form=$form field="country"}
<div class="form-group group-country {if $error}has-error{elseif $value != "" && !$error}has-success{/if}"> <div class="form-group group-country {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label} <span class="required">*</span></label> <label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input"> <div class="control-input">
<select name="{$name}" id="{$label_attr.for}" class="form-control" required> <select name="{$name}" id="{$label_attr.for}" class="form-control"{if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
<option value="">-- {intl l="Select Country"} --</option> <option value="">-- {intl l="Select Country"} --</option>
{loop type="country" name="country.list"} {loop type="country" name="country.list"}
<option value="{$ID}" <option value="{$ID}"
@@ -216,6 +226,7 @@
</select> </select>
{if $error } {if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span> <span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error} {elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span> <span class="help-block"><i class="icon-ok"></i></span>
{/if} {/if}
@@ -232,11 +243,12 @@
<div class="panel-body"> <div class="panel-body">
{form_field form=$form field="password"} {form_field form=$form field="password"}
<div class="form-group group-password {if $error}has-error{elseif $value != "" && !$error}has-success{/if}"> <div class="form-group group-password {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label} <span class="required">*</span></label> <label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input"> <div class="control-input">
<input type="password" name="{$name}" id="{$label_attr.for}" class="form-control" required autocomplete="off"> <input type="password" name="{$name}" id="{$label_attr.for}" class="form-control" autocomplete="off"{if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error } {if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span> <span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error} {elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span> <span class="help-block"><i class="icon-ok"></i></span>
{/if} {/if}
@@ -246,11 +258,12 @@
{form_field form=$form field="password_confirm"} {form_field form=$form field="password_confirm"}
<div class="form-group group-password_confirm {if $error}has-error{elseif $value != "" && !$error}has-success{/if}"> <div class="form-group group-password_confirm {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
<label class="control-label" for="{$label_attr.for}">{$label} <span class="required">*</span></label> <label class="control-label" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input"> <div class="control-input">
<input type="password" name="{$name}" id="{$label_attr.for}" class="form-control" required autocomplete="off"> <input type="password" name="{$name}" id="{$label_attr.for}" class="form-control" autocomplete="off"{if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error } {if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span> <span class="help-block"><i class="icon-remove"></i> {$message}</span>
{assign var="error_focus" value="true"}
{elseif $value != "" && !$error} {elseif $value != "" && !$error}
<span class="help-block"><i class="icon-ok"></i></span> <span class="help-block"><i class="icon-ok"></i></span>
{/if} {/if}
@@ -260,19 +273,24 @@
</div> </div>
</fieldset> </fieldset>
<div class="form-group group-agreed"> {form_field form=$form field="agreed"}
<div class="form-group group-agreed{if $error} has-error{/if}">
<div class="control-input"> <div class="control-input">
<div class="checkbox"> <div class="checkbox">
<label class="control-label" for="agreed"> <label class="control-label" for="{$label_attr.for}">
<input type="checkbox" name="agreed" id="agreed" value="1" required> I've read and agreed on <a href="#">Terms &amp; Conditions</a>. <input type="checkbox" name="{$name}" id="{$label_attr.for}" value="{$value}"{if $checked} checked{/if} {if $required} aria-required="true" required{/if}>I've read and agreed on <a href="#">Terms &amp; Conditions</a></a>.
</label> </label>
{if $error }
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
{/if}
</div> </div>
</div> </div>
</div><!--/.form-group--> </div><!--/.form-group-->
{/form_field}
<div class="form-group group-btn"> <div class="form-group group-btn">
<div class="control-btn"> <div class="control-btn">
<button type="submit" class="btn btn-register">Sign in</button> <button type="submit" class="btn btn-register">{intl l="Sign in"}</button>
</div> </div>
</div><!--/.form-group--> </div><!--/.form-group-->
</form> </form>

View File

@@ -0,0 +1,47 @@
{extends file="layout.tpl"}
{block name="body-class"}page-search{/block}
{* Breadcrumb *}
{block name='no-return-functions' append}
{$breadcrumbs = [
['title' => {intl l="Search"}, 'url'=>{url path="/search"}]
]}
{/block}
{block name="main-content"}
<div class="main">
{$limit={$smarty.get.limit|default:8}}
{$product_page={$smarty.get.page|default:1}}
{$product_order={$smarty.get.order|default:'alpha'}}
<article class="col-main {$smarty.get.mode|default:"grid"}" role="main" aria-labelledby="main-label">
<h1 id="main-label" class="page-header">{intl l="Search Result for"} <small>{$smarty.get.q}</small></h1>
{include file="includes/toolbar.html" toolbar="top" limit=$limit order=$product_order}
<div id="category-products">
<div class="products-content">
{ifloop rel="product_list"}
<ul class="product-col-3">
{loop type="product" name="product_list" title="{$smarty.get.q}" limit=$limit page=$product_page order=$product_order}
{include file="includes/single-product.html" product_id=$ID hasBtn=true hasDescription=true width="218" height="146"}
{assign "products_count" $LOOP_TOTAL}
{/loop}
</ul>
{/ifloop}
{elseloop rel="product_list"}
<h2 class="text-center">{intl l="No results found"} </h2>
{/elseloop}
</div>
</div><!-- /#category-products -->
{ifloop rel="product_list"}
{include file="includes/toolbar.html" toolbar="bottom"}
{/ifloop}
</article>
</div><!-- /.layout -->
{/block}
{block name="after-javascript-include"}{/block}

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