diff --git a/.eslintrc.js b/.eslintrc.js index 56f4da50..dabf8ae7 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -7,12 +7,12 @@ module.exports = { parserOptions: { parser: '@babel/eslint-parser', ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features - sourceType: 'module', // Allows for the use of imports + sourceType: 'module' // Allows for the use of imports }, env: { browser: true, - 'vue/setup-compiler-macros': true, + 'vue/setup-compiler-macros': true }, extends: [ @@ -26,7 +26,7 @@ module.exports = { // 'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability) // 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead) - 'standard', + 'standard' ], plugins: ['vue', 'prettier'], @@ -41,7 +41,7 @@ module.exports = { __QUASAR_SSR_PWA__: 'readonly', process: 'readonly', Capacitor: 'readonly', - chrome: 'readonly', + chrome: 'readonly' }, // add your custom rules here @@ -66,7 +66,7 @@ module.exports = { 'prefer-promise-reject-errors': 'off', semi: 'off', // allow debugger during development only - 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', + 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' }, overrides: [ { @@ -75,8 +75,8 @@ module.exports = { rules: { semi: 'off', indent: ['error', 4, { SwitchCase: 1 }], - 'space-before-function-paren': 'off', - }, - }, - ], + 'space-before-function-paren': 'off' + } + } + ] }; diff --git a/Jenkinsfile b/Jenkinsfile index 11b267b2..ef4c3583 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,34 +1,25 @@ #!/usr/bin/env groovy +def BRANCH_ENV = [ + test: 'test', + master: 'production' +] +def remote = [:] + +node { + stage('Setup') { + env.NODE_ENV = BRANCH_ENV[env.BRANCH_NAME] ?: 'dev' + + echo "NODE_NAME: ${env.NODE_NAME}" + echo "WORKSPACE: ${env.WORKSPACE}" + } +} pipeline { agent any environment { PROJECT_NAME = 'hedera-web' - STACK_NAME = "${env.PROJECT_NAME}-${env.BRANCH_NAME}" } stages { - stage('Checkout') { - steps { - script { - def packageJson = readJSON file: 'package.json' - env.VERSION = packageJson.version - - switch (env.BRANCH_NAME) { - case 'master': - env.NODE_ENV = 'production' - env.MAIN_REPLICAS = 3 - env.CRON_REPLICAS = 1 - break - case 'test': - env.NODE_ENV = 'test' - env.MAIN_REPLICAS = 1 - env.CRON_REPLICAS = 0 - break - } - } - setEnv() - } - } stage('Debuild') { when { anyOf { @@ -38,31 +29,28 @@ pipeline { } agent { docker { - image 'registry.verdnatura.es/debuild:2.21.3-vn2' + image 'registry.verdnatura.es/verdnatura/debuild:2.23.4-vn7' registryUrl 'https://registry.verdnatura.es/' registryCredentialsId 'docker-registry' - args '-v /mnt/appdata/reprepro:/reprepro' } } steps { sh 'debuild -us -uc -b' - sh 'vn-includedeb stretch' - } - } - stage('Container') { - when { - anyOf { - branch 'master' - branch 'test' + sh 'mkdir -p debuild' + sh 'mv ../hedera-web_* debuild' + + script { + def files = findFiles(glob: 'debuild/*.changes') + files.each { file -> env.CHANGES_FILE = file.name } + } + + configFileProvider([ + configFile(fileId: "dput.cf", variable: 'DPUT_CONFIG') + ]) { + sshagent(credentials: ['jenkins-agent']) { + sh 'dput --config "$DPUT_CONFIG" verdnatura "debuild/$CHANGES_FILE"' + } } - } - environment { - CREDS = credentials('docker-registry') - } - steps { - sh 'docker login --username $CREDS_USR --password $CREDS_PSW $REGISTRY' - sh 'docker-compose build --build-arg BUILD_ID=$BUILD_ID --parallel' - sh 'docker-compose push' } } stage('Deploy') { @@ -73,15 +61,41 @@ pipeline { } } environment { - DOCKER_HOST = "${env.SWARM_HOST}" + CREDS = credentials('docker-registry') + IMAGE = "$REGISTRY/verdnatura/hedera-web" } steps { - sh "docker stack deploy --with-registry-auth --compose-file docker-compose.yml ${env.STACK_NAME}" + script { + def packageJson = readJSON file: 'package.json' + env.VERSION = "${packageJson.version}" + env.TAG = "${packageJson.version}-build${env.BUILD_ID}" + } + + sh 'docker-compose build --build-arg BUILD_ID=$BUILD_ID --parallel' + sh 'docker login --username $CREDS_USR --password $CREDS_PSW $REGISTRY' + sh 'docker push $IMAGE:$TAG' + + script { + if (env.BRANCH_NAME == 'master') { + sh 'docker tag $IMAGE:$TAG $IMAGE:latest' + sh 'docker push $IMAGE:latest' + } + } + + withKubeConfig([ + serverUrl: "$KUBERNETES_API", + credentialsId: 'kubernetes', + namespace: 'salix' + ]) { + sh 'kubectl set image deployment/hedera-web-$BRANCH_NAME hedera-web-$BRANCH_NAME=$IMAGE:$TAG' + sh 'kubectl set image deployment/hedera-web-cron-$BRANCH_NAME hedera-web-cron-$BRANCH_NAME=$IMAGE:$TAG' + } } } } post { unsuccessful { + setEnv() sendEmail() } } diff --git a/README.md b/README.md index fee55494..c5032e41 100644 --- a/README.md +++ b/README.md @@ -5,17 +5,26 @@ Hedera is the main web page for Verdnatura. ## Getting Started Required dependencies. - * PHP >= 7.0 - * Node.js >= 8.0 + +- PHP >= 7.0 +- Node.js >= 8.0 Launch application for development. + ``` -$ npm run dev +$ npm run dev ``` +Launch project backend. + +``` +$ php -S 127.0.0.1:3002 -t . index.php + Run server side method from command line. ``` -$ php hedera-web.php -m method_path + +$ php hedera-web.php -m method_path + ``` ## Built with @@ -23,3 +32,4 @@ $ php hedera-web.php -m method_path * [Webpack](https://webpack.js.org/) * [MooTools](https://mootools.net/) * [TinyMCE](https://www.tinymce.com/) +``` diff --git a/package.json b/package.json index c84d82d6..9fbb260c 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,8 @@ "version": "22.48.2", "description": "Verdnatura web page", "license": "GPL-3.0", - "author": "Juan Ferrer Toribio ", + "productName": "Salix", + "author": "Verdnatura", "repository": { "type": "git", "url": "https://git.verdnatura.es/hedera-web" diff --git a/quasar.config.js b/quasar.config.js index b5b6d16b..0c26af27 100644 --- a/quasar.config.js +++ b/quasar.config.js @@ -8,249 +8,249 @@ // Configuration for your app // https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js -const ESLintPlugin = require('eslint-webpack-plugin') -const path = require('path') +const ESLintPlugin = require('eslint-webpack-plugin'); +const path = require('path'); -const { configure } = require('quasar/wrappers') +const { configure } = require('quasar/wrappers'); module.exports = configure(function (ctx) { - return { - // https://v2.quasar.dev/quasar-cli-webpack/supporting-ts - supportTS: false, + return { + // https://v2.quasar.dev/quasar-cli-webpack/supporting-ts + supportTS: false, - // https://v2.quasar.dev/quasar-cli-webpack/prefetch-feature - // preFetch: true, + // https://v2.quasar.dev/quasar-cli-webpack/prefetch-feature + // preFetch: true, - // app boot file (/src/boot) - // --> boot files are part of "main.js" - // https://v2.quasar.dev/quasar-cli-webpack/boot-files - boot: ['i18n', 'axios', 'error-handler', 'app'], + // app boot file (/src/boot) + // --> boot files are part of "main.js" + // https://v2.quasar.dev/quasar-cli-webpack/boot-files + boot: ['i18n', 'axios', 'error-handler', 'app'], - // https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-css - css: ['app.scss', 'width.scss', 'responsive.scss'], + // https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-css + css: ['app.scss', 'width.scss', 'responsive.scss'], - // https://github.com/quasarframework/quasar/tree/dev/extras - extras: [ - // 'ionicons-v4', - // 'mdi-v5', - // 'fontawesome-v6', - // 'eva-icons', - // 'themify', - // 'line-awesome', - // 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both! + // https://github.com/quasarframework/quasar/tree/dev/extras + extras: [ + // 'ionicons-v4', + // 'mdi-v5', + // 'fontawesome-v6', + // 'eva-icons', + // 'themify', + // 'line-awesome', + // 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both! - 'roboto-font', // optional, you are not bound to it - 'material-icons' // optional, you are not bound to it - ], + 'roboto-font', // optional, you are not bound to it + 'material-icons' // optional, you are not bound to it + ], - // Full list of options: https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-build - build: { - vueRouterMode: 'hash', // available values: 'hash', 'history' + // Full list of options: https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-build + build: { + vueRouterMode: 'hash', // available values: 'hash', 'history' - // transpile: false, - // publicPath: '/', + // transpile: false, + // publicPath: '/', - // Add dependencies for transpiling with Babel (Array of string/regex) - // (from node_modules, which are by default not transpiled). - // Applies only if "transpile" is set to true. - // transpileDependencies: [], + // Add dependencies for transpiling with Babel (Array of string/regex) + // (from node_modules, which are by default not transpiled). + // Applies only if "transpile" is set to true. + // transpileDependencies: [], - // rtl: true, // https://quasar.dev/options/rtl-support - // preloadChunks: true, - // showProgress: false, - // gzip: true, - // analyze: true, + // rtl: true, // https://quasar.dev/options/rtl-support + // preloadChunks: true, + // showProgress: false, + // gzip: true, + // analyze: true, - // Options below are automatically set depending on the env, set them if you want to override - // extractCSS: false, + // Options below are automatically set depending on the env, set them if you want to override + // extractCSS: false, - // https://v2.quasar.dev/quasar-cli-webpack/handling-webpack - // "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain + // https://v2.quasar.dev/quasar-cli-webpack/handling-webpack + // "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain - chainWebpack (chain) { - chain - .plugin('eslint-webpack-plugin') - .use(ESLintPlugin, [{ extensions: ['js', 'vue'] }]); + chainWebpack(chain) { + chain + .plugin('eslint-webpack-plugin') + .use(ESLintPlugin, [{ extensions: ['js', 'vue'] }]); - chain.module - .rule('i18n-resource') - .test(/\.(json5?|ya?ml)$/) - .include.add(path.resolve(__dirname, './src/i18n')) - .end() - .type('javascript/auto') - .use('i18n-resource') - .loader('@intlify/vue-i18n-loader'); - chain.module - .rule('i18n') - .resourceQuery(/blockType=i18n/) - .type('javascript/auto') - .use('i18n') - .loader('@intlify/vue-i18n-loader'); - } - }, + chain.module + .rule('i18n-resource') + .test(/\.(json5?|ya?ml)$/) + .include.add(path.resolve(__dirname, './src/i18n')) + .end() + .type('javascript/auto') + .use('i18n-resource') + .loader('@intlify/vue-i18n-loader'); + chain.module + .rule('i18n') + .resourceQuery(/blockType=i18n/) + .type('javascript/auto') + .use('i18n') + .loader('@intlify/vue-i18n-loader'); + } + }, - // Full list of options: https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-devServer - devServer: { - server: { - type: 'http' - }, - port: 8080, - open: false, - // static: __dirname, - headers: { 'Access-Control-Allow-Origin': '*' }, - // stats: { chunks: false }, - proxy: { - '/api': 'http://localhost:3000', - '/': { - target: 'http://localhost:3002', - bypass: req => (req.path !== '/' ? req.path : null) + // Full list of options: https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-devServer + devServer: { + server: { + type: 'http' + }, + port: 8080, + open: false, + // static: __dirname, + headers: { 'Access-Control-Allow-Origin': '*' }, + // stats: { chunks: false }, + proxy: { + '/api': 'http://localhost:3000', + '/': { + target: 'http://localhost:3002', + bypass: req => (req.path !== '/' ? req.path : null) + } + } + }, + + // https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-framework + framework: { + config: {}, + autoImportComponentCase: 'pascal', + // iconSet: 'material-icons', // Quasar icon set + // lang: 'en-US', // Quasar language pack + + // For special cases outside of where the auto-import strategy can have an impact + // (like functional components as one of the examples), + // you can manually specify Quasar components/directives to be available everywhere: + // + // components: [], + // directives: [], + + // Quasar plugins + plugins: ['Notify', 'Dialog'] + }, + + // animations: 'all', // --- includes all animations + // https://quasar.dev/options/animations + animations: [], + + // https://v2.quasar.dev/quasar-cli-webpack/developing-ssr/configuring-ssr + ssr: { + pwa: false, + + // manualStoreHydration: true, + // manualPostHydrationTrigger: true, + + prodPort: 3000, // The default port that the production server should use + // (gets superseded if process.env.PORT is specified at runtime) + + maxAge: 1000 * 60 * 60 * 24 * 30, + // Tell browser when a file from the server should expire from cache (in ms) + + chainWebpackWebserver(chain) { + chain + .plugin('eslint-webpack-plugin') + .use(ESLintPlugin, [{ extensions: ['js'] }]); + }, + + middlewares: [ + ctx.prod ? 'compression' : '', + 'render' // keep this as last one + ] + }, + + // https://v2.quasar.dev/quasar-cli-webpack/developing-pwa/configuring-pwa + pwa: { + workboxPluginMode: 'GenerateSW', // 'GenerateSW' or 'InjectManifest' + workboxOptions: {}, // only for GenerateSW + + // for the custom service worker ONLY (/src-pwa/custom-service-worker.[js|ts]) + // if using workbox in InjectManifest mode + + chainWebpackCustomSW(chain) { + chain + .plugin('eslint-webpack-plugin') + .use(ESLintPlugin, [{ extensions: ['js'] }]); + }, + + manifest: { + name: 'Hedera', + short_name: 'Hedera', + description: "Verdnatura's webshop", + display: 'standalone', + orientation: 'portrait', + background_color: '#ffffff', + theme_color: '#027be3', + icons: [ + { + src: 'icons/icon-128x128.png', + sizes: '128x128', + type: 'image/png' + }, + { + src: 'icons/icon-192x192.png', + sizes: '192x192', + type: 'image/png' + }, + { + src: 'icons/icon-256x256.png', + sizes: '256x256', + type: 'image/png' + }, + { + src: 'icons/icon-384x384.png', + sizes: '384x384', + type: 'image/png' + }, + { + src: 'icons/icon-512x512.png', + sizes: '512x512', + type: 'image/png' + } + ] + } + }, + + // Full list of options: https://v2.quasar.dev/quasar-cli-webpack/developing-cordova-apps/configuring-cordova + cordova: { + // noIosLegacyBuildFlag: true, // uncomment only if you know what you are doing + }, + + // Full list of options: https://v2.quasar.dev/quasar-cli-webpack/developing-capacitor-apps/configuring-capacitor + capacitor: { + hideSplashscreen: true + }, + + // Full list of options: https://v2.quasar.dev/quasar-cli-webpack/developing-electron-apps/configuring-electron + electron: { + bundler: 'packager', // 'packager' or 'builder' + + packager: { + // https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options + // OS X / Mac App Store + // appBundleId: '', + // appCategoryType: '', + // osxSign: '', + // protocol: 'myapp://path', + // Windows only + // win32metadata: { ... } + }, + + builder: { + // https://www.electron.build/configuration/configuration + + appId: 'hedera-web' + }, + + // "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain + + chainWebpackMain(chain) { + chain + .plugin('eslint-webpack-plugin') + .use(ESLintPlugin, [{ extensions: ['js'] }]); + }, + + chainWebpackPreload(chain) { + chain + .plugin('eslint-webpack-plugin') + .use(ESLintPlugin, [{ extensions: ['js'] }]); + } } - } - }, - - // https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-framework - framework: { - config: {}, - autoImportComponentCase: 'pascal', - // iconSet: 'material-icons', // Quasar icon set - // lang: 'en-US', // Quasar language pack - - // For special cases outside of where the auto-import strategy can have an impact - // (like functional components as one of the examples), - // you can manually specify Quasar components/directives to be available everywhere: - // - // components: [], - // directives: [], - - // Quasar plugins - plugins: ['Notify', 'Dialog'] - }, - - // animations: 'all', // --- includes all animations - // https://quasar.dev/options/animations - animations: [], - - // https://v2.quasar.dev/quasar-cli-webpack/developing-ssr/configuring-ssr - ssr: { - pwa: false, - - // manualStoreHydration: true, - // manualPostHydrationTrigger: true, - - prodPort: 3000, // The default port that the production server should use - // (gets superseded if process.env.PORT is specified at runtime) - - maxAge: 1000 * 60 * 60 * 24 * 30, - // Tell browser when a file from the server should expire from cache (in ms) - - chainWebpackWebserver (chain) { - chain - .plugin('eslint-webpack-plugin') - .use(ESLintPlugin, [{ extensions: ['js'] }]); - }, - - middlewares: [ - ctx.prod ? 'compression' : '', - 'render' // keep this as last one - ] - }, - - // https://v2.quasar.dev/quasar-cli-webpack/developing-pwa/configuring-pwa - pwa: { - workboxPluginMode: 'GenerateSW', // 'GenerateSW' or 'InjectManifest' - workboxOptions: {}, // only for GenerateSW - - // for the custom service worker ONLY (/src-pwa/custom-service-worker.[js|ts]) - // if using workbox in InjectManifest mode - - chainWebpackCustomSW (chain) { - chain - .plugin('eslint-webpack-plugin') - .use(ESLintPlugin, [{ extensions: ['js'] }]); - }, - - manifest: { - name: 'Hedera', - short_name: 'Hedera', - description: "Verdnatura's webshop", - display: 'standalone', - orientation: 'portrait', - background_color: '#ffffff', - theme_color: '#027be3', - icons: [ - { - src: 'icons/icon-128x128.png', - sizes: '128x128', - type: 'image/png' - }, - { - src: 'icons/icon-192x192.png', - sizes: '192x192', - type: 'image/png' - }, - { - src: 'icons/icon-256x256.png', - sizes: '256x256', - type: 'image/png' - }, - { - src: 'icons/icon-384x384.png', - sizes: '384x384', - type: 'image/png' - }, - { - src: 'icons/icon-512x512.png', - sizes: '512x512', - type: 'image/png' - } - ] - } - }, - - // Full list of options: https://v2.quasar.dev/quasar-cli-webpack/developing-cordova-apps/configuring-cordova - cordova: { - // noIosLegacyBuildFlag: true, // uncomment only if you know what you are doing - }, - - // Full list of options: https://v2.quasar.dev/quasar-cli-webpack/developing-capacitor-apps/configuring-capacitor - capacitor: { - hideSplashscreen: true - }, - - // Full list of options: https://v2.quasar.dev/quasar-cli-webpack/developing-electron-apps/configuring-electron - electron: { - bundler: 'packager', // 'packager' or 'builder' - - packager: { - // https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options - // OS X / Mac App Store - // appBundleId: '', - // appCategoryType: '', - // osxSign: '', - // protocol: 'myapp://path', - // Windows only - // win32metadata: { ... } - }, - - builder: { - // https://www.electron.build/configuration/configuration - - appId: 'hedera-web' - }, - - // "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain - - chainWebpackMain (chain) { - chain - .plugin('eslint-webpack-plugin') - .use(ESLintPlugin, [{ extensions: ['js'] }]); - }, - - chainWebpackPreload (chain) { - chain - .plugin('eslint-webpack-plugin') - .use(ESLintPlugin, [{ extensions: ['js'] }]); - } - } - }; -}) + }; +}); diff --git a/src/boot/i18n.js b/src/boot/i18n.js index f6e0703f..4072b024 100644 --- a/src/boot/i18n.js +++ b/src/boot/i18n.js @@ -3,12 +3,15 @@ import { createI18n } from 'vue-i18n'; import messages from 'src/i18n'; const i18n = createI18n({ - locale: 'es-ES', + locale: navigator.language || navigator.userLanguage, + fallbackLocale: 'en', globalInjection: true, + missingWarn: false, + fallbackWarn: false, + legacy: false, silentTranslationWarn: true, silentFallbackWarn: true, - messages, - legacy: false + messages }); export default boot(({ app }) => { diff --git a/src/components/ui/VnImg.vue b/src/components/ui/VnImg.vue new file mode 100644 index 00000000..f4e8a36c --- /dev/null +++ b/src/components/ui/VnImg.vue @@ -0,0 +1,66 @@ + + + + diff --git a/src/pages/Account/AddressList.vue b/src/pages/Account/AddressList.vue index 46c47aba..5d39dcda 100644 --- a/src/pages/Account/AddressList.vue +++ b/src/pages/Account/AddressList.vue @@ -71,7 +71,7 @@ const removeAddress = async id => { } ); getActiveAddresses(); - notify(t('defaultAddressModified'), 'positive'); + notify(t('dataSaved'), 'positive'); } catch (error) { console.error('Error removing address:', error); } diff --git a/src/pages/Cms/HomeView.vue b/src/pages/Cms/HomeView.vue new file mode 100644 index 00000000..971e1544 --- /dev/null +++ b/src/pages/Cms/HomeView.vue @@ -0,0 +1,87 @@ + + + + + + + +en-US: + startOrder: Start order +es-ES: + startOrder: Empezar pedido +ca-ES: + startOrder: Començar comanda +fr-FR: + startOrder: Lancer commande +pt-PT: + startOrder: Comece uma encomenda + diff --git a/src/router/routes.js b/src/router/routes.js index b8d46e0f..1ab82dcc 100644 --- a/src/router/routes.js +++ b/src/router/routes.js @@ -27,12 +27,12 @@ const routes = [ { name: '', path: '', - component: () => import('src/pages/Cms/Home.vue') + component: () => import('src/pages/Cms/HomeView.vue') }, { name: 'home', path: '/cms/home', - component: () => import('src/pages/Cms/Home.vue') + component: () => import('src/pages/Cms/HomeView.vue') }, { name: 'orders',