├── views ├── index.ejs ├── share │ └── side-menu.ejs ├── err │ ├── occurs-error.ejs │ ├── e401.ejs │ └── e404.ejs ├── layout.ejs ├── invocation │ └── index.ejs └── manager │ └── invocation │ └── index.ejs ├── Procfile ├── public ├── plugins │ ├── clipboard │ │ ├── .travis.yml │ │ ├── .babelrc │ │ ├── package.js │ │ ├── bower.json │ │ ├── .github │ │ │ ├── issue_template.md │ │ │ └── stale.yml │ │ ├── .editorconfig │ │ ├── composer.json │ │ ├── demo │ │ │ ├── target-div.html │ │ │ ├── function-text.html │ │ │ ├── target-textarea.html │ │ │ ├── target-input.html │ │ │ ├── constructor-node.html │ │ │ ├── function-target.html │ │ │ ├── constructor-selector.html │ │ │ └── constructor-nodelist.html │ │ ├── karma.conf.js │ │ ├── LICENSE │ │ ├── webpack.config.js │ │ ├── contributing.md │ │ └── package.json │ └── datatables │ │ ├── keyTable.dataTables.min.css │ │ ├── autoFill.bootstrap4.min.js │ │ ├── buttons.bootstrap4.min.js │ │ ├── responsive.bootstrap4.min.js │ │ ├── buttons.print.min.js │ │ ├── dataTables.bootstrap4.min.js │ │ ├── autoFill.bootstrap4.css │ │ ├── buttons.colVis.min.js │ │ ├── responsive.bootstrap4.min.css │ │ └── buttons.bootstrap4.min.css └── assets │ ├── fonts │ ├── test.ttf │ ├── typicons.eot │ ├── typicons.ttf │ ├── typicons.woff │ ├── themify9f24.eot │ ├── themify9f24.ttf │ ├── themifyd41d.eot │ ├── Tangerine_Bold.ttf │ ├── dripicons-v2.eot │ ├── dripicons-v2.ttf │ ├── dripicons-v2.woff │ ├── fa-brands-400.eot │ ├── fa-brands-400.ttf │ ├── fa-brands-400.woff │ ├── fa-regular-400.eot │ ├── fa-regular-400.ttf │ ├── fa-solid-900.eot │ ├── fa-solid-900.ttf │ ├── fa-solid-900.woff │ ├── fa-solid-900.woff2 │ ├── ionicons6f46.eot │ ├── ionicons6f46.ttf │ ├── ionicons6f46.woff │ ├── ionicons6f46.woff2 │ ├── themify9f24.woff │ ├── typiconsd41d.eot │ ├── dripicons-v2d41d.eot │ ├── fa-brands-400.woff2 │ ├── fa-regular-400.woff │ ├── fa-regular-400.woff2 │ ├── fa-solid-900d41d.eot │ ├── GreatVibes-Regular.ttf │ ├── RougeScript-Regular.ttf │ ├── Tangerine_Regular.ttf │ ├── fa-brands-400d41d.eot │ ├── fa-regular-400d41d.eot │ ├── wedding │ │ ├── VfWedding01.ttf │ │ ├── VfWedding03.ttf │ │ ├── VfWedding04.ttf │ │ ├── VfWedding05.ttf │ │ ├── VfWedding06.ttf │ │ ├── VfWedding07.ttf │ │ ├── VfWedding08.ttf │ │ ├── VfWedding09.ttf │ │ ├── VfWedding10.ttf │ │ ├── VfWedding11.ttf │ │ ├── VfWedding12.ttf │ │ ├── VfWedding14.ttf │ │ ├── VfWedding15.ttf │ │ ├── VfWedding16.ttf │ │ ├── VfWedding17.ttf │ │ ├── VfWedding18.ttf │ │ ├── VfWedding19.ttf │ │ ├── VfWedding21.ttf │ │ ├── VfWedding24.ttf │ │ ├── VfWedding25.ttf │ │ ├── VfWedding26.ttf │ │ ├── VfWedding27.ttf │ │ ├── VfWedding28.ttf │ │ ├── VfWedding29.ttf │ │ ├── VfWedding30.ttf │ │ ├── VfWedding31.ttf │ │ ├── VfWedding32.ttf │ │ ├── VfWedding33.ttf │ │ ├── VfWedding34.ttf │ │ ├── VfWedding01_0.ttf │ │ ├── VfWedding01_1.ttf │ │ ├── VfWedding03_0.ttf │ │ ├── VfWedding03_1.ttf │ │ ├── VfWedding04_0.ttf │ │ ├── VfWedding04_1.ttf │ │ ├── VfWedding05_0.ttf │ │ ├── VfWedding05_1.ttf │ │ ├── VfWedding06_0.ttf │ │ ├── VfWedding06_1.ttf │ │ ├── VfWedding07_0.ttf │ │ ├── VfWedding07_1.ttf │ │ ├── VfWedding08_0.ttf │ │ ├── VfWedding08_1.ttf │ │ ├── VfWedding09_0.ttf │ │ ├── VfWedding09_1.ttf │ │ ├── VfWedding10_0.ttf │ │ ├── VfWedding10_1.ttf │ │ ├── VfWedding11_0.ttf │ │ ├── VfWedding11_1.ttf │ │ ├── VfWedding12_0.ttf │ │ ├── VfWedding12_1.ttf │ │ ├── VfWedding14_0.ttf │ │ ├── VfWedding14_1.ttf │ │ ├── VfWedding15_0.ttf │ │ ├── VfWedding15_1.ttf │ │ ├── VfWedding16_0.ttf │ │ ├── VfWedding16_1.ttf │ │ ├── VfWedding17_0.ttf │ │ ├── VfWedding17_1.ttf │ │ ├── VfWedding18_0.ttf │ │ ├── VfWedding18_1.ttf │ │ ├── VfWedding19_0.ttf │ │ ├── VfWedding19_1.ttf │ │ ├── VfWedding21_0.ttf │ │ ├── VfWedding21_1.ttf │ │ ├── VfWedding22b.ttf │ │ ├── VfWedding22n.ttf │ │ ├── VfWedding23b.ttf │ │ ├── VfWedding23n.ttf │ │ ├── VfWedding24_0.ttf │ │ ├── VfWedding24_1.ttf │ │ ├── VfWedding25_0.ttf │ │ ├── VfWedding25_1.ttf │ │ ├── VfWedding26_0.ttf │ │ ├── VfWedding26_1.ttf │ │ ├── VfWedding27_0.ttf │ │ ├── VfWedding27_1.ttf │ │ ├── VfWedding28_0.ttf │ │ ├── VfWedding28_1.ttf │ │ ├── VfWedding29_0.ttf │ │ ├── VfWedding29_1.ttf │ │ ├── VfWedding30_0.ttf │ │ ├── VfWedding30_1.ttf │ │ ├── VfWedding31_0.ttf │ │ ├── VfWedding31_1.ttf │ │ ├── VfWedding32_0.ttf │ │ ├── VfWedding32_1.ttf │ │ ├── VfWedding33_0.ttf │ │ ├── VfWedding33_1.ttf │ │ ├── VfWedding34_0.ttf │ │ ├── VfWedding34_1.ttf │ │ ├── VfWedding02-Bold.ttf │ │ ├── VfWedding13-Bold.ttf │ │ ├── VfWedding20-Bold.ttf │ │ ├── VfWedding22b_0.ttf │ │ ├── VfWedding22b_1.ttf │ │ ├── VfWedding22n_0.ttf │ │ ├── VfWedding22n_1.ttf │ │ ├── VfWedding23b_0.ttf │ │ ├── VfWedding23b_1.ttf │ │ ├── VfWedding23n_0.ttf │ │ ├── VfWedding23n_1.ttf │ │ ├── VfWedding02-Bold_0.ttf │ │ ├── VfWedding02-Bold_1.ttf │ │ ├── VfWedding02-Normal.ttf │ │ ├── VfWedding13-Bold_0.ttf │ │ ├── VfWedding13-Bold_1.ttf │ │ ├── VfWedding13-Normal.ttf │ │ ├── VfWedding20-Bold_0.ttf │ │ ├── VfWedding20-Bold_1.ttf │ │ ├── VfWedding20-Normal.ttf │ │ ├── VfWedding02-Normal_0.ttf │ │ ├── VfWedding02-Normal_1.ttf │ │ ├── VfWedding13-Normal_0.ttf │ │ ├── VfWedding13-Normal_1.ttf │ │ ├── VfWedding20-Normal_0.ttf │ │ └── VfWedding20-Normal_1.ttf │ ├── PinyonScript-Regular.ttf │ ├── materialdesignicons-webfont772b.eot │ ├── materialdesignicons-webfont772b.ttf │ ├── materialdesignicons-webfontd41d.eot │ ├── materialdesignicons-webfont772b.woff │ ├── materialdesignicons-webfont772b.woff2 │ └── FONTLOG.txt │ ├── images │ ├── bg.jpg │ ├── err.gif │ ├── bg-fb.jpg │ ├── error.png │ ├── favicon.ico │ ├── logo-dark.png │ ├── logo-light.png │ ├── right-top.png │ ├── flags │ │ ├── us_flag.jpg │ │ ├── french_flag.jpg │ │ ├── germany_flag.jpg │ │ ├── italy_flag.jpg │ │ ├── russia_flag.jpg │ │ └── spain_flag.jpg │ ├── maintenance.png │ └── lg.dual-ring-loader.gif │ ├── js │ ├── base │ │ ├── config.js │ │ ├── common.js │ │ ├── form.js │ │ ├── validate.js │ │ ├── notify.js │ │ └── ajax.js │ ├── img.view.js │ ├── live │ │ ├── account │ │ │ └── account.action.js │ │ ├── login.admin.js │ │ ├── chart.statistical.js │ │ └── invocation │ │ │ └── action.js │ ├── imgPreview.min.js │ ├── app.js │ ├── history.char.js │ └── layout.js │ └── css │ ├── metisMenu.min.css.map │ ├── img.view.css │ ├── metismenu.min.css │ ├── custom.css │ └── bootstrap-reboot.min.css ├── .gitignore ├── controllers ├── invitation │ ├── invitation-validator.js │ ├── invitation-router.js │ └── invitation-controller.js ├── manager │ ├── account │ │ ├── account-validator.js │ │ ├── account-router.js │ │ └── account-controller.js │ ├── invocation │ │ ├── invocation-router.js │ │ ├── invocation-validator.js │ │ └── invocation-controller.js │ ├── invitation │ │ ├── invitation-validator.js │ │ ├── invitation-router.js │ │ └── invitation-controller.js │ └── index.js ├── bank │ ├── bank-router.js │ └── bank-controller.js ├── setup │ ├── setup-router.js │ └── setup-controller.js ├── index.js └── invocation │ ├── invocation-validator.js │ ├── invocation-router.js │ └── invocation-controller.js ├── configs ├── data-config.js ├── mongo-db.js └── system-configs.js ├── helpers ├── util.js ├── constants.js └── time-util.js ├── core ├── base-entity.js ├── base-entity-mongodb.js ├── base-core.js ├── base-component.js └── base-controller.js ├── domains ├── handleResult.js └── mongodb │ ├── schemas.js │ ├── seed-db.js │ └── seed-db.json ├── example.env ├── .github └── workflows │ ├── deploy-heroku.yml │ └── quote_generator.yml ├── middlewares └── authentication.js ├── business ├── entities │ └── mongodb │ │ ├── account-entity.js │ │ ├── data-config-entity.js │ │ ├── invitee-entity.js │ │ └── invocation-entity.js ├── components │ ├── data-config │ │ └── data-config-component.js │ ├── auth │ │ └── auth-component.js │ ├── account │ │ └── account-component.js │ ├── invitation │ │ └── invitation-component.js │ └── invocation │ │ └── invocation-component.js └── facade │ └── facade.js ├── index.js ├── LICENSE ├── package.json ├── app.js └── bin └── www /views/index.ejs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: npm run heroku-start -------------------------------------------------------------------------------- /public/plugins/clipboard/.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - stable 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /.idea 3 | /.nyc_output 4 | /npm-debug.log 5 | /.eslintrc.js 6 | /.env 7 | /.snyk -------------------------------------------------------------------------------- /controllers/invitation/invitation-validator.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const {body} = require('express-validator'); 4 | -------------------------------------------------------------------------------- /public/assets/fonts/test.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/test.ttf -------------------------------------------------------------------------------- /public/assets/images/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/images/bg.jpg -------------------------------------------------------------------------------- /public/assets/images/err.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/images/err.gif -------------------------------------------------------------------------------- /controllers/manager/account/account-validator.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const {body} = require('express-validator'); 4 | -------------------------------------------------------------------------------- /public/assets/images/bg-fb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/images/bg-fb.jpg -------------------------------------------------------------------------------- /public/assets/images/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/images/error.png -------------------------------------------------------------------------------- /public/assets/fonts/typicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/typicons.eot -------------------------------------------------------------------------------- /public/assets/fonts/typicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/typicons.ttf -------------------------------------------------------------------------------- /public/assets/fonts/typicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/typicons.woff -------------------------------------------------------------------------------- /public/assets/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/images/favicon.ico -------------------------------------------------------------------------------- /public/assets/fonts/themify9f24.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/themify9f24.eot -------------------------------------------------------------------------------- /public/assets/fonts/themify9f24.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/themify9f24.ttf -------------------------------------------------------------------------------- /public/assets/fonts/themifyd41d.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/themifyd41d.eot -------------------------------------------------------------------------------- /public/assets/images/logo-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/images/logo-dark.png -------------------------------------------------------------------------------- /public/assets/images/logo-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/images/logo-light.png -------------------------------------------------------------------------------- /public/assets/images/right-top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/images/right-top.png -------------------------------------------------------------------------------- /configs/data-config.js: -------------------------------------------------------------------------------- 1 | const DataConfig = { 2 | URI: 'https://wedding.sauanla.com' 3 | }; 4 | 5 | module.exports = DataConfig; 6 | -------------------------------------------------------------------------------- /public/assets/fonts/Tangerine_Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/Tangerine_Bold.ttf -------------------------------------------------------------------------------- /public/assets/fonts/dripicons-v2.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/dripicons-v2.eot -------------------------------------------------------------------------------- /public/assets/fonts/dripicons-v2.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/dripicons-v2.ttf -------------------------------------------------------------------------------- /public/assets/fonts/dripicons-v2.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/dripicons-v2.woff -------------------------------------------------------------------------------- /public/assets/fonts/fa-brands-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/fa-brands-400.eot -------------------------------------------------------------------------------- /public/assets/fonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /public/assets/fonts/fa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/fa-brands-400.woff -------------------------------------------------------------------------------- /public/assets/fonts/fa-regular-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/fa-regular-400.eot -------------------------------------------------------------------------------- /public/assets/fonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /public/assets/fonts/fa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/fa-solid-900.eot -------------------------------------------------------------------------------- /public/assets/fonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /public/assets/fonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/fa-solid-900.woff -------------------------------------------------------------------------------- /public/assets/fonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /public/assets/fonts/ionicons6f46.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/ionicons6f46.eot -------------------------------------------------------------------------------- /public/assets/fonts/ionicons6f46.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/ionicons6f46.ttf -------------------------------------------------------------------------------- /public/assets/fonts/ionicons6f46.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/ionicons6f46.woff -------------------------------------------------------------------------------- /public/assets/fonts/ionicons6f46.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/ionicons6f46.woff2 -------------------------------------------------------------------------------- /public/assets/fonts/themify9f24.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/themify9f24.woff -------------------------------------------------------------------------------- /public/assets/fonts/typiconsd41d.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/typiconsd41d.eot -------------------------------------------------------------------------------- /public/assets/images/flags/us_flag.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/images/flags/us_flag.jpg -------------------------------------------------------------------------------- /public/assets/images/maintenance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/images/maintenance.png -------------------------------------------------------------------------------- /public/assets/fonts/dripicons-v2d41d.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/dripicons-v2d41d.eot -------------------------------------------------------------------------------- /public/assets/fonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /public/assets/fonts/fa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/fa-regular-400.woff -------------------------------------------------------------------------------- /public/assets/fonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /public/assets/fonts/fa-solid-900d41d.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/fa-solid-900d41d.eot -------------------------------------------------------------------------------- /public/assets/fonts/GreatVibes-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/GreatVibes-Regular.ttf -------------------------------------------------------------------------------- /public/assets/fonts/RougeScript-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/RougeScript-Regular.ttf -------------------------------------------------------------------------------- /public/assets/fonts/Tangerine_Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/Tangerine_Regular.ttf -------------------------------------------------------------------------------- /public/assets/fonts/fa-brands-400d41d.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/fa-brands-400d41d.eot -------------------------------------------------------------------------------- /public/assets/fonts/fa-regular-400d41d.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/fa-regular-400d41d.eot -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding01.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding01.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding03.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding03.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding04.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding04.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding05.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding05.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding06.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding06.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding07.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding07.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding08.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding08.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding09.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding09.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding10.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding10.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding11.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding11.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding12.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding12.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding14.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding14.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding15.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding15.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding16.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding16.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding17.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding17.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding18.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding18.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding19.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding19.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding21.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding21.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding24.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding24.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding25.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding25.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding26.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding26.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding27.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding27.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding28.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding28.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding29.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding29.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding30.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding30.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding31.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding31.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding32.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding32.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding33.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding33.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding34.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding34.ttf -------------------------------------------------------------------------------- /public/assets/images/flags/french_flag.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/images/flags/french_flag.jpg -------------------------------------------------------------------------------- /public/assets/images/flags/germany_flag.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/images/flags/germany_flag.jpg -------------------------------------------------------------------------------- /public/assets/images/flags/italy_flag.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/images/flags/italy_flag.jpg -------------------------------------------------------------------------------- /public/assets/images/flags/russia_flag.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/images/flags/russia_flag.jpg -------------------------------------------------------------------------------- /public/assets/images/flags/spain_flag.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/images/flags/spain_flag.jpg -------------------------------------------------------------------------------- /public/assets/fonts/PinyonScript-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/PinyonScript-Regular.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding01_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding01_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding01_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding01_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding03_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding03_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding03_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding03_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding04_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding04_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding04_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding04_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding05_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding05_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding05_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding05_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding06_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding06_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding06_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding06_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding07_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding07_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding07_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding07_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding08_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding08_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding08_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding08_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding09_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding09_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding09_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding09_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding10_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding10_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding10_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding10_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding11_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding11_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding11_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding11_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding12_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding12_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding12_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding12_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding14_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding14_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding14_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding14_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding15_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding15_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding15_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding15_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding16_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding16_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding16_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding16_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding17_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding17_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding17_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding17_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding18_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding18_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding18_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding18_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding19_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding19_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding19_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding19_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding21_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding21_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding21_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding21_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding22b.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding22b.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding22n.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding22n.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding23b.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding23b.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding23n.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding23n.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding24_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding24_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding24_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding24_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding25_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding25_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding25_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding25_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding26_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding26_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding26_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding26_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding27_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding27_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding27_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding27_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding28_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding28_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding28_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding28_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding29_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding29_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding29_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding29_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding30_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding30_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding30_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding30_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding31_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding31_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding31_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding31_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding32_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding32_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding32_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding32_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding33_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding33_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding33_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding33_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding34_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding34_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding34_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding34_1.ttf -------------------------------------------------------------------------------- /public/assets/images/lg.dual-ring-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/images/lg.dual-ring-loader.gif -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding02-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding02-Bold.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding13-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding13-Bold.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding20-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding20-Bold.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding22b_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding22b_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding22b_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding22b_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding22n_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding22n_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding22n_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding22n_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding23b_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding23b_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding23b_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding23b_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding23n_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding23n_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding23n_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding23n_1.ttf -------------------------------------------------------------------------------- /public/plugins/datatables/keyTable.dataTables.min.css: -------------------------------------------------------------------------------- 1 | table.dataTable tbody th.focus,table.dataTable tbody td.focus{box-shadow:inset 0 0 1px 2px #3366FF} 2 | -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding02-Bold_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding02-Bold_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding02-Bold_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding02-Bold_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding02-Normal.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding02-Normal.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding13-Bold_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding13-Bold_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding13-Bold_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding13-Bold_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding13-Normal.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding13-Normal.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding20-Bold_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding20-Bold_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding20-Bold_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding20-Bold_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding20-Normal.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding20-Normal.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding02-Normal_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding02-Normal_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding02-Normal_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding02-Normal_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding13-Normal_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding13-Normal_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding13-Normal_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding13-Normal_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding20-Normal_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding20-Normal_0.ttf -------------------------------------------------------------------------------- /public/assets/fonts/wedding/VfWedding20-Normal_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/wedding/VfWedding20-Normal_1.ttf -------------------------------------------------------------------------------- /public/assets/fonts/materialdesignicons-webfont772b.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/materialdesignicons-webfont772b.eot -------------------------------------------------------------------------------- /public/assets/fonts/materialdesignicons-webfont772b.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/materialdesignicons-webfont772b.ttf -------------------------------------------------------------------------------- /public/assets/fonts/materialdesignicons-webfontd41d.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/materialdesignicons-webfontd41d.eot -------------------------------------------------------------------------------- /public/assets/fonts/materialdesignicons-webfont772b.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/materialdesignicons-webfont772b.woff -------------------------------------------------------------------------------- /public/assets/fonts/materialdesignicons-webfont772b.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauanla/wedding-invitation/HEAD/public/assets/fonts/materialdesignicons-webfont772b.woff2 -------------------------------------------------------------------------------- /helpers/util.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | 4 | class Util { 5 | 6 | static generateUuid() { 7 | const uuidv4 = require('uuid/v4'); 8 | return uuidv4(); 9 | } 10 | 11 | } 12 | 13 | module.exports = Util; 14 | -------------------------------------------------------------------------------- /public/plugins/clipboard/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "env", 5 | { 6 | "targets": { 7 | "uglify": true 8 | }, 9 | "modules": false 10 | } 11 | ] 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /core/base-entity.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const BaseCore = require('../core/base-core'); 4 | 5 | class BaseEntity extends BaseCore { 6 | 7 | constructor() { 8 | super(); 9 | } 10 | } 11 | 12 | module.exports = BaseEntity; 13 | -------------------------------------------------------------------------------- /public/assets/js/base/config.js: -------------------------------------------------------------------------------- 1 | const qrCodeSrc = 'https://barcode.tec-it.com/barcode.ashx?data={code}&code=MobileQRCode&multiplebarcodes=false&translate-esc=false&unit=Fit&dpi=96&imagetype=Gif&rotation=0&color=%23000000&bgcolor=%23ffffff&codepage=&qunit=Mm&quiet=0&eclevel=L'; -------------------------------------------------------------------------------- /public/assets/js/img.view.js: -------------------------------------------------------------------------------- 1 | $(() => $.imgPreview()); 2 | $.imgPreview({ 3 | el: "[data-pic]", 4 | attr: "data-pic", 5 | attrTitle: "data-pic-title", 6 | attrDesc: "data-pic-desc", 7 | mode: "single", 8 | isMaskShow: true, 9 | maskBgColor: "rgba(0,0,0,.5)" 10 | }); 11 | -------------------------------------------------------------------------------- /controllers/bank/bank-router.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | const express = require("express"); 3 | const Controller = require("./bank-controller"); 4 | 5 | const controller = new Controller(); 6 | const router = express.Router(); 7 | 8 | router.get("/", controller.bankPage); 9 | 10 | module.exports = router; 11 | -------------------------------------------------------------------------------- /controllers/setup/setup-router.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | const express = require("express"); 3 | const Controller = require("./setup-controller"); 4 | 5 | const controller = new Controller(); 6 | const router = express.Router(); 7 | 8 | router.get("/", controller.setupPage); 9 | 10 | module.exports = router; 11 | -------------------------------------------------------------------------------- /domains/handleResult.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class HandleResult { 4 | 5 | constructor(success, data, messageList) { 6 | this.success = success || false; 7 | this.data = data || {}; 8 | this.messageList = messageList || []; 9 | } 10 | } 11 | 12 | module.exports = HandleResult; 13 | -------------------------------------------------------------------------------- /public/assets/js/base/common.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | var urlSplit = window.location.pathname.split('/'); 3 | if (urlSplit.length == 4) { 4 | $('#menu-' + urlSplit[2]).addClass('active-sub active'); 5 | } else { 6 | $('#menu-Dashboard').addClass('active-sub active'); 7 | } 8 | }); -------------------------------------------------------------------------------- /core/base-entity-mongodb.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const mongoose = require('mongoose'); 4 | const BaseCore = require('../core/base-core'); 5 | 6 | class BaseEntityMongoDb extends BaseCore { 7 | 8 | constructor(model, schema) { 9 | super(); 10 | this._model = mongoose.model(model, schema); 11 | } 12 | } 13 | 14 | module.exports = BaseEntityMongoDb; -------------------------------------------------------------------------------- /public/plugins/clipboard/package.js: -------------------------------------------------------------------------------- 1 | // Package metadata for Meteor.js. 2 | 3 | Package.describe({ 4 | name: "zenorocha:clipboard", 5 | summary: "Modern copy to clipboard. No Flash. Just 3kb.", 6 | version: "2.0.6", 7 | git: "https://github.com/zenorocha/clipboard.js" 8 | }); 9 | 10 | Package.onUse(function(api) { 11 | api.addFiles("dist/clipboard.js", "client"); 12 | }); 13 | -------------------------------------------------------------------------------- /example.env: -------------------------------------------------------------------------------- 1 | NODE_ENV = development 2 | 3 | PORT = 3001 4 | NAME = 'WEDDING-INVITATION' 5 | 6 | // https://cloud.mongodb.com/ 7 | // https://i.imgur.com/Om20WQc.png 8 | URI_MONGO = 'URI' 9 | DOMAIN = 'http://localhost:3001' 10 | 11 | //https://www.google.com/recaptcha/admin 12 | SITE_KEY = 'SITE_KEY' 13 | SECRET_KEY = 'SECRET_KEY' 14 | 15 | BODY_PARSER_URLENCODED_LIMIT = '10mb' 16 | BODY_PARSER_JSON_LIMIT = '10mb' 17 | -------------------------------------------------------------------------------- /controllers/invitation/invitation-router.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | const express = require("express"); 3 | const Controller = require("./invitation-controller"); 4 | 5 | const controller = new Controller(); 6 | const router = express.Router(); 7 | 8 | router.get("/", controller.defaultPage); 9 | router.get('/:id', controller.detailInvitation); 10 | router.get('/bank', controller.bankPage); 11 | 12 | module.exports = router; 13 | -------------------------------------------------------------------------------- /controllers/manager/invocation/invocation-router.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | const express = require("express"); 3 | const Controller = require("./invocation-controller"); 4 | const validator = require("./invocation-validator"); 5 | 6 | const controller = new Controller(); 7 | const router = express.Router(); 8 | 9 | router.get('/', controller.listInvocationRender); 10 | router.delete('/', controller.deleteInvocation); 11 | 12 | module.exports = router; 13 | -------------------------------------------------------------------------------- /public/plugins/clipboard/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "clipboard", 3 | "version": "2.0.6", 4 | "description": "Modern copy to clipboard. No Flash. Just 3kb", 5 | "license": "MIT", 6 | "main": "dist/clipboard.js", 7 | "ignore": [ 8 | "/.*/", 9 | "/demo/", 10 | "/test/", 11 | "/.*", 12 | "/bower.json", 13 | "/karma.conf.js", 14 | "/src", 15 | "/lib" 16 | ], 17 | "keywords": [ 18 | "clipboard", 19 | "copy", 20 | "cut" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /public/plugins/clipboard/.github/issue_template.md: -------------------------------------------------------------------------------- 1 | ### Minimal example 2 | 3 | > Fork this [JSFiddle](https://jsfiddle.net/zenorocha/5kk0eysw/) and reproduce your issue. 4 | 5 | ### Expected behaviour 6 | 7 | I thought that by going to the page '...' and pressing the button '...' then '...' would happen. 8 | 9 | ### Actual behaviour 10 | 11 | Instead of '...', what I saw was that '...' happened instead. 12 | 13 | ### Browsers affected 14 | 15 | I tested on all major browsers and only IE 11 does not work. 16 | -------------------------------------------------------------------------------- /.github/workflows/deploy-heroku.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Heroku 2 | 3 | on: 4 | push: 5 | branches: [product] 6 | jobs: 7 | 8 | deploy: 9 | name: Deploy 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v2 13 | - uses: akhileshns/heroku-deploy@v3.12.12 # This is the action 14 | with: 15 | heroku_api_key: ${{secrets.HEROKU_API_KEY}} 16 | heroku_app_name: ${{ secrets.HEROKU_APP_NAME }} 17 | heroku_email: "phucnd.zit@gmail.com" 18 | -------------------------------------------------------------------------------- /middlewares/authentication.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | 4 | exports.requiresLogin = function (req, res, next) { 5 | if (req.session && req.session.user) { 6 | return next(); 7 | } else { 8 | return res.redirect('/manager/account/login'); 9 | } 10 | }; 11 | 12 | exports.requiresLogout = function (req, res, next) { 13 | if (req.session && req.session.user) { 14 | return res.json({err: 'You must be Logout in to Login continue'}); 15 | } else { 16 | return next(); 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /public/assets/css/metisMenu.min.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sourceRoot":"","sources":["../src/metisMenu.scss"],"names":[],"mappings":"CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,kBACE,YACA,oBAEF,6BACE,WAQF,mCACE,YAEF,gDACE,YAQF,4BACE,YAEF,yCACE,YAQF,6BACE,YAEF,0CACE,YAEF,uBACE,YAEF,kCACE,WAEF,iCACE,YAEF,uCACE,wBAEF,uBACE,YAEF,kCACE,WAEF,iCACE,YAEF,8CACE,YAEF,sCACE,aAGF,0BACE,kBACA,SACA,gBACA,gCACA,yBACA,sCAGF,sBACE,kBAGF,6BACE,kBACA,WACA,WACA,YACA,yBACA,mBACA,qBACA,UACA,4CACA,qBACA,QACA,4BAGF,wCACE,WACA,SACA,4CAGF,yFAEE,6CAGF,+GAEE","file":"metisMenu.min.css"} -------------------------------------------------------------------------------- /controllers/manager/invitation/invitation-validator.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const {body} = require('express-validator'); 3 | 4 | exports.invitationValidator = [ 5 | body('invitee') 6 | .exists().withMessage('invitee is required') 7 | .isObject().withMessage('invitee must be an object'), 8 | body('invitee.name').exists() 9 | .withMessage('name is required'), 10 | body('invitee.area') 11 | .exists().withMessage('Area a required') 12 | .isNumeric().withMessage('Area must be select') 13 | 14 | ]; 15 | 16 | -------------------------------------------------------------------------------- /public/assets/js/base/form.js: -------------------------------------------------------------------------------- 1 | const form = { 2 | serializeFormJSON: form => { 3 | var o = {}; 4 | var a = form.serializeArray(); 5 | $.each(a, function () { 6 | if (o[this.name]) { 7 | if (!o[this.name].push) { 8 | o[this.name] = [o[this.name]]; 9 | } 10 | o[this.name].push(this.value || ""); 11 | } else { 12 | o[this.name] = this.value || ""; 13 | } 14 | }); 15 | return o; 16 | } 17 | }; -------------------------------------------------------------------------------- /public/assets/js/base/validate.js: -------------------------------------------------------------------------------- 1 | const validator = { 2 | faIcon: { 3 | valid: 'fa fa-check-circle fa-lg text-success', 4 | invalid: 'fa fa-times-circle fa-lg', 5 | validating: 'fa fa-refresh' 6 | }, 7 | valid: (formid, _fields, _callBack) => { 8 | $(`#${formid}`).bootstrapValidator({ 9 | message: 'This value is not valid', 10 | excluded: [':disabled'], 11 | feedbackIcons: this.faIcon, 12 | fields: _fields 13 | }).on('success.form.bv', _callBack); 14 | } 15 | }; -------------------------------------------------------------------------------- /core/base-core.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Util = require('../helpers/util'); 4 | const TimeUtil = require('../helpers/time-util'); 5 | const Constants = require('../helpers/constants'); 6 | const sysConfig = require('../configs/system-configs'); 7 | const log = sysConfig.log(); 8 | 9 | class BaseCore { 10 | 11 | constructor() { 12 | this._config = sysConfig; 13 | this._util = Util; 14 | this._timeUtil = TimeUtil; 15 | this._constant = Constants; 16 | this._log = log; 17 | } 18 | } 19 | 20 | module.exports = BaseCore; 21 | -------------------------------------------------------------------------------- /controllers/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const express = require('express'); 4 | const router = express.Router(); 5 | 6 | /* GET home page. */ 7 | router.get('/', (req, res) => { 8 | res.redirect("/invitation") 9 | }); 10 | 11 | router.use('/invitation', require('./invitation/invitation-router')); 12 | router.use('/invocation', require('./invocation/invocation-router')); 13 | 14 | router.use('/bank', require('./bank/bank-router')); 15 | 16 | router.use('/manager', require('./manager')); 17 | 18 | router.use('/setup', require('./setup/setup-router')); 19 | 20 | module.exports = router; 21 | -------------------------------------------------------------------------------- /helpers/constants.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.ERROR_CODE = { 4 | CONTROLLER: '2000', 5 | FACADE: '2100', 6 | BUSINESS_COMPONENT: '2200', 7 | BUSINESS_ENTITIES: '2300', 8 | VALIDATOR: '3000', 9 | }; 10 | 11 | 12 | exports.MONGODB = { 13 | INSTANCES: { 14 | ACCOUNT: 'account', 15 | INVITEE: 'invitee', 16 | INVOCATION: 'invocation', 17 | DATA_CONFIG: 'data_config' 18 | } 19 | }; 20 | 21 | 22 | exports.AREA = { 23 | MALE: 1, 24 | FEMALE: 0 25 | }; 26 | 27 | exports.MODE = { 28 | DEFAULT: 1, 29 | HAS_DATA: 2 30 | }; 31 | -------------------------------------------------------------------------------- /public/plugins/clipboard/.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # http://editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | # Change these settings to your own preference 9 | indent_style = space 10 | indent_size = 4 11 | 12 | # We recommend you to keep these unchanged 13 | end_of_line = lf 14 | charset = utf-8 15 | trim_trailing_whitespace = true 16 | insert_final_newline = true 17 | 18 | [*.md] 19 | trim_trailing_whitespace = false 20 | 21 | [{package.json,bower.json}] 22 | indent_size = 2 23 | -------------------------------------------------------------------------------- /public/plugins/datatables/autoFill.bootstrap4.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | Bootstrap integration for DataTables' AutoFill 3 | ©2015 SpryMedia Ltd - datatables.net/license 4 | */ 5 | (function(b){"function"===typeof define&&define.amd?define(["jquery","datatables.net-bs4","datatables.net-autofill"],function(a){return b(a,window,document)}):"object"===typeof exports?module.exports=function(a,c){a||(a=window);c&&c.fn.dataTable||(c=require("datatables.net-bs4")(a,c).$);c.fn.dataTable.AutoFill||require("datatables.net-autofill")(a,c);return b(c,a,a.document)}:b(jQuery,window,document)})(function(b,a,c,d){b=b.fn.dataTable;b.AutoFill.classes.btn="btn btn-primary";return b}); 6 | -------------------------------------------------------------------------------- /public/plugins/clipboard/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "zenorocha/clipboardjs", 3 | "description": "Modern copy to clipboard. No Flash. Just 3kb gzipped https://clipboardjs.com", 4 | "type": "component", 5 | "homepage": "https://clipboardjs.com/", 6 | "authors": [ 7 | { 8 | "name": "Zeno Rocha", 9 | "homepage": "http://zenorocha.com/" 10 | } 11 | ], 12 | "require": { 13 | "oomphinc/composer-installers-extender": "*" 14 | }, 15 | "extra": { 16 | "component": { 17 | "scripts": [ 18 | "dist/clipboard.js" 19 | ], 20 | "files": [ 21 | "dist/clipboard.min.js" 22 | ] 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /public/assets/css/img.view.css: -------------------------------------------------------------------------------- 1 | .img-preview-mask { 2 | width: 100%; 3 | height: 100%; 4 | position: fixed; 5 | top: 0; 6 | left: 0; 7 | z-index: 9998; 8 | background-color: rgba(0, 0, 0, 0.5); 9 | } 10 | 11 | .img-preview-popover { 12 | position: fixed; 13 | z-index: 9999; 14 | } 15 | .img-preview-foot { 16 | width: 96%; 17 | padding: 0 2%; 18 | position: absolute; 19 | bottom: 0; 20 | background-color: rgba(0, 0, 0, 0.5); 21 | } 22 | 23 | .img-foot-title { 24 | font-size: 16px; 25 | color: #fff; 26 | margin-top: 5px; 27 | } 28 | 29 | .img-foot-desc { 30 | font-size: 12px; 31 | color: #fff; 32 | margin-top: 5px; 33 | line-height: 24px; 34 | } 35 | -------------------------------------------------------------------------------- /controllers/manager/invitation/invitation-router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const express = require('express'); 3 | const Controller = require('./invitation-controller'); 4 | const validator = require('./invitation-validator'); 5 | 6 | const controller = new Controller(); 7 | const router = express.Router(); 8 | 9 | 10 | //manager 11 | router.get('/', controller.list); 12 | router.get('/:id/detail', controller.detail); 13 | 14 | router.post('/create', 15 | validator.invitationValidator, 16 | controller.create); 17 | 18 | router.put('/update', 19 | validator.invitationValidator, 20 | controller.update); 21 | 22 | router.delete('/delete', controller.del); 23 | 24 | 25 | module.exports = router; 26 | -------------------------------------------------------------------------------- /configs/mongo-db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Import the mongoose module 4 | const mongoose = require('mongoose'); 5 | const sysConfig = require('./system-configs'); 6 | const log = sysConfig.log(); 7 | 8 | // Get Mongoose to use the global promise library 9 | mongoose.Promise = global.Promise; 10 | 11 | // Connecting to the database 12 | mongoose.connect(sysConfig.uri, { 13 | useNewUrlParser: true, 14 | useUnifiedTopology: true, 15 | useFindAndModify: false, 16 | useCreateIndex: true, 17 | }).then(() => { 18 | log.info('Successfully connected to the mongodb database'); 19 | }).catch(err => { 20 | log.info('Could not connect to the database. Exiting now...', err); 21 | process.exit(); 22 | }); 23 | -------------------------------------------------------------------------------- /.github/workflows/quote_generator.yml: -------------------------------------------------------------------------------- 1 | name: quote_generator 2 | 3 | on: 4 | workflow_dispatch: 5 | schedule: 6 | - cron: "00 00 * * *" 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v2 14 | - uses: actions/setup-node@v1 15 | with: 16 | node-version: 12.21.0 17 | - run: npm ci 18 | - name: Generate quote 19 | run: npm run generate 20 | - name: Update README.md 21 | run: | 22 | git config --global user.email "minhphucpk.1997@gmail.com" 23 | git config --global user.name "dinhphuc" 24 | git add . 25 | git commit -m "Updated README.md" || echo "Random Quote to commit" 26 | git push 27 | -------------------------------------------------------------------------------- /controllers/manager/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const express = require('express'); 4 | const router = express.Router(); 5 | 6 | const auth = require('../../middlewares/authentication'); 7 | /* GET login. */ 8 | router.get('/', (req, res) => { 9 | if (req.session && req.session.user) { 10 | res.redirect('/manager/invitation'); 11 | } else { 12 | return res.redirect('/manager/account/login'); 13 | } 14 | }); 15 | 16 | router.use('/invitation', auth.requiresLogin, require('./invitation/invitation-router')); 17 | router.use('/invocation', auth.requiresLogin, require('./invocation/invocation-router')); 18 | router.use('/account', require('./account/account-router')); 19 | 20 | module.exports = router; 21 | -------------------------------------------------------------------------------- /controllers/invocation/invocation-validator.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | const { body } = require('express-validator'); 4 | 5 | exports.invocationValidator = [ 6 | body('invocation') 7 | .exists().withMessage('invocation is required') 8 | .isObject().withMessage('invocation must be an object'), 9 | body('invocation.inviteeId').exists() 10 | .withMessage('name is required'), 11 | body('invocation.name').exists() 12 | .withMessage('Name a required'), 13 | body('invocation.phone').exists() 14 | .withMessage('Phone a required'), 15 | body('invocation.status').exists() 16 | .withMessage('Status a required') 17 | .isNumeric() 18 | .withMessage('Status must be select') 19 | ]; -------------------------------------------------------------------------------- /controllers/manager/invocation/invocation-validator.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | const { body } = require('express-validator'); 4 | 5 | exports.invocationValidator = [ 6 | body('invocation') 7 | .exists().withMessage('invocation is required') 8 | .isObject().withMessage('invocation must be an object'), 9 | body('invocation.inviteeId').exists() 10 | .withMessage('name is required'), 11 | body('invocation.name').exists() 12 | .withMessage('Name a required'), 13 | body('invocation.phone').exists() 14 | .withMessage('Phone a required'), 15 | body('invocation.status').exists() 16 | .withMessage('Status a required') 17 | .isNumeric() 18 | .withMessage('Status must be select') 19 | ]; -------------------------------------------------------------------------------- /core/base-component.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const BaseCore = require('../core/base-core'); 4 | 5 | class BaseComponent extends BaseCore { 6 | 7 | constructor() { 8 | super(); 9 | } 10 | 11 | _handleResult(result, resolve) { 12 | return resolve(result); 13 | } 14 | 15 | _handleError(error, reject) { 16 | this._log.error(error); 17 | 18 | return reject(error); 19 | } 20 | 21 | _handleThrowError(error) { 22 | this._log.error(error); 23 | throw error; 24 | } 25 | 26 | _generateError(message) { 27 | const error = {code: this._constant.ERROR_CODE.BUSINESS_COMPONENT, message: message}; 28 | return error; 29 | } 30 | } 31 | 32 | module.exports = BaseComponent; -------------------------------------------------------------------------------- /business/entities/mongodb/account-entity.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const BaseEntityMongoDb = require('../../../core/base-entity-mongodb'); 4 | const model = require('../../../helpers/constants').MONGODB.INSTANCES.ACCOUNT; 5 | const schema = require('../../../domains/mongodb/schemas').SCHEMAS.ACCOUNT; 6 | 7 | class AccountEntity extends BaseEntityMongoDb { 8 | 9 | constructor() { 10 | super(model, schema); 11 | } 12 | 13 | 14 | findOne(username, fieldObj = null) { 15 | return this._model.findOne({ 16 | username: username 17 | }, fieldObj); 18 | } 19 | 20 | add(data) { 21 | let newObj = new this._model(data); 22 | return newObj.save(); 23 | } 24 | 25 | } 26 | 27 | module.exports = AccountEntity; 28 | -------------------------------------------------------------------------------- /controllers/invocation/invocation-router.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | const express = require("express"); 3 | const Controller = require("./invocation-controller"); 4 | const validator = require("./invocation-validator"); 5 | 6 | const controller = new Controller(); 7 | const router = express.Router(); 8 | 9 | const recaptchaModel = require('express-recaptcha').RecaptchaV3; 10 | const recaptcha = new recaptchaModel( 11 | process.env.SITE_KEY, 12 | process.env.SECRET_KEY, 13 | { 14 | callback: 'cb', 15 | } 16 | ); 17 | router.get('/:id', recaptcha.middleware.renderWith({hl: 'vi'}), controller.createInvocationRender); 18 | router.post('/',recaptcha.middleware.verify, validator.invocationValidator, controller.createInvocation); 19 | 20 | module.exports = router; 21 | -------------------------------------------------------------------------------- /public/plugins/clipboard/.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 60 3 | 4 | # Number of days of inactivity before a stale issue is closed 5 | daysUntilClose: 7 6 | 7 | # Issues with these labels will never be considered stale 8 | exemptLabels: 9 | - pinned 10 | 11 | # Label to use when marking an issue as stale 12 | staleLabel: stale 13 | 14 | # Comment to post when marking an issue as stale. Set to `false` to disable 15 | markComment: > 16 | This issue has been automatically marked as stale because it has not had 17 | recent activity. It will be closed if no further activity occurs. Thank you 18 | for your contributions. 19 | 20 | # Comment to post when closing a stale issue. Set to `false` to disable 21 | closeComment: false 22 | -------------------------------------------------------------------------------- /business/entities/mongodb/data-config-entity.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const BaseEntityMongoDb = require('../../../core/base-entity-mongodb'); 4 | const model = require('../../../helpers/constants').MONGODB.INSTANCES.DATA_CONFIG; 5 | const schema = require('../../../domains/mongodb/schemas').SCHEMAS.DATA_CONFIG; 6 | 7 | class DataConfigEntity extends BaseEntityMongoDb { 8 | 9 | constructor() { 10 | super(model, schema); 11 | } 12 | 13 | 14 | getDefaultDataConfig(fieldObj = null) { 15 | return this._model.findOne({ 16 | default: true 17 | }, fieldObj); 18 | } 19 | 20 | addDefaultDataConfig(data) { 21 | let newObj = new this._model(data); 22 | return newObj.save(); 23 | } 24 | } 25 | 26 | module.exports = DataConfigEntity; 27 | -------------------------------------------------------------------------------- /business/components/data-config/data-config-component.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const BaseCore = require("../../../core/base-core"); 4 | const DataConfigEntity = require("../../entities/mongodb/data-config-entity"); 5 | 6 | 7 | 8 | class DataConfiComponent extends BaseCore { 9 | constructor() { 10 | super(); 11 | 12 | this._dataConfigEntity = new DataConfigEntity; 13 | } 14 | 15 | async getDefaultDataConfig() { 16 | 17 | let configs = await this._dataConfigEntity.getDefaultDataConfig(); 18 | return configs; 19 | } 20 | 21 | async addDefaultDataConfig(data) { 22 | 23 | let invitees = await this._dataConfigEntity.addDefaultDataConfig(data); 24 | return invitees; 25 | } 26 | 27 | } 28 | 29 | module.exports = DataConfiComponent; 30 | -------------------------------------------------------------------------------- /public/plugins/clipboard/demo/target-div.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | target-div 6 | 7 | 8 | 9 | 10 |
hello
11 | 12 | 13 | 14 | 15 | 16 | 17 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /public/plugins/clipboard/karma.conf.js: -------------------------------------------------------------------------------- 1 | var webpackConfig = require('./webpack.config.js'); 2 | 3 | module.exports = function (karma) { 4 | karma.set({ 5 | plugins: ['karma-webpack', 'karma-chai', 'karma-sinon', 'karma-mocha', 'karma-chrome-launcher'], 6 | 7 | frameworks: ['chai', 'sinon', 'mocha'], 8 | 9 | files: [ 10 | 'src/**/*.js', 11 | 'test/**/*.js', 12 | ], 13 | 14 | preprocessors: { 15 | 'src/**/*.js': ['webpack'], 16 | 'test/**/*.js': ['webpack'] 17 | }, 18 | 19 | webpack: { 20 | module: webpackConfig.module, 21 | plugins: webpackConfig.plugins 22 | }, 23 | 24 | webpackMiddleware: { 25 | stats: 'errors-only' 26 | }, 27 | 28 | browsers: ['ChromeHeadless'] 29 | }); 30 | }; 31 | -------------------------------------------------------------------------------- /helpers/time-util.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const sysConfig = require('../configs/system-configs'); 4 | const log = sysConfig.log(); 5 | 6 | class TimeUtil { 7 | 8 | constructor() { 9 | this._diffTime = 0; 10 | log.info('--------------- INIT TIME-UTIL CLASS ---------------'); 11 | } 12 | 13 | setCurrentTime(serverTime) { 14 | let systemTime = new Date().getTime(); 15 | 16 | this._diffTime = serverTime - systemTime; 17 | log.info(`systemTime: ${systemTime}, serverTime: ${serverTime}, diffTime: ${this._diffTime}`); 18 | } 19 | 20 | getCurrentTime() { 21 | let systemTime = new Date().getTime(); 22 | let currentTime = systemTime + this._diffTime; 23 | 24 | log.info(`current time: ${currentTime}`); 25 | 26 | return currentTime; 27 | } 28 | } 29 | 30 | module.exports = new TimeUtil(); -------------------------------------------------------------------------------- /public/plugins/clipboard/demo/function-text.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | function-text 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /public/plugins/clipboard/demo/target-textarea.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | target-textarea 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /public/plugins/clipboard/demo/target-input.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | target-input 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /public/plugins/clipboard/demo/constructor-node.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | constructor-node 6 | 7 | 8 | 9 | 10 |
11 | Copy 12 |
13 | 14 | 15 | 16 | 17 | 18 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /controllers/manager/account/account-router.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const auth = require('../../../middlewares/authentication'); 4 | const express = require("express"); 5 | const Controller = require("./account-controller"); 6 | const validator = require("./account-validator"); 7 | 8 | const controller = new Controller(); 9 | const router = express.Router(); 10 | 11 | const recaptchaModel = require('express-recaptcha').RecaptchaV3; 12 | 13 | const recaptcha = new recaptchaModel( 14 | process.env.SITE_KEY, 15 | process.env.SECRET_KEY, 16 | { 17 | callback: 'cb', 18 | } 19 | ); 20 | 21 | 22 | router.get("/login", recaptcha.middleware.renderWith({hl: 'vi'}), auth.requiresLogout, controller.loginRender); 23 | router.post("/login", recaptcha.middleware.verify, auth.requiresLogout, controller.login); 24 | router.get("/logout", auth.requiresLogin, controller.logout); 25 | 26 | module.exports = router; 27 | -------------------------------------------------------------------------------- /public/plugins/clipboard/demo/function-target.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | function-target 6 | 7 | 8 | 9 | 10 | 11 |
hello
12 | 13 | 14 | 15 | 16 | 17 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /public/plugins/datatables/buttons.bootstrap4.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | Bootstrap integration for DataTables' Buttons 3 | ©2016 SpryMedia Ltd - datatables.net/license 4 | */ 5 | (function(c){"function"===typeof define&&define.amd?define(["jquery","datatables.net-bs4","datatables.net-buttons"],function(a){return c(a,window,document)}):"object"===typeof exports?module.exports=function(a,b){a||(a=window);if(!b||!b.fn.dataTable)b=require("datatables.net-bs4")(a,b).$;b.fn.dataTable.Buttons||require("datatables.net-buttons")(a,b);return c(b,a,a.document)}:c(jQuery,window,document)})(function(c){var a=c.fn.dataTable;c.extend(!0,a.Buttons.defaults,{dom:{container:{className:"dt-buttons btn-group"}, 6 | button:{className:"btn btn-secondary"},collection:{tag:"div",className:"dt-button-collection dropdown-menu",button:{tag:"a",className:"dt-button dropdown-item",active:"active",disabled:"disabled"}}}});a.ext.buttons.collection.className+=" dropdown-toggle";return a.Buttons}); 7 | -------------------------------------------------------------------------------- /configs/system-configs.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | require('dotenv').config(); 4 | const bunyan = require('bunyan'); 5 | 6 | const log = { 7 | development: () => { 8 | return bunyan.createLogger({name: 'development', level: 'debug'}); 9 | }, 10 | production: () => { 11 | return bunyan.createLogger({name: 'production', level: 'info'}); 12 | }, 13 | test: () => { 14 | return bunyan.createLogger({name: 'test', level: 'fatal'}); 15 | } 16 | }; 17 | 18 | module.exports = { 19 | name: process.env.NAME, 20 | siteKey: process.env.SITE_KEY, 21 | secretKey: process.env.SECRET_KEY, 22 | uri: process.env.URI_MONGO, 23 | domain: process.env.DOMAIN, 24 | bodyParserUrlencodedLimit: process.env.BODY_PARSER_URLENCODED_LIMIT, 25 | bodyParserJsonLimit: process.env.BODY_PARSER_JSON_LIMIT, 26 | log: (env) => { 27 | if (env) return log[env](); 28 | return log['development'](); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /public/plugins/clipboard/demo/constructor-selector.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | constructor-selector 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /public/plugins/clipboard/demo/constructor-nodelist.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | constructor-nodelist 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /business/entities/mongodb/invitee-entity.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const BaseEntityMongoDb = require('../../../core/base-entity-mongodb'); 4 | const model = require('../../../helpers/constants').MONGODB.INSTANCES.INVITEE; 5 | const schema = require('../../../domains/mongodb/schemas').SCHEMAS.INVITEE; 6 | 7 | class AccountEntity extends BaseEntityMongoDb { 8 | 9 | constructor() { 10 | super(model, schema); 11 | } 12 | 13 | list() { 14 | return this._model.find({}).sort([['_id', -1]]); 15 | 16 | } 17 | 18 | findById(id) { 19 | return this._model.findById(id); 20 | } 21 | 22 | add(data) { 23 | let newObj = new this._model(data); 24 | return newObj.save(); 25 | } 26 | 27 | remove(id) { 28 | return this._model.remove({ _id: id }); 29 | } 30 | 31 | update(id, fieldObj) { 32 | return this._model.findByIdAndUpdate(id, { 33 | '$set': fieldObj 34 | }, { upsert: true }); 35 | } 36 | 37 | } 38 | 39 | module.exports = AccountEntity; 40 | -------------------------------------------------------------------------------- /business/entities/mongodb/invocation-entity.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const BaseEntityMongoDb = require('../../../core/base-entity-mongodb'); 4 | const model = require('../../../helpers/constants').MONGODB.INSTANCES.INVOCATION; 5 | const schema = require('../../../domains/mongodb/schemas').SCHEMAS.INVOCATION; 6 | 7 | class InvocationEntity extends BaseEntityMongoDb { 8 | 9 | constructor() { 10 | super(model, schema); 11 | } 12 | 13 | list() { 14 | return this._model.find({}).sort([['_id', -1]]); 15 | } 16 | 17 | findById(id) { 18 | return this._model.findById(id); 19 | } 20 | 21 | add(data) { 22 | let newObj = new this._model(data); 23 | return newObj.save(); 24 | } 25 | 26 | remove(id) { 27 | return this._model.remove({ _id: id }); 28 | } 29 | 30 | update(id, fieldObj) { 31 | return this._model.findByIdAndUpdate(id, { 32 | '$set': fieldObj 33 | }, { upsert: true }); 34 | } 35 | 36 | } 37 | 38 | module.exports = InvocationEntity; 39 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | const fs = require("fs"); 3 | 4 | const getQuote = async () => { 5 | try { 6 | const { data } = await axios.get("https://api.goprogram.ai/inspiration"); 7 | const quote = data.quote; 8 | const author = data.author; 9 | 10 | console.log("new quote", `"${quote}"`); 11 | 12 | return { 13 | quote, 14 | author, 15 | }; 16 | } catch (err) { 17 | console.error(err.message); 18 | return {}; 19 | } 20 | }; 21 | 22 | const generate = async () => { 23 | const { quote, author } = await getQuote(); 24 | 25 | if (!quote) return; 26 | 27 | const content = fs.readFileSync("README.md", "utf8"); 28 | 29 | const lastIndex = content.indexOf("⚡"); 30 | if (lastIndex !== -1) { 31 | let subContent = content.substring(0, lastIndex); 32 | subContent += `⚡ Quote: \n**${quote}**\n\n${author}` 33 | fs.writeFileSync("README.md", subContent); 34 | return; 35 | } 36 | 37 | fs.appendFileSync("README.md", `⚡ Quote: \n**${quote}**\n\n${author}`); 38 | }; 39 | 40 | generate(); 41 | -------------------------------------------------------------------------------- /public/assets/js/base/notify.js: -------------------------------------------------------------------------------- 1 | const notify = { 2 | EType: { 3 | SUCCESS: 'success', 4 | DANGER: 'danger', 5 | WARNING: 'warning' 6 | }, 7 | push: (messenger, type) => { 8 | let icon; 9 | switch (type) { 10 | case notify.EType.SUCCESS: 11 | toastr.success(messenger); 12 | break; 13 | case notify.EType.DANGER: 14 | toastr.error(messenger); 15 | break; 16 | default: 17 | icon = 'fa fa-check'; 18 | break; 19 | } 20 | 21 | }, 22 | loading: () => { 23 | let html = 24 | `
25 |
26 | 27 |
`; 28 | $('body').append(html); 29 | }, 30 | done: () => { 31 | $('#loading').remove(); 32 | } 33 | }; -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 sauanla 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 | -------------------------------------------------------------------------------- /public/plugins/clipboard/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Zeno Rocha 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 | -------------------------------------------------------------------------------- /views/share/side-menu.ejs: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 25 | 26 |
27 |
28 | 29 |
-------------------------------------------------------------------------------- /controllers/bank/bank-controller.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const BaseController = require("../../core/base-controller"); 4 | const { AREA, MODE } = require("../../helpers/constants"); 5 | 6 | 7 | class BankController extends BaseController { 8 | 9 | constructor() { 10 | super(); 11 | this.bankPage = this.bankPage.bind(this); 12 | } 13 | 14 | 15 | async bankPage(req, res) { 16 | 17 | try { 18 | let config = await this._facade.getDefaultDataConfig(); 19 | 20 | if (!config) { 21 | return res.render('err/occurs-error', { 22 | layout: false, 23 | err: "could not load default data" 24 | }); 25 | } 26 | 27 | res.render('invitation/bank', { 28 | layout: false, 29 | data: { 30 | cfg: config 31 | }, 32 | }); 33 | } catch (error) { 34 | res.render('err/occurs-error', { 35 | layout: false, 36 | err: error 37 | }); 38 | } 39 | } 40 | } 41 | 42 | module.exports = BankController; 43 | -------------------------------------------------------------------------------- /business/components/auth/auth-component.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const BaseCore = require("../core/base-core"); 4 | let jwt = require("jsonwebtoken"); 5 | 6 | class AuthComponent extends BaseCore { 7 | constructor() { 8 | super(); 9 | } 10 | 11 | verifyAccountToken(token) { 12 | if (token) { 13 | if (token.startsWith("Bearer ")) { 14 | // Remove Bearer from string 15 | token = token.slice(7, token.length); 16 | } 17 | 18 | jwt.verify(token, process.env.SECRET_KEY, (err, decoded) => { 19 | if (err) { 20 | return { 21 | success: false, 22 | message: "Token is not valid", 23 | }; 24 | } else { 25 | return { 26 | success: true, 27 | data: decoded 28 | }; 29 | } 30 | }); 31 | } else { 32 | return { 33 | success: false, 34 | message: "Auth token is not supplied", 35 | }; 36 | } 37 | } 38 | } 39 | 40 | module.exports = AuthComponent; 41 | -------------------------------------------------------------------------------- /public/plugins/datatables/responsive.bootstrap4.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | Bootstrap 4 integration for DataTables' Responsive 3 | ©2016 SpryMedia Ltd - datatables.net/license 4 | */ 5 | (function(c){"function"===typeof define&&define.amd?define(["jquery","datatables.net-bs4","datatables.net-responsive"],function(a){return c(a,window,document)}):"object"===typeof exports?module.exports=function(a,b){a||(a=window);if(!b||!b.fn.dataTable)b=require("datatables.net-bs4")(a,b).$;b.fn.dataTable.Responsive||require("datatables.net-responsive")(a,b);return c(b,a,a.document)}:c(jQuery,window,document)})(function(c){var a=c.fn.dataTable,b=a.Responsive.display,g=b.modal,e=c(' 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /public/assets/js/app.js: -------------------------------------------------------------------------------- 1 | !function (t) { "use strict"; var e = function () { this.$body = t("body"), this.$wrapper = t("#wrapper"), this.$btnFullScreen = t("#btn-fullscreen"), this.$leftMenuButton = t(".button-menu-mobile"), this.$menuItem = t(".has_sub > a") }; e.prototype.intSlimscrollmenu = function () { t(".slimscroll-menu").slimscroll({ height: "auto", position: "right", size: "5px", color: "#9ea5ab", wheelStep: 5, touchScrollStep: 50 }) }, e.prototype.initSlimscroll = function () { t(".slimscroll").slimscroll({ height: "auto", position: "right", size: "5px", color: "#9ea5ab", touchScrollStep: 50 }) }, e.prototype.initMetisMenu = function () { t("#side-menu").metisMenu() }, e.prototype.initLeftMenuCollapse = function () { t(".button-menu-mobile").on("click", function (e) { e.preventDefault(), t("body").toggleClass("enlarged") }) }, e.prototype.initEnlarge = function () { t(window).width() < 1025 ? t("body").addClass("enlarged") : t("body").removeClass("enlarged") }, e.prototype.initActiveMenu = function () { t("#sidebar-menu a").each(function () { var e = window.location.href.split(/[?#]/)[0]; this.href == e && (t(this).addClass("mm-active"), t(this).parent().addClass("mm-active"), t(this).parent().parent().addClass("mm-show"), t(this).parent().parent().prev().addClass("mm-active"), t(this).parent().parent().parent().addClass("mm-active"), t(this).parent().parent().parent().parent().addClass("mm-show"), t(this).parent().parent().parent().parent().parent().addClass("mm-active")) }) }, e.prototype.initComponents = function () { t('[data-toggle="tooltip"]').tooltip(), t('[data-toggle="popover"]').popover() }, e.prototype.initFullScreen = function () { this.$btnFullScreen.on("click", function (e) { e.preventDefault(), document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement ? document.cancelFullScreen ? document.cancelFullScreen() : document.mozCancelFullScreen ? document.mozCancelFullScreen() : document.webkitCancelFullScreen && document.webkitCancelFullScreen() : document.documentElement.requestFullscreen ? document.documentElement.requestFullscreen() : document.documentElement.mozRequestFullScreen ? document.documentElement.mozRequestFullScreen() : document.documentElement.webkitRequestFullscreen && document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT) }) }, e.prototype.init = function () { this.intSlimscrollmenu(), this.initSlimscroll(), this.initMetisMenu(), this.initLeftMenuCollapse(), this.initEnlarge(), this.initActiveMenu(), this.initComponents(), this.initFullScreen(), Waves.init() }, t.MainApp = new e, t.MainApp.Constructor = e }(window.jQuery), function (e) { "use strict"; window.jQuery.MainApp.init() }(); 2 | function colorLog(message, color) { 3 | 4 | color = color || "black"; 5 | 6 | switch (color) { 7 | case "success": 8 | color = "Green"; 9 | break; 10 | case "info": 11 | color = "DodgerBlue"; 12 | break; 13 | case "error": 14 | color = "Red"; 15 | break; 16 | case "warning": 17 | color = "Orange"; 18 | break; 19 | default: 20 | color = color; 21 | } 22 | 23 | console.log("%c" + message, "color:" + color); 24 | } 25 | 26 | (function() { 27 | 28 | let sig = ` __ 29 | (_ _ _ __ | _ _ _ __ 30 | __)(_||_|(_|| | | (_| o (_ (_)|||` 31 | 32 | 33 | 34 | colorLog(sig,'success'); 35 | colorLog('Github repo: https://github.com/sauanla/wedding-invitation','success'); 36 | 37 | })(); 38 | 39 | -------------------------------------------------------------------------------- /views/manager/invocation/index.ejs: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

Invocations

5 | 11 |
12 |
13 |
14 | 15 |
16 |
17 |
18 |
19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | <% for (var i = 0, len = invocations.length ; i < len; i++) {%> 34 | 35 | 36 | 40 | 41 | 42 | <% if(invocations[i].status == 1){ %> 43 | 44 | <% } else if(invocations[i].status == -1){ %> 45 | 46 | <% } else { %> 47 | 48 | <% } %> 49 | 54 | 55 | 56 | <% } %> 57 | 58 |
#NamePhoneStatusTimeMessageAction
<%= i+1 %> 37 | <%= invocations[i].name %> 39 | <%= invocations[i].phone %>Tham giaKhông Tham giaKhông Tham gia 50 | 51 | 52 | 53 |
59 |
60 |
61 |
62 |
63 | 64 |
65 | 66 | -------------------------------------------------------------------------------- /controllers/manager/invitation/invitation-controller.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const systemConfigs = require("../../../configs/system-configs"); 4 | const BaseController = require("../../../core/base-controller"); 5 | 6 | 7 | class InvitationController extends BaseController { 8 | 9 | constructor() { 10 | super(); 11 | 12 | this.list = this.list.bind(this); 13 | this.detail = this.detail.bind(this); 14 | this.create = this.create.bind(this); 15 | this.update = this.update.bind(this); 16 | this.del = this.del.bind(this); 17 | } 18 | 19 | async list(req, res) { 20 | 21 | try { 22 | let data = await this._facade.getListInvitee(); 23 | 24 | res.render('manager/invitation/index', { 25 | invitees: data, 26 | uri: systemConfigs.domain 27 | }); 28 | } catch (error) { 29 | res.render('err/occurs-error', { 30 | layout: false, 31 | err: error 32 | }); 33 | } 34 | 35 | } 36 | 37 | async detail(req, res) { 38 | try { 39 | let id = req.params.id.trim(); 40 | let data = await this._facade.getDetailInvitee(id); 41 | 42 | this._handleResult(data, res); 43 | 44 | } catch (error) { 45 | this._handleError(error.message, res); 46 | } 47 | } 48 | 49 | async create(req, res) { 50 | try { 51 | if (this._handleValidationResult(req, res)){ 52 | return false; 53 | } 54 | let invitee = { 55 | name: req.body.invitee.name, 56 | message: req.body.invitee.message, 57 | level: req.body.invitee.level, 58 | area: Number(req.body.invitee.area), 59 | }; 60 | 61 | let data = await this._facade.addInvitee(invitee); 62 | 63 | this._handleResult(data, res); 64 | } catch (error) { 65 | console.log(error); 66 | this._handleError({ 67 | code: 500, 68 | message: error.message 69 | }, res); 70 | } 71 | } 72 | 73 | async update(req, res) { 74 | try { 75 | if (this._handleValidationResult(req, res)){ 76 | return false; 77 | } 78 | let invitee = { 79 | id: req.body.invitee.id, 80 | name: req.body.invitee.name, 81 | message: req.body.invitee.message, 82 | level: req.body.invitee.level, 83 | area: Number(req.body.invitee.area), 84 | }; 85 | 86 | let data = await this._facade.updateInvitee(invitee.id, invitee); 87 | 88 | this._handleResult(data, res); 89 | } catch (error) { 90 | this._handleError(error.message, res); 91 | } 92 | } 93 | 94 | async del(req, res) { 95 | const id = req.body.id; 96 | try { 97 | 98 | const invitee = await this._facade.getDetailInvitee(id); 99 | 100 | if(!invitee){ 101 | return this._handleError('Invitee does not exist', res); 102 | } 103 | 104 | let data = await this._facade.delInvitee(id); 105 | this._handleResult(data, res); 106 | } catch (error) { 107 | this._handleError(error.message, res); 108 | } 109 | 110 | } 111 | } 112 | 113 | module.exports = InvitationController; 114 | -------------------------------------------------------------------------------- /controllers/invitation/invitation-controller.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const BaseController = require("../../core/base-controller"); 4 | const { AREA, MODE } = require("../../helpers/constants"); 5 | 6 | 7 | class InvitationController extends BaseController { 8 | 9 | constructor() { 10 | super(); 11 | 12 | this.defaultPage = this.defaultPage.bind(this); 13 | this.detailInvitation = this.detailInvitation.bind(this); 14 | this.bankPage = this.bankPage.bind(this); 15 | } 16 | 17 | async defaultPage(req, res) { 18 | 19 | try { 20 | let data = await this._facade.getDefaultDataConfig(); 21 | 22 | if (!data) { 23 | return res.redirect("/setup") 24 | } 25 | res.render('invitation/male', { 26 | layout: false, 27 | data: { 28 | mode: MODE.DEFAULT, 29 | cfg: data, 30 | invitee: null, 31 | }, 32 | }); 33 | } catch (error) { 34 | res.render('err/occurs-error', { 35 | layout: false, 36 | err: error 37 | }); 38 | } 39 | } 40 | 41 | async detailInvitation(req, res) { 42 | const id = req.params.id.trim(); 43 | try { 44 | let invitee = await this._facade.getDetailInvitee(id); 45 | let config = await this._facade.getDefaultDataConfig(); 46 | 47 | if (!config) { 48 | return res.render('err/occurs-error', { 49 | layout: false, 50 | err: "could not load default data" 51 | }); 52 | } 53 | 54 | if (!invitee) { 55 | return res.render('err/e404', { 56 | layout: false, 57 | }); 58 | } 59 | 60 | 61 | if (invitee.area === AREA.FEMALE) { 62 | res.render('invitation/female', { 63 | layout: false, 64 | data: { 65 | mode: MODE.HAS_DATA, 66 | cfg: config, 67 | invitee: invitee, 68 | }, 69 | }); 70 | } else if (invitee.area === AREA.MALE) { 71 | res.render('invitation/male', { 72 | layout: false, 73 | data: { 74 | mode: MODE.HAS_DATA, 75 | cfg: config, 76 | invitee: invitee, 77 | }, 78 | }); 79 | } 80 | 81 | 82 | } catch (error) { 83 | res.render('err/occurs-error', { 84 | layout: false, 85 | err: error 86 | }); 87 | } 88 | } 89 | 90 | async bankPage(req, res) { 91 | try { 92 | let data = await this._facade.getDefaultDataConfig(); 93 | 94 | if (!data) { 95 | return res.render('err/occurs-error', { 96 | layout: false, 97 | err: "could not load default data" 98 | }); 99 | } 100 | 101 | res.render('invitation/bank', { 102 | layout: false, 103 | data: { 104 | mode: 1 105 | }, 106 | }); 107 | } catch (error) { 108 | res.render('err/occurs-error', { 109 | layout: false, 110 | err: error 111 | }); 112 | } 113 | } 114 | } 115 | 116 | module.exports = InvitationController; 117 | -------------------------------------------------------------------------------- /public/assets/js/history.char.js: -------------------------------------------------------------------------------- 1 | var myChart; 2 | function formatDate(date) { 3 | var d = new Date(date); 4 | var curr_date = d.getDate(); 5 | var curr_month = d.getMonth() + 1; //Months are zero based 6 | var curr_year = d.getFullYear(); 7 | return curr_date + "-" + curr_month + "-" + curr_year; 8 | } 9 | format_curency = money => { 10 | money = money.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1."); 11 | return money + " VNĐ"; 12 | }; 13 | 14 | function cc(idItem, idShop, price) { 15 | $("#isLoading").hide(); 16 | var id = "1__" + idItem + "__" + idShop; 17 | $("#myModal").modal("show"); 18 | getData(id); 19 | } 20 | 21 | function genId(url) { 22 | try { 23 | const regex = /(i.)+[0-9]+(.)+[0-9]/g; 24 | const str = url; 25 | let m; 26 | 27 | while ((m = regex.exec(str)) !== null) { 28 | // This is necessary to avoid infinite loops with zero-width matches 29 | if (m.index === regex.lastIndex) { 30 | regex.lastIndex++; 31 | } 32 | 33 | // The result can be accessed through the `m`-variable. 34 | var ids = m[0].split("."); 35 | ids[0] = "1"; 36 | var temp = ids[1]; 37 | ids[1] = ids[2]; 38 | ids[2] = temp; 39 | var id = ids.join("__"); 40 | return id; 41 | } 42 | } catch (err) { 43 | console.log(err); 44 | return ""; 45 | } 46 | } 47 | 48 | $("#detailItem").click(function(e) { 49 | e.preventDefault(); 50 | $("#chart").show(); 51 | $("#isLoading").hide(); 52 | $("#isLoading").hide(); 53 | var url = $("#url").val(); 54 | var ref = $("#ref").val(); 55 | $("#urlBuy").attr("href", ref+url); 56 | if (url && url !== "") { 57 | var id = genId(url); 58 | if (id == undefined || id === "") { 59 | $("#err").show(); 60 | $("#err").text( 61 | "Chọn vào chi tiết sản phẩm trên shopee -> xong coppy Url nhé 🤔 " 62 | ); 63 | $("#chartRender").hide(); 64 | $("#isLoading").show(); 65 | } else { 66 | $("#err").hide(); 67 | getData(id); 68 | } 69 | } 70 | }); 71 | var getData = function(id) { 72 | $.ajax({ 73 | url: "/shopee/history/" + id, 74 | success: function(rp) { 75 | if (rp.status) { 76 | $("#chartRender").show(); 77 | $("#isLoading").hide(); 78 | renderChart(rp.data, rp.labels); 79 | } else { 80 | $("#chartRender").hide(); 81 | $("#isLoading").show(); 82 | if (myChart) { 83 | myChart.destroy(); 84 | } 85 | } 86 | // re-render the chart 87 | } 88 | }); 89 | }; 90 | 91 | function renderChart(data, labels) { 92 | if (myChart) { 93 | myChart.destroy(); 94 | } 95 | var ctx = document.getElementById("myChart").getContext("2d"); 96 | myChart = new Chart(ctx, { 97 | type: "line", 98 | data: { 99 | labels: labels, 100 | datasets: [ 101 | { 102 | label: "Giá sản phẩm", 103 | data: data, 104 | borderColor: "rgba(75, 192, 192, 1)", 105 | backgroundColor: "rgba(75, 192, 192, 0.2)" 106 | } 107 | ] 108 | }, 109 | options: { 110 | scales: { 111 | yAxes: [ 112 | { 113 | ticks: { 114 | beginAtZero: true, 115 | callback: function(value, index, values) { 116 | return format_curency(value); 117 | } 118 | } 119 | } 120 | ], 121 | xAxes: [ 122 | { 123 | ticks: { 124 | beginAtZero: true, 125 | callback: function(value, index, values) { 126 | return formatDate(value); 127 | } 128 | } 129 | } 130 | ] 131 | } 132 | } 133 | }); 134 | } 135 | -------------------------------------------------------------------------------- /domains/mongodb/seed-db.json: -------------------------------------------------------------------------------- 1 | { 2 | "user": { 3 | "_id": { 4 | "$oid": "60a9f7f255d63b6640beb4a7" 5 | }, 6 | "email": "admin@invitation.com", 7 | "username": "admin", 8 | "password": "$2b$10$VhmfGtzS9/IZPQuLQhmXkeTZmXrHYjIV2HCRfsOEp66Yk/OJiwow2", 9 | "password_confirm": "$2b$10$VhmfGtzS9/IZPQuLQhmXkeTZmXrHYjIV2HCRfsOEp66Yk/OJiwow2", 10 | "role": "admin", 11 | "__v": { 12 | "$numberInt": "0" 13 | } 14 | }, 15 | "data-config": { 16 | "_id": { 17 | "$oid": "60a9f87655d63b6640beb4a8" 18 | }, 19 | "male": { 20 | "name": "Nguyễn Văn An", 21 | "parent": { 22 | "father": "Họ Tên Bố", 23 | "mother": "Họ Tên Mẹ" 24 | }, 25 | "location": { 26 | "text": "Quảng Yên - Quảng Ninh - Việt Nam", 27 | "map": "https://goo.gl/maps/tRjKuVRNisqxhQaT7" 28 | }, 29 | "time_start": { 30 | "date": { 31 | "lunar": { 32 | "day": "17", 33 | "month": "12", 34 | "year": "2020" 35 | }, 36 | "day_of_week": "5", 37 | "solar": { 38 | "day": "17", 39 | "month": "12", 40 | "year": "2020" 41 | } 42 | }, 43 | "time": { 44 | "hour": "10", 45 | "minute": "00" 46 | } 47 | }, 48 | "finances": [ 49 | { 50 | "provider_name": "MB Bank", 51 | "provider_number": "9971997555555", 52 | "holder_name": "NGUYEN VAN AN" 53 | }, 54 | { 55 | "provider_name": "Techcombank", 56 | "provider_number": "19034892842011", 57 | "holder_name": "NGUYEN VAN AN" 58 | }, 59 | { 60 | "provider_name": "Momo", 61 | "provider_number": "0973999999", 62 | "holder_name": "NGUYEN VAN AN" 63 | }, 64 | { 65 | "provider_name": "Airpay", 66 | "provider_number": "0973999999", 67 | "holder_name": "NGUYEN VAN AN" 68 | } 69 | ], 70 | "email": "male@gmail.com", 71 | "phone": "0973999999" 72 | }, 73 | "female": { 74 | "name": "Nguyễn Thị Huyền Trang", 75 | "parent": { 76 | "father": "Họ Tên Bố", 77 | "mother": "Họ Tên Mẹ" 78 | }, 79 | "location": { 80 | "text": "Quốc Oai - Hà Nội - Việt Nam", 81 | "map": "https://goo.gl/maps/tTZz4qKhaiqSL8Q66" 82 | }, 83 | "time_start": { 84 | "date": { 85 | "lunar": { 86 | "day": "17", 87 | "month": "12", 88 | "year": "2020" 89 | }, 90 | "day_of_week": "5", 91 | "solar": { 92 | "day": "17", 93 | "month": "12", 94 | "year": "2020" 95 | } 96 | }, 97 | "time": { 98 | "hour": "10", 99 | "minute": "00" 100 | } 101 | }, 102 | "finances": [ 103 | { 104 | "provider_name": "Techcombank", 105 | "provider_number": "19033761344011", 106 | "holder_name": "NGUYEN HUYEN TRANG" 107 | }, 108 | { 109 | "provider_name": "Techcombank", 110 | "provider_number": "19033761344011", 111 | "holder_name": "NGUYEN HUYEN TRANG" 112 | }, 113 | { 114 | "provider_name": "Momo", 115 | "provider_number": "0973999999", 116 | "holder_name": "NGUYEN VAN AN" 117 | }, 118 | { 119 | "provider_name": "Airpay", 120 | "provider_number": "0973999999", 121 | "holder_name": "NGUYEN VAN AN" 122 | } 123 | ], 124 | "email": "female@gmail.com", 125 | "phone": "0985123123" 126 | }, 127 | "default": true 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /public/plugins/datatables/responsive.bootstrap4.min.css: -------------------------------------------------------------------------------- 1 | table.dataTable.dtr-inline.collapsed>tbody>tr>td.child,table.dataTable.dtr-inline.collapsed>tbody>tr>th.child,table.dataTable.dtr-inline.collapsed>tbody>tr>td.dataTables_empty{cursor:default !important}table.dataTable.dtr-inline.collapsed>tbody>tr>td.child:before,table.dataTable.dtr-inline.collapsed>tbody>tr>th.child:before,table.dataTable.dtr-inline.collapsed>tbody>tr>td.dataTables_empty:before{display:none !important}table.dataTable.dtr-inline.collapsed>tbody>tr>td:first-child,table.dataTable.dtr-inline.collapsed>tbody>tr>th:first-child{position:relative;padding-left:30px;cursor:pointer}table.dataTable.dtr-inline.collapsed>tbody>tr>td:first-child:before,table.dataTable.dtr-inline.collapsed>tbody>tr>th:first-child:before{top:12px;left:4px;height:14px;width:14px;display:block;position:absolute;color:white;border:2px solid white;border-radius:14px;box-shadow:0 0 3px #444;box-sizing:content-box;text-align:center;font-family:'Courier New', Courier, monospace;line-height:14px;content:'+';background-color:#0275d8}table.dataTable.dtr-inline.collapsed>tbody>tr.parent>td:first-child:before,table.dataTable.dtr-inline.collapsed>tbody>tr.parent>th:first-child:before{content:'-';background-color:#d33333}table.dataTable.dtr-inline.collapsed>tbody>tr.child td:before{display:none}table.dataTable.dtr-inline.collapsed.compact>tbody>tr>td:first-child,table.dataTable.dtr-inline.collapsed.compact>tbody>tr>th:first-child{padding-left:27px}table.dataTable.dtr-inline.collapsed.compact>tbody>tr>td:first-child:before,table.dataTable.dtr-inline.collapsed.compact>tbody>tr>th:first-child:before{top:5px;left:4px;height:14px;width:14px;border-radius:14px;line-height:14px;text-indent:3px}table.dataTable.dtr-column>tbody>tr>td.control,table.dataTable.dtr-column>tbody>tr>th.control{position:relative;cursor:pointer}table.dataTable.dtr-column>tbody>tr>td.control:before,table.dataTable.dtr-column>tbody>tr>th.control:before{top:50%;left:50%;height:16px;width:16px;margin-top:-10px;margin-left:-10px;display:block;position:absolute;color:white;border:2px solid white;border-radius:14px;box-shadow:0 0 3px #444;box-sizing:content-box;text-align:center;font-family:'Courier New', Courier, monospace;line-height:14px;content:'+';background-color:#0275d8}table.dataTable.dtr-column>tbody>tr.parent td.control:before,table.dataTable.dtr-column>tbody>tr.parent th.control:before{content:'-';background-color:#d33333}table.dataTable>tbody>tr.child{padding:0.5em 1em}table.dataTable>tbody>tr.child:hover{background:transparent !important}table.dataTable>tbody>tr.child ul{display:inline-block;list-style-type:none;margin:0;padding:0}table.dataTable>tbody>tr.child ul li{border-bottom:1px solid #efefef;padding:0.5em 0}table.dataTable>tbody>tr.child ul li:first-child{padding-top:0}table.dataTable>tbody>tr.child ul li:last-child{border-bottom:none}table.dataTable>tbody>tr.child span.dtr-title{display:inline-block;min-width:75px;font-weight:bold}div.dtr-modal{position:fixed;box-sizing:border-box;top:0;left:0;height:100%;width:100%;z-index:100;padding:10em 1em}div.dtr-modal div.dtr-modal-display{position:absolute;top:0;left:0;bottom:0;right:0;width:50%;height:50%;overflow:auto;margin:auto;z-index:102;overflow:auto;background-color:#f5f5f7;border:1px solid black;border-radius:0.5em;box-shadow:0 12px 30px rgba(0,0,0,0.6)}div.dtr-modal div.dtr-modal-content{position:relative;padding:1em}div.dtr-modal div.dtr-modal-close{position:absolute;top:6px;right:6px;width:22px;height:22px;border:1px solid #eaeaea;background-color:#f9f9f9;text-align:center;border-radius:3px;cursor:pointer;z-index:12}div.dtr-modal div.dtr-modal-close:hover{background-color:#eaeaea}div.dtr-modal div.dtr-modal-background{position:fixed;top:0;left:0;right:0;bottom:0;z-index:101;background:rgba(0,0,0,0.6)}@media screen and (max-width: 767px){div.dtr-modal div.dtr-modal-display{width:95%}}div.dtr-bs-modal table.table tr:first-child td{border-top:none} 2 | -------------------------------------------------------------------------------- /public/assets/css/bootstrap-reboot.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v4.3.1 (https://getbootstrap.com/) 3 | * Copyright 2011-2019 The Bootstrap Authors 4 | * Copyright 2011-2019 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 6 | * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md) 7 | */*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important} 8 | /*# sourceMappingURL=bootstrap-reboot.min.css.map */ -------------------------------------------------------------------------------- /public/plugins/datatables/buttons.bootstrap4.min.css: -------------------------------------------------------------------------------- 1 | @keyframes dtb-spinner{100%{transform:rotate(360deg)}}@-o-keyframes dtb-spinner{100%{-o-transform:rotate(360deg);transform:rotate(360deg)}}@-ms-keyframes dtb-spinner{100%{-ms-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes dtb-spinner{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-moz-keyframes dtb-spinner{100%{-moz-transform:rotate(360deg);transform:rotate(360deg)}}div.dt-button-info{position:fixed;top:50%;left:50%;width:400px;margin-top:-100px;margin-left:-200px;background-color:white;border:2px solid #111;box-shadow:3px 3px 8px rgba(0,0,0,0.3);border-radius:3px;text-align:center;z-index:21}div.dt-button-info h2{padding:0.5em;margin:0;font-weight:normal;border-bottom:1px solid #ddd;background-color:#f3f3f3}div.dt-button-info>div{padding:1em}ul.dt-button-collection.dropdown-menu{display:block;z-index:2002;-webkit-column-gap:8px;-moz-column-gap:8px;-ms-column-gap:8px;-o-column-gap:8px;column-gap:8px}ul.dt-button-collection.dropdown-menu.fixed{position:fixed;top:50%;left:50%;margin-left:-75px;border-radius:0}ul.dt-button-collection.dropdown-menu.fixed.two-column{margin-left:-150px}ul.dt-button-collection.dropdown-menu.fixed.three-column{margin-left:-225px}ul.dt-button-collection.dropdown-menu.fixed.four-column{margin-left:-300px}ul.dt-button-collection.dropdown-menu>*{-webkit-column-break-inside:avoid;break-inside:avoid}ul.dt-button-collection.dropdown-menu.two-column{width:300px;padding-bottom:1px;-webkit-column-count:2;-moz-column-count:2;-ms-column-count:2;-o-column-count:2;column-count:2}ul.dt-button-collection.dropdown-menu.three-column{width:450px;padding-bottom:1px;-webkit-column-count:3;-moz-column-count:3;-ms-column-count:3;-o-column-count:3;column-count:3}ul.dt-button-collection.dropdown-menu.four-column{width:600px;padding-bottom:1px;-webkit-column-count:4;-moz-column-count:4;-ms-column-count:4;-o-column-count:4;column-count:4}ul.dt-button-collection.dropdown-menu .dt-button{border-radius:0}ul.dt-button-collection{-webkit-column-gap:8px;-moz-column-gap:8px;-ms-column-gap:8px;-o-column-gap:8px;column-gap:8px}ul.dt-button-collection.fixed{position:fixed;top:50%;left:50%;margin-left:-75px;border-radius:0}ul.dt-button-collection.fixed.two-column{margin-left:-150px}ul.dt-button-collection.fixed.three-column{margin-left:-225px}ul.dt-button-collection.fixed.four-column{margin-left:-300px}ul.dt-button-collection>*{-webkit-column-break-inside:avoid;break-inside:avoid}ul.dt-button-collection.two-column{width:300px;padding-bottom:1px;-webkit-column-count:2;-moz-column-count:2;-ms-column-count:2;-o-column-count:2;column-count:2}ul.dt-button-collection.three-column{width:450px;padding-bottom:1px;-webkit-column-count:3;-moz-column-count:3;-ms-column-count:3;-o-column-count:3;column-count:3}ul.dt-button-collection.four-column{width:600px;padding-bottom:1px;-webkit-column-count:4;-moz-column-count:4;-ms-column-count:4;-o-column-count:4;column-count:4}ul.dt-button-collection .dt-button{border-radius:0}ul.dt-button-collection.fixed{max-width:none}ul.dt-button-collection.fixed:before,ul.dt-button-collection.fixed:after{display:none}div.dt-button-background{position:fixed;top:0;left:0;width:100%;height:100%;z-index:999}@media screen and (max-width: 767px){div.dt-buttons{float:none;width:100%;text-align:center;margin-bottom:0.5em}div.dt-buttons a.btn{float:none}}div.dt-buttons button.btn.processing,div.dt-buttons div.btn.processing,div.dt-buttons a.btn.processing{color:rgba(0,0,0,0.2)}div.dt-buttons button.btn.processing:after,div.dt-buttons div.btn.processing:after,div.dt-buttons a.btn.processing:after{position:absolute;top:50%;left:50%;width:16px;height:16px;margin:-8px 0 0 -8px;box-sizing:border-box;display:block;content:' ';border:2px solid #282828;border-radius:50%;border-left-color:transparent;border-right-color:transparent;animation:dtb-spinner 1500ms infinite linear;-o-animation:dtb-spinner 1500ms infinite linear;-ms-animation:dtb-spinner 1500ms infinite linear;-webkit-animation:dtb-spinner 1500ms infinite linear;-moz-animation:dtb-spinner 1500ms infinite linear} 2 | -------------------------------------------------------------------------------- /public/assets/js/layout.js: -------------------------------------------------------------------------------- 1 | function pad(num, size) { 2 | var s = num + ""; 3 | while (s.length < size) s = "0" + s; 4 | return s; 5 | } 6 | 7 | function updateTime() { 8 | var today = new Date(); 9 | $("#hour").val(pad(today.getHours(), 2)); 10 | $("#minutes").val(pad(today.getMinutes(), 2)); 11 | } 12 | 13 | 14 | function clockUpdate() { 15 | var date = new Date(); 16 | 17 | var h = pad(date.getHours(), 2); 18 | var m = pad(date.getMinutes(), 2); 19 | var s = pad(date.getSeconds(), 2); 20 | 21 | $('.digital-clock').text(h + ':' + m + ':' + s); 22 | } 23 | 24 | function init(){ 25 | clockUpdate(); 26 | setInterval(clockUpdate, 1000); 27 | } 28 | 29 | init(); 30 | 31 | 32 | 33 | 34 | 35 | /* 36 | Template Name: Veltrix - Responsive Bootstrap 4 Admin Dashboard 37 | Author: Themesbrand 38 | File: table editable Init 39 | */ 40 | 41 | (function ($) { 42 | 43 | var datatable = $('.table-editable').dataTable({ 44 | "columns": [ 45 | { "name": "id" }, 46 | { "name": "age" }, 47 | { "name": "qty" }, 48 | { "name": "cost" }, 49 | ], 50 | "bPaginate": false, 51 | "fnRowCallback": function (nRow, aData, iDisplayIndex, iDisplayIndexFull) { 52 | var setCell = function(response, newValue) { 53 | var table = new $.fn.dataTable.Api('.table'); 54 | var cell = table.cell('td.focus'); 55 | var cellData = cell.data(); 56 | 57 | var div = document.createElement('div'); 58 | div.innerHTML = cellData; 59 | var a = div.childNodes; 60 | a.innerHTML = newValue; 61 | 62 | console.log('jml a new ' + div.innerHTML); 63 | cell.data(div.innerHTML); 64 | highlightCell($(cell.node())); 65 | 66 | // This is huge cheese, but the a has lost it's editable nature. Do it again. 67 | $('td.focus a').editable({ 68 | 'mode': 'inline', 69 | 'success' : setCell 70 | }); 71 | }; 72 | $('.editable').editable( 73 | { 74 | 'mode': 'inline', 75 | 'success' : setCell 76 | } 77 | ); 78 | }, 79 | "autoFill" : { 80 | "columns" : [1, 2] 81 | }, 82 | "keys" : true 83 | }); 84 | 85 | addCellChangeHandler(); 86 | addAutoFillHandler(); 87 | 88 | function highlightCell($cell) { 89 | var originalValue = $cell.attr('data-original-value'); 90 | if (!originalValue) { 91 | return; 92 | } 93 | var actualValue = $cell.text(); 94 | if (!isNaN(originalValue)) { 95 | originalValue = parseFloat(originalValue); 96 | } 97 | if (!isNaN(actualValue)) { 98 | actualValue = parseFloat(actualValue); 99 | } 100 | if ( originalValue === actualValue ) { 101 | $cell.removeClass('cat-cell-modified').addClass('cat-cell-original'); 102 | } else { 103 | $cell.removeClass('cat-cell-original').addClass('cat-cell-modified'); 104 | } 105 | } 106 | 107 | function addCellChangeHandler() { 108 | $('a[data-pk]').on('hidden', function (e, editable) { 109 | var $a = $(this); 110 | var $cell = $a.parent('td'); 111 | highlightCell($cell); 112 | }); 113 | } 114 | 115 | function addAutoFillHandler() { 116 | var table = $('.table').DataTable(); 117 | table.on('autoFill', function (e, datatable, cells) { 118 | var datatableCellApis = $.each(cells, function(index, row) { 119 | var datatableCellApi = row[0].cell; 120 | var $jQueryObject = $(datatableCellApi.node()); 121 | highlightCell($jQueryObject); 122 | }); 123 | }); 124 | } 125 | 126 | })(jQuery); --------------------------------------------------------------------------------