Initialize multiple language and start translations (#91)

* Initialize multiple language and start translations

* continue with translation

* end translations for en and it

* fix json syntax en translation, otherwise i18n reset the file

* add language info in config

* fix json format invalid

* solve review comments
master
Andrea Di Mario 2019-11-06 09:31:25 +01:00 committed by Mark Moffat
parent 161be3075d
commit d3abc37cb0
47 changed files with 898 additions and 445 deletions

100
app.js
View File

@ -17,6 +17,7 @@ const { runIndexing } = require('./lib/indexing');
const { addSchemas } = require('./lib/schema');
const { initDb } = require('./lib/db');
let handlebars = require('express-handlebars');
const i18n = require('i18n');
// Validate our settings schema
const Ajv = require('ajv');
@ -68,6 +69,20 @@ const authorizenet = require('./routes/payments/authorizenet');
const app = express();
// Language initialize
i18n.configure({
locales: config.availableLanguages,
defaultLocale: config.defaultLocale,
cookie: 'locale',
queryParameter: 'lang',
directory: `${__dirname}/locales`,
directoryPermissions: '755',
api: {
__: '__', // now req.__ becomes req.__
__n: '__n' // and req.__n can be called as req.__n
}
});
// view engine setup
app.set('views', path.join(__dirname, '/views'));
app.engine('hbs', handlebars({
@ -81,6 +96,16 @@ app.set('view engine', 'hbs');
// helpers for the handlebar templating platform
handlebars = handlebars.create({
helpers: {
// Language helper
__: () => { return i18n.__(this, arguments); },
__n: () => { return i18n.__n(this, arguments); },
availableLanguages: (block) => {
let total = ''
for(const lang of i18n.getLocales()){
total += block.fn(lang);
}
return total;
},
perRowClass: (numProducts) => {
if(parseInt(numProducts) === 1){
return'col-md-12 col-xl-12 col m12 xl12 product-item';
@ -123,22 +148,22 @@ handlebars = handlebars.create({
},
getStatusColor: (status) => {
switch(status){
case'Paid':
return'success';
case'Approved':
return'success';
case'Approved - Processing':
return'success';
case'Failed':
return'danger';
case'Completed':
return'success';
case'Shipped':
return'success';
case'Pending':
return'warning';
default:
return'danger';
case'Paid':
return'success';
case'Approved':
return'success';
case'Approved - Processing':
return'success';
case'Failed':
return'danger';
case'Completed':
return'success';
case'Shipped':
return'success';
case'Pending':
return'warning';
default:
return'danger';
}
},
checkProductOptions: (opts) => {
@ -194,26 +219,26 @@ handlebars = handlebars.create({
},
ifCond: (v1, operator, v2, options) => {
switch(operator){
case'==':
return(v1 === v2) ? options.fn(this) : options.inverse(this);
case'!=':
return(v1 !== v2) ? options.fn(this) : options.inverse(this);
case'===':
return(v1 === v2) ? options.fn(this) : options.inverse(this);
case'<':
return(v1 < v2) ? options.fn(this) : options.inverse(this);
case'<=':
return(v1 <= v2) ? options.fn(this) : options.inverse(this);
case'>':
return(v1 > v2) ? options.fn(this) : options.inverse(this);
case'>=':
return(v1 >= v2) ? options.fn(this) : options.inverse(this);
case'&&':
return(v1 && v2) ? options.fn(this) : options.inverse(this);
case'||':
return(v1 || v2) ? options.fn(this) : options.inverse(this);
default:
return options.inverse(this);
case'==':
return(v1 === v2) ? options.fn(this) : options.inverse(this);
case'!=':
return(v1 !== v2) ? options.fn(this) : options.inverse(this);
case'===':
return(v1 === v2) ? options.fn(this) : options.inverse(this);
case'<':
return(v1 < v2) ? options.fn(this) : options.inverse(this);
case'<=':
return(v1 <= v2) ? options.fn(this) : options.inverse(this);
case'>':
return(v1 > v2) ? options.fn(this) : options.inverse(this);
case'>=':
return(v1 >= v2) ? options.fn(this) : options.inverse(this);
case'&&':
return(v1 && v2) ? options.fn(this) : options.inverse(this);
case'||':
return(v1 || v2) ? options.fn(this) : options.inverse(this);
default:
return options.inverse(this);
}
},
isAnAdmin: (value, options) => {
@ -262,6 +287,9 @@ app.use(session({
store: store
}));
// Set locales from session
app.use(i18n.init);
// serving static content
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'views', 'themes')));

View File

@ -109,6 +109,12 @@
},
"secretSession": {
"type": "string"
},
"availableLanguages": {
"type": "array"
},
"defaultLocale": {
"type": "string"
}
},
"required": [

View File

@ -24,5 +24,7 @@
"databaseConnectionString": "mongodb://127.0.0.1:27017/expresscart",
"theme": "Cloth",
"trackStock": false,
"orderHook": ""
"orderHook": "",
"availableLanguages": ["en", "it"],
"defaultLocale": "en"
}

164
locales/en.json Normal file
View File

@ -0,0 +1,164 @@
{
"Languages": "Languages",
"en": "English",
"it": "Italiano",
"Cart": "Cart",
"Name": "Name",
"New": "New",
"Settings": "Settings",
"General settings": "General settings",
"Address 1": "Address 1",
"Address 2": "Address 2",
"Country": "Country",
"State": "State",
"Postcode": "Postcode",
"Phone number": "Phone number",
"Creation date": "Creation date",
"Customers can be filtered by: email, name or phone number": "Customers can be filtered by: email, name or phone number",
"Customers": "Customers",
"Filtered term": "Filtered term",
"No orders found": "No orders found",
"Email address": "Email address",
"Please enter your email address": "Please enter your email address",
"Reset": "Reset",
"Please sign in": "Please sign in",
"Sign in": "Sign in",
"Update status": "Update status",
"Go Back": "Go Back",
"Order date": "Order date",
"Order ID": "Order ID",
"Payment Gateway ref": "Payment Gateway ref",
"Payment Gateway": "Payment Gateway",
"Order total amount": "Order total amount",
"First name": "First name",
"Last name": "Last name",
"Order comment": "Order comment",
"Products ordered": "Products ordered",
"Options": "Options",
"Filter": "Filter",
"By status": "By status",
"Orders can be filtered by: surname, email address or postcode/zipcode": "Orders can be filtered by: surname, email address or postcode/zipcode",
"Completed": "Completed",
"Paid": "Paid",
"Created": "Created",
"Cancelled": "Cancelled",
"Declined": "Declined",
"Shipped": "Shipped",
"Pending": "Pending",
"Orders": "Orders",
"Recent orders": "Recent orders",
"Status": "Status",
"Upload image": "Upload image",
"Save product": "Save product",
"Edit product": "Edit product",
"Product title": "Product title",
"Product price": "Product price",
"Published": "Published",
"Draft": "Draft",
"Stock level": "Stock level",
"Product description": "Product description",
"Validate": "Validate",
"This sets a readable URL for the product": "This sets a readable URL for the product",
"Product options": "Product options",
"Label": "Label",
"Type": "Type",
"Add": "Add",
"Remove": "Remove",
"Here you can set options for your product. Eg: Size, color, style": "Here you can set options for your product. Eg: Size, color, style",
"Allow comment": "Allow comment",
"Allow free form comments when adding products to cart": "Allow free form comments when adding products to cart",
"Product tag words": "Product tag words",
"Tag words used to indexed products, making them easier to find and filter.": "Tag words used to indexed products, making them easier to find and filter.",
"Product images": "Product images",
"Delete": "Delete",
"main image": "main image",
"Set as main image": "Set as main image",
"No images have been uploaded for this product": "No images have been uploaded for this product",
"Product image upload": "Product image upload",
"Select file": "Select file",
"Upload": "Upload",
"New product": "New product",
"Products can be filtered by: product title or product description keywords": "Products can be filtered by: product title or product description keywords",
"Products": "Products",
"Recent products": "Recent products",
"Confirm": "Confirm",
"Update": "Update",
"Setting_menu_explain": "Here you can setup a menu to displayed on your shopping cart. You can use this menu to filter your products by specifying a keyword in the \"link\" field. Eg: To show products with a keyword (or tag) of boots you would set the menu field to \"Backpacks\" and a link value \"backpack\". You can also use this menu to link to static pages, Eg: shipping, returns, help, about, contact etc.",
"Static page": "Static page",
"Page name": "Page name",
"A friendly name to manage the static page.": "A friendly name to manage the static page.",
"Page slug": "Page slug",
"Page_Slug_Description": "This is the relative URL of the page. Eg: A setting of \"about\" would make the page available at: mydomain.com/about",
"Page Enabled": "Page Enabled",
"Page content": "Page content",
"Here you can enter the content you wish to be displayed on your static page.": "Here you can enter the content you wish to be displayed on your static page.",
"New page": "New page",
"Static pages": "Static pages",
"Static_Pages_Info": "Here you can setup and manage static pages for your shopping cart. You may want to setup a page with a little bit about your business called \"About\" or \"Contact Us\" etc.",
"Edit": "Edit",
"There are currently no static pages setup. Please setup a static page.": "There are currently no static pages setup. Please setup a static page.",
"Create new": "Create new",
"Search": "Search",
"Cart name": "Cart name",
"This element is critical for search engine optimisation. Cart title is displayed if your logo is hidden.": "This element is critical for search engine optimisation. Cart title is displayed if your logo is hidden.",
"Cart description": "Cart description",
"This description shows when your website is listed in search engine results.": "This description shows when your website is listed in search engine results.",
"Cart image/logo": "Cart image/logo",
"Cart URL": "Cart URL",
"This URL is used in sitemaps and when your customer returns from completing their payment.": "This URL is used in sitemaps and when your customer returns from completing their payment.",
"This is used as the \"from\" email when sending receipts to your customers.": "This is used as the \"from\" email when sending receipts to your customers.",
"Flat shipping rate": "Flat shipping rate",
"A flat shipping rate applied to all orders.": "A flat shipping rate applied to all orders.",
"Free shipping threshold": "Free shipping threshold",
"Orders over this value will mean the shipped will the FREE. Set to high value if you always want to charge shipping.": "Orders over this value will mean the shipped will the FREE. Set to high value if you always want to charge shipping.",
"Payment gateway": "Payment gateway",
"Payment_Gateway_Info": "You will also need to configure your payment gateway credentials in the `/config/&lt;gateway_name&gt;.json` file.",
"Currency symbol": "Currency symbol",
"Set this to your currency symbol. Eg: $, £, €": "Set this to your currency symbol. Eg: $, £, €",
"Theme": "Theme",
"Theme_Info": "Themes are loaded from `/public/themes/`",
"Products per row": "Products per row",
"The number of products to be displayed across the page.": "The number of products to be displayed across the page.",
"Products per page": "Products per page",
"The number of products to be displayed on each page.": "The number of products to be displayed on each page.",
"Menu Enabled": "Menu Enabled",
"Menu_Enabled_Info": "If a menu is set you can set it up <a href=\"/admin/settings/menu\">here</a>.",
"Menu header": "Menu header",
"The heading text for your menu.": "The heading text for your menu.",
"Menu location": "Menu location",
"The location of your menu.": "The location of your menu.",
"Google_Analytics_Info": "Your Google Analytics code. Please also inlude the \"script\" tags - <a href=\"https://support.google.com/analytics/answer/1032385?hl=en\" target=\"_blank\">Help</a>",
"Custom CSS": "Custom CSS",
"Send test email": "Send test email",
"Users name": "Users name",
"User email": "User email",
"Password confirm": "Password confirm",
"User password": "User password",
"Complete setup": "Complete setup",
"User is admin?": "User is admin?",
"Generate": "Generate",
"New User": "New User",
"Create": "Create",
"Role": "Role",
"User": "User",
"No products found": "No products found",
"Category": "Category",
"Search results": "Search results",
"Add to cart": "Add to cart",
"Pay now": "Pay now",
"Customer details": "Customer details",
"Existing customer": "Existing customer",
"Forgotten": "Forgotten",
"Change customer": "Change customer",
"Enter a password to create an account for next time": "Enter a password to create an account for next time",
"Create account": "Create account",
"Your payment has been successfully processed": "Your payment has been successfully processed",
"Your payment has failed. Please try again or contact us.": "Your payment has failed. Please try again or contact us.",
"Please retain the details above as a reference of payment.": "Please retain the details above as a reference of payment.",
"Quantity": "Quantity",
"Leave a comment?": "Leave a comment?",
"Cart contents": "Cart contents",
"Shipping": "Shipping:",
"Empty cart": "Empty cart",
"List": "List"
}

165
locales/it.json Normal file
View File

@ -0,0 +1,165 @@
{
"Languages": "Lingue",
"en": "English",
"it": "Italiano",
"Cart": "Carrello",
"Name": "Nome",
"New": "Nuovo",
"List": "Lista",
"Settings": "Impostazioni",
"General settings": "Impostazioni generali",
"Address 1": "Indirizzo 1",
"Address 2": "Indirizzo 2",
"Country": "Paese",
"State": "Stato",
"Postcode": "Codice postale",
"Phone number": "Numero di telefono",
"Creation date": "Data di creazione",
"Customers can be filtered by: email, name or phone numnber": "I clienti sono filtrati per: email, nome o numero di telefono",
"Customers": "Clienti",
"Filtered term": "Filtri",
"No orders found": "Nessun ordine trovato",
"Email address": "Indirizzo email",
"Please enter your email address": "Inserisci il tuo indirizzo email",
"Reset": "Reimposta",
"Please sign in": "Per favore collegati",
"Sign in": "Collegati",
"Update status": "Aggiornamento stato",
"Go Back": "Indietro",
"Order date": "Data ordine",
"Order ID": "ID Ordine",
"Payment Gateway ref": "Ref gateway pagamento",
"Payment Gateway": "Gateway Pagamento",
"Order total amount": "Totale ordine",
"First name": "Nome",
"Last name": "Cognome",
"Order comment": "Commento ordine",
"Products ordered": "Prodotti ordinati",
"Options": "Opzioni",
"Filter": "Filtra",
"By status": "Per stato",
"Orders can be filtered by: surname, email address or postcode/zipcode": "Gli ordini possono essere filtrati per: cognome, email o CAP",
"Completed": "Completo",
"Paid": "Pagato",
"Created": "Creato",
"Cancelled": "Cancellato",
"Declined": "Rifiutato",
"Shipped": "Consegnato",
"Pending": "In sospeso",
"Orders": "Ordini",
"Recent orders": "Ordini recenti",
"Status": "Stato",
"Upload image": "Carica immagine",
"Save product": "Salva prodotto",
"Edit product": "Modifica prodotto",
"Product title": "Titolo prodotto",
"Product price": "Prezzo prodotto",
"Published": "Pubblicato",
"Draft": "Bozza",
"Stock level": "Livello stock",
"Product description": "Descrizione prodotto",
"Validate": "Valida",
"This sets a readable URL for the product": "Configura un URL leggibile per il prodotto",
"Product options": "Opzioni prodotto",
"Label": "Etichetta",
"Type": "Tipo",
"Add": "Aggiungi",
"Remove": "Rimuovi",
"Here you can set options for your product. Eg: Size, color, style": "Qui puoi conifigurare le opzioni per il prodotto. Es: taglia, colore, stile",
"Allow comment": "Permetti commenti",
"Allow free form comments when adding products to cart": "Permetti commenti quando si aggiunge un prodotto al carrello",
"Product tag words": "Tag prodotto",
"Tag words used to indexed products, making them easier to find and filter.": "Parole usate per l'indice prodotti, rende più facile le ricerche ed il filtraggio",
"Product images": "Immagini prodotto",
"Delete": "Elimina",
"main image": "immagine principale",
"Set as main image": "Seleziona come immagine principale",
"No images have been uploaded for this product": "Non è stata caricata nessuna immagine per questo prodotto",
"Product image upload": "Upload immagine prodotto",
"Select file": "Seleziona file",
"Upload": "Carica",
"New product": "Nuovo prodotto",
"Products can be filtered by: product title or product description keywords": "I prodotti possono essere filtrati per: titolo o parole chiavi nella descrizione",
"Products": "Prodotti",
"Recent products": "Prodotti recenti",
"Confirm": "Conferma",
"Update": "Aggiorna",
"Setting_menu_explain": "Qui poi configurare un menu per visualizzarlo nel carrello. Puoi usare questo menu per filtrare prodotti tramite specifiche parole chiave nel campo \"link\". Es: Per visualizzare prodotti con parola chiave (o tag) di stivali, vorrai mettere nel campo menu a \"Backpacks\" ed un valore di link \"backpack\". YSi può usare questo menu anche per pagine statiche, Es: shipping, returns, help, about, contact etc.",
"Static page": "Pagine statiche",
"Page name": "Nome pagina",
"A friendly name to manage the static page.": "Un nome semplice per gestire la pagina statica",
"Page slug": "Slug pagina",
"Page_Slug_Description": "Questo è l'url relativo della pagina. Es: Configurando \"about\" la pagina sarà disponibile a: mydomain.com/about",
"Page Enabled": "Pagina abilitata",
"Page content": "Contenuto pagina",
"Here you can enter the content you wish to be displayed on your static page.": "Qui puoi inserire il contenuto che vuoi sia visualizzato nella tua pagina",
"New page": "Nuova pagina",
"Static pages": "Pagine statiche",
"Static_Pages_Info": "Qui puoi configurare e gestire le tue pagine statiche. Vuoi configurare una pagina con informazioni sul tuo business chiamata \"About\" o \"Contattaci\" ecc.",
"Edit": "Modifica",
"There are currently no static pages setup. Please setup a static page.": "Non ci sono attualmente pagine configurate. Configurane una.",
"Create new": "Create new",
"Search": "Cerca",
"Cart name": "Nome carrello",
"This element is critical for search engine optimisation. Cart title is displayed if your logo is hidden.": "Questo elemento è importante per l'ottimizzazione dei motori di ricerca. Il titolo è visualizzato se il tuo logo è nascosto",
"Cart description": "Descrizione carrello",
"This description shows when your website is listed in search engine results.": "Questa descrizione è visualizzata quando il tuo sito appare nei risultati dei motori di ricerca",
"Cart image/logo": "Immagine/logo carrello",
"Cart URL": "URL Carrello",
"This URL is used in sitemaps and when your customer returns from completing their payment.": "Questo URL è usato nelle sitemaps e quando il tuo cliente ritorna per completare il suo pagamento",
"This is used as the \"from\" email when sending receipts to your customers.": "Questo è usato come \"from\" nelle email inviate ai clienti",
"Cart Email": "Cart Email",
"Flat shipping rate": "Tariffa di spedizione fissa",
"A flat shipping rate applied to all orders.": "Una tariffa di spedizione fissa da applicare a tutti gli ordini",
"Free shipping threshold": "Soglia di spedizione gratuita",
"Orders over this value will mean the shipped will the FREE. Set to high value if you always want to charge shipping.": "Ordini oltre questo valore avranno la spedizione GRATUITA. Configura un alto valore se vuoi sempre addebitare la spedizione.",
"Payment gateway": "Gateway pagamento",
"Payment_Gateway_Info": "Dovrai configurare anche le tue credenziali per il gateway di pagamento nel file `/config/&lt;gateway_name&gt;.json`.",
"Currency symbol": "Simbolo valuta",
"Set this to your currency symbol. Eg: $, £, €": "Configura il simbolo della tua valuta. Es: $, £, €",
"Theme": "Tema",
"Theme_Info": "I temi sono caricati da `/public/themes/`",
"Products per row": "Prodotti per riga",
"The number of products to be displayed across the page.": "Il numero di prodotti visualizzati per riga nella pagina",
"Products per page": "Prodotti per pagina",
"The number of products to be displayed on each page.": "Il numero di prodotti visualizzati per ogni pagina",
"Menu Enabled": "Menu abilitato",
"Menu_Enabled_Info": "Se è abilitato, puoi configuralo <a href=\"/admin/settings/menu\">qui</a>.",
"Menu header": "Testa del menu",
"The heading text for your menu.": "Il testo di testa del tuo menu",
"Menu location": "Posizione del menu",
"The location of your menu.": "La posizione del tuo menu",
"Google_Analytics_Info": "Il tuo codice Google Analytics . Includi anche i tags \"script\" - <a href=\"https://support.google.com/analytics/answer/1032385?hl=en\" target=\"_blank\">Aiuto</a>",
"Custom CSS": "Stile personalizzato",
"Send test email": "Invia email di test",
"Users name": "Nome utenti",
"User email": "Email utente",
"Password confirm": "Conferma password",
"User password": "Password utente",
"Complete setup": "Completa il setup",
"User is admin?": "L'utente è un admin?",
"Generate": "Genera",
"New User": "Nuovo utente",
"Create": "Create",
"Role": "Ruolo",
"User": "Utente",
"No products found": "Nessun prodotto trovato",
"Category": "Categoria",
"Search results": "Risultati ricerca",
"Add to cart": "Aggiungi al carrello",
"Pay now": "Paga ora",
"Customer details": "Dettagli cliente",
"Existing customer": "Cliente esistente",
"Forgotten": "Dimenticato",
"Change customer": "Cambia cliente",
"Enter a password to create an account for next time": "Inserisci una password per creare un account per la prossima volta",
"Create account": "Crea account",
"Your payment has been successfully processed": "Il tuo pagamento è stato processato correttamente",
"Your payment has failed. Please try again or contact us.": "Il tuo pagamento è fallito. Prova ancora, o contattaci",
"Please retain the details above as a reference of payment.": "Conserva i dettagli sopra come riferimento del pagamento",
"Quantity": "Quantità",
"Leave a comment?": "Lascia un commento?",
"Cart contents": "Contenuto del carrello",
"Shipping": "Spedizione:",
"Empty cart": "Svuota carrello"
}

79
package-lock.json generated
View File

@ -5236,6 +5236,26 @@
"toidentifier": "1.0.0"
}
},
"i18n": {
"version": "0.8.4",
"resolved": "https://registry.npmjs.org/i18n/-/i18n-0.8.4.tgz",
"integrity": "sha512-PvMcG+yqYWXrwgdmCpL+APCGa8lRY0tdlo2cXp9UeR3u4h1bJGqFsgybfmG/MqtL1iDmdaPPPLJebXGrZ1XoMQ==",
"requires": {
"debug": "*",
"make-plural": "^6.0.1",
"math-interval-parser": "^2.0.1",
"messageformat": "^2.3.0",
"mustache": "*",
"sprintf-js": "^1.1.2"
},
"dependencies": {
"sprintf-js": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
"integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug=="
}
}
},
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@ -6141,6 +6161,11 @@
}
}
},
"make-plural": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/make-plural/-/make-plural-6.0.1.tgz",
"integrity": "sha512-h0uBNi4tpDkiWUyYKrJNj8Kif6q3Ba5zp/8jnfPy3pQE+4XcTj6h3eZM5SYVUyDNX9Zk69Isr/dx0I+78aJUaQ=="
},
"map-cache": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
@ -6214,6 +6239,11 @@
}
}
},
"math-interval-parser": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/math-interval-parser/-/math-interval-parser-2.0.1.tgz",
"integrity": "sha512-VmlAmb0UJwlvMyx8iPhXUDnVW1F9IrGEd9CIOmv+XL8AErCUUuozoDMrgImvnYt2A+53qVX/tPW6YJurMKYsvA=="
},
"md5-hex": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-3.0.1.tgz",
@ -6295,6 +6325,42 @@
"integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==",
"dev": true
},
"messageformat": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/messageformat/-/messageformat-2.3.0.tgz",
"integrity": "sha512-uTzvsv0lTeQxYI2y1NPa1lItL5VRI8Gb93Y2K2ue5gBPyrbJxfDi/EYWxh2PKv5yO42AJeeqblS9MJSh/IEk4w==",
"requires": {
"make-plural": "^4.3.0",
"messageformat-formatters": "^2.0.1",
"messageformat-parser": "^4.1.2"
},
"dependencies": {
"make-plural": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/make-plural/-/make-plural-4.3.0.tgz",
"integrity": "sha512-xTYd4JVHpSCW+aqDof6w/MebaMVNTVYBZhbB/vi513xXdiPT92JMVCo0Jq8W2UZnzYRFeVbQiQ+I25l13JuKvA==",
"requires": {
"minimist": "^1.2.0"
}
},
"minimist": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"optional": true
}
}
},
"messageformat-formatters": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/messageformat-formatters/-/messageformat-formatters-2.0.1.tgz",
"integrity": "sha512-E/lQRXhtHwGuiQjI7qxkLp8AHbMD5r2217XNe/SREbBlSawe0lOqsFb7rflZJmlQFSULNLIqlcjjsCPlB3m3Mg=="
},
"messageformat-parser": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/messageformat-parser/-/messageformat-parser-4.1.2.tgz",
"integrity": "sha512-7dWuifeyldz7vhEuL96Kwq1fhZXBW+TUfbnHN4UCrCxoXQTYjHnR78eI66Gk9LaLLsAvzPNVJBaa66DRfFNaiA=="
},
"methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
@ -6453,6 +6519,14 @@
"resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
"integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg=="
},
"moment-recur": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/moment-recur/-/moment-recur-1.0.7.tgz",
"integrity": "sha1-TVCSr2SK7e1q/lwT7zjFKQHJlBk=",
"requires": {
"moment": "<3.0.0"
}
},
"mongodb": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.3.3.tgz",
@ -6543,6 +6617,11 @@
"xtend": "^4.0.0"
}
},
"mustache": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/mustache/-/mustache-3.1.0.tgz",
"integrity": "sha512-3Bxq1R5LBZp7fbFPZzFe5WN4s0q3+gxZaZuZVY+QctYJiCiVgXHOTIC0/HgZuOPFt/6BQcx5u0H2CUOxT/RoGQ=="
},
"mute-stdout": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz",

View File

@ -8,6 +8,7 @@
"deploy": "gulp deploy",
"testdata": "node lib/testdata.js",
"test": "NODE_ENV=test ava --verbose",
"dev": "nodemon app.js",
"lint": "eslint ./"
},
"engines": {
@ -29,6 +30,7 @@
"glob": "^7.1.5",
"helmet": "^3.21.2",
"html-entities": "^1.2.0",
"i18n": "^0.8.4",
"jsonschema": "^1.2.4",
"lodash": "^4.17.15",
"lunr": "^2.3.8",

View File

@ -84,7 +84,7 @@ router.get('/admin/setup', async (req, res) => {
// dont allow the user to "re-setup" if a user exists.
// set needsSetup to false as a user exists
req.session.needsSetup = false;
if(userCount && userCount === 0){
if(userCount === 0){
req.session.needsSetup = true;
res.render('setup', {
title: 'Setup',
@ -112,7 +112,7 @@ router.post('/admin/setup_action', async (req, res) => {
// check for users
const userCount = await db.users.countDocuments({});
if(userCount && userCount === 0){
if(userCount === 0){
// email is ok to be used.
try{
await db.users.insertOne(doc);

View File

@ -15,7 +15,7 @@ const {
updateTotalCartAmount,
getData,
addSitemapProducts
} = require('../lib/common');
} = require('../lib/common');
// These is the customer facing routes
router.get('/payment/:orderId', async (req, res, next) => {
@ -421,36 +421,36 @@ router.get('/search/:searchTerm/:pageNum?', (req, res) => {
getData(req, pageNum, { _id: { $in: lunrIdArray } }),
getMenu(db)
])
.then(([results, menu]) => {
// If JSON query param return json instead
if(req.query.json === 'true'){
res.status(200).json(results.data);
return;
}
.then(([results, menu]) => {
// If JSON query param return json instead
if(req.query.json === 'true'){
res.status(200).json(results.data);
return;
}
res.render(`${config.themeViews}index`, {
title: 'Results',
results: results.data,
filtered: true,
session: req.session,
metaDescription: req.app.config.cartTitle + ' - Search term: ' + searchTerm,
searchTerm: searchTerm,
pageCloseBtn: showCartCloseBtn('search'),
message: clearSessionValue(req.session, 'message'),
messageType: clearSessionValue(req.session, 'messageType'),
productsPerPage: numberProducts,
totalProductCount: results.totalProducts,
pageNum: pageNum,
paginateUrl: 'search',
config: config,
menu: sortMenu(menu),
helpers: req.handlebars.helpers,
showFooter: 'showFooter'
res.render(`${config.themeViews}index`, {
title: 'Results',
results: results.data,
filtered: true,
session: req.session,
metaDescription: req.app.config.cartTitle + ' - Search term: ' + searchTerm,
searchTerm: searchTerm,
pageCloseBtn: showCartCloseBtn('search'),
message: clearSessionValue(req.session, 'message'),
messageType: clearSessionValue(req.session, 'messageType'),
productsPerPage: numberProducts,
totalProductCount: results.totalProducts,
pageNum: pageNum,
paginateUrl: 'search',
config: config,
menu: sortMenu(menu),
helpers: req.handlebars.helpers,
showFooter: 'showFooter'
});
})
.catch((err) => {
console.error(colors.red('Error searching for products', err));
});
})
.catch((err) => {
console.error(colors.red('Error searching for products', err));
});
});
// search products
@ -475,39 +475,45 @@ router.get('/category/:cat/:pageNum?', (req, res) => {
getData(req, pageNum, { _id: { $in: lunrIdArray } }),
getMenu(db)
])
.then(([results, menu]) => {
const sortedMenu = sortMenu(menu);
.then(([results, menu]) => {
const sortedMenu = sortMenu(menu);
// If JSON query param return json instead
if(req.query.json === 'true'){
res.status(200).json(results.data);
return;
}
// If JSON query param return json instead
if(req.query.json === 'true'){
res.status(200).json(results.data);
return;
}
res.render(`${config.themeViews}index`, {
title: 'Category',
results: results.data,
filtered: true,
session: req.session,
searchTerm: searchTerm,
metaDescription: req.app.config.cartTitle + ' - Category: ' + searchTerm,
pageCloseBtn: showCartCloseBtn('category'),
message: clearSessionValue(req.session, 'message'),
messageType: clearSessionValue(req.session, 'messageType'),
productsPerPage: numberProducts,
totalProductCount: results.totalProducts,
pageNum: pageNum,
menuLink: _.find(sortedMenu.items, (obj) => { return obj.link === searchTerm; }),
paginateUrl: 'category',
config: config,
menu: sortedMenu,
helpers: req.handlebars.helpers,
showFooter: 'showFooter'
res.render(`${config.themeViews}index`, {
title: 'Category',
results: results.data,
filtered: true,
session: req.session,
searchTerm: searchTerm,
metaDescription: req.app.config.cartTitle + ' - Category: ' + searchTerm,
pageCloseBtn: showCartCloseBtn('category'),
message: clearSessionValue(req.session, 'message'),
messageType: clearSessionValue(req.session, 'messageType'),
productsPerPage: numberProducts,
totalProductCount: results.totalProducts,
pageNum: pageNum,
menuLink: _.find(sortedMenu.items, (obj) => { return obj.link === searchTerm; }),
paginateUrl: 'category',
config: config,
menu: sortedMenu,
helpers: req.handlebars.helpers,
showFooter: 'showFooter'
});
})
.catch((err) => {
console.error(colors.red('Error getting products for category', err));
});
})
.catch((err) => {
console.error(colors.red('Error getting products for category', err));
});
});
// Language setup in cookie
router.get('/lang/:locale', (req, res) => {
res.cookie('locale', req.params.locale, { maxAge: 900000, httpOnly: true });
res.redirect('back');
});
// return sitemap
@ -552,34 +558,34 @@ router.get('/page/:pageNum', (req, res, next) => {
getData(req, req.params.pageNum),
getMenu(db)
])
.then(([results, menu]) => {
// If JSON query param return json instead
if(req.query.json === 'true'){
res.status(200).json(results.data);
return;
}
.then(([results, menu]) => {
// If JSON query param return json instead
if(req.query.json === 'true'){
res.status(200).json(results.data);
return;
}
res.render(`${config.themeViews}index`, {
title: 'Shop',
results: results.data,
session: req.session,
message: clearSessionValue(req.session, 'message'),
messageType: clearSessionValue(req.session, 'messageType'),
metaDescription: req.app.config.cartTitle + ' - Products page: ' + req.params.pageNum,
pageCloseBtn: showCartCloseBtn('page'),
config: req.app.config,
productsPerPage: numberProducts,
totalProductCount: results.totalProducts,
pageNum: req.params.pageNum,
paginateUrl: 'page',
helpers: req.handlebars.helpers,
showFooter: 'showFooter',
menu: sortMenu(menu)
res.render(`${config.themeViews}index`, {
title: 'Shop',
results: results.data,
session: req.session,
message: clearSessionValue(req.session, 'message'),
messageType: clearSessionValue(req.session, 'messageType'),
metaDescription: req.app.config.cartTitle + ' - Products page: ' + req.params.pageNum,
pageCloseBtn: showCartCloseBtn('page'),
config: req.app.config,
productsPerPage: numberProducts,
totalProductCount: results.totalProducts,
pageNum: req.params.pageNum,
paginateUrl: 'page',
helpers: req.handlebars.helpers,
showFooter: 'showFooter',
menu: sortMenu(menu)
});
})
.catch((err) => {
console.error(colors.red('Error getting products for page', err));
});
})
.catch((err) => {
console.error(colors.red('Error getting products for page', err));
});
});
// The main entry point of the shop
@ -594,34 +600,34 @@ router.get('/:page?', async (req, res, next) => {
getData(req, 1, {}),
getMenu(db)
])
.then(([results, menu]) => {
// If JSON query param return json instead
if(req.query.json === 'true'){
res.status(200).json(results.data);
return;
}
.then(([results, menu]) => {
// If JSON query param return json instead
if(req.query.json === 'true'){
res.status(200).json(results.data);
return;
}
res.render(`${config.themeViews}index`, {
title: `${config.cartTitle} - Shop`,
theme: config.theme,
results: results.data,
session: req.session,
message: clearSessionValue(req.session, 'message'),
messageType: clearSessionValue(req.session, 'messageType'),
pageCloseBtn: showCartCloseBtn('page'),
config: req.app.config,
productsPerPage: numberProducts,
totalProductCount: results.totalProducts,
pageNum: 1,
paginateUrl: 'page',
helpers: req.handlebars.helpers,
showFooter: 'showFooter',
menu: sortMenu(menu)
res.render(`${config.themeViews}index`, {
title: `${config.cartTitle} - Shop`,
theme: config.theme,
results: results.data,
session: req.session,
message: clearSessionValue(req.session, 'message'),
messageType: clearSessionValue(req.session, 'messageType'),
pageCloseBtn: showCartCloseBtn('page'),
config: req.app.config,
productsPerPage: numberProducts,
totalProductCount: results.totalProducts,
pageNum: 1,
paginateUrl: 'page',
helpers: req.handlebars.helpers,
showFooter: 'showFooter',
menu: sortMenu(menu)
});
})
.catch((err) => {
console.error(colors.red('Error getting products for page', err));
});
})
.catch((err) => {
console.error(colors.red('Error getting products for page', err));
});
}else{
if(req.params.page === 'admin'){
next();

View File

@ -11,35 +11,35 @@
<td>{{result.email}}</td>
</tr>
<tr>
<td><span class="text-info">Name:</span></td>
<td><span class="text-info">{{ @root.__ "Name" }}:</span></td>
<td>{{result.firstName}} {{result.lastName}}</td>
</tr>
<tr>
<td><span class="text-info">Address 1:</span></td>
<td><span class="text-info">{{ @root.__ "Address 1" }}:</span></td>
<td>{{result.address1}}</td>
</tr>
<tr>
<td><span class="text-info">Address 2:</span></td>
<td><span class="text-info">{{ @root.__ "Address 2" }}:</span></td>
<td>{{result.address2}}</td>
</tr>
<tr>
<td><span class="text-info">Country:</span></td>
<td><span class="text-info">{{ @root.__ "Country" }}:</span></td>
<td>{{result.country}}</td>
</tr>
<tr>
<td><span class="text-info">State:</span></td>
<td><span class="text-info">{{ @root.__ "State" }}:</span></td>
<td>{{result.state}}</td>
</tr>
<tr>
<td><span class="text-info">Postcode:</span></td>
<td><span class="text-info">{{ @root.__ "Postcode" }}:</span></td>
<td>{{result.postcode}}</td>
</tr>
<tr>
<td><span class="text-info">Phone number:</span></td>
<td><span class="text-info">{{ @root.__ "Phone number" }}:</span></td>
<td>{{result.phone}}</td>
</tr>
<tr>
<td><span class="text-info">Creation date:</span></td>
<td><span class="text-info">{{ @root.__ "Creation date" }}:</span></td>
<td>{{formatDate result.created "DD/MM/YYYY hh:mmA"}}</td>
</tr>
</table>

View File

@ -11,29 +11,29 @@
<a href="/admin/customers" class="hidden-xs btn btn-warning btn-lg"><i class="fa fa-times" aria-hidden="true"></i></a>
</span>
</div>
<p class="text-warning top-pad-10">Customers can be filtered by: email, name or phone numnber</p>
<p class="text-warning top-pad-10">{{ @root.__ "Customers can be filtered by: email, name or phone number" }}</p>
</div>
{{#if customers}}
<div class="col-lg-12">
<ul class="list-group">
<li class="list-group-item">
<strong>
Customers
{{ @root.__ "Customers" }}
{{#if searchTerm}}
- <span class="text-danger">Filtered term: {{searchTerm}} </span>
- <span class="text-danger">{{ @root.__ "Filtered term" }}: {{searchTerm}} </span>
{{/if}}
</strong>
</li>
<li class="list-group-item">
<div class="row">
<div class="col-md-4">
<h5 class="text-info"><strong>Email address</strong></h5>
<h5 class="text-info"><strong>{{ @root.__ "Email address" }}</strong></h5>
</div>
<div class="col-md-4">
<h5 class="text-info"><strong>Name</strong></h5>
<h5 class="text-info"><strong>{{ @root.__ "Name" }}</strong></h5>
</div>
<div class="col-md-4">
<h5 class="text-info"><strong>Phone number</strong></h5>
<h5 class="text-info"><strong>{{ @root.__ "Phone number" }}</strong></h5>
</div>
</div>
</li>
@ -58,7 +58,7 @@
</div>
{{else}}
<h4 class="text-center">
No orders found
{{ @root.__ "No orders found" }}
</h4>
{{/if}}
</div>
</div>

View File

@ -1,9 +1,9 @@
<div class="col-md-offset-4 col-md-4 col-lg-offset-4 col-lg-4" style="padding-top: 100px" >
<form class="form-signin" action="/{{route}}/forgotten_action" method="post" role="form" data-toggle="validator">
<h2 class="form-signin-heading">Please enter your email address</h2>
<h2 class="form-signin-heading">{{ @root.__ "Please enter your email address" }}</h2>
<div class="form-group">
<input type="email" name="email" class="form-control" placeholder="email address" required autofocus>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit">Reset</button>
<button class="btn btn-lg btn-primary btn-block" type="submit">{{ @root.__ "Reset" }}</button>
</form>
</div>

View File

@ -103,13 +103,21 @@
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{{ @root.__ "Languages" }} <span class="caret"></span></a>
<ul class="dropdown-menu">
{{#availableLanguages}}
<li><a href="/lang/{{this}}">{{@root.__ this}}</a></li>
{{/availableLanguages}}
</ul>
</li>
{{#unless admin}}
{{#ifCond page '!=' 'checkout'}}
{{#ifCond page '!=' 'pay'}}
{{#if @root.session.cart}}
<li><a href="/cart" class="menu-btn"><i class="fa fa-shopping-cart" aria-hidden="true"></i> Cart <span class="badge" id="cart-count">{{@root.session.cartTotalItems}}</span></a></li>
<li><a href="/cart" class="menu-btn"><i class="fa fa-shopping-cart" aria-hidden="true"></i> {{ @root.__ "Cart" }} <span class="badge" id="cart-count">{{@root.session.cartTotalItems}}</span></a></li>
{{else}}
<li><a href="/cart" class="menu-btn"><i class="fa fa-shopping-cart" aria-hidden="true"></i> Cart <span class="badge" id="cart-count">0</span></a></li>
<li><a href="/cart" class="menu-btn"><i class="fa fa-shopping-cart" aria-hidden="true"></i> {{ @root.__ "Cart" }} <span class="badge" id="cart-count">0</span></a></li>
{{/if}}
{{/ifCond}}
{{/ifCond}}
@ -160,4 +168,4 @@
{{/if}}
<script src="/javascripts/pushy.min.js"></script>
</body>
</html>
</html>

View File

@ -1,13 +1,13 @@
<div class="col-md-offset-4 col-md-4 col-lg-offset-4 col-lg-4" style="padding-top: 100px" >
<form class="form-signin" method="post" role="form" data-toggle="validator">
<input type="hidden" name="frm_referringUrl" value="{{referringUrl}}">
<h2 class="form-signin-heading">Please sign in</h2>
<h2 class="form-signin-heading">{{ @root.__ "Please sign in" }}</h2>
<div class="form-group">
<input type="email" id="email" name="email" class="form-control" placeholder="email address" required autofocus>
</div>
<div class="form-group">
<input type="password" id="password" name="password" class="form-control" placeholder="Password" required>
</div>
<button class="btn btn-lg btn-primary btn-block" id="loginForm" type="submit">Sign in</button>
<button class="btn btn-lg btn-primary btn-block" id="loginForm" type="submit">{{ @root.__ "Sign in" }}</button>
</form>
</div>

View File

@ -6,8 +6,8 @@
<div class="order-layout col-md-12">
<div class="row">
<div class="col-md-12 bottom-pad-20">
<a id="orderStatusUpdate" class="btn btn-sm btn-success pull-left">Update status</a>
<a href="/admin/orders" class="btn btn-sm btn-info pull-right">Go Back</a>
<a id="orderStatusUpdate" class="btn btn-sm btn-success pull-left">{{ @root.__ "Update status" }}</a>
<a href="/admin/orders" class="btn btn-sm btn-info pull-right">{{ @root.__ "Go Back" }}</a>
</div>
</div>
<ul class="list-group">
@ -15,39 +15,38 @@
<strong> Order status: </strong><span class="text-{{getStatusColor result.orderStatus}} pull-right">{{result.orderStatus}}</span>
<div class="pull-right col-md-2">
<select class="form-control input-sm" id="orderStatus">
<option>Completed</option>
<option>Pending</option>
<option>Cancelled</option>
<option>Declined</option>
<option>Shipped</option>
<option>Pending</option>
<option>{{ @root.__ "Completed" }}</option>
<option>{{ @root.__ "Pending" }}</option>
<option>{{ @root.__ "Cancelled" }}</option>
<option>{{ @root.__ "Declined" }}</option>
<option>{{ @root.__ "Shipped" }}</option>
</select>
</div>
</li>
<li class="list-group-item"><strong> Order date: </strong><span class="pull-right">{{formatDate result.orderDate "DD/MM/YYYY hh:mmA"}}</span></li>
<li class="list-group-item"><strong> Order ID: </strong><span class="pull-right">{{result._id}}</span></li>
<li class="list-group-item"><strong> Payment Gateway ref: </strong><span class="pull-right">{{result.orderPaymentId}}</span></li>
<li class="list-group-item"><strong> Payment Gateway: </strong><span class="pull-right">{{result.orderPaymentGateway}}</span></li>
<li class="list-group-item"><strong> Order total amount: </strong><span class="pull-right">{{currencySymbol config.currencySymbol}}{{formatAmount result.orderTotal}}</span></li>
<li class="list-group-item"><strong> Email address: </strong><span class="pull-right">{{result.orderEmail}}</span></li>
<li class="list-group-item"><strong> First name: </strong><span class="pull-right">{{result.orderFirstname}}</span></li>
<li class="list-group-item"><strong> Last name: </strong><span class="pull-right">{{result.orderLastname}}</span></li>
<li class="list-group-item"><strong> Address 1: </strong><span class="pull-right">{{result.orderAddr1}}</span></li>
<li class="list-group-item"><strong> Address 2: </strong><span class="pull-right">{{result.orderAddr2}}</span></li>
<li class="list-group-item"><strong> Country: </strong><span class="pull-right">{{result.orderCountry}}</span></li>
<li class="list-group-item"><strong> State: </strong><span class="pull-right">{{result.orderState}}</span></li>
<li class="list-group-item"><strong> Postcode/Zipcode: </strong><span class="pull-right">{{result.orderPostcode}}</span></li>
<li class="list-group-item"><strong> Phone number: </strong><span class="pull-right">{{result.orderPhoneNumber}}</span></li>
<li class="list-group-item"><strong> Order comment: </strong><span class="pull-right">{{result.orderComment}}</span></li>
<li class="list-group-item"><strong> {{ @root.__ "Order date" }}: </strong><span class="pull-right">{{formatDate result.orderDate "DD/MM/YYYY hh:mmA"}}</span></li>
<li class="list-group-item"><strong> {{ @root.__ "Order ID" }}: </strong><span class="pull-right">{{result._id}}</span></li>
<li class="list-group-item"><strong> {{ @root.__ "Payment Gateway ref" }}: </strong><span class="pull-right">{{result.orderPaymentId}}</span></li>
<li class="list-group-item"><strong> {{ @root.__ "Payment Gateway" }}: </strong><span class="pull-right">{{result.orderPaymentGateway}}</span></li>
<li class="list-group-item"><strong> {{ @root.__ "Order total amount" }}: </strong><span class="pull-right">{{currencySymbol config.currencySymbol}}{{formatAmount result.orderTotal}}</span></li>
<li class="list-group-item"><strong> {{ @root.__ "Email address" }}: </strong><span class="pull-right">{{result.orderEmail}}</span></li>
<li class="list-group-item"><strong> {{ @root.__ "First name" }}: </strong><span class="pull-right">{{result.orderFirstname}}</span></li>
<li class="list-group-item"><strong> {{ @root.__ "Last name" }}: </strong><span class="pull-right">{{result.orderLastname}}</span></li>
<li class="list-group-item"><strong> {{ @root.__ "Address 1" }}: </strong><span class="pull-right">{{result.orderAddr1}}</span></li>
<li class="list-group-item"><strong> {{ @root.__ "Address 2" }}: </strong><span class="pull-right">{{result.orderAddr2}}</span></li>
<li class="list-group-item"><strong> {{ @root.__ "Country" }}: </strong><span class="pull-right">{{result.orderCountry}}</span></li>
<li class="list-group-item"><strong> {{ @root.__ "State" }}: </strong><span class="pull-right">{{result.orderState}}</span></li>
<li class="list-group-item"><strong> {{ @root.__ "Postcode" }}: </strong><span class="pull-right">{{result.orderPostcode}}</span></li>
<li class="list-group-item"><strong> {{ @root.__ "Phone number" }}: </strong><span class="pull-right">{{result.orderPhoneNumber}}</span></li>
<li class="list-group-item"><strong> {{ @root.__ "Order comment" }}: </strong><span class="pull-right">{{result.orderComment}}</span></li>
<li class="list-group-item">&nbsp;</li>
<li class="list-group-item"><strong class="text-info">Products ordered</strong></li>
<li class="list-group-item"><strong class="text-info">{{ @root.__ "Products ordered" }}</strong></li>
{{#each result.orderProducts}}
<li class="list-group-item">
{{this.quantity}} x {{this.title}}
{{#if this.options}}
&nbsp; > &nbsp;
<span class="text-warning"> Options: </span>
<span class="text-warning"> {{ @root.__ "Options" }}: </span>
(
{{#each this.options}}
{{#if @last}}

View File

@ -7,25 +7,25 @@
<div class="input-group">
<input type="text" name="order_filter" id="order_filter" class="form-control input-lg" placeholder="Filter orders">
<span class="input-group-btn">
<button class="btn btn-success btn-lg" id="btn_order_filter">Filter</button>
<a href="/admin/orders/bystatus/" class="hidden-xs btn btn-info btn-lg orderFilterByStatus">By status</a>
<button class="btn btn-success btn-lg" id="btn_order_filter">{{ @root.__ "Filter" }}</button>
<a href="/admin/orders/bystatus/" class="hidden-xs btn btn-info btn-lg orderFilterByStatus">{{ @root.__ "By status" }}</a>
<a href="/admin/orders" class="hidden-xs btn btn-warning btn-lg"><i class="fa fa-times" aria-hidden="true"></i></a>
</span>
</div>
<div class="orderFilter">
<div class="text-warning top-pad-10 col-md-8">Orders can be filtered by: surname, email address or postcode/zipcode</div>
<div class="text-warning top-pad-10 col-md-8">{{ @root.__ "Orders can be filtered by: surname, email address or postcode/zipcode" }}</div>
<div class="col-md-4 no-pad-right">
<div class="form-group">
<label for="orderStatusFilter" class="col-sm-2 control-label formLabel">Status</label>
<div class="col-sm-10 no-pad-right">
<select class="form-control input-sm" id="orderStatusFilter">
<option>Completed</option>
<option>Paid</option>
<option>Created</option>
<option>Cancelled</option>
<option>Declined</option>
<option>Shipped</option>
<option>Pending</option>
<option>{{ @root.__ "Completed" }}</option>
<option>{{ @root.__ "Paid" }}</option>
<option>{{ @root.__ "Created" }}</option>
<option>{{ @root.__ "Cancelled" }}</option>
<option>{{ @root.__ "Declined" }}</option>
<option>{{ @root.__ "Shipped" }}</option>
<option>{{ @root.__ "Pending" }}</option>
</select>
</div>
</div>
@ -37,27 +37,27 @@
<ul class="list-group">
<li class="list-group-item">
{{#if searchTerm}}
<strong>Orders - <span class="text-danger">Filtered term: {{searchTerm}} </span></strong>
<strong>{{ @root.__ "Orders" }} - <span class="text-danger">{{ @root.__ "Filtered term" }}: {{searchTerm}} </span></strong>
{{else}}
<strong>Recent orders</strong>
<strong>{{ @root.__ "Recent orders" }}</strong>
{{/if}}
</li>
{{#if orders}}
{{#each orders}}
<li class="list-group-item">
<h4 class="pull-right" style="padding-left: 10px;">
Status: <span class="text-{{getStatusColor this.orderStatus}}">{{this.orderStatus}}</span>
{{ @root.__ "Status" }}: <span class="text-{{getStatusColor this.orderStatus}}">{{this.orderStatus}}</span>
<a class="text-danger" href="/admin/order/delete/{{this._id}}" onclick="return confirm('Are you sure you want to delete this order?');"> <i class="fa fa-trash-o"></i></a>
</h4>
<h5>
<a href="/admin/order/view/{{this._id}}" class="text-success">View order</a> - <span class="text-info">Date: </span>{{formatDate this.orderDate "DD/MM/YYYY hh:mm"}} | <span class="text-info">Email:</span> {{this.orderEmail}} | <span class="text-info">Last name:</span> {{this.orderLastname}}
<a href="/admin/order/view/{{this._id}}" class="text-success">View order</a> - <span class="text-info">Date: </span>{{formatDate this.orderDate "DD/MM/YYYY hh:mm"}} | <span class="text-info">Email:</span> {{this.orderEmail}} | <span class="text-info">{{ @root.__ "Last name" }}:</span> {{this.orderLastname}}
</h5>
</li>
{{/each}}
{{else}}
<li class="list-group-item">
<h4 class="text-center">
No orders found
{{ @root.__ "No orders found" }}
</h4>
</li>
{{/if}}

View File

@ -3,22 +3,22 @@
<ul class="list-group">
<li class="list-group-item"><strong>Products</strong></li>
{{#ifCond session.isAdmin '===' true}}
<li class="list-group-item"><i class="fa fa-plus-square-o fa-icon" aria-hidden="true"></i> &nbsp; <a href="/admin/product/new">New</a></li>
<li class="list-group-item"><i class="fa fa-plus-square-o fa-icon" aria-hidden="true"></i> &nbsp; <a href="/admin/product/new">{{ @root.__ "New" }}</a></li>
{{/ifCond}}
<li class="list-group-item"><i class="fa fa-list fa-icon" aria-hidden="true"></i> &nbsp; <a href="/admin/products">List</a></li>
<li class="list-group-item"><i class="fa fa-list fa-icon" aria-hidden="true"></i> &nbsp; <a href="/admin/products">{{ @root.__ "List" }}</a></li>
<li class="list-group-item"><strong>Orders</strong></li>
<li class="list-group-item"><i class="fa fa-cube fa-icon" aria-hidden="true"></i> &nbsp; <a href="/admin/orders">List</a></li>
<li class="list-group-item"><i class="fa fa-cube fa-icon" aria-hidden="true"></i> &nbsp; <a href="/admin/orders">{{ @root.__ "List" }}</a></li>
<li class="list-group-item"><strong>Customers</strong></li>
<li class="list-group-item"><i class="fa fa-users fa-icon" aria-hidden="true"></i> &nbsp; <a href="/admin/customers">List</a></li>
<li class="list-group-item"><i class="fa fa-users fa-icon" aria-hidden="true"></i> &nbsp; <a href="/admin/customers">{{ @root.__ "List" }}</a></li>
<li class="list-group-item"><strong>Users</strong></li>
{{#ifCond session.isAdmin '===' true}}
<li class="list-group-item"><i class="fa fa-user-plus fa-icon" aria-hidden="true"></i> &nbsp; <a href="/admin/user/new">New</a></li>
<li class="list-group-item"><i class="fa fa-user fa-icon" aria-hidden="true"></i> &nbsp; <a href="/admin/users">Edit</a></li>
<li class="list-group-item"><i class="fa fa-user-plus fa-icon" aria-hidden="true"></i> &nbsp; <a href="/admin/user/new">{{ @root.__ "New" }}</a></li>
<li class="list-group-item"><i class="fa fa-user fa-icon" aria-hidden="true"></i> &nbsp; <a href="/admin/users">{{ @root.__ "Edit" }}</a></li>
{{/ifCond}}
<li class="list-group-item"><i class="fa fa-user-circle-o fa-icon" aria-hidden="true"></i> &nbsp; <a href="/admin/user/edit/{{session.userId}}">My Account</a></li>
<li class="list-group-item"><strong>Settings</strong></li>
<li class="list-group-item"><i class="fa fa-cog fa-icon" aria-hidden="true"></i> &nbsp; <a href="/admin/settings">General settings</a></li>
<li class="list-group-item"><strong>{{ @root.__ "Settings" }}</strong></li>
<li class="list-group-item"><i class="fa fa-cog fa-icon" aria-hidden="true"></i> &nbsp; <a href="/admin/settings">{{ @root.__ "General settings" }}</a></li>
<li class="list-group-item"><i class="fa fa-bars fa-icon" aria-hidden="true"></i> &nbsp; <a href="/admin/settings/menu">Menu</a></li>
<li class="list-group-item"><i class="fa fa-file-o fa-icon" aria-hidden="true"></i> &nbsp; <a href="/admin/settings/pages">Static pages</a></li>
<li class="list-group-item"><i class="fa fa-file-o fa-icon" aria-hidden="true"></i> &nbsp; <a href="/admin/settings/pages">{{ @root.__ "Static pages" }}</a></li>
</ul>
</div>

View File

@ -4,19 +4,19 @@
<div class="col-lg-12">
<div class="page-header">
<div class="pull-right">
<button type="button" class="btn btn-info" data-toggle="modal" data-target="#myModal">Upload image</button>
<button id="frm_edit_product_save" class="btn btn-success">Save product <i class="fa fa-floppy-o"></i></button>
<button type="button" class="btn btn-info" data-toggle="modal" data-target="#myModal">{{ @root.__ "Upload image" }}</button>
<button id="frm_edit_product_save" class="btn btn-success">{{ @root.__ "Save product" }} <i class="fa fa-floppy-o"></i></button>
</div>
<h2>Edit product</h2>
<h2>{{ @root.__ "Edit product" }}</h2>
</div>
<div class="form-group">
<label for="productTitle" class="col-sm-2 control-label">Product title *</label>
<label for="productTitle" class="col-sm-2 control-label">{{ @root.__ "Product title" }} *</label>
<div class="col-sm-10">
<input type="text" name="productTitle" class="form-control" minlength="5" maxlength="200" value="{{result.productTitle}}" required/>
</div>
</div>
<div class="form-group">
<label for="productPrice" class="col-sm-2 control-label">Product price *</label>
<label for="productPrice" class="col-sm-2 control-label">{{ @root.__ "Product price" }} *</label>
<div class="col-sm-6">
<div class="input-group">
<span class="input-group-addon">{{currencySymbol config.currencySymbol}}</span>
@ -25,24 +25,24 @@
</div>
</div>
<div class="form-group">
<label for="productPublished" class="col-sm-2 control-label">Status</label>
<label for="productPublished" class="col-sm-2 control-label">{{ @root.__ "Status" }}</label>
<div class="col-sm-6">
<select class="form-control" id="productPublished" name="productPublished">
<option value="true" {{selectState result.productPublished "true"}}>Published</option>
<option value="false" {{selectState result.productPublished "false"}}>Draft</option>
<option value="true" {{selectState result.productPublished "true"}}>{{ @root.__ "Published" }}</option>
<option value="false" {{selectState result.productPublished "false"}}>{{ @root.__ "Draft" }}</option>
</select>
</div>
</div>
{{#if config.trackStock}}
<div class="form-group">
<label for="productStock" class="col-sm-2 control-label">Stock level</label>
<label for="productStock" class="col-sm-2 control-label">{{ @root.__ "Stock level" }}</label>
<div class="col-sm-6">
<input type="number" name="productStock" class="form-control" value="{{result.productStock}}" step="any" />
</div>
</div>
{{/if}}
<div class="form-group">
<label for="editor" class="col-sm-2 control-label">Product description *</label>
<label for="editor" class="col-sm-2 control-label">{{ @root.__ "Product description" }} *</label>
<div class="col-sm-10">
<textarea id="editor" minlength="5" rows="10" id="productDescription" name="productDescription" class="form-control" required>{{result.productDescription}}</textarea>
</div>
@ -53,29 +53,29 @@
<div class="input-group">
<input type="text" class="form-control" name="productPermalink" id="productPermalink" placeholder="Permalink for the article" value={{result.productPermalink}}>
<span class="input-group-btn">
<button class="btn btn-success" id="validate_permalink" type="button">Validate</button>
<button class="btn btn-success" id="validate_permalink" type="button">{{ @root.__ "Validate" }}</button>
</span>
</div>
<p class="help-block">This sets a readable URL for the product</p>
<p class="help-block">{{ @root.__ "This sets a readable URL for the product" }}</p>
</div>
</div>
<div class="form-group">
<input type="hidden" id="productOptions" name="productOptions" value="{{stringify result.productOptions}}" />
<label for="editor" class="col-sm-2 control-label">Product options</label>
<label for="editor" class="col-sm-2 control-label">{{ @root.__ "Product options" }}</label>
<div class="col-lg-10">
<ul class="list-group" id="product_opt_wrapper">
<li class="list-group-item">
<div class="row">
<div class="col-lg-2">
<strong>Name:</strong>
<strong>{{ @root.__ "Name" }}:</strong>
<input type="text" id="product_optName" class="form-control" placeholder="size" />
</div>
<div class="col-lg-2">
<strong>Label:</strong>
<strong>{{ @root.__ "Label" }}:</strong>
<input type="text" id="product_optLabel" class="form-control" placeholder="Select size"/>
</div>
<div class="col-lg-2">
<strong>Type:</strong>
<strong>{{ @root.__ "Type" }}:</strong>
<select id="product_optType" class="form-control">
<option value="select">Select</option>
<option value="radio">Radio</option>
@ -83,11 +83,11 @@
</select>
</div>
<div class="col-lg-4">
<strong>Options:</strong>
<strong>{{ @root.__ "Options" }}:</strong>
<input type="text" id="product_optOptions" class="form-control" placeholder="comma, seporated, list"/>
</div>
<div class="col-lg-2 text-right"></br>
<button id="product_opt_add" class="btn btn-success">Add</button>
<button id="product_opt_add" class="btn btn-success">{{ @root.__ "Add" }}</button>
</div></div>
</li>
{{#each options}}
@ -98,17 +98,17 @@
<div class='col-lg-2'>{{this.optType}}</div>
<div class='col-lg-4'>{{{this.optOptions}}}</div>
<div class='col-lg-2 text-right'>
<button class='product_opt_remove btn btn-danger btn-sm'>Remove</button>
<button class='product_opt_remove btn btn-danger btn-sm'>{{ @root.__ "Remove" }}</button>
</div>
</div>
</li>
{{/each}}
</ul>
<p class="help-block">Here you can set options for your product. Eg: Size, color, style</p>
<p class="help-block">{{ @root.__ "Here you can set options for your product. Eg: Size, color, style" }}</p>
</div>
</div>
<div class="form-group">
<label for="productComment" class="col-sm-2 control-label">Allow comment</label>
<label for="productComment" class="col-sm-2 control-label">{{ @root.__ "Allow comment" }}</label>
<div class="col-sm-10">
<div class="checkbox">
<label>
@ -116,29 +116,29 @@
name="productComment">
</label>
</div>
<p class="help-block">Allow free form comments when adding products to cart</p>
<p class="help-block">{{ @root.__ "Allow free form comments when adding products to cart" }}</p>
</div>
</div>
<div class="form-group">
<label for="productTags" class="col-sm-2 control-label">Product tag words</label>
<label for="productTags" class="col-sm-2 control-label">{{ @root.__ "Product tag words" }}</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="productTags" name="productTags" value="{{result.productTags}}">
<p class="help-block">Tag words used to indexed products, making them easier to find and filter.</p>
<p class="help-block">{{ @root.__ "Tag words used to indexed products, making them easier to find and filter." }}</p>
</div>
</div>
<div id="product-images">
<h2>Product images</h2>
<h2>{{ @root.__ "Product images" }}</h2>
{{#if images}}
<div class="row">
<div class="col-md-10 col-md-offset-2">
{{#each images}}
<div class="col-md-3">
<p>
<a data-id="{{this.path}}" class="btn-delete-image btn btn-danger btn-sm">Delete</a>
<a data-id="{{this.path}}" class="btn-delete-image btn btn-danger btn-sm">{{ @root.__ "Delete" }}</a>
{{#ifCond this.productImage '==' true}}
<span class="label label-info">main image</span>
<span class="label label-info">{{ @root.__ "main image" }}</span>
{{else}}
<a data-id="{{../this.path}}" class="set-as-main-image btn btn-sm btn-success">Set as main image</a>
<a data-id="{{../this.path}}" class="set-as-main-image btn btn-sm btn-success">{{ @root.__ "Set as main image" }}</a>
{{/ifCond}}
</p>
<img src="{{this.path}}" class="product-main-image img-responsive">
@ -147,7 +147,7 @@
</div>
</div>
{{else}}
<h4 class="text-warning">No images have been uploaded for this product</h4>
<h4 class="text-warning">{{ @root.__ "No images have been uploaded for this product" }}</h4>
{{/if}}
</div>
</div>
@ -162,17 +162,17 @@
<form method="post" id="upload_form" name="upload_form" action="/admin/file/upload" enctype="multipart/form-data">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
<h4 class="modal-title" id="myModalLabel">Product image upload</h4>
<h4 class="modal-title" id="myModalLabel">{{ @root.__ "Product image upload" }}</h4>
</div>
<div class="modal-body">
<span class="btn btn-info btn-file">
Select file<input type="file" name="upload_file" id="upload_file">
{{ @root.__ "Select file" }}<input type="file" name="upload_file" id="upload_file">
</span>
<input type="hidden" id="productId" name="productId" value="{{result._id}}"/>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="submit" id="saveButton" name="saveButton" class="btn btn-primary">Upload</button>
<button type="submit" id="saveButton" name="saveButton" class="btn btn-primary">{{ @root.__ "Upload" }}</button>
</div>
</form>
</div>

View File

@ -6,16 +6,16 @@
<div class="pull-right">
<button id="frm_edit_product_save" class="btn btn-success" type="submit">Add product <i class="fa fa-plus"></i></button>
</div>
<h2>New product</h2>
<h2>{{ @root.__ "New product" }}</h2>
</div>
<div class="form-group">
<label for="productTitle" class="col-sm-2 control-label">Product title *</label>
<label for="productTitle" class="col-sm-2 control-label">{{ @root.__ "Product title" }} *</label>
<div class="col-sm-10">
<input type="text" id="productTitle" name="productTitle" class="form-control" minlength="5" maxlength="200" value="{{productTitle}}" required/>
</div>
</div>
<div class="form-group">
<label for="productPrice" class="col-sm-2 control-label">Product price *</label>
<label for="productPrice" class="col-sm-2 control-label">{{ @root.__ "Product price" }} *</label>
<div class="col-sm-6">
<div class="input-group">
<span class="input-group-addon">$</span>
@ -24,24 +24,24 @@
</div>
</div>
<div class="form-group">
<label for="productPublished" class="col-sm-2 control-label">Status</label>
<label for="productPublished" class="col-sm-2 control-label">{{ @root.__ "Status" }}</label>
<div class="col-sm-6">
<select class="form-control" id="productPublished" name="productPublished">
<option value="true" selected>Published</option>
<option value="false">Draft</option>
<option value="true" selected>{{ @root.__ "Published" }}</option>
<option value="false">{{ @root.__ "Draft" }}</option>
</select>
</div>
</div>
{{#if config.trackStock}}
<div class="form-group">
<label for="productStock" class="col-sm-2 control-label">Stock level</label>
<label for="productStock" class="col-sm-2 control-label">{{ @root.__ "Stock level" }}</label>
<div class="col-sm-6">
<input type="number" name="productStock" class="form-control" value="{{productStock}}" step="any" />
</div>
</div>
{{/if}}
<div class="form-group" id="editor-wrapper">
<label for="editor" class="col-sm-2 control-label">Product description *</label>
<label for="editor" class="col-sm-2 control-label">{{ @root.__ "Product description" }} *</label>
<div class="col-sm-10">
<textarea id="editor" minlength="5" rows="10" name="productDescription" class="form-control" required>{{productDescription}}</textarea>
</div>
@ -55,26 +55,26 @@
<button class="btn btn-success" id="validate_permalink" type="button">Validate</button>
</span>
</div>
<p class="help-block">This sets a readable URL for the product</p>
<p class="help-block">{{ @root.__ "This sets a readable URL for the product" }}</p>
</div>
</div>
<div class="form-group">
<input type="hidden" id="productOptions" name="productOptions" value="{{result.productOptions}}" />
<label for="editor" class="col-sm-2 control-label">Product options</label>
<label for="editor" class="col-sm-2 control-label">{{ @root.__ "Product options" }}</label>
<div class="col-lg-10">
<ul class="list-group" id="product_opt_wrapper">
<li class="list-group-item">
<div class="row">
<div class="col-lg-2">
<strong>Name:</strong>
<strong>{{ @root.__ "Name" }}:</strong>
<input type="text" id="product_optName" class="form-control" placeholder="Size" />
</div>
<div class="col-lg-2">
<strong>Label:</strong>
<strong>{{ @root.__ "Label" }}:</strong>
<input type="text" id="product_optLabel" class="form-control" placeholder="Select size"/>
</div>
<div class="col-lg-2">
<strong>Type:</strong>
<strong>{{ @root.__ "Type" }}:</strong>
<select id="product_optType" class="form-control">
<option value="select">Select</option>
<option value="radio">Radio</option>
@ -82,11 +82,11 @@
</select>
</div>
<div class="col-lg-4">
<strong>Options:</strong>
<strong>{{ @root.__ "Options" }}:</strong>
<input type="text" id="product_optOptions" class="form-control" placeholder="comma, seporated, list"/>
</div>
<div class="col-lg-2 text-right"></br>
<button id="product_opt_add" class="btn btn-success">Add</button>
<button id="product_opt_add" class="btn btn-success">{{ @root.__ "Add" }}</button>
</div></div>
</li>
{{#each options}}
@ -97,17 +97,17 @@
<div class='col-lg-2'>{{this.optType}}</div>
<div class='col-lg-4'>{{{this.optOptions}}}</div>
<div class='col-lg-2 text-right'>
<button class='product_opt_remove btn btn-danger btn-sm'>Remove</button>
<button class='product_opt_remove btn btn-danger btn-sm'>{{ @root.__ "Remove" }}</button>
</div>
</div>
</li>
{{/each}}
</ul>
<p class="help-block">Here you can set options for your product. Eg: Size, color, style</p>
<p class="help-block">{{ @root.__ "Here you can set options for your product. Eg: Size, color, style" }}</p>
</div>
</div>
<div class="form-group">
<label for="productComment" class="col-sm-2 control-label">Allow comment</label>
<label for="productComment" class="col-sm-2 control-label">{{ @root.__ "Allow comment" }}</label>
<div class="col-sm-10">
<div class="checkbox">
<label>
@ -115,14 +115,14 @@
name="productComment">
</label>
</div>
<p class="help-block">Allow free form comments when adding products to cart</p>
<p class="help-block">{{ @root.__ "Allow free form comments when adding products to cart" }}</p>
</div>
</div>
<div class="form-group">
<label for="productTags" class="col-sm-2 control-label">Product tag words</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="productTags" name="productTags">
<p class="help-block">Tag words used to indexed products, making them easier to find and filter.</p>
<p class="help-block">{{ @root.__ "Tag words used to indexed products, making them easier to find and filter." }}</p>
</div>
</div>
</div>

View File

@ -11,14 +11,14 @@
<a href="/admin/products" class="hidden-xs btn btn-warning btn-lg"><i class="fa fa-times" aria-hidden="true"></i></a>
</span>
</div>
<p class="text-warning top-pad-10">Products can be filtered by: product title or product description keywords</p>
<p class="text-warning top-pad-10">{{ @root.__ "Products can be filtered by: product title or product description keywords" }}</p>
</div>
{{#if results}}
<div class="col-lg-12">
<ul class="list-group">
<li class="list-group-item">
<span class="pull-right"><strong>Published</strong></span>
<strong>Products - <span class="text-danger">Filtered term: {{searchTerm}} </span></strong>
<span class="pull-right"><strong>{{ @root.__ "Published" }}</strong></span>
<strong>{{ @root.__ "Products" }} - <span class="text-danger">{{ @root.__ "Filtered term" }}: {{searchTerm}} </span></strong>
</li>
{{#each results}}
<li class="list-group-item">
@ -33,8 +33,8 @@
<div class="col-lg-12">
<ul class="list-group">
<li class="list-group-item">
<span class="pull-right"><strong>Published</strong></span>
<strong>Recent products</strong>
<span class="pull-right"><strong>{{ @root.__ "Published" }}</strong></span>
<strong>{{ @root.__ "Recent products" }}</strong>
</li>
{{#each top_results}}
<li class="list-group-item">

View File

@ -6,10 +6,10 @@
<input type="password" class="form-control" id="user_password" name="password" placeholder="Password" required>
</div>
<div class="form-group">
<label for="frm_user_password_confirm">Confirm password *</label>
<label for="frm_user_password_confirm">{{ @root.__ "Confirm" }} password *</label>
<input type="password" data-match="#user_password" placeholder="Confirm password" class="form-control" name="frm_user_password_confirm" required>
</div>
<button class="btn btn-lg btn-success btn-block" type="submit">Update password</button>
<button class="btn btn-lg btn-success btn-block" type="submit">{{ @root.__ "Update" }} password</button>
</br>
</form>
</div>

View File

@ -3,72 +3,70 @@
<div class="row">
<div class="col-md-10">
<form method="post" id="settingsForm" action="/admin/settings/update" data-toggle="validator">
<h2 class="clearfix">General Settings
<h2 class="clearfix">{{ @root.__ "General settings" }}
<div class="pull-right">
<button type="submit" id="btnSettingsUpdate" class="btn btn-success">Update</button>
<button type="submit" id="btnSettingsUpdate" class="btn btn-success">{{ @root.__ "Update" }}</button>
</h2>
<div class="form-group">
<label>Cart name *</label>
<label>{{ @root.__ "Cart name" }} *</label>
<input type="text" class="form-control" name="cartTitle" value="{{config.cartTitle}}" required>
<p class="help-block">
This element is critical for search engine optimisation. Cart title is displayed if your logo is hidden.
{{ @root.__ "This element is critical for search engine optimisation. Cart title is displayed if your logo is hidden." }}
</p>
</div>
<div class="form-group">
<label>Cart description *</label>
<label>{{ @root.__ "Cart description" }} *</label>
<input type="text" class="form-control" name="cartDescription" value="{{config.cartDescription}}" required>
<p class="help-block">This description shows when your website is listed in search engine results.</p>
<p class="help-block">{{ @root.__ "This description shows when your website is listed in search engine results." }}</p>
</div>
<div class="form-group">
<label>Cart image/logo</label>
<label>{{ @root.__ "Cart image/logo" }}</label>
<input type="text" class="form-control" name="cartLogo" value="{{config.cartLogo}}">
</div>
<div class="form-group">
<label>Cart URL *</label>
<label>{{ @root.__ "Cart URL" }} *</label>
<input type="text" class="form-control" name="baseUrl" value="{{config.baseUrl}}" required>
<p class="help-block">This URL is used in sitemaps and when your customer returns from completing their payment.</p>
<p class="help-block">{{ @root.__ "This URL is used in sitemaps and when your customer returns from completing their payment." }}</p>
</div>
<div class="form-group">
<label>Cart Email *</label>
<label>{{ @root.__ "Cart Email" }} *</label>
<input type="email" class="form-control" name="emailAddress" value="{{config.emailAddress}}" required>
<p class="help-block">This is used as the "from" email when sending receipts to your customers.</p>
<p class="help-block">{{ @root.__ "This is used as the \"from\" email when sending receipts to your customers." }}</p>
</div>
<div class="form-group">
<label>Flat shipping rate *</label>
<label>{{ @root.__ "Flat shipping rate" }} *</label>
<input type="text" class="form-control" name="flatShipping" value="{{config.flatShipping}}" required>
<p class="help-block">A flat shipping rate applied to all orders.</p>
<p class="help-block">{{ @root.__ "A flat shipping rate applied to all orders." }}</p>
</div>
<div class="form-group">
<label>Free shipping threshold</label>
<label>{{ @root.__ "Free shipping threshold" }}</label>
<input type="text" class="form-control" name="freeShippingAmount" value="{{config.freeShippingAmount}}">
<p class="help-block">Orders over this value will mean the shipped will the FREE. Set to high value if you always want to charge
shipping.</p>
<p class="help-block">{{ @root.__ "Orders over this value will mean the shipped will the FREE. Set to high value if you always want to charge shipping." }}</p>
</div>
<div class="form-group">
<label>Payment gateway</label>
<label>{{ @root.__ "Payment gateway" }}</label>
<select class="form-control" name="paymentGateway">
<option {{selectState 'paypal' config.paymentGateway}} value="paypal">Paypal</option>
<option {{selectState 'stripe' config.paymentGateway}} value="stripe">Stripe</option>
</select>
<p class="help-block">You will also need to configure your payment gateway credentials in the `/config/&lt;gateway_name&gt;.json`
file.</p>
<p class="help-block">{{ @root.__ "Payment_Gateway_Info" }}</p>
</div>
<div class="form-group">
<label>Currency symbol</label>
<label>{{ @root.__ "Currency symbol" }}</label>
<input type="text" class="form-control" name="currencySymbol" value="{{currencySymbol config.currencySymbol}}">
<p class="help-block">Set this to your currency symbol. Eg: $, £, €</p>
<p class="help-block">{{ @root.__ "Set this to your currency symbol. Eg: $, £, €" }}</p>
</div>
<div class="form-group">
<label>Theme</label>
<label>{{ @root.__ "Theme" }}</label>
<select class="form-control" name="theme">
{{#each themes}}
<option {{selectState this ../config.theme}} value="{{this}}">{{this}}</option>
{{/each}}
</select>
<p class="help-block">Themes are loaded from `/public/themes/`</p>
<p class="help-block">{{ @root.__ "Theme_Info" }}</p>
</div>
<div class="form-group">
<label>Products per row</label>
<label>{{ @root.__ "Products per row" }}</label>
<select class="form-control" name="productsPerRow">
<option value="{{config.productsPerRow}}" hidden="hidden" selected="selected">{{config.productsPerRow}}</option>
<option {{selectState '1' config.productsPerRow}}>1</option>
@ -76,36 +74,35 @@
<option {{selectState '3' config.productsPerRow}}>3</option>
<option {{selectState '4' config.productsPerRow}}>4</option>
</select>
<p class="help-block">The number of products to be displayed across the page.</p>
<p class="help-block">{{ @root.__ "The number of products to be displayed across the page." }}</p>
</div>
<div class="form-group">
<label>Products per page</label>
<label>{{ @root.__ "Products per page" }}</label>
<input type="number" class="form-control" name="productsPerPage" value="{{config.productsPerPage}}">
<p class="help-block">The number of products to be displayed on each page.</p>
<p class="help-block">{{ @root.__ "The number of products to be displayed on each page." }}</p>
</div>
<div class="form-group">
<label>Menu Enabled: </label>
<label>{{ @root.__ "Menu Enabled" }}: </label>
<div class="checkbox">
<label>
<input class="settingsMenuEnabled" type="checkbox" {{checkedState config.menuEnabled}} id="menuEnabled"
name="menuEnabled">
</label>
</div>
<p class="help-block">If a menu is set you can set it up
<a href="/admin/settings/menu">here</a>.</p>
<p class="help-block">{{{ @root.__ "Menu_Enabled_Info" }}}</p>
</div>
<div class="form-group">
<label>Menu header</label>
<label>{{ @root.__ "Menu header" }}</label>
<input type="text" class="form-control" name="menuTitle" value="{{config.menuTitle}}" placeholder="Menu">
<p class="help-block">The heading text for your menu.</p>
<p class="help-block">{{ @root.__ "The heading text for your menu." }}</p>
</div>
<div class="form-group">
<label>Menu location: </label>
<label>{{ @root.__ "Menu location" }}: </label>
<select class="form-control" name="menuLocation">
<option {{selectState 'top' config.menuLocation}}>top</option>
<option {{selectState 'side' config.menuLocation}}>side</option>
</select>
<p class="help-block">The location of your menu.</p>
<p class="help-block">{{ @root.__ "The location of your menu." }}</p>
</div>
<div class="form-group">
<label>Footer HTML</label>
@ -116,13 +113,11 @@
<label>Google analytics</label>
<textarea class="form-control" rows="3" id="googleAnalytics" name="googleAnalytics">{{googleAnalytics}}</textarea>
<input type="hidden" id="googleAnalytics_input" name="googleAnalytics_input">
<p class="help-block">Your Google Analytics code. Please also inlude the "script" tags -
<a href="https://support.google.com/analytics/answer/1032385?hl=en"
target="_blank">Help</a>
<p class="help-block">{{{ @root.__ "Google_Analytics_Info" }}}
</p>
</div>
<div class="form-group">
<label>Custom CSS</label>
<label>{{ @root.__ "Custom CSS" }}</label>
<textarea class="form-control" rows="10" id="customCss" name="customCss">{{config.customCss}}</textarea>
<input type="hidden" id="customCss_input" name="customCss_input">
</div>
@ -151,7 +146,7 @@
<input type="password" class="form-control" name="emailPassword" value="{{config.emailPassword}}" autocomplete="off" required>
</div>
<div class="form-group">
<button id="sendTestEmail" class="btn btn-success">Send test email</button>
<button id="sendTestEmail" class="btn btn-success">{{ @root.__ "Send test email" }}</button>
</div>
</div>
</div>

View File

@ -51,9 +51,8 @@
</tbody>
</table>
<p class="text-muted">
Here you can setup a menu to displayed on your shopping cart. You can use this menu to filter your products by specifying a keyword in the
"link" field. Eg: To show products with a keyword (or tag) of boots you would set the menu field to "Backpacks" and a link value "backpack".
You can also use this menu to link to static pages, Eg: shipping, returns, help, about, contact etc.
{{ @root.__ "Setting_menu_explain" }}
</p>
</div>
</div>

View File

@ -3,28 +3,28 @@
<div class="row">
<div class="col-md-12">
<form id="settingsPageEditor">
<h2 class="clearfix">Static page <div class="pull-right"><button type="submit" id="btnPageUpdate" class="btn btn-success">{{button_text}}</button></div></h2>
<h2 class="clearfix">{{ @root.__ "Static page" }} <div class="pull-right"><button type="submit" id="btnPageUpdate" class="btn btn-success">{{button_text}}</button></div></h2>
<input type="hidden" id="page_id" value="{{page._id}}">
<div class="form-group">
<label>Page name *</label>
<label>{{ @root.__ "Page name" }} *</label>
<input type="text" class="form-control" id="pageName" name="pageName" value="{{page.pageName}}" required>
<p class="help-block">A friendly name to manage the static page.</p>
<p class="help-block">{{ @root.__ "A friendly name to manage the static page." }}</p>
</div>
<div class="form-group">
<label>Page slug *</label>
<label>{{ @root.__ "Page slug" }} *</label>
<input type="text" class="form-control" id="pageSlug" name="pageSlug" value="{{page.pageSlug}}" required>
<p class="help-block">This is the relative URL of the page. Eg: A setting of "about" would make the page available at: mydomain.com/about</p>
<p class="help-block">{{ @root.__ "Page_Slug_Description" }}</p>
</div>
<div class="form-group">
<label>Page Enabled: </label>
<label>{{ @root.__ "Page Enabled" }}: </label>
<div class="checkbox">
<label><input class="settingsPageEnabled" type="checkbox" {{checkedState page.pageEnabled}} id="pageEnabled" name="pageEnabled"></label>
</div>
</div>
<div class="form-group">
<label>Page content *</label>
<label>{{ @root.__ "Page content" }} *</label>
<textarea id="pageContent">{{page.pageContent}}</textarea>
<p class="help-block">Here you can enter the content you wish to be displayed on your static page.</p>
<p class="help-block">{{ @root.__ "Here you can enter the content you wish to be displayed on your static page." }}</p>
</div>
</form>
</div>

View File

@ -2,10 +2,9 @@
<div class="col-lg-9">
<div class="row">
<div class="col-md-10">
<h2 class="clearfix">Static pages <div class="pull-right"><a href="/admin/settings/pages/new" class="btn btn-success">New page</a></div></h2>
<h2 class="clearfix">{{ @root.__ "Static pages" }} <div class="pull-right"><a href="/admin/settings/pages/new" class="btn btn-success">{{ @root.__ "New page" }}</a></div></h2>
<p class="text-muted">
Here you can setup and manage static pages for your shopping cart.
You may want to setup a page with a little bit about your business called "About" or "Contact Us" etc.
{{ @root.__ "Static_Pages_Info" }}
</p>
{{#if pages}}
<ul class="list-group">
@ -13,20 +12,20 @@
<li class="list-group-item">
<div class="row">
<div class="col-lg-8">
<h5><strong>Name:</strong>&nbsp; {{pageName}}</h5>
<h5><strong>{{ @root.__ "Name" }}:</strong>&nbsp; {{pageName}}</h5>
</div>
<div class="col-lg-4 text-right">
<a class="btn btn-sm btn-success" href="/admin/settings/pages/edit/{{_id}}">Edit</a>
<a class="btn btn-sm btn-danger" href="/admin/settings/pages/delete/{{_id}}">Delete</a>
<a class="btn btn-sm btn-success" href="/admin/settings/pages/edit/{{_id}}">{{ @root.__ "Edit" }}</a>
<a class="btn btn-sm btn-danger" href="/admin/settings/pages/delete/{{_id}}">{{ @root.__ "Delete" }}</a>
</div>
</div>
</li>
{{/each}}
</ul>
{{else}}
<h4 class="text-warning text-center">There are currently no static pages setup. Please setup a static page.</h4>
<h4 class="text-warning text-center">{{ @root.__ "There are currently no static pages setup. Please setup a static page." }}</h4>
<p class="text-center">
<a class="btn btn-success" href="/admin/settings/pages/new"> Create new</a>
<a class="btn btn-success" href="/admin/settings/pages/new"> {{ @root.__ "Create new" }}</a>
</p>
{{/if}}
</div>

View File

@ -2,21 +2,21 @@
<form class="form-signin" action="/admin/setup_action" method="post" role="form" data-toggle="validator">
<h2 class="form-signin-heading text-center">expressCart Setup</h2>
<div class="form-group">
<label for="usersName">Users name *</label>
<input type="text" class="form-control" id="usersName" name="usersName" placeholder="Users name" required>
<label for="usersName">{{ @root.__ "Users name" }} *</label>
<input type="text" class="form-control" id="usersName" name="usersName" placeholder="{{ @root.__ "Users name" }}" required>
</div>
<div class="form-group">
<label for="userEmail">User email *</label>
<input type="email" class="form-control" id="userEmail" name="userEmail" placeholder="Email address" required>
<label for="userEmail">{{ @root.__ "User email" }} *</label>
<input type="email" class="form-control" id="userEmail" name="userEmail" placeholder="{{ @root.__ "Email address" }}" required>
</div>
<div class="form-group">
<label for="userPassword">User password *</label>
<label for="userPassword">{{ @root.__ "User password" }} *</label>
<input type="password" class="form-control" id="userPassword" name="userPassword" placeholder="Password" required>
</div>
<div class="form-group">
<label for="frm_userPassword_confirm">Password confirm *</label>
<label for="frm_userPassword_confirm">{{ @root.__ "Password confirm" }} *</label>
<input type="password" data-match="#userPassword" placeholder="Confirm password" class="form-control" id="frm_userPassword_confirm" name="frm_userPassword_confirm" required>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit">Complete setup</button>
<button class="btn btn-lg btn-primary btn-block" type="submit">{{ @root.__ "Complete setup" }}</button>
</form>
</div>

View File

@ -8,7 +8,7 @@
</div>
{{/if}}
<div class="panel panel-default" style="margin-top: 30px;">
<div class="panel-heading">Cart contents</div>
<div class="panel-heading">{{ @root.__ "Cart contents" }}</div>
<div class="panel-body cart-body">
<div class="container-fluid">
{{#each @root.session.cart}}
@ -64,12 +64,13 @@
<div class="cart-contents-shipping col-md-12 col m12 no-pad-right">
{{#ifCond @root.session.shippingCostApplied '===' true}}
<div class="text-right">
Shipping:
<strong>{{currencySymbol config.currencySymbol}}{{formatAmount config.flatShipping}}</strong>
{{ @root.__ "Shipping" }}
<strong>{{currencySymbol @root.config.currencySymbol}}{{formatAmount @root.config.flatShipping}}</strong>
</div>
{{else}}
<div class="text-right">
Shipping:
{{ @root.__ "Shipping" }}
<strong>FREE</strong>
</div>
{{/ifCond}}
@ -92,12 +93,12 @@
<div class="row">
{{#if @root.session.cart}}
<div class="col-xs-6 col s6 text-left align-right">
<button class="btn btn-danger" id="empty-cart" type="button">Empty cart</button>
<button class="btn btn-danger" id="empty-cart" type="button">{{ @root.__ "Empty cart" }}</button>
</div>
{{#ifCond page '!=' 'pay'}}
<div class="text-right align-right col-xs-6 col s6">
{{#ifCond @root.page '==' 'checkout'}}
<a href="/pay" class="btn btn-default">Pay now</a>
<a href="/pay" class="btn btn-default">{{ @root.__ "Pay now" }}</a>
{{else}}
<a href="/checkout" class="btn btn-default">Checkout</a>
{{/ifCond}}
@ -105,4 +106,4 @@
{{/ifCond}} {{/if}}
</div>
</div>
</div>
</div>

View File

@ -15,7 +15,7 @@
<div class="search-bar-input input-group searchMenuLocation-{{config.menuLocation}} searchProPerRow-{{config.productsPerRow}}">
<input type="text" name="frm_search" id="frm_search" class="form-control" placeholder="Search the shop">
<span class="input-group-btn">
<button class="btn btn-primary" id="btn_search" type="submit">Search</button>
<button class="btn btn-primary" id="btn_search" type="submit">{{ @root.__ "Search" }}</button>
</span>
</div>
</li>

View File

@ -3,16 +3,16 @@
{{#if filtered}}
<div class="product-layout col-md-12">
{{#if menuLink}}
<h4>Category: <strong>{{menuLink.title}}</strong></h4>
<h4>{{ @root.__ "Category" }}: <strong>{{menuLink.title}}</strong></h4>
{{else}}
<h4>Search results: <strong>{{searchTerm}}</strong></h4>
<h4>{{ @root.__ "Search results" }}: <strong>{{searchTerm}}</strong></h4>
{{/if}}
</div>
{{/if}}
<div class="row product-layout">
{{#ifCond results.length '==' 0}}
<div class="col-md-12">
<p class="text-danger">No products found</p>
<p class="text-danger">{{ @root.__ "No products found" }}</p>
</div>
{{/ifCond}}
{{#each results}}
@ -51,7 +51,7 @@
{{currencySymbol ../config.currencySymbol}}{{formatAmount productPrice}}
</h3>
<p class="text-center">
<a class="btn btn-primary add-to-cart" data-id="{{this._id}}" data-link="{{this.productPermalink}}" data-has-options="{{checkProductOptions this.productOptions}}" role="button">Add to cart</a>
<a class="btn btn-primary add-to-cart" data-id="{{this._id}}" data-link="{{this.productPermalink}}" data-has-options="{{checkProductOptions this.productOptions}}" role="button">{{ @root.__ "Add to cart" }}</a>
</p>
</div>
</div>

View File

@ -3,7 +3,7 @@
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/">Home</a></li>
<li class="breadcrumb-item active" aria-current="page"><a href="/checkout">Checkout</a></li>
<li class="breadcrumb-item active" aria-current="page">Pay</li>
<li class="breadcrumb-item active" aria-current="page">{{ @root.__ "Pay now" }}</li>
</ol>
</nav>
<div class="row">
@ -12,10 +12,10 @@
{{/if}}
<div class="col-md-5">
<div class="panel panel-default" style="margin-top: 30px;">
<div class="panel-heading">Customer details</div>
<div class="panel-heading">{{ @root.__ "Customer details" }}</div>
{{#unless session.customer}}
<div class="panel-body customer-details-login">
<p>Existing customer</p>
<p>{{ @root.__ "Existing customer" }}</p>
<div class="form-group">
<input type="email" class="form-control" id="customerLoginEmail" name="loginEmail" minlength="5" placeholder="Email address" required>
</div>
@ -23,7 +23,7 @@
<input type="password" class="form-control" id="customerLoginPassword" name="loginPassword" minlength="5" placeholder="Password" required>
</div>
<div class="form-group">
<a href="/customer/forgotten" class="btn btn-default pull-left">Forgotten</a>
<a href="/customer/forgotten" class="btn btn-default pull-left">{{ @root.__ "Forgotten" }}</a>
</div>
<div class="form-group">
<button id="customerLogin" class="btn btn-success pull-right" type="submit">Login</button>
@ -33,7 +33,7 @@
<div class="panel-body customer-details">
{{#if session.customer}}
<div class="col-xs-12 col-md-12">
<button id="customerLogout" class="btn btn-sm btn-success pull-right">Change customer</button>
<button id="customerLogout" class="btn btn-sm btn-success pull-right">{{ @root.__ "Change customer" }}</button>
</div>
{{/if}}
<form id="shipping-form" class="shipping-form" action="/{{config.paymentGateway}}/checkout_action" method="post" role="form" data-toggle="validator" novalidate="false">
@ -45,11 +45,11 @@
{{/if}}
{{#unless session.customer}}
<div class="col-xs-12 col-md-12">
<p class="text-muted">Enter a password to create an account for next time</p>
<p class="text-muted">{{ @root.__ "Enter a password to create an account for next time" }}</p>
<div class="form-group">
<input type="password" class="form-control customerDetails" id="newCustomerPassword" name="newCustomerPassword" placeholder="Password" required>
</div>
<a id="createCustomerAccount" class="btn btn-success pull-right">Create account</a>
<a id="createCustomerAccount" class="btn btn-success pull-right">{{ @root.__ "Create account" }}</a>
</div>
{{/unless}}
</form>

View File

@ -2,20 +2,20 @@
<div class="row">
<div class="text-center col-md-10 col-md-offset-1">
{{#ifCond result.orderStatus '==' 'Paid'}}
<h2 class="text-success">Your payment has been successfully processed</h2>
<h2 class="text-success">{{ @root.__ "Your payment has been successfully processed" }}</h2>
{{else}}
<h2 class="text-danger">Your payment has failed. Please try again or contact us.</h2>
<h2 class="text-danger">{{ @root.__ "Your payment has failed. Please try again or contact us." }}</h2>
{{/ifCond}}
{{#if result}}
<div>
<p><strong>Order ID:</strong> {{result._id}}</p>
<p><strong>Payment ID:</strong> {{result.orderPaymentId}}</p>
<p><strong>{{ @root.__ "Order ID" }}:</strong> {{result._id}}</p>
<p><strong>{{ @root.__ "Payment ID" }}:</strong> {{result.orderPaymentId}}</p>
</div>
{{/if}}
{{#ifCond result.orderStatus '==' 'Paid'}}
<h3 class="text-warning">Please retain the details above as a reference of payment.</h3>
<h3 class="text-warning">{{ @root.__ "Please retain the details above as a reference of payment." }}</h3>
{{/ifCond}}
<a href="/" class="btn btn-warning">Home</a>
</div>
</div>
</div>
</div>

View File

@ -6,7 +6,7 @@
<h1 class="col-md-10 product-title">{{result.productTitle}}</h1>
<h4 class="col-md-10 product-price">{{currencySymbol config.currencySymbol}}{{result.productPrice}}</h4>
{{#if productOptions}}
<h4 class="col-md-10 product-option">Options</h4>
<h4 class="col-md-10 product-option">{{ @root.__ "Options" }}</h4>
<div class="col-md-10">
{{#each productOptions}}
{{#ifCond this.optType '==' "select"}}
@ -48,7 +48,7 @@
{{/ifCond}}
{{/if}}
<div class="col-md-10 productOptions">
<p class="product-option-text">Quantity</p>
<p class="product-option-text">{{ @root.__ "Quantity" }}</p>
<div class="input-group">
<span class="input-group-btn">
<button class="btn btn-primary qty-btn-minus" type="button">-</button>
@ -61,12 +61,12 @@
</div>
{{#if result.productComment}}
<div class="col-md-10">
Leave a comment?
{{ @root.__ "Leave a comment?" }}
<textarea class="form-control" id="product_comment"></textarea>
</div>
{{/if}}
<div class="col-md-10 btnAddToCart">
<button class="btn btn-primary btn-block product-add-to-cart" type="button">Add to cart</button>
<button class="btn btn-primary btn-block product-add-to-cart" type="button">{{ @root.__ "Add to cart" }}</button>
</div>
<div class="col-md-10 body_text">
{{{productDescription}}}

View File

@ -9,7 +9,7 @@
{{/if}}
<div class="card">
<div class="card-content">
<span class="card-title">Cart contents</span>
<span class="card-title">{{ @root.__ "Cart contents" }}</span>
{{#each @root.session.cart}}
<div class="row cart-row">
<div class="col s4 m2">
@ -58,12 +58,12 @@
<div class="cart-contents-shipping col s12 no-pad-right">
{{#ifCond @root.session.shippingCostApplied '===' true}}
<div class="text-right">
Shipping:
{{ @root.__ "Shipping" }}
<strong>{{currencySymbol config.currencySymbol}}{{formatAmount @root.config.flatShipping}}</strong>
</div>
{{else}}
<div class="text-right">
Shipping:
{{ @root.__ "Shipping" }}
<strong>FREE</strong>
</div>
{{/ifCond}}
@ -85,12 +85,12 @@
<div class="row">
{{#if @root.session.cart}}
<div class="col s6 align-right">
<button class="btn waves-effect waves-light red darken-3" id="empty-cart" type="button">Empty cart</button>
<button class="btn waves-effect waves-light red darken-3" id="empty-cart" type="button">{{ @root.__ "Empty cart" }}</button>
</div>
{{#ifCond page '!=' 'pay'}}
<div class="text-right align-right col s6">
{{#ifCond @root.page '==' 'checkout'}}
<a href="/pay" class="btn waves-effect waves-light blue darken-3">Pay now</a>
<a href="/pay" class="btn waves-effect waves-light blue darken-3">{{ @root.__ "Pay now" }}</a>
{{else}}
<a href="/checkout" class="btn waves-effect waves-light blue darken-3">Checkout</a>
{{/ifCond}}
@ -98,4 +98,4 @@
{{/ifCond}} {{/if}}
</div>
</div>
</div>
</div>

View File

@ -15,7 +15,7 @@
<input type="text" name="frm_search" id="frm_search" class="input-field" placeholder="Search the shop">
</li>
<li>
<button class="btn waves-effect waves-light blue darken-3" id="btn_search" type="submit">Search</button>
<button class="btn waves-effect waves-light blue darken-3" id="btn_search" type="submit">{{ @root.__ "Search" }}</button>
</li>
</div>
</ul>

View File

@ -3,16 +3,16 @@
{{#if filtered}}
<div class="product-layout col m12">
{{#if menuLink}}
<h4>Category: <strong>{{menuLink.title}}</strong></h4>
<h4>{{ @root.__ "Category" }}: <strong>{{menuLink.title}}</strong></h4>
{{else}}
<h4>Search results: <strong>{{searchTerm}}</strong></h4>
<h4>{{ @root.__ "Search results" }}: <strong>{{searchTerm}}</strong></h4>
{{/if}}
</div>
{{/if}}
<div class="row product-layout">
{{#ifCond results.length '==' 0}}
<div class="col m12">
<p class="text-danger">No products found</p>
<p class="text-danger">{{ @root.__ "No products found" }}</p>
</div>
{{/ifCond}}
{{#each results}}
@ -51,7 +51,7 @@
{{currencySymbol ../config.currencySymbol}}{{formatAmount productPrice}}
</h3>
<p class="text-center">
<a class="btn waves-effect waves-light blue darken-3 add-to-cart" data-id="{{this._id}}" data-link="{{this.productPermalink}}" data-has-options="{{checkProductOptions this.productOptions}}" role="button">Add to cart</a>
<a class="btn waves-effect waves-light blue darken-3 add-to-cart" data-id="{{this._id}}" data-link="{{this.productPermalink}}" data-has-options="{{checkProductOptions this.productOptions}}" role="button">{{ @root.__ "Add to cart" }}</a>
</p>
</div>
</div>

View File

@ -7,9 +7,9 @@
<div class="card">
<div class="card-content">
<div class="row">
<span class="card-title">Customer details</span>
<span class="card-title">{{ @root.__ "Customer details" }}</span>
{{#unless session.customer}}
<p>Existing customer</p>
<p>{{ @root.__ "Existing customer" }}</p>
<div class="input-field col s12">
<input type="email" id="customerLoginEmail" name="loginEmail" minlength="5" placeholder="Email address" required>
</div>
@ -17,7 +17,7 @@
<input type="password" class="form-control" id="customerLoginPassword" name="loginPassword" minlength="5" placeholder="Password" required>
</div>
<div class="input-field col s12 m6">
<a href="/customer/forgotten" class="btn waves-effect waves-light blue darken-3 pull-left">Forgotten</a>
<a href="/customer/forgotten" class="btn waves-effect waves-light blue darken-3 pull-left">{{ @root.__ "Forgotten" }}</a>
</div>
<div class="input-field col s12 m6">
<button id="customerLogin" class="btn waves-effect waves-light blue darken-3 pull-right" type="submit">Login</button>
@ -25,7 +25,7 @@
{{/unless}}
{{#if session.customer}}
<div class="col s12">
<button id="customerLogout" class="btn waves-effect waves-light blue darken-3 pull-right">Change customer</button>
<button id="customerLogout" class="btn waves-effect waves-light blue darken-3 pull-right">{{ @root.__ "Change customer" }}</button>
</div>
{{/if}}
<form id="shipping-form" class="shipping-form" action="/{{config.paymentGateway}}/checkout_action" method="post" role="form" data-toggle="validator" novalidate="false">
@ -37,13 +37,13 @@
{{/if}}
{{#unless session.customer}}
<div class="col s12">
<p class="text-muted">Enter a password to create an account for next time</p>
<p class="text-muted">{{ @root.__ "Enter a password to create an account for next time" }}</p>
<div class="input-field col s12">
<input type="password" class="form-control customerDetails" id="newCustomerPassword" name="newCustomerPassword" placeholder="Password" required>
</div>
</div>
<div class="col s12">
<a id="createCustomerAccount" class="btn waves-effect waves-light blue darken-3 pull-right">Create account</a>
<a id="createCustomerAccount" class="btn waves-effect waves-light blue darken-3 pull-right">{{ @root.__ "Create account" }}</a>
</div>
{{/unless}}
</form>

View File

@ -2,20 +2,20 @@
<div class="row">
<div class="text-center col m10 offset-m1">
{{#ifCond result.orderStatus '==' 'Paid'}}
<h2 class="text-success">Your payment has been successfully processed</h2>
<h2 class="text-success">{{ @root.__ "Your payment has been successfully processed" }}</h2>
{{else}}
<h2 class="text-danger">Your payment has failed. Please try again or contact us.</h2>
<h2 class="text-danger">{{ @root.__ "Your payment has failed. Please try again or contact us." }}</h2>
{{/ifCond}}
{{#if result}}
<div>
<p><strong>Order ID:</strong> {{result._id}}</p>
<p><strong>Payment ID:</strong> {{result.orderPaymentId}}</p>
<p><strong>{{ @root.__ "Order ID" }}:</strong> {{result._id}}</p>
<p><strong>{{ @root.__ "Payment ID" }}:</strong> {{result.orderPaymentId}}</p>
</div>
{{/if}}
{{#ifCond result.orderStatus '==' 'Paid'}}
<h3 class="text-warning">Please retain the details above as a reference of payment.</h3>
<h3 class="text-warning">{{ @root.__ "Please retain the details above as a reference of payment." }}</h3>
{{/ifCond}}
<a href="/" class="btn waves-effect waves-light blue darken-3">Home</a>
</div>
</div>
</div>
</div>

View File

@ -6,7 +6,7 @@
<h1 class="col s12 m10 product-title">{{result.productTitle}}</h1>
<h4 class="col s12 m10 product-price">{{currencySymbol config.currencySymbol}}{{result.productPrice}}</h4>
{{#if productOptions}}
<h4 class="col s12 m10 product-option">Options</h4>
<h4 class="col s12 m10 product-option">{{ @root.__ "Options" }}</h4>
<div class="col s12 m10">
{{#each productOptions}}
{{#ifCond this.optType '==' "select"}}
@ -48,7 +48,7 @@
{{/ifCond}}
{{/if}}
<div class="col s10 productOptions">
<p class="product-option-text">Quantity</p>
<p class="product-option-text">{{ @root.__ "Quantity" }}</p>
<div class="input-group">
<span class="input-group-btn">
<button class="btn waves-effect waves-light blue darken-3 qty-btn-minus" type="button">-</button>
@ -63,12 +63,12 @@
</div>
{{#if result.productComment}}
<div class="col-md-10">
Leave a comment?
{{ @root.__ "Leave a comment?" }}
<textarea class="form-control" id="product_comment"></textarea>
</div>
{{/if}}
<div class="btnAddToCart">
<button class="btn waves-effect waves-light blue darken-3 col s10 product-add-to-cart" type="button">Add to cart</button>
<button class="btn waves-effect waves-light blue darken-3 col s10 product-add-to-cart" type="button">{{ @root.__ "Add to cart" }}</button>
</div>
<div class="col s10 body_text">
{{{productDescription}}}

View File

@ -9,7 +9,7 @@
{{/if}}
<div class="card">
<div class="card-content">
<span class="card-title">Cart contents</span>
<span class="card-title">{{ @root.__ "Cart contents" }}</span>
{{#each @root.session.cart}}
<div class="row cart-row">
<div class="col s4 m2">
@ -58,12 +58,12 @@
<div class="cart-contents-shipping col s12 no-pad-right">
{{#ifCond @root.session.shippingCostApplied '===' true}}
<div class="text-right">
Shipping:
{{ @root.__ "Shipping" }}
<strong>{{currencySymbol config.currencySymbol}}{{formatAmount @root.config.flatShipping}}</strong>
</div>
{{else}}
<div class="text-right">
Shipping:
{{ @root.__ "Shipping" }}
<strong>FREE</strong>
</div>
{{/ifCond}}
@ -85,12 +85,12 @@
<div class="row">
{{#if @root.session.cart}}
<div class="col s6 align-right">
<button class="btn waves-effect waves-light red darken-3" id="empty-cart" type="button">Empty cart</button>
<button class="btn waves-effect waves-light red darken-3" id="empty-cart" type="button">{{ @root.__ "Empty cart" }}</button>
</div>
{{#ifCond page '!=' 'pay'}}
<div class="text-right align-right col s6">
{{#ifCond @root.page '==' 'checkout'}}
<a href="/pay" class="btn waves-effect waves-light black">Pay now</a>
<a href="/pay" class="btn waves-effect waves-light black">{{ @root.__ "Pay now" }}</a>
{{else}}
<a href="/checkout" class="btn waves-effect waves-light black">Checkout</a>
{{/ifCond}}
@ -98,4 +98,4 @@
{{/ifCond}} {{/if}}
</div>
</div>
</div>
</div>

View File

@ -7,7 +7,7 @@
<input type="text" name="frm_search" id="frm_search" class="input-field" placeholder="Search...">
</div>
<div class="col m4">
<a class="col m8 waves-effect waves-light btn black right" id="btn_search"><i class="material-icons white-text">search</i></a>
<a class="col m8 waves-effect waves-light btn black right" id="btn_search"><i class="material-icons white-text">{{ @root.__ "Search" }}</i></a>
</div>
</li>
<li {{#unless searchTerm}}class="navActive"{{/unless}}><a href="/">Home</a></li>

View File

@ -3,16 +3,16 @@
{{#if filtered}}
<div class="product-layout col m12">
{{#if menuLink}}
<h4>Category: <strong>{{menuLink.title}}</strong></h4>
<h4>{{ @root.__ "Category" }}: <strong>{{menuLink.title}}</strong></h4>
{{else}}
<h4>Search results: <strong>{{searchTerm}}</strong></h4>
<h4>{{ @root.__ "Search results" }}: <strong>{{searchTerm}}</strong></h4>
{{/if}}
</div>
{{/if}}
<div class="row product-layout">
{{#ifCond results.length '==' 0}}
<div class="col m12">
<p class="text-danger">No products found</p>
<p class="text-danger">{{ @root.__ "No products found" }}</p>
</div>
{{/ifCond}}
{{#each results}}
@ -51,7 +51,7 @@
{{currencySymbol ../config.currencySymbol}}{{formatAmount productPrice}}
</h3>
<p class="text-center">
<a class="btn waves-effect waves-light black add-to-cart" data-id="{{this._id}}" data-link="{{this.productPermalink}}" data-has-options="{{checkProductOptions this.productOptions}}" role="button">Add to cart</a>
<a class="btn waves-effect waves-light black add-to-cart" data-id="{{this._id}}" data-link="{{this.productPermalink}}" data-has-options="{{checkProductOptions this.productOptions}}" role="button">{{ @root.__ "Add to cart" }}</a>
</p>
</div>
</div>

View File

@ -7,9 +7,9 @@
<div class="card">
<div class="card-content">
<div class="row">
<span class="card-title">Customer details</span>
<span class="card-title">{{ @root.__ "Customer details" }}</span>
{{#unless session.customer}}
<p>Existing customer</p>
<p>{{ @root.__ "Existing customer" }}</p>
<div class="input-field col s12">
<input type="email" id="customerLoginEmail" name="loginEmail" minlength="5" placeholder="Email address" required>
</div>
@ -17,7 +17,7 @@
<input type="password" class="form-control" id="customerLoginPassword" name="loginPassword" minlength="5" placeholder="Password" required>
</div>
<div class="input-field col s12 m6">
<a href="/customer/forgotten" class="btn waves-effect waves-light black pull-left">Forgotten</a>
<a href="/customer/forgotten" class="btn waves-effect waves-light black pull-left">{{ @root.__ "Forgotten" }}</a>
</div>
<div class="input-field col s12 m6">
<button id="customerLogin" class="btn waves-effect waves-light black pull-right" type="submit">Login</button>
@ -25,7 +25,7 @@
{{/unless}}
{{#if session.customer}}
<div class="col s12">
<button id="customerLogout" class="btn waves-effect waves-light black pull-right">Change customer</button>
<button id="customerLogout" class="btn waves-effect waves-light black pull-right">{{ @root.__ "Change customer" }}</button>
</div>
{{/if}}
<form id="shipping-form" class="shipping-form" action="/{{config.paymentGateway}}/checkout_action" method="post" role="form" data-toggle="validator" novalidate="false">
@ -37,13 +37,13 @@
{{/if}}
{{#unless session.customer}}
<div class="col s12">
<p class="text-muted">Enter a password to create an account for next time</p>
<p class="text-muted">{{ @root.__ "Enter a password to create an account for next time" }}</p>
<div class="input-field col s12">
<input type="password" class="form-control customerDetails" id="newCustomerPassword" name="newCustomerPassword" placeholder="Password" required>
</div>
</div>
<div class="col s12">
<a id="createCustomerAccount" class="btn waves-effect waves-light black pull-right">Create account</a>
<a id="createCustomerAccount" class="btn waves-effect waves-light black pull-right">{{ @root.__ "Create account" }}</a>
</div>
{{/unless}}
</form>

View File

@ -2,20 +2,20 @@
<div class="row">
<div class="text-center col m10 offset-m1">
{{#ifCond result.orderStatus '==' 'Paid'}}
<h2 class="text-success">Your payment has been successfully processed</h2>
<h2 class="text-success">{{ @root.__ "Your payment has been successfully processed" }}</h2>
{{else}}
<h2 class="text-danger">Your payment has failed. Please try again or contact us.</h2>
<h2 class="text-danger">{{ @root.__ "Your payment has failed. Please try again or contact us." }}</h2>
{{/ifCond}}
{{#if result}}
<div>
<p><strong>Order ID:</strong> {{result._id}}</p>
<p><strong>Payment ID:</strong> {{result.orderPaymentId}}</p>
<p><strong>{{ @root.__ "Order ID" }}:</strong> {{result._id}}</p>
<p><strong>{{ @root.__ "Payment ID" }}:</strong> {{result.orderPaymentId}}</p>
</div>
{{/if}}
{{#ifCond result.orderStatus '==' 'Paid'}}
<h3 class="text-warning">Please retain the details above as a reference of payment.</h3>
<h3 class="text-warning">{{ @root.__ "Please retain the details above as a reference of payment." }}</h3>
{{/ifCond}}
<a href="/" class="btn waves-effect waves-light black">Home</a>
</div>
</div>
</div>
</div>

View File

@ -6,7 +6,7 @@
<h1 class="col s12 m10 product-title">{{result.productTitle}}</h1>
<h4 class="col s12 m10 product-price">{{currencySymbol config.currencySymbol}}{{result.productPrice}}</h4>
{{#if productOptions}}
<h4 class="col s12 m10 product-option">Options</h4>
<h4 class="col s12 m10 product-option">{{ @root.__ "Options" }}</h4>
<div class="col s12 m10">
{{#each productOptions}}
{{#ifCond this.optType '==' "select"}}
@ -48,7 +48,7 @@
{{/ifCond}}
{{/if}}
<div class="col s10 productOptions">
<p class="product-option-text">Quantity</p>
<p class="product-option-text">{{ @root.__ "Quantity" }}</p>
<div class="input-group">
<span class="input-group-btn">
<button class="btn waves-effect waves-light black qty-btn-minus" type="button">-</button>
@ -63,12 +63,12 @@
</div>
{{#if result.productComment}}
<div class="col-md-10">
Leave a comment?
{{ @root.__ "Leave a comment?" }}
<textarea class="form-control" id="product_comment"></textarea>
</div>
{{/if}}
<div class="btnAddToCart">
<button class="btn waves-effect waves-light black col s10 product-add-to-cart" type="button">Add to cart</button>
<button class="btn waves-effect waves-light black col s10 product-add-to-cart" type="button">{{ @root.__ "Add to cart" }}</button>
</div>
<div class="col s10 body_text">
{{{productDescription}}}

View File

@ -6,26 +6,26 @@
<form method="post" id="edit_form" action="/admin/user/update" data-toggle="validator">
<input type="hidden" name="userId" value="{{user._id}}" />
<div class="form-group">
<label>Users name</label>
<label>{{ @root.__ "Users name" }}</label>
<input type="text" class="form-control" name="usersName" value="{{user.usersName}}" required>
</div>
<div class="form-group">
<label>User email</label>
<label>{{ @root.__ "User email" }}</label>
<input type="text" class="form-control" name="userEmail" value="{{user.userEmail}}" readonly>
</div>
<div class="form-group">
<label>User password {{#ifCond session.user '==' user.userEmail}}*{{/ifCond}}</label>
<label>{{ @root.__ "User password" }} {{#ifCond session.user '==' user.userEmail}}*{{/ifCond}}</label>
<input type="password" class="form-control" name="userPassword" {{#ifCond session.user '==' user.userEmail}}required{{/ifCond}}>
</div>
<div class="form-group">
<label>Password confirm {{#ifCond session.user '==' user.userEmail}}*{{/ifCond}}</label>
<label>{{ @root.__ "Password confirm" }} {{#ifCond session.user '==' user.userEmail}}*{{/ifCond}}</label>
<input type="password" data-validation-match-match="userPassword" data-validation-match-message="Password values to not match" class="form-control" name="frm_userPassword_confirm" {{#ifCond session.user '==' user.userEmail}}required{{/ifCond}}>
</div>
{{#isAnAdmin session.isAdmin}}
{{#ifCond session.user '!=' user.userEmail}}
<div class="checkbox">
<label>
<input name="user_admin" {{#checkedState user.isAdmin}}{{/checkedState}} type="checkbox"> User is admin?
<input name="user_admin" {{#checkedState user.isAdmin}}{{/checkedState}} type="checkbox"> {{ @root.__ "User is admin?" }}
</label>
</div>
{{/ifCond}}
@ -35,13 +35,13 @@
<div class="input-group">
<input type="text" class="form-control" id="apiKey" value="{{user.apiKey}}" aria-label="..." readonly>
<div class="input-group-btn">
<button id="btnGenerateAPIkey" class="btn btn-success">Generate</button>
<button id="btnGenerateAPIkey" class="btn btn-success">{{ @root.__ "Generate" }}</button>
</div>
</div>
</div><br/>
<div class="form-group">
<div class="pull-right">
<button type="submit" class="btn btn-success">Update</button>
<button type="submit" class="btn btn-success">{{ @root.__ "Update" }}</button>
</div>
</div>
</div>

View File

@ -2,27 +2,27 @@
<div class="col-lg-9">
<div class="row">
<div class="col-md-8">
<h2>New User</h2>
<h2>{{ @root.__ "New User" }}</h2>
<form method="post" id="edit_form" action="/admin/user/insert" data-toggle="validator">
<div class="form-group">
<label>Users name *</label>
<label>{{ @root.__ "Users name" }} *</label>
<input type="text" class="form-control" name="usersName" value="{{user.usersName}}" required>
</div>
<div class="form-group">
<label>User email *</label>
<label>{{ @root.__ "User email" }} *</label>
<input type="email" class="form-control" name="userEmail" value="{{user.userEmail}}" required>
</div>
<div class="form-group">
<label>User password *</label>
<label>{{ @root.__ "User password" }} *</label>
<input type="password" class="form-control" id="userPassword" name="userPassword" required>
</div>
<div class="form-group">
<label>Password confirm *</label>
<label>{{ @root.__ "Password confirm" }} *</label>
<input type="password" data-match="#userPassword" class="form-control" name="frm_userPassword_confirm" required>
</div>
<div class="form-group">
<div class="pull-right">
<button type="submit" class="btn btn-success">Create</button>
<button type="submit" class="btn btn-success">{{ @root.__ "Create" }}</button>
</div>
</div>
</div>

View File

@ -2,17 +2,17 @@
<div class="col-lg-9">
<div class="row">
<div class="col-md-8">
<h2>Users <span class="pull-right"><a href="/admin/user/new" class="btn btn-success btn-sm">New user</a></span></h2>
<h2>Users <span class="pull-right"><a href="/admin/user/new" class="btn btn-success btn-sm">{{ @root.__ "New user" }}</a></span></h2>
<ul class="list-group">
{{#each users}}
<li class="list-group-item">
<strong>User:</strong> {{this.usersName}} - ({{this.userEmail}})
<strong>{{ @root.__ "User" }}:</strong> {{this.usersName}} - ({{this.userEmail}})
<span class="pull-right">
<strong>Role: </strong>
<strong>{{ @root.__ "Role" }}: </strong>
{{#isAnAdmin this.isAdmin}}
<span>Admin</span>
{{else}}
<span>User</span>
<span>{{ @root.__ "User" }}</span>
{{/isAnAdmin}}
{{#isAnAdmin ../session.isAdmin}}
<a href="/admin/user/edit/{{this._id}}"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></a>