docs: configurando deploy via ssh para angular
This commit is contained in:
16
.editorconfig
Normal file
16
.editorconfig
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# Editor configuration, see https://editorconfig.org
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.ts]
|
||||||
|
quote_type = single
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
max_line_length = off
|
||||||
|
trim_trailing_whitespace = false
|
||||||
49
.gitignore
vendored
Normal file
49
.gitignore
vendored
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# compiled output
|
||||||
|
/dist
|
||||||
|
/tmp
|
||||||
|
/out-tsc
|
||||||
|
# Only exists if Bazel was run
|
||||||
|
/bazel-out
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
|
||||||
|
# profiling files
|
||||||
|
chrome-profiler-events*.json
|
||||||
|
speed-measure-plugin*.json
|
||||||
|
|
||||||
|
# IDEs and editors
|
||||||
|
/.idea
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
.c9/
|
||||||
|
*.launch
|
||||||
|
.settings/
|
||||||
|
*.sublime-workspace
|
||||||
|
|
||||||
|
# IDE - VSCode
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.history/*
|
||||||
|
|
||||||
|
# misc
|
||||||
|
/.sass-cache
|
||||||
|
/connect.lock
|
||||||
|
/coverage
|
||||||
|
/libpeerconnection.log
|
||||||
|
npm-debug.log
|
||||||
|
yarn-error.log
|
||||||
|
testem.log
|
||||||
|
/typings
|
||||||
|
|
||||||
|
# System Files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
*.rar
|
||||||
|
|
||||||
|
.vercel
|
||||||
148
angular.json
Normal file
148
angular.json
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
{
|
||||||
|
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||||
|
"version": 1,
|
||||||
|
"newProjectRoot": "projects",
|
||||||
|
"projects": {
|
||||||
|
"sales": {
|
||||||
|
"projectType": "application",
|
||||||
|
"schematics": {"@schematics/angular:component": {
|
||||||
|
"style": "scss"
|
||||||
|
}},
|
||||||
|
"root": "",
|
||||||
|
"sourceRoot": "src",
|
||||||
|
"prefix": "app",
|
||||||
|
"architect": {
|
||||||
|
"build": {
|
||||||
|
"builder": "@angular-devkit/build-angular:browser",
|
||||||
|
"options": {
|
||||||
|
"outputPath": "dist/sales",
|
||||||
|
"index": "src/index.html",
|
||||||
|
"main": "src/main.ts",
|
||||||
|
"polyfills": "src/polyfills.ts",
|
||||||
|
"tsConfig": "tsconfig.app.json",
|
||||||
|
"aot": true,
|
||||||
|
"assets": [
|
||||||
|
"src/favicon.ico",
|
||||||
|
"src/assets",
|
||||||
|
"src/assets/web.config",
|
||||||
|
"src/assets/banners",
|
||||||
|
"src/assets/icones",
|
||||||
|
"src/assets/img"
|
||||||
|
],
|
||||||
|
"styles": [
|
||||||
|
{
|
||||||
|
"input": "node_modules/bootstrap/dist/css/bootstrap.min.css"
|
||||||
|
},
|
||||||
|
"node_modules/bootstrap-icons/font/bootstrap-icons.css",
|
||||||
|
"node_modules/@progress/kendo-theme-bootstrap/dist/all.css",
|
||||||
|
"src/styles.css",
|
||||||
|
"src/styles-menu.css"
|
||||||
|
],
|
||||||
|
"scripts": [
|
||||||
|
"node_modules/bootstrap/dist/js/bootstrap.bundle.min.js",
|
||||||
|
"node_modules/jquery/dist/jquery.min.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"fileReplacements": [
|
||||||
|
{
|
||||||
|
"replace": "src/environments/environment.ts",
|
||||||
|
"with": "src/environments/environment.prod.ts"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"optimization": true,
|
||||||
|
"outputHashing": "all",
|
||||||
|
"sourceMap": false,
|
||||||
|
"extractCss": true,
|
||||||
|
"namedChunks": false,
|
||||||
|
"extractLicenses": true,
|
||||||
|
"vendorChunk": false,
|
||||||
|
"buildOptimizer": true,
|
||||||
|
"budgets": [
|
||||||
|
{
|
||||||
|
"type": "initial",
|
||||||
|
"maximumWarning": "10mb",
|
||||||
|
"maximumError": "12mb"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "anyComponentStyle",
|
||||||
|
"maximumWarning": "10kb",
|
||||||
|
"maximumError": "12kb"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"serve": {
|
||||||
|
"builder": "@angular-devkit/build-angular:dev-server",
|
||||||
|
"options": {
|
||||||
|
"browserTarget": "sales:build"
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"browserTarget": "sales:build:production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extract-i18n": {
|
||||||
|
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||||
|
"options": {
|
||||||
|
"browserTarget": "sales:build"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"builder": "@angular-devkit/build-angular:karma",
|
||||||
|
"options": {
|
||||||
|
"main": "src/test.ts",
|
||||||
|
"polyfills": "src/polyfills.ts",
|
||||||
|
"tsConfig": "tsconfig.spec.json",
|
||||||
|
"karmaConfig": "karma.conf.js",
|
||||||
|
"assets": [
|
||||||
|
"src/favicon.ico",
|
||||||
|
"src/assets",
|
||||||
|
"src/assets/web.config",
|
||||||
|
"src/assets/banners",
|
||||||
|
"src/assets/icones",
|
||||||
|
"src/assets/img"
|
||||||
|
],
|
||||||
|
"styles": [
|
||||||
|
"node_modules/bootstrap/dist/css/bootstrap.min.css",
|
||||||
|
"node_modules/bootstrap-icons/font/bootstrap-icons.css",
|
||||||
|
"node_modules/line-awesome/dist/line-awesome/css/line-awesome.min.css",
|
||||||
|
"src/styles.css",
|
||||||
|
"src/styles-menu.css"
|
||||||
|
],
|
||||||
|
"scripts": ["node_modules/jquery/dist/jquery.min.js"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"builder": "@angular-devkit/build-angular:tslint",
|
||||||
|
"options": {
|
||||||
|
"tsConfig": [
|
||||||
|
"tsconfig.app.json",
|
||||||
|
"tsconfig.spec.json",
|
||||||
|
"e2e/tsconfig.json"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"**/node_modules/**"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"e2e": {
|
||||||
|
"builder": "@angular-devkit/build-angular:protractor",
|
||||||
|
"options": {
|
||||||
|
"protractorConfig": "e2e/protractor.conf.js",
|
||||||
|
"devServerTarget": "sales:serve"
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"devServerTarget": "sales:serve:production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"defaultProject": "sales"
|
||||||
|
}
|
||||||
12
browserslist
Normal file
12
browserslist
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
|
||||||
|
# For additional information regarding the format and rule options, please see:
|
||||||
|
# https://github.com/browserslist/browserslist#queries
|
||||||
|
|
||||||
|
# You can see what browsers were selected by your queries by running:
|
||||||
|
# npx browserslist
|
||||||
|
|
||||||
|
> 0.5%
|
||||||
|
last 2 versions
|
||||||
|
Firefox ESR
|
||||||
|
not dead
|
||||||
|
not IE 9-11 # For IE 9-11 support, remove 'not'.
|
||||||
32
e2e/protractor.conf.js
Normal file
32
e2e/protractor.conf.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
// @ts-check
|
||||||
|
// Protractor configuration file, see link for more information
|
||||||
|
// https://github.com/angular/protractor/blob/master/lib/config.ts
|
||||||
|
|
||||||
|
const { SpecReporter } = require('jasmine-spec-reporter');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type { import("protractor").Config }
|
||||||
|
*/
|
||||||
|
exports.config = {
|
||||||
|
allScriptsTimeout: 11000,
|
||||||
|
specs: [
|
||||||
|
'./src/**/*.e2e-spec.ts'
|
||||||
|
],
|
||||||
|
capabilities: {
|
||||||
|
browserName: 'chrome'
|
||||||
|
},
|
||||||
|
directConnect: true,
|
||||||
|
baseUrl: 'http://localhost:4200/',
|
||||||
|
framework: 'jasmine',
|
||||||
|
jasmineNodeOpts: {
|
||||||
|
showColors: true,
|
||||||
|
defaultTimeoutInterval: 30000,
|
||||||
|
print: function() {}
|
||||||
|
},
|
||||||
|
onPrepare() {
|
||||||
|
require('ts-node').register({
|
||||||
|
project: require('path').join(__dirname, './tsconfig.json')
|
||||||
|
});
|
||||||
|
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
|
||||||
|
}
|
||||||
|
};
|
||||||
23
e2e/src/app.e2e-spec.ts
Normal file
23
e2e/src/app.e2e-spec.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import { AppPage } from './app.po';
|
||||||
|
import { browser, logging } from 'protractor';
|
||||||
|
|
||||||
|
describe('workspace-project App', () => {
|
||||||
|
let page: AppPage;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
page = new AppPage();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display welcome message', () => {
|
||||||
|
page.navigateTo();
|
||||||
|
expect(page.getTitleText()).toEqual('sales app is running!');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
// Assert that there are no errors emitted from the browser
|
||||||
|
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
|
||||||
|
expect(logs).not.toContain(jasmine.objectContaining({
|
||||||
|
level: logging.Level.SEVERE,
|
||||||
|
} as logging.Entry));
|
||||||
|
});
|
||||||
|
});
|
||||||
11
e2e/src/app.po.ts
Normal file
11
e2e/src/app.po.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { browser, by, element } from 'protractor';
|
||||||
|
|
||||||
|
export class AppPage {
|
||||||
|
navigateTo(): Promise<unknown> {
|
||||||
|
return browser.get(browser.baseUrl) as Promise<unknown>;
|
||||||
|
}
|
||||||
|
|
||||||
|
getTitleText(): Promise<string> {
|
||||||
|
return element(by.css('app-root .content span')).getText() as Promise<string>;
|
||||||
|
}
|
||||||
|
}
|
||||||
13
e2e/tsconfig.json
Normal file
13
e2e/tsconfig.json
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"extends": "../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../out-tsc/e2e",
|
||||||
|
"module": "commonjs",
|
||||||
|
"target": "es5",
|
||||||
|
"types": [
|
||||||
|
"jasmine",
|
||||||
|
"jasminewd2",
|
||||||
|
"node"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
38
gitea/deploy-ssh.yaml
Normal file
38
gitea/deploy-ssh.yaml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
name: Deploy Angular via SSH
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Setup Node 16
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 16
|
||||||
|
|
||||||
|
- name: Install and Build
|
||||||
|
run: |
|
||||||
|
npm install --legacy-peer-deps
|
||||||
|
npm run build -- --prod
|
||||||
|
|
||||||
|
- name: Transferir arquivos via SCP
|
||||||
|
uses: https://github.com/appleboy/scp-action@master
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.REMOTE_HOST }}
|
||||||
|
username: ${{ secrets.REMOTE_USER }}
|
||||||
|
key: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||||
|
source: "dist/"
|
||||||
|
target: "/var/www/html/vendaweb-frontend"
|
||||||
|
strip_components: 1
|
||||||
|
|
||||||
|
- name: Reiniciar Nginx Remoto
|
||||||
|
uses: https://github.com/appleboy/ssh-action@master
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.REMOTE_HOST }}
|
||||||
|
username: ${{ secrets.REMOTE_USER }}
|
||||||
|
key: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||||
|
script: |
|
||||||
|
sudo systemctl reload nginx
|
||||||
32
karma.conf.js
Normal file
32
karma.conf.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
// Karma configuration file, see link for more information
|
||||||
|
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||||
|
|
||||||
|
module.exports = function (config) {
|
||||||
|
config.set({
|
||||||
|
basePath: '',
|
||||||
|
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||||
|
plugins: [
|
||||||
|
require('karma-jasmine'),
|
||||||
|
require('karma-chrome-launcher'),
|
||||||
|
require('karma-jasmine-html-reporter'),
|
||||||
|
require('karma-coverage-istanbul-reporter'),
|
||||||
|
require('@angular-devkit/build-angular/plugins/karma')
|
||||||
|
],
|
||||||
|
client: {
|
||||||
|
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||||
|
},
|
||||||
|
coverageIstanbulReporter: {
|
||||||
|
dir: require('path').join(__dirname, './coverage/sales'),
|
||||||
|
reports: ['html', 'lcovonly', 'text-summary'],
|
||||||
|
fixWebpackSourcePaths: true
|
||||||
|
},
|
||||||
|
reporters: ['progress', 'kjhtml'],
|
||||||
|
port: 9876,
|
||||||
|
colors: true,
|
||||||
|
logLevel: config.LOG_INFO,
|
||||||
|
autoWatch: true,
|
||||||
|
browsers: ['Chrome'],
|
||||||
|
singleRun: false,
|
||||||
|
restartOnFileChange: true
|
||||||
|
});
|
||||||
|
};
|
||||||
1
kendo-ui-license.txt
Normal file
1
kendo-ui-license.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
eyJhbGciOiJSUzI1NiIsInR5cCI6IkxJQyJ9.eyJwcm9kdWN0cyI6W3sidHJpYWwiOnRydWUsImNvZGUiOiJLRU5ET1VJQU5HVUxBUiIsImxpY2Vuc2VFeHBpcmF0aW9uRGF0ZSI6MTYyMjc5NTQwMX1dLCJpbnRlZ3JpdHkiOiJVZ3JzZnhGQ0tjcExXQlY1Wm5UV3RRMXNEc1U9IiwibGljZW5zZUhvbGRlciI6ImVkdWFyZG8uZXN0ZXZhb0BhcHBzb2x1dGkuY29tLmJyIiwiaWF0IjoxNjIwODM0NDQ0LCJhdWQiOiJlZHVhcmRvLmVzdGV2YW9AYXBwc29sdXRpLmNvbS5iciJ9.FkYEcMVlG6LO6oGZiBC6yuHBiVXPm4ebPBeLmZ-r71xIZyGwzf1NIERIbDx9akyQXVSup9vST7nx5SIfIBYopkeWYBHLv6ps7-_omU0PI8T6lRw1QMIhqJ4qMVglUwR7vaQssPYOkJUZXJ6PJxDg-AJSRgc1mpWmErjyqpC0rxMlpAJCJZNP21OSithU4MEwYCBS3O-MaN8JhsMzg6z0cBKHvYsrPFvubUDBWBcwj4wEPPEGv1f7QVpglZME4Z7ZIXvJT9bEQC71OGa9Y7vjyuWBsStl0N3a8GMOhxks2semBHsRv7zb4ZMaRouqK2ZOHT6tdjhD5imWxz1_nIDvPw
|
||||||
38395
package-lock.json
generated
Normal file
38395
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
105
package.json
Normal file
105
package.json
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
{
|
||||||
|
"name": "sales",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"scripts": {
|
||||||
|
"ng": "ng",
|
||||||
|
"start": "ng serve --host 0.0.0.0",
|
||||||
|
"build": "ng build --prod && npx kendo-ui-license activate",
|
||||||
|
"test": "ng test",
|
||||||
|
"lint": "ng lint",
|
||||||
|
"e2e": "ng e2e"
|
||||||
|
},
|
||||||
|
"private": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@agm/core": "^1.1.0",
|
||||||
|
"@angular/animations": "^9.1.13",
|
||||||
|
"@angular/common": "^9.1.13",
|
||||||
|
"@angular/compiler": "~9.1.13",
|
||||||
|
"@angular/core": "^9.1.13",
|
||||||
|
"@angular/fire": "^6.1.5",
|
||||||
|
"@angular/forms": "^9.1.13",
|
||||||
|
"@angular/localize": "^9.1.13",
|
||||||
|
"@angular/platform-browser": "~9.1.13",
|
||||||
|
"@angular/platform-browser-dynamic": "~9.1.13",
|
||||||
|
"@angular/router": "~9.1.13",
|
||||||
|
"@ngrx/effects": "^9.2.1",
|
||||||
|
"@ngrx/store": "^9.2.1",
|
||||||
|
"@ngrx/store-devtools": "^12.0.0",
|
||||||
|
"@popperjs/core": "^2.11.8",
|
||||||
|
"@progress/kendo-angular-barcodes": "^1.0.0",
|
||||||
|
"@progress/kendo-angular-buttons": "^7.0.2",
|
||||||
|
"@progress/kendo-angular-charts": "^6.0.1",
|
||||||
|
"@progress/kendo-angular-common": "^2.0.0",
|
||||||
|
"@progress/kendo-angular-dateinputs": "^6.0.0",
|
||||||
|
"@progress/kendo-angular-dialog": "^6.0.1",
|
||||||
|
"@progress/kendo-angular-dropdowns": "^6.0.1",
|
||||||
|
"@progress/kendo-angular-excel-export": "^4.0.3",
|
||||||
|
"@progress/kendo-angular-gauges": "^4.1.3",
|
||||||
|
"@progress/kendo-angular-grid": "^6.0.1",
|
||||||
|
"@progress/kendo-angular-icons": "^0.4.5",
|
||||||
|
"@progress/kendo-angular-indicators": "^1.1.2",
|
||||||
|
"@progress/kendo-angular-inputs": "^8.0.9",
|
||||||
|
"@progress/kendo-angular-intl": "^3.0.0",
|
||||||
|
"@progress/kendo-angular-l10n": "^3.0.0",
|
||||||
|
"@progress/kendo-angular-label": "^3.1.2",
|
||||||
|
"@progress/kendo-angular-layout": "^6.4.2",
|
||||||
|
"@progress/kendo-angular-listview": "^3.0.0",
|
||||||
|
"@progress/kendo-angular-menu": "^3.0.4",
|
||||||
|
"@progress/kendo-angular-navigation": "^1.1.4",
|
||||||
|
"@progress/kendo-angular-notification": "^3.0.5",
|
||||||
|
"@progress/kendo-angular-pager": "^3.0.1",
|
||||||
|
"@progress/kendo-angular-pdf-export": "^3.0.3",
|
||||||
|
"@progress/kendo-angular-popup": "^4.0.0",
|
||||||
|
"@progress/kendo-angular-progressbar": "^2.0.3",
|
||||||
|
"@progress/kendo-angular-scrollview": "^4.1.3",
|
||||||
|
"@progress/kendo-angular-tooltip": "^3.1.5",
|
||||||
|
"@progress/kendo-angular-treeview": "^6.0.0",
|
||||||
|
"@progress/kendo-data-query": "^1.5.5",
|
||||||
|
"@progress/kendo-drawing": "^1.1.2",
|
||||||
|
"@progress/kendo-licensing": "^1.0.2",
|
||||||
|
"@progress/kendo-svg-icons": "^0.1.2",
|
||||||
|
"@progress/kendo-theme-bootstrap": "^5.1.1",
|
||||||
|
"@progress/kendo-theme-default": "^5.1.1",
|
||||||
|
"bootstrap": "^5.0.0-beta3",
|
||||||
|
"bootstrap-icons": "^1.7.2",
|
||||||
|
"chart.js": "^2.9.4",
|
||||||
|
"cldr-data": "^36.0.1",
|
||||||
|
"firebase": "^8.6.2",
|
||||||
|
"hammerjs": "^2.0.0",
|
||||||
|
"jwt-decode": "^3.1.2",
|
||||||
|
"line-awesome": "^1.3.0",
|
||||||
|
"lottie-web": "^5.12.2",
|
||||||
|
"ng2-charts": "^2.3.0",
|
||||||
|
"ngx-bootstrap": "^8.0.0",
|
||||||
|
"ngx-currency": "^2.5.3",
|
||||||
|
"ngx-lottie": "^7.0.3",
|
||||||
|
"rxjs": "^6.5.5",
|
||||||
|
"stimulsoft-viewer-angular": "^2020.5.2",
|
||||||
|
"tslib": "^1.10.0",
|
||||||
|
"zone.js": "~0.10.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@angular-devkit/build-angular": "~0.901.15",
|
||||||
|
"@angular/cli": "~9.1.15",
|
||||||
|
"@angular/compiler-cli": "~9.1.13",
|
||||||
|
"@types/jasmine": "~3.5.0",
|
||||||
|
"@types/jasminewd2": "~2.0.3",
|
||||||
|
"@types/jquery": "^3.5.5",
|
||||||
|
"@types/node": "^12.11.1",
|
||||||
|
"codelyzer": "^5.1.2",
|
||||||
|
"install": "^0.13.0",
|
||||||
|
"jasmine-core": "^3.5.0",
|
||||||
|
"jasmine-spec-reporter": "~4.2.1",
|
||||||
|
"jquery": "^3.6.0",
|
||||||
|
"karma": "^5.0.9",
|
||||||
|
"karma-chrome-launcher": "^3.1.1",
|
||||||
|
"karma-coverage-istanbul-reporter": "~2.1.0",
|
||||||
|
"karma-jasmine": "^3.0.3",
|
||||||
|
"karma-jasmine-html-reporter": "^1.7.0",
|
||||||
|
"npm": "^7.13.0",
|
||||||
|
"protractor": "~7.0.0",
|
||||||
|
"ts-node": "~8.3.0",
|
||||||
|
"tslint": "~6.1.0",
|
||||||
|
"typescript": "^3.8.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
30
src/app/admin/admin.module.ts
Normal file
30
src/app/admin/admin.module.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
import { AuthGuard } from '../guards/auth.guard';
|
||||||
|
import { KendoModule } from '../shared/kendo.module';
|
||||||
|
import { LottieModule } from 'ngx-lottie';
|
||||||
|
import player from 'lottie-web';
|
||||||
|
import { PermissionUserComponent } from './permission-user/permission-user.component';
|
||||||
|
import { ComponentModule } from '../components/component.module'; // Importando o módulo correto
|
||||||
|
|
||||||
|
export function playerFactory() {
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
const routes: Routes = [
|
||||||
|
{ path: 'permission-user', component: PermissionUserComponent, canActivate: [AuthGuard] },
|
||||||
|
];
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
RouterModule.forChild(routes),
|
||||||
|
KendoModule,
|
||||||
|
LottieModule.forRoot({ player: playerFactory }),
|
||||||
|
ComponentModule, // Importa o módulo que contém HeaderAdminComponent
|
||||||
|
],
|
||||||
|
declarations: [PermissionUserComponent], // Apenas componentes exclusivos deste módulo
|
||||||
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||||
|
})
|
||||||
|
export class AdminModule {}
|
||||||
63
src/app/admin/permission-user/permission-user.component.html
Normal file
63
src/app/admin/permission-user/permission-user.component.html
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
<app-header-admin></app-header-admin>
|
||||||
|
|
||||||
|
<div class="d-flex flex-column wrapper">
|
||||||
|
<main class="flex-fill main-dashboard">
|
||||||
|
<div class="container">
|
||||||
|
<div class="title-page">
|
||||||
|
<span>Selecione o usuário</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12 col-md-8">
|
||||||
|
<kendo-combobox (selectionChange)="getPermissionUser()" (valueChange)="setUserSelected($event)"
|
||||||
|
[valueNormalizer]="valueNormalizer" [data]="users" [kendoDropDownFilter]="filterSettings" textField="name"
|
||||||
|
valueField="userId" placeholder="Selecione o usuário..." (input)="forceUppercase($event)">
|
||||||
|
</kendo-combobox>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-2">
|
||||||
|
<button kendoButton class="btn-form" [disabled]="!userSelected" [icon]="isLoading ? 'loading' : ''"
|
||||||
|
(click)="getPermissionUser()">Pesquisar Permissões</button>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-2">
|
||||||
|
<button *ngIf="permissions.length > 0" kendoButton class="btn-form" [disabled]="!userSelected"
|
||||||
|
(click)="savePermissions()">Salvar
|
||||||
|
Permissões</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex-fill">
|
||||||
|
<div *ngIf="userSelected && permissions.length; else noUserSelected">
|
||||||
|
<kendo-treeview
|
||||||
|
[nodes]="permissions"
|
||||||
|
[children]="children"
|
||||||
|
[hasChildren]="hasChildren"
|
||||||
|
textField="text"
|
||||||
|
kendoTreeViewCheckable
|
||||||
|
[(checkedKeys)]="checkedKeys">
|
||||||
|
</kendo-treeview>
|
||||||
|
</div>
|
||||||
|
<ng-template #noUserSelected>
|
||||||
|
<div class="noData">
|
||||||
|
<ng-lottie *ngIf="lottieOptions" [options]="lottieOptions" [styles]="lottieStyles"></ng-lottie>
|
||||||
|
<p class="text-muted" *ngIf="!isLoading">
|
||||||
|
{{ infoMessage }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
<div class="container-fluid home-footer">
|
||||||
|
<div class="row align-items-center justify-content-center">
|
||||||
|
<div class="col-12">
|
||||||
|
<span class="text-center text-footer">
|
||||||
|
© 2022 App Soluti Soluções em aplicativos moveis
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
363
src/app/admin/permission-user/permission-user.component.scss
Normal file
363
src/app/admin/permission-user/permission-user.component.scss
Normal file
@@ -0,0 +1,363 @@
|
|||||||
|
.wrapper {
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
background-image: url("../../../assets/img/logo.svg");
|
||||||
|
background-position: center;
|
||||||
|
cursor: pointer;
|
||||||
|
width: 100%;
|
||||||
|
height: 80px !important;
|
||||||
|
overflow: hidden;
|
||||||
|
-webkit-background-size: cover;
|
||||||
|
-moz-background-size: cover;
|
||||||
|
-o-background-size: cover;
|
||||||
|
background-size: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-productlist {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
padding: 32px 64px;
|
||||||
|
width: 100%;
|
||||||
|
height: 80px;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 80px;
|
||||||
|
top: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
|
||||||
|
/*background: #2d2e83;*/
|
||||||
|
background: #131d52;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-menu {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
position: static;
|
||||||
|
height: 48px;
|
||||||
|
|
||||||
|
background: #1d1e67;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
/* Inside auto layout */
|
||||||
|
|
||||||
|
flex: none;
|
||||||
|
order: 1;
|
||||||
|
flex-grow: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name-user {
|
||||||
|
position: static;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
font-family: "Open Sans";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 19px;
|
||||||
|
/* identical to box height */
|
||||||
|
|
||||||
|
color: #ffffff;
|
||||||
|
|
||||||
|
/* Inside auto layout */
|
||||||
|
|
||||||
|
flex: none;
|
||||||
|
order: 0;
|
||||||
|
flex-grow: 0;
|
||||||
|
margin: 0px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.last-access {
|
||||||
|
position: static;
|
||||||
|
|
||||||
|
font-family: "Open Sans";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 16px;
|
||||||
|
|
||||||
|
color: #848484;
|
||||||
|
|
||||||
|
/* Inside auto layout */
|
||||||
|
|
||||||
|
flex: none;
|
||||||
|
order: 1;
|
||||||
|
flex-grow: 0;
|
||||||
|
margin: 0px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img-config {
|
||||||
|
position: static;
|
||||||
|
background: #ffffff;
|
||||||
|
flex: none;
|
||||||
|
order: 2;
|
||||||
|
flex-grow: 0;
|
||||||
|
margin: 0px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
// modificado
|
||||||
|
position: relative;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img-user {
|
||||||
|
position: static;
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
left: 8px;
|
||||||
|
top: 6px;
|
||||||
|
|
||||||
|
background: url("../../../assets/img/img_user.svg");
|
||||||
|
border-radius: 2px;
|
||||||
|
|
||||||
|
/* Inside auto layout */
|
||||||
|
|
||||||
|
flex: none;
|
||||||
|
order: 0;
|
||||||
|
flex-grow: 0;
|
||||||
|
margin: 0px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.home-footer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 46px;
|
||||||
|
/*background: #2d2e83;*/
|
||||||
|
background: #131d52;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-footer {
|
||||||
|
position: static;
|
||||||
|
font-family: "Open Sans";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 14px;
|
||||||
|
/* identical to box height */
|
||||||
|
text-align: center;
|
||||||
|
color: #ffffff;
|
||||||
|
flex: none;
|
||||||
|
order: 0;
|
||||||
|
flex-grow: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-dashboard {
|
||||||
|
margin-top: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-order {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
position: static;
|
||||||
|
background: #ff9521;
|
||||||
|
border-radius: 5px;
|
||||||
|
/* Inside auto layout */
|
||||||
|
flex: none;
|
||||||
|
order: 1;
|
||||||
|
flex-grow: 0;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-button {
|
||||||
|
position: static;
|
||||||
|
font-family: "Open Sans";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 22px;
|
||||||
|
/* identical to box height */
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
color: #ffffff;
|
||||||
|
|
||||||
|
/* Inside auto layout */
|
||||||
|
|
||||||
|
flex: none;
|
||||||
|
order: 0;
|
||||||
|
flex-grow: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-flat {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
position: static;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid #ef7d00;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 5px;
|
||||||
|
/* Inside auto layout */
|
||||||
|
flex: none;
|
||||||
|
order: 1;
|
||||||
|
flex-grow: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.side-menu {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 16px;
|
||||||
|
|
||||||
|
position: static;
|
||||||
|
height: 100%;
|
||||||
|
left: 0px;
|
||||||
|
top: 0px;
|
||||||
|
|
||||||
|
background: #ffffff;
|
||||||
|
|
||||||
|
/* Inside auto layout */
|
||||||
|
|
||||||
|
flex: none;
|
||||||
|
order: 0;
|
||||||
|
align-self: stretch;
|
||||||
|
flex-grow: 0;
|
||||||
|
margin: 0px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-button-flat {
|
||||||
|
position: static;
|
||||||
|
font-family: "Open Sans";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 22px;
|
||||||
|
/* identical to box height */
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
color: #ef7d00;
|
||||||
|
|
||||||
|
/* Inside auto layout */
|
||||||
|
|
||||||
|
flex: none;
|
||||||
|
order: 0;
|
||||||
|
flex-grow: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-flat-blue {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
padding: 0px;
|
||||||
|
|
||||||
|
position: static;
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid #2d2e83;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
/* Inside auto layout */
|
||||||
|
|
||||||
|
flex: none;
|
||||||
|
order: 1;
|
||||||
|
align-self: stretch;
|
||||||
|
flex-grow: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-button-flat-blue {
|
||||||
|
position: static;
|
||||||
|
font-family: "Open Sans";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 22px;
|
||||||
|
/* identical to box height */
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
color: #2d2e83;
|
||||||
|
|
||||||
|
/* Inside auto layout */
|
||||||
|
|
||||||
|
flex: none;
|
||||||
|
order: 0;
|
||||||
|
flex-grow: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.noData {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
|
flex-direction: column;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-muted{
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Responsividade */
|
||||||
|
|
||||||
|
/* Smartphones */
|
||||||
|
@media (max-width: 575.98px) {
|
||||||
|
.btnSbtn-formearch {
|
||||||
|
margin-top: 10px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-page{
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.noData {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.noData p {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tablets */
|
||||||
|
@media (max-width: 991.98px) {
|
||||||
|
.btn-form {
|
||||||
|
margin-top: 10px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-page{
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Desktops */
|
||||||
|
@media (min-width: 992px) {
|
||||||
|
.btn-form {
|
||||||
|
max-width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-page{
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
192
src/app/admin/permission-user/permission-user.component.ts
Normal file
192
src/app/admin/permission-user/permission-user.component.ts
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { DropDownFilterSettings } from '@progress/kendo-angular-dropdowns';
|
||||||
|
import { Observable, of } from 'rxjs';
|
||||||
|
import { catchError, map } from 'rxjs/operators';
|
||||||
|
import { AuthService } from 'src/app/auth/services/auth.service';
|
||||||
|
import { UserService } from 'src/app/services/user.service';
|
||||||
|
import { process } from '@progress/kendo-data-query';
|
||||||
|
import { AnimationOptions } from 'ngx-lottie';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-permission-user',
|
||||||
|
templateUrl: './permission-user.component.html',
|
||||||
|
styleUrls: ['./permission-user.component.scss']
|
||||||
|
})
|
||||||
|
|
||||||
|
export class PermissionUserComponent implements OnInit {
|
||||||
|
|
||||||
|
/* Header */
|
||||||
|
public userName: string;
|
||||||
|
public storeName: string;
|
||||||
|
users: any[] = [];
|
||||||
|
public checkedKeys: any[] = [];
|
||||||
|
public data: any[] = [];
|
||||||
|
public userSelected: any;
|
||||||
|
public children = (dataItem: any): Observable<any[]> => of(dataItem.items);
|
||||||
|
public hasChildren = (dataItem: any): boolean => !!dataItem.items;
|
||||||
|
public permissions: any[] = [];
|
||||||
|
public isUserLoading = false;
|
||||||
|
public loadingIcon = '';
|
||||||
|
public isLoading = false;
|
||||||
|
public infoMessage = 'Por favor, selecione um usuário para carregar as permissões.';
|
||||||
|
|
||||||
|
public lottieOptions: AnimationOptions = {
|
||||||
|
path: 'assets/animations/no-data.json',
|
||||||
|
};
|
||||||
|
|
||||||
|
public lottieStyles = {
|
||||||
|
width: '300px',
|
||||||
|
height: '300px',
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(private readonly authService: AuthService,
|
||||||
|
private readonly userService: UserService) { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.userName = this.authService.getUserName();
|
||||||
|
this.storeName = this.authService.getStoreName();
|
||||||
|
this.userService.getUsers()
|
||||||
|
.pipe(
|
||||||
|
map((users) => {
|
||||||
|
this.users = users;
|
||||||
|
}))
|
||||||
|
.subscribe();
|
||||||
|
|
||||||
|
if (!this.userSelected) {
|
||||||
|
this.infoMessage = 'Nenhum usuário está selecionado.';
|
||||||
|
}
|
||||||
|
this.loadUsers();
|
||||||
|
}
|
||||||
|
|
||||||
|
loadUsers() {
|
||||||
|
this.isUserLoading = true;
|
||||||
|
this.userService.getUsers()
|
||||||
|
.pipe(
|
||||||
|
map((users) => {
|
||||||
|
this.users = users;
|
||||||
|
this.isUserLoading = false;
|
||||||
|
}),
|
||||||
|
catchError((error) => {
|
||||||
|
console.error('Erro ao carregar usuários:', error);
|
||||||
|
this.isUserLoading = false;
|
||||||
|
return of([]);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
logout() {
|
||||||
|
this.authService.logout();
|
||||||
|
}
|
||||||
|
|
||||||
|
public filterSettings: DropDownFilterSettings = {
|
||||||
|
caseSensitive: false,
|
||||||
|
operator: "contains",
|
||||||
|
};
|
||||||
|
|
||||||
|
public valueNormalizer = (text: Observable<string>) =>
|
||||||
|
text.pipe(
|
||||||
|
map((content: string) => {
|
||||||
|
return {
|
||||||
|
value: this.permissions[this.permissions.length - 1]?.value + 1 || 1,
|
||||||
|
text: content,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
forceUppercase(event: Event): void {
|
||||||
|
const inputElement = event.target as HTMLInputElement;
|
||||||
|
if (inputElement && inputElement.value) {
|
||||||
|
inputElement.value = inputElement.value.toUpperCase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setUserSelected(user: any) {
|
||||||
|
console.log(user);
|
||||||
|
this.userSelected = user;
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
this.permissions = [];
|
||||||
|
this.checkedKeys = [];
|
||||||
|
this.infoMessage = 'Por favor, selecione um usuário válido.';
|
||||||
|
} else {
|
||||||
|
this.checkedKeys = [];
|
||||||
|
this.infoMessage = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getPermissionUser() {
|
||||||
|
if (!this.userSelected) {
|
||||||
|
console.warn('Nenhum usuário selecionado. Não é possível buscar permissões.');
|
||||||
|
this.lottieOptions = { path: 'assets/animations/no-data.json' };
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isLoading = true;
|
||||||
|
this.lottieOptions = { path: 'assets/animations/loading.json' };
|
||||||
|
|
||||||
|
this.userService.getPermissionUser(this.userSelected.userId)
|
||||||
|
.pipe(
|
||||||
|
map((permissions) => {
|
||||||
|
this.permissions = permissions;
|
||||||
|
this.loadPermissions(this.permissions);
|
||||||
|
|
||||||
|
// If permissions are found, stop the loading animation
|
||||||
|
this.isLoading = false;
|
||||||
|
this.lottieOptions = permissions.length > 0
|
||||||
|
? { path: 'assets/animations/no-data.json' }
|
||||||
|
: { path: 'assets/animations/no-data.json' };
|
||||||
|
}),
|
||||||
|
catchError((error) => {
|
||||||
|
console.error('Erro ao carregar permissões do usuário:', error);
|
||||||
|
this.isLoading = false; // Stop loading state
|
||||||
|
this.lottieOptions = { path: 'assets/animations/no-data.json' }; // Error or no data animation
|
||||||
|
return of([]); // Default return value in case of error
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
savePermissions() {
|
||||||
|
const permissionsId: number[] = [];
|
||||||
|
const atividades: any[] = [];
|
||||||
|
const actions: any[] = [];
|
||||||
|
for (const key of this.checkedKeys) {
|
||||||
|
const ids = key.split("_");
|
||||||
|
if (ids.length > 2) {
|
||||||
|
const module = this.permissions[ids[0]];
|
||||||
|
const atividade = module.items[ids[1]];
|
||||||
|
const action = atividade.items[ids[2]];
|
||||||
|
if (action != undefined) {
|
||||||
|
actions.push(action);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const module = this.permissions[ids[0]];
|
||||||
|
const atividade = module.items[ids[1]];
|
||||||
|
if (atividade != undefined) {
|
||||||
|
atividades.push(atividade);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const updatePermissions = { atividades: atividades, actions: actions };
|
||||||
|
const userId = this.userSelected.userId;
|
||||||
|
|
||||||
|
this.userService.updatePermissionUser(userId, updatePermissions);
|
||||||
|
}
|
||||||
|
|
||||||
|
loadPermissions(data: any) {
|
||||||
|
this.checkedKeys = [];
|
||||||
|
data.filter(permission => permission.allow == 'S')
|
||||||
|
.forEach(permissionModule => {
|
||||||
|
let indice_modulo = -1;
|
||||||
|
let indice_atividade = -1;
|
||||||
|
permissionModule.items
|
||||||
|
.filter(permissionAtividade => permissionAtividade.allow == 'S')
|
||||||
|
.forEach(permissionAtividade => {
|
||||||
|
indice_modulo++;
|
||||||
|
indice_atividade++;
|
||||||
|
this.checkedKeys.push(`${indice_modulo}_${indice_atividade}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
26
src/app/app-routing.module.ts
Normal file
26
src/app/app-routing.module.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { Routes, RouterModule } from '@angular/router';
|
||||||
|
import { AuthGuard } from './guards/auth.guard';
|
||||||
|
import { MenuComponent } from './menu/menu.component';
|
||||||
|
import { MenuEcosistemaComponent } from './menu-ecosistema/menu-ecosistema.component';
|
||||||
|
|
||||||
|
|
||||||
|
const routes: Routes = [
|
||||||
|
{ path: '', redirectTo: 'sales/home', pathMatch: 'full' },
|
||||||
|
// loadChildren: () => import('./sales/sales.module').then(m => m.SalesModule), canActivate: [AuthGuard] },
|
||||||
|
{ path: 'login', loadChildren: () => import('./auth/auth.module').then(m => m.AuthModule)},
|
||||||
|
{ path: 'menu', component: MenuEcosistemaComponent},
|
||||||
|
{ path: 'financial', loadChildren: () => import('./financial/financial.module').then(m => m.FinancialModule), canActivate: [AuthGuard] },
|
||||||
|
{ path: 'sales', loadChildren: () => import('./sales/sales.module').then(m => m.SalesModule), canActivate: [AuthGuard] },
|
||||||
|
{ path: 'crm', loadChildren: () => import('./crm/crm.module').then(m => m.CrmModule), canActivate: [AuthGuard] },
|
||||||
|
{ path: 'partner', loadChildren: () => import('./partners/partners.module').then(m => m.PartnersModule), canActivate: [AuthGuard] },
|
||||||
|
{ path: 'admin', loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule), canActivate: [AuthGuard] },
|
||||||
|
{ path: 'dashboardcompany', loadChildren: () =>
|
||||||
|
import('./sales/pages/dashboard-company/dashboard-company.module').then(m => m.DashboardCompanyModule)},
|
||||||
|
];
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [RouterModule.forRoot(routes, {useHash: true})],
|
||||||
|
exports: [RouterModule]
|
||||||
|
})
|
||||||
|
export class AppRoutingModule { }
|
||||||
0
src/app/app.component.css
Normal file
0
src/app/app.component.css
Normal file
1
src/app/app.component.html
Normal file
1
src/app/app.component.html
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<router-outlet></router-outlet>
|
||||||
35
src/app/app.component.spec.ts
Normal file
35
src/app/app.component.spec.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import { TestBed, async } from '@angular/core/testing';
|
||||||
|
import { RouterTestingModule } from '@angular/router/testing';
|
||||||
|
import { AppComponent } from './app.component';
|
||||||
|
|
||||||
|
describe('AppComponent', () => {
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [
|
||||||
|
RouterTestingModule
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
AppComponent
|
||||||
|
],
|
||||||
|
}).compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should create the app', () => {
|
||||||
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
|
const app = fixture.componentInstance;
|
||||||
|
expect(app).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should have as title 'sales'`, () => {
|
||||||
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
|
const app = fixture.componentInstance;
|
||||||
|
expect(app.title).toEqual('sales');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render title', () => {
|
||||||
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
|
fixture.detectChanges();
|
||||||
|
const compiled = fixture.nativeElement;
|
||||||
|
expect(compiled.querySelector('.content span').textContent).toContain('sales app is running!');
|
||||||
|
});
|
||||||
|
});
|
||||||
10
src/app/app.component.ts
Normal file
10
src/app/app.component.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-root',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.css']
|
||||||
|
})
|
||||||
|
export class AppComponent {
|
||||||
|
title = 'sales';
|
||||||
|
}
|
||||||
103
src/app/app.module.ts
Normal file
103
src/app/app.module.ts
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
|
import { DEFAULT_CURRENCY_CODE, LOCALE_ID, NgModule } from '@angular/core';
|
||||||
|
import ptBr from '@angular/common/locales/pt';
|
||||||
|
import { HashLocationStrategy, LocationStrategy } from '@angular/common';
|
||||||
|
|
||||||
|
import { AppRoutingModule } from './app-routing.module';
|
||||||
|
import { AppComponent } from './app.component';
|
||||||
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
import { LottieModule } from 'ngx-lottie';
|
||||||
|
import player from 'lottie-web';
|
||||||
|
|
||||||
|
import { SalesModule } from './sales/sales.module';
|
||||||
|
import { FinancialModule } from './financial/financial.module';
|
||||||
|
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
|
||||||
|
import { environment } from '../environments/environment';
|
||||||
|
import { EffectsModule } from '@ngrx/effects';
|
||||||
|
import { ShoppingEffects } from './sales/store/effects/shopping.effects';
|
||||||
|
import { StoreModule } from '@ngrx/store';
|
||||||
|
import { ShoppingReducer } from './sales/store/reducers/shopping.reducer';
|
||||||
|
import { AngularFireModule } from '@angular/fire';
|
||||||
|
import { AngularFirestoreModule } from '@angular/fire/firestore';
|
||||||
|
import { AngularFireAuthModule } from '@angular/fire/auth';
|
||||||
|
import { AuthGuard } from './guards/auth.guard';
|
||||||
|
import { AuthService } from './auth/services/auth.service';
|
||||||
|
import { CustomerModule } from './sales/customer/customer.module';
|
||||||
|
import { KendoModule } from './shared/kendo.module';
|
||||||
|
import { MessageErrorComponent } from './shared/menssages/message-error/message-error.component';
|
||||||
|
import { MenuEcosistemaComponent } from './menu-ecosistema/menu-ecosistema.component';
|
||||||
|
import { ComponentModule } from './components/component.module';
|
||||||
|
import { MessageFailureComponent } from './shared/menssages/message-failure/message-failure.component';
|
||||||
|
import { CustomerSaleEffects } from './sales/store/effects/customer-sale.effects';
|
||||||
|
import { CustomerSaleReducer } from './sales/store/reducers/customer-sale.reducer';
|
||||||
|
import { MenssageInformationComponent } from './shared/menssages/menssage-information/menssage-information.component';
|
||||||
|
import { CrmModule } from './crm/crm.module';
|
||||||
|
import { registerLocaleData } from '@angular/common';
|
||||||
|
import { MenuComponent } from './menu/menu.component';
|
||||||
|
import { MenuSalesComponent } from './sales/menu-sales/menu-sales.component';
|
||||||
|
import { StimulsoftViewerModule } from 'stimulsoft-viewer-angular';
|
||||||
|
import { DialogRef } from '@progress/kendo-angular-dialog';
|
||||||
|
import { PartnersModule } from './partners/partners.module';
|
||||||
|
import { AdminModule } from './admin/admin.module';
|
||||||
|
import { DialogsModule } from '@progress/kendo-angular-dialog';
|
||||||
|
import { ChartsModule } from '@progress/kendo-angular-charts';
|
||||||
|
import 'hammerjs';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
registerLocaleData(ptBr);
|
||||||
|
|
||||||
|
export function playerFactory() {
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [
|
||||||
|
AppComponent,
|
||||||
|
MessageErrorComponent,
|
||||||
|
MessageFailureComponent,
|
||||||
|
MenuEcosistemaComponent,
|
||||||
|
MenssageInformationComponent,
|
||||||
|
MenuComponent,
|
||||||
|
MenuSalesComponent,
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
AngularFireModule.initializeApp(environment.firebase),
|
||||||
|
DialogsModule,
|
||||||
|
AngularFirestoreModule, // imports firebase/firestore, only needed for database features
|
||||||
|
AngularFireAuthModule,
|
||||||
|
BrowserModule,
|
||||||
|
HttpClientModule,
|
||||||
|
FinancialModule,
|
||||||
|
AppRoutingModule,
|
||||||
|
BrowserAnimationsModule,
|
||||||
|
SalesModule,
|
||||||
|
CustomerModule,
|
||||||
|
KendoModule,
|
||||||
|
ComponentModule,
|
||||||
|
CrmModule,
|
||||||
|
StoreModule.forRoot({ shopping: ShoppingReducer, customerSale: CustomerSaleReducer }),
|
||||||
|
EffectsModule.forRoot([ShoppingEffects, CustomerSaleEffects]),
|
||||||
|
StoreDevtoolsModule.instrument({ maxAge: 25, logOnly: environment.production }),
|
||||||
|
StimulsoftViewerModule,
|
||||||
|
PartnersModule,
|
||||||
|
AdminModule,
|
||||||
|
// LottieModule.forRoot({ player: playerFactory }),
|
||||||
|
ChartsModule,
|
||||||
|
],
|
||||||
|
exports: [StimulsoftViewerModule],
|
||||||
|
providers: [
|
||||||
|
AuthGuard, AuthService,
|
||||||
|
{ provide: LocationStrategy, useClass: HashLocationStrategy },
|
||||||
|
{ provide: LOCALE_ID, useValue: 'pt-BR' },
|
||||||
|
{ provide: DEFAULT_CURRENCY_CODE, useValue: 'BRL', },
|
||||||
|
DialogRef,
|
||||||
|
/*{
|
||||||
|
provide: ErrorHandler,
|
||||||
|
useClass: ErrorsHandler,
|
||||||
|
},*/
|
||||||
|
],
|
||||||
|
bootstrap: [AppComponent]
|
||||||
|
})
|
||||||
|
export class AppModule { }
|
||||||
9
src/app/auth/auth-login/auth-login.component.css
Normal file
9
src/app/auth/auth-login/auth-login.component.css
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
.example {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.k-form kendo-label:not(:last-of-type) {
|
||||||
|
flex-direction: column;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
0
src/app/auth/auth-login/auth-login.component.html
Normal file
0
src/app/auth/auth-login/auth-login.component.html
Normal file
0
src/app/auth/auth-login/auth-login.component.scss
Normal file
0
src/app/auth/auth-login/auth-login.component.scss
Normal file
25
src/app/auth/auth-login/auth-login.component.spec.ts
Normal file
25
src/app/auth/auth-login/auth-login.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AuthLoginComponent } from './auth-login.component';
|
||||||
|
|
||||||
|
describe('AuthLoginComponent', () => {
|
||||||
|
let component: AuthLoginComponent;
|
||||||
|
let fixture: ComponentFixture<AuthLoginComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ AuthLoginComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(AuthLoginComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
65
src/app/auth/auth-login/auth-login.component.ts
Normal file
65
src/app/auth/auth-login/auth-login.component.ts
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { FormControl, FormGroup, Validators } from '@angular/forms';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-auth-login',
|
||||||
|
templateUrl: './auth-login.component.html',
|
||||||
|
styleUrls: ['./auth-login.component.scss',
|
||||||
|
'./auth-login.component.css']
|
||||||
|
})
|
||||||
|
|
||||||
|
export class AuthLoginComponent implements OnInit {
|
||||||
|
|
||||||
|
public phoneNumberValue = '';
|
||||||
|
public phoneNumberMask = '(999) 000-00-00-00';
|
||||||
|
|
||||||
|
public form: FormGroup;
|
||||||
|
|
||||||
|
public data: any = {
|
||||||
|
fullName: '',
|
||||||
|
email: '',
|
||||||
|
phoneNumber: this.phoneNumberValue,
|
||||||
|
arrivalDate: null,
|
||||||
|
numberOfNights: null,
|
||||||
|
numberOfGuests: null,
|
||||||
|
terms: false,
|
||||||
|
comments: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.form = new FormGroup({
|
||||||
|
fullName: new FormControl(this.data.fullName, [Validators.required]),
|
||||||
|
email: new FormControl(this.data.email, [
|
||||||
|
Validators.required,
|
||||||
|
Validators.email,
|
||||||
|
]),
|
||||||
|
phoneNumber: new FormControl(this.data.phoneNumber, [
|
||||||
|
Validators.required,
|
||||||
|
]),
|
||||||
|
arrivalDate: new FormControl(this.data.arrivalDate, [
|
||||||
|
Validators.required,
|
||||||
|
]),
|
||||||
|
numberOfNights: new FormControl(this.data.numberOfNights, [
|
||||||
|
Validators.required,
|
||||||
|
]),
|
||||||
|
numberOfGuests: new FormControl(this.data.numberOfGuests, [
|
||||||
|
Validators.required,
|
||||||
|
Validators.max(5),
|
||||||
|
]),
|
||||||
|
terms: new FormControl(this.data.terms, [Validators.requiredTrue]),
|
||||||
|
comments: new FormControl(this.data.comments),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
public submitForm(): void {
|
||||||
|
this.form.markAllAsTouched();
|
||||||
|
}
|
||||||
|
|
||||||
|
public clearForm(): void {
|
||||||
|
this.form.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
25
src/app/auth/auth.module.ts
Normal file
25
src/app/auth/auth.module.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { AuthLoginComponent } from './auth-login/auth-login.component';
|
||||||
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
|
import { KendoModule } from '../shared/kendo.module';
|
||||||
|
import { LoginComponent } from './login/login.component';
|
||||||
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
import { RegisterComponent } from './register/register.component';
|
||||||
|
import { AuthService } from './services/auth.service';
|
||||||
|
|
||||||
|
const routes: Routes = [{ path: '', component: LoginComponent },
|
||||||
|
{ path: 'register', component: RegisterComponent }];
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [AuthLoginComponent, LoginComponent, RegisterComponent],
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
FormsModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
KendoModule,
|
||||||
|
RouterModule.forChild(routes),
|
||||||
|
],
|
||||||
|
providers: [AuthService]
|
||||||
|
})
|
||||||
|
export class AuthModule { }
|
||||||
206
src/app/auth/login/login.component.css
Normal file
206
src/app/auth/login/login.component.css
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
.hs-login {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 32px 64px;
|
||||||
|
position: absolute;
|
||||||
|
background: #fcfcfc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
width: 190px;
|
||||||
|
height: 51.54px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fs-login {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
/* width: 100%; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.fs-label {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container-login {
|
||||||
|
background-image: url("../../../assets/img/Background.png");
|
||||||
|
background-size: cover;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cs-login {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 60px 40px;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 500px;
|
||||||
|
background: #fcfcfc;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Textos */
|
||||||
|
.ls-saudacao,
|
||||||
|
.ls-plataforma {
|
||||||
|
font-family: "Fira Sans", sans-serif;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ls-saudacao {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 40px;
|
||||||
|
color: #ef7d00;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ls-plataforma {
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 40px;
|
||||||
|
color: #2d2e83;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ls-subtitle {
|
||||||
|
font-family: "Open Sans", sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 20px;
|
||||||
|
color: #ef7d00;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ls-text {
|
||||||
|
position: static;
|
||||||
|
width: 87px;
|
||||||
|
height: 19px;
|
||||||
|
left: 0px;
|
||||||
|
top: 37px;
|
||||||
|
|
||||||
|
font-family: "Open Sans";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 19px;
|
||||||
|
/* identical to box height */
|
||||||
|
|
||||||
|
color: #848484;
|
||||||
|
|
||||||
|
/* Inside auto layout */
|
||||||
|
|
||||||
|
flex: none;
|
||||||
|
order: 1;
|
||||||
|
flex-grow: 0;
|
||||||
|
margin: 10px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-text {
|
||||||
|
/* Auto layout */
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: flex-start;
|
||||||
|
padding: 0px;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
position: static;
|
||||||
|
width: 408px;
|
||||||
|
height: 48px;
|
||||||
|
left: 0px;
|
||||||
|
top: 66px;
|
||||||
|
|
||||||
|
/* Inside auto layout */
|
||||||
|
|
||||||
|
flex: none;
|
||||||
|
order: 2;
|
||||||
|
align-self: stretch;
|
||||||
|
flex-grow: 0;
|
||||||
|
margin: 10px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.bs-default {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
color: white;
|
||||||
|
width: 100%;
|
||||||
|
height: 48px;
|
||||||
|
background: #2d2e83;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ls-forgot-password {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ls-link-forgot-password {
|
||||||
|
text-decoration: underline;
|
||||||
|
color: #2d2e83;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsividade */
|
||||||
|
|
||||||
|
/* Smartphones */
|
||||||
|
@media (max-width: 575.98px) {
|
||||||
|
.cs-login {
|
||||||
|
padding: 40px 20px;
|
||||||
|
max-width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ls-saudacao {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ls-plataforma {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bs-default {
|
||||||
|
height: 56px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-text {
|
||||||
|
width: 300px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ls-forgot-password {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ls-link-forgot-password {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tablets */
|
||||||
|
@media (max-width: 991.98px) {
|
||||||
|
.cs-login {
|
||||||
|
max-width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ls-saudacao {
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ls-plataforma {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-text {
|
||||||
|
width: 250px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Desktops */
|
||||||
|
@media (min-width: 992px) {
|
||||||
|
.cs-login {
|
||||||
|
max-width: 500px;
|
||||||
|
}
|
||||||
|
}
|
||||||
56
src/app/auth/login/login.component.html
Normal file
56
src/app/auth/login/login.component.html
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<div class="container-fluid container-login">
|
||||||
|
<div class="d-flex flex-column">
|
||||||
|
<div class="row justify-content-center align-items-center" style="height: 100vh;">
|
||||||
|
<div class="col-12 col-sm-8 col-md-6 col-xl-4">
|
||||||
|
<div class="cs-login">
|
||||||
|
<div class="text-center">
|
||||||
|
<span class="ls-saudacao">Bem-vindo(a),</span>
|
||||||
|
<span class="ls-plataforma">à plataforma SMART</span>
|
||||||
|
</div>
|
||||||
|
<form class="fs-login" [formGroup]="form" (keydown.enter)="submitForm()">
|
||||||
|
<span class="ls-subtitle">Acesse sua conta</span>
|
||||||
|
<kendo-formfield>
|
||||||
|
<label>
|
||||||
|
<span class="ls-text">Email</span>
|
||||||
|
<kendo-textbox class="is-text" formControlName="email" placeholder="Informe seu email de acesso" #email
|
||||||
|
required>
|
||||||
|
</kendo-textbox>
|
||||||
|
</label>
|
||||||
|
<!-- <kendo-formerror *ngIf="form.controls.email.errors?.required">
|
||||||
|
Erro: Email é obrigatório!
|
||||||
|
</kendo-formerror>
|
||||||
|
<kendo-formerror *ngIf="form.controls.email.errors?.email">
|
||||||
|
Error: Informe um email com formato válido.
|
||||||
|
</kendo-formerror> -->
|
||||||
|
</kendo-formfield>
|
||||||
|
<kendo-formfield>
|
||||||
|
<label>
|
||||||
|
<span class="ls-text">Senha</span>
|
||||||
|
<kendo-textbox class="k-textbox is-text" type="password" placeholder="Informe sua senha" #password
|
||||||
|
formControlName="password">
|
||||||
|
<ng-template kendoTextBoxSuffixTemplate>
|
||||||
|
<button
|
||||||
|
kendoButton
|
||||||
|
look="clear"
|
||||||
|
[icon]="passwordVisible ? 'eye-slash' : 'eye'"
|
||||||
|
(click)="toggleVisibility()"
|
||||||
|
type="button"
|
||||||
|
></button>
|
||||||
|
</ng-template>
|
||||||
|
</kendo-textbox>
|
||||||
|
</label>
|
||||||
|
<kendo-formerror>Erro: A senha é obrigatória!</kendo-formerror>
|
||||||
|
</kendo-formfield>
|
||||||
|
<span class="ls-forgot-password">
|
||||||
|
Esqueceu a senha? <a class="ls-link-forgot-password">Recupere o acesso</a>
|
||||||
|
</span>
|
||||||
|
<button kendoButton class="bs-default" [disabled]="isLoading" [icon]="loadingIcon" (click)="submitForm()">
|
||||||
|
ENTRAR
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div kendoDialogContainer></div>
|
||||||
1
src/app/auth/login/login.component.scss
Normal file
1
src/app/auth/login/login.component.scss
Normal file
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
25
src/app/auth/login/login.component.spec.ts
Normal file
25
src/app/auth/login/login.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { LoginComponent } from './login.component';
|
||||||
|
|
||||||
|
describe('LoginComponent', () => {
|
||||||
|
let component: LoginComponent;
|
||||||
|
let fixture: ComponentFixture<LoginComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ LoginComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(LoginComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
151
src/app/auth/login/login.component.ts
Normal file
151
src/app/auth/login/login.component.ts
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
import { AfterViewInit, Component, NgZone, OnInit, ViewChild } from '@angular/core';
|
||||||
|
import { FormControl, FormGroup, Validators } from '@angular/forms';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
import { DialogService } from '@progress/kendo-angular-dialog';
|
||||||
|
import { TextBoxComponent } from '@progress/kendo-angular-inputs';
|
||||||
|
import { thumbnailsUpIcon } from '@progress/kendo-svg-icons';
|
||||||
|
import { ResultApi } from 'src/app/models/result-api.model';
|
||||||
|
import { MessageFailureComponent } from 'src/app/shared/menssages/message-failure/message-failure.component';
|
||||||
|
import { AuthService } from '../services/auth.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-login',
|
||||||
|
templateUrl: './login.component.html',
|
||||||
|
styleUrls: ['./login.component.scss',
|
||||||
|
'./login.component.css']
|
||||||
|
})
|
||||||
|
export class LoginComponent implements OnInit, AfterViewInit {
|
||||||
|
@ViewChild('password') public textbox: TextBoxComponent;
|
||||||
|
public initialPassword = true;
|
||||||
|
public passwordVisible = false;
|
||||||
|
public loadingIcon = '';
|
||||||
|
|
||||||
|
public form: FormGroup;
|
||||||
|
public data: any = {
|
||||||
|
email: '',
|
||||||
|
password: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(private authService: AuthService,
|
||||||
|
private router: Router,
|
||||||
|
private dialogService: DialogService,
|
||||||
|
private ngZone: NgZone
|
||||||
|
) {
|
||||||
|
this.form = new FormGroup({
|
||||||
|
password: new FormControl(this.data.password, [Validators.required, Validators.minLength(3)]),
|
||||||
|
email: new FormControl(this.data.email, [
|
||||||
|
Validators.required,
|
||||||
|
]),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private dialog: any;
|
||||||
|
|
||||||
|
public onEnter(event: KeyboardEvent): void {
|
||||||
|
event.preventDefault(); // Evita o envio do formulário padrão
|
||||||
|
if (this.form.valid) {
|
||||||
|
this.submitForm(); // Apenas submete se o formulário for válido
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public submitForm(): void {
|
||||||
|
this.form.markAllAsTouched();
|
||||||
|
if (this.form.valid) {
|
||||||
|
this.loadingIcon = 'loading';
|
||||||
|
const domain = '@jurunense.com.br';
|
||||||
|
let email = this.form.value.email;
|
||||||
|
|
||||||
|
// Remover domínio existente se já foi digitado
|
||||||
|
if (email.toLowerCase().endsWith(domain)) {
|
||||||
|
email = email.substring(0, email.length - domain.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
const emailUpperCase = (email + domain).toUpperCase();
|
||||||
|
const passwordUpperCase = this.form.value.password.toUpperCase();
|
||||||
|
|
||||||
|
this.authService.login({
|
||||||
|
email: emailUpperCase,
|
||||||
|
password: passwordUpperCase
|
||||||
|
})
|
||||||
|
.subscribe((res: ResultApi) => {
|
||||||
|
if (res.success) {
|
||||||
|
this.loadingIcon = '';
|
||||||
|
console.log(JSON.stringify(res.data));
|
||||||
|
this.authService.setDataInLocalStorage('user', JSON.stringify(res.data));
|
||||||
|
this.authService.setDataInLocalStorage('token', res.data.token);
|
||||||
|
localStorage.removeItem('cart');
|
||||||
|
this.router.navigate(['/menu']);
|
||||||
|
} else {
|
||||||
|
this.loadingIcon = '';
|
||||||
|
this.showErrorMessage(res.message);
|
||||||
|
}
|
||||||
|
}, err => {
|
||||||
|
this.loadingIcon = '';
|
||||||
|
this.showErrorMessage(`${err.error.message}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public get isLoading(): boolean {
|
||||||
|
return this.loadingIcon !== '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public clearForm(): void {
|
||||||
|
this.form.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public togglePass(): void {
|
||||||
|
const inputEl = this.textbox.input.nativeElement;
|
||||||
|
|
||||||
|
if (this.initialPassword) {
|
||||||
|
inputEl.type = 'password';
|
||||||
|
this.initialPassword = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inputEl.type === 'password') {
|
||||||
|
inputEl.type = 'text';
|
||||||
|
} else {
|
||||||
|
inputEl.type = 'password';
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(this.form.controls.password.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
getUserName() {
|
||||||
|
return this.authService.getUserName();
|
||||||
|
}
|
||||||
|
|
||||||
|
showErrorMessage(message: string) {
|
||||||
|
console.log('mensagem de erro', message);
|
||||||
|
const dialogRef = this.dialogService
|
||||||
|
.open({
|
||||||
|
title: 'Error',
|
||||||
|
content: MessageFailureComponent,
|
||||||
|
actions: [{ text: 'OK', primary: true }],
|
||||||
|
width: 400,
|
||||||
|
height: 250,
|
||||||
|
minWidth: 250,
|
||||||
|
});
|
||||||
|
|
||||||
|
const messageInfo = dialogRef.content.instance;
|
||||||
|
messageInfo.message = message;
|
||||||
|
this.ngZone.run(() => {
|
||||||
|
dialogRef.result.subscribe();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ngOnInit(): void { }
|
||||||
|
|
||||||
|
public ngAfterViewInit(): void {
|
||||||
|
this.textbox.input.nativeElement.type = 'password';
|
||||||
|
}
|
||||||
|
|
||||||
|
public toggleVisibility(): void {
|
||||||
|
const inputEl = this.textbox.input.nativeElement;
|
||||||
|
this.passwordVisible = !this.passwordVisible;
|
||||||
|
inputEl.type = this.passwordVisible ? 'text' : 'password';
|
||||||
|
}
|
||||||
|
}
|
||||||
42
src/app/auth/register/register.component.html
Normal file
42
src/app/auth/register/register.component.html
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<div class="example">
|
||||||
|
<form class="k-form" [formGroup]="form">
|
||||||
|
<h5 class="text-center">CADASTRO DE NOVO USUARIO</h5>
|
||||||
|
<kendo-formfield>
|
||||||
|
<kendo-label [for]="email" text="Email"></kendo-label>
|
||||||
|
<kendo-textbox
|
||||||
|
formControlName="email"
|
||||||
|
[clearButton]="true"
|
||||||
|
#email
|
||||||
|
required
|
||||||
|
></kendo-textbox>
|
||||||
|
|
||||||
|
<kendo-formerror *ngIf="form.controls.email.errors?.required"
|
||||||
|
>Error: Email is required</kendo-formerror
|
||||||
|
>
|
||||||
|
<kendo-formerror *ngIf="form.controls.email.errors?.email"
|
||||||
|
>Error: Not valid email format</kendo-formerror
|
||||||
|
>
|
||||||
|
</kendo-formfield>
|
||||||
|
|
||||||
|
<kendo-formfield>
|
||||||
|
<kendo-label [for]="password" text="Senha"></kendo-label>
|
||||||
|
<kendo-textbox
|
||||||
|
formControlName="password"
|
||||||
|
|
||||||
|
[clearButton]="true"
|
||||||
|
#password
|
||||||
|
required
|
||||||
|
></kendo-textbox>
|
||||||
|
|
||||||
|
<kendo-formerror>Error: Password is required</kendo-formerror>
|
||||||
|
</kendo-formfield>
|
||||||
|
|
||||||
|
<div class="k-form-buttons">
|
||||||
|
<button class="k-button k-primary" (click)="submitForm()">
|
||||||
|
Send Reservation Request
|
||||||
|
</button>
|
||||||
|
<button class="k-button" (click)="clearForm()">Clear</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
10
src/app/auth/register/register.component.scss
Normal file
10
src/app/auth/register/register.component.scss
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
.example {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.k-form kendo-label:not(:last-of-type) {
|
||||||
|
flex-direction: column;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
25
src/app/auth/register/register.component.spec.ts
Normal file
25
src/app/auth/register/register.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { RegisterComponent } from './register.component';
|
||||||
|
|
||||||
|
describe('RegisterComponent', () => {
|
||||||
|
let component: RegisterComponent;
|
||||||
|
let fixture: ComponentFixture<RegisterComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ RegisterComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(RegisterComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
60
src/app/auth/register/register.component.ts
Normal file
60
src/app/auth/register/register.component.ts
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { FormControl, FormGroup, Validators } from '@angular/forms';
|
||||||
|
import { AuthService } from '../services/auth.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-register',
|
||||||
|
templateUrl: './register.component.html',
|
||||||
|
styleUrls: ['./register.component.scss']
|
||||||
|
})
|
||||||
|
export class RegisterComponent implements OnInit {
|
||||||
|
|
||||||
|
public form: FormGroup;
|
||||||
|
public errorMessage: string;
|
||||||
|
public successMessage: string;
|
||||||
|
|
||||||
|
public data: any = {
|
||||||
|
email: '',
|
||||||
|
password: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(private authService: AuthService) {
|
||||||
|
this.form = new FormGroup({
|
||||||
|
password: new FormControl(this.data.password, [Validators.required, Validators.minLength(3)]),
|
||||||
|
email: new FormControl(this.data.email, [
|
||||||
|
Validators.required,
|
||||||
|
Validators.email,
|
||||||
|
]),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public submitForm(): void {
|
||||||
|
this.form.markAllAsTouched();
|
||||||
|
if (this.form.valid){
|
||||||
|
this.tryRegister({email: this.form.value.email, password: this.form.value.password});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public clearForm(): void {
|
||||||
|
this.form.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
tryRegister(value){
|
||||||
|
/*this.authService.doRegister(value)
|
||||||
|
.then(res => {
|
||||||
|
console.log(res);
|
||||||
|
this.errorMessage = '';
|
||||||
|
this.successMessage = 'Your account has been created';
|
||||||
|
console.log(this.successMessage);
|
||||||
|
}, err => {
|
||||||
|
console.log(err);
|
||||||
|
this.errorMessage = err.message;
|
||||||
|
this.successMessage = '';
|
||||||
|
console.log(err.code + ' - ' + this.errorMessage);
|
||||||
|
});*/
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
16
src/app/auth/services/auth.service.spec.ts
Normal file
16
src/app/auth/services/auth.service.spec.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AuthService } from './auth.service';
|
||||||
|
|
||||||
|
describe('AuthService', () => {
|
||||||
|
let service: AuthService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({});
|
||||||
|
service = TestBed.inject(AuthService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
183
src/app/auth/services/auth.service.ts
Normal file
183
src/app/auth/services/auth.service.ts
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { ResultApi } from 'src/app/models/result-api.model';
|
||||||
|
import { environment } from 'src/environments/environment';
|
||||||
|
import { AuthUser } from '../../models/auth.user.model';
|
||||||
|
import jwt_decode from 'jwt-decode';
|
||||||
|
import { ModuleSystem } from 'src/app/models/module.model';
|
||||||
|
import { PagesUser } from 'src/app/models/pages-user.model';
|
||||||
|
import { ActionsUser } from 'src/app/models/actions-user.model';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class AuthService {
|
||||||
|
|
||||||
|
private UserAuthenticate = false;
|
||||||
|
public actionsUser: ActionsUser[];
|
||||||
|
|
||||||
|
constructor(public httpClient: HttpClient,
|
||||||
|
public router: Router) { }
|
||||||
|
|
||||||
|
/*doRegister(value){
|
||||||
|
return new Promise<any>((resolve, reject) => {
|
||||||
|
this.afAuth.createUserWithEmailAndPassword(value.email, value.password)
|
||||||
|
.then(res => {
|
||||||
|
resolve(res);
|
||||||
|
}, err => reject(err));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
doEmailAndPasswordLogin(value){
|
||||||
|
return new Promise<any>((resolve, reject) => {
|
||||||
|
this.afAuth
|
||||||
|
.signInWithEmailAndPassword(value.email, value.password)
|
||||||
|
.then(res => {
|
||||||
|
console.log(res);
|
||||||
|
resolve(res);
|
||||||
|
}, err => reject(err));
|
||||||
|
});
|
||||||
|
} */
|
||||||
|
|
||||||
|
login(value: AuthUser): Observable<ResultApi> {
|
||||||
|
return this.httpClient.post<ResultApi>(`${environment.url}auth/login`, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
logout() {
|
||||||
|
localStorage.removeItem('user');
|
||||||
|
localStorage.removeItem('token');
|
||||||
|
this.router.navigate(['login']);
|
||||||
|
}
|
||||||
|
|
||||||
|
authenticate(value: AuthUser): Observable<ResultApi> {
|
||||||
|
return this.httpClient.post<ResultApi>(`${environment.url}auth/authenticate`, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
getDiscount(id: number = 0): Observable<ResultApi> {
|
||||||
|
const data = localStorage.getItem('user');
|
||||||
|
const user = JSON.parse(data);
|
||||||
|
const token = this.getToken();
|
||||||
|
const headers = new HttpHeaders().set('Authorization', `Basic ${token}`);
|
||||||
|
let userId = user.id;
|
||||||
|
if (id > 0){
|
||||||
|
userId = id;
|
||||||
|
}
|
||||||
|
return this.httpClient.get<ResultApi>(`${environment.url}auth/discount-user/${userId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
getModules(id: number) {
|
||||||
|
const data = localStorage.getItem('user');
|
||||||
|
const user = JSON.parse(data);
|
||||||
|
const token = this.getToken();
|
||||||
|
const headers = new HttpHeaders().set('Authorization', `Basic ${token}`);
|
||||||
|
let userId = user.id;
|
||||||
|
if (id > 0){
|
||||||
|
userId = id;
|
||||||
|
}
|
||||||
|
return this.httpClient.get<ModuleSystem[]>(`${environment.url}access-control/modules/${userId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
getPagesUser(moduleId: number) {
|
||||||
|
const data = localStorage.getItem('user');
|
||||||
|
const user = JSON.parse(data);
|
||||||
|
const token = this.getToken();
|
||||||
|
const headers = new HttpHeaders().set('Authorization', `Basic ${token}`);
|
||||||
|
|
||||||
|
return this.httpClient.get<PagesUser[]>(`${environment.url}access-control/pages/${user.id}/${moduleId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
getActionsUser(moduleId: number) {
|
||||||
|
const data = localStorage.getItem('user');
|
||||||
|
const user = JSON.parse(data);
|
||||||
|
const token = this.getToken();
|
||||||
|
const headers = new HttpHeaders().set('Authorization', `Basic ${token}`);
|
||||||
|
return this.httpClient.get<ActionsUser[]>(`${environment.url}access-control/actions/${user.id}/${moduleId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
setDataInLocalStorage(variableName: string, data: any) {
|
||||||
|
localStorage.setItem(variableName, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
getToken() {
|
||||||
|
return localStorage.getItem('token');
|
||||||
|
}
|
||||||
|
|
||||||
|
getPayload() {
|
||||||
|
try {
|
||||||
|
return jwt_decode(this.getToken()) as any;
|
||||||
|
} catch (Error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isManager() {
|
||||||
|
const data = this.getPayload();
|
||||||
|
console.log(JSON.stringify(data));
|
||||||
|
return data.sectorId.toString() === data.sectorManagerId.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
getUserName() {
|
||||||
|
const data = localStorage.getItem('user');
|
||||||
|
const user = JSON.parse(data);
|
||||||
|
return user.username;
|
||||||
|
}
|
||||||
|
|
||||||
|
getStoreName() {
|
||||||
|
const data = localStorage.getItem('user');
|
||||||
|
const user = JSON.parse(data);
|
||||||
|
return user.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
getUser() {
|
||||||
|
const data = localStorage.getItem('user');
|
||||||
|
const user = JSON.parse(data);
|
||||||
|
return user.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
getSeller() {
|
||||||
|
const data = localStorage.getItem('user');
|
||||||
|
const user = JSON.parse(data);
|
||||||
|
return user.seller;
|
||||||
|
}
|
||||||
|
|
||||||
|
getSupervisor() {
|
||||||
|
const data = localStorage.getItem('user');
|
||||||
|
const user = JSON.parse(data);
|
||||||
|
return user.supervisorId;
|
||||||
|
}
|
||||||
|
|
||||||
|
getStore() {
|
||||||
|
const data = localStorage.getItem('user');
|
||||||
|
const user = JSON.parse(data);
|
||||||
|
return user.store;
|
||||||
|
}
|
||||||
|
|
||||||
|
getDeliveryTime() {
|
||||||
|
const data = localStorage.getItem('user');
|
||||||
|
const user = JSON.parse(data);
|
||||||
|
return user.deliveryTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteDataLocalStorage(variableName: string) {
|
||||||
|
localStorage.removeItem(variableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
isAuthenticate(){
|
||||||
|
console.log(localStorage.getItem('token'));
|
||||||
|
return localStorage.getItem('token') != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
userAction(processId: number, pageId: number, actionId: number) {
|
||||||
|
const actionUser = this.actionsUser
|
||||||
|
.find(action => action.moduleId == 2 &&
|
||||||
|
action.processId == processId &&
|
||||||
|
action.pageId == pageId &&
|
||||||
|
action.actionId == actionId &&
|
||||||
|
action.access == "S" );
|
||||||
|
console.log(this.actionsUser);
|
||||||
|
return actionUser !== undefined && actionUser!== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
25
src/app/components/component.module.ts
Normal file
25
src/app/components/component.module.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { HeaderSystemComponent } from './header-system/header-system.component';
|
||||||
|
import { ReactiveFormsModule, FormsModule } from '@angular/forms';
|
||||||
|
import { KendoModule } from '../shared/kendo.module';
|
||||||
|
import { ProductListItemComponent } from './product-list-item/product-list-item.component';
|
||||||
|
import { ProductModalComponent } from '../sales/components/product-modal/product-modal.component';
|
||||||
|
import { HeaderAdminComponent } from './header-admin/header-admin.component';
|
||||||
|
import { HeaderSalesComponent } from './header-sales/header-sales.component';
|
||||||
|
import { HeaderShoppingComponent } from './header-shopping/header-shopping.component';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [HeaderSystemComponent, ProductListItemComponent, HeaderAdminComponent, HeaderSalesComponent, HeaderShoppingComponent, HeaderShoppingComponent],
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
KendoModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
FormsModule,
|
||||||
|
],
|
||||||
|
exports: [HeaderSystemComponent, ProductListItemComponent, HeaderAdminComponent, HeaderSalesComponent, HeaderShoppingComponent],
|
||||||
|
schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
|
||||||
|
})
|
||||||
|
export class ComponentModule { }
|
||||||
39
src/app/components/header-admin/header-admin.component.html
Normal file
39
src/app/components/header-admin/header-admin.component.html
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<header class="header-productlist fixed-top">
|
||||||
|
<div class="container d-flex justify-content-between align-items-center py-3">
|
||||||
|
<!-- Logo à esquerda -->
|
||||||
|
<div class="logo-jurunense">
|
||||||
|
<a href="/#/menu" title="Jurunenese">
|
||||||
|
<img [src]="imageLogoBase64" alt="Imagem" class="img-fluid" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Informações do usuário à direita -->
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<!-- Dados do usuário -->
|
||||||
|
<div class="me-3 text-end">
|
||||||
|
<span class="name-user d-block">{{ userName }}</span>
|
||||||
|
<span class="last-access d-block">Loja: {{ storeName }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Dropdown de configurações -->
|
||||||
|
<div class="dropdown">
|
||||||
|
<a
|
||||||
|
class="nav-link dropdown-toggle"
|
||||||
|
href="#"
|
||||||
|
id="navbarDropdownMenuLink"
|
||||||
|
role="button"
|
||||||
|
data-bs-toggle="dropdown"
|
||||||
|
aria-expanded="false"
|
||||||
|
>
|
||||||
|
<img src="assets/img/config.svg" alt="Configurações" class="img-config" />
|
||||||
|
</a>
|
||||||
|
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdownMenuLink">
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item" (click)="logout()">Sair</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
190
src/app/components/header-admin/header-admin.component.scss
Normal file
190
src/app/components/header-admin/header-admin.component.scss
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
.wrapper {
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-productlist {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 10px 64px;
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
height: 80px;
|
||||||
|
top: 0;
|
||||||
|
background: #131d52;
|
||||||
|
color: #fff;
|
||||||
|
|
||||||
|
.logo-jurunense {
|
||||||
|
img {
|
||||||
|
max-height: 50px;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.name-user {
|
||||||
|
font-family: "Open Sans", sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 19px;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.last-access {
|
||||||
|
font-family: "Open Sans", sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 16px;
|
||||||
|
color: #848484;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-toggle {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-height: 24px;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu {
|
||||||
|
background-color: #2d2e83;
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #fff;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #ef7d00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Footer */
|
||||||
|
.home-footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 46px;
|
||||||
|
background: #131d52;
|
||||||
|
|
||||||
|
.text-footer {
|
||||||
|
font-family: "Open Sans", sans-serif;
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 14px;
|
||||||
|
text-align: center;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Buttons */
|
||||||
|
.new-order {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
background: #ff9521;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
.text-button {
|
||||||
|
font-family: "Open Sans", sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 22px;
|
||||||
|
text-align: center;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-flat {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid #ef7d00;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
.text-button-flat {
|
||||||
|
font-family: "Open Sans", sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 22px;
|
||||||
|
text-align: center;
|
||||||
|
color: #ef7d00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-flat-blue {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid #2d2e83;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
.text-button-flat-blue {
|
||||||
|
font-family: "Open Sans", sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 22px;
|
||||||
|
text-align: center;
|
||||||
|
color: #2d2e83;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsividade */
|
||||||
|
|
||||||
|
/* Smartphones */
|
||||||
|
@media (max-width: 575.98px) {
|
||||||
|
.header-productlist {
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
.logo-jurunense img {
|
||||||
|
max-width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name-user {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.last-access {
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-order .text-button,
|
||||||
|
.button-flat .text-button-flat,
|
||||||
|
.button-flat-blue .text-button-flat-blue {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tablets */
|
||||||
|
@media (max-width: 991.98px) {
|
||||||
|
.header-productlist {
|
||||||
|
padding: 10px 20px;
|
||||||
|
|
||||||
|
.logo-jurunense img {
|
||||||
|
max-width: 150px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Desktops */
|
||||||
|
@media (min-width: 992px) {
|
||||||
|
.logo-jurunense img {
|
||||||
|
max-width: 170px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { HeaderAdminComponent } from './header-admin.component';
|
||||||
|
|
||||||
|
describe('HeaderAdminComponent', () => {
|
||||||
|
let component: HeaderAdminComponent;
|
||||||
|
let fixture: ComponentFixture<HeaderAdminComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ HeaderAdminComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(HeaderAdminComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
37
src/app/components/header-admin/header-admin.component.ts
Normal file
37
src/app/components/header-admin/header-admin.component.ts
Normal file
File diff suppressed because one or more lines are too long
42
src/app/components/header-sales/header-sales.component.html
Normal file
42
src/app/components/header-sales/header-sales.component.html
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<header class="header-productlist fixed-top">
|
||||||
|
<div class="container d-flex justify-content-between align-items-center py-3">
|
||||||
|
<!-- Logo -->
|
||||||
|
<div class="logo-jurunense">
|
||||||
|
<a href="/#/menu" title="Jurunense">
|
||||||
|
<img [src]="imageLogoBase64" alt="Logo Jurunense" class="img-fluid" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Informações do usuário -->
|
||||||
|
<div class="user-info d-flex align-items-center">
|
||||||
|
<!-- Nome do usuário e loja -->
|
||||||
|
<div class="user-details me-3 text-end">
|
||||||
|
<span class="name-user d-block">{{ userName }}</span>
|
||||||
|
<span class="last-access d-block">Loja: {{ storeName }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Carrinho -->
|
||||||
|
<div class="cart me-3 text-center">
|
||||||
|
<kendo-badge-container>
|
||||||
|
<img src="assets/img/cart.svg" alt="Carrinho" class="cart-icon" data-bs-toggle="offcanvas"
|
||||||
|
data-bs-target="#offcanvasRight" aria-controls="offcanvasRight" />
|
||||||
|
<kendo-badge [align]="align" [position]="position" [themeColor]="themeBadge">{{ (shoppingItems$ |
|
||||||
|
async)?.length || 0 }}</kendo-badge>
|
||||||
|
</kendo-badge-container>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Dropdown de configurações -->
|
||||||
|
<div class="dropdown">
|
||||||
|
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" role="button"
|
||||||
|
data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
|
<img src="assets/img/config.svg" alt="Configurações" class="img-config" />
|
||||||
|
</a>
|
||||||
|
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdownMenuLink">
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item" (click)="logout()">Sair</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
85
src/app/components/header-sales/header-sales.component.scss
Normal file
85
src/app/components/header-sales/header-sales.component.scss
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
.header-productlist {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 10px 64px;
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
height: 80px;
|
||||||
|
top: 0;
|
||||||
|
background: #131d52;
|
||||||
|
color: #ffffff;
|
||||||
|
z-index: 1000;
|
||||||
|
|
||||||
|
.logo-jurunense img {
|
||||||
|
max-height: 50px;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.user-details {
|
||||||
|
text-align: right;
|
||||||
|
|
||||||
|
.name-user {
|
||||||
|
font-family: "Open Sans", sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 19px;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.last-access {
|
||||||
|
font-family: "Open Sans", sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 16px;
|
||||||
|
color: #848484;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cart {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.cart-icon {
|
||||||
|
max-height: 24px;
|
||||||
|
width: auto;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
kendo-badge {
|
||||||
|
position: absolute;
|
||||||
|
top: -13px;
|
||||||
|
right: -13px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-toggle {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-height: 24px;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu {
|
||||||
|
background-color: #2d2e83;
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #ffffff;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #ef7d00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { HeaderSalesComponent } from './header-sales.component';
|
||||||
|
|
||||||
|
describe('HeaderSalesComponent', () => {
|
||||||
|
let component: HeaderSalesComponent;
|
||||||
|
let fixture: ComponentFixture<HeaderSalesComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ HeaderSalesComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(HeaderSalesComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
54
src/app/components/header-sales/header-sales.component.ts
Normal file
54
src/app/components/header-sales/header-sales.component.ts
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1,205 @@
|
|||||||
|
<header class="header-productlist fixed-top">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row g-0 align-items-center">
|
||||||
|
<!-- Logo and Menu -->
|
||||||
|
<div class="col-6 col-md-2 d-flex align-items-center logo-jurunense">
|
||||||
|
<div class="btn-menu">
|
||||||
|
<button class="menu-toggle me-3 d-flex align-items-center" (click)="openMenu()">
|
||||||
|
<img src="assets/img/menu.svg" alt="Menu" width="24" height="24" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="logo-jurunense">
|
||||||
|
<a href="/#/sales/home" title="Jurunenese">
|
||||||
|
<img [src]="imageLogoBase64" alt="Imagem" class="img-fluid" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Search Section para desktops -->
|
||||||
|
<div class="col-md-8 px-5 d-none d-md-flex">
|
||||||
|
<kendo-textbox class="search-product-desktop" [formControl]="searchProduct"
|
||||||
|
placeholder="Pesquise o produto desejado por aqui" (keydown.enter)="onSearch()">
|
||||||
|
<ng-template kendoTextBoxSuffixTemplate>
|
||||||
|
<button kendoButton fillMode="clear" icon="search" (click)="onSearch()"></button>
|
||||||
|
</ng-template>
|
||||||
|
</kendo-textbox>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- User Info and Cart -->
|
||||||
|
<div class="col-6 col-md-2 d-flex justify-content-end align-items-center">
|
||||||
|
<!-- Carrinho -->
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<kendo-badge-container>
|
||||||
|
<img src="assets/img/cart.svg" alt="Carrinho" data-bs-toggle="offcanvas"
|
||||||
|
data-bs-target="#offcanvasRight" aria-controls="offcanvasRight" />
|
||||||
|
<kendo-badge [align]="align" [position]="position" [themeColor]="themeBadge">
|
||||||
|
{{ (shopping$ | async).length }}
|
||||||
|
</kendo-badge>
|
||||||
|
</kendo-badge-container>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Avatar com dropdown para dispositivos móveis -->
|
||||||
|
<!-- <div class="info-user">
|
||||||
|
<div class="dropdown ms-3">
|
||||||
|
<button class="btn dropdown-toggle p-0" id="userMenuDropdown" type="button"
|
||||||
|
data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
|
<kendo-avatar [imageSrc]="'https://i.pravatar.cc/150?img=7'" [size]="'medium'"
|
||||||
|
[shape]="'circle'" title="{{ userName }}"></kendo-avatar>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="userMenuDropdown">
|
||||||
|
<li class="dropdown-header">
|
||||||
|
<span class="username"><strong>{{ userName }}</strong></span>
|
||||||
|
<div class="text-muted"><span class="loja">Loja: {{ storeName }}</span></div>
|
||||||
|
</li>
|
||||||
|
<hr>
|
||||||
|
<li><a class="dropdown-item" href="/#/profile">Perfil</a></li>
|
||||||
|
<li><a class="dropdown-item" href="/#/settings">Configurações</a></li>
|
||||||
|
<li><a class="dropdown-item" (click)="logout()">Sair</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Nome do usuário e loja -->
|
||||||
|
<div class="user-details me-3 text-end">
|
||||||
|
<span class="name-user d-block">{{ userName }}</span>
|
||||||
|
<span class="last-access d-block">Loja: {{ storeName }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Dropdown de configurações -->
|
||||||
|
<div class="dropdown">
|
||||||
|
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" role="button"
|
||||||
|
data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
|
<img src="assets/img/config.svg" alt="Configurações" class="img-config" />
|
||||||
|
</a>
|
||||||
|
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdownMenuLink">
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item" (click)="logout()">Sair</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Search Section para dispositivos móveis e tablets -->
|
||||||
|
<div class="col-12 mt-3">
|
||||||
|
<kendo-textbox class="search-product" [formControl]="searchProduct"
|
||||||
|
placeholder="Pesquise o produto desejado por aqui" (keydown.enter)="onSearch()">
|
||||||
|
<ng-template kendoTextBoxSuffixTemplate>
|
||||||
|
<button kendoButton fillMode="clear" icon="search" (click)="onSearch()"></button>
|
||||||
|
</ng-template>
|
||||||
|
</kendo-textbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Modal de Menu -->
|
||||||
|
<div class="menu-modal" [ngClass]="{'open': isMenuOpen, 'close': !isMenuOpen}">
|
||||||
|
<div class="menu-content">
|
||||||
|
<!-- Cabeçalho do Modal -->
|
||||||
|
<div class="menu-header">
|
||||||
|
<div class="user-info">
|
||||||
|
<img src="https://via.placeholder.com/64" alt="Avatar" class="user-avatar" />
|
||||||
|
<div class="user-text">
|
||||||
|
<span class="bold-text">{{ userName }}</span>
|
||||||
|
<span class="subtitle">Loja: {{ storeName }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button class="close-btn" (click)="closeMenu()">×</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Botões de Entrar e Cadastrar -->
|
||||||
|
<div class="menu-buttons">
|
||||||
|
<button class="btn-enter" (click)="logout()">Sair</button>
|
||||||
|
<button class="btn-register" (click)="closeMenu()">Voltar</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Lista de Links -->
|
||||||
|
<ul class="menu-links">
|
||||||
|
<!-- <li>
|
||||||
|
<a href="#">Nossas lojas</a>
|
||||||
|
<i class="fa-solid fa-chevron-right icon"></i>
|
||||||
|
</li>
|
||||||
|
<hr /> -->
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/#/product-list" (click)="applyFilter({ urlCategory: [] })"><strong>Todos os
|
||||||
|
departamentos</strong></a>
|
||||||
|
<i class="fa-solid fa-chevron-right icon"></i>
|
||||||
|
</li>
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<!-- Lista Dinâmica -->
|
||||||
|
<li *ngFor="let department of departments">
|
||||||
|
<a href="/#/product-list" (click)="applyFilter({ urlCategory: department.path })">{{ department.text
|
||||||
|
}}</a>
|
||||||
|
<i class="fa-solid fa-chevron-right icon"></i>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<!-- Filtros Adicionais -->
|
||||||
|
<div class="menu-filters">
|
||||||
|
<legend class="k-form-legend mt-3">Marcas</legend>
|
||||||
|
<div *ngIf="brands && brands.length > 0">
|
||||||
|
<kendo-treeview kendoTreeViewHierarchyBinding [nodes]="brands" textField="text"
|
||||||
|
[kendoTreeViewCheckable]="{ mode: 'multiple' }" [(checkedKeys)]="selectedBrandKeys"
|
||||||
|
(checkedChange)="applyFilter({ brands: selectedBrandKeys })">
|
||||||
|
</kendo-treeview>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Filtros Gerais -->
|
||||||
|
<div class="filters-section">
|
||||||
|
<legend class="k-form-legend mt-3">Filtros</legend>
|
||||||
|
|
||||||
|
<label class="k-label d-block">
|
||||||
|
<input type="checkbox" kendoCheckBox [(ngModel)]="onlyWithStock" />
|
||||||
|
<span class="ms-2">Somente produtos com estoque</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label class="k-label d-block mt-2">
|
||||||
|
<span>Filial de estoque</span>
|
||||||
|
<kendo-combobox [data]="store$ | async" textField="id" valueField="id"
|
||||||
|
(selectionChange)="selectedStore($event)">
|
||||||
|
</kendo-combobox>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label class="k-label d-block mt-2">
|
||||||
|
<input type="checkbox" kendoCheckBox [(ngModel)]="productPromotion" />
|
||||||
|
<span class="ms-2">Produtos em promoção</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label class="k-label d-block mt-2">
|
||||||
|
<span>Faixa de desconto</span>
|
||||||
|
<kendo-rangeslider [(ngModel)]="percentOff" [min]="minPercentOff" [max]="maxPercentOff"
|
||||||
|
[smallStep]="smallStep" [largeStep]="largeStep">
|
||||||
|
</kendo-rangeslider>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label class="k-label d-block mt-2">
|
||||||
|
<input type="checkbox" kendoCheckBox [(ngModel)]="markdown" />
|
||||||
|
<span class="ms-2">Produtos que baixaram de preço</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label class="k-label d-block mt-2">
|
||||||
|
<input type="checkbox" kendoCheckBox [(ngModel)]="oportunity" />
|
||||||
|
<span class="ms-2">Oportunidades</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label class="k-label d-block mt-2">
|
||||||
|
<input type="checkbox" kendoCheckBox [(ngModel)]="offers" />
|
||||||
|
<span class="ms-2">Ofertas imperdíveis</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<!-- Botão de Aplicar -->
|
||||||
|
<div class="apply-filters mt-4">
|
||||||
|
<button kendoButton class="w-100" (click)="getFilterProducts()">
|
||||||
|
Aplicar Filtros
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
@@ -0,0 +1,490 @@
|
|||||||
|
.header-productlist {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 10px 16px;
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
top: 0;
|
||||||
|
background: #131d52;
|
||||||
|
color: #ffffff;
|
||||||
|
z-index: 1000;
|
||||||
|
|
||||||
|
.menu-toggle {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-product {
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 0 10px;
|
||||||
|
background-color: #ffffff;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name-user {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
kendo-badge {
|
||||||
|
position: absolute;
|
||||||
|
top: -11px;
|
||||||
|
right: -11px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.last-access {
|
||||||
|
font-size: 10px;
|
||||||
|
color: #848484;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-content {
|
||||||
|
position: absolute;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
padding: 10px;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu {
|
||||||
|
background-color: #2d2e83;
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
.dropdown-item {
|
||||||
|
color: #ffffff;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #ef7d00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-menu {
|
||||||
|
padding: 1px;
|
||||||
|
display: flex;
|
||||||
|
border: none;
|
||||||
|
background-color: transparent;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
margin-right: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loja {
|
||||||
|
font-size: 11px;
|
||||||
|
color: #f4f4f4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Modal Fullscreen */
|
||||||
|
.menu-modal {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #fff;
|
||||||
|
z-index: 1050;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
transform: translateX(-100%);
|
||||||
|
transition: transform 0.5s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Classe para abrir o modal */
|
||||||
|
.menu-modal.open {
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Classe para fechar o modal */
|
||||||
|
.menu-modal.close {
|
||||||
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Conteúdo do Menu */
|
||||||
|
.menu-content {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
padding: 20px;
|
||||||
|
overflow-y: auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cabeçalho do Menu */
|
||||||
|
.menu-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-avatar {
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-text {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bold-text {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitle {
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Botões: Entrar e Cadastrar */
|
||||||
|
.menu-buttons {
|
||||||
|
display: flex;
|
||||||
|
/* Flexbox para alinhar os botões */
|
||||||
|
justify-content: space-between;
|
||||||
|
/* Espaço entre os botões */
|
||||||
|
gap: 10px;
|
||||||
|
/* Espaçamento entre os botões */
|
||||||
|
width: 100%;
|
||||||
|
/* Ocupa 100% da largura */
|
||||||
|
margin: 10px 0;
|
||||||
|
/* Espaçamento acima e abaixo */
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-enter,
|
||||||
|
.btn-register {
|
||||||
|
flex: 1;
|
||||||
|
/* Cada botão ocupa a mesma largura */
|
||||||
|
padding: 10px 0;
|
||||||
|
/* Espaçamento interno vertical */
|
||||||
|
text-align: center;
|
||||||
|
/* Alinhamento do texto */
|
||||||
|
font-size: 16px;
|
||||||
|
/* Tamanho da fonte */
|
||||||
|
font-weight: bold;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-enter {
|
||||||
|
background-color: #131d52;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-register {
|
||||||
|
background: transparent;
|
||||||
|
color: #131d52;
|
||||||
|
border: 2px solid #131d52;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-enter:hover,
|
||||||
|
.btn-register:hover {
|
||||||
|
opacity: 0.9;
|
||||||
|
/* Efeito ao passar o mouse */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lista de Links */
|
||||||
|
.menu-links {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item {
|
||||||
|
// flex-direction: row;
|
||||||
|
flex: 1;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-links li {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
/* Texto à esquerda, ícone à direita */
|
||||||
|
align-items: center;
|
||||||
|
padding: 15px 20px;
|
||||||
|
border-bottom: 1px solid #f1f1f1;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-links li:hover {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
/* Cor ao passar o mouse */
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-links a {
|
||||||
|
text-decoration: none;
|
||||||
|
/* Remove sublinhado */
|
||||||
|
color: #333;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 400;
|
||||||
|
flex-grow: 1;
|
||||||
|
/* Garante que o texto use o espaço restante */
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-links a:hover {
|
||||||
|
color: #131d52;
|
||||||
|
/* Cor principal ao hover */
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-links .icon {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #999;
|
||||||
|
/* Cor do ícone */
|
||||||
|
transition: transform 0.3s ease, color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-links li:hover .icon {
|
||||||
|
color: #131d52;
|
||||||
|
/* Cor ao hover */
|
||||||
|
transform: translateX(5px);
|
||||||
|
/* Desliza o ícone para direita */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
hr {
|
||||||
|
border: 0;
|
||||||
|
border-top: 1px solid #ddd;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Botão de Fechar */
|
||||||
|
.close-btn {
|
||||||
|
font-size: 24px;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Smartphones */
|
||||||
|
@media (max-width: 575.98px) {
|
||||||
|
.header-productlist {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
.menu-toggle {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-jurunense img {
|
||||||
|
max-width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-product {
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
order: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-product-desktop {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name-user,
|
||||||
|
.last-access {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-user-desktop {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-user {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-content {
|
||||||
|
padding: 10px;
|
||||||
|
/* Reduz o padding */
|
||||||
|
font-size: 12px;
|
||||||
|
/* Fonte geral menor */
|
||||||
|
}
|
||||||
|
|
||||||
|
.k-form-legend {
|
||||||
|
font-size: 12px;
|
||||||
|
/* Tamanho menor para legendas */
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-buttons {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-enter,
|
||||||
|
.btn-register {
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lista de marcas */
|
||||||
|
.kendo-treeview {
|
||||||
|
max-height: 200px;
|
||||||
|
/* Reduz altura */
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inputs e checkboxes menores */
|
||||||
|
label.k-label {
|
||||||
|
font-size: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="checkbox"] {
|
||||||
|
transform: scale(0.8);
|
||||||
|
/* Menor */
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
kendo-combobox,
|
||||||
|
kendo-rangeslider {
|
||||||
|
width: 100%;
|
||||||
|
transform: scale(0.85);
|
||||||
|
/* Reduz tamanho */
|
||||||
|
}
|
||||||
|
|
||||||
|
kendo-rangeslider {
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ajusta espaçamento das legendas */
|
||||||
|
legend {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Botão de aplicar filtros */
|
||||||
|
button[kendoButton] {
|
||||||
|
width: 100%;
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-toggle {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tablets */
|
||||||
|
@media (max-width: 991.98px) {
|
||||||
|
.header-productlist {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
.menu-toggle {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-jurunense img {
|
||||||
|
max-width: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-product {
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
order: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-product-desktop {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name-user,
|
||||||
|
.last-access {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-user-desktop {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-user {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
.dropdown-toggle,
|
||||||
|
.user-details {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu,
|
||||||
|
.user-details {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Desktops */
|
||||||
|
@media (min-width: 992px) {
|
||||||
|
.header-productlist {
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
|
||||||
|
.menu-toggle {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-jurunense img {
|
||||||
|
max-width: 170px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-product {
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-bottom: 0;
|
||||||
|
order: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-product {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-menu {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-user {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name-user,
|
||||||
|
.last-access {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { HeaderShoppingComponent } from './header-shopping.component';
|
||||||
|
|
||||||
|
describe('HeaderShoppingComponent', () => {
|
||||||
|
let component: HeaderShoppingComponent;
|
||||||
|
let fixture: ComponentFixture<HeaderShoppingComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ HeaderShoppingComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(HeaderShoppingComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
226
src/app/components/header-shopping/header-shopping.component.ts
Normal file
226
src/app/components/header-shopping/header-shopping.component.ts
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1,48 @@
|
|||||||
|
<header class="header-productlist fixed-top">
|
||||||
|
<div class="container d-flex justify-content-between align-items-center py-3">
|
||||||
|
<!-- Logo à esquerda -->
|
||||||
|
<div class="logo-jurunense">
|
||||||
|
<a href="/" title="Jurunenese">
|
||||||
|
<img [src]="imageLogoBase64" alt="Imagem" class="img-fluid" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Informações do usuário à direita -->
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<!-- Carrinho -->
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<kendo-badge-container>
|
||||||
|
<img src="assets/img/cart.svg" alt="Carrinho" data-bs-toggle="offcanvas"
|
||||||
|
data-bs-target="#offcanvasRight" aria-controls="offcanvasRight" />
|
||||||
|
<kendo-badge [align]="align" [position]="position" [themeColor]="themeBadge">
|
||||||
|
{{ (shopping$ | async).length }}
|
||||||
|
</kendo-badge>
|
||||||
|
</kendo-badge-container>
|
||||||
|
</div>
|
||||||
|
<!-- Dados do usuário -->
|
||||||
|
<div class="me-3 text-end">
|
||||||
|
<span class="name-user d-block">{{ userName }}</span>
|
||||||
|
<span class="last-access d-block">Loja: {{ storeName }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Dropdown de configurações -->
|
||||||
|
<div class="dropdown">
|
||||||
|
<a
|
||||||
|
class="nav-link dropdown-toggle"
|
||||||
|
href="#"
|
||||||
|
id="navbarDropdownMenuLink"
|
||||||
|
role="button"
|
||||||
|
data-bs-toggle="dropdown"
|
||||||
|
aria-expanded="false"
|
||||||
|
>
|
||||||
|
<img src="assets/img/config.svg" alt="Configurações" class="img-config" />
|
||||||
|
</a>
|
||||||
|
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdownMenuLink">
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item" (click)="logout()">Sair</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
197
src/app/components/header-system/header-system.component.scss
Normal file
197
src/app/components/header-system/header-system.component.scss
Normal file
@@ -0,0 +1,197 @@
|
|||||||
|
.wrapper {
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-productlist {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 10px 64px;
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
height: 80px;
|
||||||
|
top: 0;
|
||||||
|
background: #131d52;
|
||||||
|
color: #fff;
|
||||||
|
|
||||||
|
.logo-jurunense {
|
||||||
|
img {
|
||||||
|
max-height: 50px;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.name-user {
|
||||||
|
font-family: "Open Sans", sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 19px;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.last-access {
|
||||||
|
font-family: "Open Sans", sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 16px;
|
||||||
|
color: #848484;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-toggle {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-height: 24px;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu {
|
||||||
|
background-color: #2d2e83;
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #fff;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #ef7d00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Footer */
|
||||||
|
.home-footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 46px;
|
||||||
|
background: #131d52;
|
||||||
|
|
||||||
|
.text-footer {
|
||||||
|
font-family: "Open Sans", sans-serif;
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 14px;
|
||||||
|
text-align: center;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Buttons */
|
||||||
|
.new-order {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
background: #ff9521;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
.text-button {
|
||||||
|
font-family: "Open Sans", sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 22px;
|
||||||
|
text-align: center;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-flat {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid #ef7d00;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
.text-button-flat {
|
||||||
|
font-family: "Open Sans", sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 22px;
|
||||||
|
text-align: center;
|
||||||
|
color: #ef7d00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-flat-blue {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid #2d2e83;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
.text-button-flat-blue {
|
||||||
|
font-family: "Open Sans", sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 22px;
|
||||||
|
text-align: center;
|
||||||
|
color: #2d2e83;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsividade */
|
||||||
|
|
||||||
|
/* Smartphones */
|
||||||
|
@media (max-width: 575.98px) {
|
||||||
|
.header-productlist {
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
.logo-jurunense img {
|
||||||
|
max-width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name-user {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.last-access {
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-order .text-button,
|
||||||
|
.button-flat .text-button-flat,
|
||||||
|
.button-flat-blue .text-button-flat-blue {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
kendo-badge {
|
||||||
|
position: absolute;
|
||||||
|
top: -11px;
|
||||||
|
right: -11px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tablets */
|
||||||
|
@media (max-width: 991.98px) {
|
||||||
|
.header-productlist {
|
||||||
|
padding: 10px 20px;
|
||||||
|
|
||||||
|
.logo-jurunense img {
|
||||||
|
max-width: 150px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Desktops */
|
||||||
|
@media (min-width: 992px) {
|
||||||
|
.logo-jurunense img {
|
||||||
|
max-width: 170px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { HeaderSystemComponent } from './header-system.component';
|
||||||
|
|
||||||
|
describe('HeaderSystemComponent', () => {
|
||||||
|
let component: HeaderSystemComponent;
|
||||||
|
let fixture: ComponentFixture<HeaderSystemComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ HeaderSystemComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(HeaderSystemComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
108
src/app/components/header-system/header-system.component.ts
Normal file
108
src/app/components/header-system/header-system.component.ts
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1,9 @@
|
|||||||
|
<div class="product">
|
||||||
|
<div class="description">
|
||||||
|
<div class="product-name">{{ product.description }}</div>
|
||||||
|
<div class="category-name">{{ product.category }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="price">
|
||||||
|
<div>{{ product.salePrice | currency }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
.product {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
border-bottom-color: #ebebeb;
|
||||||
|
border-bottom-style: solid;
|
||||||
|
z-index: 9999;
|
||||||
|
}
|
||||||
|
.description {
|
||||||
|
flex: 1;
|
||||||
|
z-index: 9999;
|
||||||
|
}
|
||||||
|
.category-name {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.product-name {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
.product-name,
|
||||||
|
.price {
|
||||||
|
height: auto;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.product {
|
||||||
|
padding: 12px;
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/* tslint:disable:no-unused-variable */
|
||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { DebugElement } from '@angular/core';
|
||||||
|
|
||||||
|
import { ProductListItemComponent } from './product-list-item.component';
|
||||||
|
|
||||||
|
describe('ProductListItemComponent', () => {
|
||||||
|
let component: ProductListItemComponent;
|
||||||
|
let fixture: ComponentFixture<ProductListItemComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ProductListItemComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ProductListItemComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
|
import { SaleProduct } from 'src/app/models/sale-product.model';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-product-list-item',
|
||||||
|
templateUrl: './product-list-item.component.html',
|
||||||
|
styleUrls: ['./product-list-item.component.scss']
|
||||||
|
})
|
||||||
|
export class ProductListItemComponent implements OnInit {
|
||||||
|
@Input() public product: SaleProduct;
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
22
src/app/crm/crm-routing.module.ts
Normal file
22
src/app/crm/crm-routing.module.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { Routes, RouterModule } from '@angular/router';
|
||||||
|
import { CustomerComponent } from './customer/customer.component';
|
||||||
|
import { EditCustomerComponent } from './edit-customer/edit-customer.component';
|
||||||
|
import { MenuCrmComponent } from './menu-crm/menu-crm.component';
|
||||||
|
|
||||||
|
|
||||||
|
const routes: Routes = [
|
||||||
|
{
|
||||||
|
path: '', component: MenuCrmComponent,
|
||||||
|
children: [
|
||||||
|
{ path: 'customer', component: CustomerComponent },
|
||||||
|
{ path: 'customer/edit', component: EditCustomerComponent },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [RouterModule.forChild(routes)],
|
||||||
|
exports: [RouterModule]
|
||||||
|
})
|
||||||
|
export class CrmRoutingModule { }
|
||||||
23
src/app/crm/crm.module.ts
Normal file
23
src/app/crm/crm.module.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
|
||||||
|
import { CrmRoutingModule } from './crm-routing.module';
|
||||||
|
import { MenuCrmComponent } from './menu-crm/menu-crm.component';
|
||||||
|
import { ComponentModule } from '../components/component.module';
|
||||||
|
import { CustomerComponent } from './customer/customer.component';
|
||||||
|
import { KendoModule } from '../shared/kendo.module';
|
||||||
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
|
import { EditCustomerComponent } from './edit-customer/edit-customer.component';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [MenuCrmComponent, CustomerComponent, EditCustomerComponent],
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
CrmRoutingModule,
|
||||||
|
ComponentModule,
|
||||||
|
FormsModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
KendoModule,
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class CrmModule { }
|
||||||
94
src/app/crm/customer/customer.component.html
Normal file
94
src/app/crm/customer/customer.component.html
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
<div class="container mt-3 my-5">
|
||||||
|
<div>
|
||||||
|
<span class="title">Lista de clientes</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-2 w-100" class="border-radius: 20px;">
|
||||||
|
<form [formGroup]="searchForm">
|
||||||
|
<kendo-textbox
|
||||||
|
class="w-100 border"
|
||||||
|
placeholder="Informe os dados para localizar os clientes"
|
||||||
|
type="text"
|
||||||
|
formControlName="textSearch"
|
||||||
|
(keydown)="searchCustomer($event)"
|
||||||
|
>
|
||||||
|
<ng-template kendoTextBoxPrefixTemplate>
|
||||||
|
<kendo-icon name="search"></kendo-icon>
|
||||||
|
</ng-template>
|
||||||
|
<ng-template kendoTextBoxSuffixTemplate>
|
||||||
|
<div class="example-wrapper">
|
||||||
|
<kendo-combobox
|
||||||
|
[data]="listItems"
|
||||||
|
style="width: 250px"
|
||||||
|
formControlName="search"
|
||||||
|
>
|
||||||
|
</kendo-combobox>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
</kendo-textbox>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-2">
|
||||||
|
<ng-container>
|
||||||
|
<kendo-grid
|
||||||
|
style="height: calc(100vh - 280px)"
|
||||||
|
[data]="customer$ | async"
|
||||||
|
[pageSize]="20"
|
||||||
|
[pageable]="true"
|
||||||
|
[sortable]="true"
|
||||||
|
[reorderable]="true"
|
||||||
|
[resizable]="true"
|
||||||
|
[columnMenu]="{ filter: true }"
|
||||||
|
>
|
||||||
|
<kendo-grid-column field="customerId" title="Código" [width]="30">
|
||||||
|
<ng-template kendoGridCellTemplate let-dataItem>
|
||||||
|
<div>{{ dataItem.customerId }}</div>
|
||||||
|
</ng-template>
|
||||||
|
</kendo-grid-column>
|
||||||
|
<kendo-grid-column field="name" title="Nome" [width]="150">
|
||||||
|
<ng-template kendoGridCellTemplate let-dataItem>
|
||||||
|
<div>{{ dataItem.name }}</div>
|
||||||
|
</ng-template>
|
||||||
|
</kendo-grid-column>
|
||||||
|
|
||||||
|
<kendo-grid-column field="cpfcnpj" title="CPF / CNPJ" [width]="60">
|
||||||
|
<ng-template kendoGridCellTemplate let-dataItem>
|
||||||
|
<div>{{ dataItem.cpfCnpj }}</div>
|
||||||
|
</ng-template>
|
||||||
|
</kendo-grid-column>
|
||||||
|
|
||||||
|
<kendo-grid-column field="phone" title="Telefone" [width]="60">
|
||||||
|
<ng-template kendoGridCellTemplate let-dataItem>
|
||||||
|
<div>{{ dataItem.phone }}</div>
|
||||||
|
</ng-template>
|
||||||
|
</kendo-grid-column>
|
||||||
|
|
||||||
|
<kendo-grid-column field="cellPhone" title="Celular" [width]="60">
|
||||||
|
<ng-template kendoGridCellTemplate let-dataItem>
|
||||||
|
<div>{{ dataItem.cellPhone }}</div>
|
||||||
|
</ng-template>
|
||||||
|
</kendo-grid-column>
|
||||||
|
<kendo-grid-column field="cellPhone" title="Ações" [width]="50">
|
||||||
|
<ng-template kendoGridCellTemplate let-dataItem>
|
||||||
|
<div>
|
||||||
|
<a href="/crm/customer/edit">
|
||||||
|
<kendo-avatar shape="circle" initials="">
|
||||||
|
<kendo-icon name="edit"></kendo-icon>
|
||||||
|
</kendo-avatar>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
</kendo-grid-column>
|
||||||
|
</kendo-grid>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<kendo-floatingactionbutton
|
||||||
|
icon="add"
|
||||||
|
text="Novo cliente"
|
||||||
|
[align]="{ horizontal: 'end', vertical: 'bottom' }"
|
||||||
|
positionMode="absolute"
|
||||||
|
>
|
||||||
|
</kendo-floatingactionbutton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
13
src/app/crm/customer/customer.component.scss
Normal file
13
src/app/crm/customer/customer.component.scss
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
.title {
|
||||||
|
width: 810px;
|
||||||
|
height: 49px;
|
||||||
|
|
||||||
|
font-family: Montserrat;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: 40px;
|
||||||
|
line-height: 49px;
|
||||||
|
color: rgba(107, 110, 190, 1);
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
25
src/app/crm/customer/customer.component.spec.ts
Normal file
25
src/app/crm/customer/customer.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { CustomerComponent } from './customer.component';
|
||||||
|
|
||||||
|
describe('CustomerComponent', () => {
|
||||||
|
let component: CustomerComponent;
|
||||||
|
let fixture: ComponentFixture<CustomerComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ CustomerComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(CustomerComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
55
src/app/crm/customer/customer.component.ts
Normal file
55
src/app/crm/customer/customer.component.ts
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
|
||||||
|
import { FabAlign } from '@progress/kendo-angular-buttons';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { Customer } from 'src/app/models/customer.model';
|
||||||
|
import { CustomerService } from 'src/app/services/customer.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-customer',
|
||||||
|
templateUrl: './customer.component.html',
|
||||||
|
styleUrls: ['./customer.component.scss']
|
||||||
|
})
|
||||||
|
export class CustomerComponent implements OnInit {
|
||||||
|
public listItems: Array<string> = [
|
||||||
|
'Nome',
|
||||||
|
'CPF',
|
||||||
|
'Telefone',
|
||||||
|
'Celular'
|
||||||
|
];
|
||||||
|
public listFields: Array<string> = [
|
||||||
|
'name',
|
||||||
|
'document',
|
||||||
|
'phone',
|
||||||
|
'cellPhone'
|
||||||
|
];
|
||||||
|
public topEnd: FabAlign = { vertical: 'top', horizontal: 'end' };
|
||||||
|
customer$: Observable<Customer[]>;
|
||||||
|
public errorObject = null;
|
||||||
|
public isloading = false;
|
||||||
|
public searchForm: FormGroup;
|
||||||
|
|
||||||
|
constructor(private customerService: CustomerService) {
|
||||||
|
this.searchForm = new FormGroup({
|
||||||
|
search: new FormControl(),
|
||||||
|
textSearch: new FormControl(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
searchCustomer(event){
|
||||||
|
if (event.keyCode === 13) {
|
||||||
|
console.log(this.searchForm.value);
|
||||||
|
const indice = this.listItems.indexOf(this.searchForm.get('search').value);
|
||||||
|
const field = this.listFields[indice];
|
||||||
|
const textSearh = this.searchForm.get('textSearch').value;
|
||||||
|
this.customer$ = this.customerService.getCustomerByQuery(field, textSearh);
|
||||||
|
// const filter: FilterProduct = { brands: [], text: this.searchProduct.value };
|
||||||
|
// this.getSaleProducts(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
200
src/app/crm/edit-customer/edit-customer.component.html
Normal file
200
src/app/crm/edit-customer/edit-customer.component.html
Normal file
@@ -0,0 +1,200 @@
|
|||||||
|
<div class="container">
|
||||||
|
<form
|
||||||
|
class="k-form m-3 p-3"
|
||||||
|
style="background-color: white"
|
||||||
|
[formGroup]="form"
|
||||||
|
>
|
||||||
|
<fieldset class="k-form-fieldset">
|
||||||
|
<legend class="k-form-legend">Cadastro de cliente</legend>
|
||||||
|
|
||||||
|
<div class="col-12 col-sm-12 col-md-8">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 col-sm-6 col-md-6">
|
||||||
|
<kendo-formfield>
|
||||||
|
<kendo-label [for]="cpf" text="CPF / CNPJ"></kendo-label>
|
||||||
|
<kendo-textbox
|
||||||
|
formControlName="username"
|
||||||
|
#cpf
|
||||||
|
required
|
||||||
|
></kendo-textbox>
|
||||||
|
<kendo-formerror
|
||||||
|
>Error: Número do CPF é obrigatório</kendo-formerror
|
||||||
|
>
|
||||||
|
</kendo-formfield>
|
||||||
|
</div>
|
||||||
|
<div class="ccol-12 col-sm-6 col-md-6">
|
||||||
|
<kendo-formfield>
|
||||||
|
<kendo-label [for]="ie" text="Insc Estadual"></kendo-label>
|
||||||
|
<kendo-textbox formControlName="numberState" #ie></kendo-textbox>
|
||||||
|
</kendo-formfield>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-12 col-sm-12 col-md-6">
|
||||||
|
<kendo-formfield>
|
||||||
|
<kendo-label [for]="name" text="Nome"></kendo-label>
|
||||||
|
<kendo-textbox
|
||||||
|
formControlName="name"
|
||||||
|
[clearButton]="true"
|
||||||
|
#name
|
||||||
|
required
|
||||||
|
></kendo-textbox>
|
||||||
|
<kendo-formerror
|
||||||
|
>Error: O nome do cliente é obrigatório</kendo-formerror
|
||||||
|
>
|
||||||
|
</kendo-formfield>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-6 col-sm-6 col-md-6">
|
||||||
|
<kendo-formfield>
|
||||||
|
<kendo-label [for]="phone" text="Telefone"></kendo-label>
|
||||||
|
<kendo-textbox formControlName="cellPhone" #phone></kendo-textbox>
|
||||||
|
</kendo-formfield>
|
||||||
|
|
||||||
|
<kendo-formfield>
|
||||||
|
<div class="k-form-field-checkbox-wrap">
|
||||||
|
<input
|
||||||
|
kendoCheckBox
|
||||||
|
id="whatsapp1"
|
||||||
|
type="checkbox"
|
||||||
|
formControlName="whatsapp"
|
||||||
|
/>
|
||||||
|
<kendo-label
|
||||||
|
class="k-checkbox-label"
|
||||||
|
for="whatsapp1"
|
||||||
|
text="Telefone cadastrado no whatsapp?"
|
||||||
|
></kendo-label>
|
||||||
|
</div>
|
||||||
|
</kendo-formfield>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-12 col-sm-12 col-md-8">
|
||||||
|
<kendo-formfield>
|
||||||
|
<kendo-label [for]="email" text="E-Mail"></kendo-label>
|
||||||
|
<kendo-textbox
|
||||||
|
formControlName="email"
|
||||||
|
[clearButton]="true"
|
||||||
|
#email
|
||||||
|
required
|
||||||
|
></kendo-textbox>
|
||||||
|
<kendo-formerror>Error: Informe um email do cliente</kendo-formerror>
|
||||||
|
</kendo-formfield>
|
||||||
|
</div>
|
||||||
|
<legend class="k-form-legend mt-5">Endereço</legend>
|
||||||
|
<div class="col-6 col-sm-3 col-md-2">
|
||||||
|
<kendo-formfield>
|
||||||
|
<kendo-label [for]="zipcode" text="CEP"></kendo-label>
|
||||||
|
<kendo-textbox
|
||||||
|
formControlName="cep"
|
||||||
|
#zipcode
|
||||||
|
required
|
||||||
|
></kendo-textbox>
|
||||||
|
<kendo-formerror
|
||||||
|
>Error: Informe um CEP para o endereço do cliente</kendo-formerror
|
||||||
|
>
|
||||||
|
</kendo-formfield>
|
||||||
|
</div>
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-8">
|
||||||
|
<kendo-formfield>
|
||||||
|
<kendo-label [for]="address" text="Endereço"></kendo-label>
|
||||||
|
<kendo-textbox
|
||||||
|
formControlName="address"
|
||||||
|
#address
|
||||||
|
required
|
||||||
|
></kendo-textbox>
|
||||||
|
<kendo-formerror
|
||||||
|
>Error: Informe o endereço do cliente</kendo-formerror
|
||||||
|
>
|
||||||
|
</kendo-formfield>
|
||||||
|
</div>
|
||||||
|
<div class="col-4">
|
||||||
|
<kendo-formfield>
|
||||||
|
<kendo-label [for]="number" text="Número"></kendo-label>
|
||||||
|
<kendo-textbox
|
||||||
|
formControlName="addressNumber"
|
||||||
|
#number
|
||||||
|
required
|
||||||
|
></kendo-textbox>
|
||||||
|
<kendo-formerror
|
||||||
|
>Error: Informe o número do endereço do cliente</kendo-formerror
|
||||||
|
>
|
||||||
|
</kendo-formfield>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-8">
|
||||||
|
<kendo-formfield>
|
||||||
|
<kendo-label [for]="neighborhood" text="Bairro"></kendo-label>
|
||||||
|
<kendo-textbox
|
||||||
|
formControlName="neighborhood"
|
||||||
|
#neighborhood
|
||||||
|
required
|
||||||
|
></kendo-textbox>
|
||||||
|
<kendo-formerror
|
||||||
|
>Error: Informe o bairro do endereço</kendo-formerror
|
||||||
|
>
|
||||||
|
</kendo-formfield>
|
||||||
|
</div>
|
||||||
|
<div class="col-4">
|
||||||
|
<kendo-formfield>
|
||||||
|
<kendo-label [for]="complement" text="Complemento"></kendo-label>
|
||||||
|
<kendo-textbox
|
||||||
|
formControlName="complement"
|
||||||
|
#complement
|
||||||
|
></kendo-textbox>
|
||||||
|
</kendo-formfield>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-8">
|
||||||
|
<kendo-formfield>
|
||||||
|
<kendo-label [for]="city" text="Cidade"></kendo-label>
|
||||||
|
<kendo-textbox
|
||||||
|
formControlName="city"
|
||||||
|
#city
|
||||||
|
></kendo-textbox>
|
||||||
|
<kendo-formerror
|
||||||
|
>Error: Informe a cidade do endereço</kendo-formerror
|
||||||
|
>
|
||||||
|
</kendo-formfield>
|
||||||
|
</div>
|
||||||
|
<div class="col-2">
|
||||||
|
<kendo-formfield>
|
||||||
|
<kendo-label [for]="state" text="Estado"></kendo-label>
|
||||||
|
<kendo-textbox
|
||||||
|
formControlName="state"
|
||||||
|
#state
|
||||||
|
></kendo-textbox>
|
||||||
|
</kendo-formfield>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<kendo-formfield>
|
||||||
|
<div class="k-form-field-checkbox-wrap">
|
||||||
|
<input
|
||||||
|
kendoCheckBox
|
||||||
|
id="notications"
|
||||||
|
type="checkbox"
|
||||||
|
formControlName="notifications"
|
||||||
|
/>
|
||||||
|
<kendo-label
|
||||||
|
class="k-checkbox-label"
|
||||||
|
for="notications"
|
||||||
|
text="Deseja participar do programa de fidelidade?"
|
||||||
|
></kendo-label>
|
||||||
|
</div>
|
||||||
|
</kendo-formfield>
|
||||||
|
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
25
src/app/crm/edit-customer/edit-customer.component.spec.ts
Normal file
25
src/app/crm/edit-customer/edit-customer.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { EditCustomerComponent } from './edit-customer.component';
|
||||||
|
|
||||||
|
describe('EditCustomerComponent', () => {
|
||||||
|
let component: EditCustomerComponent;
|
||||||
|
let fixture: ComponentFixture<EditCustomerComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ EditCustomerComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(EditCustomerComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
196
src/app/crm/edit-customer/edit-customer.component.ts
Normal file
196
src/app/crm/edit-customer/edit-customer.component.ts
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
|
||||||
|
import { FormControl, FormGroup, Validators } from '@angular/forms';
|
||||||
|
import { DialogService } from '@progress/kendo-angular-dialog';
|
||||||
|
import { EMPTY, throwError } from 'rxjs';
|
||||||
|
import { catchError, map, switchMap, take, tap } from 'rxjs/operators';
|
||||||
|
import { Customer } from 'src/app/models/customer.model';
|
||||||
|
import { CustomerService } from 'src/app/services/customer.service';
|
||||||
|
import { MessageService } from 'src/app/services/messages.service';
|
||||||
|
import { ConsultaCepService } from 'src/app/shared/services/consulta-cep.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-edit-customer',
|
||||||
|
templateUrl: './edit-customer.component.html',
|
||||||
|
styleUrls: ['./edit-customer.component.scss']
|
||||||
|
})
|
||||||
|
export class EditCustomerComponent implements OnInit {
|
||||||
|
public phoneNumberValue = '';
|
||||||
|
public phoneNumberMask = '(99) 00000-0000';
|
||||||
|
public cpfMask = '000.000.000-00';
|
||||||
|
public cnpjMask = '00.000.000/0000-00';
|
||||||
|
public customer: Customer;
|
||||||
|
public isloading = false;
|
||||||
|
public errorObject: any;
|
||||||
|
public result;
|
||||||
|
loaderVisible = false;
|
||||||
|
@ViewChild('formCustomer') formCustomer: ElementRef;
|
||||||
|
@ViewChild('inputCpf') inputCpf: ElementRef;
|
||||||
|
|
||||||
|
public form: FormGroup;
|
||||||
|
|
||||||
|
public customerData: any = {
|
||||||
|
company: false,
|
||||||
|
cpfCnpj: '',
|
||||||
|
name: '',
|
||||||
|
numberState: '',
|
||||||
|
cellPhone: '',
|
||||||
|
whatsapp: false,
|
||||||
|
email: '',
|
||||||
|
address: '',
|
||||||
|
addressNumber: '',
|
||||||
|
complement: '',
|
||||||
|
neighborhood: '',
|
||||||
|
city: '',
|
||||||
|
state: '',
|
||||||
|
zipCode: '',
|
||||||
|
notifications: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(private readonly customerService: CustomerService,
|
||||||
|
private dialogService: DialogService,
|
||||||
|
private dialogsService: MessageService,
|
||||||
|
private cepService: ConsultaCepService) {
|
||||||
|
this.form = new FormGroup({
|
||||||
|
company: new FormControl(this.customerData.company, [
|
||||||
|
Validators.required,
|
||||||
|
]),
|
||||||
|
cpfCnpj: new FormControl(this.customerData.cpfCnpj, [
|
||||||
|
Validators.required,
|
||||||
|
]),
|
||||||
|
name: new FormControl(this.customerData.name, [
|
||||||
|
Validators.required,
|
||||||
|
]),
|
||||||
|
whatsapp: new FormControl(this.customerData.whatsapp, [
|
||||||
|
Validators.required,
|
||||||
|
]),
|
||||||
|
numberState: new FormControl(this.customerData.numberState, []),
|
||||||
|
cellPhone: new FormControl(this.customerData.cellPhone, [
|
||||||
|
Validators.required,
|
||||||
|
]),
|
||||||
|
email: new FormControl(this.customerData.email, [Validators.required]),
|
||||||
|
address: new FormControl(this.customerData.address, [Validators.required]),
|
||||||
|
addressNumber: new FormControl(this.customerData.addressNumber, [Validators.required]),
|
||||||
|
neighborhood: new FormControl(this.customerData.neighborhood),
|
||||||
|
complement: new FormControl(this.customerData.complement),
|
||||||
|
city: new FormControl(this.customerData.city),
|
||||||
|
state: new FormControl(this.customerData.state),
|
||||||
|
zipCode: new FormControl(this.customerData.zipCode),
|
||||||
|
notifications: new FormControl(this.customerData.notifications),
|
||||||
|
comments: new FormControl(this.customerData.comments),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public showConfirmation(mensage: string) {
|
||||||
|
console.log(this.form.value);
|
||||||
|
const result$ = this.dialogsService.confirmResult;
|
||||||
|
result$.asObservable()
|
||||||
|
.pipe(
|
||||||
|
take(1),
|
||||||
|
switchMap(result => result ? this.customerService.createCustomer(this.form.value) : EMPTY)
|
||||||
|
).subscribe(
|
||||||
|
successCreate => {
|
||||||
|
return successCreate;
|
||||||
|
}, err => err
|
||||||
|
);
|
||||||
|
this.dialogsService.showConfirmation('Confirmação', mensage);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
cpfCadastrado(data: Customer) {
|
||||||
|
const result$ = this.dialogsService.confirmResult;
|
||||||
|
result$.asObservable()
|
||||||
|
.pipe(
|
||||||
|
take(1),
|
||||||
|
map(result => result ? this.populateCustomer(data) : this.setFocus('inputCpf')),
|
||||||
|
// switchMap(result => result ? console.log(result) : EMPTY)
|
||||||
|
).subscribe(
|
||||||
|
successCreate => {
|
||||||
|
return successCreate;
|
||||||
|
}, err => err
|
||||||
|
);
|
||||||
|
this.dialogsService.showConfirmation('Confirmação', 'Cliente já cadastrado, deseja alterar seu cadastro?');
|
||||||
|
}
|
||||||
|
|
||||||
|
populateCustomer(data: Customer) {
|
||||||
|
this.form.patchValue({
|
||||||
|
name: data.name,
|
||||||
|
cellPhone: data.cellPhone,
|
||||||
|
email: data.email,
|
||||||
|
zipCode: data.zipCode,
|
||||||
|
address: data.address,
|
||||||
|
addressNumber: data.addressNumber,
|
||||||
|
complement: data.complement,
|
||||||
|
neighborhood: data.neighborhood,
|
||||||
|
city: data.city,
|
||||||
|
state: data.state,
|
||||||
|
mensage: data.allowMessage,
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
searchCustomerByDocument() {
|
||||||
|
const fieldCpf = 'cpfCnpj';
|
||||||
|
const cpf = this.form.value[fieldCpf];
|
||||||
|
this.isloading = true;
|
||||||
|
this.errorObject = null;
|
||||||
|
this.customerService.getCustomerbyCpf(cpf).pipe(
|
||||||
|
map(result => {
|
||||||
|
if ( result.data != null) {
|
||||||
|
this.customer = result.data;
|
||||||
|
console.log(result);
|
||||||
|
this.cpfCadastrado(result.data);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
tap(() => {
|
||||||
|
this.isloading = false;
|
||||||
|
}),
|
||||||
|
catchError(err => {
|
||||||
|
this.isloading = false;
|
||||||
|
this.errorObject = err;
|
||||||
|
console.log(err);
|
||||||
|
return throwError(err);
|
||||||
|
})).subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
setFocus(name) {
|
||||||
|
this.inputCpf.nativeElement.setFocus();
|
||||||
|
console.log(name);
|
||||||
|
/* const ele =
|
||||||
|
if (ele) {
|
||||||
|
ele.focus();
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
createCustomer() {
|
||||||
|
console.log(this.form.value);
|
||||||
|
const result$ = this.customerService.createCustomer(this.form.value);
|
||||||
|
result$.pipe(
|
||||||
|
map(c => console.log('cliente cadastrado')),
|
||||||
|
).subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
consultaCep() {
|
||||||
|
const cep = this.form.get('zipCode').value;
|
||||||
|
if (cep != null && cep !== '') {
|
||||||
|
this.cepService.consultaCep(cep)
|
||||||
|
.subscribe(
|
||||||
|
dados => {
|
||||||
|
this.populateAddress(dados);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
populateAddress(dadosCep: any) {
|
||||||
|
console.log(dadosCep);
|
||||||
|
this.form.patchValue({
|
||||||
|
address: dadosCep.logradouro,
|
||||||
|
complement: dadosCep.complemento,
|
||||||
|
neighborhood: dadosCep.bairro,
|
||||||
|
city: dadosCep.localidade,
|
||||||
|
state: dadosCep.uf
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
627
src/app/crm/menu-crm/menu-crm.component.html
Normal file
627
src/app/crm/menu-crm/menu-crm.component.html
Normal file
@@ -0,0 +1,627 @@
|
|||||||
|
|
||||||
|
<!--Navbar -->
|
||||||
|
<nav class="navbar navbar-expand-lg fixed-top">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<!-- offcanvas trigger-->
|
||||||
|
<button
|
||||||
|
class="navbar-toggler"
|
||||||
|
type="button"
|
||||||
|
data-bs-toggle="offcanvas"
|
||||||
|
data-bs-target="#offcanvasExample"
|
||||||
|
aria-controls="offcanvasExample"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="navbar-toggler-icon"
|
||||||
|
data-bs-target="#offcanvasExample"
|
||||||
|
></span>
|
||||||
|
</button>
|
||||||
|
<!-- offcanvas trigger-->
|
||||||
|
<a class="navbar-brand" style="height: 40px; width: 120px" href="#">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="230.247"
|
||||||
|
height="40"
|
||||||
|
viewBox="0 0 260.247 70.6"
|
||||||
|
>
|
||||||
|
<g
|
||||||
|
id="Grupo_3105"
|
||||||
|
data-name="Grupo 3105"
|
||||||
|
transform="translate(-720 -509)"
|
||||||
|
>
|
||||||
|
<g id="Grupo_2" data-name="Grupo 2" transform="translate(720 509)">
|
||||||
|
<path
|
||||||
|
id="Caminho_1"
|
||||||
|
data-name="Caminho 1"
|
||||||
|
d="M4.118,62.728A5.958,5.958,0,0,0,6.5,64.917a7.776,7.776,0,0,0,3.683.822,5.47,5.47,0,0,0,2.859-.685,6.025,6.025,0,0,0,1.891-1.777,8.772,8.772,0,0,0,1.142-2.326q.39-1.233.7-2.395L22.981,23.4H39.033L32.845,61.293a44.545,44.545,0,0,1-1.8,5.642,18.634,18.634,0,0,1-3.523,5.678,18.474,18.474,0,0,1-6.242,4.412A24.1,24.1,0,0,1,11.322,78.8a32.319,32.319,0,0,1-5.462-.445,46.443,46.443,0,0,1-5.179-1.2Z"
|
||||||
|
transform="translate(-0.681 -8.203)"
|
||||||
|
fill="#fff"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_2"
|
||||||
|
data-name="Caminho 2"
|
||||||
|
d="M48.366,31.258,45.807,45.086a14.283,14.283,0,0,0-.349,2.679,2.091,2.091,0,0,0,.349,1.315,1.644,1.644,0,0,0,1.337.438,2.183,2.183,0,0,0,2.094-1.046,12.462,12.462,0,0,0,1.047-3.385l2.558-13.828h11.4L61.39,46.4a12.035,12.035,0,0,1-5.233,8.4A18.931,18.931,0,0,1,45.69,57.5q-5.873,0-8.837-2.265a7.582,7.582,0,0,1-2.967-6.4,11.447,11.447,0,0,1,.059-1.168q.057-.583.174-1.266l2.849-15.143Z"
|
||||||
|
transform="translate(2.993 -7.333)"
|
||||||
|
fill="#fff"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_3"
|
||||||
|
data-name="Caminho 3"
|
||||||
|
d="M82.473,41.439q-.756-.34-1.57-.633a4.352,4.352,0,0,0-1.454-.292A5.481,5.481,0,0,0,76.8,41.1a5.071,5.071,0,0,0-1.715,1.461,7.524,7.524,0,0,0-1.018,1.948,12.739,12.739,0,0,0-.552,2.094L71.6,57.021H60.2L64.97,31.311H76.425l-1.57,4.918.117.1a11.9,11.9,0,0,1,3.692-3.945A9.418,9.418,0,0,1,84.1,30.776h.349Z"
|
||||||
|
transform="translate(5.905 -7.386)"
|
||||||
|
fill="#fff"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_4"
|
||||||
|
data-name="Caminho 4"
|
||||||
|
d="M96.512,31.258,93.955,45.086a14.19,14.19,0,0,0-.349,2.679,2.084,2.084,0,0,0,.349,1.315,1.643,1.643,0,0,0,1.337.438,2.181,2.181,0,0,0,2.092-1.046,12.462,12.462,0,0,0,1.047-3.385l2.559-13.828h11.4L109.538,46.4a12.033,12.033,0,0,1-5.234,8.4,18.927,18.927,0,0,1-10.466,2.7q-5.874,0-8.839-2.265a7.584,7.584,0,0,1-2.965-6.4q0-.583.058-1.168t.174-1.266l2.85-15.143Z"
|
||||||
|
transform="translate(8.321 -7.333)"
|
||||||
|
fill="#fff"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_5"
|
||||||
|
data-name="Caminho 5"
|
||||||
|
d="M121.978,36.083l.057.1a9.7,9.7,0,0,1,1.542-2,12.635,12.635,0,0,1,2.122-1.728,11.456,11.456,0,0,1,2.5-1.217,8.3,8.3,0,0,1,2.733-.462,8.924,8.924,0,0,1,3.226.511,5.36,5.36,0,0,1,2.094,1.387,5,5,0,0,1,1.105,2.046,9.366,9.366,0,0,1,.32,2.482,11.986,11.986,0,0,1-.087,1.413q-.088.731-.2,1.462l-3.14,16.944h-11.4l2.385-13a10.485,10.485,0,0,0,.174-1.046,8.429,8.429,0,0,0,.059-.95,2.249,2.249,0,0,0-.321-1.291,1.5,1.5,0,0,0-1.307-.463,2.205,2.205,0,0,0-2.239,1.218,15.442,15.442,0,0,0-.96,3.164l-2.268,12.368h-11.4l4.768-25.709h11.4Z"
|
||||||
|
transform="translate(11.081 -7.386)"
|
||||||
|
fill="#fff"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_6"
|
||||||
|
data-name="Caminho 6"
|
||||||
|
d="M162.677,48.305a13.84,13.84,0,0,1-5.989,6.865,18.263,18.263,0,0,1-9.305,2.386,17.484,17.484,0,0,1-5.349-.731,10.65,10.65,0,0,1-3.78-2.045,8.059,8.059,0,0,1-2.239-3.14,10.9,10.9,0,0,1-.727-4.067,11.78,11.78,0,0,1,.088-1.412q.087-.73.2-1.509a16.96,16.96,0,0,1,1.948-5.282,16.78,16.78,0,0,1,3.6-4.407,17.261,17.261,0,0,1,11.543-4.187,13.3,13.3,0,0,1,5.873,1.144,9.509,9.509,0,0,1,3.663,3.043,9.254,9.254,0,0,1,1.4,2.97,12.541,12.541,0,0,1,.407,3.165,21.587,21.587,0,0,1-.145,2.507,25.718,25.718,0,0,1-.436,2.557H146.686q-.058.342-.088.682t-.028.73a3.728,3.728,0,0,0,.406,1.754,1.719,1.719,0,0,0,1.686.78,3.091,3.091,0,0,0,2.85-1.8ZM152.965,41a1.343,1.343,0,0,0,.059-.39v-.389a3.273,3.273,0,0,0-.465-1.7,1.863,1.863,0,0,0-1.744-.779,2.629,2.629,0,0,0-1.279.317,3.052,3.052,0,0,0-.961.8,4.361,4.361,0,0,0-.61,1.072A4.291,4.291,0,0,0,147.674,41Z"
|
||||||
|
transform="translate(14.213 -7.386)"
|
||||||
|
fill="#fff"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_7"
|
||||||
|
data-name="Caminho 7"
|
||||||
|
d="M175.239,36.083l.057.1a9.67,9.67,0,0,1,1.543-2,12.582,12.582,0,0,1,2.121-1.728,11.441,11.441,0,0,1,2.5-1.217,8.285,8.285,0,0,1,2.732-.462,8.919,8.919,0,0,1,3.226.511,5.373,5.373,0,0,1,2.095,1.387,5.011,5.011,0,0,1,1.1,2.046,9.367,9.367,0,0,1,.32,2.482,11.983,11.983,0,0,1-.087,1.413q-.087.731-.2,1.462l-3.14,16.944h-11.4l2.385-13a10.182,10.182,0,0,0,.174-1.046,8.425,8.425,0,0,0,.059-.95,2.249,2.249,0,0,0-.321-1.291,1.5,1.5,0,0,0-1.307-.463,2.205,2.205,0,0,0-2.239,1.218,15.443,15.443,0,0,0-.96,3.164l-2.267,12.368h-11.4L165,31.311h11.4Z"
|
||||||
|
transform="translate(16.974 -7.386)"
|
||||||
|
fill="#fff"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_8"
|
||||||
|
data-name="Caminho 8"
|
||||||
|
d="M191.086,47.769a9.759,9.759,0,0,0,2.24,1.8,5.623,5.623,0,0,0,2.994.876,4.085,4.085,0,0,0,1.54-.317,1.31,1.31,0,0,0,.9-1v-.244a1.188,1.188,0,0,0-.641-1,7.9,7.9,0,0,0-1.977-.8,22.373,22.373,0,0,1-2.617-1,9.351,9.351,0,0,1-2.121-1.315,5.851,5.851,0,0,1-1.425-1.729,4.763,4.763,0,0,1-.523-2.288c0-.194.009-.4.029-.609s.048-.446.087-.705a8.21,8.21,0,0,1,1.57-3.6,10.8,10.8,0,0,1,3.082-2.727,15.743,15.743,0,0,1,4.245-1.728,20.713,20.713,0,0,1,9.768-.049,18.056,18.056,0,0,1,4.246,1.534l-5.176,6.963q-.873-.778-1.89-1.534a4.034,4.034,0,0,0-2.471-.755,2.519,2.519,0,0,0-1.222.318,1.306,1.306,0,0,0-.7.948V39a1.105,1.105,0,0,0,.32.78,3.326,3.326,0,0,0,.785.609,7.057,7.057,0,0,0,.96.463c.329.13.63.243.9.341a15.387,15.387,0,0,1,4.419,2.239,4.543,4.543,0,0,1,1.8,3.847c0,.194-.01.4-.029.609s-.049.431-.087.656a8.652,8.652,0,0,1-1.745,3.872,11.922,11.922,0,0,1-3.255,2.823,15.688,15.688,0,0,1-4.246,1.729,19.246,19.246,0,0,1-4.71.584,20.478,20.478,0,0,1-5.611-.706,27.977,27.977,0,0,1-4.971-1.971Z"
|
||||||
|
transform="translate(19.776 -7.386)"
|
||||||
|
fill="#fff"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_9"
|
||||||
|
data-name="Caminho 9"
|
||||||
|
d="M236.524,48.305a13.835,13.835,0,0,1-5.989,6.865,18.259,18.259,0,0,1-9.3,2.386,17.484,17.484,0,0,1-5.349-.731,10.64,10.64,0,0,1-3.78-2.045,8.059,8.059,0,0,1-2.239-3.14,10.9,10.9,0,0,1-.727-4.067,11.786,11.786,0,0,1,.088-1.412q.087-.73.2-1.509a17.016,17.016,0,0,1,1.948-5.282,16.807,16.807,0,0,1,3.605-4.407,17.261,17.261,0,0,1,11.543-4.187A13.3,13.3,0,0,1,232.4,31.92a9.506,9.506,0,0,1,3.662,3.043,9.207,9.207,0,0,1,1.4,2.97,12.491,12.491,0,0,1,.408,3.165,21.843,21.843,0,0,1-.145,2.507q-.147,1.243-.436,2.557H220.533q-.058.342-.088.682t-.028.73a3.728,3.728,0,0,0,.405,1.754,1.722,1.722,0,0,0,1.687.78,3.091,3.091,0,0,0,2.85-1.8Zm-9.71-7.3a1.383,1.383,0,0,0,.059-.39v-.389a3.273,3.273,0,0,0-.465-1.7,1.863,1.863,0,0,0-1.744-.779,2.636,2.636,0,0,0-1.281.317,3.048,3.048,0,0,0-.96.8,4.361,4.361,0,0,0-.61,1.072A4.292,4.292,0,0,0,221.522,41Z"
|
||||||
|
transform="translate(22.385 -7.386)"
|
||||||
|
fill="#fff"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_10"
|
||||||
|
data-name="Caminho 10"
|
||||||
|
d="M37.494,22.3H21.116L23.089,9.717H39.467Z"
|
||||||
|
transform="translate(1.58 -9.717)"
|
||||||
|
fill="#ef7d00"
|
||||||
|
></path>
|
||||||
|
<g
|
||||||
|
id="Grupo_1"
|
||||||
|
data-name="Grupo 1"
|
||||||
|
transform="translate(64.066 56.235)"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
id="Caminho_11"
|
||||||
|
data-name="Caminho 11"
|
||||||
|
d="M60.329,60.528h4.356l-.663,4.19h2.772l.662-4.19h4.355L69.846,72.966H65.49l.683-4.322H63.4l-.683,4.322H58.364Z"
|
||||||
|
transform="translate(-58.364 -60.329)"
|
||||||
|
fill="#ef7d00"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_12"
|
||||||
|
data-name="Caminho 12"
|
||||||
|
d="M85.916,66.8a7.694,7.694,0,0,1-7.888,6.384c-3.794,0-6.5-2.391-5.87-6.384a7.837,7.837,0,0,1,7.9-6.451C83.833,60.349,86.533,62.89,85.916,66.8Zm-9.215.067a1.887,1.887,0,0,0,1.947,2.391,2.726,2.726,0,0,0,2.7-2.391,1.922,1.922,0,0,0-1.943-2.426A2.783,2.783,0,0,0,76.7,66.866Z"
|
||||||
|
transform="translate(-56.848 -60.349)"
|
||||||
|
fill="#ef7d00"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_13"
|
||||||
|
data-name="Caminho 13"
|
||||||
|
d="M89.755,60.528h4.651l.684,6.533h.116a15.687,15.687,0,0,1,.573-1.65l2.175-4.882h4.6l.08,12.438H98.265l.466-6.813h-.083a12.046,12.046,0,0,1-.492,1.237l-2.679,5.575h-2.64L92.052,67.7a8.132,8.132,0,0,1-.036-1.55h-.148c-.112.494-.225,1.006-.353,1.5l-1.367,5.312H85.777Z"
|
||||||
|
transform="translate(-55.331 -60.329)"
|
||||||
|
fill="#ef7d00"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_14"
|
||||||
|
data-name="Caminho 14"
|
||||||
|
d="M105.37,60.528h8.363l-.536,3.4h-3.811l-.188,1.188h3.481l-.511,3.233h-3.481l-.193,1.221h3.943l-.538,3.4h-8.5Z"
|
||||||
|
transform="translate(-53.38 -60.329)"
|
||||||
|
fill="#ef7d00"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_15"
|
||||||
|
data-name="Caminho 15"
|
||||||
|
d="M131.541,65.6a3.375,3.375,0,0,0-2.458-1.254,2.962,2.962,0,0,0-2.841,2.425,2.065,2.065,0,0,0,2.14,2.426,4.238,4.238,0,0,0,2.772-1.155l-.866,4.653a10.737,10.737,0,0,1-3.3.494,5.2,5.2,0,0,1-5.322-6.3,7.861,7.861,0,0,1,7.531-6.533,8.741,8.741,0,0,1,2.954.512Z"
|
||||||
|
transform="translate(-51.368 -60.349)"
|
||||||
|
fill="#ef7d00"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_16"
|
||||||
|
data-name="Caminho 16"
|
||||||
|
d="M133.985,60.528h8.364l-.538,3.4H138l-.188,1.188h3.481l-.51,3.233H137.3l-.193,1.221h3.943l-.538,3.4h-8.5Z"
|
||||||
|
transform="translate(-50.214 -60.329)"
|
||||||
|
fill="#ef7d00"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_17"
|
||||||
|
data-name="Caminho 17"
|
||||||
|
d="M144.395,60.528h4.339l2.969,6.9h.131a18.385,18.385,0,0,1,.121-3.168l.59-3.728h4.322L154.9,72.966h-4.323l-2.943-6.533H147.5a14.36,14.36,0,0,1-.112,2.491l-.64,4.042H142.43Z"
|
||||||
|
transform="translate(-49.062 -60.329)"
|
||||||
|
fill="#ef7d00"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_18"
|
||||||
|
data-name="Caminho 18"
|
||||||
|
d="M157.643,60.528h9.5l-.639,4.042-2.473-.116-1.345,8.512h-4.52l1.346-8.512L157,64.57Z"
|
||||||
|
transform="translate(-47.449 -60.329)"
|
||||||
|
fill="#ef7d00"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_19"
|
||||||
|
data-name="Caminho 19"
|
||||||
|
d="M168.482,60.528h8.364l-.538,3.4H172.5l-.188,1.188h3.481l-.51,3.233H171.8l-.193,1.221h3.943l-.538,3.4h-8.5Z"
|
||||||
|
transform="translate(-46.397 -60.329)"
|
||||||
|
fill="#ef7d00"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_20"
|
||||||
|
data-name="Caminho 20"
|
||||||
|
d="M178.952,60.528h5.46c2.8,0,4.992,1.187,4.5,4.322a3.571,3.571,0,0,1-2.92,3.234l-.016.1a2.5,2.5,0,0,1,.642.742l2.067,4.042h-5.213l-1.348-3.992h-.082l-.631,3.992h-4.421Zm3.55,5.51h.314c.742,0,1.5-.116,1.648-1.04.151-.957-.506-1.073-1.282-1.073h-.347Z"
|
||||||
|
transform="translate(-45.238 -60.329)"
|
||||||
|
fill="#ef7d00"
|
||||||
|
></path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
<button
|
||||||
|
class="navbar-toggler"
|
||||||
|
type="button"
|
||||||
|
data-bs-toggle="collapse"
|
||||||
|
data-bs-target="#navbarSupportedContent"
|
||||||
|
aria-controls="navbarSupportedContent"
|
||||||
|
aria-expanded="false"
|
||||||
|
aria-label="Toggle navigation"
|
||||||
|
>
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||||
|
<!--form class="d-flex ms-auto">
|
||||||
|
<div class="input-group my-3 my-lg-0">
|
||||||
|
<input
|
||||||
|
class="form-control me-2"
|
||||||
|
type="search"
|
||||||
|
placeholder="Search"
|
||||||
|
aria-label="Search"
|
||||||
|
/>
|
||||||
|
<button class="btn btn-outline-success" type="submit">Search</button>
|
||||||
|
</div>
|
||||||
|
</form-->
|
||||||
|
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
|
||||||
|
<li class="nav-item dropdown">
|
||||||
|
<a
|
||||||
|
class="nav-link dropdown-toggle"
|
||||||
|
href="#"
|
||||||
|
id="navbarDropdown"
|
||||||
|
role="button"
|
||||||
|
data-bs-toggle="dropdown"
|
||||||
|
aria-expanded="false"
|
||||||
|
>
|
||||||
|
<i class="bi bi-person-fill"></i>
|
||||||
|
</a>
|
||||||
|
<ul
|
||||||
|
class="dropdown-menu dropdown-menu-end"
|
||||||
|
aria-labelledby="navbarDropdown"
|
||||||
|
>
|
||||||
|
<li><a class="dropdown-item" href="#">Action</a></li>
|
||||||
|
<li><a class="dropdown-item" href="#">Another action</a></li>
|
||||||
|
<li><hr class="dropdown-divider" /></li>
|
||||||
|
<li><a class="dropdown-item" href="#">Something else here</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<!-- Navbar -->
|
||||||
|
|
||||||
|
<!-- OffCanvas -->
|
||||||
|
<div
|
||||||
|
class="offcanvas offcanvas-start sidebar-nav text-light"
|
||||||
|
data-bs-backdrop="false"
|
||||||
|
data-bs-scroll="true"
|
||||||
|
tabindex="-1"
|
||||||
|
id="offcanvasExample"
|
||||||
|
aria-labelledby="offcanvasExampleLabel"
|
||||||
|
>
|
||||||
|
<div class="offcanvas-header mt-2">
|
||||||
|
<h5 class="offcanvas-title" id="offcanvasExampleLabel">Mestre Jurunense</h5>
|
||||||
|
</div>
|
||||||
|
<div class="offcanvas-body">
|
||||||
|
<ul class="navbar-nav">
|
||||||
|
<!--li class="nav-item">
|
||||||
|
<a
|
||||||
|
class="nav-link px-3 sidebar-link"
|
||||||
|
>
|
||||||
|
<span><i class="bi bi-graph-up-arrow me-2"></i></span>
|
||||||
|
<span>Dashboard</span>
|
||||||
|
</a>
|
||||||
|
</li-->
|
||||||
|
<li class="nav-item">
|
||||||
|
<a
|
||||||
|
class="nav-link px-3 sidebar-link"
|
||||||
|
data-bs-toggle="collapse"
|
||||||
|
href="#collapseExample"
|
||||||
|
role="button"
|
||||||
|
aria-expanded="false"
|
||||||
|
aria-controls="collapseExample"
|
||||||
|
>
|
||||||
|
<span><i class="bi bi-shop me-2"></i></span>
|
||||||
|
<span>Cadastros</span>
|
||||||
|
<span class="right-icon ms-auto"
|
||||||
|
><i class="bi bi-chevron-down"></i
|
||||||
|
></span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="collapse" id="collapseExample">
|
||||||
|
<div>
|
||||||
|
<ul class="navbar-nav ps-3">
|
||||||
|
<li>
|
||||||
|
<a href="#" class="nav-link px-3">
|
||||||
|
<span>Parceiros</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" class="nav-link px-3">
|
||||||
|
<span>Categoria</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" class="nav-link px-3">
|
||||||
|
<span>Faixa de comissão</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<ul class="navbar-nav">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a
|
||||||
|
class="nav-link px-3 sidebar-link"
|
||||||
|
data-bs-toggle="collapse"
|
||||||
|
href="#collapseregister"
|
||||||
|
role="button"
|
||||||
|
aria-expanded="false"
|
||||||
|
aria-controls="collapseregister"
|
||||||
|
>
|
||||||
|
<span><i class="bi bi-person-plus me-2"></i></span>
|
||||||
|
<span>Cadastros</span>
|
||||||
|
<span class="right-icon ms-auto"
|
||||||
|
><i class="bi bi-chevron-down"></i
|
||||||
|
></span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="collapse" id="collapseregister">
|
||||||
|
<div>
|
||||||
|
<ul class="navbar-nav ps-3">
|
||||||
|
<li>
|
||||||
|
<a href="#" class="nav-link px-3">
|
||||||
|
<span>Clientes</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- OffCanvas -->
|
||||||
|
|
||||||
|
<main class="mt-5 pt-3">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<span>teste</span>
|
||||||
|
<router-outlet></router-outlet>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<!--div class="container-fluid my-0 p-0">
|
||||||
|
<nav
|
||||||
|
class="
|
||||||
|
navbar navbar-expand-md
|
||||||
|
flex-md-column flex-row
|
||||||
|
align-items-center
|
||||||
|
py-2
|
||||||
|
text-center
|
||||||
|
sticky-top
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div class="container-fluid my-0 p-0 sticky-top">
|
||||||
|
<a class="navbar-brand" href="#">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="230.247"
|
||||||
|
height="50.6"
|
||||||
|
viewBox="0 0 260.247 70.6"
|
||||||
|
>
|
||||||
|
<g
|
||||||
|
id="Grupo_3105"
|
||||||
|
data-name="Grupo 3105"
|
||||||
|
transform="translate(-720 -509)"
|
||||||
|
>
|
||||||
|
<g id="Grupo_2" data-name="Grupo 2" transform="translate(720 509)">
|
||||||
|
<path
|
||||||
|
id="Caminho_1"
|
||||||
|
data-name="Caminho 1"
|
||||||
|
d="M4.118,62.728A5.958,5.958,0,0,0,6.5,64.917a7.776,7.776,0,0,0,3.683.822,5.47,5.47,0,0,0,2.859-.685,6.025,6.025,0,0,0,1.891-1.777,8.772,8.772,0,0,0,1.142-2.326q.39-1.233.7-2.395L22.981,23.4H39.033L32.845,61.293a44.545,44.545,0,0,1-1.8,5.642,18.634,18.634,0,0,1-3.523,5.678,18.474,18.474,0,0,1-6.242,4.412A24.1,24.1,0,0,1,11.322,78.8a32.319,32.319,0,0,1-5.462-.445,46.443,46.443,0,0,1-5.179-1.2Z"
|
||||||
|
transform="translate(-0.681 -8.203)"
|
||||||
|
fill="#fff"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_2"
|
||||||
|
data-name="Caminho 2"
|
||||||
|
d="M48.366,31.258,45.807,45.086a14.283,14.283,0,0,0-.349,2.679,2.091,2.091,0,0,0,.349,1.315,1.644,1.644,0,0,0,1.337.438,2.183,2.183,0,0,0,2.094-1.046,12.462,12.462,0,0,0,1.047-3.385l2.558-13.828h11.4L61.39,46.4a12.035,12.035,0,0,1-5.233,8.4A18.931,18.931,0,0,1,45.69,57.5q-5.873,0-8.837-2.265a7.582,7.582,0,0,1-2.967-6.4,11.447,11.447,0,0,1,.059-1.168q.057-.583.174-1.266l2.849-15.143Z"
|
||||||
|
transform="translate(2.993 -7.333)"
|
||||||
|
fill="#fff"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_3"
|
||||||
|
data-name="Caminho 3"
|
||||||
|
d="M82.473,41.439q-.756-.34-1.57-.633a4.352,4.352,0,0,0-1.454-.292A5.481,5.481,0,0,0,76.8,41.1a5.071,5.071,0,0,0-1.715,1.461,7.524,7.524,0,0,0-1.018,1.948,12.739,12.739,0,0,0-.552,2.094L71.6,57.021H60.2L64.97,31.311H76.425l-1.57,4.918.117.1a11.9,11.9,0,0,1,3.692-3.945A9.418,9.418,0,0,1,84.1,30.776h.349Z"
|
||||||
|
transform="translate(5.905 -7.386)"
|
||||||
|
fill="#fff"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_4"
|
||||||
|
data-name="Caminho 4"
|
||||||
|
d="M96.512,31.258,93.955,45.086a14.19,14.19,0,0,0-.349,2.679,2.084,2.084,0,0,0,.349,1.315,1.643,1.643,0,0,0,1.337.438,2.181,2.181,0,0,0,2.092-1.046,12.462,12.462,0,0,0,1.047-3.385l2.559-13.828h11.4L109.538,46.4a12.033,12.033,0,0,1-5.234,8.4,18.927,18.927,0,0,1-10.466,2.7q-5.874,0-8.839-2.265a7.584,7.584,0,0,1-2.965-6.4q0-.583.058-1.168t.174-1.266l2.85-15.143Z"
|
||||||
|
transform="translate(8.321 -7.333)"
|
||||||
|
fill="#fff"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_5"
|
||||||
|
data-name="Caminho 5"
|
||||||
|
d="M121.978,36.083l.057.1a9.7,9.7,0,0,1,1.542-2,12.635,12.635,0,0,1,2.122-1.728,11.456,11.456,0,0,1,2.5-1.217,8.3,8.3,0,0,1,2.733-.462,8.924,8.924,0,0,1,3.226.511,5.36,5.36,0,0,1,2.094,1.387,5,5,0,0,1,1.105,2.046,9.366,9.366,0,0,1,.32,2.482,11.986,11.986,0,0,1-.087,1.413q-.088.731-.2,1.462l-3.14,16.944h-11.4l2.385-13a10.485,10.485,0,0,0,.174-1.046,8.429,8.429,0,0,0,.059-.95,2.249,2.249,0,0,0-.321-1.291,1.5,1.5,0,0,0-1.307-.463,2.205,2.205,0,0,0-2.239,1.218,15.442,15.442,0,0,0-.96,3.164l-2.268,12.368h-11.4l4.768-25.709h11.4Z"
|
||||||
|
transform="translate(11.081 -7.386)"
|
||||||
|
fill="#fff"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_6"
|
||||||
|
data-name="Caminho 6"
|
||||||
|
d="M162.677,48.305a13.84,13.84,0,0,1-5.989,6.865,18.263,18.263,0,0,1-9.305,2.386,17.484,17.484,0,0,1-5.349-.731,10.65,10.65,0,0,1-3.78-2.045,8.059,8.059,0,0,1-2.239-3.14,10.9,10.9,0,0,1-.727-4.067,11.78,11.78,0,0,1,.088-1.412q.087-.73.2-1.509a16.96,16.96,0,0,1,1.948-5.282,16.78,16.78,0,0,1,3.6-4.407,17.261,17.261,0,0,1,11.543-4.187,13.3,13.3,0,0,1,5.873,1.144,9.509,9.509,0,0,1,3.663,3.043,9.254,9.254,0,0,1,1.4,2.97,12.541,12.541,0,0,1,.407,3.165,21.587,21.587,0,0,1-.145,2.507,25.718,25.718,0,0,1-.436,2.557H146.686q-.058.342-.088.682t-.028.73a3.728,3.728,0,0,0,.406,1.754,1.719,1.719,0,0,0,1.686.78,3.091,3.091,0,0,0,2.85-1.8ZM152.965,41a1.343,1.343,0,0,0,.059-.39v-.389a3.273,3.273,0,0,0-.465-1.7,1.863,1.863,0,0,0-1.744-.779,2.629,2.629,0,0,0-1.279.317,3.052,3.052,0,0,0-.961.8,4.361,4.361,0,0,0-.61,1.072A4.291,4.291,0,0,0,147.674,41Z"
|
||||||
|
transform="translate(14.213 -7.386)"
|
||||||
|
fill="#fff"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_7"
|
||||||
|
data-name="Caminho 7"
|
||||||
|
d="M175.239,36.083l.057.1a9.67,9.67,0,0,1,1.543-2,12.582,12.582,0,0,1,2.121-1.728,11.441,11.441,0,0,1,2.5-1.217,8.285,8.285,0,0,1,2.732-.462,8.919,8.919,0,0,1,3.226.511,5.373,5.373,0,0,1,2.095,1.387,5.011,5.011,0,0,1,1.1,2.046,9.367,9.367,0,0,1,.32,2.482,11.983,11.983,0,0,1-.087,1.413q-.087.731-.2,1.462l-3.14,16.944h-11.4l2.385-13a10.182,10.182,0,0,0,.174-1.046,8.425,8.425,0,0,0,.059-.95,2.249,2.249,0,0,0-.321-1.291,1.5,1.5,0,0,0-1.307-.463,2.205,2.205,0,0,0-2.239,1.218,15.443,15.443,0,0,0-.96,3.164l-2.267,12.368h-11.4L165,31.311h11.4Z"
|
||||||
|
transform="translate(16.974 -7.386)"
|
||||||
|
fill="#fff"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_8"
|
||||||
|
data-name="Caminho 8"
|
||||||
|
d="M191.086,47.769a9.759,9.759,0,0,0,2.24,1.8,5.623,5.623,0,0,0,2.994.876,4.085,4.085,0,0,0,1.54-.317,1.31,1.31,0,0,0,.9-1v-.244a1.188,1.188,0,0,0-.641-1,7.9,7.9,0,0,0-1.977-.8,22.373,22.373,0,0,1-2.617-1,9.351,9.351,0,0,1-2.121-1.315,5.851,5.851,0,0,1-1.425-1.729,4.763,4.763,0,0,1-.523-2.288c0-.194.009-.4.029-.609s.048-.446.087-.705a8.21,8.21,0,0,1,1.57-3.6,10.8,10.8,0,0,1,3.082-2.727,15.743,15.743,0,0,1,4.245-1.728,20.713,20.713,0,0,1,9.768-.049,18.056,18.056,0,0,1,4.246,1.534l-5.176,6.963q-.873-.778-1.89-1.534a4.034,4.034,0,0,0-2.471-.755,2.519,2.519,0,0,0-1.222.318,1.306,1.306,0,0,0-.7.948V39a1.105,1.105,0,0,0,.32.78,3.326,3.326,0,0,0,.785.609,7.057,7.057,0,0,0,.96.463c.329.13.63.243.9.341a15.387,15.387,0,0,1,4.419,2.239,4.543,4.543,0,0,1,1.8,3.847c0,.194-.01.4-.029.609s-.049.431-.087.656a8.652,8.652,0,0,1-1.745,3.872,11.922,11.922,0,0,1-3.255,2.823,15.688,15.688,0,0,1-4.246,1.729,19.246,19.246,0,0,1-4.71.584,20.478,20.478,0,0,1-5.611-.706,27.977,27.977,0,0,1-4.971-1.971Z"
|
||||||
|
transform="translate(19.776 -7.386)"
|
||||||
|
fill="#fff"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_9"
|
||||||
|
data-name="Caminho 9"
|
||||||
|
d="M236.524,48.305a13.835,13.835,0,0,1-5.989,6.865,18.259,18.259,0,0,1-9.3,2.386,17.484,17.484,0,0,1-5.349-.731,10.64,10.64,0,0,1-3.78-2.045,8.059,8.059,0,0,1-2.239-3.14,10.9,10.9,0,0,1-.727-4.067,11.786,11.786,0,0,1,.088-1.412q.087-.73.2-1.509a17.016,17.016,0,0,1,1.948-5.282,16.807,16.807,0,0,1,3.605-4.407,17.261,17.261,0,0,1,11.543-4.187A13.3,13.3,0,0,1,232.4,31.92a9.506,9.506,0,0,1,3.662,3.043,9.207,9.207,0,0,1,1.4,2.97,12.491,12.491,0,0,1,.408,3.165,21.843,21.843,0,0,1-.145,2.507q-.147,1.243-.436,2.557H220.533q-.058.342-.088.682t-.028.73a3.728,3.728,0,0,0,.405,1.754,1.722,1.722,0,0,0,1.687.78,3.091,3.091,0,0,0,2.85-1.8Zm-9.71-7.3a1.383,1.383,0,0,0,.059-.39v-.389a3.273,3.273,0,0,0-.465-1.7,1.863,1.863,0,0,0-1.744-.779,2.636,2.636,0,0,0-1.281.317,3.048,3.048,0,0,0-.96.8,4.361,4.361,0,0,0-.61,1.072A4.292,4.292,0,0,0,221.522,41Z"
|
||||||
|
transform="translate(22.385 -7.386)"
|
||||||
|
fill="#fff"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_10"
|
||||||
|
data-name="Caminho 10"
|
||||||
|
d="M37.494,22.3H21.116L23.089,9.717H39.467Z"
|
||||||
|
transform="translate(1.58 -9.717)"
|
||||||
|
fill="#ef7d00"
|
||||||
|
></path>
|
||||||
|
<g
|
||||||
|
id="Grupo_1"
|
||||||
|
data-name="Grupo 1"
|
||||||
|
transform="translate(64.066 56.235)"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
id="Caminho_11"
|
||||||
|
data-name="Caminho 11"
|
||||||
|
d="M60.329,60.528h4.356l-.663,4.19h2.772l.662-4.19h4.355L69.846,72.966H65.49l.683-4.322H63.4l-.683,4.322H58.364Z"
|
||||||
|
transform="translate(-58.364 -60.329)"
|
||||||
|
fill="#ef7d00"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_12"
|
||||||
|
data-name="Caminho 12"
|
||||||
|
d="M85.916,66.8a7.694,7.694,0,0,1-7.888,6.384c-3.794,0-6.5-2.391-5.87-6.384a7.837,7.837,0,0,1,7.9-6.451C83.833,60.349,86.533,62.89,85.916,66.8Zm-9.215.067a1.887,1.887,0,0,0,1.947,2.391,2.726,2.726,0,0,0,2.7-2.391,1.922,1.922,0,0,0-1.943-2.426A2.783,2.783,0,0,0,76.7,66.866Z"
|
||||||
|
transform="translate(-56.848 -60.349)"
|
||||||
|
fill="#ef7d00"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_13"
|
||||||
|
data-name="Caminho 13"
|
||||||
|
d="M89.755,60.528h4.651l.684,6.533h.116a15.687,15.687,0,0,1,.573-1.65l2.175-4.882h4.6l.08,12.438H98.265l.466-6.813h-.083a12.046,12.046,0,0,1-.492,1.237l-2.679,5.575h-2.64L92.052,67.7a8.132,8.132,0,0,1-.036-1.55h-.148c-.112.494-.225,1.006-.353,1.5l-1.367,5.312H85.777Z"
|
||||||
|
transform="translate(-55.331 -60.329)"
|
||||||
|
fill="#ef7d00"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_14"
|
||||||
|
data-name="Caminho 14"
|
||||||
|
d="M105.37,60.528h8.363l-.536,3.4h-3.811l-.188,1.188h3.481l-.511,3.233h-3.481l-.193,1.221h3.943l-.538,3.4h-8.5Z"
|
||||||
|
transform="translate(-53.38 -60.329)"
|
||||||
|
fill="#ef7d00"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_15"
|
||||||
|
data-name="Caminho 15"
|
||||||
|
d="M131.541,65.6a3.375,3.375,0,0,0-2.458-1.254,2.962,2.962,0,0,0-2.841,2.425,2.065,2.065,0,0,0,2.14,2.426,4.238,4.238,0,0,0,2.772-1.155l-.866,4.653a10.737,10.737,0,0,1-3.3.494,5.2,5.2,0,0,1-5.322-6.3,7.861,7.861,0,0,1,7.531-6.533,8.741,8.741,0,0,1,2.954.512Z"
|
||||||
|
transform="translate(-51.368 -60.349)"
|
||||||
|
fill="#ef7d00"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_16"
|
||||||
|
data-name="Caminho 16"
|
||||||
|
d="M133.985,60.528h8.364l-.538,3.4H138l-.188,1.188h3.481l-.51,3.233H137.3l-.193,1.221h3.943l-.538,3.4h-8.5Z"
|
||||||
|
transform="translate(-50.214 -60.329)"
|
||||||
|
fill="#ef7d00"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_17"
|
||||||
|
data-name="Caminho 17"
|
||||||
|
d="M144.395,60.528h4.339l2.969,6.9h.131a18.385,18.385,0,0,1,.121-3.168l.59-3.728h4.322L154.9,72.966h-4.323l-2.943-6.533H147.5a14.36,14.36,0,0,1-.112,2.491l-.64,4.042H142.43Z"
|
||||||
|
transform="translate(-49.062 -60.329)"
|
||||||
|
fill="#ef7d00"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_18"
|
||||||
|
data-name="Caminho 18"
|
||||||
|
d="M157.643,60.528h9.5l-.639,4.042-2.473-.116-1.345,8.512h-4.52l1.346-8.512L157,64.57Z"
|
||||||
|
transform="translate(-47.449 -60.329)"
|
||||||
|
fill="#ef7d00"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_19"
|
||||||
|
data-name="Caminho 19"
|
||||||
|
d="M168.482,60.528h8.364l-.538,3.4H172.5l-.188,1.188h3.481l-.51,3.233H171.8l-.193,1.221h3.943l-.538,3.4h-8.5Z"
|
||||||
|
transform="translate(-46.397 -60.329)"
|
||||||
|
fill="#ef7d00"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
id="Caminho_20"
|
||||||
|
data-name="Caminho 20"
|
||||||
|
d="M178.952,60.528h5.46c2.8,0,4.992,1.187,4.5,4.322a3.571,3.571,0,0,1-2.92,3.234l-.016.1a2.5,2.5,0,0,1,.642.742l2.067,4.042h-5.213l-1.348-3.992h-.082l-.631,3.992h-4.421Zm3.55,5.51h.314c.742,0,1.5-.116,1.648-1.04.151-.957-.506-1.073-1.282-1.073h-.347Z"
|
||||||
|
transform="translate(-45.238 -60.329)"
|
||||||
|
fill="#ef7d00"
|
||||||
|
></path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
<button
|
||||||
|
class="navbar-toggler"
|
||||||
|
type="button"
|
||||||
|
data-bs-toggle="collapse"
|
||||||
|
data-bs-target="#nav"
|
||||||
|
aria-controls="nav"
|
||||||
|
aria-expanded="false"
|
||||||
|
aria-label="Toggle navigation"
|
||||||
|
>
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<div class="row min-vh-100 flex-column flex-md-row">
|
||||||
|
<aside class="col-12 col-md-3 col-xl-2 p-0 bg-dark">
|
||||||
|
<nav
|
||||||
|
class="
|
||||||
|
navbar navbar-expand-md navbar-dark
|
||||||
|
bd-dark
|
||||||
|
flex-md-column flex-row
|
||||||
|
align-items-center
|
||||||
|
py-2
|
||||||
|
text-center
|
||||||
|
"
|
||||||
|
id="sidebar"
|
||||||
|
>
|
||||||
|
<div class="text-center p-3">
|
||||||
|
<img
|
||||||
|
src="https://impreza.us-themes.com/wp-content/uploads/paolo-bendandi-D-8XODEIr_s-unsplash.jpg"
|
||||||
|
alt="profile picture"
|
||||||
|
class="img-fluid rounded-circle my-4 p-1 d-none d-md-block shadow"
|
||||||
|
/>
|
||||||
|
<a href="#" class="navbar-brand mx-0 font-weight-bold text-nowrap"
|
||||||
|
>XcentPupil</a
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="navbar-toggler border-0 order-1"
|
||||||
|
data-bs-toggle="collapse"
|
||||||
|
data-bs-target="#nav"
|
||||||
|
aria-controls="nav"
|
||||||
|
aria-expanded="false"
|
||||||
|
aria-label="Toggle navigation"
|
||||||
|
>
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="collapse navbar-collapse order-last" id="nav">
|
||||||
|
<ul class="navbar-nav flex-column w-100 justify-content-center">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="#" class="nav-link active"> Edit Profile</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="#" class="nav-link"> Projects</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="#" class="nav-link"> Tasks </a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="#" class="nav-link"> Users Info </a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</aside>
|
||||||
|
<main class="col px-0 flex-grow-1 overflow-auto">
|
||||||
|
<div class="container py-3">
|
||||||
|
<router-outlet></router-outlet>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</!--div>
|
||||||
|
|
||||||
|
<!--div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-2">
|
||||||
|
<div class="d-line" style="width: 240px; left: -240;">
|
||||||
|
<div class="sidebar fixed">
|
||||||
|
<span class="fs-5 fw-semibold">MENU</span>
|
||||||
|
<ul class="list-unstyled ps-0">
|
||||||
|
<li class="mb-1">
|
||||||
|
<button class="btn btn-toggle align-items-center rounded collapsed" data-bs-toggle="collapse" data-bs-target="#home-collapse" aria-expanded="true">
|
||||||
|
Cadastro
|
||||||
|
</button>
|
||||||
|
<div class="collapse show" id="home-collapse">
|
||||||
|
<ul class="btn-toggle-nav list-unstyled fw-normal pb-1 small">
|
||||||
|
<li><a href="#" class="link-dark rounded">Clientes</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="border-top my-3"></li>
|
||||||
|
<li class="mb-1">
|
||||||
|
<button class="btn btn-toggle align-items-center rounded collapsed" data-bs-toggle="collapse" data-bs-target="#account-collapse" aria-expanded="false">
|
||||||
|
Tabelas auxiliares
|
||||||
|
</button>
|
||||||
|
<div class="collapse" id="account-collapse">
|
||||||
|
<ul class="btn-toggle-nav list-unstyled fw-normal pb-1 small">
|
||||||
|
<li><a href="#" class="link-dark rounded">Fidelidade</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-10">
|
||||||
|
<router-outlet></router-outlet>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div-->
|
||||||
64
src/app/crm/menu-crm/menu-crm.component.scss
Normal file
64
src/app/crm/menu-crm/menu-crm.component.scss
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
.navbar {
|
||||||
|
background-color: #2D2E83;
|
||||||
|
height: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#menu-vertical{
|
||||||
|
position:fixed;
|
||||||
|
z-index:999;
|
||||||
|
overflow:hidden;
|
||||||
|
padding:6px;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: #2D2E83;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--offcanvas-width: 270px;
|
||||||
|
--topNavbarHeight: 56px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-nav {
|
||||||
|
width: 270px;
|
||||||
|
background-color: #2D2E83;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-link {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-link .right-icon {
|
||||||
|
display: inline-flex;
|
||||||
|
transition: all ease 0.25s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-link[aria-expanded="true"] .right-icon {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
li a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 992px) {
|
||||||
|
|
||||||
|
body {
|
||||||
|
overflow: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
margin-left: 270px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.offcanvas-backdrop::before{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-nav{
|
||||||
|
transform: none;
|
||||||
|
visibility: visible !important;
|
||||||
|
top: 56px;
|
||||||
|
height: calc(100% - 56px);
|
||||||
|
}
|
||||||
|
}
|
||||||
25
src/app/crm/menu-crm/menu-crm.component.spec.ts
Normal file
25
src/app/crm/menu-crm/menu-crm.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { MenuCrmComponent } from './menu-crm.component';
|
||||||
|
|
||||||
|
describe('MenuCrmComponent', () => {
|
||||||
|
let component: MenuCrmComponent;
|
||||||
|
let fixture: ComponentFixture<MenuCrmComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ MenuCrmComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(MenuCrmComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
18
src/app/crm/menu-crm/menu-crm.component.ts
Normal file
18
src/app/crm/menu-crm/menu-crm.component.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-menu-crm',
|
||||||
|
templateUrl: './menu-crm.component.html',
|
||||||
|
styleUrls: ['./menu-crm.component.scss']
|
||||||
|
})
|
||||||
|
export class MenuCrmComponent implements OnInit {
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
status: boolean = false;
|
||||||
|
clickEvent(){
|
||||||
|
this.status = !this.status;
|
||||||
|
}
|
||||||
|
ngOnInit(): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
0
src/app/financial/checkout/checkout.component.css
Normal file
0
src/app/financial/checkout/checkout.component.css
Normal file
105
src/app/financial/checkout/checkout.component.html
Normal file
105
src/app/financial/checkout/checkout.component.html
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
<div class="container">
|
||||||
|
<nav class="navbar navbar-expand-lg navbar-light bg-danger">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<a class="navbar-brand text-white" href="#">Financial</a>
|
||||||
|
<button
|
||||||
|
class="navbar-toggler"
|
||||||
|
type="button"
|
||||||
|
data-bs-toggle="collapse"
|
||||||
|
data-bs-target="#navbarNav"
|
||||||
|
aria-controls="navbarNav"
|
||||||
|
aria-expanded="false"
|
||||||
|
aria-label="Toggle navigation"
|
||||||
|
>
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
<div class="collapse navbar-collapse" id="navbarNav">
|
||||||
|
<ul class="navbar-nav">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link active" aria-current="page" href="#">Home</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="#">Features</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="#">Pricing</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a
|
||||||
|
class="nav-link disabled"
|
||||||
|
href="#"
|
||||||
|
tabindex="-1"
|
||||||
|
aria-disabled="true"
|
||||||
|
>Disabled</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<div class="card mt-3">
|
||||||
|
<h2 class="card-header">Conferência de caixa</h2>
|
||||||
|
<form class="mt-3 px-3" action="">
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<kendo-floatinglabel text="Loja">
|
||||||
|
<kendo-combobox
|
||||||
|
style="width: 450px"
|
||||||
|
[data]="stores"
|
||||||
|
[textField]="'name'"
|
||||||
|
[valueField]="'id'"
|
||||||
|
[placeholder]="'Selecione a loja desejada'"
|
||||||
|
(valueChange)="handleStoreChange($event)"
|
||||||
|
></kendo-combobox>
|
||||||
|
</kendo-floatinglabel>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<kendo-floatinglabel text="Caixa">
|
||||||
|
<kendo-combobox
|
||||||
|
style="width: 450px"
|
||||||
|
[disabled]="isDisabledCheckout"
|
||||||
|
[data]="checkouts"
|
||||||
|
[textField]="'description'"
|
||||||
|
[valueField]="'id'"
|
||||||
|
[placeholder]="'Selecione o checkout desejado'"
|
||||||
|
(valueChange)="handleCheckoutChange($event)"
|
||||||
|
></kendo-combobox>
|
||||||
|
</kendo-floatinglabel>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<kendo-floatinglabel text="Usuário">
|
||||||
|
<kendo-combobox
|
||||||
|
style="width: 450px"
|
||||||
|
[disabled]="isDisabledUser"
|
||||||
|
[data]="users"
|
||||||
|
(valueChange)="handleUserChange($event)"
|
||||||
|
[textField]="'name'"
|
||||||
|
[valueField]="'id'"
|
||||||
|
[placeholder]="'Selecione o usuário desejado'"
|
||||||
|
></kendo-combobox>
|
||||||
|
</kendo-floatinglabel>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<kendo-floatinglabel text="Data movimento">
|
||||||
|
<kendo-datepicker [format]="format" [(value)]="value"></kendo-datepicker>
|
||||||
|
</kendo-floatinglabel>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3 mt-3">
|
||||||
|
<div class="col12">
|
||||||
|
<button kendoButton look="outline" [primary]="true" (click)="findOrders()">Pesquisar</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<kendo-grid>
|
||||||
|
|
||||||
|
</kendo-grid>
|
||||||
|
</div>
|
||||||
25
src/app/financial/checkout/checkout.component.spec.ts
Normal file
25
src/app/financial/checkout/checkout.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { CheckoutComponent } from './checkout.component';
|
||||||
|
|
||||||
|
describe('CheckoutComponent', () => {
|
||||||
|
let component: CheckoutComponent;
|
||||||
|
let fixture: ComponentFixture<CheckoutComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ CheckoutComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(CheckoutComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
82
src/app/financial/checkout/checkout.component.ts
Normal file
82
src/app/financial/checkout/checkout.component.ts
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
||||||
|
import { FormatSettings } from '@progress/kendo-angular-dateinputs';
|
||||||
|
import { ComboBoxComponent } from '@progress/kendo-angular-dropdowns';
|
||||||
|
import { CheckoutOrder } from 'src/app/models/checkout-order.model';
|
||||||
|
import { Checkout } from 'src/app/models/checkout.model';
|
||||||
|
import { StoreERP } from 'src/app/models/store.model';
|
||||||
|
import { User } from 'src/app/models/user.model';
|
||||||
|
import { LookupService } from 'src/app/services/lookup.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-checkout',
|
||||||
|
templateUrl: './checkout.component.html',
|
||||||
|
styleUrls: ['./checkout.component.css']
|
||||||
|
})
|
||||||
|
export class CheckoutComponent implements OnInit, OnDestroy {
|
||||||
|
@ViewChild('combo') public combo: ComboBoxComponent;
|
||||||
|
|
||||||
|
public stores: StoreERP[] = [];
|
||||||
|
public checkouts: Checkout[] = [];
|
||||||
|
public users: User[] = [];
|
||||||
|
public checkoutOrders: CheckoutOrder[] = [];
|
||||||
|
public value: Date = new Date();
|
||||||
|
public format: FormatSettings = {
|
||||||
|
displayFormat: 'dd/MM/yyyy',
|
||||||
|
inputFormat: 'dd/MM/yyyy',
|
||||||
|
};
|
||||||
|
|
||||||
|
public selectStore: StoreERP;
|
||||||
|
public selectCheckout: Checkout;
|
||||||
|
public selectUser: User;
|
||||||
|
public isDisabledCheckout = true;
|
||||||
|
public isDisabledUser = true;
|
||||||
|
|
||||||
|
constructor(private lookupService: LookupService) {}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.lookupService.getStore().subscribe((data) => (this.stores = data));
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
/*****NAO ESQUECER DO UNSUBSCRIBE************/
|
||||||
|
}
|
||||||
|
|
||||||
|
fechDataStore(idStore: string) {
|
||||||
|
this.lookupService.getCheckout(idStore).subscribe((data) => (this.checkouts = data));
|
||||||
|
this.lookupService.getUser(idStore).subscribe((data) => (this.users = data));
|
||||||
|
}
|
||||||
|
|
||||||
|
handleStoreChange(value) {
|
||||||
|
this.selectStore = value;
|
||||||
|
|
||||||
|
if (value === undefined) {
|
||||||
|
this.isDisabledCheckout = true;
|
||||||
|
this.checkouts = [];
|
||||||
|
this.isDisabledUser = true;
|
||||||
|
this.users = [];
|
||||||
|
} else {
|
||||||
|
this.isDisabledCheckout = false;
|
||||||
|
this.lookupService.getCheckout(value.id).subscribe((data) => (this.checkouts = data));
|
||||||
|
this.isDisabledUser = false;
|
||||||
|
this.lookupService.getUser(value.id).subscribe((data) => (this.users = data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCheckoutChange(value) {
|
||||||
|
this.selectCheckout = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
handleUserChange(value) {
|
||||||
|
this.selectUser = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
findOrders(){
|
||||||
|
console.log(this.selectStore);
|
||||||
|
console.log(this.selectCheckout);
|
||||||
|
console.log(this.selectUser);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
16
src/app/financial/financial-routing.module.ts
Normal file
16
src/app/financial/financial-routing.module.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
import { CheckoutComponent } from './checkout/checkout.component';
|
||||||
|
|
||||||
|
const routes: Routes = [{ path: 'checkout', component: CheckoutComponent }];
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [],
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
RouterModule.forChild(routes)
|
||||||
|
],
|
||||||
|
exports: [RouterModule]
|
||||||
|
})
|
||||||
|
export class FinancialRoutingModule { }
|
||||||
18
src/app/financial/financial.module.ts
Normal file
18
src/app/financial/financial.module.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { CheckoutComponent } from './checkout/checkout.component';
|
||||||
|
import { FinancialRoutingModule } from './financial-routing.module';
|
||||||
|
import { KendoModule } from '../shared/kendo.module';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [CheckoutComponent],
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
FinancialRoutingModule,
|
||||||
|
FormsModule,
|
||||||
|
KendoModule,
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
export class FinancialModule { }
|
||||||
16
src/app/guards/auth.guard.spec.ts
Normal file
16
src/app/guards/auth.guard.spec.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AuthGuard } from './auth.guard';
|
||||||
|
|
||||||
|
describe('AuthGuardService', () => {
|
||||||
|
let service: AuthGuard;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({});
|
||||||
|
service = TestBed.inject(AuthGuard);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
24
src/app/guards/auth.guard.ts
Normal file
24
src/app/guards/auth.guard.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTree } from '@angular/router';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { AuthService } from '../auth/services/auth.service';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class AuthGuard implements CanActivate {
|
||||||
|
|
||||||
|
constructor(private authService: AuthService, private router: Router) { }
|
||||||
|
|
||||||
|
canActivate(route: ActivatedRouteSnapshot,
|
||||||
|
state: RouterStateSnapshot): Observable<boolean> | boolean {
|
||||||
|
if (this.authService.isAuthenticate()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.router.navigate(['/login']);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
30
src/app/interceptions/error.handle.ts
Normal file
30
src/app/interceptions/error.handle.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { ErrorHandler, Injectable, NgZone } from '@angular/core';
|
||||||
|
import { DialogService } from '@progress/kendo-angular-dialog';
|
||||||
|
import { MessageErrorComponent } from '../shared/menssages/message-error/message-error.component';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ErrorsHandler implements ErrorHandler {
|
||||||
|
constructor(private dialogService: DialogService, private ngZone: NgZone) {}
|
||||||
|
|
||||||
|
handleError(error: any) {
|
||||||
|
console.log(error.message);
|
||||||
|
const dialogRef = this.dialogService
|
||||||
|
.open({
|
||||||
|
title: 'Error Dialog',
|
||||||
|
content: MessageErrorComponent,
|
||||||
|
actions: [{ text: 'OK', primary: true }],
|
||||||
|
width: 400,
|
||||||
|
height: 550,
|
||||||
|
minWidth: 250,
|
||||||
|
});
|
||||||
|
|
||||||
|
const messageInfo = dialogRef.content.instance;
|
||||||
|
messageInfo.status = error.status;
|
||||||
|
messageInfo.message = error.message;
|
||||||
|
console.log(error.status + '-' + error.message);
|
||||||
|
this.ngZone.run(() => {
|
||||||
|
dialogRef.result.subscribe((result) => console.log(result));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
188
src/app/menu-ecosistema/menu-ecosistema.component.html
Normal file
188
src/app/menu-ecosistema/menu-ecosistema.component.html
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
<header>
|
||||||
|
<app-header-system></app-header-system>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main class="container">
|
||||||
|
<div id="title-page" class="mt-3 ms-2">
|
||||||
|
<h1>Selecione o módulo desejado</h1>
|
||||||
|
</div>
|
||||||
|
<div class="row g-3 m-2 align-items-center">
|
||||||
|
<div *ngIf="moduleSale" id="item-module" class="col-12 col-sm-6 col-md-4 col-lg-2 ">
|
||||||
|
<a (click)="openModule('sales/menu')">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-title">
|
||||||
|
<svg class="mt-3 m-3" width="55" height="55" viewBox="0 0 90 80" fill="#EC7E31"
|
||||||
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path d="M22,66h5c1.1,0,2-0.9,2-2V33c0-1.1-0.9-2-2-2h-5c-1.1,0-2,0.9-2,2v31C20,65.1,20.9,66,22,66z" />
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path d="M78,31h-5c-1.1,0-2,0.9-2,2v31c0,1.1,0.9,2,2,2h5c1.1,0,2-0.9,2-2V33C80,31.9,79.1,31,78,31z" />
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path d="M53,66c1.1,0,2-0.9,2-2V33c0-1.1-0.9-2-2-2h-6c-1.1,0-2,0.9-2,2v31c0,1.1,0.9,2,2,2H53z" />
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path d="M65,66c1.1,0,2-0.9,2-2V33c0-1.1-0.9-2-2-2h-2c-1.1,0-2,0.9-2,2v31c0,1.1,0.9,2,2,2H65z" />
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path d="M39,66c1.1,0,2-0.9,2-2V33c0-1.1-0.9-2-2-2h-2c-1.1,0-2,0.9-2,2v31c0,1.1,0.9,2,2,2H39z" />
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path d="M78,72H22c-1.1,0-2,0.9-2,2v2c0,1.1,0.9,2,2,2h56c1.1,0,2-0.9,2-2v-2C80,72.9,79.1,72,78,72z" />
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path d="M78,20H22c-1.1,0-2,0.9-2,2v2c0,1.1,0.9,2,2,2h56c1.1,0,2-0.9,2-2v-2C80,20.9,79.1,20,78,20z" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="card-text">Vendas</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="modulePartner" id="item-module" class="col-12 col-sm-6 col-md-4 col-lg-2 align-self-center">
|
||||||
|
<a (click)="openModule('partner')">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-title">
|
||||||
|
|
||||||
|
<svg class="mt-3 m-3" width="55" height="55" viewBox="0 0 90 80" fill="#EC7E31"
|
||||||
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
d="M56.19,20.52a1.73,1.73,0,0,0-2.47,0l-2.47,2.25a1.62,1.62,0,0,0,0,2.43l4.21,4.08a1.1,1.1,0,0,1-.82,1.9H31.83A1.92,1.92,0,0,0,30,32.92v3.46a1.85,1.85,0,0,0,1.83,1.74H54.64a1.12,1.12,0,0,1,.82,1.9L51.25,44.1a1.62,1.62,0,0,0,0,2.43L53.72,49a1.72,1.72,0,0,0,2.47,0L69.65,36a1.62,1.62,0,0,0,0-2.43ZM44,51.05a1.73,1.73,0,0,1,2.48,0L49,53.3a1.62,1.62,0,0,1,0,2.43L44.74,59.8a1.1,1.1,0,0,0,.82,1.91H68.37a1.92,1.92,0,0,1,1.83,1.73v3.47a1.85,1.85,0,0,1-1.83,1.73H45.56a1.12,1.12,0,0,0-.82,1.91L49,74.63a1.61,1.61,0,0,1,0,2.42l-2.47,2.43a1.74,1.74,0,0,1-2.48,0l-13.45-13a1.62,1.62,0,0,1,0-2.43Z"
|
||||||
|
fill-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="card-text">Mestre Jurunense</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="moduleAdmin" id="item-module" class="col-12 col-sm-6 col-md-4 col-lg-2 align-self-center">
|
||||||
|
<a (click)="openModule('admin/permission-user')">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-title">
|
||||||
|
<div class="svg-container">
|
||||||
|
<svg class="mt-3 m-3" width="55" height="55" viewBox="0 0 90 80" fill="#EC7E31"
|
||||||
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g>
|
||||||
|
<path d="M25.8,60.6h-4.5c-0.7,0-1.3,0.6-1.3,1.3v16.1c0,0.7,0.6,1.3,1.3,1.3h2.2c2,0,3.6-1.6,3.6-3.6V62
|
||||||
|
C27.2,61.2,26.5,60.6,25.8,60.6z" />
|
||||||
|
<path d="M79.9,69.4c-0.7-1.6-2-3.3-3.9-3.5c-1-0.1-2,0.3-2.9,0.6c-3.6,1.3-7.2,2.5-10.8,3.8
|
||||||
|
c-2.3,0.8-4.7,1.6-7.2,1.8c-1.7,0.1-3.4,0-5.1,0c-0.9,0-1.7-0.7-1.7-1.7s0.7-1.7,1.7-1.7l9.1,0c1.7,0,3-1.4,3-3s-1.4-3-3-3h-7
|
||||||
|
c-0.3,0-2.2-0.1-3.4-0.6c-1.3-0.6-3-0.7-3-0.6c0,0,0,0-0.1,0H33.4c-1.5,0-2.7,1.2-2.7,2.7v11.3c0,1.3,1,2.4,2.3,2.6
|
||||||
|
c0.1,0,0.2,0,0.3,0c2.3,0,4.6,0.5,6.9,0.9c2.3,0.5,4.5,0.8,6.9,0.8c3,0.1,6.1-0.4,9-1.1c2.9-0.8,5.7-1.9,8.5-2.8
|
||||||
|
c4.8-1.6,9.7-3.3,14.5-4.9C79.7,70.7,80.2,70.2,79.9,69.4z" />
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M58,40.1v15c0,0.5,0.5,0.7,0.9,0.6c2.9-1.7,11.9-6.7,11.9-6.7
|
||||||
|
c1.2-0.7,1.9-1.9,1.9-3.3V32.2c0-0.5-0.5-0.7-0.9-0.6l-13.2,7.4C58.3,39.3,58,39.7,58,40.1" />
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||||
|
d="M56.8,36L70,28.6c0.4-0.2,0.4-0.8,0-1c-2.9-1.7-12-6.8-12-6.8
|
||||||
|
c-1.2-0.7-2.6-0.7-3.8,0c0,0-9,5.1-12,6.8c-0.4,0.2-0.4,0.8,0,1L55.6,36C55.9,36.2,56.4,36.2,56.8,36" />
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||||
|
d="M53.7,39.1l-13.2-7.4c-0.4-0.2-0.9,0.1-0.9,0.6v13.4
|
||||||
|
c0,1.3,0.7,2.6,1.9,3.3c0,0,9,5.1,11.9,6.7c0.4,0.2,0.9-0.1,0.9-0.6V40.1C54.3,39.7,54.1,39.3,53.7,39.1" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="card-text">Configurações</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<!--div class="container mt-3 mb-3 border rounded-3 shadow" style="height: 85vh">
|
||||||
|
<h1>Selecione o módulo desejado</h1>
|
||||||
|
<div class="row g-3 m-2 align-items-center">
|
||||||
|
<div class="col-12 col-sm-6 col-md-4 col-lg-2">
|
||||||
|
<a href="/#/sales/menu">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-title">
|
||||||
|
<svg
|
||||||
|
class="mt-3 m-3"
|
||||||
|
width="54"
|
||||||
|
height="55"
|
||||||
|
viewBox="0 0 54 55"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M19.6602 31.7765C24.8584 30.7533 28.443 25.8649 27.9396 20.4861C27.4362 15.1068 23.0092 11 17.7154 11C12.421 11 7.99461 15.1068 7.49064 20.4861C6.98722 25.8649 10.5718 30.7533 15.77 31.7765C6.797 32.8025 0.00929224 40.5424 0 49.7584V55H35.4444V49.7584C35.439 40.5357 28.6414 32.7913 19.6602 31.7765ZM10.257 21.4792C10.257 17.267 13.6022 13.852 17.7291 13.852C21.8559 13.852 25.2017 17.267 25.2017 21.4792C25.2017 25.6914 21.8559 29.1058 17.7291 29.1058C13.6038 29.1019 10.2608 25.6897 10.257 21.4792ZM32.6458 52.1435H2.7986V49.7584C2.7986 41.3418 9.48301 34.5192 17.7291 34.5192C25.9751 34.5192 32.6595 41.3418 32.6595 49.7584V52.1435H32.6458Z"
|
||||||
|
fill="#EC7E31"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M41.2061 0V24.4444"
|
||||||
|
stroke="#EC7E31"
|
||||||
|
stroke-width="3"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M53.4282 12.6436L28.1108 12.6436"
|
||||||
|
stroke="#EC7E31"
|
||||||
|
stroke-width="3"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="card-text">Vendas</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-6 col-md-4 col-lg-2 align-self-center">
|
||||||
|
<a href="/#/partner">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-title">
|
||||||
|
<svg
|
||||||
|
class="mt-3 m-3"
|
||||||
|
width="54"
|
||||||
|
height="55"
|
||||||
|
viewBox="0 0 54 55"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M19.6602 31.7765C24.8584 30.7533 28.443 25.8649 27.9396 20.4861C27.4362 15.1068 23.0092 11 17.7154 11C12.421 11 7.99461 15.1068 7.49064 20.4861C6.98722 25.8649 10.5718 30.7533 15.77 31.7765C6.797 32.8025 0.00929224 40.5424 0 49.7584V55H35.4444V49.7584C35.439 40.5357 28.6414 32.7913 19.6602 31.7765ZM10.257 21.4792C10.257 17.267 13.6022 13.852 17.7291 13.852C21.8559 13.852 25.2017 17.267 25.2017 21.4792C25.2017 25.6914 21.8559 29.1058 17.7291 29.1058C13.6038 29.1019 10.2608 25.6897 10.257 21.4792ZM32.6458 52.1435H2.7986V49.7584C2.7986 41.3418 9.48301 34.5192 17.7291 34.5192C25.9751 34.5192 32.6595 41.3418 32.6595 49.7584V52.1435H32.6458Z"
|
||||||
|
fill="#EC7E31"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M41.2061 0V24.4444"
|
||||||
|
stroke="#EC7E31"
|
||||||
|
stroke-width="3"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M53.4282 12.6436L28.1108 12.6436"
|
||||||
|
stroke="#EC7E31"
|
||||||
|
stroke-width="3"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="card-text">Mestre Jurunese</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row h-100">
|
||||||
|
<div class="col-7 p-0">
|
||||||
|
<img
|
||||||
|
src="../../assets/img/loja.jpeg"
|
||||||
|
alt=""
|
||||||
|
style="width: 100%; height: 100%"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col-5" style="background-color: white">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div-->
|
||||||
|
|
||||||
|
<footer></footer>
|
||||||
182
src/app/menu-ecosistema/menu-ecosistema.component.scss
Normal file
182
src/app/menu-ecosistema/menu-ecosistema.component.scss
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
.row.menu {
|
||||||
|
height: 90%;
|
||||||
|
margin: 60px 25px 25px 25px;
|
||||||
|
background: #f8f8f8;
|
||||||
|
border-radius: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
height: 90vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
width: 200px;
|
||||||
|
height: 160px;
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-small {
|
||||||
|
width: 180px;
|
||||||
|
height: 150px;
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-text {
|
||||||
|
width: 170px;
|
||||||
|
height: 44px;
|
||||||
|
|
||||||
|
font-family: Montserrat;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 22px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
color: #1c1e54;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card:hover {
|
||||||
|
transform: translateY(-3px);
|
||||||
|
box-shadow: 0 4px 17px rgba(0, 0, 0, 0.35);
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-wrapper-customer {
|
||||||
|
width: 95%;
|
||||||
|
min-height: 95%;
|
||||||
|
margin-top: 5px;
|
||||||
|
background: #f8f8f8;
|
||||||
|
border-radius: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
width: 136px;
|
||||||
|
height: 44px;
|
||||||
|
|
||||||
|
font-family: Montserrat;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 22px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
|
||||||
|
color: #1c1e54;
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-title-page {
|
||||||
|
width: 290px;
|
||||||
|
height: 98px;
|
||||||
|
|
||||||
|
font-family: Montserrat;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: 40px;
|
||||||
|
line-height: 49px;
|
||||||
|
|
||||||
|
color: #6b6ebe;
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-search-customer {
|
||||||
|
width: 100%;
|
||||||
|
height: 60px;
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-input {
|
||||||
|
height: 27px;
|
||||||
|
|
||||||
|
font-family: Montserrat;
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: 22px;
|
||||||
|
line-height: 27px;
|
||||||
|
border: none;
|
||||||
|
/* identical to box height */
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
color: #c4c4c4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-size {
|
||||||
|
width: 150px;
|
||||||
|
height: 150px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Smartphones */
|
||||||
|
@media (max-width: 575.98px) {
|
||||||
|
#title-page {
|
||||||
|
padding-top: 90px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#item-module {
|
||||||
|
margin-bottom: 00px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1{
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-small {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-text {
|
||||||
|
font-size: 16px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row.g-3.m-2.align-items-center {
|
||||||
|
flex-direction: column;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tablets */
|
||||||
|
@media (max-width: 991.98px) {
|
||||||
|
#title-page {
|
||||||
|
padding-top: 90px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#item-module {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1{
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-text {
|
||||||
|
font-size: 18px;
|
||||||
|
text-align: right;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-bdy {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
25
src/app/menu-ecosistema/menu-ecosistema.component.spec.ts
Normal file
25
src/app/menu-ecosistema/menu-ecosistema.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { MenuEcosistemaComponent } from './menu-ecosistema.component';
|
||||||
|
|
||||||
|
describe('MenuEcosistemaComponent', () => {
|
||||||
|
let component: MenuEcosistemaComponent;
|
||||||
|
let fixture: ComponentFixture<MenuEcosistemaComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ MenuEcosistemaComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(MenuEcosistemaComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
63
src/app/menu-ecosistema/menu-ecosistema.component.ts
Normal file
63
src/app/menu-ecosistema/menu-ecosistema.component.ts
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
import { AuthService } from '../auth/services/auth.service';
|
||||||
|
import { ModuleSystem } from '../models/module.model';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-menu-ecosistema',
|
||||||
|
templateUrl: './menu-ecosistema.component.html',
|
||||||
|
styleUrls: ['./menu-ecosistema.component.scss']
|
||||||
|
})
|
||||||
|
export class MenuEcosistemaComponent implements OnInit {
|
||||||
|
|
||||||
|
modules: ModuleSystem[];
|
||||||
|
moduleSale: boolean = true;
|
||||||
|
modulePartner: boolean = true;
|
||||||
|
moduleAdmin = true;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly router: Router,
|
||||||
|
private readonly authService: AuthService) { }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.authService.getModules(this.authService.getUser())
|
||||||
|
.subscribe(m => {
|
||||||
|
this.modules = m;
|
||||||
|
this.modulesUser();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
modulesUser() {
|
||||||
|
console.log(JSON.stringify(this.modules));
|
||||||
|
let module = this.modules.find(m => m.moduleId == 1) ;
|
||||||
|
if ( module === null ){
|
||||||
|
this.moduleSale = false;
|
||||||
|
} else {
|
||||||
|
console.log(JSON.stringify(module));
|
||||||
|
this.moduleSale = module.access == "S";
|
||||||
|
}
|
||||||
|
module = this.modules.find(m => m.moduleId == 2) ;
|
||||||
|
if ( module === undefined ){
|
||||||
|
this.modulePartner = false;
|
||||||
|
} else {
|
||||||
|
console.log(JSON.stringify(module));
|
||||||
|
this.modulePartner = module.access == "S";
|
||||||
|
}
|
||||||
|
module = this.modules.find(m => m.moduleId == 3) ;
|
||||||
|
this.moduleAdmin = false;
|
||||||
|
if ( module === undefined || module == null ){
|
||||||
|
this.moduleAdmin = false;
|
||||||
|
} else {
|
||||||
|
console.log(JSON.stringify(module));
|
||||||
|
this.moduleAdmin = module.access == "S";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
openModule(url: string) {
|
||||||
|
this.router.navigate([url]);
|
||||||
|
// window.open(url, '_blank');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
167
src/app/menu/menu.component.html
Normal file
167
src/app/menu/menu.component.html
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
|
||||||
|
<!--Navbar -->
|
||||||
|
<nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<!-- offcanvas trigger-->
|
||||||
|
<button
|
||||||
|
class="navbar-toggler"
|
||||||
|
type="button"
|
||||||
|
data-bs-toggle="offcanvas"
|
||||||
|
data-bs-target="#offcanvasExample"
|
||||||
|
aria-controls="offcanvasExample"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="navbar-toggler-icon"
|
||||||
|
data-bs-target="#offcanvasExample"
|
||||||
|
></span>
|
||||||
|
</button>
|
||||||
|
<!-- offcanvas trigger-->
|
||||||
|
<a class="navbar-brand" style="height: 40px; width: 120px" href="#">
|
||||||
|
<img src="assets/img/logo.svg" alt="" />
|
||||||
|
</a>
|
||||||
|
<button
|
||||||
|
class="navbar-toggler"
|
||||||
|
type="button"
|
||||||
|
data-bs-toggle="collapse"
|
||||||
|
data-bs-target="#navbarSupportedContent"
|
||||||
|
aria-controls="navbarSupportedContent"
|
||||||
|
aria-expanded="false"
|
||||||
|
aria-label="Toggle navigation"
|
||||||
|
>
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||||
|
<form class="d-flex ms-auto">
|
||||||
|
<div class="input-group my-3 my-lg-0">
|
||||||
|
<input
|
||||||
|
class="form-control me-2"
|
||||||
|
type="search"
|
||||||
|
placeholder="Search"
|
||||||
|
aria-label="Search"
|
||||||
|
/>
|
||||||
|
<button class="btn btn-outline-success" type="submit">Search</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<ul class="navbar-nav mb-2 mb-lg-0">
|
||||||
|
<li class="nav-item dropdown">
|
||||||
|
<a
|
||||||
|
class="nav-link dropdown-toggle"
|
||||||
|
href="#"
|
||||||
|
id="navbarDropdown"
|
||||||
|
role="button"
|
||||||
|
data-bs-toggle="dropdown"
|
||||||
|
aria-expanded="false"
|
||||||
|
>
|
||||||
|
<i class="bi bi-person-fill"></i>
|
||||||
|
</a>
|
||||||
|
<ul
|
||||||
|
class="dropdown-menu dropdown-menu-end"
|
||||||
|
aria-labelledby="navbarDropdown"
|
||||||
|
>
|
||||||
|
<li><a class="dropdown-item" href="#">Action</a></li>
|
||||||
|
<li><a class="dropdown-item" href="#">Another action</a></li>
|
||||||
|
<li><hr class="dropdown-divider" /></li>
|
||||||
|
<li><a class="dropdown-item" href="#">Something else here</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<!-- Navbar -->
|
||||||
|
|
||||||
|
<!-- OffCanvas -->
|
||||||
|
<div
|
||||||
|
class="offcanvas offcanvas-start sidebar-nav bg-dark text-light"
|
||||||
|
data-bs-backdrop="false"
|
||||||
|
data-bs-scroll="true"
|
||||||
|
tabindex="-1"
|
||||||
|
id="offcanvasExample"
|
||||||
|
aria-labelledby="offcanvasExampleLabel"
|
||||||
|
>
|
||||||
|
<div class="offcanvas-header">
|
||||||
|
<h5 class="offcanvas-title" id="offcanvasExampleLabel">Módulo de vendas</h5>
|
||||||
|
</div>
|
||||||
|
<div class="offcanvas-body">
|
||||||
|
<ul class="navbar-nav">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a
|
||||||
|
class="nav-link px-3 sidebar-link"
|
||||||
|
>
|
||||||
|
<span><i class="bi bi-graph-up-arrow me-2"></i></span>
|
||||||
|
<span>Dashboard</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a
|
||||||
|
class="nav-link px-3 sidebar-link"
|
||||||
|
data-bs-toggle="collapse"
|
||||||
|
href="#collapseExample"
|
||||||
|
role="button"
|
||||||
|
aria-expanded="false"
|
||||||
|
aria-controls="collapseExample"
|
||||||
|
>
|
||||||
|
<span><i class="bi bi-shop me-2"></i></span>
|
||||||
|
<span>Vendas</span>
|
||||||
|
<span class="right-icon ms-auto"
|
||||||
|
><i class="bi bi-chevron-down"></i
|
||||||
|
></span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="collapse" id="collapseExample">
|
||||||
|
<div>
|
||||||
|
<ul class="navbar-nav ps-3">
|
||||||
|
<li>
|
||||||
|
<a href="#" class="nav-link px-3">
|
||||||
|
<span>Pedidos de venda</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<ul class="navbar-nav">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a
|
||||||
|
class="nav-link px-3 sidebar-link"
|
||||||
|
data-bs-toggle="collapse"
|
||||||
|
href="#collapseregister"
|
||||||
|
role="button"
|
||||||
|
aria-expanded="false"
|
||||||
|
aria-controls="collapseregister"
|
||||||
|
>
|
||||||
|
<span><i class="bi bi-person-plus me-2"></i></span>
|
||||||
|
<span>Cadastros</span>
|
||||||
|
<span class="right-icon ms-auto"
|
||||||
|
><i class="bi bi-chevron-down"></i
|
||||||
|
></span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="collapse" id="collapseregister">
|
||||||
|
<div>
|
||||||
|
<ul class="navbar-nav ps-3">
|
||||||
|
<li>
|
||||||
|
<a href="#" class="nav-link px-3">
|
||||||
|
<span>Clientes</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- OffCanvas -->
|
||||||
|
|
||||||
|
<main class="mt-5 pt-3">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<span>teste</span>
|
||||||
|
<router-outlet></router-outlet>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
61
src/app/menu/menu.component.scss
Normal file
61
src/app/menu/menu.component.scss
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
.navbar {
|
||||||
|
background-color: rgba(28, 30, 84, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#menu-vertical{
|
||||||
|
position:fixed;
|
||||||
|
z-index:999;
|
||||||
|
overflow:hidden;
|
||||||
|
padding:6px;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--offcanvas-width: 270px;
|
||||||
|
--topNavbarHeight: 56px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-nav {
|
||||||
|
width: 270px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-link {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-link .right-icon {
|
||||||
|
display: inline-flex;
|
||||||
|
transition: all ease 0.25s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-link[aria-expanded="true"] .right-icon {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
li a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 992px) {
|
||||||
|
|
||||||
|
body {
|
||||||
|
overflow: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
margin-left: 270px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.offcanvas-backdrop::before{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-nav{
|
||||||
|
transform: none;
|
||||||
|
visibility: visible !important;
|
||||||
|
top: 56px;
|
||||||
|
height: calc(100% - 56px);
|
||||||
|
}
|
||||||
|
}
|
||||||
28
src/app/menu/menu.component.spec.ts
Normal file
28
src/app/menu/menu.component.spec.ts
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/* tslint:disable:no-unused-variable */
|
||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { DebugElement } from '@angular/core';
|
||||||
|
|
||||||
|
import { MenuComponent } from './menu.component';
|
||||||
|
|
||||||
|
describe('MenuComponent', () => {
|
||||||
|
let component: MenuComponent;
|
||||||
|
let fixture: ComponentFixture<MenuComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ MenuComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(MenuComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
15
src/app/menu/menu.component.ts
Normal file
15
src/app/menu/menu.component.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-menu',
|
||||||
|
templateUrl: './menu.component.html',
|
||||||
|
styleUrls: ['./menu.component.scss']
|
||||||
|
})
|
||||||
|
export class MenuComponent implements OnInit {
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
8
src/app/models/actions-user.model.ts
Normal file
8
src/app/models/actions-user.model.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export class ActionsUser {
|
||||||
|
moduleId: number;
|
||||||
|
processId: number;
|
||||||
|
pageId: number;
|
||||||
|
actionId: number;
|
||||||
|
userId: number;
|
||||||
|
access: string;
|
||||||
|
}
|
||||||
4
src/app/models/auth.user.model.ts
Normal file
4
src/app/models/auth.user.model.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export interface AuthUser {
|
||||||
|
email: string;
|
||||||
|
password: string;
|
||||||
|
}
|
||||||
90
src/app/models/billing.model.ts
Normal file
90
src/app/models/billing.model.ts
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
export interface Billing {
|
||||||
|
codcob: string;
|
||||||
|
cobranca: string;
|
||||||
|
pagcomissao: string;
|
||||||
|
txjuros: number;
|
||||||
|
codmoeda: string;
|
||||||
|
baixacxbanco: string;
|
||||||
|
nivelvenda: number;
|
||||||
|
fluxocx: string;
|
||||||
|
colunafluxocx: number;
|
||||||
|
numdiasvencfluxocx: number;
|
||||||
|
bloqautomatico: string;
|
||||||
|
numdiasbloqautomatic?: any;
|
||||||
|
exibircxmot: string;
|
||||||
|
exibirbk: string;
|
||||||
|
percacresvenda: number;
|
||||||
|
prazomaximovenda: number;
|
||||||
|
letracob?: any;
|
||||||
|
boleto: string;
|
||||||
|
custodia: string;
|
||||||
|
permitealtcobdesd: string;
|
||||||
|
percom: number;
|
||||||
|
vltarifa?: any;
|
||||||
|
codecf?: any;
|
||||||
|
cartao: string;
|
||||||
|
obsnf?: any;
|
||||||
|
numdiasliberacaocredito?: any;
|
||||||
|
codclicc: number;
|
||||||
|
prazocc: number;
|
||||||
|
perctxadmincc: number;
|
||||||
|
codcontacc: number;
|
||||||
|
codcobcc: string;
|
||||||
|
enviacobrancafv: string;
|
||||||
|
validalimcredecf: string;
|
||||||
|
diascarencia: number;
|
||||||
|
acertoautocxmot: string;
|
||||||
|
codparaprotesto: string;
|
||||||
|
envioparaprotesto: string;
|
||||||
|
numdiasprotesto: string;
|
||||||
|
numbanco?: any;
|
||||||
|
permitedescdevcli: string;
|
||||||
|
percommot?: any;
|
||||||
|
cobrancabroker: string;
|
||||||
|
vlminpedido?: any;
|
||||||
|
depositobancario: string;
|
||||||
|
tipocomissao: string;
|
||||||
|
codbancotarifa?: any;
|
||||||
|
codfilial?: any;
|
||||||
|
exportarecf: string;
|
||||||
|
codbanco?: any;
|
||||||
|
somatarifabancduplic?: any;
|
||||||
|
somatarifabancnf?: any;
|
||||||
|
codoperadoracartao: string;
|
||||||
|
tipooperacaotef: string;
|
||||||
|
tipopagtoecf: string;
|
||||||
|
nummaxparcelas?: any;
|
||||||
|
codparanaoprotesto?: any;
|
||||||
|
permitebaixamanual: string;
|
||||||
|
numviascpadicional: string;
|
||||||
|
codbandeira: number;
|
||||||
|
selecionaclienteecf: string;
|
||||||
|
autenticaracertocx402: string;
|
||||||
|
utilizachdesc?: any;
|
||||||
|
codcobchdesc?: any;
|
||||||
|
codcobdevchdesc?: any;
|
||||||
|
permitecontravale: string;
|
||||||
|
cobrancaemtransito: string;
|
||||||
|
calcjuroscobranca: string;
|
||||||
|
codigobandeira?: any;
|
||||||
|
convenio?: any;
|
||||||
|
recargacelular: string;
|
||||||
|
codrede?: any;
|
||||||
|
txprimeiraparcela: string;
|
||||||
|
naovalidaprazomedio?: any;
|
||||||
|
cheque: string;
|
||||||
|
flexivel: string;
|
||||||
|
codcobsefaz: string;
|
||||||
|
codbandeiraoperadoracartao: string;
|
||||||
|
bandeiracartao?: any;
|
||||||
|
percmulta: number;
|
||||||
|
cobsuppliercard: string;
|
||||||
|
indpag: number;
|
||||||
|
dtmxsalter: Date;
|
||||||
|
mxdiasinad?: any;
|
||||||
|
mxinad?: any;
|
||||||
|
codoutro?: any;
|
||||||
|
carteiradigital?: any;
|
||||||
|
nomecarteiradigital?: any;
|
||||||
|
descricaoformapagto?: any;
|
||||||
|
}
|
||||||
4
src/app/models/brand.model.ts
Normal file
4
src/app/models/brand.model.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export class BrandFilter {
|
||||||
|
description: string;
|
||||||
|
checked: boolean;
|
||||||
|
}
|
||||||
9
src/app/models/calculate-price-color.model.ts
Normal file
9
src/app/models/calculate-price-color.model.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
export class CalculatePriceColor {
|
||||||
|
storeId: string;
|
||||||
|
productId: number;
|
||||||
|
letter: string;
|
||||||
|
line: string;
|
||||||
|
can: number;
|
||||||
|
color: string;
|
||||||
|
price: number;
|
||||||
|
}
|
||||||
12
src/app/models/cart-itens.model.ts
Normal file
12
src/app/models/cart-itens.model.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
export class CartItensModel {
|
||||||
|
idProduct: number;
|
||||||
|
ean: number;
|
||||||
|
idStock: string;
|
||||||
|
deliveryMethod: string;
|
||||||
|
quantity: number;
|
||||||
|
listPrice: number;
|
||||||
|
salePrice: number;
|
||||||
|
descriptionAux: string;
|
||||||
|
environment?: string;
|
||||||
|
}
|
||||||
29
src/app/models/cart.model.ts
Normal file
29
src/app/models/cart.model.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { CartItensModel } from './cart-itens.model';
|
||||||
|
|
||||||
|
export class CartModel {
|
||||||
|
id: string;
|
||||||
|
saleStore: string;
|
||||||
|
userId: number;
|
||||||
|
idCustomer: number;
|
||||||
|
idSeller: number;
|
||||||
|
idProfessional: number;
|
||||||
|
idPaymentPlan: number;
|
||||||
|
idBilling: string;
|
||||||
|
shippingDate: Date;
|
||||||
|
scheduleDelivery: boolean;
|
||||||
|
shippingValue: number;
|
||||||
|
notation1: string;
|
||||||
|
notation2: string;
|
||||||
|
notation3: string;
|
||||||
|
idAddress: number;
|
||||||
|
deliveryNote1: string;
|
||||||
|
deliveryNote2: string;
|
||||||
|
deliveryNote3: string;
|
||||||
|
shippingPriority: string;
|
||||||
|
idStorePlace?: number;
|
||||||
|
preCustomerDocument: string;
|
||||||
|
preCustomerName: string;
|
||||||
|
preCustomerPhone: string;
|
||||||
|
carrierId: number;
|
||||||
|
itens: CartItensModel[];
|
||||||
|
}
|
||||||
6
src/app/models/category-partner.model.ts
Normal file
6
src/app/models/category-partner.model.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export class CategoryPartner {
|
||||||
|
id: number;
|
||||||
|
partnerType: string;
|
||||||
|
name: string;
|
||||||
|
paymentType: string;
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user