├── .babelrc
├── .editorconfig
├── .firebase
├── hosting.0.cache
└── hosting.ZGlzdA.cache
├── .firebaserc
├── .gitignore
├── .postcssrc.js
├── LICENSE
├── README.md
├── build
├── build.js
├── check-versions.js
├── logo.png
├── utils.js
├── vue-loader.conf.js
├── webpack.base.conf.js
├── webpack.dev.conf.js
├── webpack.prod.conf.js
└── webpack.test.conf.js
├── config
├── index.js
└── test.env.js
├── index.html
├── package-lock.json
├── package.json
├── src
├── .gitrepo
├── App.vue
├── assets
│ └── logo.png
├── components
│ ├── HelloWorld.vue
│ ├── Home.vue
│ ├── Schedule
│ │ └── Schedule.vue
│ ├── auth
│ │ └── Login.vue
│ ├── bus
│ │ └── Bus.vue
│ ├── settings
│ │ └── Settings.vue
│ ├── student
│ │ └── Students.vue
│ ├── transactions
│ │ └── Payments.vue
│ ├── users
│ │ ├── AddUser.vue
│ │ ├── Delete.vue
│ │ ├── Profile.vue
│ │ ├── Users.vue
│ │ └── admin
│ │ │ ├── AddAdminstrator.vue
│ │ │ └── ViewAdminstrators.vue
│ └── utils
│ │ ├── Alert.vue
│ │ └── Statistic.vue
├── main.js
├── router
│ ├── auth-guard.js
│ └── index.js
├── services
│ └── api.js
├── store
│ └── index.js
└── utils
│ └── date.js
├── static
├── .gitkeep
├── logo
│ ├── metro_white.png
│ └── metrotrans_logo.png
└── profile
│ ├── man_profile.png
│ └── profile_background.jpg
└── test
├── e2e
├── custom-assertions
│ └── elementCount.js
├── nightwatch.conf.js
├── runner.js
└── specs
│ └── test.js
└── unit
├── .eslintrc
├── index.js
├── karma.conf.js
└── specs
└── HelloWorld.spec.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["env", {
4 | "modules": false,
5 | "targets": {
6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
7 | }
8 | }],
9 | "stage-2"
10 | ],
11 | "plugins": ["transform-vue-jsx", "transform-runtime"],
12 | "env": {
13 | "test": {
14 | "presets": ["env", "stage-2"],
15 | "plugins": ["transform-vue-jsx", "istanbul"]
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/.firebase/hosting.0.cache:
--------------------------------------------------------------------------------
1 | 404.html,1537706663557,b7bab6b83fa074653ff28c8d2a64135d3434575f70a12ab3d3ba8080461b9537
2 | index.html,1539241533994,cf0dad7369a8e9c50f57ebc4f3ce001ee9d2c5e8c4989afe6e896d325f3158b4
3 | static/js/app.df3bb6477e3d0929ad75.js,1539241534114,78574dcaa7bb85d559922a2e67b4d472a6cd3084920292ab70ae32c8f7ad4d8a
4 | static/js/manifest.2ae2e69a05c33dfc65f8.js,1539241534114,d0ecadeafc1508d5a3eb607189a007044d53d5a55f62c43829254cab378c1f56
5 | static/js/manifest.2ae2e69a05c33dfc65f8.js.map,1539241534114,3ffe8de659447a59857aa2006c93a0e64e61e0086ce8c9efd8ca8d26a7c231ab
6 | static/js/app.df3bb6477e3d0929ad75.js.map,1539241534114,c89403d6f65bc7982b284acb0e358e81d117a439de2bf81d24f1d256fd649b37
7 | static/css/app.705ee20c5ba21a3a7bb0bec5527cb467.css,1539241534050,96d9169167e06af6d85840a9c157362ce9c6404d6a5a0b96cd16ee83ded3ec9b
8 | static/css/app.705ee20c5ba21a3a7bb0bec5527cb467.css.map,1539241534114,77f6b51981f1d67be168d1e713b4996a2d7b5eaf2db9aa4766f97ab12e3b33d9
9 | static/js/vendor.d5d23519ca77ef2ee605.js,1539241534050,c123df13ae7dae45999705f5d4299ff858397cc84c0561d5b134756630e5f65d
10 | static/js/vendor.d5d23519ca77ef2ee605.js.map,1539241534114,058ed2449d12fc13ba51764ed5c7c8bc1e4a16755caac351a10afe86d84279d0
11 |
--------------------------------------------------------------------------------
/.firebase/hosting.ZGlzdA.cache:
--------------------------------------------------------------------------------
1 | index.html,1550047020199,2871fabeb818a9a34d4a4b3e68cafa1ceade675a00b000c26d93e4238333221c
2 | static/js/manifest.2ae2e69a05c33dfc65f8.js,1550047020251,d0ecadeafc1508d5a3eb607189a007044d53d5a55f62c43829254cab378c1f56
3 | static/js/manifest.2ae2e69a05c33dfc65f8.js.map,1550047020251,49c29be7ca40b7fedc3d0f34cfc050d08ddb3a805bee53756cb1fde4e5e243a6
4 | static/logo/metro_white.png,1550047020251,b118b686198f4f455671d414913a3e37c17fa4bf2f5fac44447b0ab5a81937b4
5 | static/logo/metrotrans_logo.png,1550047020251,a8cf74581c4d2219ab59fae9c042714f28aa8f67ca519de1986bf82682dad2cd
6 | static/js/app.d7bb86633fc65803cece.js,1550047020251,8fe56e80757ec21c56ae3021ffb679b317dc58f5020869b3897b888a984b5040
7 | static/fonts/fontawesome-webfont.af7ae50.woff2,1550047020251,75408058f6c8f9bfcc2e90568ed90df3f6fb09b3c3ee1a8303a4afd3ac0bc921
8 | static/css/app.87a7ca3019ecfbfa61d3321f0b31ac11.css,1550047020215,ad6a8f4b5878c262fcd4b451ecd71791e465c9b335064fca703f32069fa3383b
9 | static/fonts/fontawesome-webfont.fee66e7.woff,1550047020251,4eef8bd2ec905087d7b4ac221dfd85d36d8c1f05d8de2915ecf4351dde4b701e
10 | static/fonts/fontawesome-webfont.674f50d.eot,1550047020211,57bf392fce6fab9ad8d0c1c3a92fdcdf61bda7959c467ebdbf9d3b4dcd9b8080
11 | static/js/app.d7bb86633fc65803cece.js.map,1550047020251,9fafc28f6659e7321680acd61d943c74131ea4c7c7e2243b06b50184e31a9dd7
12 | static/profile/man_profile.png,1550047020251,b996614df6dba2440b615f16afa7e23f7892e3b5e90a818b85059c071742c18e
13 | static/fonts/fontawesome-webfont.b06871f.ttf,1550047020251,64aa5f058bdf4b13431435cc4e8efb81c8ffd4db066748fd0cc824a57fba74de
14 | static/css/app.87a7ca3019ecfbfa61d3321f0b31ac11.css.map,1550047020251,4831b9d2dee97e72e011d089be0221a0e4f48c351ff3995db0f6b4ee10576cba
15 | static/profile/profile_background.jpg,1550047020251,b61f0c575b6ba65891883a5690504adb4750638ed5ff9c6cf5194380b01cf0b4
16 | static/img/fontawesome-webfont.912ec66.svg,1550047020199,712dd79e06a2a5e7c693fe6f926bef5f7ac278183f910ce1fc5b4c27b6488091
17 | static/js/vendor.a0083e5fc889956cb8a7.js,1550047020215,2437012a3dffa1442461e2f118f668f04aea8ff2ced7f272ec92fdd9d0067649
18 | static/js/vendor.a0083e5fc889956cb8a7.js.map,1550047020251,1312ee17773ff0a3faf80b2407d39397721f9c38edcd8206019274f6fec93b8f
19 |
--------------------------------------------------------------------------------
/.firebaserc:
--------------------------------------------------------------------------------
1 | {
2 | "projects": {
3 | "default": "metro-c7c33",
4 | "metro": "metro-c7c33"
5 | }
6 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | config/prod.env.js
4 | config/dev.env.js
5 | /dist/
6 | src/config/
7 | firebase.json
8 | npm-debug.log*
9 | yarn-debug.log*
10 | yarn-error.loggit*
11 | /test/unit/coverage/
12 | /test/e2e/reports/
13 | selenium-debug.log
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 | /src/env.js
22 |
--------------------------------------------------------------------------------
/.postcssrc.js:
--------------------------------------------------------------------------------
1 | // https://github.com/michael-ciniawsky/postcss-load-config
2 |
3 | module.exports = {
4 | "plugins": {
5 | "postcss-import": {},
6 | "postcss-url": {},
7 | // to edit target browsers: use "browserslist" field in package.json
8 | "autoprefixer": {}
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Kamau.Brian
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ticketing
2 |
3 | > Use the url provided to get to the app.
4 |
5 | >>Login With
6 | >>>> Email: testing@tests.com
7 |
8 |
9 | >>>> Password: test123
10 |
11 | > a vue js application for administrators of Metrotrans
12 |
13 | ## Build Setup
14 |
15 | ``` bash
16 | # install dependencies
17 | npm install
18 |
19 | # serve with hot reload at localhost:8080
20 | npm run dev
21 |
22 | # build for production with minification
23 | npm run build
24 |
25 | # build for production and view the bundle analyzer report
26 | npm run build --report
27 |
28 | # run unit tests
29 | npm run unit
30 |
31 | # run e2e tests
32 | npm run e2e
33 |
34 | # run all tests
35 | npm test
36 | ```
37 |
38 | For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).
39 |
--------------------------------------------------------------------------------
/build/build.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | require('./check-versions')()
3 |
4 | process.env.NODE_ENV = 'production'
5 |
6 | const ora = require('ora')
7 | const rm = require('rimraf')
8 | const path = require('path')
9 | const chalk = require('chalk')
10 | const webpack = require('webpack')
11 | const config = require('../config')
12 | const webpackConfig = require('./webpack.prod.conf')
13 |
14 | const spinner = ora('building for production...')
15 | spinner.start()
16 |
17 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
18 | if (err) throw err
19 | webpack(webpackConfig, (err, stats) => {
20 | spinner.stop()
21 | if (err) throw err
22 | process.stdout.write(stats.toString({
23 | colors: true,
24 | modules: false,
25 | children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
26 | chunks: false,
27 | chunkModules: false
28 | }) + '\n\n')
29 |
30 | if (stats.hasErrors()) {
31 | console.log(chalk.red(' Build failed with errors.\n'))
32 | process.exit(1)
33 | }
34 |
35 | console.log(chalk.cyan(' Build complete.\n'))
36 | console.log(chalk.yellow(
37 | ' Tip: built files are meant to be served over an HTTP server.\n' +
38 | ' Opening index.html over file:// won\'t work.\n'
39 | ))
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/build/check-versions.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const chalk = require('chalk')
3 | const semver = require('semver')
4 | const packageConfig = require('../package.json')
5 | const shell = require('shelljs')
6 |
7 | function exec (cmd) {
8 | return require('child_process').execSync(cmd).toString().trim()
9 | }
10 |
11 | const versionRequirements = [
12 | {
13 | name: 'node',
14 | currentVersion: semver.clean(process.version),
15 | versionRequirement: packageConfig.engines.node
16 | }
17 | ]
18 |
19 | if (shell.which('npm')) {
20 | versionRequirements.push({
21 | name: 'npm',
22 | currentVersion: exec('npm --version'),
23 | versionRequirement: packageConfig.engines.npm
24 | })
25 | }
26 |
27 | module.exports = function () {
28 | const warnings = []
29 |
30 | for (let i = 0; i < versionRequirements.length; i++) {
31 | const mod = versionRequirements[i]
32 |
33 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
34 | warnings.push(mod.name + ': ' +
35 | chalk.red(mod.currentVersion) + ' should be ' +
36 | chalk.green(mod.versionRequirement)
37 | )
38 | }
39 | }
40 |
41 | if (warnings.length) {
42 | console.log('')
43 | console.log(chalk.yellow('To use this template, you must update following to modules:'))
44 | console.log()
45 |
46 | for (let i = 0; i < warnings.length; i++) {
47 | const warning = warnings[i]
48 | console.log(' ' + warning)
49 | }
50 |
51 | console.log()
52 | process.exit(1)
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/build/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kamaubrian/TicketingWebClient/c618f581af0d889891b8bf344ebd56ced868750b/build/logo.png
--------------------------------------------------------------------------------
/build/utils.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const config = require('../config')
4 | const ExtractTextPlugin = require('extract-text-webpack-plugin')
5 | const packageConfig = require('../package.json')
6 |
7 | exports.assetsPath = function (_path) {
8 | const assetsSubDirectory = process.env.NODE_ENV === 'production'
9 | ? config.build.assetsSubDirectory
10 | : config.dev.assetsSubDirectory
11 |
12 | return path.posix.join(assetsSubDirectory, _path)
13 | }
14 |
15 | exports.cssLoaders = function (options) {
16 | options = options || {}
17 |
18 | const cssLoader = {
19 | loader: 'css-loader',
20 | options: {
21 | sourceMap: options.sourceMap
22 | }
23 | }
24 |
25 | const postcssLoader = {
26 | loader: 'postcss-loader',
27 | options: {
28 | sourceMap: options.sourceMap
29 | }
30 | }
31 |
32 | // generate loader string to be used with extract text plugin
33 | function generateLoaders (loader, loaderOptions) {
34 | const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
35 |
36 | if (loader) {
37 | loaders.push({
38 | loader: loader + '-loader',
39 | options: Object.assign({}, loaderOptions, {
40 | sourceMap: options.sourceMap
41 | })
42 | })
43 | }
44 |
45 | // Extract CSS when that option is specified
46 | // (which is the case during production build)
47 | if (options.extract) {
48 | return ExtractTextPlugin.extract({
49 | use: loaders,
50 | fallback: 'vue-style-loader'
51 | })
52 | } else {
53 | return ['vue-style-loader'].concat(loaders)
54 | }
55 | }
56 |
57 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html
58 | return {
59 | css: generateLoaders(),
60 | postcss: generateLoaders(),
61 | less: generateLoaders('less'),
62 | sass: generateLoaders('sass', { indentedSyntax: true }),
63 | scss: generateLoaders('sass'),
64 | stylus: generateLoaders('stylus'),
65 | styl: generateLoaders('stylus')
66 | }
67 | }
68 |
69 | // Generate loaders for standalone style files (outside of .vue)
70 | exports.styleLoaders = function (options) {
71 | const output = []
72 | const loaders = exports.cssLoaders(options)
73 |
74 | for (const extension in loaders) {
75 | const loader = loaders[extension]
76 | output.push({
77 | test: new RegExp('\\.' + extension + '$'),
78 | use: loader
79 | })
80 | }
81 |
82 | return output
83 | }
84 |
85 | exports.createNotifierCallback = () => {
86 | const notifier = require('node-notifier')
87 |
88 | return (severity, errors) => {
89 | if (severity !== 'error') return
90 |
91 | const error = errors[0]
92 | const filename = error.file && error.file.split('!').pop()
93 |
94 | notifier.notify({
95 | title: packageConfig.name,
96 | message: severity + ': ' + error.name,
97 | subtitle: filename || '',
98 | icon: path.join(__dirname, 'logo.png')
99 | })
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/build/vue-loader.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const utils = require('./utils')
3 | const config = require('../config')
4 | const isProduction = process.env.NODE_ENV === 'production'
5 | const sourceMapEnabled = isProduction
6 | ? config.build.productionSourceMap
7 | : config.dev.cssSourceMap
8 |
9 | module.exports = {
10 | loaders: utils.cssLoaders({
11 | sourceMap: sourceMapEnabled,
12 | extract: isProduction
13 | }),
14 | cssSourceMap: sourceMapEnabled,
15 | cacheBusting: config.dev.cacheBusting,
16 | transformToRequire: {
17 | video: ['src', 'poster'],
18 | source: 'src',
19 | img: 'src',
20 | image: 'xlink:href'
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/build/webpack.base.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const utils = require('./utils')
4 | const config = require('../config')
5 | const vueLoaderConfig = require('./vue-loader.conf')
6 |
7 | function resolve (dir) {
8 | return path.join(__dirname, '..', dir)
9 | }
10 |
11 |
12 |
13 | module.exports = {
14 | context: path.resolve(__dirname, '../'),
15 | entry: {
16 | app: './src/main.js'
17 | },
18 | output: {
19 | path: config.build.assetsRoot,
20 | filename: '[name].js',
21 | publicPath: process.env.NODE_ENV === 'production'
22 | ? config.build.assetsPublicPath
23 | : config.dev.assetsPublicPath
24 | },
25 | resolve: {
26 | extensions: ['.js', '.vue', '.json'],
27 | alias: {
28 | 'vue$': 'vue/dist/vue.esm.js',
29 | '@': resolve('src'),
30 | }
31 | },
32 | module: {
33 | rules: [
34 | {
35 | test: /\.vue$/,
36 | loader: 'vue-loader',
37 | options: vueLoaderConfig
38 | },
39 | {
40 | test: /\.js$/,
41 | loader: 'babel-loader',
42 | include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
43 | },
44 | {
45 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
46 | loader: 'url-loader',
47 | options: {
48 | limit: 10000,
49 | name: utils.assetsPath('img/[name].[hash:7].[ext]')
50 | }
51 | },
52 | {
53 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
54 | loader: 'url-loader',
55 | options: {
56 | limit: 10000,
57 | name: utils.assetsPath('media/[name].[hash:7].[ext]')
58 | }
59 | },
60 | {
61 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
62 | loader: 'url-loader',
63 | options: {
64 | limit: 10000,
65 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
66 | }
67 | }
68 | ]
69 | },
70 | node: {
71 | // prevent webpack from injecting useless setImmediate polyfill because Vue
72 | // source contains it (although only uses it if it's native).
73 | setImmediate: false,
74 | // prevent webpack from injecting mocks to Node native modules
75 | // that does not make sense for the client
76 | dgram: 'empty',
77 | fs: 'empty',
78 | net: 'empty',
79 | tls: 'empty',
80 | child_process: 'empty'
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/build/webpack.dev.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const utils = require('./utils')
3 | const webpack = require('webpack')
4 | const config = require('../config')
5 | const merge = require('webpack-merge')
6 | const path = require('path')
7 | const baseWebpackConfig = require('./webpack.base.conf')
8 | const CopyWebpackPlugin = require('copy-webpack-plugin')
9 | const HtmlWebpackPlugin = require('html-webpack-plugin')
10 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
11 | const portfinder = require('portfinder')
12 |
13 | const HOST = process.env.HOST
14 | const PORT = process.env.PORT && Number(process.env.PORT)
15 |
16 | const devWebpackConfig = merge(baseWebpackConfig, {
17 | module: {
18 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
19 | },
20 | // cheap-module-eval-source-map is faster for development
21 | devtool: config.dev.devtool,
22 |
23 | // these devServer options should be customized in /config/index.js
24 | devServer: {
25 | clientLogLevel: 'warning',
26 | historyApiFallback: {
27 | rewrites: [
28 | { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
29 | ],
30 | },
31 | hot: true,
32 | contentBase: false, // since we use CopyWebpackPlugin.
33 | compress: true,
34 | host: HOST || config.dev.host,
35 | port: PORT || config.dev.port,
36 | open: config.dev.autoOpenBrowser,
37 | overlay: config.dev.errorOverlay
38 | ? { warnings: false, errors: true }
39 | : false,
40 | publicPath: config.dev.assetsPublicPath,
41 | proxy: config.dev.proxyTable,
42 | quiet: true, // necessary for FriendlyErrorsPlugin
43 | watchOptions: {
44 | poll: config.dev.poll,
45 | }
46 | },
47 | plugins: [
48 | new webpack.DefinePlugin({
49 | 'process.env': require('../config/dev.env')
50 | }),
51 | new webpack.HotModuleReplacementPlugin(),
52 | new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
53 | new webpack.NoEmitOnErrorsPlugin(),
54 | // https://github.com/ampedandwired/html-webpack-plugin
55 | new HtmlWebpackPlugin({
56 | filename: 'index.html',
57 | template: 'index.html',
58 | inject: true
59 | }),
60 | // copy custom static assets
61 | new CopyWebpackPlugin([
62 | {
63 | from: path.resolve(__dirname, '../static'),
64 | to: config.dev.assetsSubDirectory,
65 | ignore: ['.*']
66 | }
67 | ])
68 | ]
69 | })
70 |
71 | module.exports = new Promise((resolve, reject) => {
72 | portfinder.basePort = process.env.PORT || config.dev.port
73 | portfinder.getPort((err, port) => {
74 | if (err) {
75 | reject(err)
76 | } else {
77 | // publish the new Port, necessary for e2e tests
78 | process.env.PORT = port
79 | // add port to devServer config
80 | devWebpackConfig.devServer.port = port
81 |
82 | // Add FriendlyErrorsPlugin
83 | devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
84 | compilationSuccessInfo: {
85 | messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
86 | },
87 | onErrors: config.dev.notifyOnErrors
88 | ? utils.createNotifierCallback()
89 | : undefined
90 | }))
91 |
92 | resolve(devWebpackConfig)
93 | }
94 | })
95 | })
96 |
--------------------------------------------------------------------------------
/build/webpack.prod.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const utils = require('./utils')
4 | const webpack = require('webpack')
5 | const config = require('../config')
6 | const merge = require('webpack-merge')
7 | const baseWebpackConfig = require('./webpack.base.conf')
8 | const CopyWebpackPlugin = require('copy-webpack-plugin')
9 | const HtmlWebpackPlugin = require('html-webpack-plugin')
10 | const ExtractTextPlugin = require('extract-text-webpack-plugin')
11 | const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
12 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
13 |
14 | const env = process.env.NODE_ENV === 'testing'
15 | ? require('../config/test.env')
16 | : require('../config/prod.env')
17 |
18 | const webpackConfig = merge(baseWebpackConfig, {
19 | module: {
20 | rules: utils.styleLoaders({
21 | sourceMap: config.build.productionSourceMap,
22 | extract: true,
23 | usePostCSS: true
24 | })
25 | },
26 | devtool: config.build.productionSourceMap ? config.build.devtool : false,
27 | output: {
28 | path: config.build.assetsRoot,
29 | filename: utils.assetsPath('js/[name].[chunkhash].js'),
30 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
31 | },
32 | plugins: [
33 | // http://vuejs.github.io/vue-loader/en/workflow/production.html
34 | new webpack.DefinePlugin({
35 | 'process.env': env
36 | }),
37 | new UglifyJsPlugin({
38 | uglifyOptions: {
39 | compress: {
40 | warnings: false
41 | }
42 | },
43 | sourceMap: config.build.productionSourceMap,
44 | parallel: true
45 | }),
46 | // extract css into its own file
47 | new ExtractTextPlugin({
48 | filename: utils.assetsPath('css/[name].[contenthash].css'),
49 | // Setting the following option to `false` will not extract CSS from codesplit chunks.
50 | // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
51 | // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
52 | // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
53 | allChunks: true,
54 | }),
55 | // Compress extracted CSS. We are using this plugin so that possible
56 | // duplicated CSS from different components can be deduped.
57 | new OptimizeCSSPlugin({
58 | cssProcessorOptions: config.build.productionSourceMap
59 | ? { safe: true, map: { inline: false } }
60 | : { safe: true }
61 | }),
62 | // generate dist index.html with correct asset hash for caching.
63 | // you can customize output by editing /index.html
64 | // see https://github.com/ampedandwired/html-webpack-plugin
65 | new HtmlWebpackPlugin({
66 | filename: process.env.NODE_ENV === 'testing'
67 | ? 'index.html'
68 | : config.build.index,
69 | template: 'index.html',
70 | inject: true,
71 | minify: {
72 | removeComments: true,
73 | collapseWhitespace: true,
74 | removeAttributeQuotes: true
75 | // more options:
76 | // https://github.com/kangax/html-minifier#options-quick-reference
77 | },
78 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin
79 | chunksSortMode: 'dependency'
80 | }),
81 | // keep module.id stable when vendor modules does not change
82 | new webpack.HashedModuleIdsPlugin(),
83 | // enable scope hoisting
84 | new webpack.optimize.ModuleConcatenationPlugin(),
85 | // split vendor js into its own file
86 | new webpack.optimize.CommonsChunkPlugin({
87 | name: 'vendor',
88 | minChunks (module) {
89 | // any required modules inside node_modules are extracted to vendor
90 | return (
91 | module.resource &&
92 | /\.js$/.test(module.resource) &&
93 | module.resource.indexOf(
94 | path.join(__dirname, '../node_modules')
95 | ) === 0
96 | )
97 | }
98 | }),
99 | // extract webpack runtime and module manifest to its own file in order to
100 | // prevent vendor hash from being updated whenever app bundle is updated
101 | new webpack.optimize.CommonsChunkPlugin({
102 | name: 'manifest',
103 | minChunks: Infinity
104 | }),
105 | // This instance extracts shared chunks from code splitted chunks and bundles them
106 | // in a separate chunk, similar to the vendor chunk
107 | // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
108 | new webpack.optimize.CommonsChunkPlugin({
109 | name: 'app',
110 | async: 'vendor-async',
111 | children: true,
112 | minChunks: 3
113 | }),
114 |
115 | // copy custom static assets
116 | new CopyWebpackPlugin([
117 | {
118 | from: path.resolve(__dirname, '../static'),
119 | to: config.build.assetsSubDirectory,
120 | ignore: ['.*']
121 | }
122 | ])
123 | ]
124 | })
125 |
126 | if (config.build.productionGzip) {
127 | const CompressionWebpackPlugin = require('compression-webpack-plugin')
128 |
129 | webpackConfig.plugins.push(
130 | new CompressionWebpackPlugin({
131 | asset: '[path].gz[query]',
132 | algorithm: 'gzip',
133 | test: new RegExp(
134 | '\\.(' +
135 | config.build.productionGzipExtensions.join('|') +
136 | ')$'
137 | ),
138 | threshold: 10240,
139 | minRatio: 0.8
140 | })
141 | )
142 | }
143 |
144 | if (config.build.bundleAnalyzerReport) {
145 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
146 | webpackConfig.plugins.push(new BundleAnalyzerPlugin())
147 | }
148 |
149 | module.exports = webpackConfig
150 |
--------------------------------------------------------------------------------
/build/webpack.test.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | // This is the webpack config used for unit tests.
3 |
4 | const utils = require('./utils')
5 | const webpack = require('webpack')
6 | const merge = require('webpack-merge')
7 | const baseWebpackConfig = require('./webpack.base.conf')
8 |
9 | const webpackConfig = merge(baseWebpackConfig, {
10 | // use inline sourcemap for karma-sourcemap-loader
11 | module: {
12 | rules: utils.styleLoaders()
13 | },
14 | devtool: '#inline-source-map',
15 | resolveLoader: {
16 | alias: {
17 | // necessary to to make lang="scss" work in test when using vue-loader's ?inject option
18 | // see discussion at https://github.com/vuejs/vue-loader/issues/724
19 | 'scss-loader': 'sass-loader'
20 | }
21 | },
22 | plugins: [
23 | new webpack.DefinePlugin({
24 | 'process.env': require('../config/test.env')
25 | })
26 | ]
27 | })
28 |
29 | // no need for app entry during tests
30 | delete webpackConfig.entry
31 |
32 | module.exports = webpackConfig
33 |
--------------------------------------------------------------------------------
/config/index.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | // Template version: 1.2.8
3 | // see http://vuejs-templates.github.io/webpack for documentation.
4 |
5 | const path = require('path')
6 |
7 | module.exports = {
8 | dev: {
9 |
10 | // Paths
11 | assetsSubDirectory: 'static',
12 | assetsPublicPath: '/',
13 | proxyTable: {},
14 |
15 | // Various Dev Server settings
16 | host: 'localhost', // can be overwritten by process.env.HOST
17 | port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
18 | autoOpenBrowser: false,
19 | errorOverlay: true,
20 | notifyOnErrors: true,
21 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
22 |
23 |
24 | /**
25 | * Source Maps
26 | */
27 |
28 | // https://webpack.js.org/configuration/devtool/#development
29 | devtool: 'cheap-module-eval-source-map',
30 |
31 | // If you have problems debugging vue-files in devtools,
32 | // set this to false - it *may* help
33 | // https://vue-loader.vuejs.org/en/options.html#cachebusting
34 | cacheBusting: true,
35 |
36 | cssSourceMap: true,
37 | },
38 |
39 | build: {
40 | // Template for index.html
41 | index: path.resolve(__dirname, '../dist/index.html'),
42 |
43 | // Paths
44 | assetsRoot: path.resolve(__dirname, '../dist'),
45 | assetsSubDirectory: 'static',
46 | assetsPublicPath: '/',
47 |
48 | /**
49 | * Source Maps
50 | */
51 |
52 | productionSourceMap: true,
53 | // https://webpack.js.org/configuration/devtool/#production
54 | devtool: '#source-map',
55 |
56 | // Gzip off by default as many popular static hosts such as
57 | // Surge or Netlify already gzip all static assets for you.
58 | // Before setting to `true`, make sure to:
59 | // npm install --save-dev compression-webpack-plugin
60 | productionGzip: false,
61 | productionGzipExtensions: ['js', 'css'],
62 |
63 | // Run the build command with an extra argument to
64 | // View the bundle analyzer report after build finishes:
65 | // `npm run build --report`
66 | // Set to `true` or `false` to always turn it on or off
67 | bundleAnalyzerReport: process.env.npm_config_report
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/config/test.env.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const merge = require('webpack-merge')
3 | const devEnv = require('./dev.env')
4 |
5 | module.exports = merge(devEnv, {
6 | NODE_ENV: '"testing"'
7 | })
8 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ticketing
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ticketing",
3 | "version": "1.0.0",
4 | "description": "a vue js application for administrators of Metrotrans",
5 | "author": "Kamau Brian",
6 | "private": true,
7 | "scripts": {
8 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
9 | "start": "npm run dev",
10 | "unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run",
11 | "e2e": "node test/e2e/runner.js",
12 | "test": "npm run unit && npm run e2e",
13 | "build": "node build/build.js"
14 | },
15 | "dependencies": {
16 | "apexcharts": "^2.1.2",
17 | "axios": "^0.18.0",
18 | "fast-crc32c": "^1.0.4",
19 | "firebase": "^5.5.1",
20 | "firebase-admin": "^6.0.0",
21 | "install": "^0.12.1",
22 | "lodash": "^4.17.11",
23 | "vue": "^2.5.2",
24 | "vue-apexcharts": "^1.2.1",
25 | "vue-router": "^3.0.1",
26 | "vue-perfect-scrollbar": "^0.1.0",
27 | "vuetify": "1.5.1",
28 | "vuex": "^3.0.1",
29 | "vuex-persistedstate": "^2.5.4",
30 | "vuex-router-sync": "^5.0.0",
31 | "font-awesome": "^4.7.0",
32 | "stylus": "^0.54.5",
33 | "stylus-loader": "^3.0.2"
34 | },
35 | "devDependencies": {
36 | "autoprefixer": "^7.1.2",
37 | "babel-core": "^6.22.1",
38 | "babel-helper-vue-jsx-merge-props": "^2.0.3",
39 | "babel-loader": "^7.1.1",
40 | "babel-plugin-istanbul": "^4.1.1",
41 | "babel-plugin-syntax-jsx": "^6.18.0",
42 | "babel-plugin-transform-runtime": "^6.22.0",
43 | "babel-plugin-transform-vue-jsx": "^3.5.0",
44 | "babel-preset-env": "^1.3.2",
45 | "babel-preset-stage-2": "^6.22.0",
46 | "babel-register": "^6.22.0",
47 | "chai": "^4.1.2",
48 | "chalk": "^2.0.1",
49 | "chromedriver": "^2.27.2",
50 | "copy-webpack-plugin": "^4.0.1",
51 | "cross-env": "^5.0.1",
52 | "cross-spawn": "^5.0.1",
53 | "css-loader": "^0.28.0",
54 | "extract-text-webpack-plugin": "^3.0.0",
55 | "file-loader": "^1.1.4",
56 | "friendly-errors-webpack-plugin": "^1.6.1",
57 | "html-webpack-plugin": "^2.30.1",
58 | "inject-loader": "^3.0.0",
59 | "karma": "^6.3.16",
60 | "karma-coverage": "^1.1.1",
61 | "karma-mocha": "^1.3.0",
62 | "karma-phantomjs-launcher": "^1.0.2",
63 | "karma-phantomjs-shim": "^1.4.0",
64 | "karma-sinon-chai": "^1.3.1",
65 | "karma-sourcemap-loader": "^0.3.7",
66 | "karma-spec-reporter": "0.0.31",
67 | "karma-webpack": "^2.0.2",
68 | "mocha": "^3.2.0",
69 | "nightwatch": "^0.9.12",
70 | "node-notifier": "^5.1.2",
71 | "optimize-css-assets-webpack-plugin": "^3.2.0",
72 | "ora": "^1.2.0",
73 | "phantomjs-prebuilt": "^2.1.14",
74 | "portfinder": "^1.0.13",
75 | "postcss-import": "^11.0.0",
76 | "postcss-loader": "^2.0.8",
77 | "postcss-url": "^7.2.1",
78 | "rimraf": "^2.6.0",
79 | "selenium-server": "^3.0.1",
80 | "semver": "^5.3.0",
81 | "shelljs": "^0.7.6",
82 | "sinon": "^4.0.0",
83 | "sinon-chai": "^2.8.0",
84 | "uglifyjs-webpack-plugin": "^1.1.1",
85 | "url-loader": "^0.5.8",
86 | "vue-loader": "^13.3.0",
87 | "vue-style-loader": "^3.0.1",
88 | "vue-template-compiler": "^2.5.2",
89 | "webpack": "^3.6.0",
90 | "webpack-bundle-analyzer": "^3.3.2",
91 | "webpack-cli": "^3.2.1",
92 | "webpack-dev-server": "^3.0.0",
93 | "webpack-merge": "^4.1.0"
94 | },
95 | "engines": {
96 | "node": ">= 6.0.0",
97 | "npm": ">= 3.0.0"
98 | },
99 | "browserslist": [
100 | "> 1%",
101 | "last 2 versions",
102 | "not ie <= 8"
103 | ]
104 | }
105 |
--------------------------------------------------------------------------------
/src/.gitrepo:
--------------------------------------------------------------------------------
1 | ; DO NOT EDIT (unless you know what you are doing)
2 | ;
3 | ; This subdirectory is a git "subrepo", and this file is maintained by the
4 | ; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
5 | ;
6 | [subrepo]
7 | remote = https://github.com/vuetifyjs/templates-common.git
8 | branch = subrepo/webpack-src
9 | commit = 090741fa8ba4da0c6f85db64eff64550704123e1
10 | parent = e05204fc0583a8c99f1963ce873eba1266838215
11 | method = merge
12 | cmdver = 0.4.0
13 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
14 |
15 |
16 |
17 |
18 |
19 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
39 |
40 | exit_to_app
41 |
42 | Logout
43 |
44 |
45 |
46 |
47 |
52 |
53 |
54 | MetroTrans Inc. Admin
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | {{ item.icon }}
67 |
68 |
69 | {{ item.title }}
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | MetroTrans Inc.© {{new Date().getFullYear()}}
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 | keyboard_arrow_up
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
202 |
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kamaubrian/TicketingWebClient/c618f581af0d889891b8bf344ebd56ced868750b/src/assets/logo.png
--------------------------------------------------------------------------------
/src/components/HelloWorld.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | “First, solve the problem. Then, write the code.”
8 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
36 |
--------------------------------------------------------------------------------
/src/components/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
13 |
18 |
19 |
20 |
21 |
26 |
27 |
28 |
29 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
44 |
48 |
49 |
50 |
Our Clientele
51 |
52 | Gives you Complete Control over Users
53 |
54 |
55 |
56 |
57 |
58 | Explore Users
59 |
60 |
61 |
62 |
63 |
64 |
65 |
69 |
73 |
74 |
75 |
Bus Schedules
76 |
77 | Easily Manage Bus Schedules
78 |
79 |
80 |
81 |
82 |
83 | Manage Bus Routes
84 |
85 |
86 |
87 |
88 |
89 |
90 |
94 |
98 |
99 |
100 |
System Adminstrators
101 |
102 | Manage System Adminstrators
103 |
104 |
105 |
106 |
107 |
108 | Manage System Admins.
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
121 |
124 |
125 |
126 |
Target Projections
127 |
128 | View Market Penetration Percentile
129 |
130 |
131 |
132 |
133 |
134 | View Target Projections
135 |
136 |
137 |
138 |
139 |
140 |
141 |
145 |
150 |
151 |
152 |
Revenue Collections
153 |
154 | View Revenue Collected Through Receipts
155 |
156 |
157 |
158 |
159 |
160 | View Revenue Collected
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
173 |
179 |
180 |
181 |
MetroTrans Inc. Driving School
182 |
183 | Manage Students Signed up for our service
184 |
185 |
186 |
187 |
188 |
189 | View Students
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
252 |
--------------------------------------------------------------------------------
/src/components/Schedule/Schedule.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Create Schedule
17 |
18 |
19 |
20 |
21 |
27 |
28 |
29 |
35 |
36 |
37 |
38 |
39 |
45 |
46 |
47 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
71 |
72 |
73 |
74 |
75 |
81 |
82 |
83 |
89 |
90 |
91 |
92 |
93 |
99 |
100 |
101 |
107 |
108 |
109 |
110 | Create Schedule
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 | Saved Bus Schedules
120 |
121 |
126 |
127 |
128 |
129 |
130 |
135 |
136 |
137 | {{props.item.departureLocation}} |
138 | {{ props.item.arrivalDestination }} |
139 | {{ props.item.timeTaken }} |
140 | {{ props.item.pricePerTrip }} |
141 | {{ props.item.departureTime }} |
142 |
143 |
148 | edit
149 |
150 |
153 | delete
154 |
155 | |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 | Generate Geocode Location
167 |
168 |
173 |
174 |
175 |
176 |
177 |
183 |
184 |
185 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
301 |
--------------------------------------------------------------------------------
/src/components/auth/Login.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
![MetroTrans Inc.]()
10 |
11 |
12 |
18 |
25 |
26 |
27 |
28 |
29 |
30 | LOGIN
31 |
32 |
37 |
41 |
42 | Authenticating User.....
43 |
48 |
49 |
50 |
51 |
52 |
All Rights Reserved {{new Date().getFullYear()}} ©
53 |
![MetroTrans Inc.]()
54 |
55 |
56 |
64 | {{ snackbarText ? snackbarText = error: snackbarText }}
65 |
66 | close
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
142 |
147 |
--------------------------------------------------------------------------------
/src/components/bus/Bus.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
29 |
--------------------------------------------------------------------------------
/src/components/settings/Settings.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | settings
6 |
7 |
8 |
9 |
10 | close
11 |
12 | Settings
13 |
14 |
15 | Save
16 |
17 |
18 |
19 | User Controls
20 |
21 |
22 | Content filtering
23 | Set the content filtering level to restrict apps that can be downloaded
24 |
25 |
26 |
27 |
28 | Password
29 | Require password for purchase or use password to restrict purchase
30 |
31 |
32 |
33 |
34 |
35 | General
36 |
37 |
38 |
39 |
40 |
41 | Notifications
42 | Notify me about updates to apps or games that I downloaded
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | Sound
51 | Auto-update apps at any time. Data charges may apply
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | Auto-add widgets
60 | Automatically add home screen widgets
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
80 |
--------------------------------------------------------------------------------
/src/components/student/Students.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | Registered Students
16 |
17 |
22 |
23 |
24 |
25 |
26 |
30 |
31 | {{props.item.emailAddress}} |
32 | {{props.item.firstName}} |
33 | {{props.item.lastName}} |
34 | {{props.item.phoneNumber}} |
35 | {{props.item.timeStamp}} |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
85 |
--------------------------------------------------------------------------------
/src/components/transactions/Payments.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Paid Tickets(MPESA)
17 |
18 |
24 |
25 |
26 |
27 |
28 |
32 |
33 | {{props.item.emailAddress}} |
34 | {{props.item.receiptNumber}} |
35 | {{props.item.transactionAmount}} |
36 | {{props.item.phoneNumber}} |
37 | {{props.item.fromLocation}} |
38 | {{props.item.destinationLocation}} |
39 | {{props.item.timeStamp}} |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
117 |
--------------------------------------------------------------------------------
/src/components/users/AddUser.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 | add
10 | Add New User
11 |
12 |
13 |
17 |
18 | Use Google's location service?
19 |
20 |
21 | Let Google help apps determine location. This means sending anonymous location data to Google, even when no apps are running.
22 |
23 |
24 |
25 |
26 |
27 |
32 | Disagree
33 |
34 |
35 |
40 | Agree
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
64 |
--------------------------------------------------------------------------------
/src/components/users/Delete.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/components/users/Profile.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | {{this.$store.state.adminstrator.firstName }}
11 | {{this.$store.state.adminstrator.lastName}}
12 |
13 |
14 |
23 |
30 | account_circle
31 | close
32 |
33 |
34 |
40 | edit
41 |
42 |
49 | delete
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | Profile
58 |
59 |
60 | Activity
61 |
62 |
63 | Administrators
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | work
73 |
74 |
75 | System Administrator
76 | Job Title
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 | phone
85 |
86 |
87 | {{this.$store.state.adminstrator.phoneNumber}}
88 | Mobile
89 |
90 |
91 | chat
92 |
93 |
94 |
95 |
96 |
97 | mail
98 |
99 |
100 | {{this.$store.state.adminstrator.emailAddress}}
101 | Email
102 |
103 |
104 | chat
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 | Logs
115 |
116 | Real Time Logging
122 |
123 |
124 |
125 |
126 |
130 |
137 |
142 | Lorem ipsum dolor sit amet, no nam oblique veritus. Commune scaevola imperdiet nec ut, sed
143 | euismod convenire principes at. Est et nobis iisque percipit, an vim zril disputando
144 | voluptatibus, vix an salutandi sententiae.
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
167 | {{ snackbarText }}
168 |
169 | close
170 |
171 |
172 |
180 | {{ error.message }} Adminstrator Already Exists
181 |
182 | close
183 |
184 |
185 |
186 |
187 |
188 |
309 |
--------------------------------------------------------------------------------
/src/components/users/Users.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
11 |
12 |
13 | Our Customers
14 |
15 |
16 |
17 |
18 |
19 |
20 |
26 |
27 |
28 |
29 |
30 |
34 |
35 | {{props.item.uid}} |
36 | {{props.item.email!==undefined ? props.item.email : props.item.phoneNumber}} |
37 | {{props.item.metadata.creationTime!==undefined ? props.item.metadata.creationTime: null}} |
38 | {{props.item.metadata.lastSignInTime ? props.item.metadata.lastSignInTime :null}} |
39 |
40 |
46 | edit
47 |
48 |
51 | delete
52 |
53 | |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
104 |
--------------------------------------------------------------------------------
/src/components/users/admin/AddAdminstrator.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | add
6 |
7 |
8 |
9 | New Administrator
10 |
11 |
12 |
13 |
14 |
15 | cloud_upload
16 | Upload Profile Image
17 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | Close
50 |
51 | Save
52 |
53 |
54 |
55 |
56 |
57 |
58 |
127 |
132 |
--------------------------------------------------------------------------------
/src/components/users/admin/ViewAdminstrators.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Administrator Directory
5 |
6 |
8 |
9 |
19 |
24 | md-account
25 |
26 |
27 |
28 |
31 |
32 |
36 | Select a User
37 |
38 |
44 |
45 |
46 |
49 |
51 |
52 |
53 | cancel
54 |
55 | {{selected.name}}
56 | {{selected.email}}
57 | {{selected.username}}
58 |
59 |
60 |
64 | Company:
65 | {{selected.company.name}}
66 | Website:
67 |
68 | {{selected.website}}
69 |
70 | Phone:
71 | {{ selected.phone }}
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
136 |
--------------------------------------------------------------------------------
/src/components/utils/Alert.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{text}}
4 |
5 |
6 |
16 |
--------------------------------------------------------------------------------
/src/components/utils/Statistic.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
11 | {{icon}}
12 |
13 |
14 |
15 |
{{title}}
16 |
{{subTitle}}
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
34 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | // The Vue build version to load with the `import` command
2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
3 | import Vue from 'vue'
4 | import App from './App'
5 | import router from './router'
6 | import Vuetify from 'vuetify'
7 | import 'vuetify/dist/vuetify.min.css'
8 | import 'font-awesome/css/font-awesome.css'
9 | import * as firebase from 'firebase'
10 | import {store} from './store'
11 | import AlertComponent from './components/utils/Alert';
12 | import {sync} from 'vuex-router-sync'
13 | import VueApexCharts from 'vue-apexcharts'
14 | import SettingsComponent from './components/settings/Settings'
15 | import AddUser from './components/users/AddUser'
16 | import AddAdminstrator from './components/users/admin/AddAdminstrator'
17 | import Statistic from './components/utils/Statistic'
18 | import _env from './env'
19 |
20 | Vue.use(Vuetify, { theme: {
21 | primary: '#5F9EA0',
22 | secondary: '#424242',
23 | accent: '#82B1FF',
24 | error: '#FF5252',
25 | info: '#2196F3',
26 | success: '#4CAF50',
27 | warning: '#FFC107',
28 | primarydark:'#23283a',
29 | colorBlue:'#5F9EA0'
30 | }});
31 | Vue.use(VueApexCharts);
32 | Vue.config.productionTip = false;
33 | Vue.component('app-alert',AlertComponent);
34 | Vue.component('settings-view',SettingsComponent);
35 | Vue.component('add-user',AddUser);
36 | Vue.component('add-admin',AddAdminstrator);
37 | Vue.component('mini-statistic',Statistic);
38 |
39 | sync(store,router);
40 | new Vue({
41 | el: '#app',
42 | router,
43 | store,
44 | components: { App },
45 | template: '',
46 | created(){
47 | firebase.initializeApp({
48 | apiKey: _env.apiKey,
49 | authDomain: _env.authDomain,
50 | databaseURL: _env.databaseURL,
51 | projectId: _env.projectId,
52 | storageBucket: _env.storageBucket,
53 | messagingSenderId: _env.messagingSenderId
54 | });
55 |
56 | if(this.$store.state.token !==null && this.$store.state.token !==undefined){
57 | this.$router.push('/home-dash');
58 |
59 | }
60 | }
61 |
62 | });
63 |
--------------------------------------------------------------------------------
/src/router/auth-guard.js:
--------------------------------------------------------------------------------
1 | import {store} from '../store'
2 |
3 | export default(to,from,next)=>{
4 | if(store.state.token !==null && store.state.token !== undefined){
5 | next();
6 | }else{
7 | next('/');
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router'
3 | import Home from '@/components/Home'
4 | import Schedule from '@/components/Schedule/Schedule'
5 | import Login from '@/components/auth/Login'
6 | import Payments from '@/components/transactions/Payments'
7 | import Customers from '@/components/users/Users'
8 | import Profile from '@/components/users/Profile'
9 | import Bus from '@/components/bus/Bus'
10 | import Student from '@/components/student/Students'
11 | import auth from './auth-guard'
12 | Vue.use(Router);
13 |
14 | export default new Router({
15 | routes: [
16 | {
17 | path:'/',
18 | name:'Login',
19 | component:Login
20 | },
21 | {
22 | path:'/schedule',
23 | name:'Schedule',
24 | component:Schedule,
25 | beforeEnter:auth
26 | },
27 | {
28 | path:'/payments',
29 | name:'Payments',
30 | component:Payments,
31 | beforeEnter:auth
32 | },
33 | {
34 | path:'/home-dash',
35 | name:'Home',
36 | component:Home,
37 | beforeEnter:auth
38 | },
39 | {
40 | path:'/customers',
41 | name:'Customers',
42 | component:Customers,
43 | beforeEnter:auth
44 | },
45 | {
46 | path:'/admin-profile',
47 | name:'Profile',
48 | component:Profile,
49 | beforeEnter:auth
50 | },
51 | {
52 | path:'/bus-check',
53 | name:'Bus',
54 | component:Bus,
55 | beforeEnter:auth
56 | },
57 | {
58 | path:'/students',
59 | name:'Student',
60 | component:Student,
61 | beforeEnter:auth
62 | }
63 | ],mode:'history'
64 | })
65 |
--------------------------------------------------------------------------------
/src/services/api.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 | import {store} from '../store'
3 | export default(module) => {
4 | switch(module){
5 |
6 | case 'user':
7 | return axios.create({
8 | baseURL:'https://ticketingrestapi.herokuapp.com/api/v1/user'
9 | });
10 |
11 | case 'user_v2':
12 | return axios.create({
13 | baseURL:'https://ticketingrestapi.herokuapp.com/api/v2/user'
14 | });
15 |
16 | case 'maps':
17 | return axios.create({
18 | baseURL:'https://ticketingrestapi.herokuapp.com/api/v1/maps'
19 | });
20 |
21 | case 'payments':
22 | return axios.create({
23 | baseURL:'https://ticketingrestapi.herokuapp.com/api/v2/callback/'
24 | });
25 |
26 | case 'admin':
27 | return axios.create({
28 | baseURL:'https://ticketingrestapi.herokuapp.com/api/v1/admin'
29 | });
30 |
31 | case 'bus':
32 | return axios.create({
33 | baseURL:'https://ticketingrestapi.herokuapp.com/api/v3/bus',
34 | headers:{
35 | Authorization:`Bearer ${store.state.token}`
36 | }
37 | });
38 |
39 | case 'student':
40 | return axios.create({
41 | baseURL:'https://ticketingrestapi.herokuapp.com/api/v3/student'
42 | });
43 |
44 | default:
45 | return axios.create({
46 | baseURL:'https://ticketingrestapi.herokuapp.com/api/v1/docs'
47 | });
48 | }
49 | };
50 |
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import Vuex from 'vuex';
3 | import * as firebase from 'firebase';
4 | import api from '../services/api';
5 | import createPersistedState from 'vuex-persistedstate';
6 |
7 | Vue.use(Vuex);
8 |
9 | export const store = new Vuex.Store({
10 | strict: true,
11 | plugins: [
12 | createPersistedState()
13 | ],
14 | state: {
15 | loadedSchedules: [{
16 | departureLocation: '',
17 | arrivalDestination: '',
18 | timeTaken: '',
19 | routeTaken: '',
20 | pricePerTrip: '',
21 | departureTime: '',
22 | departureLatitude: '',
23 | departureLongitude: '',
24 | arrivalLatitude: '',
25 | arrivalLongitude: '',
26 | }],
27 | payments: [{
28 | emailAddress: '',
29 | receiptNumber: '',
30 | transactionAmount: '',
31 | phoneNumber: '',
32 | fromLocation: '',
33 | destinationLocation: '',
34 | timeStamp: ''
35 | }],
36 | adminstrator: [{
37 | firstName: '',
38 | lastName: '',
39 | emailAddress: '',
40 | phoneNumber: '',
41 | authenticationPassword: '',
42 | profileImageUrl: ''
43 | }],
44 | user: null,
45 | loading: false,
46 | error: null,
47 | token: null,
48 | locationLatitude: null,
49 | locationLongitude: null,
50 | customers: [{
51 | uid: '',
52 | emailAddress: '',
53 | phoneNumber: '',
54 | creationTime: '',
55 | lastSignInTime: ''
56 | }],
57 | student: [{
58 | firstName: '',
59 | lastName: '',
60 | emailAddress: '',
61 | phoneNumber: '',
62 | timeStamp: ''
63 | }],
64 | profileImageUrl: '',
65 | successAddingAdminstrator: ''
66 | },
67 |
68 | mutations: {
69 | createSchedule(state, payload) {
70 | state.loadedSchedules.push(payload);
71 | },
72 | setLoading(state, payload) {
73 | state.loading = payload;
74 | },
75 | setError(state, payload) {
76 | state.error = payload;
77 | },
78 | clearError(state, payload) {
79 | state.error = null;
80 | },
81 | onClearToken(state) {
82 | state.token = null;
83 | },
84 | setLoadedSchedules(state, payload) {
85 | state.loadedSchedules = payload;
86 | },
87 | setLoadedStudents(state, payload) {
88 | state.student = payload;
89 | },
90 | setLoadedPayments(state, payload) {
91 | state.payments = payload;
92 | },
93 | setToken(state, payload) {
94 | state.token = payload;
95 | },
96 | setLatitude(state, payload) {
97 | state.locationLatitude = payload;
98 | },
99 | setLongitude(state, payload) {
100 | state.locationLongitude = payload;
101 | },
102 | setCustomers(state, payload) {
103 | state.customers = payload;
104 | },
105 | setAdminstrator(state, payload) {
106 | state.adminstrator = payload;
107 | },
108 | setProfileImageUrl(state, payload) {
109 | state.profileImageUrl = payload;
110 | },
111 | clearPayments(state) {
112 | state.payments = null;
113 | },
114 | clearCustomers(state) {
115 | state.customers = null
116 | },
117 | clearAdminstrator(state) {
118 | state.adminstrator = null;
119 | },
120 | clearSchedules(state) {
121 | state.loadedSchedules = null;
122 | },
123 | setSuccessCreatingAdminstrator(state, payload) {
124 | state.successAddingAdminstrator = payload;
125 | },
126 | unSetSuccessMessage(state) {
127 | state.successAddingAdminstrator = false;
128 | }
129 | },
130 | actions: {
131 | onUnSetAddingAdminstrator({commit}) {
132 | commit('unSetSuccessMessage');
133 | },
134 | async onCreateAdminstrator({commit}, payload) {
135 | try {
136 | commit('clearError');
137 | commit('setLoading', true);
138 | const filename = payload.image.name;
139 | console.log(filename);
140 | const extension = await filename.slice(filename.lastIndexOf('.'));
141 | const fileData = await firebase.storage().ref('admins/' + payload.firstName + new Date().toISOString() + extension).put(payload.image);
142 | const imagePath = await fileData.metadata.fullPath;
143 | const downloadableUrl = await firebase.storage().ref().child(imagePath).getDownloadURL();
144 | const adminstrator = {
145 | emailAddress: payload.emailAddress,
146 | authenticationPassword: payload.authenticationPassword,
147 | firstName: payload.firstName,
148 | lastName: payload.lastName,
149 | phoneNumber: payload.phoneNumber,
150 | profileImageUrl: downloadableUrl
151 | };
152 | console.log(downloadableUrl);
153 | const response = await api('admin').post('/', adminstrator);
154 | //commit('setAdminstrator',response.data.admin);
155 | console.log(response);
156 | commit('setLoading', false);
157 | commit('setSuccessCreatingAdminstrator', true);
158 | //commit('setProfileImageUrl',downloadableUrl);
159 | } catch (e) {
160 | console.log(e.message);
161 | commit('setLoading', false);
162 | commit('setError', e);
163 | }
164 | },
165 |
166 | async onFetchCustomerList({commit}) {
167 | let response;
168 | try {
169 | commit('clearError');
170 | commit('setLoading', true);
171 | response = await api('user').get('/auth/allUsers');
172 | commit('setCustomers', response.data.users);
173 | commit('setLoading', false);
174 |
175 | } catch (error) {
176 | commit('setError', error);
177 | commit('setLoading', false);
178 | }
179 | },
180 |
181 | async onFetchAllStudents({commit}) {
182 | let response;
183 | try {
184 | commit('clearError');
185 | commit('setLoading', true);
186 | response = await api('student').get('/get-all');
187 | commit('setLoadedStudents', response.data.batchStudents);
188 | console.log(response.data);
189 | commit('setLoading', false);
190 | } catch (error) {
191 | commit('setError', error);
192 | commit('setLoading', false);
193 | }
194 | },
195 |
196 | async onLoginAdminstrator({commit}, payload) {
197 | let response;
198 | try {
199 | commit('setLoading', true);
200 | commit('clearError');
201 | response = await api('admin').post('/auth/', payload);
202 | commit('setProfileImageUrl', response.data.adminFound.profileImageUrl);
203 | commit('setLoading', false);
204 | commit('setAdminstrator', response.data.adminFound);
205 | commit('setToken', response.data.token);
206 | } catch (e) {
207 |
208 | commit('setLoading', false);
209 | commit('setError', e.message);
210 | }
211 | return response;
212 | },
213 |
214 | async onFetchGeolocation({commit}, payload) {
215 | let response;
216 | try {
217 | commit('clearError');
218 | response = await api('maps').post('/', payload);
219 | commit('setLatitude', response.data.geoLocation.latitude);
220 | commit('setLongitude', response.data.geoLocation.longitude);
221 | //console.log('Latitude',response.data.geoLocation.latitude);
222 | } catch (e) {
223 | commit('setError', e.message);
224 | }
225 | },
226 |
227 | async onGetPayments({commit}) {
228 | let response;
229 | try {
230 | commit('setLoading', true);
231 | commit('clearError');
232 | response = await api('payments').get('/allTransactions');
233 | console.log("This is the response", response);
234 | commit('setLoadedPayments', response.data.response.transactions);
235 | commit('setLoading', false);
236 | } catch (e) {
237 | commit('setError', e.message);
238 | commit('setLoading', false);
239 | }
240 | },
241 |
242 | async onFetchPaymentsFromFirebase({commit}) {
243 | let response;
244 | try {
245 | commit('setLoading', true);
246 | commit('clearError');
247 | let responseArray = [];
248 | response = await firebase.database().ref('TicketPayments').once('value');
249 | const responseObjects = response.val();
250 | for (let key in responseObjects) {
251 | responseArray.push({
252 | emailAddress: responseObjects[key].emailAddress,
253 | receiptNumber: responseObjects[key].receiptNumber,
254 | transactionAmount: responseObjects[key].transactionAmount,
255 | phoneNumber: responseObjects[key].phoneNumber,
256 | fromLocation: responseObjects[key].fromLocation,
257 | destinationLocation: responseObjects[key].destinationLocation,
258 | timeStamp: responseObjects[key].timeStamp
259 | });
260 | }
261 | commit('setLoading', false);
262 | commit('setLoadedPayments', responseArray);
263 | } catch (e) {
264 | commit('setError', e);
265 | commit('setLoading', false);
266 | }
267 | },
268 | async onTextDataChanged({commit}) {
269 | let response;
270 | try {
271 | // commit('setLoading',true);
272 | commit('clearError');
273 | let responseArray = [];
274 | response = await firebase.database().ref('TicketPayments').once('value');
275 | const responseObjects = response.val();
276 | for (let key in responseObjects) {
277 | responseArray.push({
278 | emailAddress: responseObjects[key].emailAddress,
279 | receiptNumber: responseObjects[key].receiptNumber,
280 | transactionAmount: responseObjects[key].transactionAmount,
281 | phoneNumber: responseObjects[key].phoneNumber,
282 | fromLocation: responseObjects[key].fromLocation,
283 | destinationLocation: responseObjects[key].destinationLocation,
284 | timeStamp: responseObjects[key].timeStamp
285 | });
286 | }
287 | // commit('setLoading',false);
288 | commit('setLoadedPayments', responseArray);
289 | } catch (e) {
290 | commit('setError', e);
291 | //commit('setLoading',false);
292 | }
293 | },
294 | onCreateSchedule({commit, getters}, payload) {
295 | commit('setLoading', true);
296 | commit('clearError');
297 | const schedule = {
298 | departureLocation: payload.departureLocation,
299 | arrivalDestination: payload.arrivalDestination,
300 | timeTaken: payload.timeTaken,
301 | routeTaken: payload.routeTaken,
302 | pricePerTrip: payload.pricePerTrip,
303 | departureTime: payload.departureTime,
304 | departureLatitude: payload.departureLatitude,
305 | departureLongitude: payload.departureLongitude,
306 | arrivalLatitude: payload.arrivalLatitude,
307 | arrivalLongitude: payload.arrivalLongitude
308 | };
309 | firebase.database().ref("Schedule").push(schedule)
310 | .then((data) => {
311 | const key = data.key;
312 | commit('createSchedule', {...schedule, id: key});
313 | commit('setLoading', false);
314 | })
315 | .catch((error) => {
316 | console.log(error);
317 | commit('setLoading', false);
318 | commit('setError', error);
319 | })
320 |
321 | },
322 | loadSchedule({commit}) {
323 | commit('setLoading', true);
324 | firebase.database().ref('Schedule').once('value')
325 | .then(data => {
326 | const schedules = [];
327 | const objects = data.val();
328 | for (let key in objects) {
329 | schedules.push({
330 | id: key,
331 | departureLocation: objects[key].departureLocation,
332 | arrivalDestination: objects[key].arrivalDestination,
333 | timeTaken: objects[key].timeTaken,
334 | routeTaken: objects[key].routeTaken,
335 | pricePerTrip: objects[key].pricePerTrip,
336 | departureTime: objects[key].departureTime
337 | });
338 | }
339 | commit('setLoading', false);
340 | commit('setLoadedSchedules', schedules);
341 | //console.log(schedules);
342 | })
343 | .catch((error) => {
344 | commit('setLoading', false);
345 | commit('setError', error);
346 | console.log(error);
347 | });
348 | },
349 | clearErrors({commit}) {
350 | commit('clearError');
351 | },
352 | onLogout({commit}) {
353 | commit('onClearToken');
354 | commit('clearError');
355 | commit('clearSchedules');
356 | commit('clearCustomers');
357 | commit('clearAdminstrator');
358 | commit('clearPayments');
359 | },
360 | setToken({commit}, payload) {
361 | commit('setToken', payload);
362 | }
363 | },
364 | getters: {
365 | user(state) {
366 | return state.user;
367 | },
368 | error(state) {
369 | return state.error;
370 | },
371 | loading(state) {
372 | return state.loading;
373 | },
374 | loadedSchedules(state) {
375 | return state.loadedSchedules;
376 | },
377 | getToken(state) {
378 | return state.token
379 | },
380 | latitude(state) {
381 | return state.locationLatitude;
382 | },
383 | longitude(state) {
384 | return state.locationLongitude;
385 | },
386 | payments(state) {
387 | return state.payments;
388 | },
389 | customers(state) {
390 | return state.customers;
391 | },
392 | profileImageUrl(state) {
393 | return state.profileImageUrl;
394 | },
395 | onGetStudents(state) {
396 | return state.student;
397 | }
398 |
399 | }
400 | });
401 |
--------------------------------------------------------------------------------
/src/utils/date.js:
--------------------------------------------------------------------------------
1 | export default (value)=>{
2 | const date = new Date(value);
3 | return date.toLocaleString(['en-US'],{month:'short',day:'2-digit',year:'numeric',
4 | hour:'2-digit',minute:'2-digit'});
5 | };
6 |
--------------------------------------------------------------------------------
/static/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kamaubrian/TicketingWebClient/c618f581af0d889891b8bf344ebd56ced868750b/static/.gitkeep
--------------------------------------------------------------------------------
/static/logo/metro_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kamaubrian/TicketingWebClient/c618f581af0d889891b8bf344ebd56ced868750b/static/logo/metro_white.png
--------------------------------------------------------------------------------
/static/logo/metrotrans_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kamaubrian/TicketingWebClient/c618f581af0d889891b8bf344ebd56ced868750b/static/logo/metrotrans_logo.png
--------------------------------------------------------------------------------
/static/profile/man_profile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kamaubrian/TicketingWebClient/c618f581af0d889891b8bf344ebd56ced868750b/static/profile/man_profile.png
--------------------------------------------------------------------------------
/static/profile/profile_background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kamaubrian/TicketingWebClient/c618f581af0d889891b8bf344ebd56ced868750b/static/profile/profile_background.jpg
--------------------------------------------------------------------------------
/test/e2e/custom-assertions/elementCount.js:
--------------------------------------------------------------------------------
1 | // A custom Nightwatch assertion.
2 | // The assertion name is the filename.
3 | // Example usage:
4 | //
5 | // browser.assert.elementCount(selector, count)
6 | //
7 | // For more information on custom assertions see:
8 | // http://nightwatchjs.org/guide#writing-custom-assertions
9 |
10 | exports.assertion = function (selector, count) {
11 | this.message = 'Testing if element <' + selector + '> has count: ' + count
12 | this.expected = count
13 | this.pass = function (val) {
14 | return val === this.expected
15 | }
16 | this.value = function (res) {
17 | return res.value
18 | }
19 | this.command = function (cb) {
20 | var self = this
21 | return this.api.execute(function (selector) {
22 | return document.querySelectorAll(selector).length
23 | }, [selector], function (res) {
24 | cb.call(self, res)
25 | })
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/test/e2e/nightwatch.conf.js:
--------------------------------------------------------------------------------
1 | require('babel-register')
2 | var config = require('../../config')
3 |
4 | // http://nightwatchjs.org/gettingstarted#settings-file
5 | module.exports = {
6 | src_folders: ['test/e2e/specs'],
7 | output_folder: 'test/e2e/reports',
8 | custom_assertions_path: ['test/e2e/custom-assertions'],
9 |
10 | selenium: {
11 | start_process: true,
12 | server_path: require('selenium-server').path,
13 | host: '127.0.0.1',
14 | port: 4444,
15 | cli_args: {
16 | 'webdriver.chrome.driver': require('chromedriver').path
17 | }
18 | },
19 |
20 | test_settings: {
21 | default: {
22 | selenium_port: 4444,
23 | selenium_host: 'localhost',
24 | silent: true,
25 | globals: {
26 | devServerURL: 'http://localhost:' + (process.env.PORT || config.dev.port)
27 | }
28 | },
29 |
30 | chrome: {
31 | desiredCapabilities: {
32 | browserName: 'chrome',
33 | javascriptEnabled: true,
34 | acceptSslCerts: true
35 | }
36 | },
37 |
38 | firefox: {
39 | desiredCapabilities: {
40 | browserName: 'firefox',
41 | javascriptEnabled: true,
42 | acceptSslCerts: true
43 | }
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/test/e2e/runner.js:
--------------------------------------------------------------------------------
1 | // 1. start the dev server using production config
2 | process.env.NODE_ENV = 'testing'
3 |
4 | const webpack = require('webpack')
5 | const DevServer = require('webpack-dev-server')
6 |
7 | const webpackConfig = require('../../build/webpack.prod.conf')
8 | const devConfigPromise = require('../../build/webpack.dev.conf')
9 |
10 | let server
11 |
12 | devConfigPromise.then(devConfig => {
13 | const devServerOptions = devConfig.devServer
14 | const compiler = webpack(webpackConfig)
15 | server = new DevServer(compiler, devServerOptions)
16 | const port = devServerOptions.port
17 | const host = devServerOptions.host
18 | return server.listen(port, host)
19 | })
20 | .then(() => {
21 | // 2. run the nightwatch test suite against it
22 | // to run in additional browsers:
23 | // 1. add an entry in test/e2e/nightwatch.conf.json under "test_settings"
24 | // 2. add it to the --env flag below
25 | // or override the environment flag, for example: `npm run e2e -- --env chrome,firefox`
26 | // For more information on Nightwatch's config file, see
27 | // http://nightwatchjs.org/guide#settings-file
28 | let opts = process.argv.slice(2)
29 | if (opts.indexOf('--config') === -1) {
30 | opts = opts.concat(['--config', 'test/e2e/nightwatch.conf.js'])
31 | }
32 | if (opts.indexOf('--env') === -1) {
33 | opts = opts.concat(['--env', 'chrome'])
34 | }
35 |
36 | const spawn = require('cross-spawn')
37 | const runner = spawn('./node_modules/.bin/nightwatch', opts, { stdio: 'inherit' })
38 |
39 | runner.on('exit', function (code) {
40 | server.close()
41 | process.exit(code)
42 | })
43 |
44 | runner.on('error', function (err) {
45 | server.close()
46 | throw err
47 | })
48 | })
49 |
--------------------------------------------------------------------------------
/test/e2e/specs/test.js:
--------------------------------------------------------------------------------
1 | // For authoring Nightwatch tests, see
2 | // http://nightwatchjs.org/guide#usage
3 |
4 | module.exports = {
5 | 'default e2e tests': function (browser) {
6 | // automatically uses dev Server port from /config.index.js
7 | // default: http://localhost:8080
8 | // see nightwatch.conf.js
9 | const devServer = browser.globals.devServerURL
10 |
11 | browser
12 | .url(devServer)
13 | .waitForElementVisible('#app', 5000)
14 | .assert.elementPresent('.hello')
15 | .assert.containsText('h1', 'Welcome to Your Vue.js App')
16 | .assert.elementCount('img', 1)
17 | .end()
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/test/unit/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "mocha": true
4 | },
5 | "globals": {
6 | "expect": true,
7 | "sinon": true
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/test/unit/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | Vue.config.productionTip = false
4 |
5 | // require all test files (files that ends with .spec.js)
6 | const testsContext = require.context('./specs', true, /\.spec$/)
7 | testsContext.keys().forEach(testsContext)
8 |
9 | // require all src files except main.js for coverage.
10 | // you can also change this to match only the subset of files that
11 | // you want coverage for.
12 | const srcContext = require.context('../../src', true, /^\.\/(?!main(\.js)?$)/)
13 | srcContext.keys().forEach(srcContext)
14 |
--------------------------------------------------------------------------------
/test/unit/karma.conf.js:
--------------------------------------------------------------------------------
1 | // This is a karma config file. For more details see
2 | // http://karma-runner.github.io/0.13/config/configuration-file.html
3 | // we are also using it with karma-webpack
4 | // https://github.com/webpack/karma-webpack
5 |
6 | var webpackConfig = require('../../build/webpack.test.conf')
7 |
8 | module.exports = function (config) {
9 | config.set({
10 | // to run in additional browsers:
11 | // 1. install corresponding karma launcher
12 | // http://karma-runner.github.io/0.13/config/browsers.html
13 | // 2. add it to the `browsers` array below.
14 | browsers: ['PhantomJS'],
15 | frameworks: ['mocha', 'sinon-chai', 'phantomjs-shim'],
16 | reporters: ['spec', 'coverage'],
17 | files: ['./index.js'],
18 | preprocessors: {
19 | './index.js': ['webpack', 'sourcemap']
20 | },
21 | webpack: webpackConfig,
22 | webpackMiddleware: {
23 | noInfo: true
24 | },
25 | coverageReporter: {
26 | dir: './coverage',
27 | reporters: [
28 | { type: 'lcov', subdir: '.' },
29 | { type: 'text-summary' }
30 | ]
31 | }
32 | })
33 | }
34 |
--------------------------------------------------------------------------------
/test/unit/specs/HelloWorld.spec.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import HelloWorld from '@/components/HelloWorld'
3 |
4 | describe('HelloWorld.vue', () => {
5 | it('should render correct contents', () => {
6 | const Constructor = Vue.extend(HelloWorld)
7 | const vm = new Constructor().$mount()
8 | expect(vm.$el.querySelector('.hello h1').textContent)
9 | .to.equal('Welcome to Your Vue.js App')
10 | })
11 | })
12 |
--------------------------------------------------------------------------------