| @@ -7935,6 +7935,14 @@ | |||||
| "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", | "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", | ||||
| "dev": true | "dev": true | ||||
| }, | }, | ||||
| "ngx-drag-to-select": { | |||||
| "version": "3.1.1", | |||||
| "resolved": "https://registry.npmjs.org/ngx-drag-to-select/-/ngx-drag-to-select-3.1.1.tgz", | |||||
| "integrity": "sha512-QKkIEVbAxSswLZZrnoebB3iyhN2uY8eihxDtOIakDd/m5SnH/P0d36imXeaM7ZnaTc04XJIaptz4JkumMCBu2g==", | |||||
| "requires": { | |||||
| "tslib": "^1.9.0" | |||||
| } | |||||
| }, | |||||
| "nice-try": { | "nice-try": { | ||||
| "version": "1.0.5", | "version": "1.0.5", | ||||
| "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", | "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", | ||||
| @@ -21,6 +21,7 @@ | |||||
| "@angular/router": "~8.2.9", | "@angular/router": "~8.2.9", | ||||
| "ionicons": "^4.6.3", | "ionicons": "^4.6.3", | ||||
| "moment": "^2.24.0", | "moment": "^2.24.0", | ||||
| "ngx-drag-to-select": "^3.1.1", | |||||
| "rxjs": "~6.4.0", | "rxjs": "~6.4.0", | ||||
| "tslib": "^1.10.0", | "tslib": "^1.10.0", | ||||
| "zone.js": "~0.9.1" | "zone.js": "~0.9.1" | ||||
| @@ -1,5 +1,6 @@ | |||||
| import { BrowserModule } from '@angular/platform-browser'; | import { BrowserModule } from '@angular/platform-browser'; | ||||
| import { NgModule } from '@angular/core'; | import { NgModule } from '@angular/core'; | ||||
| import { FormsModule } from '@angular/forms'; | |||||
| // Importing Routes | // Importing Routes | ||||
| import { AppRoutingModule } from './app-routing.module'; | import { AppRoutingModule } from './app-routing.module'; | ||||
| @@ -16,6 +17,9 @@ import { CustomSelectorComponent } from './custom-selector/custom-selector.compo | |||||
| import { FaqComponent } from './faq/faq.component'; | import { FaqComponent } from './faq/faq.component'; | ||||
| import { SupportComponent } from './support/support.component'; | import { SupportComponent } from './support/support.component'; | ||||
| // Plugin / Other packages | |||||
| import { DragToSelectModule } from 'ngx-drag-to-select'; | |||||
| @NgModule({ | @NgModule({ | ||||
| declarations: [ | declarations: [ | ||||
| AppComponent, | AppComponent, | ||||
| @@ -31,7 +35,9 @@ import { SupportComponent } from './support/support.component'; | |||||
| ], | ], | ||||
| imports: [ | imports: [ | ||||
| BrowserModule, | BrowserModule, | ||||
| AppRoutingModule | |||||
| AppRoutingModule, | |||||
| FormsModule, | |||||
| DragToSelectModule.forRoot() | |||||
| ], | ], | ||||
| providers: [], | providers: [], | ||||
| bootstrap: [AppComponent] | bootstrap: [AppComponent] | ||||
| @@ -1,4 +1,6 @@ | |||||
| .selector { | .selector { | ||||
| position: relative; | |||||
| .container { | .container { | ||||
| display: flex; | display: flex; | ||||
| width: 100%; | width: 100%; | ||||
| @@ -7,6 +9,7 @@ | |||||
| color: var(--brand-blue); | color: var(--brand-blue); | ||||
| align-items: center; | align-items: center; | ||||
| justify-content: space-between; | justify-content: space-between; | ||||
| position: relative; | |||||
| .selected-value { | .selected-value { | ||||
| font-weight: 500; | font-weight: 500; | ||||
| @@ -43,6 +46,9 @@ | |||||
| border-bottom-left-radius: 10px; | border-bottom-left-radius: 10px; | ||||
| border-bottom-right-radius: 10px; | border-bottom-right-radius: 10px; | ||||
| overflow: hidden; | overflow: hidden; | ||||
| position: absolute; | |||||
| left: 10%; | |||||
| top: 100%; | |||||
| } | } | ||||
| li { | li { | ||||
| @@ -13,13 +13,28 @@ | |||||
| <span> Sunday </span><span> Monday </span><span> Tuesday </span><span> Wednesday </span> | <span> Sunday </span><span> Monday </span><span> Tuesday </span><span> Wednesday </span> | ||||
| <span> Thursday </span><span> Friday </span><span> Saturday </span> | <span> Thursday </span><span> Friday </span><span> Saturday </span> | ||||
| </div> | </div> | ||||
| <div class="dates"> | |||||
| <span class="non-current-date" *ngFor="let preceedingDay of preceedingDays"> {{ preceedingDay }} </span> | |||||
| <span [ngClass]="{'current-date': currentDate === selectedMonthDay && currentMonth === selectedMonth, 'active' : selectedDate === selectedMonthDay }" *ngFor="let selectedMonthDay of selectedMonthDays" (click)="selectDay(selectedMonthDay)"> {{ selectedMonthDay }} | |||||
| <dts-select-container class="dates" [(selectedItems)]="selectedDatesForSchedule" (select)="selectDates($event)"> | |||||
| <span class="non-current-date" *ngFor="let preceedingDay of preceedingDays"> | |||||
| {{ preceedingDay }} | |||||
| </span> | </span> | ||||
| <span class="non-current-date" *ngFor="let succeedingDay of succeedingDays"> {{ succeedingDay }} </span> | |||||
| </div> | |||||
| <span [dtsSelectItem]="selectedMonthDay" [ngClass]="{'current-date': currentDate === selectedMonthDay && currentMonth === selectedMonth }" *ngFor="let selectedMonthDay of selectedMonthDays; let i = index;"> | |||||
| {{ selectedMonthDay }} | |||||
| </span> | |||||
| <span class="non-current-date" *ngFor="let succeedingDay of succeedingDays"> | |||||
| {{ succeedingDay }} | |||||
| </span> | |||||
| </dts-select-container> | |||||
| <p class="note"> | |||||
| <strong> Note: </strong> Hold CTRL and click on dates for multisection | |||||
| </p> | |||||
| </section> | </section> | ||||
| <button class="add-schedule-button" [ngClass]="{'active' : selectedDatesForSchedule.length > 0 }" | |||||
| (click)="showSchedulePopup = true"> | |||||
| <i class="icon ion-md-add"></i> | |||||
| </button> | |||||
| </div> | </div> | ||||
| <div class="schedule-list-holder"> | <div class="schedule-list-holder"> | ||||
| @@ -37,7 +52,7 @@ | |||||
| </div> | </div> | ||||
| <div class="dates"> | <div class="dates"> | ||||
| <span class="non-current-date" *ngFor="let preceedingDay of preceedingDays"> {{ preceedingDay }} </span> | <span class="non-current-date" *ngFor="let preceedingDay of preceedingDays"> {{ preceedingDay }} </span> | ||||
| <span [ngClass]="{'current-date': currentDate === selectedMonthDay && currentMonth === selectedMonth, 'active' : selectedDate === selectedMonthDay }" *ngFor="let selectedMonthDay of selectedMonthDays"> | |||||
| <span [ngClass]="{'current-date': currentDate === selectedMonthDay && currentMonth === selectedMonth }" *ngFor="let selectedMonthDay of selectedMonthDays"> | |||||
| {{ selectedMonthDay }} | {{ selectedMonthDay }} | ||||
| </span> | </span> | ||||
| <span class="non-current-date" *ngFor="let succeedingDay of succeedingDays"> | <span class="non-current-date" *ngFor="let succeedingDay of succeedingDays"> | ||||
| @@ -101,7 +116,49 @@ | |||||
| <p> Oct 29 2019 </p> | <p> Oct 29 2019 </p> | ||||
| </li> | </li> | ||||
| </ul> | </ul> | ||||
| </div> | </div> | ||||
| </div> | |||||
| <div class="overlay" [ngClass]="{'active' : showSchedulePopup }"> | |||||
| <section class="scheduling-popup"> | |||||
| <input type="text" placeholder="Schedule Title"> | |||||
| <ul> | |||||
| <li (click)="scheduleType = 'holiday'"> | |||||
| <button class="radio" [ngClass]="{'active' : scheduleType === 'holiday'}"></button> | |||||
| <label> Holiday </label> | |||||
| </li> | |||||
| <li (click)="scheduleType = 'event'"> | |||||
| <button class="radio" [ngClass]="{'active' : scheduleType === 'event'}"></button> <label> Event </label> | |||||
| </li> | |||||
| <li (click)="scheduleType = 'change time'"> | |||||
| <button class="radio" [ngClass]="{'active' : scheduleType === 'change time'}"></button> <label> Change Timings </label> | |||||
| </li> | |||||
| </ul> | |||||
| <div class="time-selector" *ngIf="scheduleType === 'change time'"> | |||||
| <div class="input-holder"> | |||||
| <input type="tel" maxlength="2" [(ngModel)]="scheduleFromTime.hour"> | |||||
| : | |||||
| <input type="tel" maxlength="2" [(ngModel)]="scheduleFromTime.min"> | |||||
| <button (click)="scheduleFromTime.isBeforeMidday = !scheduleFromTime.isBeforeMidday"> | |||||
| <span *ngIf="scheduleFromTime.isBeforeMidday"> AM </span> | |||||
| <span *ngIf="!scheduleFromTime.isBeforeMidday"> PM </span> | |||||
| </button> | |||||
| </div> | |||||
| <div class="input-holder"> | |||||
| <input type="tel" maxlength="2" [(ngModel)]="scheduleToTime.hour"> | |||||
| : | |||||
| <input type="tel" maxlength="2" [(ngModel)]="scheduleToTime.min"> | |||||
| <button (click)="scheduleToTime.isBeforeMidday = !scheduleToTime.isBeforeMidday"> | |||||
| <span *ngIf="scheduleToTime.isBeforeMidday"> AM </span> | |||||
| <span *ngIf="!scheduleToTime.isBeforeMidday"> PM </span> | |||||
| </button> | |||||
| </div> | |||||
| </div> | |||||
| <div class="action-buttons"> | |||||
| <button class="rect-button"> Submit </button> | |||||
| <button class="rect-button" (click)="showSchedulePopup = false"> Cancel </button> | |||||
| </div> | |||||
| </section> | |||||
| </div> | </div> | ||||
| @@ -8,12 +8,51 @@ | |||||
| .calendar-holder { | .calendar-holder { | ||||
| width: 65%; | width: 65%; | ||||
| margin-right: auto; | margin-right: auto; | ||||
| position: relative; | |||||
| height: calc(100vh - 70px); | |||||
| overflow: auto; | |||||
| .widget-heading-holder { | .widget-heading-holder { | ||||
| width: 100%; | width: 100%; | ||||
| } | } | ||||
| } | } | ||||
| .add-schedule-button { | |||||
| position: absolute; | |||||
| right: 30px; | |||||
| bottom: 50px; | |||||
| width: 50px; | |||||
| height: 50px; | |||||
| border-radius: 50%; | |||||
| background-color: var(--brand-blue); | |||||
| color: white; | |||||
| border: 0px; | |||||
| font-size: 20px; | |||||
| transform: scale(0); | |||||
| transition: transform 0.3s; | |||||
| &.active { | |||||
| transform: scale(1); | |||||
| animation: ripple-effect 1s linear; | |||||
| animation-iteration-count: 3; | |||||
| } | |||||
| } | |||||
| @keyframes ripple-effect { | |||||
| 0% { | |||||
| box-shadow: 0 0 0 10px rgba(black, 0.3); | |||||
| } | |||||
| 30% { | |||||
| box-shadow: 0 0 0 20px rgba(black, 0.2); | |||||
| } | |||||
| 60% { | |||||
| box-shadow: 0 0 0 30px rgba(black, 0.1); | |||||
| } | |||||
| 100% { | |||||
| box-shadow: 0 0 0 50px rgba(black, 0); | |||||
| } | |||||
| } | |||||
| .schedule-list-holder { | .schedule-list-holder { | ||||
| width: 30%; | width: 30%; | ||||
| background-color: white; | background-color: white; | ||||
| @@ -52,6 +91,14 @@ | |||||
| border-radius: 10px; | border-radius: 10px; | ||||
| margin-top: 30px; | margin-top: 30px; | ||||
| .note { | |||||
| font-size: 14px; | |||||
| color: var(--grey); | |||||
| font-style: italic; | |||||
| margin-top: 10px; | |||||
| letter-spacing: 1px; | |||||
| } | |||||
| .month { | .month { | ||||
| text-align: center; | text-align: center; | ||||
| padding: 5px 0 20px; | padding: 5px 0 20px; | ||||
| @@ -90,6 +137,12 @@ | |||||
| width: 100%; | width: 100%; | ||||
| flex-wrap: wrap; | flex-wrap: wrap; | ||||
| .dts-select-item.selected { | |||||
| background-color: var(--brand-blue); | |||||
| color: white; | |||||
| } | |||||
| span { | span { | ||||
| display: block; | display: block; | ||||
| cursor: pointer; | cursor: pointer; | ||||
| @@ -109,9 +162,6 @@ | |||||
| border-right: 0; | border-right: 0; | ||||
| } | } | ||||
| &:hover { | |||||
| background-color: #efefef; | |||||
| } | |||||
| &.current-date { | &.current-date { | ||||
| color: var(--brand-blue); | color: var(--brand-blue); | ||||
| @@ -128,11 +178,6 @@ | |||||
| } | } | ||||
| } | } | ||||
| &.active { | |||||
| background-color: var(--brand-blue); | |||||
| color: white; | |||||
| } | |||||
| &.non-current-date { | &.non-current-date { | ||||
| color: #cecece; | color: #cecece; | ||||
| } | } | ||||
| @@ -371,3 +416,135 @@ | |||||
| padding-left: 20px; | padding-left: 20px; | ||||
| } | } | ||||
| } | } | ||||
| .overlay { | |||||
| background-color: rgba(black, 0.2); | |||||
| position: fixed; | |||||
| left: 0; | |||||
| top: 0; | |||||
| width: 100%; | |||||
| height: 100%; | |||||
| z-index: 1; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| transition: opacity 0.3s; | |||||
| opacity: 0; | |||||
| transform: scale(0); | |||||
| &.active { | |||||
| transform: scale(1); | |||||
| opacity: 1; | |||||
| } | |||||
| } | |||||
| .scheduling-popup { | |||||
| background-color: white; | |||||
| box-shadow: 0px 0px 5px #cecece; | |||||
| border-radius: 10px; | |||||
| padding: 15px; | |||||
| width: 300px; | |||||
| input[type="text"] { | |||||
| border: 0px; | |||||
| border-bottom: 1px solid #efefef; | |||||
| font-size: 14px; | |||||
| letter-spacing: 1px; | |||||
| padding: 5px; | |||||
| font-weight: 500; | |||||
| color: var(--grey); | |||||
| width: 100%; | |||||
| &::placeholder { | |||||
| opacity: 0.5; | |||||
| } | |||||
| } | |||||
| ul { | |||||
| list-style: none; | |||||
| margin: 10px 0; | |||||
| } | |||||
| .radio { | |||||
| width: 15px; | |||||
| height: 15px; | |||||
| border-radius: 50%; | |||||
| background-color: white; | |||||
| margin-right: 10px; | |||||
| border: 1px solid var(--grey); | |||||
| position: relative; | |||||
| &.active { | |||||
| &::before { | |||||
| content: ""; | |||||
| position: absolute; | |||||
| display: block; | |||||
| width: 70%; | |||||
| height: 70%; | |||||
| left: 15%; | |||||
| top: 15%; | |||||
| border-radius: 50%; | |||||
| background-color: var(--brand-blue); | |||||
| } | |||||
| } | |||||
| } | |||||
| li { | |||||
| padding: 5px 0; | |||||
| display: flex; | |||||
| width: 100%; | |||||
| align-items: center; | |||||
| label { | |||||
| font-size: 15px; | |||||
| color: var(--grey); | |||||
| font-weight: 500; | |||||
| letter-spacing: 1px; | |||||
| } | |||||
| } | |||||
| .time-selector { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: space-between; | |||||
| width: 100%; | |||||
| margin-bottom: 15px; | |||||
| .input-holder { | |||||
| display: flex; | |||||
| width: 45%; | |||||
| border: 1px solid #efefef; | |||||
| align-items: center; | |||||
| color: var(--grey); | |||||
| input { | |||||
| width: calc((100% - 40px) / 2); | |||||
| height: 30px; | |||||
| font-size: 12px; | |||||
| border: 0px; | |||||
| text-align: center; | |||||
| color: var(--dark-grey); | |||||
| } | |||||
| button { | |||||
| width: 40px; | |||||
| align-self: stretch; | |||||
| border: 0px; | |||||
| background-color: var(#efefef); | |||||
| color: var(--dark-grey); | |||||
| } | |||||
| } | |||||
| } | |||||
| .action-buttons { | |||||
| display: flex; | |||||
| width: 100%; | |||||
| justify-content: space-between; | |||||
| button:last-child { | |||||
| background-color: white; | |||||
| color: var(--brand-blue); | |||||
| border: 1px solid var(--brand-blue); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -17,6 +17,20 @@ export class SchedulesComponent implements OnInit { | |||||
| succeedingDays: Array<number> = []; | succeedingDays: Array<number> = []; | ||||
| selectedMonthDays: Array<number> = []; | selectedMonthDays: Array<number> = []; | ||||
| selectedTab: string = 'holiday'; | selectedTab: string = 'holiday'; | ||||
| selectedDatePosition: any; | |||||
| selectedDatesForSchedule: Array<number> = []; | |||||
| showSchedulePopup: boolean = false; | |||||
| scheduleType: string = 'change time'; | |||||
| scheduleFromTime = { | |||||
| hour: '09', | |||||
| min: '30', | |||||
| isBeforeMidday: true | |||||
| }; | |||||
| scheduleToTime = { | |||||
| hour: '09', | |||||
| min: '00', | |||||
| isBeforeMidday: false | |||||
| }; | |||||
| constructor() { } | constructor() { } | ||||
| @@ -28,6 +42,10 @@ export class SchedulesComponent implements OnInit { | |||||
| this.renderCalendar(); | this.renderCalendar(); | ||||
| } | } | ||||
| selectDates(dates: Array<number>) { | |||||
| this.selectedDatesForSchedule = dates; | |||||
| } | |||||
| selectDay(selectedMonthDay: number) { | selectDay(selectedMonthDay: number) { | ||||
| this.selectedDate = selectedMonthDay; | this.selectedDate = selectedMonthDay; | ||||
| } | } | ||||
| @@ -6,7 +6,7 @@ import { Component, OnInit } from '@angular/core'; | |||||
| styleUrls: ['./widgets-holder.component.scss'] | styleUrls: ['./widgets-holder.component.scss'] | ||||
| }) | }) | ||||
| export class WidgetsHolderComponent implements OnInit { | export class WidgetsHolderComponent implements OnInit { | ||||
| selected_nav: string = 'schedule'; | |||||
| selected_nav: string = 'dashboard'; | |||||
| constructor() { } | constructor() { } | ||||