├── .env.example ├── .eslintrc ├── .gitignore ├── .prettierrc ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── babel.config.js ├── dist ├── css │ ├── app.8e4d25c3.css │ └── chunk-vendors.95db2415.css ├── favicon.ico ├── fonts │ ├── fa-brands-400.4b115e11.woff2 │ ├── fa-brands-400.b90365bc.woff │ ├── fa-brands-400.c39278f7.ttf │ ├── fa-brands-400.d9d17590.eot │ ├── fa-regular-400.414ff5da.eot │ ├── fa-regular-400.5dd3976c.woff │ ├── fa-regular-400.65779ebc.woff2 │ ├── fa-regular-400.f6c6f6c8.ttf │ ├── fa-solid-900.46280631.woff2 │ ├── fa-solid-900.61969d43.woff │ ├── fa-solid-900.b5596f4d.eot │ └── fa-solid-900.b70cea03.ttf ├── img │ ├── fa-brands-400.80533988.svg │ ├── fa-regular-400.e7e957c8.svg │ ├── fa-solid-900.82905d8d.svg │ └── logo.44914c2a.png ├── index.html ├── js │ ├── app.98c1abd1.js │ ├── app.98c1abd1.js.map │ ├── chunk-vendors.04cbc518.js │ └── chunk-vendors.04cbc518.js.map └── static │ ├── android-icon-144x144.png │ ├── android-icon-192x192.png │ ├── android-icon-36x36.png │ ├── android-icon-48x48.png │ ├── android-icon-72x72.png │ ├── android-icon-96x96.png │ ├── apple-icon-114x114.png │ ├── apple-icon-120x120.png │ ├── apple-icon-144x144.png │ ├── apple-icon-152x152.png │ ├── apple-icon-180x180.png │ ├── apple-icon-57x57.png │ ├── apple-icon-60x60.png │ ├── apple-icon-72x72.png │ ├── apple-icon-76x76.png │ ├── apple-icon-precomposed.png │ ├── apple-icon.png │ ├── browserconfig.xml │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon-96x96.png │ ├── favicon.ico │ ├── manifest.json │ ├── ms-icon-144x144.png │ ├── ms-icon-150x150.png │ ├── ms-icon-310x310.png │ └── ms-icon-70x70.png ├── docker └── nginx │ ├── default.conf │ └── vhost.conf ├── jest.config.js ├── jsconfig.json ├── package.json ├── public ├── favicon.ico ├── index.html └── static │ ├── android-icon-144x144.png │ ├── android-icon-192x192.png │ ├── android-icon-36x36.png │ ├── android-icon-48x48.png │ ├── android-icon-72x72.png │ ├── android-icon-96x96.png │ ├── apple-icon-114x114.png │ ├── apple-icon-120x120.png │ ├── apple-icon-144x144.png │ ├── apple-icon-152x152.png │ ├── apple-icon-180x180.png │ ├── apple-icon-57x57.png │ ├── apple-icon-60x60.png │ ├── apple-icon-72x72.png │ ├── apple-icon-76x76.png │ ├── apple-icon-precomposed.png │ ├── apple-icon.png │ ├── browserconfig.xml │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon-96x96.png │ ├── favicon.ico │ ├── manifest.json │ ├── ms-icon-144x144.png │ ├── ms-icon-150x150.png │ ├── ms-icon-310x310.png │ └── ms-icon-70x70.png ├── src ├── App.vue ├── assets │ ├── app.scss │ ├── css │ │ └── styles.css │ └── images │ │ └── logo.png ├── components │ ├── Alerts │ │ └── Error.vue │ ├── Auth │ │ └── Login.vue │ ├── Breadcrumbs.vue │ ├── Choice │ │ ├── Add.vue │ │ ├── Create.vue │ │ ├── Edit.vue │ │ ├── Form.vue │ │ ├── List.vue │ │ ├── Score.vue │ │ ├── ScoreForm.vue │ │ └── Table.vue │ ├── Footer.vue │ ├── Header.vue │ ├── Helpers │ │ └── Countdown.vue │ ├── Home.vue │ ├── Notification.vue │ ├── Order │ │ ├── Create.vue │ │ ├── Edit.vue │ │ ├── Form.vue │ │ ├── List.vue │ │ └── Table.vue │ ├── PageNotFound.vue │ ├── Print.vue │ ├── Product │ │ ├── CheckboxList.vue │ │ ├── Create.vue │ │ ├── Edit.vue │ │ ├── Form.vue │ │ ├── InputsList.vue │ │ ├── List.vue │ │ ├── Show.vue │ │ └── Table.vue │ ├── User │ │ ├── AutoComplete.vue │ │ ├── ChangePassword.vue │ │ ├── Create.vue │ │ ├── Edit.vue │ │ ├── Form.vue │ │ ├── List.vue │ │ ├── Profile.vue │ │ └── Table.vue │ └── Vendor │ │ ├── Create.vue │ │ ├── Edit.vue │ │ ├── Form.vue │ │ ├── List.vue │ │ └── Table.vue ├── config │ ├── client.js │ ├── i18n.js │ ├── router.js │ └── store.js ├── filters │ └── index.js ├── helper │ └── date.helper.js ├── i18n │ ├── en.js │ ├── index.js │ └── pl.js ├── main.js ├── security │ ├── auth.js │ └── guard.js └── services │ ├── api.service.js │ ├── auth.service.js │ ├── choice.service.js │ ├── order.service.js │ ├── product.service.js │ ├── user.service.js │ └── vendor.service.js ├── tests └── helper │ └── date.spec.js ├── vue.config.js └── yarn.lock /.env.example: -------------------------------------------------------------------------------- 1 | #The VUE_APP_ prefix is important here, and variales without that prefix won't be available in your app. 2 | VUE_APP_API_URL=http://forfeater.com:3000 3 | VUE_APP_LOCALE='en' -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "env": { 4 | "node": true, 5 | "jest": true 6 | }, 7 | "extends": ["plugin:vue/essential", "plugin:prettier/recommended", "eslint:recommended"], 8 | "rules": { 9 | "jest/no-disabled-tests": "warn", 10 | "jest/no-focused-tests": "error", 11 | "jest/no-identical-title": "error", 12 | "jest/prefer-to-have-length": "warn", 13 | "jest/valid-expect": "error" 14 | }, 15 | "parserOptions": { 16 | "parser": "babel-eslint" 17 | }, 18 | "plugins": ["jest", "prettier"], 19 | "settings": { 20 | "import/resolver": "webpack" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | 4 | package-lock.json 5 | 6 | # local env files 7 | .env 8 | .env.local 9 | .env.*.local 10 | 11 | # Log files 12 | npm-debug.log* 13 | yarn-debug.log* 14 | yarn-error.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw* 24 | /out 25 | 26 | # jest testing framework 27 | /coverage 28 | 29 | 30 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 140, 3 | "singleQuote": true 4 | } 5 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # production stage 2 | FROM nginx:1.13.12-alpine as production-stage 3 | COPY /docker/nginx/default.conf /etc/nginx/conf.d/default.conf 4 | COPY ./dist /usr/share/nginx/html 5 | EXPOSE 80 6 | CMD ["nginx", "-g", "daemon off;"] -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Sofware Brothers 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | docker-build: 2 | docker build -t forfeater-vue . 3 | 4 | docker-run: 5 | docker run -itd -p 80:80 --rm --name forfeater-vue forfeater-vue 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # forfeater-vue 2 | 3 | # Yarn (without docker) 4 | 5 | ## Project setup 6 | ``` 7 | yarn install 8 | ``` 9 | 10 | ### Compiles and hot-reloads for development 11 | ``` 12 | yarn run serve -w 13 | ``` 14 | 15 | ### Compiles and minifies for production 16 | ``` 17 | yarn run build 18 | ``` 19 | 20 | ### Lints and fixes files 21 | ``` 22 | yarn run lint 23 | ``` 24 | 25 | # Docker 26 | ``` 27 | docker build -t forfeater-vue . 28 | docker run -itd -p 80:80 --rm --name forfeater-vue forfeater-vue 29 | ``` 30 | 31 | ## License 32 | 33 | forfeater is Copyright © 2018 SoftwareBrothers.co. It is free software, and may be redistributed under the terms specified in the [LICENSE](LICENSE) file. 34 | 35 | ## About SoftwareBrothers.co 36 | 37 | 38 | 39 | 40 | We are a software company who provides web and mobile development and UX/UI services, friendly team that helps clients from all over the world to transform their businesses and create astonishing products. 41 | 42 | * We are available to [hire](https://softwarebrothers.co/contact). 43 | * If you want to work for us - checkout the [career page](https://softwarebrothers.co/career). 44 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app', 4 | [ 5 | '@babel/preset-env', 6 | { 7 | targets: { 8 | node: 'current' 9 | } 10 | } 11 | ] 12 | ] 13 | }; 14 | -------------------------------------------------------------------------------- /dist/css/app.8e4d25c3.css: -------------------------------------------------------------------------------- 1 | .product-input-list[data-v-3f273ad6]{word-wrap:break-word;overflow:auto}.autocomplete{position:relative;width:130px}.autocomplete-results{padding:0;margin:0;border:1px solid #eee;height:auto;overflow:auto}.autocomplete-result{list-style:none;text-align:left;padding:4px 2px;cursor:pointer}.autocomplete-result:hover{background-color:orange;color:#fff}.autocomplete-error{color:red}.no-active[data-v-1e1f109f]{color:red;opacity:.5}@page{margin:0}button svg[data-v-51b9ebcb]{margin-left:.5rem}@media print{.VueTables__search{display:none!important}.VueTables__table td:nth-child(4),.VueTables__table td:nth-child(5),.VueTables__table th:nth-child(4),.VueTables__table th:nth-child(5){display:none}}#logo[data-v-46c90655]{height:50px;width:auto}.navbar-dark .navbar-nav .router-link-active[data-v-46c90655]{color:#fff}.nav-user[data-v-46c90655]{display:inline;margin-right:10px;color:#fff}.nav-user a[data-v-46c90655]{display:inline;color:#fff;padding:0}header[data-v-46c90655]{margin-bottom:2rem}html{position:relative;min-height:100%}body{margin-bottom:60px}.footer{position:absolute;bottom:0;width:100%;height:60px;line-height:60px;color:#fff;background-color:orange}body>.container{padding:60px 15px 0}.footer>.container{padding-right:15px;padding-left:15px}main{margin-top:1rem;margin-bottom:60px;padding-bottom:50px}code{font-size:80%}li a{color:green}.navbar{background-color:orange}.navbar-logo{height:40px;width:auto;margin:0 10px 0 0}.jumbotron{background-color:#fec}@media (min-width:576px){.jumbotron{padding:1rem}}.btn-action{padding:.5rem}.p-0{padding:0}.btn-warning.col-white,.btn-warning.col-white:active,.btn-warning.col-white:disabled,.btn-warning.col-white:focus,.btn-warning.col-white:hover,.btn-warning.col-white:visited,.col-white{color:#fff}.btn-custom{max-width:200px;margin:0 0 .5rem 0}.breadcrumb.breadcrumb{background-color:#eee8aa}.breadcrumb-item.active{color:#2e8b57}.message .media,.notification .media{padding-top:0;border:0}.notification>.delete{right:.5rem!important;top:.5rem!important}@-webkit-keyframes spinAround{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spinAround{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.button,.delete{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.block:not(:last-child),.highlight:not(:last-child),.notification:not(:last-child){margin-bottom:1.5rem}.delete{-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,.2);border:none;border-radius:290486px;cursor:pointer;pointer-events:auto;display:inline-block;-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0;font-size:0;height:20px;max-height:20px;max-width:20px;min-height:20px;min-width:20px;outline:none;position:relative;vertical-align:top;width:20px}.delete:after,.delete:before{background-color:#fff;content:"";display:block;left:50%;position:absolute;top:50%;-webkit-transform:translateX(-50%) translateY(-50%) rotate(45deg);transform:translateX(-50%) translateY(-50%) rotate(45deg);-webkit-transform-origin:center center;transform-origin:center center}.delete:before{height:2px;width:50%}.delete:after{height:50%;width:2px}.delete:focus,.delete:hover{background-color:rgba(10,10,10,.3)}.delete:active{background-color:rgba(10,10,10,.4)}.is-small.delete{height:16px;max-height:16px;max-width:16px;min-height:16px;min-width:16px;width:16px}.is-medium.delete{height:24px;max-height:24px;max-width:24px;min-height:24px;min-width:24px;width:24px}.is-large.delete{height:32px;max-height:32px;max-width:32px;min-height:32px;min-width:32px;width:32px}.button.is-loading:after,.loader{-webkit-animation:spinAround .5s linear infinite;animation:spinAround .5s linear infinite;border:2px solid #dbdbdb;border-radius:290486px;border-right-color:transparent;border-top-color:transparent;content:"";display:block;height:1em;position:relative;width:1em}.button{-moz-appearance:none;-webkit-appearance:none;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:none;box-shadow:none;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;font-size:1rem;height:2.25em;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;line-height:1.5;padding-left:calc(.625em - 1px);padding-right:calc(.625em - 1px);position:relative;vertical-align:top}.button:active,.button:focus,.is-active.button,.is-focused.button{outline:none}.button[disabled],fieldset[disabled] .button{cursor:not-allowed}.button{background-color:#fff;border-color:#dbdbdb;border-width:1px;color:#363636;cursor:pointer;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;padding-bottom:calc(.375em - 1px);padding-left:.75em;padding-right:.75em;padding-top:calc(.375em - 1px);text-align:center;white-space:nowrap}.button strong{color:inherit}.button .icon,.button .icon.is-large,.button .icon.is-medium,.button .icon.is-small{height:1.5em;width:1.5em}.button .icon:first-child:not(:last-child){margin-left:calc(-.375em - 1px);margin-right:.1875em}.button .icon:last-child:not(:first-child){margin-left:.1875em;margin-right:calc(-.375em - 1px)}.button .icon:first-child:last-child{margin-left:calc(-.375em - 1px);margin-right:calc(-.375em - 1px)}.button.is-hovered,.button:hover{border-color:#b5b5b5;color:#363636}.button.is-focused,.button:focus{border-color:#3273dc;color:#363636}.button.is-focused:not(:active),.button:focus:not(:active){-webkit-box-shadow:0 0 0 .125em rgba(50,115,220,.25);box-shadow:0 0 0 .125em rgba(50,115,220,.25)}.button.is-active,.button:active{border-color:#4a4a4a;color:#363636}.button.is-text{background-color:transparent;border-color:transparent;color:#4a4a4a;text-decoration:underline}.button.is-text.is-focused,.button.is-text.is-hovered,.button.is-text:focus,.button.is-text:hover{background-color:#f5f5f5;color:#363636}.button.is-text.is-active,.button.is-text:active{background-color:#e8e8e8;color:#363636}.button.is-text[disabled],fieldset[disabled] .button.is-text{background-color:transparent;border-color:transparent;-webkit-box-shadow:none;box-shadow:none}.button.is-white{background-color:#fff;border-color:transparent;color:#0a0a0a}.button.is-white.is-hovered,.button.is-white:hover{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}.button.is-white.is-focused,.button.is-white:focus{border-color:transparent;color:#0a0a0a}.button.is-white.is-focused:not(:active),.button.is-white:focus:not(:active){-webkit-box-shadow:0 0 0 .125em hsla(0,0%,100%,.25);box-shadow:0 0 0 .125em hsla(0,0%,100%,.25)}.button.is-white.is-active,.button.is-white:active{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}.button.is-white[disabled],fieldset[disabled] .button.is-white{background-color:#fff;border-color:transparent;-webkit-box-shadow:none;box-shadow:none}.button.is-white.is-inverted{background-color:#0a0a0a;color:#fff}.button.is-white.is-inverted:hover{background-color:#000}.button.is-white.is-inverted[disabled],fieldset[disabled] .button.is-white.is-inverted{background-color:#0a0a0a;border-color:transparent;-webkit-box-shadow:none;box-shadow:none;color:#fff}.button.is-white.is-loading:after{border-color:transparent transparent #0a0a0a #0a0a0a!important}.button.is-white.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-white.is-outlined:focus,.button.is-white.is-outlined:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}.button.is-white.is-outlined.is-loading:after{border-color:transparent transparent #fff #fff!important}.button.is-white.is-outlined[disabled],fieldset[disabled] .button.is-white.is-outlined{background-color:transparent;border-color:#fff;-webkit-box-shadow:none;box-shadow:none;color:#fff}.button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}.button.is-white.is-inverted.is-outlined:focus,.button.is-white.is-inverted.is-outlined:hover{background-color:#0a0a0a;color:#fff}.button.is-white.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;-webkit-box-shadow:none;box-shadow:none;color:#0a0a0a}.button.is-black{background-color:#0a0a0a;border-color:transparent;color:#fff}.button.is-black.is-hovered,.button.is-black:hover{background-color:#040404;border-color:transparent;color:#fff}.button.is-black.is-focused,.button.is-black:focus{border-color:transparent;color:#fff}.button.is-black.is-focused:not(:active),.button.is-black:focus:not(:active){-webkit-box-shadow:0 0 0 .125em rgba(10,10,10,.25);box-shadow:0 0 0 .125em rgba(10,10,10,.25)}.button.is-black.is-active,.button.is-black:active{background-color:#000;border-color:transparent;color:#fff}.button.is-black[disabled],fieldset[disabled] .button.is-black{background-color:#0a0a0a;border-color:transparent;-webkit-box-shadow:none;box-shadow:none}.button.is-black.is-inverted{background-color:#fff;color:#0a0a0a}.button.is-black.is-inverted:hover{background-color:#f2f2f2}.button.is-black.is-inverted[disabled],fieldset[disabled] .button.is-black.is-inverted{background-color:#fff;border-color:transparent;-webkit-box-shadow:none;box-shadow:none;color:#0a0a0a}.button.is-black.is-loading:after{border-color:transparent transparent #fff #fff!important}.button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}.button.is-black.is-outlined:focus,.button.is-black.is-outlined:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.button.is-black.is-outlined.is-loading:after{border-color:transparent transparent #0a0a0a #0a0a0a!important}.button.is-black.is-outlined[disabled],fieldset[disabled] .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;-webkit-box-shadow:none;box-shadow:none;color:#0a0a0a}.button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-black.is-inverted.is-outlined:focus,.button.is-black.is-inverted.is-outlined:hover{background-color:#fff;color:#0a0a0a}.button.is-black.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;-webkit-box-shadow:none;box-shadow:none;color:#fff}.button.is-light{background-color:#f5f5f5;border-color:transparent;color:#363636}.button.is-light.is-hovered,.button.is-light:hover{background-color:#eee;border-color:transparent;color:#363636}.button.is-light.is-focused,.button.is-light:focus{border-color:transparent;color:#363636}.button.is-light.is-focused:not(:active),.button.is-light:focus:not(:active){-webkit-box-shadow:0 0 0 .125em hsla(0,0%,96.1%,.25);box-shadow:0 0 0 .125em hsla(0,0%,96.1%,.25)}.button.is-light.is-active,.button.is-light:active{background-color:#e8e8e8;border-color:transparent;color:#363636}.button.is-light[disabled],fieldset[disabled] .button.is-light{background-color:#f5f5f5;border-color:transparent;-webkit-box-shadow:none;box-shadow:none}.button.is-light.is-inverted{background-color:#363636;color:#f5f5f5}.button.is-light.is-inverted:hover{background-color:#292929}.button.is-light.is-inverted[disabled],fieldset[disabled] .button.is-light.is-inverted{background-color:#363636;border-color:transparent;-webkit-box-shadow:none;box-shadow:none;color:#f5f5f5}.button.is-light.is-loading:after{border-color:transparent transparent #363636 #363636!important}.button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;color:#f5f5f5}.button.is-light.is-outlined:focus,.button.is-light.is-outlined:hover{background-color:#f5f5f5;border-color:#f5f5f5;color:#363636}.button.is-light.is-outlined.is-loading:after{border-color:transparent transparent #f5f5f5 #f5f5f5!important}.button.is-light.is-outlined[disabled],fieldset[disabled] .button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;-webkit-box-shadow:none;box-shadow:none;color:#f5f5f5}.button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:#363636;color:#363636}.button.is-light.is-inverted.is-outlined:focus,.button.is-light.is-inverted.is-outlined:hover{background-color:#363636;color:#f5f5f5}.button.is-light.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:#363636;-webkit-box-shadow:none;box-shadow:none;color:#363636}.button.is-dark{background-color:#363636;border-color:transparent;color:#f5f5f5}.button.is-dark.is-hovered,.button.is-dark:hover{background-color:#2f2f2f;border-color:transparent;color:#f5f5f5}.button.is-dark.is-focused,.button.is-dark:focus{border-color:transparent;color:#f5f5f5}.button.is-dark.is-focused:not(:active),.button.is-dark:focus:not(:active){-webkit-box-shadow:0 0 0 .125em rgba(54,54,54,.25);box-shadow:0 0 0 .125em rgba(54,54,54,.25)}.button.is-dark.is-active,.button.is-dark:active{background-color:#292929;border-color:transparent;color:#f5f5f5}.button.is-dark[disabled],fieldset[disabled] .button.is-dark{background-color:#363636;border-color:transparent;-webkit-box-shadow:none;box-shadow:none}.button.is-dark.is-inverted{background-color:#f5f5f5;color:#363636}.button.is-dark.is-inverted:hover{background-color:#e8e8e8}.button.is-dark.is-inverted[disabled],fieldset[disabled] .button.is-dark.is-inverted{background-color:#f5f5f5;border-color:transparent;-webkit-box-shadow:none;box-shadow:none;color:#363636}.button.is-dark.is-loading:after{border-color:transparent transparent #f5f5f5 #f5f5f5!important}.button.is-dark.is-outlined{background-color:transparent;border-color:#363636;color:#363636}.button.is-dark.is-outlined:focus,.button.is-dark.is-outlined:hover{background-color:#363636;border-color:#363636;color:#f5f5f5}.button.is-dark.is-outlined.is-loading:after{border-color:transparent transparent #363636 #363636!important}.button.is-dark.is-outlined[disabled],fieldset[disabled] .button.is-dark.is-outlined{background-color:transparent;border-color:#363636;-webkit-box-shadow:none;box-shadow:none;color:#363636}.button.is-dark.is-inverted.is-outlined{background-color:transparent;border-color:#f5f5f5;color:#f5f5f5}.button.is-dark.is-inverted.is-outlined:focus,.button.is-dark.is-inverted.is-outlined:hover{background-color:#f5f5f5;color:#363636}.button.is-dark.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-dark.is-inverted.is-outlined{background-color:transparent;border-color:#f5f5f5;-webkit-box-shadow:none;box-shadow:none;color:#f5f5f5}.button.is-primary{background-color:#00d1b2;border-color:transparent;color:#fff}.button.is-primary.is-hovered,.button.is-primary:hover{background-color:#00c4a7;border-color:transparent;color:#fff}.button.is-primary.is-focused,.button.is-primary:focus{border-color:transparent;color:#fff}.button.is-primary.is-focused:not(:active),.button.is-primary:focus:not(:active){-webkit-box-shadow:0 0 0 .125em rgba(0,209,178,.25);box-shadow:0 0 0 .125em rgba(0,209,178,.25)}.button.is-primary.is-active,.button.is-primary:active{background-color:#00b89c;border-color:transparent;color:#fff}.button.is-primary[disabled],fieldset[disabled] .button.is-primary{background-color:#00d1b2;border-color:transparent;-webkit-box-shadow:none;box-shadow:none}.button.is-primary.is-inverted{background-color:#fff;color:#00d1b2}.button.is-primary.is-inverted:hover{background-color:#f2f2f2}.button.is-primary.is-inverted[disabled],fieldset[disabled] .button.is-primary.is-inverted{background-color:#fff;border-color:transparent;-webkit-box-shadow:none;box-shadow:none;color:#00d1b2}.button.is-primary.is-loading:after{border-color:transparent transparent #fff #fff!important}.button.is-primary.is-outlined{background-color:transparent;border-color:#00d1b2;color:#00d1b2}.button.is-primary.is-outlined:focus,.button.is-primary.is-outlined:hover{background-color:#00d1b2;border-color:#00d1b2;color:#fff}.button.is-primary.is-outlined.is-loading:after{border-color:transparent transparent #00d1b2 #00d1b2!important}.button.is-primary.is-outlined[disabled],fieldset[disabled] .button.is-primary.is-outlined{background-color:transparent;border-color:#00d1b2;-webkit-box-shadow:none;box-shadow:none;color:#00d1b2}.button.is-primary.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-primary.is-inverted.is-outlined:focus,.button.is-primary.is-inverted.is-outlined:hover{background-color:#fff;color:#00d1b2}.button.is-primary.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-primary.is-inverted.is-outlined{background-color:transparent;border-color:#fff;-webkit-box-shadow:none;box-shadow:none;color:#fff}.button.is-link{background-color:#3273dc;border-color:transparent;color:#fff}.button.is-link.is-hovered,.button.is-link:hover{background-color:#276cda;border-color:transparent;color:#fff}.button.is-link.is-focused,.button.is-link:focus{border-color:transparent;color:#fff}.button.is-link.is-focused:not(:active),.button.is-link:focus:not(:active){-webkit-box-shadow:0 0 0 .125em rgba(50,115,220,.25);box-shadow:0 0 0 .125em rgba(50,115,220,.25)}.button.is-link.is-active,.button.is-link:active{background-color:#2366d1;border-color:transparent;color:#fff}.button.is-link[disabled],fieldset[disabled] .button.is-link{background-color:#3273dc;border-color:transparent;-webkit-box-shadow:none;box-shadow:none}.button.is-link.is-inverted{background-color:#fff;color:#3273dc}.button.is-link.is-inverted:hover{background-color:#f2f2f2}.button.is-link.is-inverted[disabled],fieldset[disabled] .button.is-link.is-inverted{background-color:#fff;border-color:transparent;-webkit-box-shadow:none;box-shadow:none;color:#3273dc}.button.is-link.is-loading:after{border-color:transparent transparent #fff #fff!important}.button.is-link.is-outlined{background-color:transparent;border-color:#3273dc;color:#3273dc}.button.is-link.is-outlined:focus,.button.is-link.is-outlined:hover{background-color:#3273dc;border-color:#3273dc;color:#fff}.button.is-link.is-outlined.is-loading:after{border-color:transparent transparent #3273dc #3273dc!important}.button.is-link.is-outlined[disabled],fieldset[disabled] .button.is-link.is-outlined{background-color:transparent;border-color:#3273dc;-webkit-box-shadow:none;box-shadow:none;color:#3273dc}.button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-link.is-inverted.is-outlined:focus,.button.is-link.is-inverted.is-outlined:hover{background-color:#fff;color:#3273dc}.button.is-link.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;-webkit-box-shadow:none;box-shadow:none;color:#fff}.button.is-info{background-color:#209cee;border-color:transparent;color:#fff}.button.is-info.is-hovered,.button.is-info:hover{background-color:#1496ed;border-color:transparent;color:#fff}.button.is-info.is-focused,.button.is-info:focus{border-color:transparent;color:#fff}.button.is-info.is-focused:not(:active),.button.is-info:focus:not(:active){-webkit-box-shadow:0 0 0 .125em rgba(32,156,238,.25);box-shadow:0 0 0 .125em rgba(32,156,238,.25)}.button.is-info.is-active,.button.is-info:active{background-color:#118fe4;border-color:transparent;color:#fff}.button.is-info[disabled],fieldset[disabled] .button.is-info{background-color:#209cee;border-color:transparent;-webkit-box-shadow:none;box-shadow:none}.button.is-info.is-inverted{background-color:#fff;color:#209cee}.button.is-info.is-inverted:hover{background-color:#f2f2f2}.button.is-info.is-inverted[disabled],fieldset[disabled] .button.is-info.is-inverted{background-color:#fff;border-color:transparent;-webkit-box-shadow:none;box-shadow:none;color:#209cee}.button.is-info.is-loading:after{border-color:transparent transparent #fff #fff!important}.button.is-info.is-outlined{background-color:transparent;border-color:#209cee;color:#209cee}.button.is-info.is-outlined:focus,.button.is-info.is-outlined:hover{background-color:#209cee;border-color:#209cee;color:#fff}.button.is-info.is-outlined.is-loading:after{border-color:transparent transparent #209cee #209cee!important}.button.is-info.is-outlined[disabled],fieldset[disabled] .button.is-info.is-outlined{background-color:transparent;border-color:#209cee;-webkit-box-shadow:none;box-shadow:none;color:#209cee}.button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-info.is-inverted.is-outlined:focus,.button.is-info.is-inverted.is-outlined:hover{background-color:#fff;color:#209cee}.button.is-info.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;-webkit-box-shadow:none;box-shadow:none;color:#fff}.button.is-success{background-color:#23d160;border-color:transparent;color:#fff}.button.is-success.is-hovered,.button.is-success:hover{background-color:#22c65b;border-color:transparent;color:#fff}.button.is-success.is-focused,.button.is-success:focus{border-color:transparent;color:#fff}.button.is-success.is-focused:not(:active),.button.is-success:focus:not(:active){-webkit-box-shadow:0 0 0 .125em rgba(35,209,96,.25);box-shadow:0 0 0 .125em rgba(35,209,96,.25)}.button.is-success.is-active,.button.is-success:active{background-color:#20bc56;border-color:transparent;color:#fff}.button.is-success[disabled],fieldset[disabled] .button.is-success{background-color:#23d160;border-color:transparent;-webkit-box-shadow:none;box-shadow:none}.button.is-success.is-inverted{background-color:#fff;color:#23d160}.button.is-success.is-inverted:hover{background-color:#f2f2f2}.button.is-success.is-inverted[disabled],fieldset[disabled] .button.is-success.is-inverted{background-color:#fff;border-color:transparent;-webkit-box-shadow:none;box-shadow:none;color:#23d160}.button.is-success.is-loading:after{border-color:transparent transparent #fff #fff!important}.button.is-success.is-outlined{background-color:transparent;border-color:#23d160;color:#23d160}.button.is-success.is-outlined:focus,.button.is-success.is-outlined:hover{background-color:#23d160;border-color:#23d160;color:#fff}.button.is-success.is-outlined.is-loading:after{border-color:transparent transparent #23d160 #23d160!important}.button.is-success.is-outlined[disabled],fieldset[disabled] .button.is-success.is-outlined{background-color:transparent;border-color:#23d160;-webkit-box-shadow:none;box-shadow:none;color:#23d160}.button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-success.is-inverted.is-outlined:focus,.button.is-success.is-inverted.is-outlined:hover{background-color:#fff;color:#23d160}.button.is-success.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;-webkit-box-shadow:none;box-shadow:none;color:#fff}.button.is-warning{background-color:#ffdd57;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning.is-hovered,.button.is-warning:hover{background-color:#ffdb4a;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning.is-focused,.button.is-warning:focus{border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning.is-focused:not(:active),.button.is-warning:focus:not(:active){-webkit-box-shadow:0 0 0 .125em rgba(255,221,87,.25);box-shadow:0 0 0 .125em rgba(255,221,87,.25)}.button.is-warning.is-active,.button.is-warning:active{background-color:#ffd83d;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning[disabled],fieldset[disabled] .button.is-warning{background-color:#ffdd57;border-color:transparent;-webkit-box-shadow:none;box-shadow:none}.button.is-warning.is-inverted{color:#ffdd57}.button.is-warning.is-inverted,.button.is-warning.is-inverted:hover{background-color:rgba(0,0,0,.7)}.button.is-warning.is-inverted[disabled],fieldset[disabled] .button.is-warning.is-inverted{background-color:rgba(0,0,0,.7);border-color:transparent;-webkit-box-shadow:none;box-shadow:none;color:#ffdd57}.button.is-warning.is-loading:after{border-color:transparent transparent rgba(0,0,0,.7) rgba(0,0,0,.7)!important}.button.is-warning.is-outlined{background-color:transparent;border-color:#ffdd57;color:#ffdd57}.button.is-warning.is-outlined:focus,.button.is-warning.is-outlined:hover{background-color:#ffdd57;border-color:#ffdd57;color:rgba(0,0,0,.7)}.button.is-warning.is-outlined.is-loading:after{border-color:transparent transparent #ffdd57 #ffdd57!important}.button.is-warning.is-outlined[disabled],fieldset[disabled] .button.is-warning.is-outlined{background-color:transparent;border-color:#ffdd57;-webkit-box-shadow:none;box-shadow:none;color:#ffdd57}.button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,.7);color:rgba(0,0,0,.7)}.button.is-warning.is-inverted.is-outlined:focus,.button.is-warning.is-inverted.is-outlined:hover{background-color:rgba(0,0,0,.7);color:#ffdd57}.button.is-warning.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,.7);-webkit-box-shadow:none;box-shadow:none;color:rgba(0,0,0,.7)}.button.is-danger{background-color:#ff3860;border-color:transparent;color:#fff}.button.is-danger.is-hovered,.button.is-danger:hover{background-color:#ff2b56;border-color:transparent;color:#fff}.button.is-danger.is-focused,.button.is-danger:focus{border-color:transparent;color:#fff}.button.is-danger.is-focused:not(:active),.button.is-danger:focus:not(:active){-webkit-box-shadow:0 0 0 .125em rgba(255,56,96,.25);box-shadow:0 0 0 .125em rgba(255,56,96,.25)}.button.is-danger.is-active,.button.is-danger:active{background-color:#ff1f4b;border-color:transparent;color:#fff}.button.is-danger[disabled],fieldset[disabled] .button.is-danger{background-color:#ff3860;border-color:transparent;-webkit-box-shadow:none;box-shadow:none}.button.is-danger.is-inverted{background-color:#fff;color:#ff3860}.button.is-danger.is-inverted:hover{background-color:#f2f2f2}.button.is-danger.is-inverted[disabled],fieldset[disabled] .button.is-danger.is-inverted{background-color:#fff;border-color:transparent;-webkit-box-shadow:none;box-shadow:none;color:#ff3860}.button.is-danger.is-loading:after{border-color:transparent transparent #fff #fff!important}.button.is-danger.is-outlined{background-color:transparent;border-color:#ff3860;color:#ff3860}.button.is-danger.is-outlined:focus,.button.is-danger.is-outlined:hover{background-color:#ff3860;border-color:#ff3860;color:#fff}.button.is-danger.is-outlined.is-loading:after{border-color:transparent transparent #ff3860 #ff3860!important}.button.is-danger.is-outlined[disabled],fieldset[disabled] .button.is-danger.is-outlined{background-color:transparent;border-color:#ff3860;-webkit-box-shadow:none;box-shadow:none;color:#ff3860}.button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-danger.is-inverted.is-outlined:focus,.button.is-danger.is-inverted.is-outlined:hover{background-color:#fff;color:#ff3860}.button.is-danger.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;-webkit-box-shadow:none;box-shadow:none;color:#fff}.button.is-small{border-radius:2px;font-size:.75rem}.button.is-normal{font-size:1rem}.button.is-medium{font-size:1.25rem}.button.is-large{font-size:1.5rem}.button[disabled],fieldset[disabled] .button{background-color:#fff;border-color:#dbdbdb;-webkit-box-shadow:none;box-shadow:none;opacity:.5}.button.is-fullwidth{display:-webkit-box;display:-ms-flexbox;display:flex;width:100%}.button.is-loading{color:transparent!important;pointer-events:none}.button.is-loading:after{position:absolute;left:calc(50% - .5em);top:calc(50% - .5em);position:absolute!important}.button.is-static{background-color:#f5f5f5;border-color:#dbdbdb;color:#7a7a7a;-webkit-box-shadow:none;box-shadow:none;pointer-events:none}.button.is-rounded{border-radius:290486px;padding-left:1em;padding-right:1em}.buttons{-webkit-box-align:center;-ms-flex-align:center;align-items:center;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.buttons .button{margin-bottom:.5rem}.buttons .button:not(:last-child):not(.is-fullwidth){margin-right:.5rem}.buttons:last-child{margin-bottom:-.5rem}.buttons:not(:last-child){margin-bottom:1rem}.buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large){border-radius:2px;font-size:.75rem}.buttons.are-medium .button:not(.is-small):not(.is-normal):not(.is-large){font-size:1.25rem}.buttons.are-large .button:not(.is-small):not(.is-normal):not(.is-medium){font-size:1.5rem}.buttons.has-addons .button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.buttons.has-addons .button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}.buttons.has-addons .button:last-child{margin-right:0}.buttons.has-addons .button.is-hovered,.buttons.has-addons .button:hover{z-index:2}.buttons.has-addons .button.is-active,.buttons.has-addons .button.is-focused,.buttons.has-addons .button.is-selected,.buttons.has-addons .button:active,.buttons.has-addons .button:focus{z-index:3}.buttons.has-addons .button.is-active:hover,.buttons.has-addons .button.is-focused:hover,.buttons.has-addons .button.is-selected:hover,.buttons.has-addons .button:active:hover,.buttons.has-addons .button:focus:hover{z-index:4}.buttons.has-addons .button.is-expanded{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.buttons.is-centered{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.buttons.is-right{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.notification{background-color:#f5f5f5;border-radius:4px;padding:1.25rem 2.5rem 1.25rem 1.5rem;position:relative}.notification a:not(.button):not(.dropdown-item){color:currentColor;text-decoration:underline}.notification strong{color:currentColor}.notification code,.notification pre{background:#fff}.notification pre code{background:transparent}.notification>.delete{position:absolute;right:.5rem;top:.5rem}.notification .content,.notification .subtitle,.notification .title{color:currentColor}.notification.is-white{background-color:#fff;color:#0a0a0a}.notification.is-black{background-color:#0a0a0a;color:#fff}.notification.is-light{background-color:#f5f5f5;color:#363636}.notification.is-dark{background-color:#363636;color:#f5f5f5}.notification.is-primary{background-color:#00d1b2;color:#fff}.notification.is-link{background-color:#3273dc;color:#fff}.notification.is-info{background-color:#209cee;color:#fff}.notification.is-success{background-color:#23d160;color:#fff}.notification.is-warning{background-color:#ffdd57;color:rgba(0,0,0,.7)}.notification.is-danger{background-color:#ff3860;color:#fff}.heading{display:block;font-size:11px;letter-spacing:1px;margin-bottom:5px;text-transform:uppercase}.highlight{font-weight:400;max-width:100%;overflow:hidden;padding:0}.highlight pre{overflow:auto;max-width:100%}.number{-webkit-box-align:center;-ms-flex-align:center;align-items:center;background-color:#f5f5f5;border-radius:290486px;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;font-size:1.25rem;height:2em;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;margin-right:1.5rem;min-width:2.5em;padding:.25rem .5rem;text-align:center;vertical-align:top}.media{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start;display:-webkit-box;display:-ms-flexbox;display:flex;text-align:left}.media .content:not(:last-child){margin-bottom:.75rem}.media .media{border-top:1px solid hsla(0,0%,85.9%,.5);display:-webkit-box;display:-ms-flexbox;display:flex;padding-top:.75rem}.media .media .content:not(:last-child),.media .media .control:not(:last-child){margin-bottom:.5rem}.media .media .media{padding-top:.5rem}.media .media .media+.media{margin-top:.5rem}.media+.media{border-top:1px solid hsla(0,0%,85.9%,.5);margin-top:1rem;padding-top:1rem}.media.is-large+.media{margin-top:1.5rem;padding-top:1.5rem}.media-left,.media-right{-ms-flex-preferred-size:auto;flex-basis:auto;-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0}.media-left{margin-right:1rem}.media-right{margin-left:1rem}.media-content{-ms-flex-preferred-size:auto;flex-basis:auto;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-negative:1;flex-shrink:1;text-align:left}@media screen and (max-width:768px){.media-content{overflow-x:auto}}body{background:#fafafa} -------------------------------------------------------------------------------- /dist/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/favicon.ico -------------------------------------------------------------------------------- /dist/fonts/fa-brands-400.4b115e11.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/fonts/fa-brands-400.4b115e11.woff2 -------------------------------------------------------------------------------- /dist/fonts/fa-brands-400.b90365bc.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/fonts/fa-brands-400.b90365bc.woff -------------------------------------------------------------------------------- /dist/fonts/fa-brands-400.c39278f7.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/fonts/fa-brands-400.c39278f7.ttf -------------------------------------------------------------------------------- /dist/fonts/fa-brands-400.d9d17590.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/fonts/fa-brands-400.d9d17590.eot -------------------------------------------------------------------------------- /dist/fonts/fa-regular-400.414ff5da.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/fonts/fa-regular-400.414ff5da.eot -------------------------------------------------------------------------------- /dist/fonts/fa-regular-400.5dd3976c.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/fonts/fa-regular-400.5dd3976c.woff -------------------------------------------------------------------------------- /dist/fonts/fa-regular-400.65779ebc.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/fonts/fa-regular-400.65779ebc.woff2 -------------------------------------------------------------------------------- /dist/fonts/fa-regular-400.f6c6f6c8.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/fonts/fa-regular-400.f6c6f6c8.ttf -------------------------------------------------------------------------------- /dist/fonts/fa-solid-900.46280631.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/fonts/fa-solid-900.46280631.woff2 -------------------------------------------------------------------------------- /dist/fonts/fa-solid-900.61969d43.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/fonts/fa-solid-900.61969d43.woff -------------------------------------------------------------------------------- /dist/fonts/fa-solid-900.b5596f4d.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/fonts/fa-solid-900.b5596f4d.eot -------------------------------------------------------------------------------- /dist/fonts/fa-solid-900.b70cea03.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/fonts/fa-solid-900.b70cea03.ttf -------------------------------------------------------------------------------- /dist/img/logo.44914c2a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/img/logo.44914c2a.png -------------------------------------------------------------------------------- /dist/index.html: -------------------------------------------------------------------------------- 1 | forfeater-vue
-------------------------------------------------------------------------------- /dist/static/android-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/static/android-icon-144x144.png -------------------------------------------------------------------------------- /dist/static/android-icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/static/android-icon-192x192.png -------------------------------------------------------------------------------- /dist/static/android-icon-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/static/android-icon-36x36.png -------------------------------------------------------------------------------- /dist/static/android-icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/static/android-icon-48x48.png -------------------------------------------------------------------------------- /dist/static/android-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/static/android-icon-72x72.png -------------------------------------------------------------------------------- /dist/static/android-icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/static/android-icon-96x96.png -------------------------------------------------------------------------------- /dist/static/apple-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/static/apple-icon-114x114.png -------------------------------------------------------------------------------- /dist/static/apple-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/static/apple-icon-120x120.png -------------------------------------------------------------------------------- /dist/static/apple-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/static/apple-icon-144x144.png -------------------------------------------------------------------------------- /dist/static/apple-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/static/apple-icon-152x152.png -------------------------------------------------------------------------------- /dist/static/apple-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/static/apple-icon-180x180.png -------------------------------------------------------------------------------- /dist/static/apple-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/static/apple-icon-57x57.png -------------------------------------------------------------------------------- /dist/static/apple-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/static/apple-icon-60x60.png -------------------------------------------------------------------------------- /dist/static/apple-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/static/apple-icon-72x72.png -------------------------------------------------------------------------------- /dist/static/apple-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/static/apple-icon-76x76.png -------------------------------------------------------------------------------- /dist/static/apple-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/static/apple-icon-precomposed.png -------------------------------------------------------------------------------- /dist/static/apple-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/static/apple-icon.png -------------------------------------------------------------------------------- /dist/static/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | #ffffff -------------------------------------------------------------------------------- /dist/static/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/static/favicon-16x16.png -------------------------------------------------------------------------------- /dist/static/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/static/favicon-32x32.png -------------------------------------------------------------------------------- /dist/static/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/static/favicon-96x96.png -------------------------------------------------------------------------------- /dist/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/static/favicon.ico -------------------------------------------------------------------------------- /dist/static/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "App", 3 | "icons": [ 4 | { 5 | "src": "\/android-icon-36x36.png", 6 | "sizes": "36x36", 7 | "type": "image\/png", 8 | "density": "0.75" 9 | }, 10 | { 11 | "src": "\/android-icon-48x48.png", 12 | "sizes": "48x48", 13 | "type": "image\/png", 14 | "density": "1.0" 15 | }, 16 | { 17 | "src": "\/android-icon-72x72.png", 18 | "sizes": "72x72", 19 | "type": "image\/png", 20 | "density": "1.5" 21 | }, 22 | { 23 | "src": "\/android-icon-96x96.png", 24 | "sizes": "96x96", 25 | "type": "image\/png", 26 | "density": "2.0" 27 | }, 28 | { 29 | "src": "\/android-icon-144x144.png", 30 | "sizes": "144x144", 31 | "type": "image\/png", 32 | "density": "3.0" 33 | }, 34 | { 35 | "src": "\/android-icon-192x192.png", 36 | "sizes": "192x192", 37 | "type": "image\/png", 38 | "density": "4.0" 39 | } 40 | ] 41 | } -------------------------------------------------------------------------------- /dist/static/ms-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/static/ms-icon-144x144.png -------------------------------------------------------------------------------- /dist/static/ms-icon-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/static/ms-icon-150x150.png -------------------------------------------------------------------------------- /dist/static/ms-icon-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/static/ms-icon-310x310.png -------------------------------------------------------------------------------- /dist/static/ms-icon-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/dist/static/ms-icon-70x70.png -------------------------------------------------------------------------------- /docker/nginx/default.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | server_name localhost; 4 | 5 | #charset koi8-r; 6 | #access_log /var/log/nginx/host.access.log main; 7 | 8 | location / { 9 | root /usr/share/nginx/html; 10 | index index.html index.htm; 11 | try_files $uri $uri/ /index.html =404; 12 | } 13 | 14 | #error_page 404 /404.html; 15 | 16 | # redirect server error pages to the static page /50x.html 17 | # 18 | error_page 500 502 503 504 /50x.html; 19 | location = /50x.html { 20 | root /usr/share/nginx/html; 21 | } 22 | 23 | # proxy the PHP scripts to Apache listening on 127.0.0.1:80 24 | # 25 | #location ~ \.php$ { 26 | # proxy_pass http://127.0.0.1; 27 | #} 28 | 29 | # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 30 | # 31 | #location ~ \.php$ { 32 | # root html; 33 | # fastcgi_pass 127.0.0.1:9000; 34 | # fastcgi_index index.php; 35 | # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; 36 | # include fastcgi_params; 37 | #} 38 | 39 | # deny access to .htaccess files, if Apache's document root 40 | # concurs with nginx's one 41 | # 42 | #location ~ /\.ht { 43 | # deny all; 44 | #} 45 | } 46 | -------------------------------------------------------------------------------- /docker/nginx/vhost.conf: -------------------------------------------------------------------------------- 1 | server { 2 | location / { 3 | try_files $uri $uri/ /index.html; 4 | } 5 | } -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | moduleFileExtensions: ['js', 'json', 'vue'], 3 | transform: { 4 | '.*\\.(vue)$': 'vue-jest', 5 | '^.+\\.js$': '/node_modules/babel-jest' 6 | }, 7 | moduleNameMapper: { 8 | '^@/(.*)$': '/src/$1' 9 | }, 10 | collectCoverage: true, 11 | collectCoverageFrom: ['**/*.{js,vue}', '!**/node_modules/**'], 12 | coverageReporters: ['html', 'text-summary'] 13 | }; 14 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "allowSyntheticDefaultImports": false, 5 | "baseUrl": "./", 6 | "paths": { 7 | "@/*": ["src/*"] 8 | } 9 | }, 10 | "exclude": ["node_modules", "dist"] 11 | } 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "forfeater-vue", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint", 9 | "fix": "eslint --fix .", 10 | "test": "jest" 11 | }, 12 | "dependencies": { 13 | "@fortawesome/fontawesome-free": "^5.7.2", 14 | "@fortawesome/fontawesome-svg-core": "^1.2.15", 15 | "@fortawesome/free-solid-svg-icons": "^5.7.2", 16 | "@fortawesome/vue-fontawesome": "^0.1.5", 17 | "@vue/component-compiler-utils": "^2.6.0", 18 | "axios": "^0.18.0", 19 | "bootstrap": "^4.3.1", 20 | "buefy": "^0.7.2", 21 | "bulma": "^0.7.4", 22 | "dotenv": "^6.2.0", 23 | "dotenv-webpack": "^1.7.0", 24 | "jquery": "^3.3.1", 25 | "moment": "^2.24.0", 26 | "popper.js": "^1.14.7", 27 | "qs": "^6.6.0", 28 | "vee-validate": "^2.1.7", 29 | "vue": "^2.6.6", 30 | "vue-flatpickr-component": "^8.1.1", 31 | "vue-i18n": "^8.8.1", 32 | "vue-loader": "^15.7.0", 33 | "vue-router": "^3.0.2", 34 | "vue-tables-2": "^1.4.70", 35 | "vue-template-loader": "^1.0.0", 36 | "vuex": "^3.1.0" 37 | }, 38 | "devDependencies": { 39 | "@babel/core": "^7.2.2", 40 | "@babel/preset-env": "^7.3.1", 41 | "@vue/cli-plugin-babel": "^3.4.0", 42 | "@vue/cli-plugin-eslint": "^3.4.0", 43 | "@vue/cli-service": "^3.4.0", 44 | "@vue/test-utils": "^1.0.0-beta.29", 45 | "babel-eslint": "^10.0.1", 46 | "babel-jest": "^24.1.0", 47 | "eslint": "^5.13.0", 48 | "eslint-config-prettier": "^4.0.0", 49 | "eslint-import-resolver-webpack": "^0.11.0", 50 | "eslint-plugin-jest": "^22.2.2", 51 | "eslint-plugin-prettier": "^3.0.1", 52 | "eslint-plugin-vue": "^5.1.0", 53 | "jest": "^24.1.0", 54 | "js-beautify": "^1.8.9", 55 | "node-sass": "^4.11.0", 56 | "prettier": "^1.16.4", 57 | "sass-loader": "^7.1.0", 58 | "vue-jest": "^3.0.3", 59 | "vue-template-compiler": "^2.6.6" 60 | }, 61 | "postcss": { 62 | "plugins": { 63 | "autoprefixer": {} 64 | } 65 | }, 66 | "browserslist": [ 67 | "> 1%", 68 | "last 2 versions", 69 | "not ie <= 8" 70 | ] 71 | } 72 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | forfeater-vue 28 | 29 | 30 | 33 |
34 | 35 | 36 | -------------------------------------------------------------------------------- /public/static/android-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/public/static/android-icon-144x144.png -------------------------------------------------------------------------------- /public/static/android-icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/public/static/android-icon-192x192.png -------------------------------------------------------------------------------- /public/static/android-icon-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/public/static/android-icon-36x36.png -------------------------------------------------------------------------------- /public/static/android-icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/public/static/android-icon-48x48.png -------------------------------------------------------------------------------- /public/static/android-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/public/static/android-icon-72x72.png -------------------------------------------------------------------------------- /public/static/android-icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/public/static/android-icon-96x96.png -------------------------------------------------------------------------------- /public/static/apple-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/public/static/apple-icon-114x114.png -------------------------------------------------------------------------------- /public/static/apple-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/public/static/apple-icon-120x120.png -------------------------------------------------------------------------------- /public/static/apple-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/public/static/apple-icon-144x144.png -------------------------------------------------------------------------------- /public/static/apple-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/public/static/apple-icon-152x152.png -------------------------------------------------------------------------------- /public/static/apple-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/public/static/apple-icon-180x180.png -------------------------------------------------------------------------------- /public/static/apple-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/public/static/apple-icon-57x57.png -------------------------------------------------------------------------------- /public/static/apple-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/public/static/apple-icon-60x60.png -------------------------------------------------------------------------------- /public/static/apple-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/public/static/apple-icon-72x72.png -------------------------------------------------------------------------------- /public/static/apple-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/public/static/apple-icon-76x76.png -------------------------------------------------------------------------------- /public/static/apple-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/public/static/apple-icon-precomposed.png -------------------------------------------------------------------------------- /public/static/apple-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/public/static/apple-icon.png -------------------------------------------------------------------------------- /public/static/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | #ffffff -------------------------------------------------------------------------------- /public/static/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/public/static/favicon-16x16.png -------------------------------------------------------------------------------- /public/static/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/public/static/favicon-32x32.png -------------------------------------------------------------------------------- /public/static/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/public/static/favicon-96x96.png -------------------------------------------------------------------------------- /public/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/public/static/favicon.ico -------------------------------------------------------------------------------- /public/static/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "App", 3 | "icons": [ 4 | { 5 | "src": "\/android-icon-36x36.png", 6 | "sizes": "36x36", 7 | "type": "image\/png", 8 | "density": "0.75" 9 | }, 10 | { 11 | "src": "\/android-icon-48x48.png", 12 | "sizes": "48x48", 13 | "type": "image\/png", 14 | "density": "1.0" 15 | }, 16 | { 17 | "src": "\/android-icon-72x72.png", 18 | "sizes": "72x72", 19 | "type": "image\/png", 20 | "density": "1.5" 21 | }, 22 | { 23 | "src": "\/android-icon-96x96.png", 24 | "sizes": "96x96", 25 | "type": "image\/png", 26 | "density": "2.0" 27 | }, 28 | { 29 | "src": "\/android-icon-144x144.png", 30 | "sizes": "144x144", 31 | "type": "image\/png", 32 | "density": "3.0" 33 | }, 34 | { 35 | "src": "\/android-icon-192x192.png", 36 | "sizes": "192x192", 37 | "type": "image\/png", 38 | "density": "4.0" 39 | } 40 | ] 41 | } -------------------------------------------------------------------------------- /public/static/ms-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/public/static/ms-icon-144x144.png -------------------------------------------------------------------------------- /public/static/ms-icon-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/public/static/ms-icon-150x150.png -------------------------------------------------------------------------------- /public/static/ms-icon-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/public/static/ms-icon-310x310.png -------------------------------------------------------------------------------- /public/static/ms-icon-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/public/static/ms-icon-70x70.png -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 22 | 23 | 30 | -------------------------------------------------------------------------------- /src/assets/app.scss: -------------------------------------------------------------------------------- 1 | @import '~buefy/src/scss/components/_message'; 2 | @import '~bulma/sass/utilities/_all'; 3 | @import '~bulma/sass/elements/button'; 4 | @import '~bulma/sass/elements/notification'; 5 | @import '~bulma/sass/elements/other'; 6 | @import '~bulma/sass/components/media'; -------------------------------------------------------------------------------- /src/assets/css/styles.css: -------------------------------------------------------------------------------- 1 | html { 2 | position: relative; 3 | min-height: 100%; 4 | } 5 | body { 6 | /* Margin bottom by footer height */ 7 | margin-bottom: 60px; 8 | background: #fafafa; 9 | } 10 | 11 | .footer { 12 | position: absolute; 13 | bottom: 0; 14 | width: 100%; 15 | /* Set the fixed height of the footer here */ 16 | height: 60px; 17 | line-height: 60px; /* Vertically center the text there */ 18 | color: #fff; 19 | background-color: orange; 20 | } 21 | 22 | body > .container { 23 | padding: 60px 15px 0; 24 | } 25 | 26 | .footer > .container { 27 | padding-right: 15px; 28 | padding-left: 15px; 29 | } 30 | 31 | main{ 32 | margin-top: 1rem; 33 | margin-bottom: 60px; 34 | padding-bottom: 50px; 35 | } 36 | 37 | code { 38 | font-size: 80%; 39 | } 40 | 41 | li a { 42 | color: green; 43 | } 44 | 45 | .navbar { 46 | background-color: orange; 47 | } 48 | 49 | .navbar-logo { 50 | height: 40px; 51 | width: auto; 52 | margin: 0 10px 0 0; 53 | } 54 | 55 | .jumbotron { 56 | background-color: #ffeecc; 57 | } 58 | 59 | @media (min-width: 576px) { 60 | .jumbotron { 61 | padding: 1rem; 62 | } 63 | } 64 | 65 | .btn-action { 66 | padding: 0.5rem; 67 | } 68 | 69 | .p-0 { 70 | padding: 0; 71 | } 72 | 73 | .btn-warning.col-white, 74 | .btn-warning.col-white:hover, 75 | .btn-warning.col-white:active, 76 | .btn-warning.col-white:focus, 77 | .btn-warning.col-white:visited, 78 | .btn-warning.col-white:disabled { 79 | color: #fff; 80 | } 81 | 82 | .col-white{ 83 | color: #fff; 84 | } 85 | 86 | .btn-custom { 87 | max-width: 200px; 88 | margin: 0 0 0.5rem 0; 89 | } 90 | 91 | .breadcrumb.breadcrumb { 92 | background-color: #EEE8AA; 93 | } 94 | 95 | .breadcrumb-item.active { 96 | color: #2E8B57; 97 | } -------------------------------------------------------------------------------- /src/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftwareBrothers/forfeater-vue/baa3ba42a622fe32003521a022269f7770dc31a3/src/assets/images/logo.png -------------------------------------------------------------------------------- /src/components/Alerts/Error.vue: -------------------------------------------------------------------------------- 1 | 4 | 23 | -------------------------------------------------------------------------------- /src/components/Auth/Login.vue: -------------------------------------------------------------------------------- 1 | 48 | 49 | 84 | -------------------------------------------------------------------------------- /src/components/Breadcrumbs.vue: -------------------------------------------------------------------------------- 1 | 11 | 29 | 30 | -------------------------------------------------------------------------------- /src/components/Choice/Add.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | 113 | -------------------------------------------------------------------------------- /src/components/Choice/Create.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 35 | -------------------------------------------------------------------------------- /src/components/Choice/Edit.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 54 | -------------------------------------------------------------------------------- /src/components/Choice/Form.vue: -------------------------------------------------------------------------------- 1 | 52 | 53 | 128 | -------------------------------------------------------------------------------- /src/components/Choice/List.vue: -------------------------------------------------------------------------------- 1 | 36 | 75 | 91 | -------------------------------------------------------------------------------- /src/components/Choice/Score.vue: -------------------------------------------------------------------------------- 1 | 43 | 44 | 81 | -------------------------------------------------------------------------------- /src/components/Choice/ScoreForm.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 35 | -------------------------------------------------------------------------------- /src/components/Choice/Table.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 75 | -------------------------------------------------------------------------------- /src/components/Footer.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /src/components/Header.vue: -------------------------------------------------------------------------------- 1 | 46 | 47 | 63 | 64 | 94 | -------------------------------------------------------------------------------- /src/components/Helpers/Countdown.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 47 | -------------------------------------------------------------------------------- /src/components/Home.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 15 | -------------------------------------------------------------------------------- /src/components/Notification.vue: -------------------------------------------------------------------------------- 1 | 12 | 62 | -------------------------------------------------------------------------------- /src/components/Order/Create.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 36 | -------------------------------------------------------------------------------- /src/components/Order/Edit.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 69 | -------------------------------------------------------------------------------- /src/components/Order/Form.vue: -------------------------------------------------------------------------------- 1 | 53 | 54 | 153 | 157 | -------------------------------------------------------------------------------- /src/components/Order/List.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 37 | -------------------------------------------------------------------------------- /src/components/Order/Table.vue: -------------------------------------------------------------------------------- 1 | 70 | 71 | 102 | 103 | 109 | -------------------------------------------------------------------------------- /src/components/PageNotFound.vue: -------------------------------------------------------------------------------- 1 | 20 | -------------------------------------------------------------------------------- /src/components/Print.vue: -------------------------------------------------------------------------------- 1 | 7 | 17 | 28 | -------------------------------------------------------------------------------- /src/components/Product/CheckboxList.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 40 | -------------------------------------------------------------------------------- /src/components/Product/Create.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 40 | -------------------------------------------------------------------------------- /src/components/Product/Edit.vue: -------------------------------------------------------------------------------- 1 | 37 | 38 | 58 | -------------------------------------------------------------------------------- /src/components/Product/Form.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 68 | -------------------------------------------------------------------------------- /src/components/Product/InputsList.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 44 | 45 | 51 | -------------------------------------------------------------------------------- /src/components/Product/List.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 43 | -------------------------------------------------------------------------------- /src/components/Product/Show.vue: -------------------------------------------------------------------------------- 1 | 41 | 42 | 67 | -------------------------------------------------------------------------------- /src/components/Product/Table.vue: -------------------------------------------------------------------------------- 1 | 50 | 51 | 73 | -------------------------------------------------------------------------------- /src/components/User/AutoComplete.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 84 | 110 | -------------------------------------------------------------------------------- /src/components/User/ChangePassword.vue: -------------------------------------------------------------------------------- 1 | 39 | 40 | 67 | -------------------------------------------------------------------------------- /src/components/User/Create.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 33 | -------------------------------------------------------------------------------- /src/components/User/Edit.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 53 | -------------------------------------------------------------------------------- /src/components/User/Form.vue: -------------------------------------------------------------------------------- 1 | 68 | 69 | 100 | -------------------------------------------------------------------------------- /src/components/User/List.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 38 | -------------------------------------------------------------------------------- /src/components/User/Profile.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 37 | -------------------------------------------------------------------------------- /src/components/User/Table.vue: -------------------------------------------------------------------------------- 1 | 43 | 44 | 68 | -------------------------------------------------------------------------------- /src/components/Vendor/Create.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 33 | -------------------------------------------------------------------------------- /src/components/Vendor/Edit.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | 51 | -------------------------------------------------------------------------------- /src/components/Vendor/Form.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 52 | -------------------------------------------------------------------------------- /src/components/Vendor/List.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 37 | -------------------------------------------------------------------------------- /src/components/Vendor/Table.vue: -------------------------------------------------------------------------------- 1 | 42 | 43 | 67 | -------------------------------------------------------------------------------- /src/config/client.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import store from '@/config/store'; 3 | 4 | const headers = { 5 | common: { 6 | 'Content-Type': 'application/json', 7 | Accept: 'application/json', 8 | 'Access-Control-Allow-Origin': '*' 9 | } 10 | }; 11 | 12 | const client = axios.create({ 13 | baseURL: process.env.VUE_APP_API_URL, 14 | headers, 15 | withCredentials: true 16 | }); 17 | 18 | client.interceptors.response.use( 19 | response => { 20 | return response.data; 21 | }, 22 | error => { 23 | store.dispatch('setNotification', { type: 'error', message: error.message, code: error.code }); 24 | return false; 25 | } 26 | ); 27 | 28 | export default client; 29 | -------------------------------------------------------------------------------- /src/config/i18n.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import VueI18n from 'vue-i18n'; 3 | 4 | import messages from '@/i18n'; 5 | 6 | Vue.use(VueI18n); 7 | 8 | export default new VueI18n({ 9 | locale: process.env.VUE_APP_LOCALE || 'en', 10 | messages 11 | }); 12 | -------------------------------------------------------------------------------- /src/config/router.js: -------------------------------------------------------------------------------- 1 | import VueRouter from 'vue-router'; 2 | import Vue from 'vue'; 3 | 4 | import Guard from '@/security/guard'; 5 | 6 | import Login from '@/components/Auth/Login'; 7 | 8 | import Home from '@/components/Home'; 9 | import PageNotFound from '@/components/PageNotFound'; 10 | 11 | import ChoiceAdd from '@/components/Choice/Add'; 12 | import ChoiceCreate from '@/components/Choice/Create'; 13 | import ChoiceEdit from '@/components/Choice/Edit'; 14 | import ChoiceScore from '@/components/Choice/Score'; 15 | 16 | import UserList from '@/components/User/List'; 17 | import UserCreate from '@/components/User/Create'; 18 | import UserEdit from '@/components/User/Edit'; 19 | import UserProfile from '@/components/User/Profile'; 20 | import UserChangePassword from '@/components/User/ChangePassword'; 21 | 22 | import VendorList from '@/components/Vendor/List'; 23 | import VendorCreate from '@/components/Vendor/Create'; 24 | import VendorEdit from '@/components/Vendor/Edit'; 25 | 26 | import ProductList from '@/components/Product/List'; 27 | import ProductCreate from '@/components/Product/Create'; 28 | import ProductEdit from '@/components/Product/Edit'; 29 | import ProductShow from '@/components/Product/Show'; 30 | 31 | import OrderList from '@/components/Order/List'; 32 | import OrderCreate from '@/components/Order/Create'; 33 | import OrderEdit from '@/components/Order/Edit'; 34 | 35 | import ChoiceList from '@/components/Choice/List'; 36 | 37 | Vue.use(VueRouter); 38 | 39 | export default new VueRouter({ 40 | mode: 'history', 41 | routes: [ 42 | { path: '*', component: PageNotFound }, 43 | { 44 | path: '/login', 45 | name: 'Login', 46 | component: Login, 47 | beforeEnter: Guard.isGuest 48 | }, 49 | { 50 | path: '/', 51 | name: 'Home', 52 | component: Home, 53 | beforeEnter: Guard.isAuthenticated 54 | }, 55 | { 56 | path: '/order', 57 | name: 'ChoiceAdd', 58 | component: ChoiceAdd, 59 | beforeEnter: Guard.isAuthenticated 60 | }, 61 | { 62 | path: '/user/my-profile', 63 | name: 'UserProfile', 64 | component: UserProfile, 65 | beforeEnter: Guard.isAuthenticated 66 | }, 67 | 68 | { 69 | path: '/user/change-password', 70 | name: 'UserChangePassword', 71 | component: UserChangePassword, 72 | beforeEnter: Guard.isAuthenticated 73 | }, 74 | { 75 | path: '/users', 76 | name: 'UserList', 77 | component: UserList, 78 | meta: { adminAuth: true }, 79 | beforeEnter: Guard.isAuthenticated 80 | }, 81 | { 82 | path: '/users/create', 83 | name: 'UserCreate', 84 | component: UserCreate, 85 | meta: { adminAuth: true }, 86 | beforeEnter: Guard.isAuthenticated 87 | }, 88 | { 89 | path: '/users/:id/edit', 90 | name: 'UserEdit', 91 | component: UserEdit, 92 | meta: { adminAuth: true }, 93 | beforeEnter: Guard.isAuthenticated 94 | }, 95 | { 96 | path: '/vendors', 97 | name: 'VendorList', 98 | component: VendorList, 99 | meta: { adminAuth: true }, 100 | beforeEnter: Guard.isAuthenticated 101 | }, 102 | { 103 | path: '/vendors/create', 104 | name: 'VendorCreate', 105 | component: VendorCreate, 106 | meta: { adminAuth: true }, 107 | beforeEnter: Guard.isAuthenticated 108 | }, 109 | { 110 | path: '/vendors/:id/edit', 111 | name: 'VendorEdit', 112 | component: VendorEdit, 113 | meta: { adminAuth: true }, 114 | beforeEnter: Guard.isAuthenticated 115 | }, 116 | 117 | { 118 | path: '/vendors/:vendorId/products', 119 | name: 'ProductList', 120 | component: ProductList, 121 | meta: { adminAuth: true }, 122 | beforeEnter: Guard.isAuthenticated 123 | }, 124 | { 125 | path: '/vendors/:vendorId/products/create', 126 | name: 'ProductCreate', 127 | component: ProductCreate, 128 | meta: { adminAuth: true }, 129 | beforeEnter: Guard.isAuthenticated 130 | }, 131 | { 132 | path: '/vendors/:vendorId/products/:id/edit', 133 | name: 'ProductEdit', 134 | component: ProductEdit, 135 | meta: { adminAuth: true }, 136 | beforeEnter: Guard.isAuthenticated 137 | }, 138 | { 139 | path: '/vendors/:vendorId/products/:id', 140 | name: 'ProductShow', 141 | component: ProductShow, 142 | meta: { adminAuth: true }, 143 | beforeEnter: Guard.isAuthenticated 144 | }, 145 | { 146 | path: '/orders', 147 | name: 'OrderList', 148 | component: OrderList, 149 | beforeEnter: Guard.isAuthenticated 150 | }, 151 | { 152 | path: '/orders/create', 153 | name: 'OrderCreate', 154 | component: OrderCreate, 155 | meta: { adminAuth: true }, 156 | beforeEnter: Guard.isAuthenticated 157 | }, 158 | { 159 | path: '/orders/:id/edit', 160 | name: 'OrderEdit', 161 | component: OrderEdit, 162 | meta: { adminAuth: true }, 163 | beforeEnter: Guard.isAuthenticated 164 | }, 165 | { 166 | path: '/orders/:orderId/choices', 167 | name: 'ChoiceList', 168 | component: ChoiceList, 169 | beforeEnter: Guard.isAuthenticated 170 | }, 171 | { 172 | path: '/orders/:orderId/choices/create', 173 | name: 'ChoiceCreate', 174 | component: ChoiceCreate, 175 | beforeEnter: Guard.isAuthenticated 176 | }, 177 | { 178 | path: '/orders/:orderId/choices/:choiceId/edit', 179 | name: 'ChoiceEdit', 180 | component: ChoiceEdit, 181 | beforeEnter: Guard.isAuthenticated 182 | }, 183 | { 184 | path: '/orders/:id/score', 185 | name: 'ChoiceScore', 186 | component: ChoiceScore, 187 | beforeEnter: Guard.isAuthenticated 188 | } 189 | ] 190 | }); 191 | -------------------------------------------------------------------------------- /src/config/store.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import Vuex from 'vuex'; 3 | import { AuthService } from '@/services/auth.service'; 4 | import { getExpireDate } from '@/helper/date.helper'; 5 | 6 | Vue.use(Vuex); 7 | 8 | const service = new AuthService(); 9 | 10 | const LOGIN = 'LOGIN'; 11 | const LOGOUT = 'LOGOUT'; 12 | const AUTH = 'AUTH'; 13 | const NOTIFICATION = 'NOTIFICATION'; 14 | const CLEAR_NOTIFICATION = 'CLEAR_NOTIFICATION'; 15 | 16 | const state = { 17 | user: localStorage.getItem('user') ? JSON.parse(localStorage.getItem('user')) : null, 18 | token: localStorage.getItem('token') || null, 19 | notification: null 20 | }; 21 | 22 | const getters = { 23 | user: state => state.user, 24 | token: state => state.token, 25 | isAuthenticated: state => !!state.token, 26 | authStatus: state => state.status, 27 | notification: state => state.notification 28 | }; 29 | 30 | const mutations = { 31 | [LOGIN](state, user) { 32 | state.user = user; 33 | }, 34 | [LOGOUT](state) { 35 | state.user = null; 36 | state.token = null; 37 | }, 38 | [AUTH](state, token) { 39 | state.token = token; 40 | }, 41 | [NOTIFICATION](state, notification) { 42 | state.notification = notification; 43 | }, 44 | [CLEAR_NOTIFICATION](state) { 45 | state.notification = null; 46 | } 47 | }; 48 | 49 | const actions = { 50 | authenticate: async (context, payload) => { 51 | const data = await service.authorize({ 52 | username: payload.username, 53 | password: payload.password 54 | }); 55 | if (data) { 56 | let token = data.access_token; 57 | context.commit(AUTH, token); 58 | localStorage.setItem('token', token); 59 | localStorage.setItem('token_expires_at', getExpireDate(data.expires_in)); 60 | return token; 61 | } 62 | return false; 63 | }, 64 | logout: context => { 65 | context.commit(LOGOUT); 66 | localStorage.removeItem('token'); 67 | localStorage.removeItem('user'); 68 | localStorage.removeItem('token_expires_at'); 69 | }, 70 | getUser: async context => { 71 | const token = localStorage.getItem('token') || null; 72 | if (token) { 73 | const user = await service.getUserProfile(token); 74 | if (user) { 75 | context.commit(LOGIN, user); 76 | localStorage.setItem('user', JSON.stringify(user)); 77 | return user; 78 | } 79 | } 80 | return false; 81 | }, 82 | setNotification: (context, notification) => { 83 | context.commit(NOTIFICATION, notification); 84 | }, 85 | removeNotification: context => { 86 | context.commit(CLEAR_NOTIFICATION); 87 | } 88 | }; 89 | 90 | export default new Vuex.Store({ 91 | state: state, 92 | getters: getters, 93 | mutations: mutations, 94 | actions: actions 95 | }); 96 | -------------------------------------------------------------------------------- /src/filters/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | const moment = require('moment'); 3 | Vue.filter('two_digits', value => { 4 | if (value.toString().length <= 1) { 5 | return '0' + value.toString(); 6 | } 7 | return value.toString(); 8 | }); 9 | Vue.filter('moment', date => { 10 | if (!date) return null; 11 | return moment(date).format('DD/MM/YYYY HH:mm'); 12 | }); 13 | -------------------------------------------------------------------------------- /src/helper/date.helper.js: -------------------------------------------------------------------------------- 1 | import moment from 'moment'; 2 | 3 | export function getExpireDate(seconds) { 4 | return moment() 5 | .add(seconds, 'seconds') 6 | .toISOString(); 7 | } 8 | 9 | export function isExpired(dateStringISO) { 10 | const expire = moment(dateStringISO); 11 | return moment().isAfter(expire); 12 | } 13 | -------------------------------------------------------------------------------- /src/i18n/en.js: -------------------------------------------------------------------------------- 1 | export default { 2 | choices: { 3 | saved: 'You order has been stored!' 4 | }, 5 | orders: { 6 | lack: 'There is no restaurants available for today' 7 | }, 8 | errors: { 9 | auth: { 10 | general: 'Sorry, something went wrong' 11 | } 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /src/i18n/index.js: -------------------------------------------------------------------------------- 1 | import en from '@/i18n/en'; 2 | import pl from '@/i18n/pl'; 3 | 4 | export default { ['en']: en, ['pl']: pl }; 5 | -------------------------------------------------------------------------------- /src/i18n/pl.js: -------------------------------------------------------------------------------- 1 | export default { 2 | choices: { 3 | saved: 'Twoje zamównie zostało zapisane!' 4 | }, 5 | errors: { 6 | auth: { 7 | general: 'Coś poszło nie tak, spróbuj ponownie' 8 | } 9 | }, 10 | orders: { 11 | lack: 'Brak wyboru restauracji' 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import VeeValidate from 'vee-validate'; 3 | import Buefy from 'buefy'; 4 | 5 | import router from '@/config/router'; 6 | import store from '@/config/store'; 7 | import i18n from '@/config/i18n'; 8 | 9 | import '@/filters/index'; 10 | 11 | import App from './App.vue'; 12 | import 'bootstrap/dist/css/bootstrap.css'; 13 | import '@fortawesome/fontawesome-free/css/all.css'; 14 | import '@fortawesome/fontawesome-free/css/fontawesome.css'; 15 | 16 | import { ClientTable } from 'vue-tables-2'; 17 | import { library } from '@fortawesome/fontawesome-svg-core'; 18 | import { faEdit, faTrash, faList, faComment, faPlus, faPrint } from '@fortawesome/free-solid-svg-icons'; 19 | 20 | import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'; 21 | library.add(faEdit); 22 | library.add(faTrash); 23 | library.add(faList); 24 | library.add(faComment); 25 | library.add(faPlus); 26 | library.add(faPrint); 27 | Vue.component('font-awesome-icon', FontAwesomeIcon); 28 | 29 | Vue.use(Buefy, { defaultIconPack: 'fas' }); 30 | Vue.use(VeeValidate); 31 | Vue.use(ClientTable, {}, false, 'bootstrap4', 'default'); 32 | 33 | Vue.config.productionTip = false; 34 | 35 | new Vue({ 36 | el: '#app', 37 | router, 38 | store, 39 | i18n, 40 | render: h => h(App) 41 | }); 42 | -------------------------------------------------------------------------------- /src/security/auth.js: -------------------------------------------------------------------------------- 1 | import { isExpired } from '@/helper/date.helper'; 2 | import store from '@/config/store'; 3 | 4 | class Auth { 5 | isValid() { 6 | const token = localStorage.getItem('token') || null; 7 | const date = localStorage.getItem('token_expires_at') || null; 8 | if (token && !isExpired(date)) { 9 | return true; 10 | } 11 | store.dispatch('logout'); 12 | return false; 13 | } 14 | } 15 | 16 | export default new Auth(); 17 | -------------------------------------------------------------------------------- /src/security/guard.js: -------------------------------------------------------------------------------- 1 | import Auth from '@/security/auth'; 2 | import store from '@/config/store'; 3 | 4 | class Guard { 5 | isGuest(to, from, next) { 6 | next(!Auth.isValid()); 7 | } 8 | 9 | isAdmin(to, from, next) { 10 | next(Auth.isValid() && store.getters.user.role === 'admin'); 11 | } 12 | 13 | async isAuthenticated(to, from, next) { 14 | let redirectToLogin = { 15 | name: 'Login', 16 | query: { 17 | redirect: to.name 18 | } 19 | }; 20 | 21 | if (!Auth.isValid()) { 22 | next(redirectToLogin); 23 | } 24 | 25 | next(await store.dispatch('getUser')); 26 | } 27 | } 28 | 29 | export default new Guard(); 30 | -------------------------------------------------------------------------------- /src/services/api.service.js: -------------------------------------------------------------------------------- 1 | import client from '@/config/client'; 2 | 3 | export class ApiService { 4 | token = null; 5 | 6 | constructor() { 7 | this.initClient(); 8 | } 9 | 10 | initClient() { 11 | this.client = client; 12 | this.initToken(); 13 | } 14 | 15 | initToken() { 16 | this.token = localStorage.getItem('token') || null; 17 | if (this.token) { 18 | this.client.defaults.headers.common['Authorization'] = `Bearer ${this.token}`; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/services/auth.service.js: -------------------------------------------------------------------------------- 1 | import qs from 'qs'; 2 | 3 | import { ApiService } from '@/services/api.service'; 4 | 5 | export class AuthService extends ApiService { 6 | constructor() { 7 | super(); 8 | this.uri = 'auth'; 9 | } 10 | async authorize(credential) { 11 | const data = { 12 | grant_type: 'password', 13 | username: credential.username, 14 | password: credential.password, 15 | client_id: process.env.VUE_APP_API_CLIENT_ID || 'forfeaterWeb', 16 | client_secret: process.env.VUE_APP_API_CLIENT_SECRET || 'forfeaterSecret' 17 | }; 18 | return await this.client.post(`${this.uri}/login`, qs.stringify(data), { 19 | headers: { 20 | 'Content-Type': 'application/x-www-form-urlencoded' 21 | } 22 | }); 23 | } 24 | 25 | async getUserProfile() { 26 | this.initToken(); 27 | return await this.client.get(`${this.uri}/user`); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/services/choice.service.js: -------------------------------------------------------------------------------- 1 | import { ApiService } from '@/services/api.service'; 2 | import { ProductService } from '@/services/product.service'; 3 | 4 | export class ChoiceService extends ApiService { 5 | constructor() { 6 | super(); 7 | this.uri = 'choices'; 8 | this.productService = new ProductService(); 9 | } 10 | 11 | getAll() { 12 | return this.client.get(this.uri); 13 | } 14 | 15 | getAllFromOrder(orderId) { 16 | return this.client.get(`orders/${orderId}/${this.uri}`); 17 | } 18 | 19 | find(id) { 20 | return this.client.get(`${this.uri}/${id}`); 21 | } 22 | 23 | getFromOrder(orderId) { 24 | return this.client.get(`orders/${orderId}/choice`); 25 | } 26 | 27 | getFromProduct(Product) { 28 | return this.client.get(`vendors/${Product.vendorId}/products/${Product.id}/choices`); 29 | } 30 | 31 | store(User, Order, Product, comment) { 32 | return this.client.put(`orders/${Order.id}/choices`, { 33 | orderId: Order.id, 34 | userId: User.id, 35 | productId: Product.id, 36 | orderComment: comment 37 | }); 38 | } 39 | 40 | async save(User, Order, Product, commentText) { 41 | const data = await this.store(User, Order, Product, commentText); 42 | const product = await this.productService.find(Product.vendorId, data.productId); 43 | const { id = null, orderComment: comment = null, orderId } = data; 44 | return { id, product, comment, orderId }; 45 | } 46 | 47 | rate(orderId, Score) { 48 | return this.client.patch(`orders/${orderId}/ratings`, { 49 | mark: Score.score, 50 | scoreComment: Score.comment 51 | }); 52 | } 53 | 54 | remove(orderId, choiceId) { 55 | return this.client.delete(`orders/${orderId}/choices/${choiceId}`); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/services/order.service.js: -------------------------------------------------------------------------------- 1 | import store from '@/config/store'; 2 | 3 | import { ApiService } from '@/services/api.service'; 4 | import { ProductService } from '@/services/product.service'; 5 | import { ChoiceService } from '@/services/choice.service'; 6 | 7 | export class OrderService extends ApiService { 8 | constructor() { 9 | super(); 10 | this.uri = 'orders'; 11 | this.productService = new ProductService(); 12 | this.choiceService = new ChoiceService(); 13 | } 14 | 15 | find(orderId) { 16 | return this.client.get(`${this.uri}/${orderId}`); 17 | } 18 | 19 | getActive() { 20 | return this.client.get(this.uri, { 21 | params: { active: 1 } 22 | }); 23 | } 24 | 25 | getAll() { 26 | return this.client.get(this.uri); 27 | } 28 | 29 | getOrderWithChoices(orderId) { 30 | return this.client.get(`${this.uri}/${orderId}/choices`); 31 | } 32 | 33 | remove(orderId) { 34 | return this.client.delete(`${this.uri}/${orderId}`); 35 | } 36 | 37 | store(order) { 38 | return this.client.post(this.uri, order); 39 | } 40 | 41 | update(order) { 42 | return this.client.patch(`${this.uri}/${order.id}`, order); 43 | } 44 | 45 | async getAllWithProductChoices() { 46 | const data = await this.getAll(); 47 | return this.getProductChoicesFromOrders(data); 48 | } 49 | 50 | async getAllActiveWithProductChoices() { 51 | const data = await this.getActive(); 52 | return this.getProductChoicesFromOrders(data); 53 | } 54 | 55 | async getProductChoicesFromOrders(data) { 56 | const orders = []; 57 | 58 | for (const order of data) { 59 | order.vendor.products = await this.productService.getAllActiveByVendor(order.vendor.id); 60 | const choices = await this.getOrderWithChoices(order.id); 61 | const userChoice = choices.find(x => x.userId === store.getters.user.id); 62 | order.choice = { 63 | id: (userChoice && userChoice.id) || null, 64 | product: (userChoice && userChoice.product) || null, 65 | comment: (userChoice && userChoice.orderComment) || null 66 | }; 67 | 68 | orders.push(order); 69 | } 70 | return orders; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/services/product.service.js: -------------------------------------------------------------------------------- 1 | import { ApiService } from '@/services/api.service'; 2 | 3 | export class ProductService extends ApiService { 4 | constructor() { 5 | super(); 6 | this.uri = 'vendors'; 7 | } 8 | find(vendorId, id) { 9 | return this.client.get(`${this.uri}/${vendorId}/products/${id}`); 10 | } 11 | 12 | getAll(vendorId) { 13 | return this.client.get(`${this.uri}/${vendorId}/products`); 14 | } 15 | 16 | remove(vendorId, productId) { 17 | return this.client.delete(`${this.uri}/${vendorId}/products/${productId}`); 18 | } 19 | 20 | store(product) { 21 | return this.client.post(`${this.uri}/${product.vendorId}/products`, product); 22 | } 23 | 24 | update(product) { 25 | return this.client.patch(`${this.uri}/${product.vendorId}/products/${product.id}`, product); 26 | } 27 | 28 | getAllActiveByVendor(vendorId) { 29 | return this.client.get(`${this.uri}/${vendorId}/products`, { 30 | params: { 31 | active: 1, 32 | vendorId: vendorId 33 | } 34 | }); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/services/user.service.js: -------------------------------------------------------------------------------- 1 | import { ApiService } from '@/services/api.service'; 2 | 3 | export class UserService extends ApiService { 4 | constructor() { 5 | super(); 6 | this.uri = 'users'; 7 | } 8 | 9 | find(id) { 10 | return this.client.get(`${this.uri}/${id}`); 11 | } 12 | 13 | getAll() { 14 | return this.client.get(this.uri); 15 | } 16 | 17 | remove(userId) { 18 | return this.client.delete(`${this.uri}/${userId}`); 19 | } 20 | 21 | store(user) { 22 | return this.client.post(this.uri, user); 23 | } 24 | 25 | update(user) { 26 | return this.client.patch(`${this.uri}/${user.id}`, user); 27 | } 28 | 29 | changePassword(user, password) { 30 | return this.client.put(`${this.uri}/${user.id}/password`, { newPassword: password }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/services/vendor.service.js: -------------------------------------------------------------------------------- 1 | import { ApiService } from '@/services/api.service'; 2 | 3 | export class VendorService extends ApiService { 4 | constructor() { 5 | super(); 6 | this.uri = '/vendors'; 7 | } 8 | 9 | find(id) { 10 | return this.client.get(`${this.uri}/${id}`); 11 | } 12 | 13 | getAll() { 14 | return this.client.get(this.uri); 15 | } 16 | 17 | getTodayVendor() { 18 | const vendors = this.getAll(); 19 | return vendors[0] || null; 20 | } 21 | 22 | remove(id) { 23 | return this.client.delete(`${this.uri}/${id}`); 24 | } 25 | 26 | store(vendor) { 27 | return this.client.post(this.uri, vendor); 28 | } 29 | 30 | update(vendor) { 31 | return this.client.patch(`${this.uri}/${vendor.id}`, vendor); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tests/helper/date.spec.js: -------------------------------------------------------------------------------- 1 | import { getExpireDate, isExpired } from '@/helper/date.helper'; 2 | 3 | describe('Testing date helper', () => { 4 | test('Check if is expire', () => { 5 | const now = new Date(); 6 | let expire = now.getTime() - 1000 * 60 * 60 * 24; 7 | expire = new Date(expire).toISOString(); 8 | expect(isExpired(expire)).toBe(true); 9 | }); 10 | test('Check if is not expire', () => { 11 | const now = new Date(); 12 | let expire = now.getTime() + 1000 * 60 * 60 * 24; 13 | expire = new Date(expire).toISOString(); 14 | expect(isExpired(expire)).toBe(false); 15 | }); 16 | test('Check if return correct expire date', () => { 17 | const now = new Date(); 18 | let date = now.getTime() + 3600 * 1000; 19 | date = new Date(date).toISOString(); 20 | expect(getExpireDate(3600)).toBe(date); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | configureWebpack: { 3 | devtool: 'source-map' 4 | } 5 | }; 6 | --------------------------------------------------------------------------------