├── projects
├── admin-portal
│ ├── README.md
│ ├── src
│ │ ├── assets
│ │ │ ├── .gitkeep
│ │ │ └── images
│ │ │ │ ├── login-background.jpg
│ │ │ │ └── logo_transparent.png
│ │ ├── app
│ │ │ ├── app.component.scss
│ │ │ ├── app.component.html
│ │ │ ├── app.component.ts
│ │ │ ├── app-routing.module.ts
│ │ │ ├── authentication
│ │ │ │ ├── authentication.module.ts
│ │ │ │ ├── login-container.component.spec.ts
│ │ │ │ └── login-container.component.ts
│ │ │ ├── app.module.ts
│ │ │ └── app.component.spec.ts
│ │ ├── environments
│ │ │ ├── environment.prod.ts
│ │ │ └── environment.ts
│ │ ├── favicon.ico
│ │ ├── main.ts
│ │ ├── index.html
│ │ ├── test.ts
│ │ ├── styles.scss
│ │ └── polyfills.ts
│ ├── tslint.json
│ ├── tsconfig.app.json
│ ├── e2e
│ │ ├── src
│ │ │ ├── app.po.ts
│ │ │ └── app.e2e-spec.ts
│ │ ├── tsconfig.json
│ │ └── protractor.conf.js
│ ├── .browserslistrc
│ └── karma.conf.js
├── tenant-portal
│ ├── README.md
│ ├── src
│ │ ├── assets
│ │ │ ├── .gitkeep
│ │ │ ├── css
│ │ │ │ ├── material-overrides
│ │ │ │ │ ├── material-overrides.scss
│ │ │ │ │ └── app-mat-card.scss
│ │ │ │ ├── _text.scss
│ │ │ │ ├── styles.scss
│ │ │ │ ├── _flex.scss
│ │ │ │ └── _utility.scss
│ │ │ └── images
│ │ │ │ ├── login-background.jpg
│ │ │ │ └── logo_transparent.png
│ │ ├── app
│ │ │ ├── app.component.scss
│ │ │ ├── help
│ │ │ │ ├── help.component.scss
│ │ │ │ ├── help.component.html
│ │ │ │ ├── help.component.ts
│ │ │ │ └── help.module.ts
│ │ │ ├── account
│ │ │ │ ├── account.component.scss
│ │ │ │ ├── signature
│ │ │ │ │ ├── signature.component.scss
│ │ │ │ │ ├── signature.component.html
│ │ │ │ │ └── signature.component.ts
│ │ │ │ ├── payment-methods
│ │ │ │ │ ├── payment-method-detail.component.scss
│ │ │ │ │ ├── payment-method-list.component.scss
│ │ │ │ │ ├── payment-method-list.component.html
│ │ │ │ │ ├── payment-method-detail.component.html
│ │ │ │ │ ├── payment-method-list.component.ts
│ │ │ │ │ └── payment-method-detail.component.ts
│ │ │ │ ├── account-detail
│ │ │ │ │ ├── account-detail.component.scss
│ │ │ │ │ ├── account-detail.component.ts
│ │ │ │ │ └── account-detail.component.html
│ │ │ │ ├── account.component.ts
│ │ │ │ ├── account.component.html
│ │ │ │ └── account.module.ts
│ │ │ ├── payments
│ │ │ │ ├── payments.component.scss
│ │ │ │ ├── payment.ts
│ │ │ │ ├── payments.component.ts
│ │ │ │ ├── payment.service.ts
│ │ │ │ ├── payments.module.ts
│ │ │ │ └── payments.component.html
│ │ │ ├── documents
│ │ │ │ ├── documents.component.scss
│ │ │ │ ├── documents.component.html
│ │ │ │ ├── documents.component.ts
│ │ │ │ └── documents.module.ts
│ │ │ ├── properties
│ │ │ │ ├── property.component.scss
│ │ │ │ ├── property.component.html
│ │ │ │ ├── property.component.ts
│ │ │ │ └── property.module.ts
│ │ │ ├── maintenance
│ │ │ │ ├── maintenance.component.scss
│ │ │ │ ├── maintenance-dashboard
│ │ │ │ │ ├── maintenance-dashboard.component.scss
│ │ │ │ │ ├── maintenance-dashboard.component.html
│ │ │ │ │ ├── maintenance-dashboard.module.ts
│ │ │ │ │ └── maintenance-dashboard.component.ts
│ │ │ │ ├── maintenance.component.html
│ │ │ │ ├── maintenance-status.enum.ts
│ │ │ │ ├── maintenance-list
│ │ │ │ │ ├── maintenance-list.component.scss
│ │ │ │ │ ├── maintenance-list.component.ts
│ │ │ │ │ └── maintenance-list.component.html
│ │ │ │ ├── maintenance-create
│ │ │ │ │ ├── maintenance-create-payload.interface.ts
│ │ │ │ │ ├── maintenance-create.component.scss
│ │ │ │ │ ├── maintenance-create.component.html
│ │ │ │ │ └── maintenance-create.component.ts
│ │ │ │ ├── maintenance.component.ts
│ │ │ │ ├── maintenance.interface.ts
│ │ │ │ ├── maintenance.module.ts
│ │ │ │ └── maintenance.service.ts
│ │ │ ├── app.component.html
│ │ │ ├── shared
│ │ │ │ ├── enums
│ │ │ │ │ └── app-url.enum.ts
│ │ │ │ ├── interfaces
│ │ │ │ │ └── paginated-response.interface.ts
│ │ │ │ ├── material-defaults
│ │ │ │ │ ├── mat-form-field-default-options.ts
│ │ │ │ │ └── mat-dialog-default-options.ts
│ │ │ │ └── interceptors
│ │ │ │ │ └── headers.interceptor.ts
│ │ │ ├── announcements
│ │ │ │ ├── announcement-detail
│ │ │ │ │ ├── announcement-detail.component.scss
│ │ │ │ │ ├── announcement.interface.ts
│ │ │ │ │ ├── announcement-detail.component.html
│ │ │ │ │ └── announcement-detail.component.ts
│ │ │ │ ├── announcement-list
│ │ │ │ │ ├── announcement-list.component.scss
│ │ │ │ │ ├── announcement-list.component.html
│ │ │ │ │ └── announcement-list.component.ts
│ │ │ │ ├── announcement.module.ts
│ │ │ │ └── announcement.service.ts
│ │ │ ├── leases
│ │ │ │ ├── lease.ts
│ │ │ │ └── lease.service.ts
│ │ │ ├── charges
│ │ │ │ ├── charge.ts
│ │ │ │ └── charge.service.ts
│ │ │ ├── app.component.ts
│ │ │ ├── home
│ │ │ │ ├── home.component.scss
│ │ │ │ ├── home.module.ts
│ │ │ │ ├── home.component.ts
│ │ │ │ └── home.component.html
│ │ │ ├── app-wrapper
│ │ │ │ ├── app-wrapper.component.scss
│ │ │ │ ├── app-wrapper.component.html
│ │ │ │ └── app-wrapper.component.ts
│ │ │ ├── authentication
│ │ │ │ ├── authentication.module.ts
│ │ │ │ ├── login-container.component.ts
│ │ │ │ ├── auth.guard.ts
│ │ │ │ └── authentication.service.ts
│ │ │ ├── app.module.ts
│ │ │ ├── core.module.ts
│ │ │ └── app-router.module.ts
│ │ ├── favicon.png
│ │ ├── typings.d.ts
│ │ ├── environments
│ │ │ ├── environment.prod.ts
│ │ │ └── environment.ts
│ │ ├── main.ts
│ │ ├── index.html
│ │ ├── test.ts
│ │ └── polyfills.ts
│ ├── tslint.json
│ ├── tsconfig.app.json
│ ├── e2e
│ │ ├── src
│ │ │ ├── app.po.ts
│ │ │ └── app.e2e-spec.ts
│ │ ├── tsconfig.json
│ │ └── protractor.conf.js
│ ├── .browserslistrc
│ └── karma.conf.js
└── propertium-common
│ ├── src
│ ├── lib
│ │ ├── propertium-auth
│ │ │ ├── login-credentials.interface.ts
│ │ │ ├── propertium-login-page.component.scss
│ │ │ ├── propertium-login-page.component.spec.ts
│ │ │ ├── propertium-login-page.module.ts
│ │ │ ├── propertium-login-page.component.ts
│ │ │ └── propertium-login-page.component.html
│ │ └── material-defaults
│ │ │ ├── mat-form-field-default-options.ts
│ │ │ └── mat-dialog-default-options.ts
│ ├── public-api.ts
│ └── test.ts
│ ├── ng-package.json
│ ├── tsconfig.lib.prod.json
│ ├── tslint.json
│ ├── package.json
│ ├── tsconfig.spec.json
│ ├── tsconfig.lib.json
│ ├── README.md
│ └── karma.conf.js
├── .prettierrc
├── .editorconfig
├── tsconfig.json
├── .gitignore
├── README.md
├── package.json
├── tslint.base.json
└── angular.json
/projects/admin-portal/README.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/projects/tenant-portal/README.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/projects/admin-portal/src/assets/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/assets/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/projects/admin-portal/src/app/app.component.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/app.component.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/help/help.component.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/account/account.component.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/payments/payments.component.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/documents/documents.component.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/properties/property.component.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/account/signature/signature.component.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/maintenance/maintenance.component.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/projects/admin-portal/src/app/app.component.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/projects/admin-portal/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tslint.base.json"
3 | }
4 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/app.component.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/help/help.component.html:
--------------------------------------------------------------------------------
1 |
Help Component!
2 |
--------------------------------------------------------------------------------
/projects/tenant-portal/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tslint.base.json"
3 | }
4 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/account/payment-methods/payment-method-detail.component.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/account/payment-methods/payment-method-list.component.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/account/signature/signature.component.html:
--------------------------------------------------------------------------------
1 | Signature!
2 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/properties/property.component.html:
--------------------------------------------------------------------------------
1 | Property Component!
2 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/documents/documents.component.html:
--------------------------------------------------------------------------------
1 | Documents Component!
2 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/maintenance/maintenance-dashboard/maintenance-dashboard.component.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/maintenance/maintenance.component.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/assets/css/material-overrides/material-overrides.scss:
--------------------------------------------------------------------------------
1 | @import './app-mat-card.scss';
2 |
--------------------------------------------------------------------------------
/projects/admin-portal/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true
3 | };
4 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/account/payment-methods/payment-method-list.component.html:
--------------------------------------------------------------------------------
1 | Payment Method List Component!
2 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/account/payment-methods/payment-method-detail.component.html:
--------------------------------------------------------------------------------
1 | Payment Method Detail Component!
2 |
--------------------------------------------------------------------------------
/projects/admin-portal/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aaron-chesley/ng2-property-management/HEAD/projects/admin-portal/src/favicon.ico
--------------------------------------------------------------------------------
/projects/tenant-portal/src/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aaron-chesley/ng2-property-management/HEAD/projects/tenant-portal/src/favicon.png
--------------------------------------------------------------------------------
/projects/tenant-portal/src/typings.d.ts:
--------------------------------------------------------------------------------
1 | /* SystemJS module definition */
2 | declare var module: NodeModule;
3 | interface NodeModule {
4 | id: string;
5 | }
6 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 120,
3 | "singleQuote": true,
4 | "useTabs": false,
5 | "tabWidth": 2,
6 | "semi": true,
7 | "bracketSpacing": true
8 | }
9 |
--------------------------------------------------------------------------------
/projects/propertium-common/src/lib/propertium-auth/login-credentials.interface.ts:
--------------------------------------------------------------------------------
1 | export interface LoginCredentials {
2 | email: string;
3 | password: string;
4 | }
5 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/maintenance/maintenance-status.enum.ts:
--------------------------------------------------------------------------------
1 | export enum MaintenanceStatus {
2 | PENDING = 'PENDING',
3 | COMPLETED = 'COMPLETED',
4 | }
5 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/maintenance/maintenance-list/maintenance-list.component.scss:
--------------------------------------------------------------------------------
1 | button {
2 | margin: 16px 8px 16px 0px;
3 | }
4 |
5 | table {
6 | width: 100%;
7 | }
8 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/payments/payment.ts:
--------------------------------------------------------------------------------
1 | export class Payment {
2 | id: number;
3 | amount: number;
4 | created_on: string;
5 | paid_by: any;
6 | charge: any;
7 | }
8 |
--------------------------------------------------------------------------------
/projects/admin-portal/src/assets/images/login-background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aaron-chesley/ng2-property-management/HEAD/projects/admin-portal/src/assets/images/login-background.jpg
--------------------------------------------------------------------------------
/projects/admin-portal/src/assets/images/logo_transparent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aaron-chesley/ng2-property-management/HEAD/projects/admin-portal/src/assets/images/logo_transparent.png
--------------------------------------------------------------------------------
/projects/tenant-portal/src/assets/images/login-background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aaron-chesley/ng2-property-management/HEAD/projects/tenant-portal/src/assets/images/login-background.jpg
--------------------------------------------------------------------------------
/projects/tenant-portal/src/assets/images/logo_transparent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aaron-chesley/ng2-property-management/HEAD/projects/tenant-portal/src/assets/images/logo_transparent.png
--------------------------------------------------------------------------------
/projects/tenant-portal/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true,
3 | envName: 'prod',
4 | baseUrl: 'http://gmc.aaronchesley.com/api',
5 | };
6 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/maintenance/maintenance-create/maintenance-create-payload.interface.ts:
--------------------------------------------------------------------------------
1 | export interface MaintenanceCreatePayload {
2 | description: string;
3 | permissionToEnter: boolean;
4 | }
5 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/shared/enums/app-url.enum.ts:
--------------------------------------------------------------------------------
1 | export enum AppUrl {
2 | LOGIN = '/login',
3 | MAINTENANCE_LIST = '/connect/maintenance/list',
4 | MAINTENANCE_CREATE = '/connect/maintenance/create',
5 | }
6 |
--------------------------------------------------------------------------------
/projects/propertium-common/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "dest": "../../dist/propertium-common",
4 | "lib": {
5 | "entryFile": "src/public-api.ts"
6 | }
7 | }
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/announcements/announcement-detail/announcement-detail.component.scss:
--------------------------------------------------------------------------------
1 | mat-dialog-content {
2 | display: flex;
3 | flex-direction: column;
4 | small {
5 | margin-bottom: 10px;
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/announcements/announcement-detail/announcement.interface.ts:
--------------------------------------------------------------------------------
1 | export class Announcement {
2 | url: string;
3 | title: string;
4 | body: string;
5 | dateCreated: string;
6 | dateUpdated: string;
7 | }
8 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/leases/lease.ts:
--------------------------------------------------------------------------------
1 | export class Lease {
2 | amount: number;
3 | created_on: string;
4 | date_due: string;
5 | description: string;
6 | lease: any;
7 | name: string;
8 | url: string;
9 | }
10 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/shared/interfaces/paginated-response.interface.ts:
--------------------------------------------------------------------------------
1 | export interface PaginatedResponse {
2 | count: number;
3 | next: string;
4 | pageNumber: number;
5 | previous: string;
6 | results: R[];
7 | }
8 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/charges/charge.ts:
--------------------------------------------------------------------------------
1 | export class Charge {
2 | amount: number;
3 | created_on: string;
4 | date_due: string;
5 | description: string;
6 | lease: any;
7 | name: string;
8 | url: string;
9 | }
10 |
--------------------------------------------------------------------------------
/projects/propertium-common/tsconfig.lib.prod.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "./tsconfig.lib.json",
4 | "angularCompilerOptions": {
5 | "enableIvy": false
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/projects/admin-portal/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-root',
5 | templateUrl: './app.component.html',
6 | styleUrls: ['./app.component.scss'],
7 | })
8 | export class AppComponent {}
9 |
--------------------------------------------------------------------------------
/projects/propertium-common/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tslint.base.json",
3 | "rules": {
4 | "directive-selector": [true, "attribute", "propertium", "camelCase"],
5 | "component-selector": [true, "element", "propertium", "kebab-case"]
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-root',
5 | templateUrl: './app.component.html',
6 | styleUrls: ['./app.component.scss']
7 | })
8 | export class AppComponent {}
9 |
--------------------------------------------------------------------------------
/projects/admin-portal/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../out-tsc/app",
5 | "types": []
6 | },
7 | "files": ["src/main.ts", "src/polyfills.ts"],
8 | "include": ["src/**/*.d.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/projects/tenant-portal/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../out-tsc/app",
5 | "types": []
6 | },
7 | "files": ["src/main.ts", "src/polyfills.ts"],
8 | "include": ["src/**/*.d.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/projects/propertium-common/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@propertium/common",
3 | "version": "0.0.1",
4 | "peerDependencies": {
5 | "@angular/core": "^10.0.2",
6 | "@angular/material": "^10.0.1"
7 | },
8 | "dependencies": {
9 | "tslib": "^2.0.0"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/projects/propertium-common/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../out-tsc/spec",
5 | "types": ["jasmine", "node"]
6 | },
7 | "files": ["src/test.ts"],
8 | "include": ["**/*.spec.ts", "**/*.d.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/projects/propertium-common/src/lib/material-defaults/mat-form-field-default-options.ts:
--------------------------------------------------------------------------------
1 | import { MatFormFieldDefaultOptions } from '@angular/material/form-field';
2 |
3 | export const matFormFieldDefaultOptions: MatFormFieldDefaultOptions = {
4 | appearance: 'outline',
5 | floatLabel: 'always',
6 | };
7 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/shared/material-defaults/mat-form-field-default-options.ts:
--------------------------------------------------------------------------------
1 | import { MatFormFieldDefaultOptions } from '@angular/material/form-field';
2 |
3 | export const matFormFieldDefaultOptions: MatFormFieldDefaultOptions = {
4 | appearance: 'outline',
5 | floatLabel: 'always',
6 | };
7 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/announcements/announcement-detail/announcement-detail.component.html:
--------------------------------------------------------------------------------
1 | {{ data.announcement.title }}
2 |
3 | {{ data.announcement.dateCreated | date }}
4 | {{ data.announcement.body }}
5 |
6 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/help/help.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'help-container',
5 | templateUrl: './help.component.html',
6 | styleUrls: ['./help.component.scss']
7 | })
8 | export class HelpComponent {
9 | constructor() {}
10 | }
11 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.md]
12 | max_line_length = off
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/account/account-detail/account-detail.component.scss:
--------------------------------------------------------------------------------
1 | mat-card {
2 | max-width: 500px;
3 | mat-form-field {
4 | width: 100%;
5 | }
6 | }
7 |
8 | mat-label {
9 | font-weight: bold;
10 | }
11 |
12 | .form-item {
13 | display: flex;
14 | flex-direction: column;
15 | }
16 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/account/account.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-account-container',
5 | templateUrl: './account.component.html',
6 | styleUrls: ['./account.component.scss'],
7 | })
8 | export class AccountComponent {
9 | constructor() {}
10 | }
11 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/account/signature/signature.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'signature',
5 | templateUrl: './signature.component.html',
6 | styles: ['./signature.component.scss']
7 | })
8 | export class SignatureComponent {
9 | constructor() {}
10 | }
11 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/documents/documents.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'documents-container',
5 | templateUrl: './documents.component.html',
6 | styleUrls: ['./documents.component.scss']
7 | })
8 | export class DocumentsComponent {
9 | constructor() {}
10 | }
11 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/payments/payments.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-payments-container',
5 | templateUrl: './payments.component.html',
6 | styleUrls: ['./payments.component.scss'],
7 | })
8 | export class PaymentsComponent {
9 | constructor() {}
10 | }
11 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/assets/css/material-overrides/app-mat-card.scss:
--------------------------------------------------------------------------------
1 | .mat-card {
2 | display: flex !important;
3 | flex-direction: column !important;
4 | }
5 |
6 | .mat-card-header {
7 | flex-shrink: 0 !important;
8 | }
9 |
10 | .mat-card-content {
11 | flex-grow: 1 !important;
12 | overflow: auto !important;
13 | }
14 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/properties/property.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-property-container',
5 | templateUrl: './property.component.html',
6 | styleUrls: ['./property.component.scss'],
7 | })
8 | export class PropertyComponent {
9 | constructor() {}
10 | }
11 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/home/home.component.scss:
--------------------------------------------------------------------------------
1 | .cards {
2 | display: grid;
3 | grid-gap: 10px;
4 | }
5 |
6 | @media (min-width: 600px) {
7 | .cards {
8 | grid-template-columns: repeat(2, 1fr);
9 | }
10 | }
11 |
12 | @media (min-width: 900px) {
13 | .cards {
14 | grid-template-columns: repeat(3, 1fr);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/maintenance/maintenance.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-maintenance-container',
5 | templateUrl: './maintenance.component.html',
6 | styleUrls: ['./maintenance.component.scss'],
7 | })
8 | export class MaintenanceComponent {
9 | constructor() {}
10 | }
11 |
--------------------------------------------------------------------------------
/projects/propertium-common/src/lib/material-defaults/mat-dialog-default-options.ts:
--------------------------------------------------------------------------------
1 | import { MatDialogConfig } from '@angular/material/dialog';
2 |
3 | export const matDialogDefaultOptions: MatDialogConfig = {
4 | maxWidth: '600px',
5 | minWidth: '320px',
6 | maxHeight: '80vh',
7 | disableClose: false,
8 | hasBackdrop: true,
9 | autoFocus: true,
10 | };
11 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/account/account-detail/account-detail.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-account-detail',
5 | templateUrl: './account-detail.component.html',
6 | styleUrls: ['./account-detail.component.scss'],
7 | })
8 | export class AccountDetailComponent {
9 | constructor() {}
10 | }
11 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/shared/material-defaults/mat-dialog-default-options.ts:
--------------------------------------------------------------------------------
1 | import { MatDialogConfig } from '@angular/material/dialog';
2 |
3 | export const matDialogDefaultOptions: MatDialogConfig = {
4 | maxWidth: '600px',
5 | minWidth: '320px',
6 | maxHeight: '80vh',
7 | disableClose: false,
8 | hasBackdrop: true,
9 | autoFocus: true,
10 | };
11 |
--------------------------------------------------------------------------------
/projects/admin-portal/e2e/src/app.po.ts:
--------------------------------------------------------------------------------
1 | import { browser, by, element } from 'protractor';
2 |
3 | export class AppPage {
4 | navigateTo(): Promise {
5 | return browser.get(browser.baseUrl) as Promise;
6 | }
7 |
8 | getTitleText(): Promise {
9 | return element(by.css('app-root .content span')).getText() as Promise;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/projects/tenant-portal/e2e/src/app.po.ts:
--------------------------------------------------------------------------------
1 | import { browser, by, element } from 'protractor';
2 |
3 | export class AppPage {
4 | navigateTo(): Promise {
5 | return browser.get(browser.baseUrl) as Promise;
6 | }
7 |
8 | getTitleText(): Promise {
9 | return element(by.css('app-root .content span')).getText() as Promise;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/account/payment-methods/payment-method-list.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-payment-method-list',
5 | templateUrl: './payment-method-list.component.html',
6 | styleUrls: ['./payment-method-list.component.scss'],
7 | })
8 | export class PaymentMethodListComponent {
9 | constructor() {}
10 | }
11 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/maintenance/maintenance-create/maintenance-create.component.scss:
--------------------------------------------------------------------------------
1 | mat-card {
2 | max-width: 500px;
3 | mat-form-field {
4 | width: 100%;
5 | }
6 | mat-radio-group {
7 | display: flex;
8 | flex-direction: column;
9 | mat-radio-button {
10 | margin: 5px;
11 | }
12 | }
13 | }
14 |
15 | mat-label {
16 | font-weight: bold;
17 | }
18 |
--------------------------------------------------------------------------------
/projects/admin-portal/e2e/tsconfig.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "../../../tsconfig.json",
4 | "compilerOptions": {
5 | "outDir": "../../../out-tsc/e2e",
6 | "module": "commonjs",
7 | "target": "es2018",
8 | "types": [
9 | "jasmine",
10 | "jasminewd2",
11 | "node"
12 | ]
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/projects/tenant-portal/e2e/tsconfig.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "../../../tsconfig.json",
4 | "compilerOptions": {
5 | "outDir": "../../../out-tsc/e2e",
6 | "module": "commonjs",
7 | "target": "es2018",
8 | "types": [
9 | "jasmine",
10 | "jasminewd2",
11 | "node"
12 | ]
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/account/payment-methods/payment-method-detail.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-payment-method-detail',
5 | templateUrl: './payment-method-detail.component.html',
6 | styleUrls: ['./payment-method-detail.component.scss'],
7 | })
8 | export class PaymentMethodDetailComponent {
9 | constructor() {}
10 | }
11 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/main.ts:
--------------------------------------------------------------------------------
1 | import { enableProdMode } from '@angular/core';
2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
3 |
4 | import { AppModule } from './app/app.module';
5 | import { environment } from './environments/environment';
6 |
7 | if (environment.production) {
8 | enableProdMode();
9 | }
10 |
11 | platformBrowserDynamic().bootstrapModule(AppModule);
12 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/maintenance/maintenance.interface.ts:
--------------------------------------------------------------------------------
1 | import { MaintenanceStatus } from './maintenance-status.enum';
2 |
3 | export interface Maintenance {
4 | url: string;
5 | id: string;
6 | description: string;
7 | permissionToEnter: boolean;
8 | photo: string;
9 | status: MaintenanceStatus;
10 | dateCompleted: string;
11 | dateCreated: string;
12 | dateUpdated: string;
13 | }
14 |
--------------------------------------------------------------------------------
/projects/admin-portal/src/main.ts:
--------------------------------------------------------------------------------
1 | import { enableProdMode } from '@angular/core';
2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
3 |
4 | import { AppModule } from './app/app.module';
5 | import { environment } from './environments/environment';
6 |
7 | if (environment.production) {
8 | enableProdMode();
9 | }
10 |
11 | platformBrowserDynamic().bootstrapModule(AppModule)
12 | .catch(err => console.error(err));
13 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/help/help.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { Routes, RouterModule } from '@angular/router';
3 |
4 | import { HelpComponent } from './help.component';
5 |
6 | const routes: Routes = [{ path: '', component: HelpComponent }];
7 |
8 | @NgModule({
9 | declarations: [HelpComponent],
10 | imports: [RouterModule.forChild(routes)],
11 | exports: [RouterModule],
12 | providers: [],
13 | })
14 | export class HelpModule {}
15 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/announcements/announcement-list/announcement-list.component.scss:
--------------------------------------------------------------------------------
1 | mat-card {
2 | mat-card-content {
3 | max-height: 448px;
4 | overflow-y: auto;
5 | mat-list {
6 | mat-list-item {
7 | cursor: pointer;
8 | h3 {
9 | font-weight: bold;
10 | }
11 | p {
12 | font-style: italic;
13 | }
14 | small {
15 | font-size: 0.8rem !important;
16 | }
17 | }
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/projects/tenant-portal/.browserslistrc:
--------------------------------------------------------------------------------
1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
2 | # For additional information regarding the format and rule options, please see:
3 | # https://github.com/browserslist/browserslist#queries
4 |
5 | # You can see what browsers were selected by your queries by running:
6 | # npx browserslist
7 |
8 | > 0.5%
9 | last 2 versions
10 | Firefox ESR
11 | not dead
12 | not IE 9-11 # For IE 9-11 support, remove 'not'.
13 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/properties/property.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { Routes, RouterModule } from '@angular/router';
3 |
4 | import { PropertyComponent } from './property.component';
5 |
6 | const routes: Routes = [{ path: '', component: PropertyComponent }];
7 |
8 | @NgModule({
9 | declarations: [PropertyComponent],
10 | imports: [RouterModule.forChild(routes)],
11 | exports: [RouterModule],
12 | providers: [],
13 | })
14 | export class PropertyModule {}
15 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/documents/documents.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { Routes, RouterModule } from '@angular/router';
3 |
4 | import { DocumentsComponent } from './documents.component';
5 |
6 | const routes: Routes = [{ path: '', component: DocumentsComponent }];
7 |
8 | @NgModule({
9 | declarations: [DocumentsComponent],
10 | imports: [RouterModule.forChild(routes)],
11 | exports: [RouterModule],
12 | providers: [],
13 | })
14 | export class DocumentsModule {}
15 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | // The file contents for the current environment will overwrite these during build.
2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do
3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead.
4 | // The list of which env maps to which file can be found in `.angular-cli.json`.
5 |
6 | export const environment = {
7 | production: false,
8 | envName: 'dev',
9 | baseUrl: 'http://localhost:8000/api',
10 | };
11 |
--------------------------------------------------------------------------------
/projects/admin-portal/src/app/app-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { Routes, RouterModule } from '@angular/router';
3 |
4 | const routes: Routes = [
5 | {
6 | path: 'auth',
7 | loadChildren: () => import('./authentication/authentication.module').then((m) => m.AuthenticationModule),
8 | },
9 | { path: '', redirectTo: 'auth', pathMatch: 'full' },
10 | ];
11 |
12 | @NgModule({
13 | imports: [RouterModule.forRoot(routes)],
14 | exports: [RouterModule],
15 | })
16 | export class AppRoutingModule {}
17 |
--------------------------------------------------------------------------------
/projects/propertium-common/src/public-api.ts:
--------------------------------------------------------------------------------
1 | export * from './lib/propertium-auth/propertium-login-page.module';
2 | export * from './lib/propertium-auth/propertium-login-page.component';
3 | export * from './lib/propertium-auth/login-credentials.interface';
4 |
5 | export * from './lib/material-defaults/mat-dialog-default-options';
6 | export * from './lib/material-defaults/mat-form-field-default-options';
7 |
8 | export * from './lib/material-defaults/mat-dialog-default-options';
9 | export * from './lib/material-defaults/mat-form-field-default-options';
10 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/charges/charge.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { HttpClient } from '@angular/common/http';
3 | import { environment } from '../../environments/environment';
4 |
5 | @Injectable()
6 | export class ChargeService {
7 | private chargesUrl: string = environment.baseUrl + '/charges';
8 |
9 | constructor(private http: HttpClient) {}
10 |
11 | getCharges() {
12 | return this.http.get(this.chargesUrl);
13 | }
14 |
15 | getCharge(id) {
16 | return this.http.get(this.chargesUrl);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "outDir": "./dist/out-tsc",
6 | "sourceMap": true,
7 | "declaration": false,
8 | "downlevelIteration": true,
9 | "experimentalDecorators": true,
10 | "moduleResolution": "node",
11 | "importHelpers": true,
12 | "target": "es2015",
13 | "module": "es2020",
14 | "lib": ["es2018", "dom"],
15 | "paths": {
16 | "@propertium/common": ["dist/propertium-common/propertium-common", "dist/propertium-common"]
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/payments/payment.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { HttpClient } from '@angular/common/http';
3 | import { environment } from '../../environments/environment';
4 |
5 | @Injectable()
6 | export class PaymentService {
7 | private paymentsUrl: string = environment.baseUrl + '/payments';
8 |
9 | constructor(private http: HttpClient) {}
10 |
11 | getPayments() {
12 | return this.http.get(this.paymentsUrl);
13 | }
14 |
15 | getPayment(id) {
16 | return this.http.get(this.paymentsUrl);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/payments/payments.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { Routes, RouterModule } from '@angular/router';
3 |
4 | import { PaymentService } from './payment.service';
5 | import { PaymentsComponent } from './payments.component';
6 |
7 | const routes: Routes = [{ path: '', component: PaymentsComponent }];
8 |
9 | @NgModule({
10 | declarations: [PaymentsComponent],
11 | imports: [RouterModule.forChild(routes)],
12 | exports: [RouterModule],
13 | providers: [PaymentService],
14 | })
15 | export class PaymentsModule {}
16 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/maintenance/maintenance-dashboard/maintenance-dashboard.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Maintenance
4 |
5 | {{ numOfPendingRequests$ | async }} open requests
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/leases/lease.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { HttpClient } from '@angular/common/http';
3 | import { environment } from '../../environments/environment';
4 |
5 | @Injectable()
6 | export class LeaseService {
7 | private leasesUrl: string = environment.baseUrl + '/leases';
8 |
9 | constructor(private http: HttpClient) {}
10 |
11 | getLeases() {
12 | return this.http.get(this.leasesUrl);
13 | }
14 |
15 | getLease(id) {
16 | const url = this.leasesUrl + '/' + id + '/';
17 | return this.http.get(url);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/announcements/announcement-list/announcement-list.component.html:
--------------------------------------------------------------------------------
1 |
2 | Announcements
3 |
4 |
5 |
6 | {{ announcement.title }}
7 | {{ announcement.dateCreated | date }}
8 | Read...
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/app-wrapper/app-wrapper.component.scss:
--------------------------------------------------------------------------------
1 | $header-height: 60px;
2 |
3 | .header {
4 | position: fixed;
5 | height: $header-height;
6 | top: 0;
7 | left: 0;
8 | right: 0;
9 | }
10 |
11 | .spacer {
12 | flex: 1 1 auto;
13 | }
14 |
15 | .sidenav-container {
16 | position: absolute;
17 | top: $header-height;
18 | bottom: 0;
19 | left: 0;
20 | right: 0;
21 | }
22 |
23 | .sidenav {
24 | display: flex;
25 | align-items: center;
26 | justify-content: center;
27 | width: 200px;
28 | background: #f8f8f8;
29 | }
30 |
31 | .main-content {
32 | padding: 10px;
33 | }
34 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/maintenance/maintenance-dashboard/maintenance-dashboard.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { MaintenanceDashboardComponent } from './maintenance-dashboard.component';
3 | import { MatCardModule } from '@angular/material/card';
4 | import { MatButtonModule } from '@angular/material/button';
5 | import { CommonModule } from '@angular/common';
6 |
7 | @NgModule({
8 | declarations: [MaintenanceDashboardComponent],
9 | imports: [CommonModule, MatCardModule, MatButtonModule],
10 | exports: [MaintenanceDashboardComponent],
11 | })
12 | export class MaintenanceDashboardModule {}
13 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/authentication/authentication.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { Routes, RouterModule } from '@angular/router';
3 | import { PropertiumLoginPageModule } from '@propertium/common';
4 |
5 | import { LoginContainerComponent } from './login-container.component';
6 |
7 | const routes: Routes = [{ path: '', component: LoginContainerComponent }];
8 |
9 | @NgModule({
10 | declarations: [LoginContainerComponent],
11 | imports: [RouterModule.forChild(routes), PropertiumLoginPageModule],
12 | exports: [RouterModule],
13 | providers: [],
14 | })
15 | export class AuthenticationModule {}
16 |
--------------------------------------------------------------------------------
/projects/admin-portal/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Propertium Admin Portal
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/projects/propertium-common/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "../../tsconfig.json",
4 | "compilerOptions": {
5 | "outDir": "../../out-tsc/lib",
6 | "target": "es2015",
7 | "declaration": true,
8 | "inlineSources": true,
9 | "types": [],
10 | "lib": [
11 | "dom",
12 | "es2018"
13 | ]
14 | },
15 | "angularCompilerOptions": {
16 | "skipTemplateCodegen": true,
17 | "strictMetadataEmit": true,
18 | "enableResourceInlining": true
19 | },
20 | "exclude": [
21 | "src/test.ts",
22 | "**/*.spec.ts"
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/announcements/announcement-detail/announcement-detail.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, Inject } from '@angular/core';
2 | import { MAT_DIALOG_DATA } from '@angular/material/dialog';
3 | import { Announcement } from './announcement.interface';
4 |
5 | interface AnnouncementDetailDialogData {
6 | announcement: Announcement;
7 | }
8 |
9 | @Component({
10 | selector: 'app-announcement-detail',
11 | templateUrl: './announcement-detail.component.html',
12 | styleUrls: ['./announcement-detail.component.scss'],
13 | })
14 | export class AnnouncementDetailComponent {
15 | constructor(@Inject(MAT_DIALOG_DATA) public data: AnnouncementDetailDialogData) {}
16 | }
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist
5 | /tmp
6 | /out-tsc
7 |
8 | # dependencies
9 | /node_modules
10 |
11 | # IDEs and editors
12 | .vscode
13 | /.idea
14 | .project
15 | .classpath
16 | .c9/
17 | *.launch
18 | .settings/
19 | *.sublime-workspace
20 |
21 | # IDE - VSCode
22 | .vscode/*
23 | !.vscode/settings.json
24 | !.vscode/tasks.json
25 | !.vscode/launch.json
26 | !.vscode/extensions.json
27 |
28 | # misc
29 | /.sass-cache
30 | /connect.lock
31 | /coverage
32 | /libpeerconnection.log
33 | npm-debug.log
34 | testem.log
35 | /typings
36 |
37 | # e2e
38 | /e2e/*.js
39 | /e2e/*.map
40 |
41 | # System Files
42 | .DS_Store
43 | Thumbs.db
44 |
--------------------------------------------------------------------------------
/projects/admin-portal/src/app/authentication/authentication.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { Routes, RouterModule } from '@angular/router';
4 | import { PropertiumLoginPageModule } from '@propertium/common';
5 | import { LoginContainerComponent } from './login-container.component';
6 |
7 | const routes: Routes = [
8 | { path: '', redirectTo: 'login' },
9 | { path: 'login', component: LoginContainerComponent },
10 | ];
11 |
12 | @NgModule({
13 | declarations: [LoginContainerComponent],
14 | imports: [CommonModule, RouterModule.forChild(routes), PropertiumLoginPageModule],
15 | exports: [RouterModule],
16 | })
17 | export class AuthenticationModule {}
18 |
--------------------------------------------------------------------------------
/projects/admin-portal/.browserslistrc:
--------------------------------------------------------------------------------
1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
2 | # For additional information regarding the format and rule options, please see:
3 | # https://github.com/browserslist/browserslist#queries
4 |
5 | # For the full list of supported browsers by the Angular framework, please see:
6 | # https://angular.io/guide/browser-support
7 |
8 | # You can see what browsers were selected by your queries by running:
9 | # npx browserslist
10 |
11 | last 1 Chrome version
12 | last 1 Firefox version
13 | last 2 Edge major versions
14 | last 2 Safari major version
15 | last 2 iOS major versions
16 | Firefox ESR
17 | not IE 9-11 # For IE 9-11 support, remove 'not'.
18 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/account/account-detail/account-detail.component.html:
--------------------------------------------------------------------------------
1 |
2 | Account Details
3 |
4 |
5 | Email
6 |
7 |
8 |
9 |
10 |
11 | Email Reminders
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Propertium Tenant Portal
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/projects/admin-portal/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | // This file can be replaced during build by using the `fileReplacements` array.
2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
3 | // The list of file replacements can be found in `angular.json`.
4 |
5 | export const environment = {
6 | production: false
7 | };
8 |
9 | /*
10 | * For easier debugging in development mode, you can import the following file
11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
12 | *
13 | * This import should be commented out in production mode because it will have a negative impact
14 | * on performance if an error is thrown.
15 | */
16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI.
17 |
--------------------------------------------------------------------------------
/projects/admin-portal/e2e/src/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { AppPage } from './app.po';
2 | import { browser, logging } from 'protractor';
3 |
4 | describe('workspace-project App', () => {
5 | let page: AppPage;
6 |
7 | beforeEach(() => {
8 | page = new AppPage();
9 | });
10 |
11 | it('should display welcome message', () => {
12 | page.navigateTo();
13 | expect(page.getTitleText()).toEqual('admin-portal app is running!');
14 | });
15 |
16 | afterEach(async () => {
17 | // Assert that there are no errors emitted from the browser
18 | const logs = await browser.manage().logs().get(logging.Type.BROWSER);
19 | expect(logs).not.toContain(jasmine.objectContaining({
20 | level: logging.Level.SEVERE,
21 | } as logging.Entry));
22 | });
23 | });
24 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/account/account.component.html:
--------------------------------------------------------------------------------
1 |
30 |
31 |
--------------------------------------------------------------------------------
/projects/propertium-common/src/lib/propertium-auth/propertium-login-page.component.scss:
--------------------------------------------------------------------------------
1 | .login-container {
2 | height: 100vh;
3 | display: flex;
4 | justify-content: center;
5 | align-items: center;
6 | background-repeat: no-repeat;
7 | background-size: cover;
8 | background-position: center;
9 | }
10 |
11 | form {
12 | width: 100%;
13 | max-width: 400px;
14 | }
15 |
16 | .title {
17 | text-align: center;
18 | }
19 |
20 | .input-group {
21 | display: flex;
22 | flex-direction: column;
23 | }
24 |
25 | .input-group > button:not(:last-child) {
26 | margin-bottom: 0.5rem;
27 | }
28 |
29 | input:-webkit-autofill,
30 | input:-webkit-autofill:hover,
31 | input:-webkit-autofill:focus,
32 | input:-webkit-autofill:active {
33 | -webkit-box-shadow: 0 0 0 30px white inset !important;
34 | }
35 |
--------------------------------------------------------------------------------
/projects/tenant-portal/e2e/src/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { AppPage } from './app.po';
2 | import { browser, logging } from 'protractor';
3 |
4 | describe('workspace-project App', () => {
5 | let page: AppPage;
6 |
7 | beforeEach(() => {
8 | page = new AppPage();
9 | });
10 |
11 | it('should display welcome message', () => {
12 | page.navigateTo();
13 | expect(page.getTitleText()).toEqual('tenant-portal app is running!');
14 | });
15 |
16 | afterEach(async () => {
17 | // Assert that there are no errors emitted from the browser
18 | const logs = await browser.manage().logs().get(logging.Type.BROWSER);
19 | expect(logs).not.toContain(
20 | jasmine.objectContaining({
21 | level: logging.Level.SEVERE,
22 | } as logging.Entry)
23 | );
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/announcements/announcement.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { MatDialogModule } from '@angular/material/dialog';
4 | import { MatCardModule } from '@angular/material/card';
5 | import { MatListModule } from '@angular/material/list';
6 | import { AnnouncementListComponent } from './announcement-list/announcement-list.component';
7 | import { AnnouncementDetailComponent } from './announcement-detail/announcement-detail.component';
8 |
9 | @NgModule({
10 | declarations: [AnnouncementListComponent, AnnouncementDetailComponent],
11 | imports: [CommonModule, MatDialogModule, MatCardModule, MatListModule],
12 | exports: [AnnouncementListComponent],
13 | providers: [],
14 | })
15 | export class AnnouncementModule {}
16 |
--------------------------------------------------------------------------------
/projects/admin-portal/src/app/authentication/login-container.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { LoginContainerComponent } from './login-container.component';
4 |
5 | describe('LoginContainerComponent', () => {
6 | let component: LoginContainerComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async(() => {
10 | TestBed.configureTestingModule({
11 | declarations: [LoginContainerComponent],
12 | }).compileComponents();
13 | }));
14 |
15 | beforeEach(() => {
16 | fixture = TestBed.createComponent(LoginContainerComponent);
17 | component = fixture.componentInstance;
18 | fixture.detectChanges();
19 | });
20 |
21 | it('should create', () => {
22 | expect(component).toBeTruthy();
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/projects/admin-portal/src/test.ts:
--------------------------------------------------------------------------------
1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files
2 |
3 | import 'zone.js/dist/zone-testing';
4 | import { getTestBed } from '@angular/core/testing';
5 | import {
6 | BrowserDynamicTestingModule,
7 | platformBrowserDynamicTesting
8 | } from '@angular/platform-browser-dynamic/testing';
9 |
10 | declare const require: {
11 | context(path: string, deep?: boolean, filter?: RegExp): {
12 | keys(): string[];
13 | (id: string): T;
14 | };
15 | };
16 |
17 | // First, initialize the Angular testing environment.
18 | getTestBed().initTestEnvironment(
19 | BrowserDynamicTestingModule,
20 | platformBrowserDynamicTesting()
21 | );
22 | // Then we find all the tests.
23 | const context = require.context('./', true, /\.spec\.ts$/);
24 | // And load the modules.
25 | context.keys().map(context);
26 |
--------------------------------------------------------------------------------
/projects/propertium-common/src/lib/propertium-auth/propertium-login-page.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { PropertiumLoginPageComponent } from './propertium-login-page.component';
4 |
5 | describe('PropertiumLoginPageComponent', () => {
6 | let component: PropertiumLoginPageComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async(() => {
10 | TestBed.configureTestingModule({
11 | declarations: [ PropertiumLoginPageComponent ]
12 | })
13 | .compileComponents();
14 | }));
15 |
16 | beforeEach(() => {
17 | fixture = TestBed.createComponent(PropertiumLoginPageComponent);
18 | component = fixture.componentInstance;
19 | fixture.detectChanges();
20 | });
21 |
22 | it('should create', () => {
23 | expect(component).toBeTruthy();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/projects/admin-portal/src/app/authentication/login-container.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, ChangeDetectionStrategy } from '@angular/core';
2 | import { LoginCredentials } from '@propertium/common';
3 |
4 | @Component({
5 | selector: 'app-login-container',
6 | template: `
7 |
13 | `,
14 | changeDetection: ChangeDetectionStrategy.OnPush,
15 | })
16 | export class LoginContainerComponent {
17 | loginBackgroundUrl = '../../../assets/images/login-background.jpg';
18 | logoUrl = '../../../assets/images/logo_transparent.png';
19 | loginTitle = 'Admin Login';
20 | constructor() {}
21 |
22 | onLogin(credentials: LoginCredentials) {
23 | console.log('CREDENTIALS: ', credentials);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/projects/propertium-common/src/test.ts:
--------------------------------------------------------------------------------
1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files
2 |
3 | import 'zone.js/dist/zone';
4 | import 'zone.js/dist/zone-testing';
5 | import { getTestBed } from '@angular/core/testing';
6 | import {
7 | BrowserDynamicTestingModule,
8 | platformBrowserDynamicTesting
9 | } from '@angular/platform-browser-dynamic/testing';
10 |
11 | declare const require: {
12 | context(path: string, deep?: boolean, filter?: RegExp): {
13 | keys(): string[];
14 | (id: string): T;
15 | };
16 | };
17 |
18 | // First, initialize the Angular testing environment.
19 | getTestBed().initTestEnvironment(
20 | BrowserDynamicTestingModule,
21 | platformBrowserDynamicTesting()
22 | );
23 | // Then we find all the tests.
24 | const context = require.context('./', true, /\.spec\.ts$/);
25 | // And load the modules.
26 | context.keys().map(context);
27 |
--------------------------------------------------------------------------------
/projects/propertium-common/src/lib/propertium-auth/propertium-login-page.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { ReactiveFormsModule } from '@angular/forms';
4 | import { MatCardModule } from '@angular/material/card';
5 | import { MatFormFieldModule } from '@angular/material/form-field';
6 | import { MatInputModule } from '@angular/material/input';
7 | import { MatButtonModule } from '@angular/material/button';
8 | import { MatIconModule } from '@angular/material/icon';
9 | import { PropertiumLoginPageComponent } from './propertium-login-page.component';
10 |
11 | @NgModule({
12 | declarations: [PropertiumLoginPageComponent],
13 | imports: [
14 | CommonModule,
15 | ReactiveFormsModule,
16 | MatCardModule,
17 | MatFormFieldModule,
18 | MatInputModule,
19 | MatButtonModule,
20 | MatIconModule,
21 | ],
22 | exports: [PropertiumLoginPageComponent],
23 | })
24 | export class PropertiumLoginPageModule {}
25 |
--------------------------------------------------------------------------------
/projects/admin-portal/e2e/protractor.conf.js:
--------------------------------------------------------------------------------
1 | // @ts-check
2 | // Protractor configuration file, see link for more information
3 | // https://github.com/angular/protractor/blob/master/lib/config.ts
4 |
5 | const { SpecReporter, StacktraceOption } = require('jasmine-spec-reporter');
6 |
7 | /**
8 | * @type { import("protractor").Config }
9 | */
10 | exports.config = {
11 | allScriptsTimeout: 11000,
12 | specs: [
13 | './src/**/*.e2e-spec.ts'
14 | ],
15 | capabilities: {
16 | browserName: 'chrome'
17 | },
18 | directConnect: true,
19 | baseUrl: 'http://localhost:4200/',
20 | framework: 'jasmine',
21 | jasmineNodeOpts: {
22 | showColors: true,
23 | defaultTimeoutInterval: 30000,
24 | print: function() {}
25 | },
26 | onPrepare() {
27 | require('ts-node').register({
28 | project: require('path').join(__dirname, './tsconfig.json')
29 | });
30 | jasmine.getEnv().addReporter(new SpecReporter({
31 | spec: {
32 | displayStacktrace: StacktraceOption.PRETTY
33 | }
34 | }));
35 | }
36 | };
--------------------------------------------------------------------------------
/projects/tenant-portal/e2e/protractor.conf.js:
--------------------------------------------------------------------------------
1 | // @ts-check
2 | // Protractor configuration file, see link for more information
3 | // https://github.com/angular/protractor/blob/master/lib/config.ts
4 |
5 | const { SpecReporter, StacktraceOption } = require('jasmine-spec-reporter');
6 |
7 | /**
8 | * @type { import("protractor").Config }
9 | */
10 | exports.config = {
11 | allScriptsTimeout: 11000,
12 | specs: [
13 | './src/**/*.e2e-spec.ts'
14 | ],
15 | capabilities: {
16 | browserName: 'chrome'
17 | },
18 | directConnect: true,
19 | baseUrl: 'http://localhost:4200/',
20 | framework: 'jasmine',
21 | jasmineNodeOpts: {
22 | showColors: true,
23 | defaultTimeoutInterval: 30000,
24 | print: function() {}
25 | },
26 | onPrepare() {
27 | require('ts-node').register({
28 | project: require('path').join(__dirname, './tsconfig.json')
29 | });
30 | jasmine.getEnv().addReporter(new SpecReporter({
31 | spec: {
32 | displayStacktrace: StacktraceOption.PRETTY
33 | }
34 | }));
35 | }
36 | };
--------------------------------------------------------------------------------
/projects/admin-portal/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { BrowserModule } from '@angular/platform-browser';
2 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
3 | import { NgModule } from '@angular/core';
4 |
5 | import { AppRoutingModule } from './app-routing.module';
6 | import { AppComponent } from './app.component';
7 | import { MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field';
8 | import { matFormFieldDefaultOptions, matDialogDefaultOptions } from '@propertium/common';
9 | import { MAT_DIALOG_DEFAULT_OPTIONS } from '@angular/material/dialog';
10 |
11 | @NgModule({
12 | declarations: [AppComponent],
13 | imports: [BrowserModule, BrowserAnimationsModule, AppRoutingModule],
14 | providers: [
15 | {
16 | provide: MAT_FORM_FIELD_DEFAULT_OPTIONS,
17 | useValue: matFormFieldDefaultOptions,
18 | },
19 | {
20 | provide: MAT_DIALOG_DEFAULT_OPTIONS,
21 | useValue: matDialogDefaultOptions,
22 | },
23 | ],
24 | bootstrap: [AppComponent],
25 | })
26 | export class AppModule {}
27 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/home/home.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { Routes, RouterModule } from '@angular/router';
3 | import { MatCardModule } from '@angular/material/card';
4 | import { MatIconModule } from '@angular/material/icon';
5 | import { MatTableModule } from '@angular/material/table';
6 |
7 | import { HomeComponent } from './home.component';
8 | import { AnnouncementModule } from '../announcements/announcement.module';
9 | import { MaintenanceDashboardModule } from '../maintenance/maintenance-dashboard/maintenance-dashboard.module';
10 | import { MatButtonModule } from '@angular/material/button';
11 |
12 | const routes: Routes = [{ path: '', component: HomeComponent }];
13 |
14 | @NgModule({
15 | declarations: [HomeComponent],
16 | imports: [
17 | RouterModule.forChild(routes),
18 | AnnouncementModule,
19 | MaintenanceDashboardModule,
20 | MatCardModule,
21 | MatIconModule,
22 | MatTableModule,
23 | MatButtonModule,
24 | ],
25 | exports: [RouterModule],
26 | providers: [],
27 | })
28 | export class HomeModule {}
29 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/home/home.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-home-container',
5 | templateUrl: './home.component.html',
6 | styleUrls: ['./home.component.scss'],
7 | })
8 | export class HomeComponent {
9 | announcements: any;
10 | announcementOpened = false;
11 | selectedAnnouncement: any;
12 |
13 | displayedColumns: string[] = ['Description', 'Amount'];
14 | tableData: any[] = [
15 | {
16 | item: 'Rent',
17 | amount: '$980.00',
18 | },
19 | {
20 | item: 'Media Package',
21 | amount: '$100.00',
22 | },
23 | {
24 | item: 'Water/Sewer',
25 | amount: '$60.00',
26 | },
27 | {
28 | item: 'Trash',
29 | amount: '$30.00',
30 | },
31 | {
32 | item: 'Pet Rent',
33 | amount: '$35.00',
34 | },
35 | {
36 | item: 'Tenant Liability Insurance',
37 | amount: '$9.50',
38 | },
39 | {
40 | item: 'Credits & Payments',
41 | amount: '$1214.50',
42 | },
43 | ];
44 |
45 | constructor() {}
46 | }
47 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/maintenance/maintenance-list/maintenance-list.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
2 | import { Observable } from 'rxjs';
3 | import { MaintenanceService } from '../../maintenance/maintenance.service';
4 | import { PaginatedResponse } from '../../shared/interfaces/paginated-response.interface';
5 | import { Maintenance } from '../maintenance.interface';
6 |
7 | @Component({
8 | selector: 'app-maintenance-list',
9 | templateUrl: './maintenance-list.component.html',
10 | styleUrls: ['./maintenance-list.component.scss'],
11 | changeDetection: ChangeDetectionStrategy.OnPush,
12 | })
13 | export class MaintenanceListComponent implements OnInit {
14 | displayedColumns: string[] = ['Date', 'Description', 'Permission to Enter', 'Status', 'Completed On'];
15 | paginatedMaintenanceRequests$: Observable>;
16 |
17 | constructor(private maintenanceService: MaintenanceService) {}
18 |
19 | ngOnInit() {
20 | this.paginatedMaintenanceRequests$ = this.maintenanceService.getMaintenanceList();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/projects/tenant-portal/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration file, see link for more information
2 | // https://karma-runner.github.io/0.13/config/configuration-file.html
3 |
4 | module.exports = function (config) {
5 | config.set({
6 | basePath: '',
7 | frameworks: ['jasmine', '@angular-devkit/build-angular'],
8 | plugins: [
9 | require('karma-jasmine'),
10 | require('karma-chrome-launcher'),
11 | require('karma-jasmine-html-reporter'),
12 | require('karma-coverage-istanbul-reporter'),
13 | require('@angular-devkit/build-angular/plugins/karma'),
14 | ],
15 | client: {
16 | clearContext: false, // leave Jasmine Spec Runner output visible in browser
17 | },
18 | coverageIstanbulReporter: {
19 | dir: require('path').join(__dirname, 'coverage'),
20 | reports: ['html', 'lcovonly'],
21 | fixWebpackSourcePaths: true,
22 | },
23 |
24 | reporters: ['progress', 'kjhtml'],
25 | port: 9876,
26 | colors: true,
27 | logLevel: config.LOG_INFO,
28 | autoWatch: true,
29 | browsers: ['Chrome'],
30 | singleRun: false,
31 | });
32 | };
33 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/authentication/login-container.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { Router } from '@angular/router';
3 | import { LoginCredentials } from '@propertium/common';
4 | import { AuthenticationService } from './authentication.service';
5 |
6 | @Component({
7 | selector: 'app-login-container',
8 | template: `
9 |
15 | `,
16 | })
17 | export class LoginContainerComponent {
18 | loginBackgroundUrl = '../../../assets/images/login-background.jpg';
19 | logoUrl = '../../../assets/images/logo_transparent.png';
20 | loginTitle = 'Tenant Login';
21 |
22 | constructor(private authService: AuthenticationService, private router: Router) {}
23 |
24 | onSubmit(credentials: LoginCredentials) {
25 | this.authService.getTokenFromServer(credentials).subscribe(
26 | (res) => {
27 | this.router.navigate(['/connect']);
28 | },
29 | (err) => {}
30 | );
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/maintenance/maintenance-dashboard/maintenance-dashboard.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, ChangeDetectionStrategy, OnInit } from '@angular/core';
2 | import { MaintenanceService } from '../maintenance.service';
3 | import { Observable } from 'rxjs';
4 | import { Router } from '@angular/router';
5 | import { AppUrl } from '../../shared/enums/app-url.enum';
6 |
7 | @Component({
8 | selector: 'app-maintenance-dashboard',
9 | templateUrl: './maintenance-dashboard.component.html',
10 | styleUrls: ['./maintenance-dashboard.component.scss'],
11 | changeDetection: ChangeDetectionStrategy.OnPush,
12 | })
13 | export class MaintenanceDashboardComponent implements OnInit {
14 | numOfPendingRequests$: Observable;
15 | constructor(private maintenanceService: MaintenanceService, private router: Router) {}
16 |
17 | ngOnInit() {
18 | this.numOfPendingRequests$ = this.maintenanceService.getNumberOfPendingRequests();
19 | }
20 |
21 | onViewClicked() {
22 | this.router.navigate([AppUrl.MAINTENANCE_LIST]);
23 | }
24 |
25 | onRequestClicked() {
26 | this.router.navigate([AppUrl.MAINTENANCE_CREATE]);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/projects/admin-portal/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration file, see link for more information
2 | // https://karma-runner.github.io/1.0/config/configuration-file.html
3 |
4 | module.exports = function (config) {
5 | config.set({
6 | basePath: '',
7 | frameworks: ['jasmine', '@angular-devkit/build-angular'],
8 | plugins: [
9 | require('karma-jasmine'),
10 | require('karma-chrome-launcher'),
11 | require('karma-jasmine-html-reporter'),
12 | require('karma-coverage-istanbul-reporter'),
13 | require('@angular-devkit/build-angular/plugins/karma')
14 | ],
15 | client: {
16 | clearContext: false // leave Jasmine Spec Runner output visible in browser
17 | },
18 | coverageIstanbulReporter: {
19 | dir: require('path').join(__dirname, '../../coverage/admin-portal'),
20 | reports: ['html', 'lcovonly', 'text-summary'],
21 | fixWebpackSourcePaths: true
22 | },
23 | reporters: ['progress', 'kjhtml'],
24 | port: 9876,
25 | colors: true,
26 | logLevel: config.LOG_INFO,
27 | autoWatch: true,
28 | browsers: ['Chrome'],
29 | singleRun: false,
30 | restartOnFileChange: true
31 | });
32 | };
33 |
--------------------------------------------------------------------------------
/projects/propertium-common/README.md:
--------------------------------------------------------------------------------
1 | # PropertiumCommon
2 |
3 | This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 10.0.2.
4 |
5 | ## Code scaffolding
6 |
7 | Run `ng generate component component-name --project propertium-common` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project propertium-common`.
8 | > Note: Don't forget to add `--project propertium-common` or else it will be added to the default project in your `angular.json` file.
9 |
10 | ## Build
11 |
12 | Run `ng build propertium-common` to build the project. The build artifacts will be stored in the `dist/` directory.
13 |
14 | ## Publishing
15 |
16 | After building your library with `ng build propertium-common`, go to the dist folder `cd dist/propertium-common` and run `npm publish`.
17 |
18 | ## Running unit tests
19 |
20 | Run `ng test propertium-common` to execute the unit tests via [Karma](https://karma-runner.github.io).
21 |
22 | ## Further help
23 |
24 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PropertyManagement
2 |
3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.1.2.
4 |
5 | ## Development server
6 |
7 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
8 |
9 | ## Code scaffolding
10 |
11 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|module`.
12 |
13 | ## Build
14 |
15 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build.
16 |
17 | ## Running unit tests
18 |
19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
20 |
21 | ## Running end-to-end tests
22 |
23 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
24 | Before running the tests make sure you are serving the app via `ng serve`.
25 |
26 | ## Further help
27 |
28 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
29 |
--------------------------------------------------------------------------------
/projects/propertium-common/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration file, see link for more information
2 | // https://karma-runner.github.io/1.0/config/configuration-file.html
3 |
4 | module.exports = function (config) {
5 | config.set({
6 | basePath: '',
7 | frameworks: ['jasmine', '@angular-devkit/build-angular'],
8 | plugins: [
9 | require('karma-jasmine'),
10 | require('karma-chrome-launcher'),
11 | require('karma-jasmine-html-reporter'),
12 | require('karma-coverage-istanbul-reporter'),
13 | require('@angular-devkit/build-angular/plugins/karma')
14 | ],
15 | client: {
16 | clearContext: false // leave Jasmine Spec Runner output visible in browser
17 | },
18 | coverageIstanbulReporter: {
19 | dir: require('path').join(__dirname, '../../coverage/propertium-common'),
20 | reports: ['html', 'lcovonly', 'text-summary'],
21 | fixWebpackSourcePaths: true
22 | },
23 | reporters: ['progress', 'kjhtml'],
24 | port: 9876,
25 | colors: true,
26 | logLevel: config.LOG_INFO,
27 | autoWatch: true,
28 | browsers: ['Chrome'],
29 | singleRun: false,
30 | restartOnFileChange: true
31 | });
32 | };
33 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/test.ts:
--------------------------------------------------------------------------------
1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files
2 |
3 | import 'zone.js/dist/long-stack-trace-zone';
4 | import 'zone.js/dist/proxy.js';
5 | import 'zone.js/dist/sync-test';
6 | import 'zone.js/dist/jasmine-patch';
7 | import 'zone.js/dist/async-test';
8 | import 'zone.js/dist/fake-async-test';
9 | import { getTestBed } from '@angular/core/testing';
10 | import {
11 | BrowserDynamicTestingModule,
12 | platformBrowserDynamicTesting
13 | } from '@angular/platform-browser-dynamic/testing';
14 |
15 | // Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
16 | declare const __karma__: any;
17 | declare const require: any;
18 |
19 | // Prevent Karma from running prematurely.
20 | __karma__.loaded = function () {};
21 |
22 | // First, initialize the Angular testing environment.
23 | getTestBed().initTestEnvironment(
24 | BrowserDynamicTestingModule,
25 | platformBrowserDynamicTesting()
26 | );
27 | // Then we find all the tests.
28 | const context = require.context('./', true, /\.spec\.ts$/);
29 | // And load the modules.
30 | context.keys().map(context);
31 | // Finally, start Karma to run the tests.
32 | __karma__.start();
33 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { BrowserModule } from '@angular/platform-browser';
3 | import { MatToolbarModule } from '@angular/material/toolbar';
4 | import { MatIconModule } from '@angular/material/icon';
5 | import { MatMenuModule } from '@angular/material/menu';
6 | import { MatSidenavModule } from '@angular/material/sidenav';
7 | import { MatListModule } from '@angular/material/list';
8 | import { MatButtonModule } from '@angular/material/button';
9 |
10 | import { CoreModule } from './core.module';
11 | import { AppRouter } from './app-router.module';
12 | import { AppComponent } from './app.component';
13 | import { AppWrapperComponent } from './app-wrapper/app-wrapper.component';
14 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
15 |
16 | @NgModule({
17 | declarations: [AppComponent, AppWrapperComponent],
18 | imports: [
19 | BrowserModule,
20 | CoreModule,
21 | AppRouter,
22 | BrowserAnimationsModule,
23 | MatToolbarModule,
24 | MatIconModule,
25 | MatMenuModule,
26 | MatSidenavModule,
27 | MatListModule,
28 | MatButtonModule,
29 | ],
30 | bootstrap: [AppComponent],
31 | })
32 | export class AppModule {}
33 |
--------------------------------------------------------------------------------
/projects/admin-portal/src/app/app.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed, async } from '@angular/core/testing';
2 | import { RouterTestingModule } from '@angular/router/testing';
3 | import { AppComponent } from './app.component';
4 |
5 | describe('AppComponent', () => {
6 | beforeEach(async(() => {
7 | TestBed.configureTestingModule({
8 | imports: [
9 | RouterTestingModule
10 | ],
11 | declarations: [
12 | AppComponent
13 | ],
14 | }).compileComponents();
15 | }));
16 |
17 | it('should create the app', () => {
18 | const fixture = TestBed.createComponent(AppComponent);
19 | const app = fixture.componentInstance;
20 | expect(app).toBeTruthy();
21 | });
22 |
23 | it(`should have as title 'admin-portal'`, () => {
24 | const fixture = TestBed.createComponent(AppComponent);
25 | const app = fixture.componentInstance;
26 | expect(app.title).toEqual('admin-portal');
27 | });
28 |
29 | it('should render title', () => {
30 | const fixture = TestBed.createComponent(AppComponent);
31 | fixture.detectChanges();
32 | const compiled = fixture.nativeElement;
33 | expect(compiled.querySelector('.content span').textContent).toContain('admin-portal app is running!');
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/maintenance/maintenance-create/maintenance-create.component.html:
--------------------------------------------------------------------------------
1 |
31 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/announcements/announcement.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { HttpClient } from '@angular/common/http';
3 | import { Observable } from 'rxjs';
4 | import { shareReplay } from 'rxjs/operators';
5 | import { environment } from '../../environments/environment';
6 | import { PaginatedResponse } from '../shared/interfaces/paginated-response.interface';
7 | import { Announcement } from './announcement-detail/announcement.interface';
8 |
9 | @Injectable({ providedIn: 'root' })
10 | export class AnnouncementService {
11 | private announcementUrl: string = environment.baseUrl + '/announcements/';
12 | private announcements$: Observable>;
13 |
14 | constructor(private http: HttpClient) {}
15 |
16 | fetchAnnouncements(): Observable> {
17 | if (!this.announcements$) {
18 | this.announcements$ = this.http
19 | .get>(`${this.announcementUrl}`)
20 | .pipe(shareReplay(1));
21 | }
22 | return this.announcements$;
23 | }
24 |
25 | fetchAnnouncement(url: string): Observable {
26 | return this.http.get(url);
27 | }
28 |
29 | clearCache() {
30 | this.announcements$ = null;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/announcements/announcement-list/announcement-list.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
2 | import { Observable } from 'rxjs';
3 | import { MatDialog } from '@angular/material/dialog';
4 | import { PaginatedResponse } from '../../shared/interfaces/paginated-response.interface';
5 | import { AnnouncementService } from '../announcement.service';
6 | import { Announcement } from '../announcement-detail/announcement.interface';
7 | import { AnnouncementDetailComponent } from '../announcement-detail/announcement-detail.component';
8 |
9 | @Component({
10 | selector: 'app-announcement-list',
11 | templateUrl: './announcement-list.component.html',
12 | styleUrls: ['./announcement-list.component.scss'],
13 | changeDetection: ChangeDetectionStrategy.OnPush,
14 | })
15 | export class AnnouncementListComponent implements OnInit {
16 | announcements$: Observable>;
17 | constructor(private announcementService: AnnouncementService, private dialogService: MatDialog) {}
18 |
19 | ngOnInit() {
20 | this.announcements$ = this.announcementService.fetchAnnouncements();
21 | }
22 |
23 | openAnnouncement(announcement: Announcement) {
24 | this.dialogService.open(AnnouncementDetailComponent, {
25 | data: { announcement },
26 | });
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/projects/propertium-common/src/lib/propertium-auth/propertium-login-page.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit, Output, EventEmitter, Input } from '@angular/core';
2 | import { FormGroup, FormBuilder, Validators } from '@angular/forms';
3 | import { LoginCredentials } from './login-credentials.interface';
4 |
5 | @Component({
6 | selector: 'propertium-login-page',
7 | templateUrl: './propertium-login-page.component.html',
8 | styleUrls: ['./propertium-login-page.component.scss'],
9 | })
10 | export class PropertiumLoginPageComponent implements OnInit {
11 | @Input() backgroundUrl: string;
12 | @Input() logoUrl: string;
13 | @Input() loginTitle: string;
14 | @Output() login = new EventEmitter();
15 | loginForm: FormGroup;
16 | passwordInputType = 'password';
17 |
18 | constructor(private fb: FormBuilder) {}
19 |
20 | ngOnInit(): void {
21 | this.initializeLoginForm();
22 | }
23 |
24 | onSubmit(): void {
25 | this.login.emit(this.loginForm.value);
26 | }
27 |
28 | togglePasswordInputType() {
29 | this.passwordInputType = this.passwordInputType === 'password' ? 'text' : 'password';
30 | }
31 |
32 | private initializeLoginForm(): void {
33 | this.loginForm = this.fb.group({
34 | email: ['', [Validators.required, Validators.email]],
35 | password: ['', Validators.required],
36 | });
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/core.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule, LocationStrategy, HashLocationStrategy } from '@angular/common';
3 | import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
4 |
5 | import { ChargeService } from './charges/charge.service';
6 | import { LeaseService } from './leases/lease.service';
7 |
8 | import { HeadersInterceptor } from './shared/interceptors/headers.interceptor';
9 | import { MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field';
10 | import { matFormFieldDefaultOptions } from './shared/material-defaults/mat-form-field-default-options';
11 | import { MAT_DIALOG_DEFAULT_OPTIONS } from '@angular/material/dialog';
12 | import { matDialogDefaultOptions } from './shared/material-defaults/mat-dialog-default-options';
13 |
14 | @NgModule({
15 | declarations: [],
16 | imports: [CommonModule, HttpClientModule],
17 | exports: [],
18 | providers: [
19 | ChargeService,
20 | LeaseService,
21 | { provide: HTTP_INTERCEPTORS, useClass: HeadersInterceptor, multi: true },
22 | {
23 | provide: LocationStrategy,
24 | useClass: HashLocationStrategy,
25 | },
26 | {
27 | provide: MAT_FORM_FIELD_DEFAULT_OPTIONS,
28 | useValue: matFormFieldDefaultOptions,
29 | },
30 | {
31 | provide: MAT_DIALOG_DEFAULT_OPTIONS,
32 | useValue: matDialogDefaultOptions,
33 | },
34 | ],
35 | })
36 | export class CoreModule {}
37 |
--------------------------------------------------------------------------------
/projects/propertium-common/src/lib/propertium-auth/propertium-login-page.component.html:
--------------------------------------------------------------------------------
1 |
31 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/maintenance/maintenance-list/maintenance-list.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | | Date |
6 | {{ element.dateCreated | date: 'medium' }} |
7 |
8 |
9 |
10 | Description |
11 | {{ element.description }} |
12 |
13 |
14 |
15 | Permission to Enter |
16 | {{ element.permissionToEnter ? 'Yes' : 'No' }} |
17 |
18 |
19 |
20 | Status |
21 | {{ element.status | titlecase }} |
22 |
23 |
24 |
25 | Completed On |
26 | {{ element.dateCompleted | date: 'medium' }} |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/app-wrapper/app-wrapper.component.html:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
33 | {{ link.icon }} {{ link.title }}
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/maintenance/maintenance.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { Routes, RouterModule } from '@angular/router';
4 | import { ReactiveFormsModule } from '@angular/forms';
5 | import { MatCardModule } from '@angular/material/card';
6 | import { MatFormFieldModule } from '@angular/material/form-field';
7 | import { MatRadioModule } from '@angular/material/radio';
8 | import { MatInputModule } from '@angular/material/input';
9 | import { MatTableModule } from '@angular/material/table';
10 | import { MatButtonModule } from '@angular/material/button';
11 | import { MaintenanceComponent } from './maintenance.component';
12 | import { MaintenanceListComponent } from './maintenance-list/maintenance-list.component';
13 | import { MaintenanceCreateComponent } from './maintenance-create/maintenance-create.component';
14 |
15 | const routes: Routes = [
16 | {
17 | path: '',
18 | component: MaintenanceComponent,
19 | children: [
20 | { path: '', redirectTo: 'list', pathMatch: 'full' },
21 | { path: 'list', component: MaintenanceListComponent },
22 | { path: 'create', component: MaintenanceCreateComponent },
23 | ],
24 | },
25 | ];
26 |
27 | @NgModule({
28 | declarations: [MaintenanceComponent, MaintenanceListComponent, MaintenanceCreateComponent],
29 | imports: [
30 | CommonModule,
31 | RouterModule.forChild(routes),
32 | ReactiveFormsModule,
33 | MatCardModule,
34 | MatFormFieldModule,
35 | MatRadioModule,
36 | MatInputModule,
37 | MatTableModule,
38 | MatButtonModule,
39 | ],
40 | exports: [RouterModule],
41 | })
42 | export class MaintenanceModule {}
43 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/shared/interceptors/headers.interceptor.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { HttpInterceptor, HttpHandler, HttpRequest, HttpEvent, HttpErrorResponse } from '@angular/common/http';
3 | import { throwError, Observable } from 'rxjs';
4 | import { catchError } from 'rxjs/operators';
5 | import { AuthenticationService } from '../../authentication/authentication.service';
6 |
7 | @Injectable()
8 | export class HeadersInterceptor implements HttpInterceptor {
9 | constructor(private authService: AuthenticationService) {}
10 | intercept(req: HttpRequest, next: HttpHandler): Observable> {
11 | let headersConfig = req.clone({ headers: req.headers.set('Accept', 'application/json') });
12 |
13 | const token = this.authService.token;
14 |
15 | if (token && token.access) {
16 | headersConfig = headersConfig.clone({
17 | headers: headersConfig.headers.set('Authorization', `jwt ${token.access}`),
18 | });
19 | }
20 |
21 | if (!headersConfig.headers.has('Content-Type') && !(headersConfig.body instanceof FormData)) {
22 | headersConfig = headersConfig.clone({ headers: headersConfig.headers.set('Content-Type', 'application/json') });
23 | }
24 |
25 | const request = headersConfig.clone();
26 | return next.handle(request).pipe(
27 | catchError((error: HttpErrorResponse) => {
28 | let errorMessage = '';
29 | if (error.error instanceof ErrorEvent) {
30 | // client-side error
31 | errorMessage = `Error: ${error.error.message}`;
32 | } else {
33 | // server-side error
34 | errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
35 | }
36 | return throwError(errorMessage);
37 | })
38 | );
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/maintenance/maintenance-create/maintenance-create.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
2 | import { Location } from '@angular/common';
3 | import { MaintenanceCreatePayload } from './maintenance-create-payload.interface';
4 | import { MaintenanceService } from '../../maintenance/maintenance.service';
5 | import { FormBuilder, Validators, FormGroup } from '@angular/forms';
6 | import { finalize } from 'rxjs/operators';
7 | import { Router } from '@angular/router';
8 | import { AppUrl } from '../../shared/enums/app-url.enum';
9 |
10 | @Component({
11 | selector: 'app-maintenance-create',
12 | templateUrl: './maintenance-create.component.html',
13 | styleUrls: ['./maintenance-create.component.scss'],
14 | changeDetection: ChangeDetectionStrategy.OnPush,
15 | })
16 | export class MaintenanceCreateComponent implements OnInit {
17 | loading: boolean;
18 | maintenanceForm: FormGroup;
19 |
20 | constructor(
21 | private location: Location,
22 | private router: Router,
23 | private maintenanceService: MaintenanceService,
24 | private fb: FormBuilder
25 | ) {}
26 |
27 | ngOnInit() {
28 | this.createMaintenanceForm();
29 | }
30 |
31 | onSubmit() {
32 | const payload: MaintenanceCreatePayload = this.maintenanceForm.value;
33 | this.loading = true;
34 | this.maintenanceService
35 | .createMaintenanceItem(payload)
36 | .pipe(finalize(() => (this.loading = false)))
37 | .subscribe(() => this.router.navigate([AppUrl.MAINTENANCE_LIST]));
38 | }
39 |
40 | goBack() {
41 | this.location.back();
42 | }
43 |
44 | private createMaintenanceForm() {
45 | this.maintenanceForm = this.fb.group({
46 | description: ['', [Validators.required]],
47 | permissionToEnter: [null, [Validators.required]],
48 | });
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/projects/admin-portal/src/styles.scss:
--------------------------------------------------------------------------------
1 | // Custom Theming for Angular Material
2 | // For more information: https://material.angular.io/guide/theming
3 | @import '~@angular/material/theming';
4 | // Plus imports for other components in your app.
5 |
6 | // Include the common styles for Angular Material. We include this here so that you only
7 | // have to load a single css file for Angular Material in your app.
8 | // Be sure that you only ever include this mixin once!
9 | @include mat-core();
10 |
11 | // Define the palettes for your theme using the Material Design palettes available in palette.scss
12 | // (imported above). For each palette, you can optionally specify a default, lighter, and darker
13 | // hue. Available color palettes: https://material.io/design/color/
14 | $admin-portal-primary: mat-palette($mat-indigo);
15 | $admin-portal-accent: mat-palette($mat-pink, A200, A100, A400);
16 |
17 | // The warn palette is optional (defaults to red).
18 | $admin-portal-warn: mat-palette($mat-red);
19 |
20 | // Create the theme object (a Sass map containing all of the palettes).
21 | $admin-portal-theme: mat-light-theme($admin-portal-primary, $admin-portal-accent, $admin-portal-warn);
22 |
23 | // Include theme styles for core and each component used in your app.
24 | // Alternatively, you can import and @include the theme mixins for each component
25 | // that you are using.
26 | @include angular-material-theme($admin-portal-theme);
27 |
28 | $red: #f52f22;
29 | $pink: #f1428a;
30 | $purple: #781da0;
31 | $ultramarine: #343dac;
32 | $blue: #0065ab;
33 | $cyan: #00b7d6;
34 | $teal: #00968b;
35 | $green: #48960c;
36 | $yellow: #ffdc0b;
37 | $orange: #f57600;
38 | $red-orange: #ee4a08;
39 | $warm-grey: #80746d;
40 | $neutral-grey: #747474;
41 | $cool-grey: #61717d;
42 |
43 | html,
44 | body {
45 | height: 100%;
46 | }
47 | body {
48 | margin: 0;
49 | font-family: Roboto, 'Helvetica Neue', sans-serif;
50 | }
51 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/account/account.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { Routes, RouterModule } from '@angular/router';
3 | import { MatCardModule } from '@angular/material/card';
4 | import { MatFormFieldModule } from '@angular/material/form-field';
5 | import { MatCheckboxModule } from '@angular/material/checkbox';
6 | import { MatTabsModule } from '@angular/material/tabs';
7 | import { MatButtonModule } from '@angular/material/button';
8 | import { AccountComponent } from './account.component';
9 | import { AccountDetailComponent } from './account-detail/account-detail.component';
10 | import { SignatureComponent } from './signature/signature.component';
11 | import { PaymentMethodListComponent } from './payment-methods/payment-method-list.component';
12 | import { PaymentMethodDetailComponent } from './payment-methods/payment-method-detail.component';
13 | import { MatInputModule } from '@angular/material/input';
14 |
15 | const routes: Routes = [
16 | {
17 | path: '',
18 | component: AccountComponent,
19 | children: [
20 | { path: '', redirectTo: 'details', pathMatch: 'full' },
21 | { path: 'details', component: AccountDetailComponent },
22 | { path: 'signature', component: SignatureComponent },
23 | { path: 'payment_methods', component: PaymentMethodListComponent },
24 | { path: 'payment_methods/:id', component: PaymentMethodDetailComponent },
25 | ],
26 | },
27 | ];
28 |
29 | @NgModule({
30 | declarations: [
31 | AccountComponent,
32 | AccountDetailComponent,
33 | SignatureComponent,
34 | PaymentMethodListComponent,
35 | PaymentMethodDetailComponent,
36 | ],
37 | imports: [
38 | RouterModule.forChild(routes),
39 | MatCardModule,
40 | MatFormFieldModule,
41 | MatCheckboxModule,
42 | MatTabsModule,
43 | MatButtonModule,
44 | MatInputModule,
45 | ],
46 | exports: [RouterModule],
47 | providers: [],
48 | })
49 | export class AccountModule {}
50 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/app-router.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { RouterModule, Routes } from '@angular/router';
3 | import { AppWrapperComponent } from './app-wrapper/app-wrapper.component';
4 | import { AuthGuard } from './authentication/auth.guard';
5 |
6 | const routes: Routes = [
7 | { path: '', redirectTo: 'connect', pathMatch: 'full' },
8 | {
9 | path: 'login',
10 | loadChildren: () => import('./authentication/authentication.module').then((m) => m.AuthenticationModule),
11 | },
12 | {
13 | path: 'connect',
14 | canActivate: [AuthGuard],
15 | component: AppWrapperComponent,
16 | children: [
17 | {
18 | path: '',
19 | redirectTo: 'home',
20 | pathMatch: 'full',
21 | },
22 | {
23 | path: 'home',
24 | loadChildren: () => import('./home/home.module').then((m) => m.HomeModule),
25 | },
26 | {
27 | path: 'help',
28 | loadChildren: () => import('./help/help.module').then((m) => m.HelpModule),
29 | },
30 | {
31 | path: 'maintenance',
32 | loadChildren: () => import('./maintenance/maintenance.module').then((m) => m.MaintenanceModule),
33 | },
34 | {
35 | path: 'payments',
36 | loadChildren: () => import('./payments/payments.module').then((m) => m.PaymentsModule),
37 | },
38 | {
39 | path: 'property',
40 | loadChildren: () => import('./properties/property.module').then((m) => m.PropertyModule),
41 | },
42 | {
43 | path: 'documents',
44 | loadChildren: () => import('./documents/documents.module').then((m) => m.DocumentsModule),
45 | },
46 | {
47 | path: 'account',
48 | loadChildren: () => import('./account/account.module').then((m) => m.AccountModule),
49 | },
50 | ],
51 | },
52 | ];
53 |
54 | @NgModule({
55 | imports: [RouterModule.forRoot(routes)],
56 | exports: [RouterModule],
57 | })
58 | export class AppRouter {}
59 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/maintenance/maintenance.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { HttpClient } from '@angular/common/http';
3 | import { Observable } from 'rxjs';
4 | import { shareReplay, tap } from 'rxjs/operators';
5 | import { environment } from '../../environments/environment';
6 | import { Maintenance } from './maintenance.interface';
7 | import { MaintenanceCreatePayload } from './maintenance-create/maintenance-create-payload.interface';
8 | import { PaginatedResponse } from '../shared/interfaces/paginated-response.interface';
9 |
10 | @Injectable({ providedIn: 'root' })
11 | export class MaintenanceService {
12 | private maintenanceUrl: string = environment.baseUrl + '/maintenance/';
13 | private maintenanceRequests$: Observable>;
14 | private numberOfPendingRequests$: Observable;
15 |
16 | constructor(private http: HttpClient) {}
17 |
18 | getMaintenanceList(): Observable> {
19 | if (!this.maintenanceRequests$) {
20 | this.maintenanceRequests$ = this.http
21 | .get>(this.maintenanceUrl)
22 | .pipe(shareReplay(1));
23 | }
24 | return this.maintenanceRequests$;
25 | }
26 |
27 | getMaintenanceItem(id: string): Observable {
28 | return this.http.get(this.maintenanceUrl);
29 | }
30 |
31 | createMaintenanceItem(payload: MaintenanceCreatePayload): Observable {
32 | return this.http.post(this.maintenanceUrl, payload).pipe(tap(() => this.resetMaintenanceListCache()));
33 | }
34 |
35 | getNumberOfPendingRequests(): Observable {
36 | if (!this.numberOfPendingRequests$) {
37 | this.numberOfPendingRequests$ = this.http
38 | .get(`${this.maintenanceUrl}pending_requests/`)
39 | .pipe(shareReplay(1));
40 | }
41 | return this.numberOfPendingRequests$;
42 | }
43 |
44 | private resetMaintenanceListCache() {
45 | this.maintenanceRequests$ = null;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/authentication/auth.guard.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import {
3 | ActivatedRouteSnapshot,
4 | CanActivate,
5 | RouterStateSnapshot,
6 | Router,
7 | CanLoad,
8 | CanActivateChild,
9 | Route,
10 | } from '@angular/router';
11 | import { Observable, of } from 'rxjs';
12 | import { switchMap } from 'rxjs/operators';
13 | import { AuthenticationService } from './authentication.service';
14 | import { Token } from './authentication.service';
15 | import { AppUrl } from '../shared/enums/app-url.enum';
16 |
17 | @Injectable({ providedIn: 'root' })
18 | export class AuthGuard implements CanActivate, CanActivateChild, CanLoad {
19 | constructor(private router: Router, private authService: AuthenticationService) {}
20 |
21 | canActivate(): Observable {
22 | return this.authService.token$.pipe(
23 | switchMap((token) => {
24 | if (token && !this.authService.isTokenExpired(token.access)) {
25 | return of(true);
26 | }
27 |
28 | const localStorageToken = this.authService.getTokenFromLocalStorage();
29 | if (localStorageToken && !this.authService.isTokenExpired(localStorageToken.access)) {
30 | this.authService.setAuthToken(localStorageToken);
31 | return of(true);
32 | }
33 |
34 | if (localStorageToken && !this.authService.isTokenExpired(localStorageToken.refresh)) {
35 | return this.authService.refreshTokenFromServer(localStorageToken.refresh).pipe(
36 | switchMap((res: Token) => {
37 | this.authService.setAuthToken(res);
38 | return of(!!this.authService.token$);
39 | })
40 | );
41 | }
42 |
43 | this.router.navigate([AppUrl.LOGIN]);
44 | return of(false);
45 | })
46 | );
47 | }
48 |
49 | canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable {
50 | return this.canActivate();
51 | }
52 |
53 | canLoad(route: Route): Observable {
54 | return this.canActivate();
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/app-wrapper/app-wrapper.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit, OnDestroy } from '@angular/core';
2 | import { AuthenticationService } from '../authentication/authentication.service';
3 | import { Breakpoints, BreakpointObserver } from '@angular/cdk/layout';
4 | import { takeUntil } from 'rxjs/operators';
5 | import { Subject } from 'rxjs';
6 |
7 | @Component({
8 | selector: 'app-wrapper',
9 | templateUrl: './app-wrapper.component.html',
10 | styleUrls: ['./app-wrapper.component.scss'],
11 | })
12 | export class AppWrapperComponent implements OnInit, OnDestroy {
13 | isMobile: boolean;
14 | drawerMode: string;
15 | navLinks = [
16 | { title: 'Dashboard', url: '/connect/home', icon: 'dashboard' },
17 | { title: 'Payments', url: '/connect/payments', icon: 'payment' },
18 | { title: 'Maintenance', url: '/connect/maintenance', icon: 'engineering' },
19 | { title: 'Documents', url: '/connect/documents', icon: 'snippet_folder' },
20 | { title: 'Property', url: '/connect/property', icon: 'apartment' },
21 | { title: 'Account', url: '/connect/account', icon: 'account_box' },
22 | { title: 'Help', url: '/connect/help', icon: 'help_center' },
23 | ];
24 | ngUnsubscribe$: Subject = new Subject();
25 |
26 | constructor(private authService: AuthenticationService, private breakpointObserver: BreakpointObserver) {}
27 |
28 | ngOnInit() {
29 | this.manageScreenSize();
30 | }
31 |
32 | ngOnDestroy() {
33 | this.ngUnsubscribe$.next();
34 | this.ngUnsubscribe$.complete();
35 | }
36 |
37 | logout() {
38 | this.authService.logout();
39 | }
40 |
41 | private manageScreenSize() {
42 | /* Subscribe to screen size. */
43 | this.breakpointObserver
44 | .observe([Breakpoints.Handset, Breakpoints.TabletPortrait])
45 | .pipe(takeUntil(this.ngUnsubscribe$))
46 | .subscribe((result) => {
47 | if (result.matches) {
48 | this.isMobile = true;
49 | this.drawerMode = 'over';
50 | } else {
51 | this.isMobile = false;
52 | this.drawerMode = 'side';
53 | }
54 | });
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/assets/css/_text.scss:
--------------------------------------------------------------------------------
1 | .text-justify {
2 | text-align: justify !important;
3 | }
4 |
5 | .text-nowrap {
6 | white-space: nowrap !important;
7 | }
8 |
9 | .text-truncate {
10 | overflow: hidden;
11 | text-overflow: ellipsis;
12 | white-space: nowrap;
13 | }
14 |
15 | .text-left {
16 | text-align: left !important;
17 | }
18 |
19 | .text-right {
20 | text-align: right !important;
21 | }
22 |
23 | .text-center {
24 | text-align: center !important;
25 | }
26 |
27 | @media (min-width: 576px) {
28 | .text-sm-left {
29 | text-align: left !important;
30 | }
31 | .text-sm-right {
32 | text-align: right !important;
33 | }
34 | .text-sm-center {
35 | text-align: center !important;
36 | }
37 | }
38 |
39 | @media (min-width: 768px) {
40 | .text-md-left {
41 | text-align: left !important;
42 | }
43 | .text-md-right {
44 | text-align: right !important;
45 | }
46 | .text-md-center {
47 | text-align: center !important;
48 | }
49 | }
50 |
51 | @media (min-width: 992px) {
52 | .text-lg-left {
53 | text-align: left !important;
54 | }
55 | .text-lg-right {
56 | text-align: right !important;
57 | }
58 | .text-lg-center {
59 | text-align: center !important;
60 | }
61 | }
62 |
63 | @media (min-width: 1200px) {
64 | .text-xl-left {
65 | text-align: left !important;
66 | }
67 | .text-xl-right {
68 | text-align: right !important;
69 | }
70 | .text-xl-center {
71 | text-align: center !important;
72 | }
73 | }
74 |
75 | .text-lowercase {
76 | text-transform: lowercase !important;
77 | }
78 |
79 | .text-uppercase {
80 | text-transform: uppercase !important;
81 | }
82 |
83 | .text-capitalize {
84 | text-transform: capitalize !important;
85 | }
86 |
87 | .font-weight-normal {
88 | font-weight: normal;
89 | }
90 |
91 | .font-weight-bold {
92 | font-weight: bold;
93 | }
94 |
95 | .font-italic {
96 | font-style: italic;
97 | }
98 |
99 | .text-hide {
100 | font: 0/0 a;
101 | color: transparent;
102 | text-shadow: none;
103 | background-color: transparent;
104 | border: 0;
105 | }
106 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/assets/css/styles.scss:
--------------------------------------------------------------------------------
1 | // Custom Theming for Angular Material
2 | // For more information: https://material.angular.io/guide/theming
3 | @import '~@angular/material/theming';
4 | // Plus imports for other components in your app.
5 |
6 | // Include the common styles for Angular Material. We include this here so that you only
7 | // have to load a single css file for Angular Material in your app.
8 | // Be sure that you only ever include this mixin once!
9 | @include mat-core();
10 |
11 | // Define the palettes for your theme using the Material Design palettes available in palette.scss
12 | // (imported above). For each palette, you can optionally specify a default, lighter, and darker
13 | // hue. Available color palettes: https://material.io/design/color/
14 | $tenant-portal-primary: mat-palette($mat-indigo);
15 | $tenant-portal-accent: mat-palette($mat-pink, A200, A100, A400);
16 |
17 | // The warn palette is optional (defaults to red).
18 | $tenant-portal-warn: mat-palette($mat-red);
19 |
20 | // Create the theme object (a Sass map containing all of the palettes).
21 | $tenant-portal-theme: mat-light-theme($tenant-portal-primary, $tenant-portal-accent, $tenant-portal-warn);
22 |
23 | // Include theme styles for core and each component used in your app.
24 | // Alternatively, you can import and @include the theme mixins for each component
25 | // that you are using.
26 | @include angular-material-theme($tenant-portal-theme);
27 |
28 | @import url('./_flex.scss');
29 | @import url('./_utility.scss');
30 | @import url('./_text.scss');
31 | // @import url('./material-overrides/material-overrides.scss');
32 |
33 | $red: #f52f22;
34 | $pink: #f1428a;
35 | $purple: #781da0;
36 | $ultramarine: #343dac;
37 | $blue: #0065ab;
38 | $cyan: #00b7d6;
39 | $teal: #00968b;
40 | $green: #48960c;
41 | $yellow: #ffdc0b;
42 | $orange: #f57600;
43 | $red-orange: #ee4a08;
44 | $warm-grey: #80746d;
45 | $neutral-grey: #747474;
46 | $cool-grey: #61717d;
47 |
48 | .announcement {
49 | background-color: $yellow;
50 | }
51 |
52 | .address {
53 | background-color: $red !important;
54 | }
55 |
56 | .maintenance {
57 | background-color: $ultramarine !important;
58 | }
59 |
60 | .lease {
61 | background-color: $green !important;
62 | }
63 |
64 | .pointer {
65 | cursor: pointer;
66 | }
67 |
68 | html,
69 | body {
70 | height: 100%;
71 | }
72 | body {
73 | margin: 0;
74 | font-family: Roboto, 'Helvetica Neue', sans-serif;
75 | }
76 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/authentication/authentication.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { Router } from '@angular/router';
3 | import { HttpClient } from '@angular/common/http';
4 | import { BehaviorSubject, Observable } from 'rxjs';
5 | import { tap } from 'rxjs/operators';
6 | import { JwtHelperService } from '@auth0/angular-jwt';
7 | import { LoginCredentials } from '@propertium/common';
8 | import { environment } from '../../environments/environment';
9 | import { AppUrl } from '../shared/enums/app-url.enum';
10 |
11 | export interface Token {
12 | access: string;
13 | refresh: string;
14 | }
15 |
16 | @Injectable({ providedIn: 'root' })
17 | export class AuthenticationService {
18 | token$: Observable;
19 | private baseUrl: string = environment.baseUrl + '/auth';
20 | private jwtHelper: JwtHelperService = new JwtHelperService();
21 | private _token: BehaviorSubject = new BehaviorSubject(null);
22 |
23 | constructor(private http: HttpClient, private router: Router) {
24 | this.token$ = this._token.asObservable();
25 | }
26 | get token(): Token {
27 | return this._token.getValue();
28 | }
29 |
30 | getTokenFromServer(creds: LoginCredentials): Observable {
31 | return this.http.post(`${this.baseUrl}/get_token/tenant/`, creds).pipe(
32 | tap((token) => {
33 | this.setAuthToken(token);
34 | })
35 | );
36 | }
37 |
38 | refreshTokenFromServer(tokenString: string) {
39 | return this.http
40 | .post(`${this.baseUrl}/refresh_token/`, { refresh: tokenString })
41 | .pipe(
42 | tap((token) => {
43 | this.setAuthToken(token);
44 | })
45 | );
46 | }
47 |
48 | setAuthToken(token: Token) {
49 | this.saveTokenToLocalStorage(token);
50 | this._token.next(token);
51 | }
52 |
53 | saveTokenToLocalStorage(token: Token) {
54 | localStorage.setItem('token', JSON.stringify(token));
55 | }
56 |
57 | getTokenFromLocalStorage(): Token {
58 | return JSON.parse(localStorage.getItem('token'));
59 | }
60 |
61 | removeTokenFromLocalStorage() {
62 | localStorage.removeItem('token');
63 | }
64 |
65 | isTokenExpired(tokenString: string) {
66 | return this.jwtHelper.isTokenExpired(tokenString);
67 | }
68 |
69 | decodeToken() {
70 | return this.token && this.jwtHelper.decodeToken(this.token.access);
71 | }
72 |
73 | logout() {
74 | this.removeTokenFromLocalStorage();
75 | this._token.next(null);
76 | this.router.navigate([AppUrl.LOGIN]).then(() => location.reload());
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tenant-portal",
3 | "version": "0.0.0",
4 | "license": "MIT",
5 | "scripts": {
6 | "ng": "ng",
7 | "start:tenant": "ng serve --project tenant-portal --port 4200",
8 | "start:admin": "ng serve --project admin-portal --port 4201",
9 | "start:propertium-common": "ng build --project propertium-common --prod --watch",
10 | "build:tenant": "ng build --project tenant-portal",
11 | "build:admin": "ng build --project admin-portal",
12 | "test:tenant": "ng test --project tenant-portal",
13 | "test:admin": "ng test --project admin-portal",
14 | "lint:tenant": "ng lint --project tenant-portal",
15 | "lint:admin": "ng lint --project admin-portal",
16 | "e2e:tenant": "ng e2e --project tenant-portal",
17 | "e2e:admin": "ng e2e --project admin-portal",
18 | "bundle-report": "webpack-bundle-analyzer dist/stats.json",
19 | "postinstall": "ngcc"
20 | },
21 | "private": true,
22 | "dependencies": {
23 | "@angular/animations": "^10.1.0",
24 | "@angular/cdk": "^10.2.0",
25 | "@angular/common": "^10.1.0",
26 | "@angular/compiler": "^10.1.0",
27 | "@angular/compiler-cli": "^10.1.0",
28 | "@angular/core": "^10.1.0",
29 | "@angular/forms": "^10.1.0",
30 | "@angular/language-service": "^10.1.0",
31 | "@angular/material": "^10.2.0",
32 | "@angular/platform-browser": "^10.1.0",
33 | "@angular/platform-browser-dynamic": "^10.1.0",
34 | "@angular/platform-server": "^10.1.0",
35 | "@angular/router": "^10.1.0",
36 | "@auth0/angular-jwt": "^4.2.0",
37 | "@webcomponents/custom-elements": "^1.4.1",
38 | "core-js": "^2.6.11",
39 | "jasmine-core": "~3.5.0",
40 | "protractor": "~7.0.0",
41 | "rxjs": "^6.6.0",
42 | "tslib": "^2.0.0",
43 | "tslint": "~6.1.0",
44 | "zone.js": "~0.10.3"
45 | },
46 | "devDependencies": {
47 | "@angular-devkit/build-angular": "~0.1001.0",
48 | "@angular-devkit/build-ng-packagr": "~0.1001.0",
49 | "@angular/cli": "^10.1.0",
50 | "@types/jasmine": "^2.8.17",
51 | "@types/node": "^12.12.47",
52 | "codelyzer": "^5.2.2",
53 | "jasmine-core": "2.7.0",
54 | "jasmine-spec-reporter": "~5.0.0",
55 | "karma": "~5.0.0",
56 | "karma-chrome-launcher": "~3.1.0",
57 | "karma-cli": "~1.0.1",
58 | "karma-coverage-istanbul-reporter": "~3.0.2",
59 | "karma-jasmine": "~3.3.0",
60 | "karma-jasmine-html-reporter": "^1.5.0",
61 | "ng-packagr": "^10.0.0",
62 | "protractor": "~5.1.2",
63 | "ts-node": "3.3.0",
64 | "tslint": "5.6.0",
65 | "typescript": "^3.9.6",
66 | "webpack-bundle-analyzer": "^3.8.0"
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This file includes polyfills needed by Angular and is loaded before the app.
3 | * You can add your own extra polyfills to this file.
4 | *
5 | * This file is divided into 2 sections:
6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
8 | * file.
9 | *
10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
13 | *
14 | * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
15 | */
16 |
17 | /***************************************************************************************************
18 | * BROWSER POLYFILLS
19 | */
20 |
21 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/
22 | // import 'core-js/es6/symbol';
23 | // import 'core-js/es6/object';
24 | // import 'core-js/es6/function';
25 | // import 'core-js/es6/parse-int';
26 | // import 'core-js/es6/parse-float';
27 | // import 'core-js/es6/number';
28 | // import 'core-js/es6/math';
29 | // import 'core-js/es6/string';
30 | // import 'core-js/es6/date';
31 | // import 'core-js/es6/array';
32 | // import 'core-js/es6/regexp';
33 | // import 'core-js/es6/map';
34 | // import 'core-js/es6/weak-map';
35 | // import 'core-js/es6/set';
36 |
37 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */
38 | // import 'classlist.js'; // Run `npm install --save classlist.js`.
39 |
40 | /** IE10 and IE11 requires the following to support `@angular/animation`. */
41 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`.
42 |
43 |
44 | /** Evergreen browsers require these. **/
45 | import 'core-js/es6/reflect';
46 |
47 |
48 | /** ALL Firefox browsers require the following to support `@angular/animation`. **/
49 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`.
50 |
51 |
52 |
53 | /***************************************************************************************************
54 | * Zone JS is required by Angular itself.
55 | */
56 | import 'zone.js/dist/zone'; // Included with Angular CLI.
57 |
58 |
59 |
60 | /***************************************************************************************************
61 | * APPLICATION IMPORTS
62 | */
63 |
64 | /**
65 | * Date, currency, decimal and percent pipes.
66 | * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10
67 | */
68 | // import 'intl'; // Run `npm install --save intl`.
69 | /**
70 | * Need to import at least one locale-data with intl.
71 | */
72 | // import 'intl/locale-data/jsonp/en';
73 |
--------------------------------------------------------------------------------
/tslint.base.json:
--------------------------------------------------------------------------------
1 | {
2 | "rulesDirectory": ["node_modules/codelyzer"],
3 | "rules": {
4 | "arrow-return-shorthand": true,
5 | "callable-types": true,
6 | "class-name": true,
7 | "comment-format": [true, "check-space"],
8 | "curly": true,
9 | "deprecation": {
10 | "severity": "warning"
11 | },
12 | "eofline": true,
13 | "forin": true,
14 | "import-blacklist": [true],
15 | "import-spacing": true,
16 | "indent": [true, "spaces"],
17 | "interface-over-type-literal": true,
18 | "label-position": true,
19 | "max-line-length": [true, 140],
20 | "member-access": false,
21 | "member-ordering": [true, { "order": "instance-sandwich" }],
22 | "no-arg": true,
23 | "no-bitwise": true,
24 | "no-console": [true, "debug", "info", "time", "timeEnd", "trace"],
25 | "no-construct": true,
26 | "no-debugger": true,
27 | "no-duplicate-super": true,
28 | "no-empty": false,
29 | "no-empty-interface": true,
30 | "no-eval": true,
31 | "no-inferrable-types": [true, "ignore-params"],
32 | "no-misused-new": true,
33 | "no-non-null-assertion": true,
34 | "no-shadowed-variable": true,
35 | "no-string-literal": false,
36 | "no-string-throw": true,
37 | "no-switch-case-fall-through": true,
38 | "no-trailing-whitespace": true,
39 | "no-unnecessary-initializer": true,
40 | "no-unused-expression": true,
41 | "no-var-keyword": true,
42 | "object-literal-sort-keys": false,
43 | "one-line": [true, "check-open-brace", "check-catch", "check-else", "check-whitespace"],
44 | "prefer-const": true,
45 | "quotemark": [true, "single"],
46 | "radix": true,
47 | "semicolon": [true],
48 | "triple-equals": [true, "allow-null-check"],
49 | "typedef-whitespace": [
50 | true,
51 | {
52 | "call-signature": "nospace",
53 | "index-signature": "nospace",
54 | "parameter": "nospace",
55 | "property-declaration": "nospace",
56 | "variable-declaration": "nospace"
57 | }
58 | ],
59 | "typeof-compare": true,
60 | "unified-signatures": true,
61 | "variable-name": false,
62 | "whitespace": [true, "check-branch", "check-decl", "check-operator", "check-separator", "check-type"],
63 | "directive-selector": [true, "attribute", "app", "camelCase"],
64 | "component-selector": [true, "element", "app", "kebab-case"],
65 | "no-inputs-metadata-property": true,
66 | "no-outputs-metadata-property": true,
67 | "no-host-metadata-property": true,
68 | "no-input-rename": true,
69 | "no-output-rename": true,
70 | "use-lifecycle-interface": true,
71 | "use-pipe-transform-interface": true,
72 | "component-class-suffix": true,
73 | "directive-class-suffix": true,
74 | "no-access-missing-member": true,
75 | "templates-use-public": true,
76 | "invoke-injectable": true
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/projects/admin-portal/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This file includes polyfills needed by Angular and is loaded before the app.
3 | * You can add your own extra polyfills to this file.
4 | *
5 | * This file is divided into 2 sections:
6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
8 | * file.
9 | *
10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
13 | *
14 | * Learn more in https://angular.io/guide/browser-support
15 | */
16 |
17 | /***************************************************************************************************
18 | * BROWSER POLYFILLS
19 | */
20 |
21 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */
22 | // import 'classlist.js'; // Run `npm install --save classlist.js`.
23 |
24 | /**
25 | * Web Animations `@angular/platform-browser/animations`
26 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
27 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
28 | */
29 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`.
30 |
31 | /**
32 | * By default, zone.js will patch all possible macroTask and DomEvents
33 | * user can disable parts of macroTask/DomEvents patch by setting following flags
34 | * because those flags need to be set before `zone.js` being loaded, and webpack
35 | * will put import in the top of bundle, so user need to create a separate file
36 | * in this directory (for example: zone-flags.ts), and put the following flags
37 | * into that file, and then add the following code before importing zone.js.
38 | * import './zone-flags';
39 | *
40 | * The flags allowed in zone-flags.ts are listed here.
41 | *
42 | * The following flags will work for all browsers.
43 | *
44 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
45 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
46 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
47 | *
48 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
49 | * with the following flag, it will bypass `zone.js` patch for IE/Edge
50 | *
51 | * (window as any).__Zone_enable_cross_context_check = true;
52 | *
53 | */
54 |
55 | /***************************************************************************************************
56 | * Zone JS is required by default for Angular itself.
57 | */
58 | import 'zone.js/dist/zone'; // Included with Angular CLI.
59 |
60 |
61 | /***************************************************************************************************
62 | * APPLICATION IMPORTS
63 | */
64 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/home/home.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Your current balance: $0.00
8 | info
13 |
14 |
15 |
16 |
17 | | Description |
18 | {{ element.item }} |
19 |
20 |
21 |
22 | Name |
23 | {{ element.amount }} | app-announcement-list
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | Address
43 |
44 |
45 | 10464 S Jordan Gateway #235
46 | South Jordan, Utah
47 | 84095
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | Lease
59 |
60 | View Lease
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
79 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/app/payments/payments.component.html:
--------------------------------------------------------------------------------
1 |
90 |
--------------------------------------------------------------------------------
/angular.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3 | "version": 1,
4 | "newProjectRoot": "projects",
5 | "projects": {
6 | "tenant-portal": {
7 | "projectType": "application",
8 | "schematics": {
9 | "@schematics/angular:component": {
10 | "style": "scss"
11 | }
12 | },
13 | "root": "projects/tenant-portal",
14 | "sourceRoot": "projects/tenant-portal/src",
15 | "architect": {
16 | "build": {
17 | "builder": "@angular-devkit/build-angular:browser",
18 | "options": {
19 | "outputPath": "dist/tenant-portal",
20 | "index": "projects/tenant-portal/src/index.html",
21 | "main": "projects/tenant-portal/src/main.ts",
22 | "polyfills": "projects/tenant-portal/src/polyfills.ts",
23 | "tsConfig": "projects/tenant-portal/tsconfig.app.json",
24 | "aot": true,
25 | "assets": ["projects/tenant-portal/src/assets", "projects/tenant-portal/src/favicon.png"],
26 | "styles": ["projects/tenant-portal/src/assets/css/styles.scss"],
27 | "scripts": ["node_modules/@webcomponents/custom-elements/custom-elements.min.js"]
28 | },
29 | "configurations": {
30 | "production": {
31 | "fileReplacements": [
32 | {
33 | "replace": "libs/shared/environments/environment.ts",
34 | "with": "libs/shared/environments/environment.prod.ts"
35 | }
36 | ],
37 | "optimization": true,
38 | "outputHashing": "all",
39 | "sourceMap": false,
40 | "extractCss": true,
41 | "namedChunks": false,
42 | "extractLicenses": true,
43 | "vendorChunk": false,
44 | "buildOptimizer": true,
45 | "budgets": [
46 | {
47 | "type": "anyComponentStyle",
48 | "maximumWarning": "6kb",
49 | "maximumError": "10mb"
50 | }
51 | ]
52 | }
53 | }
54 | },
55 | "serve": {
56 | "builder": "@angular-devkit/build-angular:dev-server",
57 | "options": {
58 | "browserTarget": "tenant-portal:build"
59 | },
60 | "configurations": {
61 | "production": {
62 | "browserTarget": "tenant-portal:build:production"
63 | }
64 | }
65 | },
66 | "extract-i18n": {
67 | "builder": "@angular-devkit/build-angular:extract-i18n",
68 | "options": {
69 | "browserTarget": "tenant-portal:build"
70 | }
71 | },
72 | "test": {
73 | "builder": "@angular-devkit/build-angular:karma",
74 | "options": {
75 | "main": "projects/tenant-portal/src/test.ts",
76 | "polyfills": "projects/tenant-portal/src/polyfills.ts",
77 | "tsConfig": "projects/tenant-portal/tsconfig.spec.json",
78 | "karmaConfig": "projects/tenant-portal/karma.conf.js",
79 | "assets": ["projects/tenant-portal/src/assets", "src/favicon.png"],
80 | "styles": ["projects/tenant-portal/src/assets/css/styles.scss"],
81 | "scripts": ["node_modules/@webcomponents/custom-elements/custom-elements.min.js"]
82 | }
83 | },
84 | "lint": {
85 | "builder": "@angular-devkit/build-angular:tslint",
86 | "options": {
87 | "tsConfig": ["projects/tenant-portal/tsconfig.app.json", "projects/tenant-portal/tsconfig.spec.json"],
88 | "exclude": []
89 | }
90 | }
91 | }
92 | },
93 | "tenant-portal-e2e": {
94 | "root": "e2e",
95 | "sourceRoot": "e2e",
96 | "projectType": "application",
97 | "architect": {
98 | "e2e": {
99 | "builder": "@angular-devkit/build-angular:protractor",
100 | "options": {
101 | "protractorConfig": "./protractor.conf.js",
102 | "devServerTarget": "tenant-portal:serve"
103 | }
104 | },
105 | "lint": {
106 | "builder": "@angular-devkit/build-angular:tslint",
107 | "options": {
108 | "tsConfig": ["e2e/tsconfig.e2e.json"],
109 | "exclude": []
110 | }
111 | }
112 | }
113 | },
114 | "admin-portal": {
115 | "projectType": "application",
116 | "schematics": {
117 | "@schematics/angular:component": {
118 | "style": "scss"
119 | }
120 | },
121 | "root": "projects/admin-portal",
122 | "sourceRoot": "projects/admin-portal/src",
123 | "prefix": "app",
124 | "architect": {
125 | "build": {
126 | "builder": "@angular-devkit/build-angular:browser",
127 | "options": {
128 | "outputPath": "dist/admin-portal",
129 | "index": "projects/admin-portal/src/index.html",
130 | "main": "projects/admin-portal/src/main.ts",
131 | "polyfills": "projects/admin-portal/src/polyfills.ts",
132 | "tsConfig": "projects/admin-portal/tsconfig.app.json",
133 | "aot": true,
134 | "assets": ["projects/admin-portal/src/favicon.ico", "projects/admin-portal/src/assets"],
135 | "styles": ["projects/admin-portal/src/styles.scss"],
136 | "scripts": []
137 | },
138 | "configurations": {
139 | "production": {
140 | "fileReplacements": [
141 | {
142 | "replace": "projects/admin-portal/src/environments/environment.ts",
143 | "with": "projects/admin-portal/src/environments/environment.prod.ts"
144 | }
145 | ],
146 | "optimization": true,
147 | "outputHashing": "all",
148 | "sourceMap": false,
149 | "extractCss": true,
150 | "namedChunks": false,
151 | "extractLicenses": true,
152 | "vendorChunk": false,
153 | "buildOptimizer": true,
154 | "budgets": [
155 | {
156 | "type": "initial",
157 | "maximumWarning": "2mb",
158 | "maximumError": "5mb"
159 | },
160 | {
161 | "type": "anyComponentStyle",
162 | "maximumWarning": "6kb",
163 | "maximumError": "10kb"
164 | }
165 | ]
166 | }
167 | }
168 | },
169 | "serve": {
170 | "builder": "@angular-devkit/build-angular:dev-server",
171 | "options": {
172 | "browserTarget": "admin-portal:build"
173 | },
174 | "configurations": {
175 | "production": {
176 | "browserTarget": "admin-portal:build:production"
177 | }
178 | }
179 | },
180 | "extract-i18n": {
181 | "builder": "@angular-devkit/build-angular:extract-i18n",
182 | "options": {
183 | "browserTarget": "admin-portal:build"
184 | }
185 | },
186 | "test": {
187 | "builder": "@angular-devkit/build-angular:karma",
188 | "options": {
189 | "main": "projects/admin-portal/src/test.ts",
190 | "polyfills": "projects/admin-portal/src/polyfills.ts",
191 | "tsConfig": "projects/admin-portal/tsconfig.spec.json",
192 | "karmaConfig": "projects/admin-portal/karma.conf.js",
193 | "assets": ["projects/admin-portal/src/favicon.ico", "projects/admin-portal/src/assets"],
194 | "styles": ["projects/admin-portal/src/styles.scss"],
195 | "scripts": []
196 | }
197 | },
198 | "lint": {
199 | "builder": "@angular-devkit/build-angular:tslint",
200 | "options": {
201 | "tsConfig": [
202 | "projects/admin-portal/tsconfig.app.json",
203 | "projects/admin-portal/tsconfig.spec.json",
204 | "projects/admin-portal/e2e/tsconfig.json"
205 | ],
206 | "exclude": ["**/node_modules/**"]
207 | }
208 | },
209 | "e2e": {
210 | "builder": "@angular-devkit/build-angular:protractor",
211 | "options": {
212 | "protractorConfig": "projects/admin-portal/e2e/protractor.conf.js",
213 | "devServerTarget": "admin-portal:serve"
214 | },
215 | "configurations": {
216 | "production": {
217 | "devServerTarget": "admin-portal:serve:production"
218 | }
219 | }
220 | }
221 | }
222 | },
223 | "propertium-common": {
224 | "projectType": "library",
225 | "root": "projects/propertium-common",
226 | "sourceRoot": "projects/propertium-common/src",
227 | "prefix": "propertium",
228 | "architect": {
229 | "build": {
230 | "builder": "@angular-devkit/build-ng-packagr:build",
231 | "options": {
232 | "tsConfig": "projects/propertium-common/tsconfig.lib.json",
233 | "project": "projects/propertium-common/ng-package.json"
234 | },
235 | "configurations": {
236 | "production": {
237 | "tsConfig": "projects/propertium-common/tsconfig.lib.prod.json"
238 | }
239 | }
240 | },
241 | "test": {
242 | "builder": "@angular-devkit/build-angular:karma",
243 | "options": {
244 | "main": "projects/propertium-common/src/test.ts",
245 | "tsConfig": "projects/propertium-common/tsconfig.spec.json",
246 | "karmaConfig": "projects/propertium-common/karma.conf.js"
247 | }
248 | },
249 | "lint": {
250 | "builder": "@angular-devkit/build-angular:tslint",
251 | "options": {
252 | "tsConfig": [
253 | "projects/propertium-common/tsconfig.lib.json",
254 | "projects/propertium-common/tsconfig.spec.json"
255 | ],
256 | "exclude": ["**/node_modules/**"]
257 | }
258 | }
259 | }
260 | }
261 | },
262 | "defaultProject": "tenant-portal"
263 | }
264 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/assets/css/_flex.scss:
--------------------------------------------------------------------------------
1 | .d-flex {
2 | display: -webkit-box !important;
3 | display: -webkit-flex !important;
4 | display: -ms-flexbox !important;
5 | display: flex !important;
6 | }
7 |
8 | .d-inline-flex {
9 | display: -webkit-inline-box !important;
10 | display: -webkit-inline-flex !important;
11 | display: -ms-inline-flexbox !important;
12 | display: inline-flex !important;
13 | }
14 |
15 | @media (min-width: 576px) {
16 | .d-sm-none {
17 | display: none !important;
18 | }
19 | .d-sm-inline {
20 | display: inline !important;
21 | }
22 | .d-sm-inline-block {
23 | display: inline-block !important;
24 | }
25 | .d-sm-block {
26 | display: block !important;
27 | }
28 | .d-sm-table {
29 | display: table !important;
30 | }
31 | .d-sm-table-cell {
32 | display: table-cell !important;
33 | }
34 | .d-sm-flex {
35 | display: -webkit-box !important;
36 | display: -webkit-flex !important;
37 | display: -ms-flexbox !important;
38 | display: flex !important;
39 | }
40 | .d-sm-inline-flex {
41 | display: -webkit-inline-box !important;
42 | display: -webkit-inline-flex !important;
43 | display: -ms-inline-flexbox !important;
44 | display: inline-flex !important;
45 | }
46 | }
47 |
48 | @media (min-width: 768px) {
49 | .d-md-none {
50 | display: none !important;
51 | }
52 | .d-md-inline {
53 | display: inline !important;
54 | }
55 | .d-md-inline-block {
56 | display: inline-block !important;
57 | }
58 | .d-md-block {
59 | display: block !important;
60 | }
61 | .d-md-table {
62 | display: table !important;
63 | }
64 | .d-md-table-cell {
65 | display: table-cell !important;
66 | }
67 | .d-md-flex {
68 | display: -webkit-box !important;
69 | display: -webkit-flex !important;
70 | display: -ms-flexbox !important;
71 | display: flex !important;
72 | }
73 | .d-md-inline-flex {
74 | display: -webkit-inline-box !important;
75 | display: -webkit-inline-flex !important;
76 | display: -ms-inline-flexbox !important;
77 | display: inline-flex !important;
78 | }
79 | }
80 |
81 | @media (min-width: 992px) {
82 | .d-lg-none {
83 | display: none !important;
84 | }
85 | .d-lg-inline {
86 | display: inline !important;
87 | }
88 | .d-lg-inline-block {
89 | display: inline-block !important;
90 | }
91 | .d-lg-block {
92 | display: block !important;
93 | }
94 | .d-lg-table {
95 | display: table !important;
96 | }
97 | .d-lg-table-cell {
98 | display: table-cell !important;
99 | }
100 | .d-lg-flex {
101 | display: -webkit-box !important;
102 | display: -webkit-flex !important;
103 | display: -ms-flexbox !important;
104 | display: flex !important;
105 | }
106 | .d-lg-inline-flex {
107 | display: -webkit-inline-box !important;
108 | display: -webkit-inline-flex !important;
109 | display: -ms-inline-flexbox !important;
110 | display: inline-flex !important;
111 | }
112 | }
113 |
114 | @media (min-width: 1200px) {
115 | .d-xl-none {
116 | display: none !important;
117 | }
118 | .d-xl-inline {
119 | display: inline !important;
120 | }
121 | .d-xl-inline-block {
122 | display: inline-block !important;
123 | }
124 | .d-xl-block {
125 | display: block !important;
126 | }
127 | .d-xl-table {
128 | display: table !important;
129 | }
130 | .d-xl-table-cell {
131 | display: table-cell !important;
132 | }
133 | .d-xl-flex {
134 | display: -webkit-box !important;
135 | display: -webkit-flex !important;
136 | display: -ms-flexbox !important;
137 | display: flex !important;
138 | }
139 | .d-xl-inline-flex {
140 | display: -webkit-inline-box !important;
141 | display: -webkit-inline-flex !important;
142 | display: -ms-inline-flexbox !important;
143 | display: inline-flex !important;
144 | }
145 | }
146 |
147 | .flex-first {
148 | -webkit-box-ordinal-group: 0;
149 | -webkit-order: -1;
150 | -ms-flex-order: -1;
151 | order: -1;
152 | }
153 |
154 | .flex-last {
155 | -webkit-box-ordinal-group: 2;
156 | -webkit-order: 1;
157 | -ms-flex-order: 1;
158 | order: 1;
159 | }
160 |
161 | .flex-unordered {
162 | -webkit-box-ordinal-group: 1;
163 | -webkit-order: 0;
164 | -ms-flex-order: 0;
165 | order: 0;
166 | }
167 |
168 | .flex-row {
169 | -webkit-box-orient: horizontal !important;
170 | -webkit-box-direction: normal !important;
171 | -webkit-flex-direction: row !important;
172 | -ms-flex-direction: row !important;
173 | flex-direction: row !important;
174 | }
175 |
176 | .flex-column {
177 | -webkit-box-orient: vertical !important;
178 | -webkit-box-direction: normal !important;
179 | -webkit-flex-direction: column !important;
180 | -ms-flex-direction: column !important;
181 | flex-direction: column !important;
182 | }
183 |
184 | .flex-row-reverse {
185 | -webkit-box-orient: horizontal !important;
186 | -webkit-box-direction: reverse !important;
187 | -webkit-flex-direction: row-reverse !important;
188 | -ms-flex-direction: row-reverse !important;
189 | flex-direction: row-reverse !important;
190 | }
191 |
192 | .flex-column-reverse {
193 | -webkit-box-orient: vertical !important;
194 | -webkit-box-direction: reverse !important;
195 | -webkit-flex-direction: column-reverse !important;
196 | -ms-flex-direction: column-reverse !important;
197 | flex-direction: column-reverse !important;
198 | }
199 |
200 | .flex-wrap {
201 | -webkit-flex-wrap: wrap !important;
202 | -ms-flex-wrap: wrap !important;
203 | flex-wrap: wrap !important;
204 | }
205 |
206 | .flex-nowrap {
207 | -webkit-flex-wrap: nowrap !important;
208 | -ms-flex-wrap: nowrap !important;
209 | flex-wrap: nowrap !important;
210 | }
211 |
212 | .flex-wrap-reverse {
213 | -webkit-flex-wrap: wrap-reverse !important;
214 | -ms-flex-wrap: wrap-reverse !important;
215 | flex-wrap: wrap-reverse !important;
216 | }
217 |
218 | .justify-content-start {
219 | -webkit-box-pack: start !important;
220 | -webkit-justify-content: flex-start !important;
221 | -ms-flex-pack: start !important;
222 | justify-content: flex-start !important;
223 | }
224 |
225 | .justify-content-end {
226 | -webkit-box-pack: end !important;
227 | -webkit-justify-content: flex-end !important;
228 | -ms-flex-pack: end !important;
229 | justify-content: flex-end !important;
230 | }
231 |
232 | .justify-content-center {
233 | -webkit-box-pack: center !important;
234 | -webkit-justify-content: center !important;
235 | -ms-flex-pack: center !important;
236 | justify-content: center !important;
237 | }
238 |
239 | .justify-content-between {
240 | -webkit-box-pack: justify !important;
241 | -webkit-justify-content: space-between !important;
242 | -ms-flex-pack: justify !important;
243 | justify-content: space-between !important;
244 | }
245 |
246 | .justify-content-around {
247 | -webkit-justify-content: space-around !important;
248 | -ms-flex-pack: distribute !important;
249 | justify-content: space-around !important;
250 | }
251 |
252 | .align-items-start {
253 | -webkit-box-align: start !important;
254 | -webkit-align-items: flex-start !important;
255 | -ms-flex-align: start !important;
256 | align-items: flex-start !important;
257 | }
258 |
259 | .align-items-end {
260 | -webkit-box-align: end !important;
261 | -webkit-align-items: flex-end !important;
262 | -ms-flex-align: end !important;
263 | align-items: flex-end !important;
264 | }
265 |
266 | .align-items-center {
267 | -webkit-box-align: center !important;
268 | -webkit-align-items: center !important;
269 | -ms-flex-align: center !important;
270 | align-items: center !important;
271 | }
272 |
273 | .align-items-baseline {
274 | -webkit-box-align: baseline !important;
275 | -webkit-align-items: baseline !important;
276 | -ms-flex-align: baseline !important;
277 | align-items: baseline !important;
278 | }
279 |
280 | .align-items-stretch {
281 | -webkit-box-align: stretch !important;
282 | -webkit-align-items: stretch !important;
283 | -ms-flex-align: stretch !important;
284 | align-items: stretch !important;
285 | }
286 |
287 | .align-content-start {
288 | -webkit-align-content: flex-start !important;
289 | -ms-flex-line-pack: start !important;
290 | align-content: flex-start !important;
291 | }
292 |
293 | .align-content-end {
294 | -webkit-align-content: flex-end !important;
295 | -ms-flex-line-pack: end !important;
296 | align-content: flex-end !important;
297 | }
298 |
299 | .align-content-center {
300 | -webkit-align-content: center !important;
301 | -ms-flex-line-pack: center !important;
302 | align-content: center !important;
303 | }
304 |
305 | .align-content-between {
306 | -webkit-align-content: space-between !important;
307 | -ms-flex-line-pack: justify !important;
308 | align-content: space-between !important;
309 | }
310 |
311 | .align-content-around {
312 | -webkit-align-content: space-around !important;
313 | -ms-flex-line-pack: distribute !important;
314 | align-content: space-around !important;
315 | }
316 |
317 | .align-content-stretch {
318 | -webkit-align-content: stretch !important;
319 | -ms-flex-line-pack: stretch !important;
320 | align-content: stretch !important;
321 | }
322 |
323 | .align-self-auto {
324 | -webkit-align-self: auto !important;
325 | -ms-flex-item-align: auto !important;
326 | -ms-grid-row-align: auto !important;
327 | align-self: auto !important;
328 | }
329 |
330 | .align-self-start {
331 | -webkit-align-self: flex-start !important;
332 | -ms-flex-item-align: start !important;
333 | align-self: flex-start !important;
334 | }
335 |
336 | .align-self-end {
337 | -webkit-align-self: flex-end !important;
338 | -ms-flex-item-align: end !important;
339 | align-self: flex-end !important;
340 | }
341 |
342 | .align-self-center {
343 | -webkit-align-self: center !important;
344 | -ms-flex-item-align: center !important;
345 | -ms-grid-row-align: center !important;
346 | align-self: center !important;
347 | }
348 |
349 | .align-self-baseline {
350 | -webkit-align-self: baseline !important;
351 | -ms-flex-item-align: baseline !important;
352 | align-self: baseline !important;
353 | }
354 |
355 | .align-self-stretch {
356 | -webkit-align-self: stretch !important;
357 | -ms-flex-item-align: stretch !important;
358 | -ms-grid-row-align: stretch !important;
359 | align-self: stretch !important;
360 | }
361 |
362 | @media (min-width: 576px) {
363 | .flex-sm-first {
364 | -webkit-box-ordinal-group: 0;
365 | -webkit-order: -1;
366 | -ms-flex-order: -1;
367 | order: -1;
368 | }
369 | .flex-sm-last {
370 | -webkit-box-ordinal-group: 2;
371 | -webkit-order: 1;
372 | -ms-flex-order: 1;
373 | order: 1;
374 | }
375 | .flex-sm-unordered {
376 | -webkit-box-ordinal-group: 1;
377 | -webkit-order: 0;
378 | -ms-flex-order: 0;
379 | order: 0;
380 | }
381 | .flex-sm-row {
382 | -webkit-box-orient: horizontal !important;
383 | -webkit-box-direction: normal !important;
384 | -webkit-flex-direction: row !important;
385 | -ms-flex-direction: row !important;
386 | flex-direction: row !important;
387 | }
388 | .flex-sm-column {
389 | -webkit-box-orient: vertical !important;
390 | -webkit-box-direction: normal !important;
391 | -webkit-flex-direction: column !important;
392 | -ms-flex-direction: column !important;
393 | flex-direction: column !important;
394 | }
395 | .flex-sm-row-reverse {
396 | -webkit-box-orient: horizontal !important;
397 | -webkit-box-direction: reverse !important;
398 | -webkit-flex-direction: row-reverse !important;
399 | -ms-flex-direction: row-reverse !important;
400 | flex-direction: row-reverse !important;
401 | }
402 | .flex-sm-column-reverse {
403 | -webkit-box-orient: vertical !important;
404 | -webkit-box-direction: reverse !important;
405 | -webkit-flex-direction: column-reverse !important;
406 | -ms-flex-direction: column-reverse !important;
407 | flex-direction: column-reverse !important;
408 | }
409 | .flex-sm-wrap {
410 | -webkit-flex-wrap: wrap !important;
411 | -ms-flex-wrap: wrap !important;
412 | flex-wrap: wrap !important;
413 | }
414 | .flex-sm-nowrap {
415 | -webkit-flex-wrap: nowrap !important;
416 | -ms-flex-wrap: nowrap !important;
417 | flex-wrap: nowrap !important;
418 | }
419 | .flex-sm-wrap-reverse {
420 | -webkit-flex-wrap: wrap-reverse !important;
421 | -ms-flex-wrap: wrap-reverse !important;
422 | flex-wrap: wrap-reverse !important;
423 | }
424 | .justify-content-sm-start {
425 | -webkit-box-pack: start !important;
426 | -webkit-justify-content: flex-start !important;
427 | -ms-flex-pack: start !important;
428 | justify-content: flex-start !important;
429 | }
430 | .justify-content-sm-end {
431 | -webkit-box-pack: end !important;
432 | -webkit-justify-content: flex-end !important;
433 | -ms-flex-pack: end !important;
434 | justify-content: flex-end !important;
435 | }
436 | .justify-content-sm-center {
437 | -webkit-box-pack: center !important;
438 | -webkit-justify-content: center !important;
439 | -ms-flex-pack: center !important;
440 | justify-content: center !important;
441 | }
442 | .justify-content-sm-between {
443 | -webkit-box-pack: justify !important;
444 | -webkit-justify-content: space-between !important;
445 | -ms-flex-pack: justify !important;
446 | justify-content: space-between !important;
447 | }
448 | .justify-content-sm-around {
449 | -webkit-justify-content: space-around !important;
450 | -ms-flex-pack: distribute !important;
451 | justify-content: space-around !important;
452 | }
453 | .align-items-sm-start {
454 | -webkit-box-align: start !important;
455 | -webkit-align-items: flex-start !important;
456 | -ms-flex-align: start !important;
457 | align-items: flex-start !important;
458 | }
459 | .align-items-sm-end {
460 | -webkit-box-align: end !important;
461 | -webkit-align-items: flex-end !important;
462 | -ms-flex-align: end !important;
463 | align-items: flex-end !important;
464 | }
465 | .align-items-sm-center {
466 | -webkit-box-align: center !important;
467 | -webkit-align-items: center !important;
468 | -ms-flex-align: center !important;
469 | align-items: center !important;
470 | }
471 | .align-items-sm-baseline {
472 | -webkit-box-align: baseline !important;
473 | -webkit-align-items: baseline !important;
474 | -ms-flex-align: baseline !important;
475 | align-items: baseline !important;
476 | }
477 | .align-items-sm-stretch {
478 | -webkit-box-align: stretch !important;
479 | -webkit-align-items: stretch !important;
480 | -ms-flex-align: stretch !important;
481 | align-items: stretch !important;
482 | }
483 | .align-content-sm-start {
484 | -webkit-align-content: flex-start !important;
485 | -ms-flex-line-pack: start !important;
486 | align-content: flex-start !important;
487 | }
488 | .align-content-sm-end {
489 | -webkit-align-content: flex-end !important;
490 | -ms-flex-line-pack: end !important;
491 | align-content: flex-end !important;
492 | }
493 | .align-content-sm-center {
494 | -webkit-align-content: center !important;
495 | -ms-flex-line-pack: center !important;
496 | align-content: center !important;
497 | }
498 | .align-content-sm-between {
499 | -webkit-align-content: space-between !important;
500 | -ms-flex-line-pack: justify !important;
501 | align-content: space-between !important;
502 | }
503 | .align-content-sm-around {
504 | -webkit-align-content: space-around !important;
505 | -ms-flex-line-pack: distribute !important;
506 | align-content: space-around !important;
507 | }
508 | .align-content-sm-stretch {
509 | -webkit-align-content: stretch !important;
510 | -ms-flex-line-pack: stretch !important;
511 | align-content: stretch !important;
512 | }
513 | .align-self-sm-auto {
514 | -webkit-align-self: auto !important;
515 | -ms-flex-item-align: auto !important;
516 | -ms-grid-row-align: auto !important;
517 | align-self: auto !important;
518 | }
519 | .align-self-sm-start {
520 | -webkit-align-self: flex-start !important;
521 | -ms-flex-item-align: start !important;
522 | align-self: flex-start !important;
523 | }
524 | .align-self-sm-end {
525 | -webkit-align-self: flex-end !important;
526 | -ms-flex-item-align: end !important;
527 | align-self: flex-end !important;
528 | }
529 | .align-self-sm-center {
530 | -webkit-align-self: center !important;
531 | -ms-flex-item-align: center !important;
532 | -ms-grid-row-align: center !important;
533 | align-self: center !important;
534 | }
535 | .align-self-sm-baseline {
536 | -webkit-align-self: baseline !important;
537 | -ms-flex-item-align: baseline !important;
538 | align-self: baseline !important;
539 | }
540 | .align-self-sm-stretch {
541 | -webkit-align-self: stretch !important;
542 | -ms-flex-item-align: stretch !important;
543 | -ms-grid-row-align: stretch !important;
544 | align-self: stretch !important;
545 | }
546 | }
547 |
548 | @media (min-width: 768px) {
549 | .flex-md-first {
550 | -webkit-box-ordinal-group: 0;
551 | -webkit-order: -1;
552 | -ms-flex-order: -1;
553 | order: -1;
554 | }
555 | .flex-md-last {
556 | -webkit-box-ordinal-group: 2;
557 | -webkit-order: 1;
558 | -ms-flex-order: 1;
559 | order: 1;
560 | }
561 | .flex-md-unordered {
562 | -webkit-box-ordinal-group: 1;
563 | -webkit-order: 0;
564 | -ms-flex-order: 0;
565 | order: 0;
566 | }
567 | .flex-md-row {
568 | -webkit-box-orient: horizontal !important;
569 | -webkit-box-direction: normal !important;
570 | -webkit-flex-direction: row !important;
571 | -ms-flex-direction: row !important;
572 | flex-direction: row !important;
573 | }
574 | .flex-md-column {
575 | -webkit-box-orient: vertical !important;
576 | -webkit-box-direction: normal !important;
577 | -webkit-flex-direction: column !important;
578 | -ms-flex-direction: column !important;
579 | flex-direction: column !important;
580 | }
581 | .flex-md-row-reverse {
582 | -webkit-box-orient: horizontal !important;
583 | -webkit-box-direction: reverse !important;
584 | -webkit-flex-direction: row-reverse !important;
585 | -ms-flex-direction: row-reverse !important;
586 | flex-direction: row-reverse !important;
587 | }
588 | .flex-md-column-reverse {
589 | -webkit-box-orient: vertical !important;
590 | -webkit-box-direction: reverse !important;
591 | -webkit-flex-direction: column-reverse !important;
592 | -ms-flex-direction: column-reverse !important;
593 | flex-direction: column-reverse !important;
594 | }
595 | .flex-md-wrap {
596 | -webkit-flex-wrap: wrap !important;
597 | -ms-flex-wrap: wrap !important;
598 | flex-wrap: wrap !important;
599 | }
600 | .flex-md-nowrap {
601 | -webkit-flex-wrap: nowrap !important;
602 | -ms-flex-wrap: nowrap !important;
603 | flex-wrap: nowrap !important;
604 | }
605 | .flex-md-wrap-reverse {
606 | -webkit-flex-wrap: wrap-reverse !important;
607 | -ms-flex-wrap: wrap-reverse !important;
608 | flex-wrap: wrap-reverse !important;
609 | }
610 | .justify-content-md-start {
611 | -webkit-box-pack: start !important;
612 | -webkit-justify-content: flex-start !important;
613 | -ms-flex-pack: start !important;
614 | justify-content: flex-start !important;
615 | }
616 | .justify-content-md-end {
617 | -webkit-box-pack: end !important;
618 | -webkit-justify-content: flex-end !important;
619 | -ms-flex-pack: end !important;
620 | justify-content: flex-end !important;
621 | }
622 | .justify-content-md-center {
623 | -webkit-box-pack: center !important;
624 | -webkit-justify-content: center !important;
625 | -ms-flex-pack: center !important;
626 | justify-content: center !important;
627 | }
628 | .justify-content-md-between {
629 | -webkit-box-pack: justify !important;
630 | -webkit-justify-content: space-between !important;
631 | -ms-flex-pack: justify !important;
632 | justify-content: space-between !important;
633 | }
634 | .justify-content-md-around {
635 | -webkit-justify-content: space-around !important;
636 | -ms-flex-pack: distribute !important;
637 | justify-content: space-around !important;
638 | }
639 | .align-items-md-start {
640 | -webkit-box-align: start !important;
641 | -webkit-align-items: flex-start !important;
642 | -ms-flex-align: start !important;
643 | align-items: flex-start !important;
644 | }
645 | .align-items-md-end {
646 | -webkit-box-align: end !important;
647 | -webkit-align-items: flex-end !important;
648 | -ms-flex-align: end !important;
649 | align-items: flex-end !important;
650 | }
651 | .align-items-md-center {
652 | -webkit-box-align: center !important;
653 | -webkit-align-items: center !important;
654 | -ms-flex-align: center !important;
655 | align-items: center !important;
656 | }
657 | .align-items-md-baseline {
658 | -webkit-box-align: baseline !important;
659 | -webkit-align-items: baseline !important;
660 | -ms-flex-align: baseline !important;
661 | align-items: baseline !important;
662 | }
663 | .align-items-md-stretch {
664 | -webkit-box-align: stretch !important;
665 | -webkit-align-items: stretch !important;
666 | -ms-flex-align: stretch !important;
667 | align-items: stretch !important;
668 | }
669 | .align-content-md-start {
670 | -webkit-align-content: flex-start !important;
671 | -ms-flex-line-pack: start !important;
672 | align-content: flex-start !important;
673 | }
674 | .align-content-md-end {
675 | -webkit-align-content: flex-end !important;
676 | -ms-flex-line-pack: end !important;
677 | align-content: flex-end !important;
678 | }
679 | .align-content-md-center {
680 | -webkit-align-content: center !important;
681 | -ms-flex-line-pack: center !important;
682 | align-content: center !important;
683 | }
684 | .align-content-md-between {
685 | -webkit-align-content: space-between !important;
686 | -ms-flex-line-pack: justify !important;
687 | align-content: space-between !important;
688 | }
689 | .align-content-md-around {
690 | -webkit-align-content: space-around !important;
691 | -ms-flex-line-pack: distribute !important;
692 | align-content: space-around !important;
693 | }
694 | .align-content-md-stretch {
695 | -webkit-align-content: stretch !important;
696 | -ms-flex-line-pack: stretch !important;
697 | align-content: stretch !important;
698 | }
699 | .align-self-md-auto {
700 | -webkit-align-self: auto !important;
701 | -ms-flex-item-align: auto !important;
702 | -ms-grid-row-align: auto !important;
703 | align-self: auto !important;
704 | }
705 | .align-self-md-start {
706 | -webkit-align-self: flex-start !important;
707 | -ms-flex-item-align: start !important;
708 | align-self: flex-start !important;
709 | }
710 | .align-self-md-end {
711 | -webkit-align-self: flex-end !important;
712 | -ms-flex-item-align: end !important;
713 | align-self: flex-end !important;
714 | }
715 | .align-self-md-center {
716 | -webkit-align-self: center !important;
717 | -ms-flex-item-align: center !important;
718 | -ms-grid-row-align: center !important;
719 | align-self: center !important;
720 | }
721 | .align-self-md-baseline {
722 | -webkit-align-self: baseline !important;
723 | -ms-flex-item-align: baseline !important;
724 | align-self: baseline !important;
725 | }
726 | .align-self-md-stretch {
727 | -webkit-align-self: stretch !important;
728 | -ms-flex-item-align: stretch !important;
729 | -ms-grid-row-align: stretch !important;
730 | align-self: stretch !important;
731 | }
732 | }
733 |
734 | @media (min-width: 992px) {
735 | .flex-lg-first {
736 | -webkit-box-ordinal-group: 0;
737 | -webkit-order: -1;
738 | -ms-flex-order: -1;
739 | order: -1;
740 | }
741 | .flex-lg-last {
742 | -webkit-box-ordinal-group: 2;
743 | -webkit-order: 1;
744 | -ms-flex-order: 1;
745 | order: 1;
746 | }
747 | .flex-lg-unordered {
748 | -webkit-box-ordinal-group: 1;
749 | -webkit-order: 0;
750 | -ms-flex-order: 0;
751 | order: 0;
752 | }
753 | .flex-lg-row {
754 | -webkit-box-orient: horizontal !important;
755 | -webkit-box-direction: normal !important;
756 | -webkit-flex-direction: row !important;
757 | -ms-flex-direction: row !important;
758 | flex-direction: row !important;
759 | }
760 | .flex-lg-column {
761 | -webkit-box-orient: vertical !important;
762 | -webkit-box-direction: normal !important;
763 | -webkit-flex-direction: column !important;
764 | -ms-flex-direction: column !important;
765 | flex-direction: column !important;
766 | }
767 | .flex-lg-row-reverse {
768 | -webkit-box-orient: horizontal !important;
769 | -webkit-box-direction: reverse !important;
770 | -webkit-flex-direction: row-reverse !important;
771 | -ms-flex-direction: row-reverse !important;
772 | flex-direction: row-reverse !important;
773 | }
774 | .flex-lg-column-reverse {
775 | -webkit-box-orient: vertical !important;
776 | -webkit-box-direction: reverse !important;
777 | -webkit-flex-direction: column-reverse !important;
778 | -ms-flex-direction: column-reverse !important;
779 | flex-direction: column-reverse !important;
780 | }
781 | .flex-lg-wrap {
782 | -webkit-flex-wrap: wrap !important;
783 | -ms-flex-wrap: wrap !important;
784 | flex-wrap: wrap !important;
785 | }
786 | .flex-lg-nowrap {
787 | -webkit-flex-wrap: nowrap !important;
788 | -ms-flex-wrap: nowrap !important;
789 | flex-wrap: nowrap !important;
790 | }
791 | .flex-lg-wrap-reverse {
792 | -webkit-flex-wrap: wrap-reverse !important;
793 | -ms-flex-wrap: wrap-reverse !important;
794 | flex-wrap: wrap-reverse !important;
795 | }
796 | .justify-content-lg-start {
797 | -webkit-box-pack: start !important;
798 | -webkit-justify-content: flex-start !important;
799 | -ms-flex-pack: start !important;
800 | justify-content: flex-start !important;
801 | }
802 | .justify-content-lg-end {
803 | -webkit-box-pack: end !important;
804 | -webkit-justify-content: flex-end !important;
805 | -ms-flex-pack: end !important;
806 | justify-content: flex-end !important;
807 | }
808 | .justify-content-lg-center {
809 | -webkit-box-pack: center !important;
810 | -webkit-justify-content: center !important;
811 | -ms-flex-pack: center !important;
812 | justify-content: center !important;
813 | }
814 | .justify-content-lg-between {
815 | -webkit-box-pack: justify !important;
816 | -webkit-justify-content: space-between !important;
817 | -ms-flex-pack: justify !important;
818 | justify-content: space-between !important;
819 | }
820 | .justify-content-lg-around {
821 | -webkit-justify-content: space-around !important;
822 | -ms-flex-pack: distribute !important;
823 | justify-content: space-around !important;
824 | }
825 | .align-items-lg-start {
826 | -webkit-box-align: start !important;
827 | -webkit-align-items: flex-start !important;
828 | -ms-flex-align: start !important;
829 | align-items: flex-start !important;
830 | }
831 | .align-items-lg-end {
832 | -webkit-box-align: end !important;
833 | -webkit-align-items: flex-end !important;
834 | -ms-flex-align: end !important;
835 | align-items: flex-end !important;
836 | }
837 | .align-items-lg-center {
838 | -webkit-box-align: center !important;
839 | -webkit-align-items: center !important;
840 | -ms-flex-align: center !important;
841 | align-items: center !important;
842 | }
843 | .align-items-lg-baseline {
844 | -webkit-box-align: baseline !important;
845 | -webkit-align-items: baseline !important;
846 | -ms-flex-align: baseline !important;
847 | align-items: baseline !important;
848 | }
849 | .align-items-lg-stretch {
850 | -webkit-box-align: stretch !important;
851 | -webkit-align-items: stretch !important;
852 | -ms-flex-align: stretch !important;
853 | align-items: stretch !important;
854 | }
855 | .align-content-lg-start {
856 | -webkit-align-content: flex-start !important;
857 | -ms-flex-line-pack: start !important;
858 | align-content: flex-start !important;
859 | }
860 | .align-content-lg-end {
861 | -webkit-align-content: flex-end !important;
862 | -ms-flex-line-pack: end !important;
863 | align-content: flex-end !important;
864 | }
865 | .align-content-lg-center {
866 | -webkit-align-content: center !important;
867 | -ms-flex-line-pack: center !important;
868 | align-content: center !important;
869 | }
870 | .align-content-lg-between {
871 | -webkit-align-content: space-between !important;
872 | -ms-flex-line-pack: justify !important;
873 | align-content: space-between !important;
874 | }
875 | .align-content-lg-around {
876 | -webkit-align-content: space-around !important;
877 | -ms-flex-line-pack: distribute !important;
878 | align-content: space-around !important;
879 | }
880 | .align-content-lg-stretch {
881 | -webkit-align-content: stretch !important;
882 | -ms-flex-line-pack: stretch !important;
883 | align-content: stretch !important;
884 | }
885 | .align-self-lg-auto {
886 | -webkit-align-self: auto !important;
887 | -ms-flex-item-align: auto !important;
888 | -ms-grid-row-align: auto !important;
889 | align-self: auto !important;
890 | }
891 | .align-self-lg-start {
892 | -webkit-align-self: flex-start !important;
893 | -ms-flex-item-align: start !important;
894 | align-self: flex-start !important;
895 | }
896 | .align-self-lg-end {
897 | -webkit-align-self: flex-end !important;
898 | -ms-flex-item-align: end !important;
899 | align-self: flex-end !important;
900 | }
901 | .align-self-lg-center {
902 | -webkit-align-self: center !important;
903 | -ms-flex-item-align: center !important;
904 | -ms-grid-row-align: center !important;
905 | align-self: center !important;
906 | }
907 | .align-self-lg-baseline {
908 | -webkit-align-self: baseline !important;
909 | -ms-flex-item-align: baseline !important;
910 | align-self: baseline !important;
911 | }
912 | .align-self-lg-stretch {
913 | -webkit-align-self: stretch !important;
914 | -ms-flex-item-align: stretch !important;
915 | -ms-grid-row-align: stretch !important;
916 | align-self: stretch !important;
917 | }
918 | }
919 |
920 | @media (min-width: 1200px) {
921 | .flex-xl-first {
922 | -webkit-box-ordinal-group: 0;
923 | -webkit-order: -1;
924 | -ms-flex-order: -1;
925 | order: -1;
926 | }
927 | .flex-xl-last {
928 | -webkit-box-ordinal-group: 2;
929 | -webkit-order: 1;
930 | -ms-flex-order: 1;
931 | order: 1;
932 | }
933 | .flex-xl-unordered {
934 | -webkit-box-ordinal-group: 1;
935 | -webkit-order: 0;
936 | -ms-flex-order: 0;
937 | order: 0;
938 | }
939 | .flex-xl-row {
940 | -webkit-box-orient: horizontal !important;
941 | -webkit-box-direction: normal !important;
942 | -webkit-flex-direction: row !important;
943 | -ms-flex-direction: row !important;
944 | flex-direction: row !important;
945 | }
946 | .flex-xl-column {
947 | -webkit-box-orient: vertical !important;
948 | -webkit-box-direction: normal !important;
949 | -webkit-flex-direction: column !important;
950 | -ms-flex-direction: column !important;
951 | flex-direction: column !important;
952 | }
953 | .flex-xl-row-reverse {
954 | -webkit-box-orient: horizontal !important;
955 | -webkit-box-direction: reverse !important;
956 | -webkit-flex-direction: row-reverse !important;
957 | -ms-flex-direction: row-reverse !important;
958 | flex-direction: row-reverse !important;
959 | }
960 | .flex-xl-column-reverse {
961 | -webkit-box-orient: vertical !important;
962 | -webkit-box-direction: reverse !important;
963 | -webkit-flex-direction: column-reverse !important;
964 | -ms-flex-direction: column-reverse !important;
965 | flex-direction: column-reverse !important;
966 | }
967 | .flex-xl-wrap {
968 | -webkit-flex-wrap: wrap !important;
969 | -ms-flex-wrap: wrap !important;
970 | flex-wrap: wrap !important;
971 | }
972 | .flex-xl-nowrap {
973 | -webkit-flex-wrap: nowrap !important;
974 | -ms-flex-wrap: nowrap !important;
975 | flex-wrap: nowrap !important;
976 | }
977 | .flex-xl-wrap-reverse {
978 | -webkit-flex-wrap: wrap-reverse !important;
979 | -ms-flex-wrap: wrap-reverse !important;
980 | flex-wrap: wrap-reverse !important;
981 | }
982 | .justify-content-xl-start {
983 | -webkit-box-pack: start !important;
984 | -webkit-justify-content: flex-start !important;
985 | -ms-flex-pack: start !important;
986 | justify-content: flex-start !important;
987 | }
988 | .justify-content-xl-end {
989 | -webkit-box-pack: end !important;
990 | -webkit-justify-content: flex-end !important;
991 | -ms-flex-pack: end !important;
992 | justify-content: flex-end !important;
993 | }
994 | .justify-content-xl-center {
995 | -webkit-box-pack: center !important;
996 | -webkit-justify-content: center !important;
997 | -ms-flex-pack: center !important;
998 | justify-content: center !important;
999 | }
1000 | .justify-content-xl-between {
1001 | -webkit-box-pack: justify !important;
1002 | -webkit-justify-content: space-between !important;
1003 | -ms-flex-pack: justify !important;
1004 | justify-content: space-between !important;
1005 | }
1006 | .justify-content-xl-around {
1007 | -webkit-justify-content: space-around !important;
1008 | -ms-flex-pack: distribute !important;
1009 | justify-content: space-around !important;
1010 | }
1011 | .align-items-xl-start {
1012 | -webkit-box-align: start !important;
1013 | -webkit-align-items: flex-start !important;
1014 | -ms-flex-align: start !important;
1015 | align-items: flex-start !important;
1016 | }
1017 | .align-items-xl-end {
1018 | -webkit-box-align: end !important;
1019 | -webkit-align-items: flex-end !important;
1020 | -ms-flex-align: end !important;
1021 | align-items: flex-end !important;
1022 | }
1023 | .align-items-xl-center {
1024 | -webkit-box-align: center !important;
1025 | -webkit-align-items: center !important;
1026 | -ms-flex-align: center !important;
1027 | align-items: center !important;
1028 | }
1029 | .align-items-xl-baseline {
1030 | -webkit-box-align: baseline !important;
1031 | -webkit-align-items: baseline !important;
1032 | -ms-flex-align: baseline !important;
1033 | align-items: baseline !important;
1034 | }
1035 | .align-items-xl-stretch {
1036 | -webkit-box-align: stretch !important;
1037 | -webkit-align-items: stretch !important;
1038 | -ms-flex-align: stretch !important;
1039 | align-items: stretch !important;
1040 | }
1041 | .align-content-xl-start {
1042 | -webkit-align-content: flex-start !important;
1043 | -ms-flex-line-pack: start !important;
1044 | align-content: flex-start !important;
1045 | }
1046 | .align-content-xl-end {
1047 | -webkit-align-content: flex-end !important;
1048 | -ms-flex-line-pack: end !important;
1049 | align-content: flex-end !important;
1050 | }
1051 | .align-content-xl-center {
1052 | -webkit-align-content: center !important;
1053 | -ms-flex-line-pack: center !important;
1054 | align-content: center !important;
1055 | }
1056 | .align-content-xl-between {
1057 | -webkit-align-content: space-between !important;
1058 | -ms-flex-line-pack: justify !important;
1059 | align-content: space-between !important;
1060 | }
1061 | .align-content-xl-around {
1062 | -webkit-align-content: space-around !important;
1063 | -ms-flex-line-pack: distribute !important;
1064 | align-content: space-around !important;
1065 | }
1066 | .align-content-xl-stretch {
1067 | -webkit-align-content: stretch !important;
1068 | -ms-flex-line-pack: stretch !important;
1069 | align-content: stretch !important;
1070 | }
1071 | .align-self-xl-auto {
1072 | -webkit-align-self: auto !important;
1073 | -ms-flex-item-align: auto !important;
1074 | -ms-grid-row-align: auto !important;
1075 | align-self: auto !important;
1076 | }
1077 | .align-self-xl-start {
1078 | -webkit-align-self: flex-start !important;
1079 | -ms-flex-item-align: start !important;
1080 | align-self: flex-start !important;
1081 | }
1082 | .align-self-xl-end {
1083 | -webkit-align-self: flex-end !important;
1084 | -ms-flex-item-align: end !important;
1085 | align-self: flex-end !important;
1086 | }
1087 | .align-self-xl-center {
1088 | -webkit-align-self: center !important;
1089 | -ms-flex-item-align: center !important;
1090 | -ms-grid-row-align: center !important;
1091 | align-self: center !important;
1092 | }
1093 | .align-self-xl-baseline {
1094 | -webkit-align-self: baseline !important;
1095 | -ms-flex-item-align: baseline !important;
1096 | align-self: baseline !important;
1097 | }
1098 | .align-self-xl-stretch {
1099 | -webkit-align-self: stretch !important;
1100 | -ms-flex-item-align: stretch !important;
1101 | -ms-grid-row-align: stretch !important;
1102 | align-self: stretch !important;
1103 | }
1104 | }
1105 |
1106 | @media (max-width: 576px) {
1107 | .flex-sm-down-first {
1108 | -webkit-box-ordinal-group: 0;
1109 | -webkit-order: -1;
1110 | -ms-flex-order: -1;
1111 | order: -1;
1112 | }
1113 | .flex-sm-down-last {
1114 | -webkit-box-ordinal-group: 2;
1115 | -webkit-order: 1;
1116 | -ms-flex-order: 1;
1117 | order: 1;
1118 | }
1119 | .flex-sm-down-unordered {
1120 | -webkit-box-ordinal-group: 1;
1121 | -webkit-order: 0;
1122 | -ms-flex-order: 0;
1123 | order: 0;
1124 | }
1125 | }
1126 |
1127 | @media (max-width: 768px) {
1128 | .flex-md-down-first {
1129 | -webkit-box-ordinal-group: 0;
1130 | -webkit-order: -1;
1131 | -ms-flex-order: -1;
1132 | order: -1;
1133 | }
1134 | .flex-md-down-last {
1135 | -webkit-box-ordinal-group: 2;
1136 | -webkit-order: 1;
1137 | -ms-flex-order: 1;
1138 | order: 1;
1139 | }
1140 | .flex-md-down-unordered {
1141 | -webkit-box-ordinal-group: 1;
1142 | -webkit-order: 0;
1143 | -ms-flex-order: 0;
1144 | order: 0;
1145 | }
1146 | }
1147 |
1148 | @media (max-width: 992px) {
1149 | .flex-lg-down-first {
1150 | -webkit-box-ordinal-group: 0;
1151 | -webkit-order: -1;
1152 | -ms-flex-order: -1;
1153 | order: -1;
1154 | }
1155 | .flex-lg-down-last {
1156 | -webkit-box-ordinal-group: 2;
1157 | -webkit-order: 1;
1158 | -ms-flex-order: 1;
1159 | order: 1;
1160 | }
1161 | .flex-lg-down-unordered {
1162 | -webkit-box-ordinal-group: 1;
1163 | -webkit-order: 0;
1164 | -ms-flex-order: 0;
1165 | order: 0;
1166 | }
1167 | }
1168 |
--------------------------------------------------------------------------------
/projects/tenant-portal/src/assets/css/_utility.scss:
--------------------------------------------------------------------------------
1 | .no-gutters {
2 | margin-right: 0;
3 | margin-left: 0;
4 | }
5 |
6 | .no-gutters > .col,
7 | .no-gutters > [class*="col-"] {
8 | padding-right: 0;
9 | padding-left: 0;
10 | }
11 | .float-left {
12 | float: left !important;
13 | }
14 |
15 | .float-right {
16 | float: right !important;
17 | }
18 |
19 | .float-none {
20 | float: none !important;
21 | }
22 |
23 | @media (min-width: 576px) {
24 | .float-sm-left {
25 | float: left !important;
26 | }
27 | .float-sm-right {
28 | float: right !important;
29 | }
30 | .float-sm-none {
31 | float: none !important;
32 | }
33 | }
34 |
35 | @media (min-width: 768px) {
36 | .float-md-left {
37 | float: left !important;
38 | }
39 | .float-md-right {
40 | float: right !important;
41 | }
42 | .float-md-none {
43 | float: none !important;
44 | }
45 | }
46 |
47 | @media (min-width: 992px) {
48 | .float-lg-left {
49 | float: left !important;
50 | }
51 | .float-lg-right {
52 | float: right !important;
53 | }
54 | .float-lg-none {
55 | float: none !important;
56 | }
57 | }
58 |
59 | @media (min-width: 1200px) {
60 | .float-xl-left {
61 | float: left !important;
62 | }
63 | .float-xl-right {
64 | float: right !important;
65 | }
66 | .float-xl-none {
67 | float: none !important;
68 | }
69 | }
70 |
71 | .fixed-top {
72 | position: fixed;
73 | top: 0;
74 | right: 0;
75 | left: 0;
76 | z-index: 1030;
77 | }
78 |
79 | .fixed-bottom {
80 | position: fixed;
81 | right: 0;
82 | bottom: 0;
83 | left: 0;
84 | z-index: 1030;
85 | }
86 |
87 | .sticky-top {
88 | position: -webkit-sticky;
89 | position: sticky;
90 | top: 0;
91 | z-index: 1030;
92 | }
93 |
94 | .sr-only {
95 | position: absolute;
96 | width: 1px;
97 | height: 1px;
98 | padding: 0;
99 | margin: -1px;
100 | overflow: hidden;
101 | clip: rect(0, 0, 0, 0);
102 | border: 0;
103 | }
104 |
105 | .sr-only-focusable:active,
106 | .sr-only-focusable:focus {
107 | position: static;
108 | width: auto;
109 | height: auto;
110 | margin: 0;
111 | overflow: visible;
112 | clip: auto;
113 | }
114 |
115 | .w-25 {
116 | width: 25% !important;
117 | }
118 |
119 | .w-50 {
120 | width: 50% !important;
121 | }
122 |
123 | .w-75 {
124 | width: 75% !important;
125 | }
126 |
127 | .w-100 {
128 | width: 100% !important;
129 | }
130 |
131 | .h-25 {
132 | height: 25% !important;
133 | }
134 |
135 | .h-50 {
136 | height: 50% !important;
137 | }
138 |
139 | .h-75 {
140 | height: 75% !important;
141 | }
142 |
143 | .h-100 {
144 | height: 100% !important;
145 | }
146 |
147 | .mw-100 {
148 | max-width: 100% !important;
149 | }
150 |
151 | .mh-100 {
152 | max-height: 100% !important;
153 | }
154 |
155 | .m-0 {
156 | margin: 0 0 !important;
157 | }
158 |
159 | .mt-0 {
160 | margin-top: 0 !important;
161 | }
162 |
163 | .mr-0 {
164 | margin-right: 0 !important;
165 | }
166 |
167 | .mb-0 {
168 | margin-bottom: 0 !important;
169 | }
170 |
171 | .ml-0 {
172 | margin-left: 0 !important;
173 | }
174 |
175 | .mx-0 {
176 | margin-right: 0 !important;
177 | margin-left: 0 !important;
178 | }
179 |
180 | .my-0 {
181 | margin-top: 0 !important;
182 | margin-bottom: 0 !important;
183 | }
184 |
185 | .m-1 {
186 | margin: 0.25rem 0.25rem !important;
187 | }
188 |
189 | .mt-1 {
190 | margin-top: 0.25rem !important;
191 | }
192 |
193 | .mr-1 {
194 | margin-right: 0.25rem !important;
195 | }
196 |
197 | .mb-1 {
198 | margin-bottom: 0.25rem !important;
199 | }
200 |
201 | .ml-1 {
202 | margin-left: 0.25rem !important;
203 | }
204 |
205 | .mx-1 {
206 | margin-right: 0.25rem !important;
207 | margin-left: 0.25rem !important;
208 | }
209 |
210 | .my-1 {
211 | margin-top: 0.25rem !important;
212 | margin-bottom: 0.25rem !important;
213 | }
214 |
215 | .m-2 {
216 | margin: 0.5rem 0.5rem !important;
217 | }
218 |
219 | .mt-2 {
220 | margin-top: 0.5rem !important;
221 | }
222 |
223 | .mr-2 {
224 | margin-right: 0.5rem !important;
225 | }
226 |
227 | .mb-2 {
228 | margin-bottom: 0.5rem !important;
229 | }
230 |
231 | .ml-2 {
232 | margin-left: 0.5rem !important;
233 | }
234 |
235 | .mx-2 {
236 | margin-right: 0.5rem !important;
237 | margin-left: 0.5rem !important;
238 | }
239 |
240 | .my-2 {
241 | margin-top: 0.5rem !important;
242 | margin-bottom: 0.5rem !important;
243 | }
244 |
245 | .m-3 {
246 | margin: 1rem 1rem !important;
247 | }
248 |
249 | .mt-3 {
250 | margin-top: 1rem !important;
251 | }
252 |
253 | .mr-3 {
254 | margin-right: 1rem !important;
255 | }
256 |
257 | .mb-3 {
258 | margin-bottom: 1rem !important;
259 | }
260 |
261 | .ml-3 {
262 | margin-left: 1rem !important;
263 | }
264 |
265 | .mx-3 {
266 | margin-right: 1rem !important;
267 | margin-left: 1rem !important;
268 | }
269 |
270 | .my-3 {
271 | margin-top: 1rem !important;
272 | margin-bottom: 1rem !important;
273 | }
274 |
275 | .m-4 {
276 | margin: 1.5rem 1.5rem !important;
277 | }
278 |
279 | .mt-4 {
280 | margin-top: 1.5rem !important;
281 | }
282 |
283 | .mr-4 {
284 | margin-right: 1.5rem !important;
285 | }
286 |
287 | .mb-4 {
288 | margin-bottom: 1.5rem !important;
289 | }
290 |
291 | .ml-4 {
292 | margin-left: 1.5rem !important;
293 | }
294 |
295 | .mx-4 {
296 | margin-right: 1.5rem !important;
297 | margin-left: 1.5rem !important;
298 | }
299 |
300 | .my-4 {
301 | margin-top: 1.5rem !important;
302 | margin-bottom: 1.5rem !important;
303 | }
304 |
305 | .m-5 {
306 | margin: 3rem 3rem !important;
307 | }
308 |
309 | .mt-5 {
310 | margin-top: 3rem !important;
311 | }
312 |
313 | .mr-5 {
314 | margin-right: 3rem !important;
315 | }
316 |
317 | .mb-5 {
318 | margin-bottom: 3rem !important;
319 | }
320 |
321 | .ml-5 {
322 | margin-left: 3rem !important;
323 | }
324 |
325 | .mx-5 {
326 | margin-right: 3rem !important;
327 | margin-left: 3rem !important;
328 | }
329 |
330 | .my-5 {
331 | margin-top: 3rem !important;
332 | margin-bottom: 3rem !important;
333 | }
334 |
335 | .p-0 {
336 | padding: 0 0 !important;
337 | }
338 |
339 | .pt-0 {
340 | padding-top: 0 !important;
341 | }
342 |
343 | .pr-0 {
344 | padding-right: 0 !important;
345 | }
346 |
347 | .pb-0 {
348 | padding-bottom: 0 !important;
349 | }
350 |
351 | .pl-0 {
352 | padding-left: 0 !important;
353 | }
354 |
355 | .px-0 {
356 | padding-right: 0 !important;
357 | padding-left: 0 !important;
358 | }
359 |
360 | .py-0 {
361 | padding-top: 0 !important;
362 | padding-bottom: 0 !important;
363 | }
364 |
365 | .p-1 {
366 | padding: 0.25rem 0.25rem !important;
367 | }
368 |
369 | .pt-1 {
370 | padding-top: 0.25rem !important;
371 | }
372 |
373 | .pr-1 {
374 | padding-right: 0.25rem !important;
375 | }
376 |
377 | .pb-1 {
378 | padding-bottom: 0.25rem !important;
379 | }
380 |
381 | .pl-1 {
382 | padding-left: 0.25rem !important;
383 | }
384 |
385 | .px-1 {
386 | padding-right: 0.25rem !important;
387 | padding-left: 0.25rem !important;
388 | }
389 |
390 | .py-1 {
391 | padding-top: 0.25rem !important;
392 | padding-bottom: 0.25rem !important;
393 | }
394 |
395 | .p-2 {
396 | padding: 0.5rem 0.5rem !important;
397 | }
398 |
399 | .pt-2 {
400 | padding-top: 0.5rem !important;
401 | }
402 |
403 | .pr-2 {
404 | padding-right: 0.5rem !important;
405 | }
406 |
407 | .pb-2 {
408 | padding-bottom: 0.5rem !important;
409 | }
410 |
411 | .pl-2 {
412 | padding-left: 0.5rem !important;
413 | }
414 |
415 | .px-2 {
416 | padding-right: 0.5rem !important;
417 | padding-left: 0.5rem !important;
418 | }
419 |
420 | .py-2 {
421 | padding-top: 0.5rem !important;
422 | padding-bottom: 0.5rem !important;
423 | }
424 |
425 | .p-3 {
426 | padding: 1rem 1rem !important;
427 | }
428 |
429 | .pt-3 {
430 | padding-top: 1rem !important;
431 | }
432 |
433 | .pr-3 {
434 | padding-right: 1rem !important;
435 | }
436 |
437 | .pb-3 {
438 | padding-bottom: 1rem !important;
439 | }
440 |
441 | .pl-3 {
442 | padding-left: 1rem !important;
443 | }
444 |
445 | .px-3 {
446 | padding-right: 1rem !important;
447 | padding-left: 1rem !important;
448 | }
449 |
450 | .py-3 {
451 | padding-top: 1rem !important;
452 | padding-bottom: 1rem !important;
453 | }
454 |
455 | .p-4 {
456 | padding: 1.5rem 1.5rem !important;
457 | }
458 |
459 | .pt-4 {
460 | padding-top: 1.5rem !important;
461 | }
462 |
463 | .pr-4 {
464 | padding-right: 1.5rem !important;
465 | }
466 |
467 | .pb-4 {
468 | padding-bottom: 1.5rem !important;
469 | }
470 |
471 | .pl-4 {
472 | padding-left: 1.5rem !important;
473 | }
474 |
475 | .px-4 {
476 | padding-right: 1.5rem !important;
477 | padding-left: 1.5rem !important;
478 | }
479 |
480 | .py-4 {
481 | padding-top: 1.5rem !important;
482 | padding-bottom: 1.5rem !important;
483 | }
484 |
485 | .p-5 {
486 | padding: 3rem 3rem !important;
487 | }
488 |
489 | .pt-5 {
490 | padding-top: 3rem !important;
491 | }
492 |
493 | .pr-5 {
494 | padding-right: 3rem !important;
495 | }
496 |
497 | .pb-5 {
498 | padding-bottom: 3rem !important;
499 | }
500 |
501 | .pl-5 {
502 | padding-left: 3rem !important;
503 | }
504 |
505 | .px-5 {
506 | padding-right: 3rem !important;
507 | padding-left: 3rem !important;
508 | }
509 |
510 | .py-5 {
511 | padding-top: 3rem !important;
512 | padding-bottom: 3rem !important;
513 | }
514 |
515 | .m-auto {
516 | margin: auto !important;
517 | }
518 |
519 | .mt-auto {
520 | margin-top: auto !important;
521 | }
522 |
523 | .mr-auto {
524 | margin-right: auto !important;
525 | }
526 |
527 | .mb-auto {
528 | margin-bottom: auto !important;
529 | }
530 |
531 | .ml-auto {
532 | margin-left: auto !important;
533 | }
534 |
535 | .mx-auto {
536 | margin-right: auto !important;
537 | margin-left: auto !important;
538 | }
539 |
540 | .my-auto {
541 | margin-top: auto !important;
542 | margin-bottom: auto !important;
543 | }
544 |
545 | @media (min-width: 576px) {
546 | .m-sm-0 {
547 | margin: 0 0 !important;
548 | }
549 | .mt-sm-0 {
550 | margin-top: 0 !important;
551 | }
552 | .mr-sm-0 {
553 | margin-right: 0 !important;
554 | }
555 | .mb-sm-0 {
556 | margin-bottom: 0 !important;
557 | }
558 | .ml-sm-0 {
559 | margin-left: 0 !important;
560 | }
561 | .mx-sm-0 {
562 | margin-right: 0 !important;
563 | margin-left: 0 !important;
564 | }
565 | .my-sm-0 {
566 | margin-top: 0 !important;
567 | margin-bottom: 0 !important;
568 | }
569 | .m-sm-1 {
570 | margin: 0.25rem 0.25rem !important;
571 | }
572 | .mt-sm-1 {
573 | margin-top: 0.25rem !important;
574 | }
575 | .mr-sm-1 {
576 | margin-right: 0.25rem !important;
577 | }
578 | .mb-sm-1 {
579 | margin-bottom: 0.25rem !important;
580 | }
581 | .ml-sm-1 {
582 | margin-left: 0.25rem !important;
583 | }
584 | .mx-sm-1 {
585 | margin-right: 0.25rem !important;
586 | margin-left: 0.25rem !important;
587 | }
588 | .my-sm-1 {
589 | margin-top: 0.25rem !important;
590 | margin-bottom: 0.25rem !important;
591 | }
592 | .m-sm-2 {
593 | margin: 0.5rem 0.5rem !important;
594 | }
595 | .mt-sm-2 {
596 | margin-top: 0.5rem !important;
597 | }
598 | .mr-sm-2 {
599 | margin-right: 0.5rem !important;
600 | }
601 | .mb-sm-2 {
602 | margin-bottom: 0.5rem !important;
603 | }
604 | .ml-sm-2 {
605 | margin-left: 0.5rem !important;
606 | }
607 | .mx-sm-2 {
608 | margin-right: 0.5rem !important;
609 | margin-left: 0.5rem !important;
610 | }
611 | .my-sm-2 {
612 | margin-top: 0.5rem !important;
613 | margin-bottom: 0.5rem !important;
614 | }
615 | .m-sm-3 {
616 | margin: 1rem 1rem !important;
617 | }
618 | .mt-sm-3 {
619 | margin-top: 1rem !important;
620 | }
621 | .mr-sm-3 {
622 | margin-right: 1rem !important;
623 | }
624 | .mb-sm-3 {
625 | margin-bottom: 1rem !important;
626 | }
627 | .ml-sm-3 {
628 | margin-left: 1rem !important;
629 | }
630 | .mx-sm-3 {
631 | margin-right: 1rem !important;
632 | margin-left: 1rem !important;
633 | }
634 | .my-sm-3 {
635 | margin-top: 1rem !important;
636 | margin-bottom: 1rem !important;
637 | }
638 | .m-sm-4 {
639 | margin: 1.5rem 1.5rem !important;
640 | }
641 | .mt-sm-4 {
642 | margin-top: 1.5rem !important;
643 | }
644 | .mr-sm-4 {
645 | margin-right: 1.5rem !important;
646 | }
647 | .mb-sm-4 {
648 | margin-bottom: 1.5rem !important;
649 | }
650 | .ml-sm-4 {
651 | margin-left: 1.5rem !important;
652 | }
653 | .mx-sm-4 {
654 | margin-right: 1.5rem !important;
655 | margin-left: 1.5rem !important;
656 | }
657 | .my-sm-4 {
658 | margin-top: 1.5rem !important;
659 | margin-bottom: 1.5rem !important;
660 | }
661 | .m-sm-5 {
662 | margin: 3rem 3rem !important;
663 | }
664 | .mt-sm-5 {
665 | margin-top: 3rem !important;
666 | }
667 | .mr-sm-5 {
668 | margin-right: 3rem !important;
669 | }
670 | .mb-sm-5 {
671 | margin-bottom: 3rem !important;
672 | }
673 | .ml-sm-5 {
674 | margin-left: 3rem !important;
675 | }
676 | .mx-sm-5 {
677 | margin-right: 3rem !important;
678 | margin-left: 3rem !important;
679 | }
680 | .my-sm-5 {
681 | margin-top: 3rem !important;
682 | margin-bottom: 3rem !important;
683 | }
684 | .p-sm-0 {
685 | padding: 0 0 !important;
686 | }
687 | .pt-sm-0 {
688 | padding-top: 0 !important;
689 | }
690 | .pr-sm-0 {
691 | padding-right: 0 !important;
692 | }
693 | .pb-sm-0 {
694 | padding-bottom: 0 !important;
695 | }
696 | .pl-sm-0 {
697 | padding-left: 0 !important;
698 | }
699 | .px-sm-0 {
700 | padding-right: 0 !important;
701 | padding-left: 0 !important;
702 | }
703 | .py-sm-0 {
704 | padding-top: 0 !important;
705 | padding-bottom: 0 !important;
706 | }
707 | .p-sm-1 {
708 | padding: 0.25rem 0.25rem !important;
709 | }
710 | .pt-sm-1 {
711 | padding-top: 0.25rem !important;
712 | }
713 | .pr-sm-1 {
714 | padding-right: 0.25rem !important;
715 | }
716 | .pb-sm-1 {
717 | padding-bottom: 0.25rem !important;
718 | }
719 | .pl-sm-1 {
720 | padding-left: 0.25rem !important;
721 | }
722 | .px-sm-1 {
723 | padding-right: 0.25rem !important;
724 | padding-left: 0.25rem !important;
725 | }
726 | .py-sm-1 {
727 | padding-top: 0.25rem !important;
728 | padding-bottom: 0.25rem !important;
729 | }
730 | .p-sm-2 {
731 | padding: 0.5rem 0.5rem !important;
732 | }
733 | .pt-sm-2 {
734 | padding-top: 0.5rem !important;
735 | }
736 | .pr-sm-2 {
737 | padding-right: 0.5rem !important;
738 | }
739 | .pb-sm-2 {
740 | padding-bottom: 0.5rem !important;
741 | }
742 | .pl-sm-2 {
743 | padding-left: 0.5rem !important;
744 | }
745 | .px-sm-2 {
746 | padding-right: 0.5rem !important;
747 | padding-left: 0.5rem !important;
748 | }
749 | .py-sm-2 {
750 | padding-top: 0.5rem !important;
751 | padding-bottom: 0.5rem !important;
752 | }
753 | .p-sm-3 {
754 | padding: 1rem 1rem !important;
755 | }
756 | .pt-sm-3 {
757 | padding-top: 1rem !important;
758 | }
759 | .pr-sm-3 {
760 | padding-right: 1rem !important;
761 | }
762 | .pb-sm-3 {
763 | padding-bottom: 1rem !important;
764 | }
765 | .pl-sm-3 {
766 | padding-left: 1rem !important;
767 | }
768 | .px-sm-3 {
769 | padding-right: 1rem !important;
770 | padding-left: 1rem !important;
771 | }
772 | .py-sm-3 {
773 | padding-top: 1rem !important;
774 | padding-bottom: 1rem !important;
775 | }
776 | .p-sm-4 {
777 | padding: 1.5rem 1.5rem !important;
778 | }
779 | .pt-sm-4 {
780 | padding-top: 1.5rem !important;
781 | }
782 | .pr-sm-4 {
783 | padding-right: 1.5rem !important;
784 | }
785 | .pb-sm-4 {
786 | padding-bottom: 1.5rem !important;
787 | }
788 | .pl-sm-4 {
789 | padding-left: 1.5rem !important;
790 | }
791 | .px-sm-4 {
792 | padding-right: 1.5rem !important;
793 | padding-left: 1.5rem !important;
794 | }
795 | .py-sm-4 {
796 | padding-top: 1.5rem !important;
797 | padding-bottom: 1.5rem !important;
798 | }
799 | .p-sm-5 {
800 | padding: 3rem 3rem !important;
801 | }
802 | .pt-sm-5 {
803 | padding-top: 3rem !important;
804 | }
805 | .pr-sm-5 {
806 | padding-right: 3rem !important;
807 | }
808 | .pb-sm-5 {
809 | padding-bottom: 3rem !important;
810 | }
811 | .pl-sm-5 {
812 | padding-left: 3rem !important;
813 | }
814 | .px-sm-5 {
815 | padding-right: 3rem !important;
816 | padding-left: 3rem !important;
817 | }
818 | .py-sm-5 {
819 | padding-top: 3rem !important;
820 | padding-bottom: 3rem !important;
821 | }
822 | .m-sm-auto {
823 | margin: auto !important;
824 | }
825 | .mt-sm-auto {
826 | margin-top: auto !important;
827 | }
828 | .mr-sm-auto {
829 | margin-right: auto !important;
830 | }
831 | .mb-sm-auto {
832 | margin-bottom: auto !important;
833 | }
834 | .ml-sm-auto {
835 | margin-left: auto !important;
836 | }
837 | .mx-sm-auto {
838 | margin-right: auto !important;
839 | margin-left: auto !important;
840 | }
841 | .my-sm-auto {
842 | margin-top: auto !important;
843 | margin-bottom: auto !important;
844 | }
845 | }
846 |
847 | @media (min-width: 768px) {
848 | .m-md-0 {
849 | margin: 0 0 !important;
850 | }
851 | .mt-md-0 {
852 | margin-top: 0 !important;
853 | }
854 | .mr-md-0 {
855 | margin-right: 0 !important;
856 | }
857 | .mb-md-0 {
858 | margin-bottom: 0 !important;
859 | }
860 | .ml-md-0 {
861 | margin-left: 0 !important;
862 | }
863 | .mx-md-0 {
864 | margin-right: 0 !important;
865 | margin-left: 0 !important;
866 | }
867 | .my-md-0 {
868 | margin-top: 0 !important;
869 | margin-bottom: 0 !important;
870 | }
871 | .m-md-1 {
872 | margin: 0.25rem 0.25rem !important;
873 | }
874 | .mt-md-1 {
875 | margin-top: 0.25rem !important;
876 | }
877 | .mr-md-1 {
878 | margin-right: 0.25rem !important;
879 | }
880 | .mb-md-1 {
881 | margin-bottom: 0.25rem !important;
882 | }
883 | .ml-md-1 {
884 | margin-left: 0.25rem !important;
885 | }
886 | .mx-md-1 {
887 | margin-right: 0.25rem !important;
888 | margin-left: 0.25rem !important;
889 | }
890 | .my-md-1 {
891 | margin-top: 0.25rem !important;
892 | margin-bottom: 0.25rem !important;
893 | }
894 | .m-md-2 {
895 | margin: 0.5rem 0.5rem !important;
896 | }
897 | .mt-md-2 {
898 | margin-top: 0.5rem !important;
899 | }
900 | .mr-md-2 {
901 | margin-right: 0.5rem !important;
902 | }
903 | .mb-md-2 {
904 | margin-bottom: 0.5rem !important;
905 | }
906 | .ml-md-2 {
907 | margin-left: 0.5rem !important;
908 | }
909 | .mx-md-2 {
910 | margin-right: 0.5rem !important;
911 | margin-left: 0.5rem !important;
912 | }
913 | .my-md-2 {
914 | margin-top: 0.5rem !important;
915 | margin-bottom: 0.5rem !important;
916 | }
917 | .m-md-3 {
918 | margin: 1rem 1rem !important;
919 | }
920 | .mt-md-3 {
921 | margin-top: 1rem !important;
922 | }
923 | .mr-md-3 {
924 | margin-right: 1rem !important;
925 | }
926 | .mb-md-3 {
927 | margin-bottom: 1rem !important;
928 | }
929 | .ml-md-3 {
930 | margin-left: 1rem !important;
931 | }
932 | .mx-md-3 {
933 | margin-right: 1rem !important;
934 | margin-left: 1rem !important;
935 | }
936 | .my-md-3 {
937 | margin-top: 1rem !important;
938 | margin-bottom: 1rem !important;
939 | }
940 | .m-md-4 {
941 | margin: 1.5rem 1.5rem !important;
942 | }
943 | .mt-md-4 {
944 | margin-top: 1.5rem !important;
945 | }
946 | .mr-md-4 {
947 | margin-right: 1.5rem !important;
948 | }
949 | .mb-md-4 {
950 | margin-bottom: 1.5rem !important;
951 | }
952 | .ml-md-4 {
953 | margin-left: 1.5rem !important;
954 | }
955 | .mx-md-4 {
956 | margin-right: 1.5rem !important;
957 | margin-left: 1.5rem !important;
958 | }
959 | .my-md-4 {
960 | margin-top: 1.5rem !important;
961 | margin-bottom: 1.5rem !important;
962 | }
963 | .m-md-5 {
964 | margin: 3rem 3rem !important;
965 | }
966 | .mt-md-5 {
967 | margin-top: 3rem !important;
968 | }
969 | .mr-md-5 {
970 | margin-right: 3rem !important;
971 | }
972 | .mb-md-5 {
973 | margin-bottom: 3rem !important;
974 | }
975 | .ml-md-5 {
976 | margin-left: 3rem !important;
977 | }
978 | .mx-md-5 {
979 | margin-right: 3rem !important;
980 | margin-left: 3rem !important;
981 | }
982 | .my-md-5 {
983 | margin-top: 3rem !important;
984 | margin-bottom: 3rem !important;
985 | }
986 | .p-md-0 {
987 | padding: 0 0 !important;
988 | }
989 | .pt-md-0 {
990 | padding-top: 0 !important;
991 | }
992 | .pr-md-0 {
993 | padding-right: 0 !important;
994 | }
995 | .pb-md-0 {
996 | padding-bottom: 0 !important;
997 | }
998 | .pl-md-0 {
999 | padding-left: 0 !important;
1000 | }
1001 | .px-md-0 {
1002 | padding-right: 0 !important;
1003 | padding-left: 0 !important;
1004 | }
1005 | .py-md-0 {
1006 | padding-top: 0 !important;
1007 | padding-bottom: 0 !important;
1008 | }
1009 | .p-md-1 {
1010 | padding: 0.25rem 0.25rem !important;
1011 | }
1012 | .pt-md-1 {
1013 | padding-top: 0.25rem !important;
1014 | }
1015 | .pr-md-1 {
1016 | padding-right: 0.25rem !important;
1017 | }
1018 | .pb-md-1 {
1019 | padding-bottom: 0.25rem !important;
1020 | }
1021 | .pl-md-1 {
1022 | padding-left: 0.25rem !important;
1023 | }
1024 | .px-md-1 {
1025 | padding-right: 0.25rem !important;
1026 | padding-left: 0.25rem !important;
1027 | }
1028 | .py-md-1 {
1029 | padding-top: 0.25rem !important;
1030 | padding-bottom: 0.25rem !important;
1031 | }
1032 | .p-md-2 {
1033 | padding: 0.5rem 0.5rem !important;
1034 | }
1035 | .pt-md-2 {
1036 | padding-top: 0.5rem !important;
1037 | }
1038 | .pr-md-2 {
1039 | padding-right: 0.5rem !important;
1040 | }
1041 | .pb-md-2 {
1042 | padding-bottom: 0.5rem !important;
1043 | }
1044 | .pl-md-2 {
1045 | padding-left: 0.5rem !important;
1046 | }
1047 | .px-md-2 {
1048 | padding-right: 0.5rem !important;
1049 | padding-left: 0.5rem !important;
1050 | }
1051 | .py-md-2 {
1052 | padding-top: 0.5rem !important;
1053 | padding-bottom: 0.5rem !important;
1054 | }
1055 | .p-md-3 {
1056 | padding: 1rem 1rem !important;
1057 | }
1058 | .pt-md-3 {
1059 | padding-top: 1rem !important;
1060 | }
1061 | .pr-md-3 {
1062 | padding-right: 1rem !important;
1063 | }
1064 | .pb-md-3 {
1065 | padding-bottom: 1rem !important;
1066 | }
1067 | .pl-md-3 {
1068 | padding-left: 1rem !important;
1069 | }
1070 | .px-md-3 {
1071 | padding-right: 1rem !important;
1072 | padding-left: 1rem !important;
1073 | }
1074 | .py-md-3 {
1075 | padding-top: 1rem !important;
1076 | padding-bottom: 1rem !important;
1077 | }
1078 | .p-md-4 {
1079 | padding: 1.5rem 1.5rem !important;
1080 | }
1081 | .pt-md-4 {
1082 | padding-top: 1.5rem !important;
1083 | }
1084 | .pr-md-4 {
1085 | padding-right: 1.5rem !important;
1086 | }
1087 | .pb-md-4 {
1088 | padding-bottom: 1.5rem !important;
1089 | }
1090 | .pl-md-4 {
1091 | padding-left: 1.5rem !important;
1092 | }
1093 | .px-md-4 {
1094 | padding-right: 1.5rem !important;
1095 | padding-left: 1.5rem !important;
1096 | }
1097 | .py-md-4 {
1098 | padding-top: 1.5rem !important;
1099 | padding-bottom: 1.5rem !important;
1100 | }
1101 | .p-md-5 {
1102 | padding: 3rem 3rem !important;
1103 | }
1104 | .pt-md-5 {
1105 | padding-top: 3rem !important;
1106 | }
1107 | .pr-md-5 {
1108 | padding-right: 3rem !important;
1109 | }
1110 | .pb-md-5 {
1111 | padding-bottom: 3rem !important;
1112 | }
1113 | .pl-md-5 {
1114 | padding-left: 3rem !important;
1115 | }
1116 | .px-md-5 {
1117 | padding-right: 3rem !important;
1118 | padding-left: 3rem !important;
1119 | }
1120 | .py-md-5 {
1121 | padding-top: 3rem !important;
1122 | padding-bottom: 3rem !important;
1123 | }
1124 | .m-md-auto {
1125 | margin: auto !important;
1126 | }
1127 | .mt-md-auto {
1128 | margin-top: auto !important;
1129 | }
1130 | .mr-md-auto {
1131 | margin-right: auto !important;
1132 | }
1133 | .mb-md-auto {
1134 | margin-bottom: auto !important;
1135 | }
1136 | .ml-md-auto {
1137 | margin-left: auto !important;
1138 | }
1139 | .mx-md-auto {
1140 | margin-right: auto !important;
1141 | margin-left: auto !important;
1142 | }
1143 | .my-md-auto {
1144 | margin-top: auto !important;
1145 | margin-bottom: auto !important;
1146 | }
1147 | }
1148 |
1149 | @media (min-width: 992px) {
1150 | .m-lg-0 {
1151 | margin: 0 0 !important;
1152 | }
1153 | .mt-lg-0 {
1154 | margin-top: 0 !important;
1155 | }
1156 | .mr-lg-0 {
1157 | margin-right: 0 !important;
1158 | }
1159 | .mb-lg-0 {
1160 | margin-bottom: 0 !important;
1161 | }
1162 | .ml-lg-0 {
1163 | margin-left: 0 !important;
1164 | }
1165 | .mx-lg-0 {
1166 | margin-right: 0 !important;
1167 | margin-left: 0 !important;
1168 | }
1169 | .my-lg-0 {
1170 | margin-top: 0 !important;
1171 | margin-bottom: 0 !important;
1172 | }
1173 | .m-lg-1 {
1174 | margin: 0.25rem 0.25rem !important;
1175 | }
1176 | .mt-lg-1 {
1177 | margin-top: 0.25rem !important;
1178 | }
1179 | .mr-lg-1 {
1180 | margin-right: 0.25rem !important;
1181 | }
1182 | .mb-lg-1 {
1183 | margin-bottom: 0.25rem !important;
1184 | }
1185 | .ml-lg-1 {
1186 | margin-left: 0.25rem !important;
1187 | }
1188 | .mx-lg-1 {
1189 | margin-right: 0.25rem !important;
1190 | margin-left: 0.25rem !important;
1191 | }
1192 | .my-lg-1 {
1193 | margin-top: 0.25rem !important;
1194 | margin-bottom: 0.25rem !important;
1195 | }
1196 | .m-lg-2 {
1197 | margin: 0.5rem 0.5rem !important;
1198 | }
1199 | .mt-lg-2 {
1200 | margin-top: 0.5rem !important;
1201 | }
1202 | .mr-lg-2 {
1203 | margin-right: 0.5rem !important;
1204 | }
1205 | .mb-lg-2 {
1206 | margin-bottom: 0.5rem !important;
1207 | }
1208 | .ml-lg-2 {
1209 | margin-left: 0.5rem !important;
1210 | }
1211 | .mx-lg-2 {
1212 | margin-right: 0.5rem !important;
1213 | margin-left: 0.5rem !important;
1214 | }
1215 | .my-lg-2 {
1216 | margin-top: 0.5rem !important;
1217 | margin-bottom: 0.5rem !important;
1218 | }
1219 | .m-lg-3 {
1220 | margin: 1rem 1rem !important;
1221 | }
1222 | .mt-lg-3 {
1223 | margin-top: 1rem !important;
1224 | }
1225 | .mr-lg-3 {
1226 | margin-right: 1rem !important;
1227 | }
1228 | .mb-lg-3 {
1229 | margin-bottom: 1rem !important;
1230 | }
1231 | .ml-lg-3 {
1232 | margin-left: 1rem !important;
1233 | }
1234 | .mx-lg-3 {
1235 | margin-right: 1rem !important;
1236 | margin-left: 1rem !important;
1237 | }
1238 | .my-lg-3 {
1239 | margin-top: 1rem !important;
1240 | margin-bottom: 1rem !important;
1241 | }
1242 | .m-lg-4 {
1243 | margin: 1.5rem 1.5rem !important;
1244 | }
1245 | .mt-lg-4 {
1246 | margin-top: 1.5rem !important;
1247 | }
1248 | .mr-lg-4 {
1249 | margin-right: 1.5rem !important;
1250 | }
1251 | .mb-lg-4 {
1252 | margin-bottom: 1.5rem !important;
1253 | }
1254 | .ml-lg-4 {
1255 | margin-left: 1.5rem !important;
1256 | }
1257 | .mx-lg-4 {
1258 | margin-right: 1.5rem !important;
1259 | margin-left: 1.5rem !important;
1260 | }
1261 | .my-lg-4 {
1262 | margin-top: 1.5rem !important;
1263 | margin-bottom: 1.5rem !important;
1264 | }
1265 | .m-lg-5 {
1266 | margin: 3rem 3rem !important;
1267 | }
1268 | .mt-lg-5 {
1269 | margin-top: 3rem !important;
1270 | }
1271 | .mr-lg-5 {
1272 | margin-right: 3rem !important;
1273 | }
1274 | .mb-lg-5 {
1275 | margin-bottom: 3rem !important;
1276 | }
1277 | .ml-lg-5 {
1278 | margin-left: 3rem !important;
1279 | }
1280 | .mx-lg-5 {
1281 | margin-right: 3rem !important;
1282 | margin-left: 3rem !important;
1283 | }
1284 | .my-lg-5 {
1285 | margin-top: 3rem !important;
1286 | margin-bottom: 3rem !important;
1287 | }
1288 | .p-lg-0 {
1289 | padding: 0 0 !important;
1290 | }
1291 | .pt-lg-0 {
1292 | padding-top: 0 !important;
1293 | }
1294 | .pr-lg-0 {
1295 | padding-right: 0 !important;
1296 | }
1297 | .pb-lg-0 {
1298 | padding-bottom: 0 !important;
1299 | }
1300 | .pl-lg-0 {
1301 | padding-left: 0 !important;
1302 | }
1303 | .px-lg-0 {
1304 | padding-right: 0 !important;
1305 | padding-left: 0 !important;
1306 | }
1307 | .py-lg-0 {
1308 | padding-top: 0 !important;
1309 | padding-bottom: 0 !important;
1310 | }
1311 | .p-lg-1 {
1312 | padding: 0.25rem 0.25rem !important;
1313 | }
1314 | .pt-lg-1 {
1315 | padding-top: 0.25rem !important;
1316 | }
1317 | .pr-lg-1 {
1318 | padding-right: 0.25rem !important;
1319 | }
1320 | .pb-lg-1 {
1321 | padding-bottom: 0.25rem !important;
1322 | }
1323 | .pl-lg-1 {
1324 | padding-left: 0.25rem !important;
1325 | }
1326 | .px-lg-1 {
1327 | padding-right: 0.25rem !important;
1328 | padding-left: 0.25rem !important;
1329 | }
1330 | .py-lg-1 {
1331 | padding-top: 0.25rem !important;
1332 | padding-bottom: 0.25rem !important;
1333 | }
1334 | .p-lg-2 {
1335 | padding: 0.5rem 0.5rem !important;
1336 | }
1337 | .pt-lg-2 {
1338 | padding-top: 0.5rem !important;
1339 | }
1340 | .pr-lg-2 {
1341 | padding-right: 0.5rem !important;
1342 | }
1343 | .pb-lg-2 {
1344 | padding-bottom: 0.5rem !important;
1345 | }
1346 | .pl-lg-2 {
1347 | padding-left: 0.5rem !important;
1348 | }
1349 | .px-lg-2 {
1350 | padding-right: 0.5rem !important;
1351 | padding-left: 0.5rem !important;
1352 | }
1353 | .py-lg-2 {
1354 | padding-top: 0.5rem !important;
1355 | padding-bottom: 0.5rem !important;
1356 | }
1357 | .p-lg-3 {
1358 | padding: 1rem 1rem !important;
1359 | }
1360 | .pt-lg-3 {
1361 | padding-top: 1rem !important;
1362 | }
1363 | .pr-lg-3 {
1364 | padding-right: 1rem !important;
1365 | }
1366 | .pb-lg-3 {
1367 | padding-bottom: 1rem !important;
1368 | }
1369 | .pl-lg-3 {
1370 | padding-left: 1rem !important;
1371 | }
1372 | .px-lg-3 {
1373 | padding-right: 1rem !important;
1374 | padding-left: 1rem !important;
1375 | }
1376 | .py-lg-3 {
1377 | padding-top: 1rem !important;
1378 | padding-bottom: 1rem !important;
1379 | }
1380 | .p-lg-4 {
1381 | padding: 1.5rem 1.5rem !important;
1382 | }
1383 | .pt-lg-4 {
1384 | padding-top: 1.5rem !important;
1385 | }
1386 | .pr-lg-4 {
1387 | padding-right: 1.5rem !important;
1388 | }
1389 | .pb-lg-4 {
1390 | padding-bottom: 1.5rem !important;
1391 | }
1392 | .pl-lg-4 {
1393 | padding-left: 1.5rem !important;
1394 | }
1395 | .px-lg-4 {
1396 | padding-right: 1.5rem !important;
1397 | padding-left: 1.5rem !important;
1398 | }
1399 | .py-lg-4 {
1400 | padding-top: 1.5rem !important;
1401 | padding-bottom: 1.5rem !important;
1402 | }
1403 | .p-lg-5 {
1404 | padding: 3rem 3rem !important;
1405 | }
1406 | .pt-lg-5 {
1407 | padding-top: 3rem !important;
1408 | }
1409 | .pr-lg-5 {
1410 | padding-right: 3rem !important;
1411 | }
1412 | .pb-lg-5 {
1413 | padding-bottom: 3rem !important;
1414 | }
1415 | .pl-lg-5 {
1416 | padding-left: 3rem !important;
1417 | }
1418 | .px-lg-5 {
1419 | padding-right: 3rem !important;
1420 | padding-left: 3rem !important;
1421 | }
1422 | .py-lg-5 {
1423 | padding-top: 3rem !important;
1424 | padding-bottom: 3rem !important;
1425 | }
1426 | .m-lg-auto {
1427 | margin: auto !important;
1428 | }
1429 | .mt-lg-auto {
1430 | margin-top: auto !important;
1431 | }
1432 | .mr-lg-auto {
1433 | margin-right: auto !important;
1434 | }
1435 | .mb-lg-auto {
1436 | margin-bottom: auto !important;
1437 | }
1438 | .ml-lg-auto {
1439 | margin-left: auto !important;
1440 | }
1441 | .mx-lg-auto {
1442 | margin-right: auto !important;
1443 | margin-left: auto !important;
1444 | }
1445 | .my-lg-auto {
1446 | margin-top: auto !important;
1447 | margin-bottom: auto !important;
1448 | }
1449 | }
1450 |
1451 | @media (min-width: 1200px) {
1452 | .m-xl-0 {
1453 | margin: 0 0 !important;
1454 | }
1455 | .mt-xl-0 {
1456 | margin-top: 0 !important;
1457 | }
1458 | .mr-xl-0 {
1459 | margin-right: 0 !important;
1460 | }
1461 | .mb-xl-0 {
1462 | margin-bottom: 0 !important;
1463 | }
1464 | .ml-xl-0 {
1465 | margin-left: 0 !important;
1466 | }
1467 | .mx-xl-0 {
1468 | margin-right: 0 !important;
1469 | margin-left: 0 !important;
1470 | }
1471 | .my-xl-0 {
1472 | margin-top: 0 !important;
1473 | margin-bottom: 0 !important;
1474 | }
1475 | .m-xl-1 {
1476 | margin: 0.25rem 0.25rem !important;
1477 | }
1478 | .mt-xl-1 {
1479 | margin-top: 0.25rem !important;
1480 | }
1481 | .mr-xl-1 {
1482 | margin-right: 0.25rem !important;
1483 | }
1484 | .mb-xl-1 {
1485 | margin-bottom: 0.25rem !important;
1486 | }
1487 | .ml-xl-1 {
1488 | margin-left: 0.25rem !important;
1489 | }
1490 | .mx-xl-1 {
1491 | margin-right: 0.25rem !important;
1492 | margin-left: 0.25rem !important;
1493 | }
1494 | .my-xl-1 {
1495 | margin-top: 0.25rem !important;
1496 | margin-bottom: 0.25rem !important;
1497 | }
1498 | .m-xl-2 {
1499 | margin: 0.5rem 0.5rem !important;
1500 | }
1501 | .mt-xl-2 {
1502 | margin-top: 0.5rem !important;
1503 | }
1504 | .mr-xl-2 {
1505 | margin-right: 0.5rem !important;
1506 | }
1507 | .mb-xl-2 {
1508 | margin-bottom: 0.5rem !important;
1509 | }
1510 | .ml-xl-2 {
1511 | margin-left: 0.5rem !important;
1512 | }
1513 | .mx-xl-2 {
1514 | margin-right: 0.5rem !important;
1515 | margin-left: 0.5rem !important;
1516 | }
1517 | .my-xl-2 {
1518 | margin-top: 0.5rem !important;
1519 | margin-bottom: 0.5rem !important;
1520 | }
1521 | .m-xl-3 {
1522 | margin: 1rem 1rem !important;
1523 | }
1524 | .mt-xl-3 {
1525 | margin-top: 1rem !important;
1526 | }
1527 | .mr-xl-3 {
1528 | margin-right: 1rem !important;
1529 | }
1530 | .mb-xl-3 {
1531 | margin-bottom: 1rem !important;
1532 | }
1533 | .ml-xl-3 {
1534 | margin-left: 1rem !important;
1535 | }
1536 | .mx-xl-3 {
1537 | margin-right: 1rem !important;
1538 | margin-left: 1rem !important;
1539 | }
1540 | .my-xl-3 {
1541 | margin-top: 1rem !important;
1542 | margin-bottom: 1rem !important;
1543 | }
1544 | .m-xl-4 {
1545 | margin: 1.5rem 1.5rem !important;
1546 | }
1547 | .mt-xl-4 {
1548 | margin-top: 1.5rem !important;
1549 | }
1550 | .mr-xl-4 {
1551 | margin-right: 1.5rem !important;
1552 | }
1553 | .mb-xl-4 {
1554 | margin-bottom: 1.5rem !important;
1555 | }
1556 | .ml-xl-4 {
1557 | margin-left: 1.5rem !important;
1558 | }
1559 | .mx-xl-4 {
1560 | margin-right: 1.5rem !important;
1561 | margin-left: 1.5rem !important;
1562 | }
1563 | .my-xl-4 {
1564 | margin-top: 1.5rem !important;
1565 | margin-bottom: 1.5rem !important;
1566 | }
1567 | .m-xl-5 {
1568 | margin: 3rem 3rem !important;
1569 | }
1570 | .mt-xl-5 {
1571 | margin-top: 3rem !important;
1572 | }
1573 | .mr-xl-5 {
1574 | margin-right: 3rem !important;
1575 | }
1576 | .mb-xl-5 {
1577 | margin-bottom: 3rem !important;
1578 | }
1579 | .ml-xl-5 {
1580 | margin-left: 3rem !important;
1581 | }
1582 | .mx-xl-5 {
1583 | margin-right: 3rem !important;
1584 | margin-left: 3rem !important;
1585 | }
1586 | .my-xl-5 {
1587 | margin-top: 3rem !important;
1588 | margin-bottom: 3rem !important;
1589 | }
1590 | .p-xl-0 {
1591 | padding: 0 0 !important;
1592 | }
1593 | .pt-xl-0 {
1594 | padding-top: 0 !important;
1595 | }
1596 | .pr-xl-0 {
1597 | padding-right: 0 !important;
1598 | }
1599 | .pb-xl-0 {
1600 | padding-bottom: 0 !important;
1601 | }
1602 | .pl-xl-0 {
1603 | padding-left: 0 !important;
1604 | }
1605 | .px-xl-0 {
1606 | padding-right: 0 !important;
1607 | padding-left: 0 !important;
1608 | }
1609 | .py-xl-0 {
1610 | padding-top: 0 !important;
1611 | padding-bottom: 0 !important;
1612 | }
1613 | .p-xl-1 {
1614 | padding: 0.25rem 0.25rem !important;
1615 | }
1616 | .pt-xl-1 {
1617 | padding-top: 0.25rem !important;
1618 | }
1619 | .pr-xl-1 {
1620 | padding-right: 0.25rem !important;
1621 | }
1622 | .pb-xl-1 {
1623 | padding-bottom: 0.25rem !important;
1624 | }
1625 | .pl-xl-1 {
1626 | padding-left: 0.25rem !important;
1627 | }
1628 | .px-xl-1 {
1629 | padding-right: 0.25rem !important;
1630 | padding-left: 0.25rem !important;
1631 | }
1632 | .py-xl-1 {
1633 | padding-top: 0.25rem !important;
1634 | padding-bottom: 0.25rem !important;
1635 | }
1636 | .p-xl-2 {
1637 | padding: 0.5rem 0.5rem !important;
1638 | }
1639 | .pt-xl-2 {
1640 | padding-top: 0.5rem !important;
1641 | }
1642 | .pr-xl-2 {
1643 | padding-right: 0.5rem !important;
1644 | }
1645 | .pb-xl-2 {
1646 | padding-bottom: 0.5rem !important;
1647 | }
1648 | .pl-xl-2 {
1649 | padding-left: 0.5rem !important;
1650 | }
1651 | .px-xl-2 {
1652 | padding-right: 0.5rem !important;
1653 | padding-left: 0.5rem !important;
1654 | }
1655 | .py-xl-2 {
1656 | padding-top: 0.5rem !important;
1657 | padding-bottom: 0.5rem !important;
1658 | }
1659 | .p-xl-3 {
1660 | padding: 1rem 1rem !important;
1661 | }
1662 | .pt-xl-3 {
1663 | padding-top: 1rem !important;
1664 | }
1665 | .pr-xl-3 {
1666 | padding-right: 1rem !important;
1667 | }
1668 | .pb-xl-3 {
1669 | padding-bottom: 1rem !important;
1670 | }
1671 | .pl-xl-3 {
1672 | padding-left: 1rem !important;
1673 | }
1674 | .px-xl-3 {
1675 | padding-right: 1rem !important;
1676 | padding-left: 1rem !important;
1677 | }
1678 | .py-xl-3 {
1679 | padding-top: 1rem !important;
1680 | padding-bottom: 1rem !important;
1681 | }
1682 | .p-xl-4 {
1683 | padding: 1.5rem 1.5rem !important;
1684 | }
1685 | .pt-xl-4 {
1686 | padding-top: 1.5rem !important;
1687 | }
1688 | .pr-xl-4 {
1689 | padding-right: 1.5rem !important;
1690 | }
1691 | .pb-xl-4 {
1692 | padding-bottom: 1.5rem !important;
1693 | }
1694 | .pl-xl-4 {
1695 | padding-left: 1.5rem !important;
1696 | }
1697 | .px-xl-4 {
1698 | padding-right: 1.5rem !important;
1699 | padding-left: 1.5rem !important;
1700 | }
1701 | .py-xl-4 {
1702 | padding-top: 1.5rem !important;
1703 | padding-bottom: 1.5rem !important;
1704 | }
1705 | .p-xl-5 {
1706 | padding: 3rem 3rem !important;
1707 | }
1708 | .pt-xl-5 {
1709 | padding-top: 3rem !important;
1710 | }
1711 | .pr-xl-5 {
1712 | padding-right: 3rem !important;
1713 | }
1714 | .pb-xl-5 {
1715 | padding-bottom: 3rem !important;
1716 | }
1717 | .pl-xl-5 {
1718 | padding-left: 3rem !important;
1719 | }
1720 | .px-xl-5 {
1721 | padding-right: 3rem !important;
1722 | padding-left: 3rem !important;
1723 | }
1724 | .py-xl-5 {
1725 | padding-top: 3rem !important;
1726 | padding-bottom: 3rem !important;
1727 | }
1728 | .m-xl-auto {
1729 | margin: auto !important;
1730 | }
1731 | .mt-xl-auto {
1732 | margin-top: auto !important;
1733 | }
1734 | .mr-xl-auto {
1735 | margin-right: auto !important;
1736 | }
1737 | .mb-xl-auto {
1738 | margin-bottom: auto !important;
1739 | }
1740 | .ml-xl-auto {
1741 | margin-left: auto !important;
1742 | }
1743 | .mx-xl-auto {
1744 | margin-right: auto !important;
1745 | margin-left: auto !important;
1746 | }
1747 | .my-xl-auto {
1748 | margin-top: auto !important;
1749 | margin-bottom: auto !important;
1750 | }
1751 | }
1752 |
1753 | .invisible {
1754 | visibility: hidden !important;
1755 | }
1756 |
1757 | .hidden-xs-up {
1758 | display: none !important;
1759 | }
1760 |
1761 | @media (max-width: 575px) {
1762 | .hidden-xs-down {
1763 | display: none !important;
1764 | }
1765 | }
1766 |
1767 | @media (min-width: 576px) {
1768 | .hidden-sm-up {
1769 | display: none !important;
1770 | }
1771 | }
1772 |
1773 | @media (max-width: 767px) {
1774 | .hidden-sm-down {
1775 | display: none !important;
1776 | }
1777 | }
1778 |
1779 | @media (min-width: 768px) {
1780 | .hidden-md-up {
1781 | display: none !important;
1782 | }
1783 | }
1784 |
1785 | @media (max-width: 991px) {
1786 | .hidden-md-down {
1787 | display: none !important;
1788 | }
1789 | }
1790 |
1791 | @media (min-width: 992px) {
1792 | .hidden-lg-up {
1793 | display: none !important;
1794 | }
1795 | }
1796 |
1797 | @media (max-width: 1199px) {
1798 | .hidden-lg-down {
1799 | display: none !important;
1800 | }
1801 | }
1802 |
1803 | @media (min-width: 1200px) {
1804 | .hidden-xl-up {
1805 | display: none !important;
1806 | }
1807 | }
1808 |
1809 | .hidden-xl-down {
1810 | display: none !important;
1811 | }
1812 |
1813 | .visible-print-block {
1814 | display: none !important;
1815 | }
1816 |
1817 | @media print {
1818 | .visible-print-block {
1819 | display: block !important;
1820 | }
1821 | }
1822 |
1823 | .visible-print-inline {
1824 | display: none !important;
1825 | }
1826 |
1827 | @media print {
1828 | .visible-print-inline {
1829 | display: inline !important;
1830 | }
1831 | }
1832 |
1833 | .visible-print-inline-block {
1834 | display: none !important;
1835 | }
1836 |
1837 | @media print {
1838 | .visible-print-inline-block {
1839 | display: inline-block !important;
1840 | }
1841 | }
1842 |
1843 | @media print {
1844 | .hidden-print {
1845 | display: none !important;
1846 | }
1847 | }
1848 |
--------------------------------------------------------------------------------