From d77f0f83595b0aed12ce6879fe573949e6abe1b2 Mon Sep 17 00:00:00 2001 From: ctengiz Date: Wed, 10 Apr 2024 13:43:00 +0300 Subject: [PATCH] base ui --- ui/.editorconfig | 9 + ui/.eslintignore | 7 + ui/.eslintrc.cjs | 69 +++++++ ui/.gitignore | 33 ++++ ui/.npmrc | 5 + ui/.vscode/extensions.json | 15 ++ ui/.vscode/settings.json | 15 ++ ui/README.md | 41 +++++ ui/index.html | 21 +++ ui/jsconfig.json | 39 ++++ ui/package.json | 39 ++++ ui/postcss.config.cjs | 27 +++ ui/public/bres.png | Bin 0 -> 15528 bytes ui/public/favicon.ico | Bin 0 -> 25124 bytes ui/public/icons/favicon-128x128.png | Bin 0 -> 2505 bytes ui/public/icons/favicon-16x16.png | Bin 0 -> 433 bytes ui/public/icons/favicon-32x32.png | Bin 0 -> 734 bytes ui/public/icons/favicon-96x96.png | Bin 0 -> 1933 bytes ui/public/notitek.png | Bin 0 -> 20092 bytes ui/quasar.config.js | 240 +++++++++++++++++++++++++ ui/src/App.vue | 9 + ui/src/assets/quasar-logo-vertical.svg | 15 ++ ui/src/boot/.gitkeep | 0 ui/src/boot/axios.js | 24 +++ ui/src/boot/pinia.js | 4 + ui/src/boot/version.js | 5 + ui/src/components/EssentialLink.vue | 48 +++++ ui/src/css/app.scss | 12 ++ ui/src/css/panel.scss | 44 +++++ ui/src/css/quasar.variables.scss | 25 +++ ui/src/layouts/MainLayout.vue | 106 +++++++++++ ui/src/layouts/landingLayout.vue | 46 +++++ ui/src/layouts/panelLayout.vue | 64 +++++++ ui/src/pages/ErrorNotFound.vue | 29 +++ ui/src/pages/IndexPage.vue | 15 ++ ui/src/pages/login.vue | 54 ++++++ ui/src/router/index.js | 66 +++++++ ui/src/router/routes.js | 33 ++++ ui/src/stores/index.js | 20 +++ ui/src/stores/login.js | 79 ++++++++ ui/src/stores/store-flag.d.ts | 10 ++ 41 files changed, 1268 insertions(+) create mode 100644 ui/.editorconfig create mode 100644 ui/.eslintignore create mode 100644 ui/.eslintrc.cjs create mode 100644 ui/.gitignore create mode 100644 ui/.npmrc create mode 100644 ui/.vscode/extensions.json create mode 100644 ui/.vscode/settings.json create mode 100644 ui/README.md create mode 100644 ui/index.html create mode 100644 ui/jsconfig.json create mode 100644 ui/package.json create mode 100644 ui/postcss.config.cjs create mode 100644 ui/public/bres.png create mode 100644 ui/public/favicon.ico create mode 100644 ui/public/icons/favicon-128x128.png create mode 100644 ui/public/icons/favicon-16x16.png create mode 100644 ui/public/icons/favicon-32x32.png create mode 100644 ui/public/icons/favicon-96x96.png create mode 100644 ui/public/notitek.png create mode 100644 ui/quasar.config.js create mode 100644 ui/src/App.vue create mode 100644 ui/src/assets/quasar-logo-vertical.svg create mode 100644 ui/src/boot/.gitkeep create mode 100644 ui/src/boot/axios.js create mode 100644 ui/src/boot/pinia.js create mode 100644 ui/src/boot/version.js create mode 100644 ui/src/components/EssentialLink.vue create mode 100644 ui/src/css/app.scss create mode 100644 ui/src/css/panel.scss create mode 100644 ui/src/css/quasar.variables.scss create mode 100644 ui/src/layouts/MainLayout.vue create mode 100644 ui/src/layouts/landingLayout.vue create mode 100644 ui/src/layouts/panelLayout.vue create mode 100644 ui/src/pages/ErrorNotFound.vue create mode 100644 ui/src/pages/IndexPage.vue create mode 100644 ui/src/pages/login.vue create mode 100644 ui/src/router/index.js create mode 100644 ui/src/router/routes.js create mode 100644 ui/src/stores/index.js create mode 100644 ui/src/stores/login.js create mode 100644 ui/src/stores/store-flag.d.ts diff --git a/ui/.editorconfig b/ui/.editorconfig new file mode 100644 index 0000000..9d08a1a --- /dev/null +++ b/ui/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/ui/.eslintignore b/ui/.eslintignore new file mode 100644 index 0000000..9f81cf8 --- /dev/null +++ b/ui/.eslintignore @@ -0,0 +1,7 @@ +/dist +/src-capacitor +/src-cordova +/.quasar +/node_modules +.eslintrc.cjs +/quasar.config.*.temporary.compiled* diff --git a/ui/.eslintrc.cjs b/ui/.eslintrc.cjs new file mode 100644 index 0000000..b3d242c --- /dev/null +++ b/ui/.eslintrc.cjs @@ -0,0 +1,69 @@ +module.exports = { + // https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy + // This option interrupts the configuration hierarchy at this file + // Remove this if you have an higher level ESLint config file (it usually happens into a monorepos) + root: true, + + parserOptions: { + ecmaVersion: 2022, // Allows for the parsing of modern ECMAScript features + }, + + env: { + node: true, + browser: true + }, + + // Rules order is important, please avoid shuffling them + extends: [ + // Base ESLint recommended rules + // 'eslint:recommended', + + // Uncomment any of the lines below to choose desired strictness, + // but leave only one uncommented! + // See https://eslint.vuejs.org/rules/#available-rules + 'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention) + // 'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability) + // 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead) + + // https://github.com/prettier/eslint-config-prettier#installation + // usage with Prettier, provided by 'eslint-config-prettier'. + 'prettier' + ], + + plugins: [ + // https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-files + // required to lint *.vue files + 'vue', + + // https://github.com/typescript-eslint/typescript-eslint/issues/389#issuecomment-509292674 + // Prettier has not been included as plugin to avoid performance impact + // add it as an extension for your IDE + + ], + + globals: { + ga: 'readonly', // Google Analytics + cordova: 'readonly', + __statics: 'readonly', + __QUASAR_SSR__: 'readonly', + __QUASAR_SSR_SERVER__: 'readonly', + __QUASAR_SSR_CLIENT__: 'readonly', + __QUASAR_SSR_PWA__: 'readonly', + process: 'readonly', + Capacitor: 'readonly', + chrome: 'readonly' + }, + + // add your custom rules here + rules: { + + 'prefer-promise-reject-errors': 'off', + + // allow debugger during development only + 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', + + // + 'vue/multi-word-component-names': 'off', + 'vue/no-dupe-keys': 'off' + } +} diff --git a/ui/.gitignore b/ui/.gitignore new file mode 100644 index 0000000..f1d913c --- /dev/null +++ b/ui/.gitignore @@ -0,0 +1,33 @@ +.DS_Store +.thumbs.db +node_modules + +# Quasar core related directories +.quasar +/dist +/quasar.config.*.temporary.compiled* + +# Cordova related directories and files +/src-cordova/node_modules +/src-cordova/platforms +/src-cordova/plugins +/src-cordova/www + +# Capacitor related directories and files +/src-capacitor/www +/src-capacitor/node_modules + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +*.suo +*.ntvs* +*.njsproj +*.sln + +# local .env files +.env.local* diff --git a/ui/.npmrc b/ui/.npmrc new file mode 100644 index 0000000..eb19082 --- /dev/null +++ b/ui/.npmrc @@ -0,0 +1,5 @@ +# pnpm-related options +shamefully-hoist=true +strict-peer-dependencies=false +# to get the latest compatible packages when creating the project https://github.com/pnpm/pnpm/issues/6463 +resolution-mode=highest diff --git a/ui/.vscode/extensions.json b/ui/.vscode/extensions.json new file mode 100644 index 0000000..fe38802 --- /dev/null +++ b/ui/.vscode/extensions.json @@ -0,0 +1,15 @@ +{ + "recommendations": [ + "dbaeumer.vscode-eslint", + "esbenp.prettier-vscode", + "editorconfig.editorconfig", + "vue.volar", + "wayou.vscode-todo-highlight" + ], + "unwantedRecommendations": [ + "octref.vetur", + "hookyqr.beautify", + "dbaeumer.jshint", + "ms-vscode.vscode-typescript-tslint-plugin" + ] +} \ No newline at end of file diff --git a/ui/.vscode/settings.json b/ui/.vscode/settings.json new file mode 100644 index 0000000..b3bb1e4 --- /dev/null +++ b/ui/.vscode/settings.json @@ -0,0 +1,15 @@ +{ + "editor.bracketPairColorization.enabled": true, + "editor.guides.bracketPairs": true, + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.codeActionsOnSave": [ + "source.fixAll.eslint" + ], + "eslint.validate": [ + "javascript", + "javascriptreact", + "typescript", + "vue" + ] +} \ No newline at end of file diff --git a/ui/README.md b/ui/README.md new file mode 100644 index 0000000..f39cece --- /dev/null +++ b/ui/README.md @@ -0,0 +1,41 @@ +# Bordro Eşleme (tr.com.notitek.bordro-esleme) + +Bordro Eşleme + +## Install the dependencies +```bash +yarn +# or +npm install +``` + +### Start the app in development mode (hot-code reloading, error reporting, etc.) +```bash +quasar dev +``` + + +### Lint the files +```bash +yarn lint +# or +npm run lint +``` + + +### Format the files +```bash +yarn format +# or +npm run format +``` + + + +### Build the app for production +```bash +quasar build +``` + +### Customize the configuration +See [Configuring quasar.config.js](https://v2.quasar.dev/quasar-cli-vite/quasar-config-js). diff --git a/ui/index.html b/ui/index.html new file mode 100644 index 0000000..3c8c78f --- /dev/null +++ b/ui/index.html @@ -0,0 +1,21 @@ + + + + <%= productName %> + + + + + + + + + + + + + + + + + diff --git a/ui/jsconfig.json b/ui/jsconfig.json new file mode 100644 index 0000000..456944a --- /dev/null +++ b/ui/jsconfig.json @@ -0,0 +1,39 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "src/*": [ + "src/*" + ], + "app/*": [ + "*" + ], + "components/*": [ + "src/components/*" + ], + "layouts/*": [ + "src/layouts/*" + ], + "pages/*": [ + "src/pages/*" + ], + "assets/*": [ + "src/assets/*" + ], + "boot/*": [ + "src/boot/*" + ], + "stores/*": [ + "src/stores/*" + ], + "vue$": [ + "node_modules/vue/dist/vue.runtime.esm-bundler.js" + ] + } + }, + "exclude": [ + "dist", + ".quasar", + "node_modules" + ] +} \ No newline at end of file diff --git a/ui/package.json b/ui/package.json new file mode 100644 index 0000000..f3b1094 --- /dev/null +++ b/ui/package.json @@ -0,0 +1,39 @@ +{ + "name": "tr.com.notitek.bordro-esleme", + "version": "0.0.1", + "description": "Bordro Eşleme", + "productName": "Bordro Eşleme", + "author": "dev@notitek.com.tr", + "private": true, + "scripts": { + "lint": "eslint --ext .js,.vue ./", + "format": "prettier --write \"**/*.{js,vue,scss,html,md,json}\" --ignore-path .gitignore", + "test": "echo \"No test specified\" && exit 0", + "dev": "quasar dev", + "build": "quasar build" + }, + "dependencies": { + "@quasar/extras": "^1.16.4", + "axios": "^1.2.1", + "jwt-decode": "^4.0.0", + "pinia": "^2.0.11", + "quasar": "^2.8.0", + "vue": "^3.4.18", + "vue-router": "^4.0.12" + }, + "devDependencies": { + "@quasar/app-vite": "^1.8.0", + "autoprefixer": "^10.4.2", + "eslint": "^8.11.0", + "eslint-config-prettier": "^8.1.0", + "eslint-plugin-vue": "^9.0.0", + "postcss": "^8.4.14", + "prettier": "^2.5.1", + "vite-plugin-checker": "^0.6.4" + }, + "engines": { + "node": "^20 || ^18 || ^16", + "npm": ">= 6.13.4", + "yarn": ">= 1.21.1" + } +} diff --git a/ui/postcss.config.cjs b/ui/postcss.config.cjs new file mode 100644 index 0000000..94b7b1c --- /dev/null +++ b/ui/postcss.config.cjs @@ -0,0 +1,27 @@ +/* eslint-disable */ +// https://github.com/michael-ciniawsky/postcss-load-config + +module.exports = { + plugins: [ + // https://github.com/postcss/autoprefixer + require('autoprefixer')({ + overrideBrowserslist: [ + 'last 4 Chrome versions', + 'last 4 Firefox versions', + 'last 4 Edge versions', + 'last 4 Safari versions', + 'last 4 Android versions', + 'last 4 ChromeAndroid versions', + 'last 4 FirefoxAndroid versions', + 'last 4 iOS versions' + ] + }) + + // https://github.com/elchininet/postcss-rtlcss + // If you want to support RTL css, then + // 1. yarn/npm install postcss-rtlcss + // 2. optionally set quasar.config.js > framework > lang to an RTL language + // 3. uncomment the following line: + // require('postcss-rtlcss') + ] +} diff --git a/ui/public/bres.png b/ui/public/bres.png new file mode 100644 index 0000000000000000000000000000000000000000..d19883962628d7fcbe736c6255977d494fb2a1bc GIT binary patch literal 15528 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 literal 0 HcmV?d00001 diff --git a/ui/public/favicon.ico b/ui/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..324249b816c09771e48d2eeed8d26ea0f28de84a GIT binary patch literal 25124 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 TR(R#~00000NkvXXu0mjf^}l?9 literal 0 HcmV?d00001 diff --git a/ui/public/icons/favicon-16x16.png b/ui/public/icons/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..287e7fe9b3abe4d214778c4f822d6ccdaa2113f0 GIT binary patch literal 433 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstUx|vage(c z!@6@aFM*uW0G|+7_W~av6B#&3iU7Ih!oqOD)80TcK!6ECF)$qWb~x_k0ONt^m5wGS zy&cc_I9~B{Ll!^aX7@TAWCbH5Bapn{=X@=|%}=}{3&>F^3GxeO`2Oj}`Io$ZSSLuC z{CwY9U|ZQSFGS5?w(O4EM!S}6%q@1ld+6@=>)k;0t2|vCLnJPn`m+liR^SolO_=Nu z7VcI)_uv0cQ_t1b^2ahH82-w=m{fgTea(&fY3x#pg2BadU%Y$HuiDV(v2IUb(wxRk zHz!_UXg;p$*Sv3wn@{VzT8U-nUmWc5Q#lZ%^}O!0{$!C0pCV@*4C5*L^yt3q3Ffu; zowN$IIB#|sw-%nSO?BauUg&EXrs?wV#0Os`Rfd0y{(J1&CAa!lvI6;x#X;^) z4C~IxyaaMe1AIbU-3xqx%oAP?K+-`{1V{pbp|CK70VJ8=EDXj;Z=l%>aPowg;{gwQ zpvY-&hoheMK=G44j%R#8Y8V+onooE;UJrD;=;tzPomv2puUr!37tA2?=Q;b4&rE-R zUs1MNQ*~RnZ~KBDQ#YpOHOmE^u$~qEz%P=^iR~xQj2oUVjv*GOQz!RMTV%k~8tgH9 zTD{AZ!1OtDo8JHLn7u^jP|o?lzO&DLi-Z{(IF@k>2~63l%N1=d`bqU**^9?pYdEjB z&hWb}Q6XFrx#^ARMy73c74j^n*XKXlm{L4#?);j9fHZq27*uSV+L3|<8!+M8ck(YvAi|!Z3biau_p?)|UU+klolEKjb@!ZK*8?Iico*TVYeFu~F(v1@tmU<_zykzu(P4HUg zow)~k-zAh>H*u?Uw3;opj4_gbi`Rx&dpFTt_cHH9`|wTQsb_rOvU=5Pr8VBSrJ~9= zMRCr*r(IiAQ`}!HW@Oa)vTRAqv$uNu^&%G+2>mKJd(bLv^}(ZWpVV?5e|cj4C#xHG hcHZeL|6KR?KT})3!St2$g(ra0h^MQc%Q~loCIG4cA{GDu literal 0 HcmV?d00001 diff --git a/ui/public/icons/favicon-96x96.png b/ui/public/icons/favicon-96x96.png new file mode 100644 index 0000000000000000000000000000000000000000..9e8cfcadba6698f464178d7f29b0951ebb533266 GIT binary patch literal 1933 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 literal 0 HcmV?d00001 diff --git a/ui/quasar.config.js b/ui/quasar.config.js new file mode 100644 index 0000000..8a11ef6 --- /dev/null +++ b/ui/quasar.config.js @@ -0,0 +1,240 @@ +/* eslint-env node */ + +/* + * This file runs in a Node context (it's NOT transpiled by Babel), so use only + * the ES6 features that are supported by your Node version. https://node.green/ + */ + +// Configuration for your app +// https://v2.quasar.dev/quasar-cli-vite/quasar-config-js + + +const { configure } = require('quasar/wrappers'); + + +module.exports = configure(function (ctx) { + return { + // https://v2.quasar.dev/quasar-cli-vite/prefetch-feature + // preFetch: true, + + // app boot file (/src/boot) + // --> boot files are part of "main.js" + // https://v2.quasar.dev/quasar-cli-vite/boot-files + boot: [ + 'axios', + 'version', + 'pinia', + ], + + // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#css + css: [ + 'app.scss' + ], + + // https://github.com/quasarframework/quasar/tree/dev/extras + extras: [ + // 'ionicons-v4', + 'mdi-v7', + // 'fontawesome-v6', + // 'eva-icons', + // 'themify', + // 'line-awesome', + 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both! + + //'roboto-font', // optional, you are not bound to it + 'material-icons', // optional, you are not bound to it + ], + + // Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#build + build: { + target: { + browser: [ 'es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1' ], + node: 'node20' + }, + + vueRouterMode: 'history', // available values: 'hash', 'history' + // vueRouterBase, + // vueDevtools, + // vueOptionsAPI: false, + + // rebuildCache: true, // rebuilds Vite/linter/etc cache on startup + + // publicPath: '/', + // analyze: true, + env: { + apiAddr: (() => { + if (process.env.CUSTOM_API) { + return process.env.CUSTOM_API + } else { + if (ctx.dev) { + return 'http://localhost:41000/api' + } else { + return '/api' + } + } + })(), + wsAddr: (() => { + if (process.env.CUSTOM_WS) { + return process.env.CUSTOM_WS + } else { + if (ctx.dev) { + return 'ws://127.0.0.1:41000/ws' + } else { + return 'wss://bres.notitek.com.tr/ws' + } + } + })(), + }, + // rawDefine: {} + // ignorePublicFolder: true, + // minify: false, + // polyfillModulePreload: true, + // distDir + + extendViteConf (viteConf) { + viteConf.resolve.preserveSymlinks = true + }, + + // viteVuePluginOptions: {}, + + vitePlugins: [ + ['vite-plugin-checker', { + eslint: { + lintCommand: 'eslint "./**/*.{js,mjs,cjs,vue}"' + } + }, { server: false }] + ] + }, + + // Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#devServer + devServer: { + // https: true + port:9400, + open: true // opens browser window automatically + }, + + // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#framework + framework: { + config: {}, + + // iconSet: 'material-icons', // Quasar icon set + // lang: 'en-US', // Quasar language pack + + // For special cases outside of where the auto-import strategy can have an impact + // (like functional components as one of the examples), + // you can manually specify Quasar components/directives to be available everywhere: + // + // components: [], + // directives: [], + + // Quasar plugins + plugins: [ + 'Notify', + 'Loading', + 'Dialog', + 'Meta' + ] + }, + + // animations: 'all', // --- includes all animations + // https://v2.quasar.dev/options/animations + animations: [], + + // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#property-sourcefiles + // sourceFiles: { + // rootComponent: 'src/App.vue', + // router: 'src/router/index', + // store: 'src/store/index', + // registerServiceWorker: 'src-pwa/register-service-worker', + // serviceWorker: 'src-pwa/custom-service-worker', + // pwaManifestFile: 'src-pwa/manifest.json', + // electronMain: 'src-electron/electron-main', + // electronPreload: 'src-electron/electron-preload' + // }, + + // https://v2.quasar.dev/quasar-cli-vite/developing-ssr/configuring-ssr + ssr: { + // ssrPwaHtmlFilename: 'offline.html', // do NOT use index.html as name! + // will mess up SSR + + // extendSSRWebserverConf (esbuildConf) {}, + // extendPackageJson (json) {}, + + pwa: false, + + // manualStoreHydration: true, + // manualPostHydrationTrigger: true, + + prodPort: 3000, // The default port that the production server should use + // (gets superseded if process.env.PORT is specified at runtime) + + middlewares: [ + 'render' // keep this as last one + ] + }, + + // https://v2.quasar.dev/quasar-cli-vite/developing-pwa/configuring-pwa + pwa: { + workboxMode: 'generateSW', // or 'injectManifest' + injectPwaMetaTags: true, + swFilename: 'sw.js', + manifestFilename: 'manifest.json', + useCredentialsForManifestTag: false, + // useFilenameHashes: true, + // extendGenerateSWOptions (cfg) {} + // extendInjectManifestOptions (cfg) {}, + // extendManifestJson (json) {} + // extendPWACustomSWConf (esbuildConf) {} + }, + + // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-cordova-apps/configuring-cordova + cordova: { + // noIosLegacyBuildFlag: true, // uncomment only if you know what you are doing + }, + + // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-capacitor-apps/configuring-capacitor + capacitor: { + hideSplashscreen: true + }, + + // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-electron-apps/configuring-electron + electron: { + // extendElectronMainConf (esbuildConf) + // extendElectronPreloadConf (esbuildConf) + + // specify the debugging port to use for the Electron app when running in development mode + inspectPort: 5858, + + bundler: 'packager', // 'packager' or 'builder' + + packager: { + // https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options + + // OS X / Mac App Store + // appBundleId: '', + // appCategoryType: '', + // osxSign: '', + // protocol: 'myapp://path', + + // Windows only + // win32metadata: { ... } + }, + + builder: { + // https://www.electron.build/configuration/configuration + + appId: 'tr.com.notitek.bres' + } + }, + + // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-browser-extensions/configuring-bex + bex: { + contentScripts: [ + 'my-content-script' + ], + + // extendBexScriptsConf (esbuildConf) {} + // extendBexManifestJson (json) {} + } + } +}); diff --git a/ui/src/App.vue b/ui/src/App.vue new file mode 100644 index 0000000..79d5cce --- /dev/null +++ b/ui/src/App.vue @@ -0,0 +1,9 @@ + + + diff --git a/ui/src/assets/quasar-logo-vertical.svg b/ui/src/assets/quasar-logo-vertical.svg new file mode 100644 index 0000000..8210831 --- /dev/null +++ b/ui/src/assets/quasar-logo-vertical.svg @@ -0,0 +1,15 @@ + + + + + + + + + \ No newline at end of file diff --git a/ui/src/boot/.gitkeep b/ui/src/boot/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/ui/src/boot/axios.js b/ui/src/boot/axios.js new file mode 100644 index 0000000..9dbc942 --- /dev/null +++ b/ui/src/boot/axios.js @@ -0,0 +1,24 @@ +import { boot } from 'quasar/wrappers' +import axios from 'axios' + +// Be careful when using SSR for cross-request state pollution +// due to creating a Singleton instance here; +// If any client changes this (global) instance, it might be a +// good idea to move this instance creation inside of the +// "export default () => {}" function below (which runs individually +// for each client) +const api = axios.create({ baseURL: 'https://api.example.com' }) + +export default boot(({ app }) => { + // for use inside Vue files (Options API) through this.$axios and this.$api + + app.config.globalProperties.$axios = axios + // ^ ^ ^ this will allow you to use this.$axios (for Vue Options API form) + // so you won't necessarily have to import axios in each vue file + + app.config.globalProperties.$api = api + // ^ ^ ^ this will allow you to use this.$api (for Vue Options API form) + // so you can easily perform requests against your app's API +}) + +export { api } diff --git a/ui/src/boot/pinia.js b/ui/src/boot/pinia.js new file mode 100644 index 0000000..0f05547 --- /dev/null +++ b/ui/src/boot/pinia.js @@ -0,0 +1,4 @@ +import { useLoginStore } from 'stores/login' + +const store = useLoginStore() +store.load() diff --git a/ui/src/boot/version.js b/ui/src/boot/version.js new file mode 100644 index 0000000..247117a --- /dev/null +++ b/ui/src/boot/version.js @@ -0,0 +1,5 @@ +import vdata from '../../version' + +const $VERSION = vdata +export { $VERSION } + diff --git a/ui/src/components/EssentialLink.vue b/ui/src/components/EssentialLink.vue new file mode 100644 index 0000000..3a29f8f --- /dev/null +++ b/ui/src/components/EssentialLink.vue @@ -0,0 +1,48 @@ + + + diff --git a/ui/src/css/app.scss b/ui/src/css/app.scss new file mode 100644 index 0000000..3038c18 --- /dev/null +++ b/ui/src/css/app.scss @@ -0,0 +1,12 @@ +// app global css in SCSS form +@import "panel"; + +@import url('https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,200;0,300;0,400;0,500;0,600;0,700;1,200;1,300;1,400;1,500;1,600;1,700&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=Merriweather:ital,wght@0,300;0,400;0,700;0,900;1,300;1,400;1,700;1,900&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,300;0,400;0,700;0,900;1,300;1,400;1,700;1,900&display=swap'); + +body { + font-family: 'Nunito', sans-serif; + font-size: 16px; + color: #334155; +} diff --git a/ui/src/css/panel.scss b/ui/src/css/panel.scss new file mode 100644 index 0000000..01a8491 --- /dev/null +++ b/ui/src/css/panel.scss @@ -0,0 +1,44 @@ +:root { + --pcolor1: #c84b41; + --pcolor2: #020f40; + --pcolor3: #64748b; +} + +.text-pcolor1 { + color: var(--pcolor1) !important; +} + +.bg-pcolor1 { + background-color: var(--pcolor1) !important; +} + +.text-pcolor2 { + color: var(--pcolor2) !important; +} + +.bg-pcolor2 { + background-color: var(--pcolor2) !important; +} + +.text-pcolor3 { + color: var(--pcolor3) !important; +} + +.bg-pcolor3 { + background-color: var(--pcolor3) !important; +} + + +.border-bottom { + border-bottom: #cccccc 1px solid; +} + + +a.pcolor1link { + color: var(--pcolor1); + text-decoration: none; + &:hover { + color: var(--pcolor1); + text-decoration: underline; + } +} diff --git a/ui/src/css/quasar.variables.scss b/ui/src/css/quasar.variables.scss new file mode 100644 index 0000000..3996ce1 --- /dev/null +++ b/ui/src/css/quasar.variables.scss @@ -0,0 +1,25 @@ +// Quasar SCSS (& Sass) Variables +// -------------------------------------------------- +// To customize the look and feel of this app, you can override +// the Sass/SCSS variables found in Quasar's source Sass/SCSS files. + +// Check documentation for full list of Quasar variables + +// Your own variables (that are declared here) and Quasar's own +// ones will be available out of the box in your .vue/.scss/.sass files + +// It's highly recommended to change the default colors +// to match your app's branding. +// Tip: Use the "Theme Builder" on Quasar's documentation website. + +$primary : #1976D2; +$secondary : #26A69A; +$accent : #9C27B0; + +$dark : #1D1D1D; +$dark-page : #121212; + +$positive : #21BA45; +$negative : #C10015; +$info : #31CCEC; +$warning : #F2C037; diff --git a/ui/src/layouts/MainLayout.vue b/ui/src/layouts/MainLayout.vue new file mode 100644 index 0000000..e4a792e --- /dev/null +++ b/ui/src/layouts/MainLayout.vue @@ -0,0 +1,106 @@ + + + diff --git a/ui/src/layouts/landingLayout.vue b/ui/src/layouts/landingLayout.vue new file mode 100644 index 0000000..7f9dd8b --- /dev/null +++ b/ui/src/layouts/landingLayout.vue @@ -0,0 +1,46 @@ + + + diff --git a/ui/src/layouts/panelLayout.vue b/ui/src/layouts/panelLayout.vue new file mode 100644 index 0000000..eba898c --- /dev/null +++ b/ui/src/layouts/panelLayout.vue @@ -0,0 +1,64 @@ + + + + diff --git a/ui/src/pages/ErrorNotFound.vue b/ui/src/pages/ErrorNotFound.vue new file mode 100644 index 0000000..23041c4 --- /dev/null +++ b/ui/src/pages/ErrorNotFound.vue @@ -0,0 +1,29 @@ + + + diff --git a/ui/src/pages/IndexPage.vue b/ui/src/pages/IndexPage.vue new file mode 100644 index 0000000..a595c2d --- /dev/null +++ b/ui/src/pages/IndexPage.vue @@ -0,0 +1,15 @@ + + + diff --git a/ui/src/pages/login.vue b/ui/src/pages/login.vue new file mode 100644 index 0000000..7f314a0 --- /dev/null +++ b/ui/src/pages/login.vue @@ -0,0 +1,54 @@ + + + diff --git a/ui/src/router/index.js b/ui/src/router/index.js new file mode 100644 index 0000000..e28c96f --- /dev/null +++ b/ui/src/router/index.js @@ -0,0 +1,66 @@ +import { + createMemoryHistory, + createRouter, + createWebHashHistory, + createWebHistory, +} from 'vue-router' +import routes from './routes' +import useLoginStore from 'stores/login' + +/* + * If not building with SSR mode, you can + * directly export the Router instantiation; + * + * The function below can be async too; either use + * async/await or return a Promise which resolves + * with the Router instance. + */ + +const createHistory = process.env.SERVER + ? createMemoryHistory + : (process.env.VUE_ROUTER_MODE === 'history' + ? createWebHistory + : createWebHashHistory) + +const Router = createRouter({ + scrollBehavior: () => ({ left: 0, top: 0 }), + routes, + + // Leave this as is and make changes in quasar.conf.js instead! + // quasar.conf.js -> build -> vueRouterMode + // quasar.conf.js -> build -> publicPath + history: createHistory(process.env.VUE_ROUTER_BASE), +}) + +Router.beforeEach( + (to, from) => { + const loginStore = useLoginStore() + + const isLoggedIn = loginStore.IsLoggedIn() + + // instead of having to check every route record with + // to.matched.some(record => record.meta.requiresAuth) + + if (to.meta.requiresAuth && !isLoggedIn && + ((to.path !== '/') || (to.path !== 'login'))) { + // this route requires auth, check if logged in + // if not, redirect to login page. + + return { + path: '/login', + // save the location we were at to come back later + //query: { redirect: to.fullPath }, + } + } + + if ((isLoggedIn) && ((to.path === '/') || (to.path === 'login'))) { + return { + path: '/panel', + query: '', + } + } + }, +) + +export default Router + diff --git a/ui/src/router/routes.js b/ui/src/router/routes.js new file mode 100644 index 0000000..695c004 --- /dev/null +++ b/ui/src/router/routes.js @@ -0,0 +1,33 @@ + +const routes = [ + { + path: '/', + component: () => import('layouts/panelLayout.vue'), + meta: { + requiresAuth: true + }, + children: [ + { path: '', component: () => import('pages/IndexPage.vue') }, + ] + }, + + { + path: '/login', + component: () => import('layouts/landingLayout.vue'), + children: [ + { path: '', component: () => import('pages/login.vue') } + ], + meta: { + requiresAuth: false + }, + }, + + // Always leave this as last one, + // but you can also remove it + { + path: '/:catchAll(.*)*', + component: () => import('pages/ErrorNotFound.vue') + } +] + +export default routes diff --git a/ui/src/stores/index.js b/ui/src/stores/index.js new file mode 100644 index 0000000..ca5bee5 --- /dev/null +++ b/ui/src/stores/index.js @@ -0,0 +1,20 @@ +import { store } from 'quasar/wrappers' +import { createPinia } from 'pinia' + +/* + * If not building with SSR mode, you can + * directly export the Store instantiation; + * + * The function below can be async too; either use + * async/await or return a Promise which resolves + * with the Store instance. + */ + +export default store((/* { ssrContext } */) => { + const pinia = createPinia() + + // You can add Pinia plugins here + // pinia.use(SomePiniaPlugin) + + return pinia +}) diff --git a/ui/src/stores/login.js b/ui/src/stores/login.js new file mode 100644 index 0000000..69f7954 --- /dev/null +++ b/ui/src/stores/login.js @@ -0,0 +1,79 @@ +import { defineStore } from 'pinia' +import { LocalStorage } from 'quasar' +import { api } from 'boot/axios' +import { jwtDecode } from "jwt-decode" +import Router from 'src/router/index' + +export const sessionName = 'bresSession' + +const defaultState = { + LoggedIn: false, + Token: '', + UsrKSUID: '', + ClientKSUID: '', + Email: '', + Fullname: '', +} + +export const useLoginStore = defineStore('login', { + state: () => { + return JSON.parse(JSON.stringify(defaultState)) + }, + getters: {}, + actions: { + + login (payload) { + // kaldıysa önceki session'ı uçuralım + LocalStorage.remove(sessionName) + const ds = JSON.parse(JSON.stringify(defaultState)) + Object.assign(this, ds) + + payload['LoggedIn'] = true + const pl = JSON.parse(JSON.stringify(payload)) + Object.assign(this, pl) + api.defaults.headers.common['Authorization'] = `Bearer ${payload.Token}` + LocalStorage.set(sessionName, payload) + }, + + logout () { + // todo: burada güvenlik zafiyeti var ! backend'de token invalidate edilmeli + // bunun için memlist'e ek bir claim tutulabilir + // ve jwtAuth verify koduna yazılıabilinir. + // örnek : https://dev.to/stevensunflash/a-working-solution-to-jwt-creation-and-invalidation-in-golang-4oe4 + const ds = JSON.parse(JSON.stringify(defaultState)) + Object.assign(this, ds) + + api.defaults.headers.common['Authorization'] = '' + LocalStorage.remove(sessionName) + + if (Router) { + Router.push('/login') + //router.push({ path: '/login', replace: true }) + } + }, + + updateState (payload) { + Object.assign(this, payload) + api.defaults.headers.common['Authorization'] = `Bearer ${payload.Token}` + }, + + load() { + const authInfo = LocalStorage.getItem(sessionName) + if (authInfo) { + const decoded = jwtDecode(authInfo.Token) + const now = Date.now() / 1000 + if (decoded.exp < now) { + this.logout() + } else { + this.updateState(authInfo) + } + } + }, + + IsLoggedIn () { + return this.LoggedIn + } + } +}) + +export default useLoginStore diff --git a/ui/src/stores/store-flag.d.ts b/ui/src/stores/store-flag.d.ts new file mode 100644 index 0000000..7677175 --- /dev/null +++ b/ui/src/stores/store-flag.d.ts @@ -0,0 +1,10 @@ +/* eslint-disable */ +// THIS FEATURE-FLAG FILE IS AUTOGENERATED, +// REMOVAL OR CHANGES WILL CAUSE RELATED TYPES TO STOP WORKING +import "quasar/dist/types/feature-flag"; + +declare module "quasar/dist/types/feature-flag" { + interface QuasarFeatureFlags { + store: true; + } +}