81 changed files with 4262 additions and 1084 deletions
@ -1,363 +0,0 @@ |
|||
<div class="fixed flex items-center justify-center right-0 w-10 h-10 shadow-lg rounded-l-lg z-90 cursor-pointer bg-red-600 bg-opacity-90 print:hidden" [class.lg:right-0]="config.layout === 'centered' || config.layout === 'material'" [class.lg:right-16]="config.layout !== 'centered' && config.layout !== 'material'" |
|||
style="top: 275px" (click)="settingsDrawer.toggle()"> |
|||
<mat-icon class="icon-size-5 text-white animate-spin-slow" [svgIcon]="'heroicons_solid:cog'"></mat-icon> |
|||
</div> |
|||
|
|||
<teso-drawer class="w-screen min-w-screen sm:w-100 sm:min-w-100 z-999" fixed [mode]="'over'" [name]="'settingsDrawer'" [position]="'right'" #settingsDrawer> |
|||
|
|||
<div class="flex flex-col w-full overflow-auto bg-card"> |
|||
<div class="flex flex-row items-center px-6 h-20 min-h-20 text-white bg-primary"> |
|||
<mat-icon class="icon-size-7 text-current" [svgIcon]="'heroicons_solid:cog'"></mat-icon> |
|||
<div class="ml-3 text-2xl font-semibold tracking-tight">Settings</div> |
|||
<button class="ml-auto" mat-icon-button (click)="settingsDrawer.close()"> |
|||
<mat-icon |
|||
class="text-current" |
|||
[svgIcon]="'heroicons_outline:x'"></mat-icon> |
|||
</button> |
|||
</div> |
|||
|
|||
<div class="flex flex-col p-6"> |
|||
|
|||
<!-- Theme --> |
|||
<div class="text-md font-semibold text-secondary">THEME</div> |
|||
<div class="grid grid-cols-2 sm:grid-cols-3 gap-3 mt-6"> |
|||
<ng-container *ngFor="let theme of themes"> |
|||
<div class="flex items-center justify-center px-4 py-3 rounded-full cursor-pointer ring-inset ring-primary bg-hover" [class.ring-2]="config.theme === theme[0]" (click)="setTheme(theme[0])"> |
|||
<div class="flex-0 w-3 h-3 rounded-full" [style.background-color]="theme[1].primary"></div> |
|||
<div class="ml-2.5 font-medium leading-5 truncate" [class.text-secondary]="config.theme !== theme[0]"> |
|||
{{theme[0] | titlecase}} |
|||
</div> |
|||
</div> |
|||
</ng-container> |
|||
</div> |
|||
|
|||
<hr class="my-8"> |
|||
|
|||
<!-- Scheme --> |
|||
<div class="text-md font-semibold text-secondary">SCHEME</div> |
|||
<div class="grid grid-cols-3 gap-3 justify-items-start mt-6"> |
|||
<!-- Auto --> |
|||
<div class="flex items-center py-3 pl-5 pr-6 rounded-full cursor-pointer ring-inset ring-primary bg-hover" [class.ring-2]="config.scheme === 'auto'" matTooltip="Automatically sets the scheme based on user's operating system's color scheme preference using 'prefer-color-scheme' media query." |
|||
(click)="setScheme('auto')"> |
|||
<div class="flex items-center rounded-full overflow-hidden"> |
|||
<mat-icon class="icon-size-5" [svgIcon]="'heroicons_solid:lightning-bolt'"></mat-icon> |
|||
</div> |
|||
<div class="flex items-center ml-2 font-medium leading-5" [class.text-secondary]="config.scheme !== 'auto'"> |
|||
Auto |
|||
</div> |
|||
</div> |
|||
<!-- Dark --> |
|||
<div class="flex items-center py-3 pl-5 pr-6 rounded-full cursor-pointer ring-inset ring-primary bg-hover" [class.ring-2]="config.scheme === 'dark'" (click)="setScheme('dark')"> |
|||
<div class="flex items-center rounded-full overflow-hidden"> |
|||
<mat-icon class="icon-size-5" [svgIcon]="'heroicons_solid:moon'"></mat-icon> |
|||
</div> |
|||
<div class="flex items-center ml-2 font-medium leading-5" [class.text-secondary]="config.scheme !== 'dark'"> |
|||
Dark |
|||
</div> |
|||
</div> |
|||
<!-- Light --> |
|||
<div class="flex items-center py-3 pl-5 pr-6 rounded-full cursor-pointer ring-inset ring-primary bg-hover" [class.ring-2]="config.scheme === 'light'" (click)="setScheme('light')"> |
|||
<div class="flex items-center rounded-full overflow-hidden"> |
|||
<mat-icon class="icon-size-5" [svgIcon]="'heroicons_solid:sun'"></mat-icon> |
|||
</div> |
|||
<div class="flex items-center ml-2 font-medium leading-5" [class.text-secondary]="config.scheme !== 'light'"> |
|||
Light |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<hr class="my-8"> |
|||
|
|||
<!-- Layout --> |
|||
<div class="text-md font-semibold text-secondary">LAYOUT</div> |
|||
<div class="grid grid-cols-3 gap-3 mt-6"> |
|||
|
|||
<!-- Empty --> |
|||
<div class="flex flex-col cursor-pointer" (click)="setLayout('empty')"> |
|||
<div class="flex flex-col h-20 rounded-md overflow-hidden border-2 hover:opacity-80" [class.border-primary]="config.layout === 'empty'"> |
|||
<div class="flex flex-col flex-auto bg-gray-50 dark:bg-gray-900"></div> |
|||
</div> |
|||
<div class="mt-2 text-md font-medium text-center text-secondary" [class.text-primary]="config.layout === 'empty'"> |
|||
Empty |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Classic --> |
|||
<div class="flex flex-col cursor-pointer" (click)="setLayout('classic')"> |
|||
<div class="flex h-20 rounded-md overflow-hidden border-2 hover:opacity-80" [class.border-primary]="config.layout === 'classic'"> |
|||
<div class="w-8 bg-gray-100 dark:bg-gray-800"> |
|||
<div class="mt-3 mx-1.5 space-y-1"> |
|||
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div> |
|||
</div> |
|||
</div> |
|||
<div class="flex flex-col flex-auto border-l"> |
|||
<div class="h-3 bg-gray-100 dark:bg-gray-800"> |
|||
<div class="flex items-center justify-end h-full mr-1.5"> |
|||
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
</div> |
|||
</div> |
|||
<div class="flex flex-auto border-t bg-gray-50 dark:bg-gray-900"></div> |
|||
</div> |
|||
</div> |
|||
<div class="mt-2 text-md font-medium text-center text-secondary" [class.text-primary]="config.layout === 'classic'"> |
|||
Classic |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Classy --> |
|||
<div class="flex flex-col cursor-pointer" (click)="setLayout('classy')"> |
|||
<div class="flex h-20 rounded-md overflow-hidden border-2 hover:opacity-80" [class.border-primary]="config.layout === 'classy'"> |
|||
<div class="w-8 bg-gray-100 dark:bg-gray-800"> |
|||
<div class="flex items-center mt-1 mx-1"> |
|||
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-1 h-1 ml-auto rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-1 h-1 ml-0.5 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
</div> |
|||
<div class="w-4 h-4 mt-2.5 mx-auto rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="mt-2 mx-1 space-y-1"> |
|||
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div> |
|||
</div> |
|||
</div> |
|||
<div class="flex flex-col flex-auto border-l"> |
|||
<div class="h-3 bg-gray-100 dark:bg-gray-800"> |
|||
<div class="flex items-center justify-end h-full mr-2"> |
|||
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
</div> |
|||
</div> |
|||
<div class="flex flex-auto border-t bg-gray-50 dark:bg-gray-900"></div> |
|||
</div> |
|||
</div> |
|||
<div class="mt-2 text-md font-medium text-center text-secondary" [class.text-primary]="config.layout === 'classy'"> |
|||
Classy |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Compact --> |
|||
<div class="flex flex-col cursor-pointer" (click)="setLayout('compact')"> |
|||
<div class="flex h-20 rounded-md overflow-hidden border-2 hover:opacity-80" [class.border-primary]="config.layout === 'compact'"> |
|||
<div class="w-5 bg-gray-100 dark:bg-gray-800"> |
|||
<div class="w-3 h-3 mt-2 mx-auto rounded-sm bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="flex flex-col items-center w-full mt-2 space-y-1"> |
|||
<div class="w-3 h-2.5 rounded-sm bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-3 h-2.5 rounded-sm bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-3 h-2.5 rounded-sm bg-gray-300 dark:bg-gray-700"></div> |
|||
</div> |
|||
</div> |
|||
<div class="flex flex-col flex-auto border-l"> |
|||
<div class="h-3 bg-gray-100 dark:bg-gray-800"> |
|||
<div class="flex items-center justify-end h-full mr-1.5"> |
|||
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
</div> |
|||
</div> |
|||
<div class="flex flex-auto border-t bg-gray-50 dark:bg-gray-900"></div> |
|||
</div> |
|||
</div> |
|||
<div class="mt-2 text-md font-medium text-center text-secondary" [class.text-primary]="config.layout === 'compact'"> |
|||
Compact |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Dense --> |
|||
<div class="flex flex-col cursor-pointer" (click)="setLayout('dense')"> |
|||
<div class="flex h-20 rounded-md overflow-hidden border-2 hover:opacity-80" [class.border-primary]="config.layout === 'dense'"> |
|||
<div class="w-4 bg-gray-100 dark:bg-gray-800"> |
|||
<div class="w-2 h-2 mt-2 mx-auto rounded-sm bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="flex flex-col items-center w-full mt-2 space-y-1"> |
|||
<div class="w-2 h-2 rounded-sm bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-2 h-2 rounded-sm bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-2 h-2 rounded-sm bg-gray-300 dark:bg-gray-700"></div> |
|||
</div> |
|||
</div> |
|||
<div class="flex flex-col flex-auto border-l"> |
|||
<div class="h-3 bg-gray-100 dark:bg-gray-800"> |
|||
<div class="flex items-center justify-end h-full mr-1.5"> |
|||
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
</div> |
|||
</div> |
|||
<div class="flex flex-auto border-t bg-gray-50 dark:bg-gray-900"></div> |
|||
</div> |
|||
</div> |
|||
<div class="mt-2 text-md font-medium text-center text-secondary" [class.text-primary]="config.layout === 'dense'"> |
|||
Dense |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Futuristic --> |
|||
<div class="flex flex-col cursor-pointer" (click)="setLayout('futuristic')"> |
|||
<div class="flex h-20 rounded-md overflow-hidden border-2 hover:opacity-80" [class.border-primary]="config.layout === 'futuristic'"> |
|||
<div class="w-8 bg-gray-100 dark:bg-gray-800"> |
|||
<div class="flex flex-col flex-auto h-full py-3 px-1.5 space-y-1"> |
|||
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="flex-auto"></div> |
|||
<div class="h-1 rounded-sm bg-gray-300 dark:bg-gray-700"></div> |
|||
</div> |
|||
</div> |
|||
<div class="flex flex-col flex-auto border-l"> |
|||
<div class="h-3 bg-gray-100 dark:bg-gray-800"> |
|||
<div class="flex items-center justify-end h-full mr-1.5"> |
|||
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
</div> |
|||
</div> |
|||
<div class="flex flex-auto border-t bg-gray-50 dark:bg-gray-900"></div> |
|||
</div> |
|||
</div> |
|||
<div class="mt-2 text-md font-medium text-center text-secondary" [class.text-primary]="config.layout === 'futuristic'"> |
|||
Futuristic |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Thin --> |
|||
<div class="flex flex-col cursor-pointer" (click)="setLayout('thin')"> |
|||
<div class="flex h-20 rounded-md overflow-hidden border-2 hover:opacity-80" [class.border-primary]="config.layout === 'thin'"> |
|||
<div class="w-3 bg-gray-100 dark:bg-gray-800"> |
|||
<div class="w-1.5 h-1.5 mt-2 mx-auto rounded-sm bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="flex flex-col items-center w-full mt-2 space-y-1"> |
|||
<div class="w-1.5 h-1.5 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-1.5 h-1.5 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-1.5 h-1.5 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-1.5 h-1.5 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-1.5 h-1.5 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
</div> |
|||
</div> |
|||
<div class="flex flex-col flex-auto border-l"> |
|||
<div class="h-3 bg-gray-100 dark:bg-gray-800"> |
|||
<div class="flex items-center justify-end h-full mr-1.5"> |
|||
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
</div> |
|||
</div> |
|||
<div class="flex flex-auto border-t bg-gray-50 dark:bg-gray-900"></div> |
|||
</div> |
|||
</div> |
|||
<div class="mt-2 text-md font-medium text-center text-secondary" [class.text-primary]="config.layout === 'thin'"> |
|||
Thin |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="col-span-2"></div> |
|||
|
|||
<!-- Centered --> |
|||
<div class="flex flex-col cursor-pointer" (click)="setLayout('centered')"> |
|||
<div class="flex h-20 rounded-md overflow-hidden border-2 hover:opacity-80" [class.border-primary]="config.layout === 'centered'"> |
|||
<div class="flex flex-col flex-auto my-1 mx-2 border rounded-md overflow-hidden"> |
|||
<div class="flex items-center h-3 bg-gray-100 dark:bg-gray-800"> |
|||
<div class="flex ml-1.5"> |
|||
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-3 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-3 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-3 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
</div> |
|||
<div class="flex items-center justify-end ml-auto mr-1.5"> |
|||
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-1 h-1 ml-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
</div> |
|||
</div> |
|||
<div class="flex flex-auto border-t bg-gray-50 dark:bg-gray-900"></div> |
|||
</div> |
|||
</div> |
|||
<div class="mt-2 text-md font-medium text-center text-secondary" [class.text-primary]="config.layout === 'centered'"> |
|||
Centered |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Enterprise --> |
|||
<div class="flex flex-col cursor-pointer" (click)="setLayout('enterprise')"> |
|||
<div class="flex flex-col h-20 rounded-md overflow-hidden border-2 hover:opacity-80" [class.border-primary]="config.layout === 'enterprise'"> |
|||
<div class="flex items-center h-3 px-2 bg-gray-100 dark:bg-gray-800"> |
|||
<div class="w-2 h-2 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="flex items-center justify-end ml-auto space-x-1"> |
|||
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
</div> |
|||
</div> |
|||
<div class="flex items-center h-3 px-2 border-t border-b space-x-1 bg-gray-100 dark:bg-gray-800"> |
|||
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
</div> |
|||
<div class="flex flex-col flex-auto my-1 mx-2 border rounded overflow-hidden"> |
|||
<div class="flex flex-auto bg-gray-50 dark:bg-gray-900"></div> |
|||
</div> |
|||
</div> |
|||
<div class="mt-2 text-md font-medium text-center text-secondary" [class.text-primary]="config.layout === 'enterprise'"> |
|||
Enterprise |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Material --> |
|||
<div class="flex flex-col cursor-pointer" (click)="setLayout('material')"> |
|||
<div class="flex flex-col h-20 rounded-md overflow-hidden border-2 hover:opacity-80" [class.border-primary]="config.layout === 'material'"> |
|||
<div class="flex flex-col flex-auto my-1 mx-2 border rounded overflow-hidden"> |
|||
<div class="flex items-center h-4 px-2 bg-gray-100 dark:bg-gray-800"> |
|||
<div class="w-2 h-2 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="flex items-center justify-end ml-auto space-x-1"> |
|||
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
</div> |
|||
</div> |
|||
<div class="flex items-center h-2 px-2 space-x-1 bg-gray-100 dark:bg-gray-800"> |
|||
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
</div> |
|||
<div class="flex flex-auto border-t bg-gray-50 dark:bg-gray-900"></div> |
|||
</div> |
|||
</div> |
|||
<div class="mt-2 text-md font-medium text-center text-secondary" [class.text-primary]="config.layout === 'material'"> |
|||
Material |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Modern --> |
|||
<div class="flex flex-col cursor-pointer" (click)="setLayout('modern')"> |
|||
<div class="flex flex-col h-20 rounded-md overflow-hidden border-2 hover:opacity-80" [class.border-primary]="config.layout === 'modern'"> |
|||
<div class="flex items-center h-4 px-2 border-b bg-gray-100 dark:bg-gray-800"> |
|||
<div class="w-2 h-2 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="flex items-center h-3 ml-2 space-x-1"> |
|||
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-3 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
</div> |
|||
<div class="flex items-center justify-end ml-auto space-x-1"> |
|||
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
<div class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-700"></div> |
|||
</div> |
|||
</div> |
|||
<div class="flex flex-col flex-auto"> |
|||
<div class="flex flex-auto bg-gray-50 dark:bg-gray-900"></div> |
|||
</div> |
|||
</div> |
|||
<div class="mt-2 text-md font-medium text-center text-secondary" [class.text-primary]="config.layout === 'modern'"> |
|||
Modern |
|||
</div> |
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</teso-drawer> |
@ -1,124 +0,0 @@ |
|||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core'; |
|||
import { Router } from '@angular/router'; |
|||
import { Subject } from 'rxjs'; |
|||
import { takeUntil } from 'rxjs/operators'; |
|||
import { tesoConfigService } from '@teso/services/config'; |
|||
import { tesoTailwindService } from '@teso/services/tailwind'; |
|||
import { AppConfig, Scheme, Theme } from 'app/core/config/app.config'; |
|||
import { Layout } from 'app/layout/layout.types'; |
|||
|
|||
@Component({ |
|||
selector : 'settings', |
|||
templateUrl : './settings.component.html', |
|||
styles : [ |
|||
` |
|||
settings { |
|||
position: static; |
|||
display: block; |
|||
flex: none; |
|||
width: auto; |
|||
} |
|||
` |
|||
], |
|||
encapsulation: ViewEncapsulation.None |
|||
}) |
|||
export class SettingsComponent implements OnInit, OnDestroy |
|||
{ |
|||
config: AppConfig; |
|||
layout: Layout; |
|||
scheme: 'dark' | 'light'; |
|||
theme: string; |
|||
themes: [string, any][] = []; |
|||
private _unsubscribeAll: Subject<any> = new Subject<any>(); |
|||
|
|||
/** |
|||
* Constructor |
|||
*/ |
|||
constructor( |
|||
private _router: Router, |
|||
private _tesoConfigService: tesoConfigService, |
|||
private _tesoTailwindService: tesoTailwindService |
|||
) |
|||
{ |
|||
} |
|||
|
|||
// -----------------------------------------------------------------------------------------------------
|
|||
// @ Lifecycle hooks
|
|||
// -----------------------------------------------------------------------------------------------------
|
|||
|
|||
/** |
|||
* On init |
|||
*/ |
|||
ngOnInit(): void |
|||
{ |
|||
// Get the themes
|
|||
this._tesoTailwindService.tailwindConfig$ |
|||
.pipe(takeUntil(this._unsubscribeAll)) |
|||
.subscribe((config) => { |
|||
this.themes = Object.entries(config.themes); |
|||
}); |
|||
|
|||
// Subscribe to config changes
|
|||
this._tesoConfigService.config$ |
|||
.pipe(takeUntil(this._unsubscribeAll)) |
|||
.subscribe((config: AppConfig) => { |
|||
|
|||
// Store the config
|
|||
this.config = config; |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* On destroy |
|||
*/ |
|||
ngOnDestroy(): void |
|||
{ |
|||
// Unsubscribe from all subscriptions
|
|||
this._unsubscribeAll.next(); |
|||
this._unsubscribeAll.complete(); |
|||
} |
|||
|
|||
// -----------------------------------------------------------------------------------------------------
|
|||
// @ Public methods
|
|||
// -----------------------------------------------------------------------------------------------------
|
|||
|
|||
/** |
|||
* Set the layout on the config |
|||
* |
|||
* @param layout |
|||
*/ |
|||
setLayout(layout: string): void |
|||
{ |
|||
// Clear the 'layout' query param to allow layout changes
|
|||
this._router.navigate([], { |
|||
queryParams : { |
|||
layout: null |
|||
}, |
|||
queryParamsHandling: 'merge' |
|||
}).then(() => { |
|||
|
|||
// Set the config
|
|||
this._tesoConfigService.config = {layout}; |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* Set the scheme on the config |
|||
* |
|||
* @param scheme |
|||
*/ |
|||
setScheme(scheme: Scheme): void |
|||
{ |
|||
this._tesoConfigService.config = {scheme}; |
|||
} |
|||
|
|||
/** |
|||
* Set the theme on the config |
|||
* |
|||
* @param theme |
|||
*/ |
|||
setTheme(theme: Theme): void |
|||
{ |
|||
this._tesoConfigService.config = {theme}; |
|||
} |
|||
} |
@ -1,28 +0,0 @@ |
|||
import { NgModule } from '@angular/core'; |
|||
import { CommonModule } from '@angular/common'; |
|||
import { RouterModule } from '@angular/router'; |
|||
import { MatIconModule } from '@angular/material/icon'; |
|||
import { MatTooltipModule } from '@angular/material/tooltip'; |
|||
import { tesoDrawerModule } from '@teso/components/drawer'; |
|||
import { SettingsComponent } from 'app/layout/common/settings/settings.component'; |
|||
import { MatButtonModule } from '@angular/material/button'; |
|||
|
|||
@NgModule({ |
|||
declarations: [ |
|||
SettingsComponent |
|||
], |
|||
imports: [ |
|||
CommonModule, |
|||
RouterModule, |
|||
MatIconModule, |
|||
MatTooltipModule, |
|||
tesoDrawerModule, |
|||
MatButtonModule |
|||
], |
|||
exports : [ |
|||
SettingsComponent |
|||
] |
|||
}) |
|||
export class SettingsModule |
|||
{ |
|||
} |
@ -0,0 +1,5 @@ |
|||
export interface ProductUpload { |
|||
highlight: boolean; |
|||
file: File; |
|||
imageSRC:string; |
|||
} |
@ -1 +0,0 @@ |
|||
<p>adverts works!</p> |
@ -1,15 +0,0 @@ |
|||
import { Component, OnInit } from '@angular/core'; |
|||
|
|||
@Component({ |
|||
selector: 'app-adverts', |
|||
templateUrl: './adverts.component.html', |
|||
styleUrls: ['./adverts.component.scss'] |
|||
}) |
|||
export class AdvertsComponent implements OnInit { |
|||
|
|||
constructor() { } |
|||
|
|||
ngOnInit(): void { |
|||
} |
|||
|
|||
} |
@ -1,12 +0,0 @@ |
|||
import { NgModule } from '@angular/core'; |
|||
import { CommonModule } from '@angular/common'; |
|||
|
|||
|
|||
|
|||
@NgModule({ |
|||
declarations: [], |
|||
imports: [ |
|||
CommonModule |
|||
] |
|||
}) |
|||
export class AdvertsModule { } |
@ -1 +0,0 @@ |
|||
<p>campaigns works!</p> |
@ -1,15 +0,0 @@ |
|||
import { Component, OnInit } from '@angular/core'; |
|||
|
|||
@Component({ |
|||
selector: 'app-campaigns', |
|||
templateUrl: './campaigns.component.html', |
|||
styleUrls: ['./campaigns.component.scss'] |
|||
}) |
|||
export class CampaignsComponent implements OnInit { |
|||
|
|||
constructor() { } |
|||
|
|||
ngOnInit(): void { |
|||
} |
|||
|
|||
} |
@ -1,12 +0,0 @@ |
|||
import { NgModule } from '@angular/core'; |
|||
import { CommonModule } from '@angular/common'; |
|||
|
|||
|
|||
|
|||
@NgModule({ |
|||
declarations: [], |
|||
imports: [ |
|||
CommonModule |
|||
] |
|||
}) |
|||
export class CampaignsModule { } |
@ -0,0 +1,115 @@ |
|||
<div class="xl:col-span-2 flex flex-col flex-auto bg-card shadow rounded-2xl overflow-hidden"> |
|||
<div class="overflow-x-auto mx-6 py-10"> |
|||
<table class="w-full bg-transparent" mat-table matSort [dataSource]="couponsDataSource" [trackBy]="trackByFn" |
|||
#couponsTable> |
|||
<!-- Transaction ID --> |
|||
<ng-container matColumnDef="product"> |
|||
<th mat-header-cell mat-sort-header *matHeaderCellDef> |
|||
Product |
|||
</th> |
|||
<td mat-cell *matCellDef="let transaction"> |
|||
<span class="pr-6 whitespace-wrap"> |
|||
{{transaction.name}} |
|||
</span> |
|||
</td> |
|||
</ng-container> |
|||
|
|||
<!-- Request Name --> |
|||
<ng-container matColumnDef="quantity"> |
|||
<th mat-header-cell mat-sort-header *matHeaderCellDef> |
|||
Quantity Left |
|||
</th> |
|||
<td mat-cell *matCellDef="let transaction"> |
|||
<span class="pr-6 whitespace-wrap" style="display: flex;justify-content: center;"> |
|||
{{transaction.quantity}} |
|||
</span> |
|||
</td> |
|||
</ng-container> |
|||
<ng-container matColumnDef="type"> |
|||
<th mat-header-cell mat-sort-header *matHeaderCellDef> |
|||
Coupon Type |
|||
</th> |
|||
<td mat-cell *matCellDef="let transaction"> |
|||
<span class="pr-6 whitespace-wrap"> |
|||
{{transaction.type}} |
|||
</span> |
|||
</td> |
|||
</ng-container> |
|||
<ng-container matColumnDef="condition"> |
|||
<th mat-header-cell mat-sort-header *matHeaderCellDef> |
|||
Condition |
|||
</th> |
|||
<td mat-cell *matCellDef="let transaction"> |
|||
<span class="pr-6 whitespace-wrap"> |
|||
{{transaction.condition}} |
|||
</span> |
|||
</td> |
|||
</ng-container> |
|||
|
|||
<ng-container matColumnDef="range"> |
|||
<th mat-header-cell mat-sort-header *matHeaderCellDef> |
|||
Range |
|||
</th> |
|||
<td mat-cell *matCellDef="let transaction"> |
|||
<span class="pr-6 whitespace-wrap" style="display: flex;justify-content: center;font-weight: bold;"> |
|||
{{transaction.range}} |
|||
</span> |
|||
</td> |
|||
</ng-container> |
|||
<ng-container matColumnDef="claimed"> |
|||
<th mat-header-cell mat-sort-header *matHeaderCellDef> |
|||
Number Claimed |
|||
</th> |
|||
<td mat-cell *matCellDef="let transaction"> |
|||
<span class="pr-6 whitespace-wrap" style="display: flex;justify-content: center;"> |
|||
{{transaction.claimed}} |
|||
</span> |
|||
</td> |
|||
</ng-container> |
|||
<ng-container matColumnDef="status"> |
|||
<th mat-header-cell mat-sort-header *matHeaderCellDef> |
|||
Status |
|||
</th> |
|||
<td mat-cell *matCellDef="let transaction"> |
|||
<span class="pr-6 whitespace-wrap"> |
|||
Active |
|||
</span> |
|||
</td> |
|||
</ng-container> |
|||
<ng-container matColumnDef="expiration"> |
|||
<th mat-header-cell mat-sort-header *matHeaderCellDef> |
|||
Expiration |
|||
</th> |
|||
<td mat-cell *matCellDef="let transaction"> |
|||
<span class="pr-6 whitespace-wrap"> |
|||
{{transaction.expiration | date}} |
|||
</span> |
|||
</td> |
|||
</ng-container> |
|||
<!-- Amount --> |
|||
<ng-container matColumnDef="actions"> |
|||
<th mat-header-cell mat-sort-header *matHeaderCellDef> |
|||
Actions |
|||
</th> |
|||
<td mat-cell *matCellDef="let transaction"> |
|||
<div style="display: flex;"> |
|||
<button class=" sm:inline-flex" mat-flat-button style="background-color: #96260a;color:white;">Cancel |
|||
</button> |
|||
|
|||
</div> |
|||
</td> |
|||
</ng-container> |
|||
<!-- Footer --> |
|||
<ng-container matColumnDef="recentOrdersTableFooter"> |
|||
<td class="py-6 px-0 border-0" mat-footer-cell *matFooterCellDef colspan="6"> |
|||
<mat-paginator style="position:sticky;bottom: 0;width: 100%;" [pageSize]="20" |
|||
[pageSizeOptions]="[10, 20, 25,50, 100]" [showFirstLastButtons]="true"></mat-paginator> |
|||
</td> |
|||
</ng-container> |
|||
|
|||
<tr mat-header-row *matHeaderRowDef="couponsTableColumns"></tr> |
|||
<tr class="coupons-row h-14" mat-row *matRowDef="let row; columns: couponsTableColumns;"></tr> |
|||
<tr class="h-16 border-0" mat-footer-row *matFooterRowDef="['recentOrdersTableFooter']"></tr> |
|||
</table> |
|||
</div> |
|||
</div> |
@ -0,0 +1,6 @@ |
|||
.coupons-row{ |
|||
color: #003445 !important; |
|||
} |
|||
.pr-6 { |
|||
color: #003445; |
|||
} |
@ -1,20 +1,20 @@ |
|||
import { ComponentFixture, TestBed } from '@angular/core/testing'; |
|||
|
|||
import { CampaignsComponent } from './campaigns.component'; |
|||
import { ActiveCouponsComponent } from './active-coupons.component'; |
|||
|
|||
describe('CampaignsComponent', () => { |
|||
let component: CampaignsComponent; |
|||
let fixture: ComponentFixture<CampaignsComponent>; |
|||
describe('ActiveCouponsComponent', () => { |
|||
let component: ActiveCouponsComponent; |
|||
let fixture: ComponentFixture<ActiveCouponsComponent>; |
|||
|
|||
beforeEach(async () => { |
|||
await TestBed.configureTestingModule({ |
|||
declarations: [ CampaignsComponent ] |
|||
declarations: [ ActiveCouponsComponent ] |
|||
}) |
|||
.compileComponents(); |
|||
}); |
|||
|
|||
beforeEach(() => { |
|||
fixture = TestBed.createComponent(CampaignsComponent); |
|||
fixture = TestBed.createComponent(ActiveCouponsComponent); |
|||
component = fixture.componentInstance; |
|||
fixture.detectChanges(); |
|||
}); |
@ -0,0 +1,23 @@ |
|||
import { ChangeDetectionStrategy, Component, Input, OnInit, ViewChild } from '@angular/core'; |
|||
import { MatSort } from '@angular/material/sort'; |
|||
import { MatTableDataSource } from '@angular/material/table'; |
|||
|
|||
@Component({ |
|||
selector: 'activecoupons', |
|||
templateUrl: './active-coupons.component.html', |
|||
styleUrls: ['./active-coupons.component.scss'], |
|||
changeDetection: ChangeDetectionStrategy.OnPush, |
|||
exportAs: 'activecoupons' |
|||
}) |
|||
export class ActiveCouponsComponent implements OnInit { |
|||
@Input() couponsDataSource: MatTableDataSource<any>; |
|||
couponsTableColumns: string[] = ['product', 'quantity', 'type', 'condition', 'range', 'claimed', 'status', 'expiration', 'actions']; |
|||
@ViewChild('couponsTable', { read: MatSort }) couponsTableMatSort: MatSort; |
|||
constructor() { } |
|||
|
|||
ngOnInit(): void { |
|||
} |
|||
trackByFn(index: number, item: any): any { |
|||
return item.id || index; |
|||
} |
|||
} |
@ -0,0 +1,134 @@ |
|||
<div class="row" style="display: flex;justify-content:space-between"> |
|||
<div class="row" style="display: flex;justify-content:center;width: 100%;"> |
|||
<h2 mat-dialog-title style="text-align: center;">New Coupons </h2> |
|||
</div> |
|||
<!-- <button mat-button mat-dialog-close>Cancel</button> --> |
|||
<button mat-button [mat-dialog-close]="true" cdkFocusInitial>x</button> |
|||
</div> |
|||
<mat-dialog-content class="mat-typography"> |
|||
<div class=" py-2 pl-3 pr-3 sm:py-4 md:pl-4 md:pr-6"> |
|||
<div class="columns" style="display: flex;align-items: center"> |
|||
<div class="column" style="display: flex;align-items: baseline"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Target Business </strong> |
|||
</mat-label> |
|||
</div> |
|||
<div class="column"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
Target Name |
|||
</mat-label> |
|||
<button style="background-color: blue;color:white;margin-right:20px;" mat-button (click)="lookupBusiness()">Search</button> |
|||
</div> |
|||
</div> |
|||
<hr/> |
|||
<div class="columns" style="display: flex;align-items: center"> |
|||
<div class="column" style="display: flex;align-items: baseline"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Target Name </strong> |
|||
</mat-label> |
|||
</div> |
|||
<div class="column"> |
|||
<mat-form-field appearance="fill" style="min-width: 200px;"> |
|||
<mat-select required> |
|||
<mat-option value="low">Product 1</mat-option> |
|||
<mat-option value="standard">Product 2</mat-option> |
|||
<mat-option value="high">Product 3</mat-option> |
|||
<mat-option value="high">Product 4</mat-option> |
|||
</mat-select> |
|||
</mat-form-field> |
|||
</div> |
|||
</div> |
|||
<div class="columns" style="display: flex;align-items: center;margin-top: 15px;"> |
|||
<div class="column" style="display: flex;align-items: baseline"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Original Price </strong> |
|||
</mat-label> |
|||
</div> |
|||
<div class="column"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
GH¢200 |
|||
</mat-label> |
|||
</div> |
|||
</div> |
|||
<div class="columns" style="display: flex;align-items: center;margin-top: 15px;"> |
|||
<div class="column" style="display: flex;align-items: baseline"> |
|||
<mat-label style="margin-right: 20px;"> |
|||
<strong class="tileHead">Coupon Type</strong> |
|||
</mat-label> |
|||
</div> |
|||
<div class="column"> |
|||
<mat-form-field appearance="fill" style="min-width: 200px;"> |
|||
<mat-select required> |
|||
<mat-option value="low">Freebie</mat-option> |
|||
<mat-option value="standard">Discount</mat-option> |
|||
<mat-option value="high">Proximity Freebie</mat-option> |
|||
<mat-option value="high">Proximity Discount</mat-option> |
|||
</mat-select> |
|||
</mat-form-field> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="columns" style="display: flex;align-items: center"> |
|||
<div class="column"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Coupon Condition</strong> |
|||
</mat-label> |
|||
</div> |
|||
<div class="column"> |
|||
<textarea name="" id="" cols="30" rows="5" style="border: 1px solid #cbd5e1;"></textarea> |
|||
</div> |
|||
</div> |
|||
<div class="columns" style="display: flex;align-items: center"> |
|||
<div class="column" style="display: flex;align-items: baseline"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Number Of Coupons</strong> |
|||
</mat-label> |
|||
</div> |
|||
<div class="column"> |
|||
<mat-form-field appearance="fill" style="min-width: 200px;"> |
|||
<input matInput style="margin-left:10px;" type="number"> |
|||
</mat-form-field> |
|||
</div> |
|||
|
|||
</div> |
|||
<div style="display: flex;align-items: baseline"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Percentage Off </strong> |
|||
</mat-label> |
|||
<mat-form-field appearance="fill" style="margin-right:10px;"> |
|||
<span matPrefix>From </span> |
|||
<input matInput type="number"> |
|||
<span matSuffix>% </span> |
|||
</mat-form-field> |
|||
<mat-form-field appearance="fill" style="margin-left:10px;"> |
|||
<span matPrefix>To </span> |
|||
<input matInput type="number"> |
|||
<span matSuffix>% </span> |
|||
</mat-form-field> |
|||
</div> |
|||
<div style="display: flex;align-items: baseline"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Coupon Worth </strong> |
|||
</mat-label> |
|||
<mat-label> |
|||
From GH¢200 To GH¢800 |
|||
</mat-label> |
|||
</div> |
|||
<div style="display: flex;align-items: baseline;margin-top: 20px;"> |
|||
<mat-label style="margin-right: 30px;"> |
|||
<strong class="tileHead">Date Of Expiration </strong> |
|||
</mat-label> |
|||
<mat-form-field appearance="outline"> |
|||
<input matInput style="margin-left:10px;" type="date"> |
|||
</mat-form-field> |
|||
<mat-form-field appearance="fill" style="width: 200px;"> |
|||
<span matPrefix>Time </span> |
|||
<input matInput type="time"> |
|||
</mat-form-field> |
|||
</div> |
|||
<div class="row" style="display: flex;justify-content:space-around;width:100%;"> |
|||
<button style="background-color: blue;color:white;margin-right:20px;" mat-button>Generate Coupons</button> |
|||
|
|||
</div> |
|||
</div> |
|||
</mat-dialog-content> |
@ -0,0 +1,11 @@ |
|||
.columns { |
|||
display: flex; |
|||
flex-direction: row; |
|||
flex-wrap: wrap; |
|||
width: 100%; |
|||
} |
|||
|
|||
.column { |
|||
flex: 50%; |
|||
font-size: medium; |
|||
} |
@ -0,0 +1,25 @@ |
|||
import { ComponentFixture, TestBed } from '@angular/core/testing'; |
|||
|
|||
import { AdminNewCouponsComponent } from './admin-new-coupons.component'; |
|||
|
|||
describe('AdminNewCouponsComponent', () => { |
|||
let component: AdminNewCouponsComponent; |
|||
let fixture: ComponentFixture<AdminNewCouponsComponent>; |
|||
|
|||
beforeEach(async () => { |
|||
await TestBed.configureTestingModule({ |
|||
declarations: [ AdminNewCouponsComponent ] |
|||
}) |
|||
.compileComponents(); |
|||
}); |
|||
|
|||
beforeEach(() => { |
|||
fixture = TestBed.createComponent(AdminNewCouponsComponent); |
|||
component = fixture.componentInstance; |
|||
fixture.detectChanges(); |
|||
}); |
|||
|
|||
it('should create', () => { |
|||
expect(component).toBeTruthy(); |
|||
}); |
|||
}); |
@ -0,0 +1,22 @@ |
|||
import { Component, Inject, OnInit } from '@angular/core'; |
|||
import { MAT_DIALOG_DATA, MatDialog } from '@angular/material/dialog'; |
|||
import { BusinessLookUpComponent } from '../../Products/BusinessLookUp/business-look-up.component'; |
|||
|
|||
@Component({ |
|||
selector: 'app-admin-new-coupons', |
|||
templateUrl: './admin-new-coupons.component.html', |
|||
styleUrls: ['./admin-new-coupons.component.scss'] |
|||
}) |
|||
export class AdminNewCouponsComponent implements OnInit { |
|||
constructor(@Inject(MAT_DIALOG_DATA) public data: { product: any }, public dialog: MatDialog,) { } |
|||
|
|||
ngOnInit(): void { |
|||
} |
|||
lookupBusiness() { |
|||
const dialogRef = this.dialog.open(BusinessLookUpComponent, { |
|||
disableClose: true, |
|||
hasBackdrop: true, |
|||
|
|||
}); |
|||
} |
|||
} |
@ -0,0 +1,115 @@ |
|||
<div class="xl:col-span-2 flex flex-col flex-auto bg-card shadow rounded-2xl overflow-hidden"> |
|||
<div class="overflow-x-auto mx-6 py-10"> |
|||
<table class="w-full bg-transparent" mat-table matSort [dataSource]="couponsDataSource" [trackBy]="trackByFn" |
|||
#couponsTable> |
|||
<!-- Transaction ID --> |
|||
<ng-container matColumnDef="product"> |
|||
<th mat-header-cell mat-sort-header *matHeaderCellDef> |
|||
Product |
|||
</th> |
|||
<td mat-cell *matCellDef="let transaction"> |
|||
<span class="pr-6 whitespace-wrap"> |
|||
{{transaction.name}} |
|||
</span> |
|||
</td> |
|||
</ng-container> |
|||
|
|||
<!-- Request Name --> |
|||
<ng-container matColumnDef="quantity"> |
|||
<th mat-header-cell mat-sort-header *matHeaderCellDef> |
|||
Quantity Left |
|||
</th> |
|||
<td mat-cell *matCellDef="let transaction"> |
|||
<span class="pr-6 whitespace-wrap" style="display: flex;justify-content: center;"> |
|||
{{transaction.quantity}} |
|||
</span> |
|||
</td> |
|||
</ng-container> |
|||
<ng-container matColumnDef="type"> |
|||
<th mat-header-cell mat-sort-header *matHeaderCellDef> |
|||
Coupon Type |
|||
</th> |
|||
<td mat-cell *matCellDef="let transaction"> |
|||
<span class="pr-6 whitespace-wrap"> |
|||
{{transaction.type}} |
|||
</span> |
|||
</td> |
|||
</ng-container> |
|||
<ng-container matColumnDef="condition"> |
|||
<th mat-header-cell mat-sort-header *matHeaderCellDef> |
|||
Condition |
|||
</th> |
|||
<td mat-cell *matCellDef="let transaction"> |
|||
<span class="pr-6 whitespace-wrap"> |
|||
{{transaction.condition}} |
|||
</span> |
|||
</td> |
|||
</ng-container> |
|||
|
|||
<ng-container matColumnDef="range"> |
|||
<th mat-header-cell mat-sort-header *matHeaderCellDef> |
|||
Range |
|||
</th> |
|||
<td mat-cell *matCellDef="let transaction"> |
|||
<span class="pr-6 whitespace-wrap" style="display: flex;justify-content: center;font-weight: bold;"> |
|||
{{transaction.range}} |
|||
</span> |
|||
</td> |
|||
</ng-container> |
|||
<ng-container matColumnDef="claimed"> |
|||
<th mat-header-cell mat-sort-header *matHeaderCellDef> |
|||
Number Claimed |
|||
</th> |
|||
<td mat-cell *matCellDef="let transaction"> |
|||
<span class="pr-6 whitespace-wrap" style="display: flex;justify-content: center;"> |
|||
{{transaction.claimed}} |
|||
</span> |
|||
</td> |
|||
</ng-container> |
|||
<ng-container matColumnDef="status"> |
|||
<th mat-header-cell mat-sort-header *matHeaderCellDef> |
|||
Status |
|||
</th> |
|||
<td mat-cell *matCellDef="let transaction"> |
|||
<span class="pr-6 whitespace-wrap"> |
|||
Expired |
|||
</span> |
|||
</td> |
|||
</ng-container> |
|||
<ng-container matColumnDef="expiration"> |
|||
<th mat-header-cell mat-sort-header *matHeaderCellDef> |
|||
Expiration |
|||
</th> |
|||
<td mat-cell *matCellDef="let transaction"> |
|||
<span class="pr-6 whitespace-wrap"> |
|||
{{transaction.expiration | date}} |
|||
</span> |
|||
</td> |
|||
</ng-container> |
|||
<!-- Amount --> |
|||
<ng-container matColumnDef="actions"> |
|||
<th mat-header-cell mat-sort-header *matHeaderCellDef> |
|||
Actions |
|||
</th> |
|||
<td mat-cell *matCellDef="let transaction"> |
|||
<div style="display: flex;"> |
|||
<button class=" sm:inline-flex" mat-flat-button style="background-color: #0152cc;color: white;">Regenerate |
|||
</button> |
|||
|
|||
</div> |
|||
</td> |
|||
</ng-container> |
|||
<!-- Footer --> |
|||
<ng-container matColumnDef="recentOrdersTableFooter"> |
|||
<td class="py-6 px-0 border-0" mat-footer-cell *matFooterCellDef colspan="6"> |
|||
<mat-paginator style="position:sticky;bottom: 0;width: 100%;" [pageSize]="20" |
|||
[pageSizeOptions]="[10, 20, 25,50, 100]" [showFirstLastButtons]="true"></mat-paginator> |
|||
</td> |
|||
</ng-container> |
|||
|
|||
<tr mat-header-row *matHeaderRowDef="couponsTableColumns"></tr> |
|||
<tr class="coupons-row h-14" mat-row *matRowDef="let row; columns: couponsTableColumns;"></tr> |
|||
<tr class="h-16 border-0" mat-footer-row *matFooterRowDef="['recentOrdersTableFooter']"></tr> |
|||
</table> |
|||
</div> |
|||
</div> |
@ -0,0 +1,6 @@ |
|||
.coupons-row{ |
|||
color: #003445 !important; |
|||
} |
|||
.pr-6 { |
|||
color: #003445; |
|||
} |
@ -0,0 +1,25 @@ |
|||
import { ComponentFixture, TestBed } from '@angular/core/testing'; |
|||
|
|||
import { InactiveCouponsComponent } from './inactive-coupons.component'; |
|||
|
|||
describe('InactiveCouponsComponent', () => { |
|||
let component: InactiveCouponsComponent; |
|||
let fixture: ComponentFixture<InactiveCouponsComponent>; |
|||
|
|||
beforeEach(async () => { |
|||
await TestBed.configureTestingModule({ |
|||
declarations: [ InactiveCouponsComponent ] |
|||
}) |
|||
.compileComponents(); |
|||
}); |
|||
|
|||
beforeEach(() => { |
|||
fixture = TestBed.createComponent(InactiveCouponsComponent); |
|||
component = fixture.componentInstance; |
|||
fixture.detectChanges(); |
|||
}); |
|||
|
|||
it('should create', () => { |
|||
expect(component).toBeTruthy(); |
|||
}); |
|||
}); |
@ -0,0 +1,23 @@ |
|||
import { ChangeDetectionStrategy, Component, Input, OnInit, ViewChild } from '@angular/core'; |
|||
import { MatSort } from '@angular/material/sort'; |
|||
import { MatTableDataSource } from '@angular/material/table'; |
|||
|
|||
@Component({ |
|||
selector: 'inactivecoupons', |
|||
templateUrl: './inactive-coupons.component.html', |
|||
styleUrls: ['./inactive-coupons.component.scss'], |
|||
changeDetection: ChangeDetectionStrategy.OnPush, |
|||
exportAs: 'inactivecoupons' |
|||
}) |
|||
export class InactiveCouponsComponent implements OnInit { |
|||
@Input() couponsDataSource: MatTableDataSource<any>; |
|||
couponsTableColumns: string[] = ['product', 'quantity', 'type', 'condition', 'range', 'claimed', 'status', 'expiration', 'actions']; |
|||
@ViewChild('couponsTable', { read: MatSort }) couponsTableMatSort: MatSort; |
|||
constructor() { } |
|||
|
|||
ngOnInit(): void { |
|||
} |
|||
trackByFn(index: number, item: any): any { |
|||
return item.id || index; |
|||
} |
|||
} |
@ -0,0 +1,120 @@ |
|||
<div class="row" style="display: flex;justify-content:space-between"> |
|||
<div class="row" style="display: flex;justify-content:center;width: 100%;"> |
|||
<h2 mat-dialog-title style="text-align: center;">New Coupons </h2> |
|||
</div> |
|||
<!-- <button mat-button mat-dialog-close>Cancel</button> --> |
|||
<button mat-button [mat-dialog-close]="true" cdkFocusInitial>x</button> |
|||
</div> |
|||
<mat-dialog-content class="mat-typography"> |
|||
<div class=" py-2 pl-3 pr-3 sm:py-4 md:pl-4 md:pr-6"> |
|||
<div class="columns" style="display: flex;align-items: center"> |
|||
<div class="column" style="display: flex;align-items: baseline"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Target Product </strong> |
|||
</mat-label> |
|||
</div> |
|||
<div class="column"> |
|||
<mat-form-field appearance="fill" style="min-width: 200px;"> |
|||
<mat-select required> |
|||
<mat-option value="low">Product 1</mat-option> |
|||
<mat-option value="standard">Product 2</mat-option> |
|||
<mat-option value="high">Product 3</mat-option> |
|||
<mat-option value="high">Product 4</mat-option> |
|||
</mat-select> |
|||
</mat-form-field> |
|||
</div> |
|||
</div> |
|||
<div class="columns" style="display: flex;align-items: center;margin-top: 15px;"> |
|||
<div class="column" style="display: flex;align-items: baseline"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Original Price </strong> |
|||
</mat-label> |
|||
</div> |
|||
<div class="column"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
GH¢200 |
|||
</mat-label> |
|||
</div> |
|||
</div> |
|||
<div class="columns" style="display: flex;align-items: center;margin-top: 15px;"> |
|||
<div class="column" style="display: flex;align-items: baseline"> |
|||
<mat-label style="margin-right: 20px;"> |
|||
<strong class="tileHead">Coupon Type</strong> |
|||
</mat-label> |
|||
</div> |
|||
<div class="column"> |
|||
<mat-form-field appearance="fill" style="min-width: 200px;"> |
|||
<mat-select required> |
|||
<mat-option value="low">Freebie</mat-option> |
|||
<mat-option value="standard">Discount</mat-option> |
|||
<mat-option value="high">Proximity Freebie</mat-option> |
|||
<mat-option value="high">Proximity Discount</mat-option> |
|||
</mat-select> |
|||
</mat-form-field> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="columns" style="display: flex;align-items: center"> |
|||
<div class="column"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Coupon Condition</strong> |
|||
</mat-label> |
|||
</div> |
|||
<div class="column"> |
|||
<textarea name="" id="" cols="30" rows="5" style="border: 1px solid #cbd5e1;"></textarea> |
|||
</div> |
|||
</div> |
|||
<div class="columns" style="display: flex;align-items: center"> |
|||
<div class="column" style="display: flex;align-items: baseline"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Number Of Coupons</strong> |
|||
</mat-label> |
|||
</div> |
|||
<div class="column"> |
|||
<mat-form-field appearance="fill" style="min-width: 200px;"> |
|||
<input matInput style="margin-left:10px;" type="number"> |
|||
</mat-form-field> |
|||
</div> |
|||
|
|||
</div> |
|||
<div style="display: flex;align-items: baseline"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Percentage Off </strong> |
|||
</mat-label> |
|||
<mat-form-field appearance="fill" style="margin-right:10px;"> |
|||
<span matPrefix>From </span> |
|||
<input matInput type="number"> |
|||
<span matSuffix>% </span> |
|||
</mat-form-field> |
|||
<mat-form-field appearance="fill" style="margin-left:10px;"> |
|||
<span matPrefix>To </span> |
|||
<input matInput type="number"> |
|||
<span matSuffix>% </span> |
|||
</mat-form-field> |
|||
</div> |
|||
<div style="display: flex;align-items: baseline"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Coupon Worth </strong> |
|||
</mat-label> |
|||
<mat-label> |
|||
From GH¢200 To GH¢800 |
|||
</mat-label> |
|||
</div> |
|||
<div style="display: flex;align-items: baseline;margin-top: 20px;"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Date Of Expiration </strong> |
|||
</mat-label> |
|||
<mat-form-field appearance="outline"> |
|||
<input matInput style="margin-left:10px;" type="date"> |
|||
</mat-form-field> |
|||
<mat-form-field appearance="fill"> |
|||
<span matPrefix>Time </span> |
|||
<input matInput type="time"> |
|||
</mat-form-field> |
|||
</div> |
|||
<div class="row" style="display: flex;justify-content:space-around;width:100%;"> |
|||
<button style="background-color: blue;color:white;margin-right:20px;" mat-button>Generate Coupons</button> |
|||
|
|||
</div> |
|||
</div> |
|||
</mat-dialog-content> |
@ -0,0 +1,11 @@ |
|||
.columns { |
|||
display: flex; |
|||
flex-direction: row; |
|||
flex-wrap: wrap; |
|||
width: 100%; |
|||
} |
|||
|
|||
.column { |
|||
flex: 50%; |
|||
font-size: medium; |
|||
} |
@ -1,20 +1,20 @@ |
|||
import { ComponentFixture, TestBed } from '@angular/core/testing'; |
|||
|
|||
import { AdvertsComponent } from './adverts.component'; |
|||
import { NewCouponsComponent } from './new-coupons.component'; |
|||
|
|||
describe('AdvertsComponent', () => { |
|||
let component: AdvertsComponent; |
|||
let fixture: ComponentFixture<AdvertsComponent>; |
|||
describe('NewCouponsComponent', () => { |
|||
let component: NewCouponsComponent; |
|||
let fixture: ComponentFixture<NewCouponsComponent>; |
|||
|
|||
beforeEach(async () => { |
|||
await TestBed.configureTestingModule({ |
|||
declarations: [ AdvertsComponent ] |
|||
declarations: [ NewCouponsComponent ] |
|||
}) |
|||
.compileComponents(); |
|||
}); |
|||
|
|||
beforeEach(() => { |
|||
fixture = TestBed.createComponent(AdvertsComponent); |
|||
fixture = TestBed.createComponent(NewCouponsComponent); |
|||
component = fixture.componentInstance; |
|||
fixture.detectChanges(); |
|||
}); |
@ -0,0 +1,15 @@ |
|||
import { Component, OnInit } from '@angular/core'; |
|||
|
|||
@Component({ |
|||
selector: 'app-new-coupons', |
|||
templateUrl: './new-coupons.component.html', |
|||
styleUrls: ['./new-coupons.component.scss'] |
|||
}) |
|||
export class NewCouponsComponent implements OnInit { |
|||
|
|||
constructor() { } |
|||
|
|||
ngOnInit(): void { |
|||
} |
|||
|
|||
} |
@ -1 +1,32 @@ |
|||
<p>coupons works!</p> |
|||
<div class="flex flex-col flex-auto w-full"> |
|||
|
|||
<div class="flex flex-wrap w-full max-w-screen-xl mx-auto p-6 md:p-8"> |
|||
|
|||
<!-- Title and action buttons --> |
|||
<div class="flex items-center justify-between w-full" style="margin-bottom: 20px;"> |
|||
<div> |
|||
<div class="text-3xl font-semibold tracking-tight leading-8">Coupons</div> |
|||
<div class="font-medium tracking-tight text-secondary">Here is a list of all your coupons on Teso (850) |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="flex flex-shrink-0 items-center mt-6 sm:mt-0 sm:ml-4"> |
|||
<button class="ml-3" mat-flat-button style="margin-right: 10px;background-color: #003445;" (click)="generateCoupons()"> |
|||
<mat-icon class="icon-size-5" [svgIcon]="'heroicons_solid:plus'" style="color: white !important;"></mat-icon> |
|||
<span class="ml-2" style="color: white;">Add Coupon</span> |
|||
</button> |
|||
|
|||
</div> |
|||
</div> |
|||
|
|||
<mat-tab-group mat-align-tabs="center" style="width: 1440px;"> |
|||
<mat-tab label="Active Coupons"> |
|||
<activecoupons [couponsDataSource]="activecouponsData"></activecoupons> |
|||
</mat-tab> |
|||
<mat-tab label="Inactive Coupons"> |
|||
<inactivecoupons [couponsDataSource]="inactivecouponsData"></inactivecoupons> |
|||
</mat-tab> |
|||
</mat-tab-group> |
|||
|
|||
</div> |
|||
</div> |
@ -0,0 +1,12 @@ |
|||
import { Route } from '@angular/router'; |
|||
import { CouponsComponent } from './coupons.component'; |
|||
|
|||
export const couponsRoutes: Route[] = [ |
|||
{ |
|||
path : '', |
|||
component: CouponsComponent, |
|||
// resolve : {
|
|||
// data: FollowersResolver
|
|||
// }
|
|||
} |
|||
]; |
@ -0,0 +1,83 @@ |
|||
<div class="flex flex-col flex-auto w-full"> |
|||
|
|||
<div class="flex flex-wrap w-full max-w-screen-xl mx-auto p-6 md:p-8"> |
|||
|
|||
<!-- Title and action buttons --> |
|||
<div class="flex items-center justify-between w-full" style="margin-bottom: 20px;" *ngIf="!isScreenSmall"> |
|||
<div> |
|||
<div class="text-3xl font-semibold tracking-tight leading-8">Products</div> |
|||
<div class="font-medium tracking-tight text-secondary">Here is a list of all products in your Teso (850) |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="flex flex-shrink-0 items-center mt-6 sm:mt-0 sm:ml-4"> |
|||
<!-- Search --> |
|||
<mat-form-field class="teso-mat-dense teso-mat-no-subscript teso-mat-rounded min-w-64"> |
|||
<mat-icon class="icon-size-5" matPrefix [svgIcon]="'heroicons_solid:search'"></mat-icon> |
|||
<input matInput [autocomplete]="'off'" [placeholder]="'Look-up product'"> |
|||
</mat-form-field> |
|||
|
|||
</div> |
|||
</div> |
|||
<div class="flex items-center justify-between w-full" style="margin-bottom: 20px;" *ngIf="isScreenSmall"> |
|||
<div> |
|||
<div class="text-3xl font-semibold tracking-tight leading-8">Products</div> |
|||
<div class="font-medium tracking-tight text-secondary">(850) products |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="flex-col items-center justify-end mt-6 ml-10"> |
|||
<button mat-flat-button [color]="'primary'" (click)="createProduct()" style="margin-bottom: 10px;"> |
|||
<mat-icon class="icon-size-5" [svgIcon]="'heroicons_solid:plus'"></mat-icon> |
|||
<span class="ml-2">Add Product</span> |
|||
</button> |
|||
<!-- Search --> |
|||
<mat-form-field class="teso-mat-dense teso-mat-no-subscript teso-mat-rounded "> |
|||
<mat-icon class="icon-size-5" matPrefix [svgIcon]="'heroicons_solid:search'"></mat-icon> |
|||
<input matInput [autocomplete]="'off'" [placeholder]="'Search'"> |
|||
</mat-form-field> |
|||
|
|||
</div> |
|||
</div> |
|||
|
|||
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6 w-full min-w-0"> |
|||
<ng-container *ngFor="let product of data.teamproducts"> |
|||
<!-- <div class="flex flex-col flex-auto items-center bg-card shadow rounded-2xl overflow-hidden"> --> |
|||
<div class="product"> |
|||
<div class="product-content"> |
|||
<div class="product-img"> |
|||
<img [src]="product.image" alt="product image" style="max-height:200px;"> |
|||
</div> |
|||
<div class="product-btns"> |
|||
<button type="button" class="btn-buy" (click)="generateCoupon(product)" *ngIf="product.title.includes('Developer')"> |
|||
Generate Coupons |
|||
</button> |
|||
<button type="button" class="btn-cart" (click)="createProduct()" *ngIf="!product.title.includes('Developer')"> |
|||
Add Product |
|||
</button> |
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
<div class="product-info"> |
|||
<div class="product-info-top"> |
|||
<h2 class="sm-title">@product.CategoryID</h2> |
|||
</div> |
|||
<a href="#" class="product-name">@product.ProductName</a> |
|||
<p class="product-price"><span></span></p> |
|||
<p class="product-price"><span>₵</span> @product.UnitPrice</p> |
|||
<p>@product.ProductDesc</p> |
|||
</div> |
|||
<!-- </div> --> |
|||
</div> |
|||
</ng-container> |
|||
</div> |
|||
<mat-paginator |
|||
class="sticky sm:absolute sm:inset-x-0 sm:bottom-0 border-b sm:border-t sm:border-b-0 z-10 bg-gray-50 dark:bg-transparent" |
|||
[pageSizeOptions]="[5, 10, 25, 100]" [showFirstLastButtons]="true"></mat-paginator> |
|||
<ng-template #noProducts> |
|||
<div class="p-8 sm:p-16 border-t text-4xl font-semibold tracking-tight text-center">There are no monthly desires yet! |
|||
</div> |
|||
</ng-template> |
|||
</div> |
|||
</div> |
@ -0,0 +1,384 @@ |
|||
* { |
|||
padding: 0; |
|||
margin: 0; |
|||
box-sizing: border-box; |
|||
} |
|||
|
|||
body { |
|||
font-family: 'Quicksand', sans-serif; |
|||
} |
|||
|
|||
.btn2 { |
|||
background-color: transparent; |
|||
/* Blue background */ |
|||
border: none; |
|||
/* Remove borders */ |
|||
color: #003445; |
|||
/* White text */ |
|||
padding: 12px 16px; |
|||
/* Some padding */ |
|||
font-size: 16px; |
|||
/* Set a font size */ |
|||
cursor: pointer; |
|||
/* Mouse pointer on hover */ |
|||
} |
|||
|
|||
|
|||
/* Darker background on mouse-over */ |
|||
|
|||
|
|||
/* .btn2:hover { |
|||
background-color: RoyalBlue; |
|||
}*/ |
|||
|
|||
.btn-outline-success { |
|||
color: #28a745; |
|||
background-color: transparent; |
|||
background-image: none; |
|||
border-color: #28a745 !important; |
|||
} |
|||
|
|||
.btn { |
|||
display: inline-block; |
|||
font-weight: 400; |
|||
text-align: center; |
|||
white-space: nowrap; |
|||
vertical-align: middle; |
|||
-webkit-user-select: none; |
|||
-moz-user-select: none; |
|||
-ms-user-select: none; |
|||
user-select: none; |
|||
border: 1px solid transparent; |
|||
padding: .375rem .75rem; |
|||
font-size: 1rem; |
|||
line-height: 1.5; |
|||
border-radius: .25rem; |
|||
transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out; |
|||
} |
|||
|
|||
.btn-danger { |
|||
color: #fff; |
|||
background-color: #dc3545; |
|||
border-color: #dc3545; |
|||
} |
|||
|
|||
.btn { |
|||
display: inline-block; |
|||
font-weight: 400; |
|||
text-align: center; |
|||
white-space: nowrap; |
|||
vertical-align: middle; |
|||
-webkit-user-select: none; |
|||
-moz-user-select: none; |
|||
-ms-user-select: none; |
|||
user-select: none; |
|||
border: 1px solid transparent; |
|||
padding: .375rem .75rem; |
|||
font-size: 1rem; |
|||
line-height: 1.5; |
|||
border-radius: .25rem; |
|||
transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out; |
|||
} |
|||
|
|||
.form-control { |
|||
display: block; |
|||
width: 70%; |
|||
padding: .375rem .75rem; |
|||
font-size: 1rem; |
|||
line-height: 1.5; |
|||
color: #495057; |
|||
background-color: #fff; |
|||
background-clip: padding-box; |
|||
border: 1px solid #ced4da; |
|||
border-radius: .25rem; |
|||
transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out; |
|||
} |
|||
|
|||
[type=search] { |
|||
outline-offset: -2px; |
|||
-webkit-appearance: none; |
|||
} |
|||
|
|||
button, |
|||
input { |
|||
overflow: visible; |
|||
} |
|||
|
|||
|
|||
/* Utility stylings */ |
|||
|
|||
img { |
|||
width: 100%; |
|||
display: block; |
|||
} |
|||
|
|||
.container { |
|||
width: 88vw; |
|||
margin: 0 auto; |
|||
} |
|||
|
|||
.lg-title, |
|||
.md-title, |
|||
.sm-title { |
|||
font-family: 'Roboto', sans-serif; |
|||
padding: 0.6rem 0; |
|||
text-transform: capitalize; |
|||
} |
|||
|
|||
.lg-title { |
|||
font-size: 2.5rem; |
|||
font-weight: 500; |
|||
text-align: center; |
|||
padding: 1.3rem 0; |
|||
opacity: 0.9; |
|||
} |
|||
|
|||
.md-title { |
|||
font-size: 2rem; |
|||
font-family: 'Roboto', sans-serif; |
|||
} |
|||
|
|||
.sm-title { |
|||
font-weight: 300; |
|||
font-size: 1rem; |
|||
text-transform: uppercase; |
|||
} |
|||
|
|||
.text-light { |
|||
font-size: 1rem; |
|||
font-weight: 600; |
|||
line-height: 1.5; |
|||
opacity: 0.5; |
|||
margin: 0.4rem 0; |
|||
} |
|||
|
|||
|
|||
/* product section */ |
|||
|
|||
.products { |
|||
background: #f8f9fa; |
|||
// padding: 3.2rem 0; |
|||
} |
|||
|
|||
.products .text-light { |
|||
text-align: center; |
|||
width: 70%; |
|||
margin: 0.9rem auto; |
|||
} |
|||
|
|||
.product { |
|||
// margin: 2rem; |
|||
position: relative; |
|||
} |
|||
|
|||
.product-content { |
|||
background: #ededed; |
|||
padding: 1rem 0.5rem 1rem 0.5rem; |
|||
cursor: pointer; |
|||
} |
|||
|
|||
.product-img { |
|||
background: rgba(255, 255, 255, 0.5); |
|||
box-shadow: 0 0 20px 10px rgba(255, 255, 255, 0.5); |
|||
width: 200px; |
|||
height: 200px; |
|||
margin: 0 auto; |
|||
border-radius: 50%; |
|||
transition: background 0.5s ease; |
|||
} |
|||
|
|||
.product-btns { |
|||
display: flex; |
|||
justify-content: center; |
|||
margin-top: 1.4rem; |
|||
opacity: 0; |
|||
transition: opacity 0.6s ease; |
|||
} |
|||
|
|||
.btn-cart, |
|||
.btn-buy { |
|||
background: transparent; |
|||
border: 1px solid black; |
|||
padding: 0.8rem 0; |
|||
width: 125px; |
|||
font-family: inherit; |
|||
text-transform: uppercase; |
|||
cursor: pointer; |
|||
border: none; |
|||
transition: all 0.6s ease; |
|||
} |
|||
|
|||
.btn-cart { |
|||
background: black; |
|||
color: white; |
|||
} |
|||
|
|||
.btn-cart:hover { |
|||
background: #40c9a2; |
|||
} |
|||
|
|||
.btn-buy { |
|||
background: white; |
|||
} |
|||
|
|||
.btn-buy:hover { |
|||
background: #40c9a2; |
|||
color: #fff; |
|||
} |
|||
|
|||
.product-info { |
|||
background: white; |
|||
padding: 2rem; |
|||
} |
|||
|
|||
.product-info-top { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
} |
|||
|
|||
.rating span { |
|||
color: #40c9a2; |
|||
} |
|||
|
|||
.product-name { |
|||
color: black; |
|||
display: block; |
|||
text-decoration: none; |
|||
font-size: 1rem; |
|||
text-transform: uppercase; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
.product-price { |
|||
padding-top: 0.6rem; |
|||
padding-right: 0.6rem; |
|||
display: inline-block; |
|||
} |
|||
|
|||
.product-price:first-of-type { |
|||
text-decoration: line-through; |
|||
color: #40c9a2; |
|||
} |
|||
|
|||
.product-img img { |
|||
transition: transform 0.6s ease; |
|||
} |
|||
|
|||
.product:hover .product-img img { |
|||
transform: scale(1.1); |
|||
} |
|||
|
|||
.product:hover .product-img { |
|||
background: #40c9a2; |
|||
} |
|||
|
|||
.product:hover .product-btns { |
|||
opacity: 1; |
|||
} |
|||
|
|||
.off-info .sm-title { |
|||
background: #40c9a2; |
|||
color: white; |
|||
display: inline-block; |
|||
padding: 0.5rem; |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
writing-mode: vertical-lr; |
|||
transform: rotate(180deg); |
|||
z-index: 1; |
|||
letter-spacing: 3px; |
|||
cursor: pointer; |
|||
} |
|||
|
|||
|
|||
/* product collection */ |
|||
|
|||
.product-collection { |
|||
padding: 3.2rem 0; |
|||
} |
|||
|
|||
.product-collection-wrapper { |
|||
padding: 3.2rem 0; |
|||
} |
|||
|
|||
.flex { |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: flex-end; |
|||
} |
|||
|
|||
.product-col-r-bottom>div:first-child { |
|||
background: #eaa001; |
|||
} |
|||
|
|||
.product-col-r-bottom>div:last-child { |
|||
background: #0090ff; |
|||
} |
|||
|
|||
.product-col-content { |
|||
text-align: center; |
|||
color: white; |
|||
} |
|||
|
|||
.product-collection .text-light { |
|||
opacity: 1; |
|||
font-size: 0.8; |
|||
font-weight: 400; |
|||
line-height: 1.7; |
|||
} |
|||
|
|||
.btn-dark { |
|||
background: black; |
|||
color: white; |
|||
outline: 0; |
|||
border-radius: 25px; |
|||
padding: 0.7rem 1rem; |
|||
border: 0; |
|||
margin-top: 1rem; |
|||
cursor: pointer; |
|||
transition: all 0.6s ease; |
|||
font-size: 1rem; |
|||
font-family: inherit; |
|||
} |
|||
|
|||
.btn-dark:hover { |
|||
background: #40c9a2; |
|||
} |
|||
|
|||
|
|||
/* Media Queries */ |
|||
|
|||
@media screen and (min-width: 992px) { |
|||
.product-items { |
|||
display: grid; |
|||
grid-template-columns: repeat(2, 1fr); |
|||
} |
|||
.product-col-r-bottom { |
|||
display: grid; |
|||
grid-template-columns: repeat(2, 1fr); |
|||
} |
|||
} |
|||
|
|||
@media screen and (min-width: 1200px) { |
|||
.product-items { |
|||
grid-template-columns: repeat(3, 1fr); |
|||
} |
|||
.products .text-light { |
|||
width: 50%; |
|||
} |
|||
} |
|||
|
|||
@media screen and (min-width: 1336px) { |
|||
.product-items { |
|||
grid-template-columns: repeat(3, 1fr); |
|||
} |
|||
.product-collection-wrapper { |
|||
display: grid; |
|||
grid-template-columns: repeat(2, 1fr); |
|||
} |
|||
.product-col-left { |
|||
height: 121.5vh; |
|||
} |
|||
} |
@ -1,20 +1,20 @@ |
|||
import { ComponentFixture, TestBed } from '@angular/core/testing'; |
|||
|
|||
import { ProductListComponent } from './product-list.component'; |
|||
import { ListDesiresComponent } from './list-desires.component'; |
|||
|
|||
describe('ProductListComponent', () => { |
|||
let component: ProductListComponent; |
|||
let fixture: ComponentFixture<ProductListComponent>; |
|||
describe('ListDesiresComponent', () => { |
|||
let component: ListDesiresComponent; |
|||
let fixture: ComponentFixture<ListDesiresComponent>; |
|||
|
|||
beforeEach(async () => { |
|||
await TestBed.configureTestingModule({ |
|||
declarations: [ ProductListComponent ] |
|||
declarations: [ ListDesiresComponent ] |
|||
}) |
|||
.compileComponents(); |
|||
}); |
|||
|
|||
beforeEach(() => { |
|||
fixture = TestBed.createComponent(ProductListComponent); |
|||
fixture = TestBed.createComponent(ListDesiresComponent); |
|||
component = fixture.componentInstance; |
|||
fixture.detectChanges(); |
|||
}); |
@ -0,0 +1,154 @@ |
|||
import { Component, OnInit, ViewChild } from '@angular/core'; |
|||
import { MatDialog } from '@angular/material/dialog'; |
|||
import { MatPaginator } from '@angular/material/paginator'; |
|||
import { MatSort } from '@angular/material/sort'; |
|||
import { Router } from '@angular/router'; |
|||
import { ConfirmBoxEvokeService } from '@costlydeveloper/ngx-awesome-popup'; |
|||
import { tesoMediaWatcherService } from '@teso/services/media-watcher'; |
|||
import { Subject } from 'rxjs'; |
|||
import { takeUntil } from 'rxjs/operators'; |
|||
import { AdminCouponDialogComponent } from '../../Products/AdminCouponDialog/admin-coupon-dialog.component'; |
|||
import { CouponDialogComponent } from '../../Products/CouponDialog/coupon-dialog.component'; |
|||
|
|||
@Component({ |
|||
selector: 'app-list-desires', |
|||
templateUrl: './list-desires.component.html', |
|||
styleUrls: ['./list-desires.component.scss'] |
|||
}) |
|||
export class ListDesiresComponent implements OnInit { |
|||
|
|||
data: { teamproducts: { id: string; image: string; name: string; email: string; phone: string; title: string; }[]; }; |
|||
@ViewChild(MatPaginator) private _paginator: MatPaginator; |
|||
@ViewChild(MatSort) private _sort: MatSort; |
|||
isScreenSmall: boolean; |
|||
private _unsubscribeAll: Subject<any> = new Subject<any>(); |
|||
constructor(private router: Router, private _tesoMediaWatcherService: tesoMediaWatcherService, |
|||
public dialog: MatDialog, private confirmBoxEvokeService: ConfirmBoxEvokeService) { } |
|||
|
|||
ngOnDestroy(): void { |
|||
// Unsubscribe from all subscriptions
|
|||
this._unsubscribeAll.next(); |
|||
this._unsubscribeAll.complete(); |
|||
} |
|||
|
|||
ngOnInit(): void { |
|||
// Subscribe to media changes
|
|||
this._tesoMediaWatcherService.onMediaChange$ |
|||
.pipe(takeUntil(this._unsubscribeAll)) |
|||
.subscribe(({ matchingAliases }) => { |
|||
|
|||
// Check if the screen is small
|
|||
this.isScreenSmall = !matchingAliases.includes('md'); |
|||
}); |
|||
this.data = { |
|||
teamproducts: [ |
|||
{ |
|||
id: '2bfa2be5-7688-48d5-b5ac-dc0d9ac97f14', |
|||
image: 'assets/images/brands/bagset.png', |
|||
name: 'Nadia Mcknight', |
|||
email: 'nadiamcknight@mail.com', |
|||
phone: '+1-943-511-2203', |
|||
title: 'Project Director' |
|||
}, |
|||
{ |
|||
id: '77a4383b-b5a5-4943-bc46-04c3431d1566', |
|||
image: 'assets/images/brands/bagset.png', |
|||
name: 'Best Blackburn', |
|||
email: 'blackburn.best@beadzza.me', |
|||
phone: '+1-814-498-3701', |
|||
title: 'Senior Developer' |
|||
}, |
|||
{ |
|||
id: '8bb0f597-673a-47ca-8c77-2f83219cb9af', |
|||
image: 'assets/images/brands/bagset.png', |
|||
name: 'Duncan Carver', |
|||
email: 'duncancarver@mail.info', |
|||
phone: '+1-968-547-2111', |
|||
title: 'Senior Developer' |
|||
}, |
|||
{ |
|||
id: 'c318e31f-1d74-49c5-8dae-2bc5805e2fdb', |
|||
image: 'assets/images/brands/bagset.png', |
|||
name: 'Martin Richards', |
|||
email: 'martinrichards@mail.biz', |
|||
phone: '+1-902-500-2668', |
|||
title: 'Junior Developer' |
|||
}, |
|||
{ |
|||
id: '0a8bc517-631a-4a93-aacc-000fa2e8294c', |
|||
image: 'assets/images/brands/bagset.png', |
|||
name: 'Candice Munoz', |
|||
email: 'candicemunoz@mail.co.uk', |
|||
phone: '+1-838-562-2769', |
|||
title: 'Lead Designer' |
|||
}, |
|||
{ |
|||
id: 'a4c9945a-757b-40b0-8942-d20e0543cabd', |
|||
image: 'assets/images/brands/bagset.png', |
|||
name: 'Vickie Mosley', |
|||
email: 'vickiemosley@mail.net', |
|||
phone: '+1-939-555-3054', |
|||
title: 'Designer' |
|||
}, |
|||
{ |
|||
id: 'b8258ccf-48b5-46a2-9c95-e0bd7580c645', |
|||
image: 'assets/images/brands/bagset.png', |
|||
name: 'Tina Harris', |
|||
email: 'tinaharris@mail.ca', |
|||
phone: '+1-933-464-2431', |
|||
title: 'Designer' |
|||
}, |
|||
{ |
|||
id: 'f004ea79-98fc-436c-9ba5-6cfe32fe583d', |
|||
image: 'assets/images/brands/bagset.png', |
|||
name: 'Holt Manning', |
|||
email: 'holtmanning@mail.org', |
|||
phone: '+1-822-531-2600', |
|||
title: 'Marketing Manager' |
|||
}, |
|||
{ |
|||
id: '8b69fe2d-d7cc-4a3d-983d-559173e37d37', |
|||
image: 'assets/images/brands/bagset.png', |
|||
name: 'Misty Ramsey', |
|||
email: 'mistyramsey@mail.us', |
|||
phone: '+1-990-457-2106', |
|||
title: 'Consultant' |
|||
} |
|||
] |
|||
} |
|||
} |
|||
createProduct() { |
|||
this.router.navigate(['products/create-product']); |
|||
} |
|||
editProduct(productID: any) { |
|||
this.router.navigate(['products/' + productID]); |
|||
} |
|||
generateCoupon(product: any) { |
|||
if (!true) { |
|||
const dialogRef = this.dialog.open(CouponDialogComponent, { |
|||
disableClose: true, |
|||
hasBackdrop: true, |
|||
data: { product: product }, |
|||
|
|||
}); |
|||
} else { |
|||
const dialogRef = this.dialog.open(AdminCouponDialogComponent, { |
|||
disableClose: true, |
|||
hasBackdrop: true, |
|||
data: { product: product }, |
|||
|
|||
}); |
|||
} |
|||
} |
|||
deleteProduct(product: any) { |
|||
this.confirmBoxEvokeService.danger("Delete Product", |
|||
"Are you sure you would like to delete this product from your inventory ?", |
|||
"Yes", "No") |
|||
.subscribe((response: any) => { |
|||
console.log(response) |
|||
if (response.clickedButtonID === "yes") { |
|||
this.data.teamproducts = this.data.teamproducts.filter((e) => e == product); |
|||
} |
|||
}); |
|||
} |
|||
} |
@ -1 +1 @@ |
|||
<p>desires works!</p> |
|||
<router-outlet></router-outlet> |
|||
|
@ -0,0 +1,384 @@ |
|||
* { |
|||
padding: 0; |
|||
margin: 0; |
|||
box-sizing: border-box; |
|||
} |
|||
|
|||
body { |
|||
font-family: 'Quicksand', sans-serif; |
|||
} |
|||
|
|||
.btn2 { |
|||
background-color: transparent; |
|||
/* Blue background */ |
|||
border: none; |
|||
/* Remove borders */ |
|||
color: #003445; |
|||
/* White text */ |
|||
padding: 12px 16px; |
|||
/* Some padding */ |
|||
font-size: 16px; |
|||
/* Set a font size */ |
|||
cursor: pointer; |
|||
/* Mouse pointer on hover */ |
|||
} |
|||
|
|||
|
|||
/* Darker background on mouse-over */ |
|||
|
|||
|
|||
/* .btn2:hover { |
|||
background-color: RoyalBlue; |
|||
}*/ |
|||
|
|||
.btn-outline-success { |
|||
color: #28a745; |
|||
background-color: transparent; |
|||
background-image: none; |
|||
border-color: #28a745 !important; |
|||
} |
|||
|
|||
.btn { |
|||
display: inline-block; |
|||
font-weight: 400; |
|||
text-align: center; |
|||
white-space: nowrap; |
|||
vertical-align: middle; |
|||
-webkit-user-select: none; |
|||
-moz-user-select: none; |
|||
-ms-user-select: none; |
|||
user-select: none; |
|||
border: 1px solid transparent; |
|||
padding: .375rem .75rem; |
|||
font-size: 1rem; |
|||
line-height: 1.5; |
|||
border-radius: .25rem; |
|||
transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out; |
|||
} |
|||
|
|||
.btn-danger { |
|||
color: #fff; |
|||
background-color: #dc3545; |
|||
border-color: #dc3545; |
|||
} |
|||
|
|||
.btn { |
|||
display: inline-block; |
|||
font-weight: 400; |
|||
text-align: center; |
|||
white-space: nowrap; |
|||
vertical-align: middle; |
|||
-webkit-user-select: none; |
|||
-moz-user-select: none; |
|||
-ms-user-select: none; |
|||
user-select: none; |
|||
border: 1px solid transparent; |
|||
padding: .375rem .75rem; |
|||
font-size: 1rem; |
|||
line-height: 1.5; |
|||
border-radius: .25rem; |
|||
transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out; |
|||
} |
|||
|
|||
.form-control { |
|||
display: block; |
|||
width: 70%; |
|||
padding: .375rem .75rem; |
|||
font-size: 1rem; |
|||
line-height: 1.5; |
|||
color: #495057; |
|||
background-color: #fff; |
|||
background-clip: padding-box; |
|||
border: 1px solid #ced4da; |
|||
border-radius: .25rem; |
|||
transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out; |
|||
} |
|||
|
|||
[type=search] { |
|||
outline-offset: -2px; |
|||
-webkit-appearance: none; |
|||
} |
|||
|
|||
button, |
|||
input { |
|||
overflow: visible; |
|||
} |
|||
|
|||
|
|||
/* Utility stylings */ |
|||
|
|||
img { |
|||
width: 100%; |
|||
display: block; |
|||
} |
|||
|
|||
.container { |
|||
width: 88vw; |
|||
margin: 0 auto; |
|||
} |
|||
|
|||
.lg-title, |
|||
.md-title, |
|||
.sm-title { |
|||
font-family: 'Roboto', sans-serif; |
|||
padding: 0.6rem 0; |
|||
text-transform: capitalize; |
|||
} |
|||
|
|||
.lg-title { |
|||
font-size: 2.5rem; |
|||
font-weight: 500; |
|||
text-align: center; |
|||
padding: 1.3rem 0; |
|||
opacity: 0.9; |
|||
} |
|||
|
|||
.md-title { |
|||
font-size: 2rem; |
|||
font-family: 'Roboto', sans-serif; |
|||
} |
|||
|
|||
.sm-title { |
|||
font-weight: 300; |
|||
font-size: 1rem; |
|||
text-transform: uppercase; |
|||
} |
|||
|
|||
.text-light { |
|||
font-size: 1rem; |
|||
font-weight: 600; |
|||
line-height: 1.5; |
|||
opacity: 0.5; |
|||
margin: 0.4rem 0; |
|||
} |
|||
|
|||
|
|||
/* product section */ |
|||
|
|||
.products { |
|||
background: #f8f9fa; |
|||
// padding: 3.2rem 0; |
|||
} |
|||
|
|||
.products .text-light { |
|||
text-align: center; |
|||
width: 70%; |
|||
margin: 0.9rem auto; |
|||
} |
|||
|
|||
.product { |
|||
// margin: 2rem; |
|||
position: relative; |
|||
} |
|||
|
|||
.product-content { |
|||
background: #ededed; |
|||
padding: 1rem 0.5rem 1rem 0.5rem; |
|||
cursor: pointer; |
|||
} |
|||
|
|||
.product-img { |
|||
background: rgba(255, 255, 255, 0.5); |
|||
box-shadow: 0 0 20px 10px rgba(255, 255, 255, 0.5); |
|||
width: 200px; |
|||
height: 200px; |
|||
margin: 0 auto; |
|||
border-radius: 50%; |
|||
transition: background 0.5s ease; |
|||
} |
|||
|
|||
.product-btns { |
|||
display: flex; |
|||
justify-content: center; |
|||
margin-top: 1.4rem; |
|||
opacity: 0; |
|||
transition: opacity 0.6s ease; |
|||
} |
|||
|
|||
.btn-cart, |
|||
.btn-buy { |
|||
background: transparent; |
|||
border: 1px solid black; |
|||
padding: 0.8rem 0; |
|||
width: 125px; |
|||
font-family: inherit; |
|||
text-transform: uppercase; |
|||
cursor: pointer; |
|||
border: none; |
|||
transition: all 0.6s ease; |
|||
} |
|||
|
|||
.btn-cart { |
|||
background: black; |
|||
color: white; |
|||
} |
|||
|
|||
.btn-cart:hover { |
|||
background: #40c9a2; |
|||
} |
|||
|
|||
.btn-buy { |
|||
background: white; |
|||
} |
|||
|
|||
.btn-buy:hover { |
|||
background: #40c9a2; |
|||
color: #fff; |
|||
} |
|||
|
|||
.product-info { |
|||
background: white; |
|||
padding: 2rem; |
|||
} |
|||
|
|||
.product-info-top { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
} |
|||
|
|||
.rating span { |
|||
color: #40c9a2; |
|||
} |
|||
|
|||
.product-name { |
|||
color: black; |
|||
display: block; |
|||
text-decoration: none; |
|||
font-size: 1rem; |
|||
text-transform: uppercase; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
.product-price { |
|||
padding-top: 0.6rem; |
|||
padding-right: 0.6rem; |
|||
display: inline-block; |
|||
} |
|||
|
|||
.product-price:first-of-type { |
|||
text-decoration: line-through; |
|||
color: #40c9a2; |
|||
} |
|||
|
|||
.product-img img { |
|||
transition: transform 0.6s ease; |
|||
} |
|||
|
|||
.product:hover .product-img img { |
|||
transform: scale(1.1); |
|||
} |
|||
|
|||
.product:hover .product-img { |
|||
background: #40c9a2; |
|||
} |
|||
|
|||
.product:hover .product-btns { |
|||
opacity: 1; |
|||
} |
|||
|
|||
.off-info .sm-title { |
|||
background: #40c9a2; |
|||
color: white; |
|||
display: inline-block; |
|||
padding: 0.5rem; |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
writing-mode: vertical-lr; |
|||
transform: rotate(180deg); |
|||
z-index: 1; |
|||
letter-spacing: 3px; |
|||
cursor: pointer; |
|||
} |
|||
|
|||
|
|||
/* product collection */ |
|||
|
|||
.product-collection { |
|||
padding: 3.2rem 0; |
|||
} |
|||
|
|||
.product-collection-wrapper { |
|||
padding: 3.2rem 0; |
|||
} |
|||
|
|||
.flex { |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: flex-end; |
|||
} |
|||
|
|||
.product-col-r-bottom>div:first-child { |
|||
background: #eaa001; |
|||
} |
|||
|
|||
.product-col-r-bottom>div:last-child { |
|||
background: #0090ff; |
|||
} |
|||
|
|||
.product-col-content { |
|||
text-align: center; |
|||
color: white; |
|||
} |
|||
|
|||
.product-collection .text-light { |
|||
opacity: 1; |
|||
font-size: 0.8; |
|||
font-weight: 400; |
|||
line-height: 1.7; |
|||
} |
|||
|
|||
.btn-dark { |
|||
background: black; |
|||
color: white; |
|||
outline: 0; |
|||
border-radius: 25px; |
|||
padding: 0.7rem 1rem; |
|||
border: 0; |
|||
margin-top: 1rem; |
|||
cursor: pointer; |
|||
transition: all 0.6s ease; |
|||
font-size: 1rem; |
|||
font-family: inherit; |
|||
} |
|||
|
|||
.btn-dark:hover { |
|||
background: #40c9a2; |
|||
} |
|||
|
|||
|
|||
/* Media Queries */ |
|||
|
|||
@media screen and (min-width: 992px) { |
|||
.product-items { |
|||
display: grid; |
|||
grid-template-columns: repeat(2, 1fr); |
|||
} |
|||
.product-col-r-bottom { |
|||
display: grid; |
|||
grid-template-columns: repeat(2, 1fr); |
|||
} |
|||
} |
|||
|
|||
@media screen and (min-width: 1200px) { |
|||
.product-items { |
|||
grid-template-columns: repeat(3, 1fr); |
|||
} |
|||
.products .text-light { |
|||
width: 50%; |
|||
} |
|||
} |
|||
|
|||
@media screen and (min-width: 1336px) { |
|||
.product-items { |
|||
grid-template-columns: repeat(3, 1fr); |
|||
} |
|||
.product-collection-wrapper { |
|||
display: grid; |
|||
grid-template-columns: repeat(2, 1fr); |
|||
} |
|||
.product-col-left { |
|||
height: 121.5vh; |
|||
} |
|||
} |
@ -1,12 +1,59 @@ |
|||
import { NgModule } from '@angular/core'; |
|||
import { CommonModule } from '@angular/common'; |
|||
import { ListDesiresComponent } from './ListDesires/list-desires.component'; |
|||
import { DesiresComponent } from './desires.component'; |
|||
import { MatButtonModule } from '@angular/material/button'; |
|||
import { MatButtonToggleModule } from '@angular/material/button-toggle'; |
|||
import { MatRippleModule } from '@angular/material/core'; |
|||
import { MatDialogModule } from '@angular/material/dialog'; |
|||
import { MatDividerModule } from '@angular/material/divider'; |
|||
import { MatFormFieldModule } from '@angular/material/form-field'; |
|||
import { MatIconModule } from '@angular/material/icon'; |
|||
import { MatInputModule } from '@angular/material/input'; |
|||
import { MatMenuModule } from '@angular/material/menu'; |
|||
import { MatPaginatorModule } from '@angular/material/paginator'; |
|||
import { MatProgressBarModule } from '@angular/material/progress-bar'; |
|||
import { MatSelectModule } from '@angular/material/select'; |
|||
import { MatSidenavModule } from '@angular/material/sidenav'; |
|||
import { MatSortModule } from '@angular/material/sort'; |
|||
import { MatTableModule } from '@angular/material/table'; |
|||
import { MatTabsModule } from '@angular/material/tabs'; |
|||
import { MatTooltipModule } from '@angular/material/tooltip'; |
|||
import { RouterModule } from '@angular/router'; |
|||
import { TranslocoModule } from '@ngneat/transloco'; |
|||
import { SharedModule } from 'app/shared/shared.module'; |
|||
import { QuillModule } from 'ngx-quill'; |
|||
import { desiresRoutes } from './desires.routing'; |
|||
|
|||
|
|||
|
|||
@NgModule({ |
|||
declarations: [], |
|||
declarations: [ |
|||
DesiresComponent, |
|||
ListDesiresComponent |
|||
], |
|||
imports: [ |
|||
CommonModule |
|||
RouterModule.forChild(desiresRoutes), |
|||
QuillModule.forRoot(), |
|||
MatButtonModule, |
|||
MatButtonToggleModule, |
|||
MatDividerModule, |
|||
MatIconModule, |
|||
MatFormFieldModule, |
|||
MatInputModule, |
|||
MatMenuModule, |
|||
MatProgressBarModule, |
|||
MatRippleModule, |
|||
MatSidenavModule, |
|||
MatSortModule, |
|||
MatTableModule, |
|||
MatTabsModule, |
|||
MatDialogModule, |
|||
TranslocoModule, |
|||
SharedModule, |
|||
MatPaginatorModule, |
|||
MatSelectModule, |
|||
MatTooltipModule, |
|||
] |
|||
}) |
|||
export class DesiresModule { } |
|||
|
@ -0,0 +1,36 @@ |
|||
import { Route } from '@angular/router'; |
|||
import { EditProductComponent } from '../Products/EditProduct/edit-product.component'; |
|||
import { NewProductComponent } from '../Products/NewProduct/new-product.component'; |
|||
import { DesiresComponent } from './desires.component'; |
|||
import { ListDesiresComponent } from './ListDesires/list-desires.component'; |
|||
|
|||
export const desiresRoutes: Route[] = [ |
|||
{ |
|||
path : '', |
|||
component: DesiresComponent, |
|||
// resolve : {
|
|||
// data: FollowersResolver
|
|||
// }
|
|||
children : [ |
|||
{ |
|||
path : '', |
|||
pathMatch: 'full', |
|||
component: ListDesiresComponent, |
|||
}, |
|||
{ |
|||
path : 'create-product', |
|||
component: NewProductComponent, |
|||
// resolve : {
|
|||
// course: AcademyCourseResolver
|
|||
// }
|
|||
}, |
|||
// {
|
|||
// path : ':id',
|
|||
// component: EditProductComponent,
|
|||
// // resolve : {
|
|||
// // course: AcademyCourseResolver
|
|||
// // }
|
|||
// }
|
|||
] |
|||
} |
|||
]; |
@ -0,0 +1,129 @@ |
|||
<div class="row" style="display: flex;justify-content:space-between"> |
|||
<div class="row" style="display: flex;justify-content:center;width: 100%;"> |
|||
<h2 mat-dialog-title style="text-align: center;">Coupons for {{data.product.name}}</h2> |
|||
</div> |
|||
<!-- <button mat-button mat-dialog-close>Cancel</button> --> |
|||
<button mat-button [mat-dialog-close]="true" cdkFocusInitial>x</button> |
|||
</div> |
|||
<mat-dialog-content class="mat-typography"> |
|||
<div class=" py-2 pl-3 pr-3 sm:py-4 md:pl-4 md:pr-6"> |
|||
<div class="columns" style="display: flex;align-items: center"> |
|||
<div class="column" style="display: flex;align-items: baseline"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Target Business </strong> |
|||
</mat-label> |
|||
</div> |
|||
<div class="column"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
Target Name |
|||
</mat-label> |
|||
<button style="background-color: blue;color:white;margin-right:20px;" mat-button (click)="lookupBusiness()">Search</button> |
|||
</div> |
|||
</div> |
|||
<hr/> |
|||
<div class="columns" style="display: flex;align-items: center"> |
|||
<div class="column" style="display: flex;align-items: baseline"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Target Name </strong> |
|||
</mat-label> |
|||
</div> |
|||
<div class="column"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
Target Name |
|||
</mat-label> |
|||
</div> |
|||
</div> |
|||
<div class="columns" style="display: flex;align-items: center;margin-top: 15px;"> |
|||
<div class="column" style="display: flex;align-items: baseline"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Original Price </strong> |
|||
</mat-label> |
|||
</div> |
|||
<div class="column"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
GH¢200 |
|||
</mat-label> |
|||
</div> |
|||
</div> |
|||
<div class="columns" style="display: flex;align-items: center;margin-top: 15px;"> |
|||
<div class="column" style="display: flex;align-items: baseline"> |
|||
<mat-label style="margin-right: 20px;"> |
|||
<strong class="tileHead">Coupon Type</strong> |
|||
</mat-label> |
|||
</div> |
|||
<div class="column"> |
|||
<mat-form-field appearance="fill" style="min-width: 200px;"> |
|||
<mat-select required> |
|||
<mat-option value="low">Freebie</mat-option> |
|||
<mat-option value="standard">Discount</mat-option> |
|||
<mat-option value="high">Proximity Freebie</mat-option> |
|||
<mat-option value="high">Proximity Discount</mat-option> |
|||
</mat-select> |
|||
</mat-form-field> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="columns" style="display: flex;align-items: center"> |
|||
<div class="column"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Coupon Condition</strong> |
|||
</mat-label> |
|||
</div> |
|||
<div class="column"> |
|||
<textarea name="" id="" cols="30" rows="5" style="border: 1px solid #cbd5e1;"></textarea> |
|||
</div> |
|||
</div> |
|||
<div class="columns" style="display: flex;align-items: center"> |
|||
<div class="column" style="display: flex;align-items: baseline"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Number Of Coupons</strong> |
|||
</mat-label> |
|||
</div> |
|||
<div class="column"> |
|||
<mat-form-field appearance="fill" style="min-width: 200px;"> |
|||
<input matInput style="margin-left:10px;" type="number"> |
|||
</mat-form-field> |
|||
</div> |
|||
|
|||
</div> |
|||
<div style="display: flex;align-items: baseline"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Percentage Off </strong> |
|||
</mat-label> |
|||
<mat-form-field appearance="fill" style="margin-right:10px;"> |
|||
<span matPrefix>From </span> |
|||
<input matInput type="number"> |
|||
<span matSuffix>% </span> |
|||
</mat-form-field> |
|||
<mat-form-field appearance="fill" style="margin-left:10px;"> |
|||
<span matPrefix>To </span> |
|||
<input matInput type="number"> |
|||
<span matSuffix>% </span> |
|||
</mat-form-field> |
|||
</div> |
|||
<div style="display: flex;align-items: baseline"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Coupon Worth </strong> |
|||
</mat-label> |
|||
<mat-label> |
|||
From GH¢200 To GH¢800 |
|||
</mat-label> |
|||
</div> |
|||
<div style="display: flex;align-items: baseline;margin-top: 20px;"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Date Of Expiration </strong> |
|||
</mat-label> |
|||
<mat-form-field appearance="outline"> |
|||
<input matInput style="margin-left:10px;" type="date"> |
|||
</mat-form-field> |
|||
<mat-form-field appearance="fill"> |
|||
<span matPrefix>Time </span> |
|||
<input matInput type="time"> |
|||
</mat-form-field> |
|||
</div> |
|||
<div class="row" style="display: flex;justify-content:space-around;width:100%;"> |
|||
<button style="background-color: blue;color:white;margin-right:20px;" mat-button>Generate Coupons</button> |
|||
|
|||
</div> |
|||
</div> |
|||
</mat-dialog-content> |
@ -0,0 +1,11 @@ |
|||
.columns { |
|||
display: flex; |
|||
flex-direction: row; |
|||
flex-wrap: wrap; |
|||
width: 100%; |
|||
} |
|||
|
|||
.column { |
|||
flex: 50%; |
|||
font-size: medium; |
|||
} |
@ -0,0 +1,23 @@ |
|||
import { Component, Inject, OnInit } from '@angular/core'; |
|||
import { MatDialog, MAT_DIALOG_DATA } from '@angular/material/dialog'; |
|||
import { BusinessLookUpComponent } from '../BusinessLookUp/business-look-up.component'; |
|||
|
|||
@Component({ |
|||
selector: 'admin-coupon-dialog', |
|||
templateUrl: './admin-coupon-dialog.component.html', |
|||
styleUrls: ['./admin-coupon-dialog.component.scss'] |
|||
}) |
|||
export class AdminCouponDialogComponent implements OnInit { |
|||
|
|||
constructor(@Inject(MAT_DIALOG_DATA) public data: { product: any }, public dialog: MatDialog,) { } |
|||
|
|||
ngOnInit(): void { |
|||
} |
|||
lookupBusiness() { |
|||
const dialogRef = this.dialog.open(BusinessLookUpComponent, { |
|||
disableClose: true, |
|||
hasBackdrop: true, |
|||
|
|||
}); |
|||
} |
|||
} |
@ -0,0 +1,93 @@ |
|||
<div class="row" style="display: flex;justify-content:end;margin-bottom: 20px;"> |
|||
<button mat-button [mat-dialog-close]="true" cdkFocusInitial>x</button> |
|||
</div> |
|||
<mat-dialog-content class="mat-typography"> |
|||
<div class="flex flex-shrink-0 items-center mt-6 sm:mt-0 sm:ml-4 justify-center"> |
|||
<!-- Search --> |
|||
<mat-form-field class="teso-mat-dense teso-mat-no-subscript teso-mat-rounded min-w-64"> |
|||
<mat-icon class="icon-size-5" matPrefix [svgIcon]="'heroicons_solid:search'"></mat-icon> |
|||
<input matInput [autocomplete]="'off'" [placeholder]="'Enter Business Name or email here'"> |
|||
</mat-form-field> |
|||
<button class="ml-3" mat-flat-button [color]="'primary'" style="margin-left: 10px;"> |
|||
<mat-icon class="icon-size-5" [svgIcon]="'heroicons_solid:search'"></mat-icon> |
|||
<span class="ml-2">Search</span> |
|||
</button> |
|||
</div> |
|||
<div class="flex flex-shrink-0 items-center justify-center" style="margin-top: 10px !important;"> |
|||
<a href="javascript:void(0)" |
|||
style="color: #1890ff;text-decoration: none;background-color: transparent;outline: 0;cursor: pointer;">Target |
|||
Business not registered on teso ?</a> |
|||
</div> |
|||
<table class="w-full bg-transparent" mat-table matSort [dataSource]="typesDataSource" [trackBy]="trackByFn" |
|||
#typesTable> |
|||
<!-- Transaction ID --> |
|||
<ng-container matColumnDef="transactionId"> |
|||
<th mat-header-cell mat-sort-header *matHeaderCellDef> |
|||
Business |
|||
</th> |
|||
<td mat-cell *matCellDef="let transaction" style="display: flex;padding:10px;"> |
|||
<div id="circle"> |
|||
<div> |
|||
<span>{{transaction.name.substring(0,2).toUpperCase()}}</span> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="flex flex-col"> |
|||
<span class="pr-6 font-medium text-sm text-secondary whitespace-nowrap"> |
|||
{{transaction.name}} |
|||
</span> |
|||
|
|||
<span class="pr-6 font-small text-sm text-secondary whitespace-nowrap"> |
|||
{{transaction.email}} |
|||
</span> |
|||
</div> |
|||
</td> |
|||
</ng-container> |
|||
|
|||
<!-- Request Name --> |
|||
<ng-container matColumnDef="name"> |
|||
<th mat-header-cell mat-sort-header *matHeaderCellDef> |
|||
Contact |
|||
</th> |
|||
<td mat-cell *matCellDef="let transaction"> |
|||
<span class="pr-6 whitespace-wrap"> |
|||
{{transaction.phone}} |
|||
</span> |
|||
</td> |
|||
</ng-container> |
|||
<ng-container matColumnDef="members"> |
|||
<th mat-header-cell mat-sort-header *matHeaderCellDef> |
|||
Address |
|||
</th> |
|||
<td mat-cell *matCellDef="let transaction"> |
|||
<span class="pr-6 whitespace-wrap"> |
|||
AK-151-0000 |
|||
</span> |
|||
</td> |
|||
</ng-container> |
|||
<!-- Amount --> |
|||
<ng-container matColumnDef="actions"> |
|||
<th mat-header-cell mat-sort-header *matHeaderCellDef> |
|||
Actions |
|||
</th> |
|||
<td mat-cell *matCellDef="let transaction"> |
|||
<div style="display: flex;"> |
|||
<button class="sm:inline-flex" mat-flat-button [color]="'primary'"> |
|||
Select |
|||
</button> |
|||
</div> |
|||
</td> |
|||
</ng-container> |
|||
<!-- Footer --> |
|||
<ng-container matColumnDef="recentOrdersTableFooter"> |
|||
<td class="py-6 px-0 border-0" mat-footer-cell *matFooterCellDef colspan="6"> |
|||
<mat-paginator style="position:sticky;bottom: 0;width: 100%;" [pageSize]="20" |
|||
[pageSizeOptions]="[10, 20, 25,50, 100]" [showFirstLastButtons]="true"></mat-paginator> |
|||
</td> |
|||
</ng-container> |
|||
|
|||
<tr mat-header-row *matHeaderRowDef="typesTableColumns"></tr> |
|||
<tr class="users-row h-14" mat-row *matRowDef="let row; columns: typesTableColumns;"></tr> |
|||
<tr class="h-16 border-0" mat-footer-row *matFooterRowDef="['recentOrdersTableFooter']"></tr> |
|||
</table> |
|||
</mat-dialog-content> |
@ -0,0 +1,19 @@ |
|||
.users-row { |
|||
cursor: pointer; |
|||
} |
|||
|
|||
#circle { |
|||
background: #00a4be; |
|||
width: 45px; |
|||
height: 45px; |
|||
border-radius: 64px; |
|||
color: #003445; |
|||
font-weight: bold; |
|||
text-align: center; |
|||
justify-content: center; |
|||
display: flex; |
|||
align-content: center; |
|||
align-items: center; |
|||
font-size: initial; |
|||
margin-right: 15px; |
|||
} |
@ -1,20 +1,20 @@ |
|||
import { ComponentFixture, TestBed } from '@angular/core/testing'; |
|||
|
|||
import { NewProductComponent } from './new-product.component'; |
|||
import { BusinessLookUpComponent } from './business-look-up.component'; |
|||
|
|||
describe('NewProductComponent', () => { |
|||
let component: NewProductComponent; |
|||
let fixture: ComponentFixture<NewProductComponent>; |
|||
describe('BusinessLookUpComponent', () => { |
|||
let component: BusinessLookUpComponent; |
|||
let fixture: ComponentFixture<BusinessLookUpComponent>; |
|||
|
|||
beforeEach(async () => { |
|||
await TestBed.configureTestingModule({ |
|||
declarations: [ NewProductComponent ] |
|||
declarations: [ BusinessLookUpComponent ] |
|||
}) |
|||
.compileComponents(); |
|||
}); |
|||
|
|||
beforeEach(() => { |
|||
fixture = TestBed.createComponent(NewProductComponent); |
|||
fixture = TestBed.createComponent(BusinessLookUpComponent); |
|||
component = fixture.componentInstance; |
|||
fixture.detectChanges(); |
|||
}); |
@ -0,0 +1,121 @@ |
|||
import { Component, OnInit, ViewChild } from '@angular/core'; |
|||
import { FormControl } from '@angular/forms'; |
|||
import { MatSort } from '@angular/material/sort'; |
|||
import { MatTableDataSource } from '@angular/material/table'; |
|||
import { Subject } from 'rxjs'; |
|||
export const finance = { |
|||
types: [ |
|||
{ |
|||
id: '1b6fd296-bc6a-4d45-bf4f-e45519a58cf5', |
|||
transactionId: '528651571NT', |
|||
name: 'Morgan Page', |
|||
phone: "+233 244 419 000", |
|||
email:"business@bacware.com", |
|||
status: 'Active', |
|||
date: '2019-10-07T22:22:37.274Z' |
|||
}, |
|||
{ |
|||
id: '2dec6074-98bd-4623-9526-6480e4776569', |
|||
transactionId: '421436904YT', |
|||
name: 'Nita Hebert', |
|||
phone: "+233 244 419 000", |
|||
email:"business@bacware.com", |
|||
status: 'Active', |
|||
date: '2019-12-18T14:51:24.461Z' |
|||
}, |
|||
{ |
|||
id: 'ae7c065f-4197-4021-a799-7a221822ad1d', |
|||
transactionId: '685377421YT', |
|||
name: 'Marsha Chambers', |
|||
phone: "+233 244 419 000", |
|||
email:"business@bacware.com", |
|||
status: 'Active', |
|||
date: '2019-12-25T17:52:14.304Z' |
|||
}, |
|||
{ |
|||
id: '0c43dd40-74f6-49d5-848a-57a4a45772ab', |
|||
transactionId: '884960091RT', |
|||
name: 'Charmaine Jackson', |
|||
phone: "+233 244 419 000", |
|||
email:"business@bacware.com", |
|||
status: 'Active', |
|||
date: '2019-11-29T06:32:16.111Z' |
|||
}, |
|||
{ |
|||
id: 'e5c9f0ed-a64c-4bfe-a113-29f80b4e162c', |
|||
transactionId: '361402213NT', |
|||
name: 'Maura Carey', |
|||
phone: "+233 244 419 000", |
|||
email:"business@bacware.com", |
|||
status: 'Active', |
|||
date: '2019-11-24T12:13:23.064Z' |
|||
}, { |
|||
id: '1b6fd296-bc6a-4d45-bf4f-e45519a58cf5', |
|||
transactionId: '528651571NT', |
|||
name: 'Morgan Page', |
|||
phone: "+233 244 419 000", |
|||
email:"business@bacware.com", |
|||
status: 'Active', |
|||
date: '2019-10-07T22:22:37.274Z' |
|||
}, |
|||
{ |
|||
id: '2dec6074-98bd-4623-9526-6480e4776569', |
|||
transactionId: '421436904YT', |
|||
name: 'Nita Hebert', |
|||
phone: "+233 244 419 000", |
|||
email:"business@bacware.com", |
|||
status: 'Active', |
|||
date: '2019-12-18T14:51:24.461Z' |
|||
}, |
|||
{ |
|||
id: 'ae7c065f-4197-4021-a799-7a221822ad1d', |
|||
transactionId: '685377421YT', |
|||
name: 'Marsha Chambers', |
|||
phone: "+233 244 419 000", |
|||
email:"business@bacware.com", |
|||
status: 'Active', |
|||
date: '2019-12-25T17:52:14.304Z' |
|||
}, |
|||
{ |
|||
id: '0c43dd40-74f6-49d5-848a-57a4a45772ab', |
|||
transactionId: '884960091RT', |
|||
name: 'Charmaine Jackson', |
|||
phone: "+233 244 419 000", |
|||
email:"business@bacware.com", |
|||
status: 'Active', |
|||
date: '2019-11-29T06:32:16.111Z' |
|||
}, |
|||
{ |
|||
id: 'e5c9f0ed-a64c-4bfe-a113-29f80b4e162c', |
|||
transactionId: '361402213NT', |
|||
name: 'Maura Carey', |
|||
phone: "+233 244 419 000", |
|||
email:"business@bacware.com", |
|||
status: 'Active', |
|||
date: '2019-11-24T12:13:23.064Z' |
|||
}, |
|||
] |
|||
}; |
|||
@Component({ |
|||
selector: 'app-business-look-up', |
|||
templateUrl: './business-look-up.component.html', |
|||
styleUrls: ['./business-look-up.component.scss'] |
|||
}) |
|||
export class BusinessLookUpComponent implements OnInit { |
|||
@ViewChild('typesTable', { read: MatSort }) typesTableMatSort: MatSort; |
|||
searchInputControl: FormControl = new FormControl(); |
|||
data: any; |
|||
typesDataSource: MatTableDataSource<any> = new MatTableDataSource(); |
|||
typesTableColumns: string[] = ['transactionId', 'name', 'members', 'actions']; |
|||
htmlRequest: string; |
|||
transferType: string; |
|||
private _unsubscribeAll: Subject<any> = new Subject<any>(); |
|||
constructor() { } |
|||
|
|||
ngOnInit(): void { |
|||
this.typesDataSource.data = finance.types; |
|||
} |
|||
trackByFn(index: number, item: any): any { |
|||
return item.id || index; |
|||
} |
|||
} |
@ -0,0 +1,115 @@ |
|||
<div class="row" style="display: flex;justify-content:space-between"> |
|||
<div class="row" style="display: flex;justify-content:center;width: 100%;"> |
|||
<h2 mat-dialog-title style="text-align: center;">Coupons for {{data.product.name}}</h2> |
|||
</div> |
|||
<!-- <button mat-button mat-dialog-close>Cancel</button> --> |
|||
<button mat-button [mat-dialog-close]="true" cdkFocusInitial>x</button> |
|||
</div> |
|||
<mat-dialog-content class="mat-typography"> |
|||
<div class=" py-2 pl-3 pr-3 sm:py-4 md:pl-4 md:pr-6"> |
|||
<div class="columns" style="display: flex;align-items: center"> |
|||
<div class="column" style="display: flex;align-items: baseline"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Target Name </strong> |
|||
</mat-label> |
|||
</div> |
|||
<div class="column"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
Target Name |
|||
</mat-label> |
|||
</div> |
|||
</div> |
|||
<div class="columns" style="display: flex;align-items: center;margin-top: 15px;"> |
|||
<div class="column" style="display: flex;align-items: baseline"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Original Price </strong> |
|||
</mat-label> |
|||
</div> |
|||
<div class="column"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
GH¢200 |
|||
</mat-label> |
|||
</div> |
|||
</div> |
|||
<div class="columns" style="display: flex;align-items: center;margin-top: 15px;"> |
|||
<div class="column" style="display: flex;align-items: baseline"> |
|||
<mat-label style="margin-right: 20px;"> |
|||
<strong class="tileHead">Coupon Type</strong> |
|||
</mat-label> |
|||
</div> |
|||
<div class="column"> |
|||
<mat-form-field appearance="fill" style="min-width: 200px;"> |
|||
<mat-select required> |
|||
<mat-option value="low">Freebie</mat-option> |
|||
<mat-option value="standard">Discount</mat-option> |
|||
<mat-option value="high">Proximity Freebie</mat-option> |
|||
<mat-option value="high">Proximity Discount</mat-option> |
|||
</mat-select> |
|||
</mat-form-field> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="columns" style="display: flex;align-items: center"> |
|||
<div class="column"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Coupon Condition</strong> |
|||
</mat-label> |
|||
</div> |
|||
<div class="column"> |
|||
<textarea name="" id="" cols="30" rows="5" style="border: 1px solid #cbd5e1;"></textarea> |
|||
</div> |
|||
</div> |
|||
<div class="columns" style="display: flex;align-items: center"> |
|||
<div class="column" style="display: flex;align-items: baseline"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Number Of Coupons</strong> |
|||
</mat-label> |
|||
</div> |
|||
<div class="column"> |
|||
<mat-form-field appearance="fill" style="min-width: 200px;"> |
|||
<input matInput style="margin-left:10px;" type="number"> |
|||
</mat-form-field> |
|||
</div> |
|||
|
|||
</div> |
|||
<div style="display: flex;align-items: baseline"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Percentage Off </strong> |
|||
</mat-label> |
|||
<mat-form-field appearance="fill" style="margin-right:10px;"> |
|||
<span matPrefix>From </span> |
|||
<input matInput type="number"> |
|||
<span matSuffix>% </span> |
|||
</mat-form-field> |
|||
<mat-form-field appearance="fill" style="margin-left:10px;"> |
|||
<span matPrefix>To </span> |
|||
<input matInput type="number"> |
|||
<span matSuffix>% </span> |
|||
</mat-form-field> |
|||
</div> |
|||
<div style="display: flex;align-items: baseline"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Coupon Worth </strong> |
|||
</mat-label> |
|||
<mat-label> |
|||
From GH¢200 To GH¢800 |
|||
</mat-label> |
|||
</div> |
|||
<div style="display: flex;align-items: baseline;margin-top: 20px;"> |
|||
<mat-label style="margin-right: 48px;"> |
|||
<strong class="tileHead">Date Of Expiration </strong> |
|||
</mat-label> |
|||
<mat-form-field appearance="outline"> |
|||
<input matInput style="margin-left:10px;" type="date"> |
|||
</mat-form-field> |
|||
<mat-form-field appearance="fill"> |
|||
<span matPrefix>Time </span> |
|||
<input matInput type="time"> |
|||
</mat-form-field> |
|||
</div> |
|||
<div class="row" style="display: flex;justify-content:space-around;width:100%;"> |
|||
<button style="background-color: blue;color:white;margin-right:20px;" mat-button>Generate Coupons</button> |
|||
|
|||
</div> |
|||
</div> |
|||
</mat-dialog-content> |
@ -0,0 +1,11 @@ |
|||
.columns { |
|||
display: flex; |
|||
flex-direction: row; |
|||
flex-wrap: wrap; |
|||
width: 100%; |
|||
} |
|||
|
|||
.column { |
|||
flex: 50%; |
|||
font-size: medium; |
|||
} |
@ -0,0 +1,16 @@ |
|||
import { Component, Inject, OnInit } from '@angular/core'; |
|||
import { MAT_DIALOG_DATA } from '@angular/material/dialog'; |
|||
|
|||
@Component({ |
|||
selector: 'app-coupon-dialog', |
|||
templateUrl: './coupon-dialog.component.html', |
|||
styleUrls: ['./coupon-dialog.component.scss'] |
|||
}) |
|||
export class CouponDialogComponent implements OnInit { |
|||
|
|||
constructor(@Inject(MAT_DIALOG_DATA) public data: { product: any },) { } |
|||
|
|||
ngOnInit(): void { |
|||
} |
|||
|
|||
} |
@ -0,0 +1,78 @@ |
|||
.columns { |
|||
display: flex; |
|||
flex-direction: row; |
|||
flex-wrap: wrap; |
|||
width: 100%; |
|||
} |
|||
|
|||
.column { |
|||
flex: 50%; |
|||
font-size: medium; |
|||
} |
|||
|
|||
.tileHead { |
|||
font-size: 17px; |
|||
color: #003445; |
|||
font-family: Roboto, "Helvetica Neue", sans-serif; |
|||
line-height: 3rem; |
|||
} |
|||
|
|||
.ticketLine > a:hover { |
|||
color: cornflowerblue; |
|||
text-decoration: underline; |
|||
} |
|||
|
|||
.ticketLine > a { |
|||
color: cornflowerblue; |
|||
font-style: italic; |
|||
} |
|||
|
|||
::ng-deep { |
|||
@media screen and (min-width: 992px) { |
|||
.ql-container .ql-editor { |
|||
min-height: 160px; |
|||
max-height: 270px; |
|||
height: 270px; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.imageList { |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
} |
|||
|
|||
.imageHolder { |
|||
flex-grow: 1; |
|||
width: 22%; |
|||
max-width: 180px; |
|||
height: 180px; |
|||
margin: 10px; |
|||
border: 3px solid #003445; |
|||
padding: 5px; |
|||
position: relative; |
|||
} |
|||
.productImage{ |
|||
max-width: 130px; |
|||
margin: 10px; |
|||
} |
|||
.deleteelement { |
|||
position: absolute; |
|||
top: 5px; |
|||
right: 5px; |
|||
|
|||
} |
|||
|
|||
@media screen and (max-width: 992px) { |
|||
.imageHolder { |
|||
flex-grow: 1; |
|||
width: 22%; |
|||
max-width: 180px; |
|||
min-width: 180px; |
|||
height: 180px; |
|||
margin: 10px; |
|||
border: 3px solid #003445; |
|||
padding: 5px; |
|||
position: relative; |
|||
} |
|||
} |
@ -0,0 +1,78 @@ |
|||
.columns { |
|||
display: flex; |
|||
flex-direction: row; |
|||
flex-wrap: wrap; |
|||
width: 100%; |
|||
} |
|||
|
|||
.column { |
|||
flex: 50%; |
|||
font-size: medium; |
|||
} |
|||
|
|||
.tileHead { |
|||
font-size: 17px; |
|||
color: #003445; |
|||
font-family: Roboto, "Helvetica Neue", sans-serif; |
|||
line-height: 3rem; |
|||
} |
|||
|
|||
.ticketLine > a:hover { |
|||
color: cornflowerblue; |
|||
text-decoration: underline; |
|||
} |
|||
|
|||
.ticketLine > a { |
|||
color: cornflowerblue; |
|||
font-style: italic; |
|||
} |
|||
|
|||
::ng-deep { |
|||
@media screen and (min-width: 992px) { |
|||
.ql-container .ql-editor { |
|||
min-height: 160px; |
|||
max-height: 270px; |
|||
height: 270px; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.imageList { |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
} |
|||
|
|||
.imageHolder { |
|||
flex-grow: 1; |
|||
width: 22%; |
|||
max-width: 180px; |
|||
height: 180px; |
|||
margin: 10px; |
|||
border: 3px solid #003445; |
|||
padding: 5px; |
|||
position: relative; |
|||
} |
|||
.productImage{ |
|||
max-width: 130px; |
|||
margin: 10px; |
|||
} |
|||
.deleteelement { |
|||
position: absolute; |
|||
top: 5px; |
|||
right: 5px; |
|||
|
|||
} |
|||
|
|||
@media screen and (max-width: 992px) { |
|||
.imageHolder { |
|||
flex-grow: 1; |
|||
width: 22%; |
|||
max-width: 180px; |
|||
min-width: 180px; |
|||
height: 180px; |
|||
margin: 10px; |
|||
border: 3px solid #003445; |
|||
padding: 5px; |
|||
position: relative; |
|||
} |
|||
} |
@ -1,15 +1,133 @@ |
|||
import { Component, OnInit } from '@angular/core'; |
|||
import { Component, OnDestroy, OnInit } from '@angular/core'; |
|||
import { tesoMediaWatcherService } from '@teso/services/media-watcher'; |
|||
import { ProductUpload } from 'app/models/generalModel'; |
|||
import { Subject } from 'rxjs'; |
|||
import { takeUntil } from 'rxjs/operators'; |
|||
import { ConfirmBoxEvokeService } from '@costlydeveloper/ngx-awesome-popup'; |
|||
const modules = { |
|||
toolbar: [ |
|||
['bold', 'italic', 'underline', 'strike'], |
|||
['blockquote', 'code-block'], |
|||
|
|||
[{ 'header': 1 }, { 'header': 2 }], |
|||
[{ 'list': 'ordered' }, { 'list': 'bullet' }], |
|||
[{ 'script': 'sub' }, { 'script': 'super' }], |
|||
[{ 'indent': '-1' }, { 'indent': '+1' }], |
|||
[{ 'direction': 'rtl' }], |
|||
|
|||
[{ 'size': ['small', false, 'large', 'huge'] }], |
|||
[{ 'header': [1, 2, 3, 4, 5, 6, false] }], |
|||
|
|||
[{ 'color': [] }, { 'background': [] }], |
|||
[{ 'font': [] }], |
|||
[{ 'align': [] }], |
|||
|
|||
['clean'], |
|||
|
|||
|
|||
] |
|||
}; |
|||
|
|||
@Component({ |
|||
selector: 'app-new-product', |
|||
templateUrl: './new-product.component.html', |
|||
styleUrls: ['./new-product.component.scss'] |
|||
}) |
|||
export class NewProductComponent implements OnInit { |
|||
export class NewProductComponent implements OnInit, OnDestroy { |
|||
|
|||
constructor() { } |
|||
htmlRequest: string; |
|||
transferType: string; |
|||
placeHolder: string = ""; |
|||
selected: any; |
|||
isScreenSmall: boolean; |
|||
productImages: ProductUpload[] = []; |
|||
private _unsubscribeAll: Subject<any> = new Subject<any>(); |
|||
constructor(private _tesoMediaWatcherService: tesoMediaWatcherService, private confirmBoxEvokeService: ConfirmBoxEvokeService) { } |
|||
|
|||
ngOnInit(): void { |
|||
this._tesoMediaWatcherService.onMediaChange$ |
|||
.pipe(takeUntil(this._unsubscribeAll)) |
|||
.subscribe(({ matchingAliases }) => { |
|||
|
|||
// Check if the screen is small
|
|||
this.isScreenSmall = !matchingAliases.includes('md'); |
|||
}); |
|||
} |
|||
quillConfig = modules; |
|||
items = [ |
|||
{ id: 1, name: 'Python' }, |
|||
{ id: 2, name: 'Node Js' }, |
|||
{ id: 3, name: 'Java' }, |
|||
{ id: 4, name: 'PHP', disabled: true }, |
|||
{ id: 5, name: 'Django' }, |
|||
{ id: 6, name: 'Angular' }, |
|||
{ id: 7, name: 'Vue' }, |
|||
{ id: 8, name: 'ReactJs' }, |
|||
]; |
|||
ngOnDestroy(): void { |
|||
// Unsubscribe from all subscriptions
|
|||
this._unsubscribeAll.next(); |
|||
this._unsubscribeAll.complete(); |
|||
} |
|||
|
|||
// readURL(event: Event): void {
|
|||
// if (event.target.files && event.target.files[0]) {
|
|||
// const file = event.target.files[0];
|
|||
|
|||
// const reader = new FileReader();
|
|||
// reader.onload = e => this.imageSrc = reader.result;
|
|||
|
|||
// reader.readAsDataURL(file);
|
|||
// }
|
|||
// }
|
|||
onFileSelected(event) { |
|||
|
|||
const file: File = event.target.files[0]; |
|||
if (file.type.includes("image")) { |
|||
console.log(file) |
|||
if (this.productImages.length == 0) { |
|||
var productImage: ProductUpload = { |
|||
file: file, |
|||
highlight: true, |
|||
imageSRC: "", |
|||
}; |
|||
let reader = new FileReader(); |
|||
reader.onload = (event: any) => { |
|||
productImage.imageSRC = event.target.result; |
|||
} |
|||
reader.readAsDataURL(file); |
|||
|
|||
this.productImages.push(productImage); |
|||
|
|||
} else { |
|||
var productImage: ProductUpload = { |
|||
file: file, |
|||
highlight: false, |
|||
imageSRC: "", |
|||
}; |
|||
|
|||
let reader = new FileReader(); |
|||
reader.onload = (event: any) => { |
|||
productImage.imageSRC = event.target.result; |
|||
} |
|||
reader.readAsDataURL(file); |
|||
|
|||
this.productImages.push(productImage); |
|||
} |
|||
} else { |
|||
this.confirmBoxEvokeService.danger("Incompatible File", "Only images can be added", "OK").subscribe(); |
|||
} |
|||
} |
|||
|
|||
removeImage(item: ProductUpload) { |
|||
this.productImages = this.productImages.filter((e) => e != item); |
|||
} |
|||
|
|||
submit() { |
|||
if (this.productImages.length == 0) { |
|||
this.confirmBoxEvokeService.warning("Add Product Images", "To add a new product, you must add at least one image to support it", "OK").subscribe(); |
|||
} else { |
|||
|
|||
} |
|||
} |
|||
} |
|||
|
@ -1,102 +1,153 @@ |
|||
import { Component, OnInit, ViewChild } from '@angular/core'; |
|||
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; |
|||
import { MatDialog } from '@angular/material/dialog'; |
|||
import { MatPaginator } from '@angular/material/paginator'; |
|||
import { MatSort } from '@angular/material/sort'; |
|||
import { Router } from '@angular/router'; |
|||
import { ConfirmBoxEvokeService } from '@costlydeveloper/ngx-awesome-popup'; |
|||
import { tesoMediaWatcherService } from '@teso/services/media-watcher'; |
|||
import { Subject } from 'rxjs'; |
|||
import { takeUntil } from 'rxjs/operators'; |
|||
import { AdminCouponDialogComponent } from '../AdminCouponDialog/admin-coupon-dialog.component'; |
|||
import { CouponDialogComponent } from '../CouponDialog/coupon-dialog.component'; |
|||
|
|||
@Component({ |
|||
selector: 'app-product-list', |
|||
templateUrl: './product-list.component.html', |
|||
styleUrls: ['./product-list.component.scss'] |
|||
}) |
|||
export class ProductListComponent implements OnInit { |
|||
data: { teamMembers: { id: string; avatar: string; name: string; email: string; phone: string; title: string; }[]; }; |
|||
export class ProductListComponent implements OnInit, OnDestroy { |
|||
data: { teamproducts: { id: string; image: string; name: string; email: string; phone: string; title: string; }[]; }; |
|||
@ViewChild(MatPaginator) private _paginator: MatPaginator; |
|||
@ViewChild(MatSort) private _sort: MatSort; |
|||
constructor(private router: Router,) { |
|||
isScreenSmall: boolean; |
|||
private _unsubscribeAll: Subject<any> = new Subject<any>(); |
|||
constructor(private router: Router, private _tesoMediaWatcherService: tesoMediaWatcherService, |
|||
public dialog: MatDialog, private confirmBoxEvokeService: ConfirmBoxEvokeService) { } |
|||
|
|||
ngOnDestroy(): void { |
|||
// Unsubscribe from all subscriptions
|
|||
this._unsubscribeAll.next(); |
|||
this._unsubscribeAll.complete(); |
|||
} |
|||
|
|||
ngOnInit(): void { |
|||
// Subscribe to media changes
|
|||
this._tesoMediaWatcherService.onMediaChange$ |
|||
.pipe(takeUntil(this._unsubscribeAll)) |
|||
.subscribe(({ matchingAliases }) => { |
|||
|
|||
// Check if the screen is small
|
|||
this.isScreenSmall = !matchingAliases.includes('md'); |
|||
}); |
|||
this.data = { |
|||
teamMembers : [ |
|||
teamproducts: [ |
|||
{ |
|||
id : '2bfa2be5-7688-48d5-b5ac-dc0d9ac97f14', |
|||
avatar: 'assets/images/brands/bagset.png', |
|||
name : 'Nadia Mcknight', |
|||
email : 'nadiamcknight@mail.com', |
|||
phone : '+1-943-511-2203', |
|||
title : 'Project Director' |
|||
id: '2bfa2be5-7688-48d5-b5ac-dc0d9ac97f14', |
|||
image: 'assets/images/brands/bagset.png', |
|||
name: 'Nadia Mcknight', |
|||
email: 'nadiamcknight@mail.com', |
|||
phone: '+1-943-511-2203', |
|||
title: 'Project Director' |
|||
}, |
|||
{ |
|||
id : '77a4383b-b5a5-4943-bc46-04c3431d1566', |
|||
avatar: 'assets/images/brands/bagset.png', |
|||
name : 'Best Blackburn', |
|||
email : 'blackburn.best@beadzza.me', |
|||
phone : '+1-814-498-3701', |
|||
title : 'Senior Developer' |
|||
id: '77a4383b-b5a5-4943-bc46-04c3431d1566', |
|||
image: 'assets/images/brands/bagset.png', |
|||
name: 'Best Blackburn', |
|||
email: 'blackburn.best@beadzza.me', |
|||
phone: '+1-814-498-3701', |
|||
title: 'Senior Developer' |
|||
}, |
|||
{ |
|||
id : '8bb0f597-673a-47ca-8c77-2f83219cb9af', |
|||
avatar: 'assets/images/brands/bagset.png', |
|||
name : 'Duncan Carver', |
|||
email : 'duncancarver@mail.info', |
|||
phone : '+1-968-547-2111', |
|||
title : 'Senior Developer' |
|||
id: '8bb0f597-673a-47ca-8c77-2f83219cb9af', |
|||
image: 'assets/images/brands/bagset.png', |
|||
name: 'Duncan Carver', |
|||
email: 'duncancarver@mail.info', |
|||
phone: '+1-968-547-2111', |
|||
title: 'Senior Developer' |
|||
}, |
|||
{ |
|||
id : 'c318e31f-1d74-49c5-8dae-2bc5805e2fdb', |
|||
avatar: 'assets/images/brands/bagset.png', |
|||
name : 'Martin Richards', |
|||
email : 'martinrichards@mail.biz', |
|||
phone : '+1-902-500-2668', |
|||
title : 'Junior Developer' |
|||
id: 'c318e31f-1d74-49c5-8dae-2bc5805e2fdb', |
|||
image: 'assets/images/brands/bagset.png', |
|||
name: 'Martin Richards', |
|||
email: 'martinrichards@mail.biz', |
|||
phone: '+1-902-500-2668', |
|||
title: 'Junior Developer' |
|||
}, |
|||
{ |
|||
id : '0a8bc517-631a-4a93-aacc-000fa2e8294c', |
|||
avatar: 'assets/images/brands/bagset.png', |
|||
name : 'Candice Munoz', |
|||
email : 'candicemunoz@mail.co.uk', |
|||
phone : '+1-838-562-2769', |
|||
title : 'Lead Designer' |
|||
id: '0a8bc517-631a-4a93-aacc-000fa2e8294c', |
|||
image: 'assets/images/brands/bagset.png', |
|||
name: 'Candice Munoz', |
|||
email: 'candicemunoz@mail.co.uk', |
|||
phone: '+1-838-562-2769', |
|||
title: 'Lead Designer' |
|||
}, |
|||
{ |
|||
id : 'a4c9945a-757b-40b0-8942-d20e0543cabd', |
|||
avatar: 'assets/images/brands/bagset.png', |
|||
name : 'Vickie Mosley', |
|||
email : 'vickiemosley@mail.net', |
|||
phone : '+1-939-555-3054', |
|||
title : 'Designer' |
|||
id: 'a4c9945a-757b-40b0-8942-d20e0543cabd', |
|||
image: 'assets/images/brands/bagset.png', |
|||
name: 'Vickie Mosley', |
|||
email: 'vickiemosley@mail.net', |
|||
phone: '+1-939-555-3054', |
|||
title: 'Designer' |
|||
}, |
|||
{ |
|||
id : 'b8258ccf-48b5-46a2-9c95-e0bd7580c645', |
|||
avatar: 'assets/images/brands/bagset.png', |
|||
name : 'Tina Harris', |
|||
email : 'tinaharris@mail.ca', |
|||
phone : '+1-933-464-2431', |
|||
title : 'Designer' |
|||
id: 'b8258ccf-48b5-46a2-9c95-e0bd7580c645', |
|||
image: 'assets/images/brands/bagset.png', |
|||
name: 'Tina Harris', |
|||
email: 'tinaharris@mail.ca', |
|||
phone: '+1-933-464-2431', |
|||
title: 'Designer' |
|||
}, |
|||
{ |
|||
id : 'f004ea79-98fc-436c-9ba5-6cfe32fe583d', |
|||
avatar: 'assets/images/brands/bagset.png', |
|||
name : 'Holt Manning', |
|||
email : 'holtmanning@mail.org', |
|||
phone : '+1-822-531-2600', |
|||
title : 'Marketing Manager' |
|||
id: 'f004ea79-98fc-436c-9ba5-6cfe32fe583d', |
|||
image: 'assets/images/brands/bagset.png', |
|||
name: 'Holt Manning', |
|||
email: 'holtmanning@mail.org', |
|||
phone: '+1-822-531-2600', |
|||
title: 'Marketing Manager' |
|||
}, |
|||
{ |
|||
id : '8b69fe2d-d7cc-4a3d-983d-559173e37d37', |
|||
avatar: 'assets/images/brands/bagset.png', |
|||
name : 'Misty Ramsey', |
|||
email : 'mistyramsey@mail.us', |
|||
phone : '+1-990-457-2106', |
|||
title : 'Consultant' |
|||
id: '8b69fe2d-d7cc-4a3d-983d-559173e37d37', |
|||
image: 'assets/images/brands/bagset.png', |
|||
name: 'Misty Ramsey', |
|||
email: 'mistyramsey@mail.us', |
|||
phone: '+1-990-457-2106', |
|||
title: 'Consultant' |
|||
} |
|||
] |
|||
] |
|||
} |
|||
} |
|||
createProduct() { |
|||
this.router.navigate(['products/create-product']); |
|||
} |
|||
editProduct(productID:any) { |
|||
this.router.navigate(['products/'+productID]); |
|||
editProduct(productID: any) { |
|||
this.router.navigate(['products/' + productID]); |
|||
} |
|||
generateCoupon(product: any) { |
|||
if (!true) { |
|||
const dialogRef = this.dialog.open(CouponDialogComponent, { |
|||
disableClose: true, |
|||
hasBackdrop: true, |
|||
data: { product: product }, |
|||
|
|||
}); |
|||
} else { |
|||
const dialogRef = this.dialog.open(AdminCouponDialogComponent, { |
|||
disableClose: true, |
|||
hasBackdrop: true, |
|||
data: { product: product }, |
|||
|
|||
}); |
|||
} |
|||
} |
|||
deleteProduct(product: any) { |
|||
this.confirmBoxEvokeService.danger("Delete Product", |
|||
"Are you sure you would like to delete this product from your inventory ?", |
|||
"Yes", "No") |
|||
.subscribe((response: any) => { |
|||
console.log(response) |
|||
if (response.clickedButtonID === "yes") { |
|||
this.data.teamproducts = this.data.teamproducts.filter((e) => e == product); |
|||
} |
|||
}); |
|||
} |
|||
} |
@ -1,25 +0,0 @@ |
|||
import { ComponentFixture, TestBed } from '@angular/core/testing'; |
|||
|
|||
import { ProductsComponent } from './products.component'; |
|||
|
|||
describe('ProductsComponent', () => { |
|||
let component: ProductsComponent; |
|||
let fixture: ComponentFixture<ProductsComponent>; |
|||
|
|||
beforeEach(async () => { |
|||
await TestBed.configureTestingModule({ |
|||
declarations: [ ProductsComponent ] |
|||
}) |
|||
.compileComponents(); |
|||
}); |
|||
|
|||
beforeEach(() => { |
|||
fixture = TestBed.createComponent(ProductsComponent); |
|||
component = fixture.componentInstance; |
|||
fixture.detectChanges(); |
|||
}); |
|||
|
|||
it('should create', () => { |
|||
expect(component).toBeTruthy(); |
|||
}); |
|||
}); |
@ -1,99 +1,105 @@ |
|||
<div class="flex flex-col sm:flex-row items-center md:items-start sm:justify-center md:justify-start flex-auto min-w-0"> |
|||
<div class="md:flex md:items-center md:justify-end w-full sm:w-auto md:h-full md:w-1/2 py-8 px-4 sm:p-12 md:p-16 sm:rounded-2xl md:rounded-none sm:shadow md:shadow-none sm:bg-card"> |
|||
<div *ngIf="isScreenSmall" |
|||
class="md:flex md:items-center md:justify-end w-full sm:w-auto md:h-full md:w-1/2 py-8 px-4 sm:p-12 md:p-16 sm:rounded-2xl md:rounded-none sm:shadow md:shadow-none sm:bg-card"> |
|||
<div class="w-full max-w-80 sm:w-80 mx-auto sm:mx-0"> |
|||
<!-- Logo --> |
|||
<div class="w-20"> |
|||
<img src="assets/images/logo.png"> |
|||
</div> |
|||
<div class="w-full sm:w-auto py-8 px-4 sm:p-12 sm:rounded-2xl sm:shadow sm:bg-card"> |
|||
<!-- Logo --> |
|||
<div class="w-20"> |
|||
<img src="assets/images/logo.png"> |
|||
</div> |
|||
|
|||
<!-- Title --> |
|||
<div class="mt-8 text-4xl font-extrabold tracking-tight leading-tight">Sign in</div> |
|||
<div class="flex items-baseline mt-0.5 font-medium"> |
|||
<div>Don't have an account?</div> |
|||
<a class="ml-1 text-primary-500 hover:underline" [routerLink]="['/sign-up']">Sign up |
|||
</a> |
|||
</div> |
|||
<!-- Title --> |
|||
<div class="mt-8 text-4xl font-extrabold tracking-tight leading-tight">Sign in</div> |
|||
<div class="flex items-baseline mt-0.5 font-medium"> |
|||
<div>Enter phone number of business</div> |
|||
</div> |
|||
|
|||
<!-- Alert --> |
|||
<teso-alert class="mt-8 -mb-4" *ngIf="showAlert" [appearance]="'outline'" [showIcon]="false" [type]="alert.type" [@shake]="alert.type === 'error'"> |
|||
{{alert.message}} |
|||
</teso-alert> |
|||
<!-- Alert --> |
|||
<teso-alert class="mt-8 -mb-4" *ngIf="showAlert" [appearance]="'outline'" [showIcon]="false" |
|||
[type]="alert.type" [@shake]="alert.type === 'error'"> |
|||
{{alert.message}} |
|||
</teso-alert> |
|||
|
|||
<!-- Sign in form --> |
|||
<form class="mt-8" [formGroup]="signInForm" #signInNgForm="ngForm"> |
|||
<!-- Sign in form --> |
|||
|
|||
<!-- Email field --> |
|||
<mat-form-field class="w-full"> |
|||
<mat-label>Email address</mat-label> |
|||
<input id="email" matInput [formControlName]="'email'"> |
|||
<mat-error *ngIf="signInForm.get('email').hasError('required')"> |
|||
Email address is required |
|||
</mat-error> |
|||
<mat-error *ngIf="signInForm.get('email').hasError('email')"> |
|||
Please enter a valid email address |
|||
</mat-error> |
|||
</mat-form-field> |
|||
<mat-form-field appearance="outline"> |
|||
|
|||
<!-- Password field --> |
|||
<mat-form-field class="w-full"> |
|||
<mat-label>Password</mat-label> |
|||
<input id="password" matInput type="password" [formControlName]="'password'" #passwordField> |
|||
<button mat-icon-button type="button" (click)="passwordField.type === 'password' ? passwordField.type = 'text' : passwordField.type = 'password'" matSuffix> |
|||
<mat-icon |
|||
class="icon-size-5" |
|||
*ngIf="passwordField.type === 'password'" |
|||
[svgIcon]="'heroicons_solid:eye'"></mat-icon> |
|||
<mat-icon |
|||
class="icon-size-5" |
|||
*ngIf="passwordField.type === 'text'" |
|||
[svgIcon]="'heroicons_solid:eye-off'"></mat-icon> |
|||
</button> |
|||
<mat-error> |
|||
Password is required |
|||
</mat-error> |
|||
<ngx-mat-intl-tel-input [preferredCountries]="['gh', 'ng']" [onlyCountries]="['gh', 'ng']" |
|||
[enablePlaceholder]="true" [enableSearch]="false" name="phone"> |
|||
</ngx-mat-intl-tel-input> |
|||
<mat-hint>Standard call, message, or data rates may apply.</mat-hint> |
|||
</mat-form-field> |
|||
|
|||
<!-- Actions --> |
|||
<div class="inline-flex items-end justify-between w-full mt-1.5"> |
|||
<mat-checkbox [color]="'primary'" [formControlName]="'rememberMe'"> |
|||
<div class="inline-flex items-end justify-between w-full mt-3.5"> |
|||
<mat-checkbox [color]="'primary'"> |
|||
Remember me |
|||
</mat-checkbox> |
|||
<a class="text-md font-medium text-primary-500 hover:underline" [routerLink]="['/forgot-password']">Forgot password? |
|||
</a> |
|||
</div> |
|||
|
|||
<!-- Submit button --> |
|||
<button class="teso-mat-button-large w-full mt-6" mat-flat-button [color]="'primary'" [disabled]="signInForm.disabled" (click)="signIn()"> |
|||
<span *ngIf="!signInForm.disabled"> |
|||
<button class="teso-mat-button-large w-full mt-6" mat-flat-button [color]="'primary'" |
|||
(click)="signIn()"> |
|||
<span> |
|||
Sign in |
|||
</span> |
|||
<mat-progress-spinner |
|||
*ngIf="signInForm.disabled" |
|||
[diameter]="24" |
|||
[mode]="'indeterminate'"></mat-progress-spinner> |
|||
<!-- <mat-progress-spinner |
|||
*ngIf="signInForm.disabled" |
|||
[diameter]="24" |
|||
[mode]="'indeterminate'"></mat-progress-spinner> --> |
|||
</button> |
|||
</div> |
|||
|
|||
<!-- Separator --> |
|||
<div class="flex items-center mt-8"> |
|||
<div class="flex-auto mt-px border-t"></div> |
|||
<div class="mx-2 text-secondary">Or continue with</div> |
|||
<div class="flex-auto mt-px border-t"></div> |
|||
</div> |
|||
|
|||
</form> |
|||
</div> |
|||
</div> |
|||
<div id="welcomeBoard" class="relative hidden md:flex flex-auto items-center justify-center w-1/2 h-full p-16 lg:px-28 overflow-hidden bg-gray-800 dark:border-l"> |
|||
<div id="welcomeBoard" |
|||
class="relative hidden md:flex flex-auto items-center justify-center w-1/2 h-full p-5 lg:px-20 overflow-hidden bg-gray-800 dark:border-l"> |
|||
|
|||
<div class="z-10 relative w-full max-w-2xl"> |
|||
<div class="text-7xl font-bold leading-none text-gray-100 welcomeText"> |
|||
<div>Welcome to</div> |
|||
<div>our community</div> |
|||
</div> |
|||
<div class="mt-6 text-lg tracking-tight leading-6 text-gray-400 welcomeText"> |
|||
Teso is an exclusive marketing company with specialized mechanics to boost sales and provide undoubtedly the best of services and user experiences to it’s users. |
|||
</div> |
|||
<div class="w-full max-w-80 sm:w-80 mx-auto sm:mx-0"> |
|||
<div class="w-full sm:w-auto py-5 px-4 sm:p-8 sm:rounded-2xl sm:shadow sm:bg-card" style="background-color: #484444c4 !important;color: white !important;"> |
|||
<!-- Logo --> |
|||
<div class="w-30" style="width: 100%;justify-content: center;display: flex;"> |
|||
<img src="assets/images/logo.png"> |
|||
</div> |
|||
|
|||
<!-- Title --> |
|||
<div class="mt-8 text-4xl font-extrabold tracking-tight leading-tight">Sign in</div> |
|||
<div class="flex items-baseline mt-0.5 font-medium"> |
|||
<div>Enter phone number of business</div> |
|||
</div> |
|||
|
|||
<!-- Alert --> |
|||
<teso-alert class="mt-8 -mb-4" *ngIf="showAlert" [appearance]="'outline'" [showIcon]="false" |
|||
[type]="alert.type" [@shake]="alert.type === 'error'"> |
|||
{{alert.message}} |
|||
</teso-alert> |
|||
|
|||
<!-- Sign in form --> |
|||
|
|||
<mat-form-field appearance="outline"> |
|||
<ngx-mat-intl-tel-input [preferredCountries]="['gh', 'ng']" [onlyCountries]="['gh', 'ng']" |
|||
[enablePlaceholder]="true" [enableSearch]="false" name="phone"> |
|||
</ngx-mat-intl-tel-input> |
|||
<mat-hint style="color: white !important;">Standard call, message, or data rates may apply.</mat-hint> |
|||
</mat-form-field> |
|||
<!-- Actions --> |
|||
<div class="inline-flex items-end justify-between w-full mt-3.5"> |
|||
<mat-checkbox [color]="'primary'"> |
|||
Remember me |
|||
</mat-checkbox> |
|||
</div> |
|||
|
|||
<!-- Submit button --> |
|||
<button class="teso-mat-button-large w-full mt-6" mat-flat-button [color]="'primary'" |
|||
(click)="signIn()"> |
|||
<span> |
|||
Sign in |
|||
</span> |
|||
<!-- <mat-progress-spinner |
|||
*ngIf="signInForm.disabled" |
|||
[diameter]="24" |
|||
[mode]="'indeterminate'"></mat-progress-spinner> --> |
|||
</button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
@ -0,0 +1,16 @@ |
|||
import { Pipe, PipeTransform } from "@angular/core"; |
|||
import { DomSanitizer, SafeUrl } from "@angular/platform-browser"; |
|||
|
|||
@Pipe({ |
|||
name: 'sanitizeUrl' |
|||
}) |
|||
export class SanitizerUrlPipe implements PipeTransform { |
|||
|
|||
constructor( |
|||
private sanitize: DomSanitizer |
|||
) { } |
|||
|
|||
transform(value: string): SafeUrl { |
|||
return this.sanitize.bypassSecurityTrustUrl(value); |
|||
} |
|||
} |
@ -1,84 +0,0 @@ |
|||
body teso-splash-screen { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
background-color: #111827; |
|||
color: #F9FAFB; |
|||
z-index: 999999; |
|||
pointer-events: none; |
|||
opacity: 1; |
|||
visibility: visible; |
|||
transition: opacity 400ms cubic-bezier(0.4, 0, 0.2, 1); |
|||
} |
|||
|
|||
body teso-splash-screen img { |
|||
width: 120px; |
|||
max-width: 120px; |
|||
} |
|||
|
|||
body teso-splash-screen .spinner { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
margin-top: 40px; |
|||
width: 56px; |
|||
} |
|||
|
|||
body teso-splash-screen .spinner>div { |
|||
width: 12px; |
|||
height: 12px; |
|||
background-color: #1E96F7; |
|||
border-radius: 100%; |
|||
display: inline-block; |
|||
-webkit-animation: teso-bouncedelay 1s infinite ease-in-out both; |
|||
animation: teso-bouncedelay 1s infinite ease-in-out both; |
|||
} |
|||
|
|||
body teso-splash-screen .spinner .bounce1 { |
|||
-webkit-animation-delay: -0.32s; |
|||
animation-delay: -0.32s; |
|||
} |
|||
|
|||
body teso-splash-screen .spinner .bounce2 { |
|||
-webkit-animation-delay: -0.16s; |
|||
animation-delay: -0.16s; |
|||
} |
|||
|
|||
@-webkit-keyframes teso-bouncedelay { |
|||
0%, |
|||
80%, |
|||
100% { |
|||
-webkit-transform: scale(0) |
|||
} |
|||
40% { |
|||
-webkit-transform: scale(1.0) |
|||
} |
|||
} |
|||
|
|||
@keyframes teso-bouncedelay { |
|||
0%, |
|||
80%, |
|||
100% { |
|||
-webkit-transform: scale(0); |
|||
transform: scale(0); |
|||
} |
|||
40% { |
|||
-webkit-transform: scale(1.0); |
|||
transform: scale(1.0); |
|||
} |
|||
} |
|||
|
|||
body:not(.teso-splash-screen-hidden) { |
|||
overflow: hidden; |
|||
} |
|||
|
|||
body.teso-splash-screen-hidden teso-splash-screen { |
|||
visibility: hidden; |
|||
opacity: 0; |
|||
} |
Loading…
Reference in new issue