| @@ -1 +1,77 @@ | |||
| <p>calendar works!</p> | |||
| <div class="page"> | |||
| <header class="nav-header"> | |||
| <button class="close-button" (click)="back()"> | |||
| <svg-icon [applyClass]="true" class="icon" src="assets/custom-icons/close.svg"></svg-icon> | |||
| </button> | |||
| <button class="profile-button" [routerLink]="['/profile']"> | |||
| <img src="https://pbs.twimg.com/profile_images/3478244961/01ebfc40ecc194a2abc81e82ab877af4.jpeg"> | |||
| </button> | |||
| </header> | |||
| <h2 class="calendar-header"> | |||
| {{ selectedMonth }} {{ selectedYear }} | |||
| </h2> | |||
| <section class="mini-calendar"> | |||
| <div class="days"> | |||
| <span> S </span><span> M </span><span> T </span><span> W </span> | |||
| <span> T </span><span> F </span><span> S </span> | |||
| </div> | |||
| <div class="dates"> | |||
| <span class="non-current-date" *ngFor="let preceedingDay of preceedingDays"> {{ preceedingDay }} </span> | |||
| <span [ngClass]="{'current-date': currentDate === selectedMonthDay && currentMonth === selectedMonth && currentYear === selectedYear, | |||
| 'active': selectedDate === selectedMonthDay }" | |||
| *ngFor="let selectedMonthDay of selectedMonthDays" | |||
| (click)="selectedDate = selectedMonthDay"> | |||
| {{ selectedMonthDay }} | |||
| </span> | |||
| <span class="non-current-date" *ngFor="let succeedingDay of succeedingDays"> | |||
| {{ succeedingDay }} | |||
| </span> | |||
| </div> | |||
| </section> | |||
| <section class="schedule-details"> | |||
| <header> {{ selectedDate }}, {{ selectedMonth }} {{ selectedYear }} </header> | |||
| <ul> | |||
| <li class="attended"> | |||
| <svg-icon [applyClass]="true" class="icon checkmark" src="assets/custom-icons/checkmark.svg"></svg-icon> | |||
| <div class="content"> | |||
| <label> Mathematics class </label> | |||
| <p> 8:00 AM to 10:00 AM </p> | |||
| </div> | |||
| <button> Attended </button> | |||
| </li> | |||
| <li class="absent"> | |||
| <svg-icon [applyClass]="true" class="icon checkmark" src="assets/custom-icons/checkmark.svg"></svg-icon> | |||
| <div class="content"> | |||
| <label> Physics class </label> | |||
| <p> 11:00 AM to 1:00 PM </p> | |||
| </div> | |||
| <button> Absent </button> | |||
| </li> | |||
| <li class="late"> | |||
| <svg-icon [applyClass]="true" class="icon checkmark" src="assets/custom-icons/checkmark.svg"></svg-icon> | |||
| <div class="content"> | |||
| <label> Chemistry class </label> | |||
| <p> 2:00 PM to 3:00 PM </p> | |||
| </div> | |||
| <button> Late </button> | |||
| </li> | |||
| <li class="progress"> | |||
| <svg-icon [applyClass]="true" class="icon checkmark" src="assets/custom-icons/checkmark.svg"></svg-icon> | |||
| <div class="content"> | |||
| <label> Social Science class </label> | |||
| <p> 4:00 AM to 5:00 PM </p> | |||
| </div> | |||
| <button> In Progress </button> | |||
| </li> | |||
| </ul> | |||
| </section> | |||
| <button class="add-button"> <svg-icon [applyClass]="true" class="icon" src="assets/custom-icons/plus.svg"></svg-icon> </button> | |||
| </div> | |||
| @@ -0,0 +1,278 @@ | |||
| .page { | |||
| height: 100vh; | |||
| overflow: auto; | |||
| background-color: var(--ash-black); | |||
| } | |||
| .nav-header { | |||
| background-color: var(--ash-black); | |||
| display: flex; | |||
| align-items: center; | |||
| padding: 0 5%; | |||
| height: 60px; | |||
| position: sticky; | |||
| position: -webkit-sticky; | |||
| top: 0; | |||
| z-index: 1; | |||
| .close-button { | |||
| border: 0px; | |||
| background-color: transparent; | |||
| .icon { | |||
| width: 16px; | |||
| height: 16px; | |||
| fill: var(--light-grey); | |||
| } | |||
| } | |||
| .profile-button { | |||
| background-color: transparent; | |||
| margin-left: auto; | |||
| border: 0px; | |||
| margin-top: 5px; | |||
| } | |||
| img { | |||
| width: 35px; | |||
| height: 35px; | |||
| border-radius: 50%; | |||
| overflow: hidden; | |||
| } | |||
| } | |||
| .calendar-header { | |||
| color: white; | |||
| font-size: 18px; | |||
| font-weight: 500; | |||
| padding: 0 5%; | |||
| } | |||
| .mini-calendar { | |||
| width: 100%; | |||
| margin: 10px auto; | |||
| .days { | |||
| display: flex; | |||
| width: 100vw; | |||
| margin: 0 auto 10px; | |||
| padding: 10px 0; | |||
| position: relative; | |||
| &::before { | |||
| content: ''; | |||
| position: absolute; | |||
| bottom: 0; | |||
| left: 5%; | |||
| width: 90%; | |||
| height: 1px; | |||
| background-color: rgba(white, 0.1); | |||
| } | |||
| span { | |||
| width: calc(100vw / 7); | |||
| text-align: center; | |||
| font-size: 12px; | |||
| color: var(--light-grey); | |||
| } | |||
| } | |||
| .dates { | |||
| display: flex; | |||
| width: 100vw; | |||
| margin: 0 auto; | |||
| flex-wrap: wrap; | |||
| span { | |||
| display: block; | |||
| font-size: 13px; | |||
| width: calc(100vw / 7); | |||
| color: var(--light-grey); | |||
| font-weight: 500; | |||
| position: relative; | |||
| text-align: center; | |||
| transition: background-color 0.3s, color 0.3s; | |||
| height: calc(100vw / 7); | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| border-radius: 50%; | |||
| &.current-date { | |||
| color: white; | |||
| font-weight: 600; | |||
| } | |||
| &.active { | |||
| background-color: var(--black); | |||
| color: white; | |||
| } | |||
| &.non-current-date { | |||
| color: var(--dark-grey); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| .schedule-details { | |||
| max-height: calc(100vh - 60px); | |||
| background-color: white; | |||
| padding: 20px 5% 100px; | |||
| overflow: auto; | |||
| border-top-left-radius: 30px; | |||
| border-top-right-radius: 30px; | |||
| header { | |||
| color: var(--dark-grey); | |||
| font-size: 16px; | |||
| font-weight: 700; | |||
| } | |||
| ul { | |||
| list-style: none; | |||
| } | |||
| li { | |||
| display: flex; | |||
| width: 100%; | |||
| align-items: center; | |||
| justify-content: space-between; | |||
| margin: 0px auto; | |||
| padding-top: 20px; | |||
| position: relative; | |||
| &.attended { | |||
| button { | |||
| background-color: var(--green); | |||
| } | |||
| &::before { | |||
| border-color: var(--green); | |||
| } | |||
| .checkmark { | |||
| fill: var(--green); | |||
| } | |||
| } | |||
| &.absent { | |||
| button { | |||
| background-color: rgba(red, 0.5); | |||
| } | |||
| &::before { | |||
| border-color: rgba(red, 0.5); | |||
| } | |||
| .checkmark { | |||
| fill: rgba(red, 0.5); | |||
| } | |||
| } | |||
| &.late { | |||
| button { | |||
| background-color: rgba(orange, 0.5); | |||
| } | |||
| &::before { | |||
| border-color: rgba(orange, 0.5); | |||
| } | |||
| .checkmark { | |||
| fill: rgba(orange, 0.5); | |||
| } | |||
| } | |||
| &.progress { | |||
| button { | |||
| background-color: var(--teal); | |||
| } | |||
| &::before { | |||
| border-color: var(--teal); | |||
| } | |||
| .checkmark { | |||
| fill: var(--teal); | |||
| } | |||
| } | |||
| &:last-child::before { | |||
| display: none; | |||
| } | |||
| &::before { | |||
| content: ''; | |||
| position: absolute; | |||
| left: 8px; | |||
| top: 50%; | |||
| height: 100%; | |||
| width: 1px; | |||
| border-right: 1px dashed var(--light-grey); | |||
| } | |||
| .icon { | |||
| background-color: white; | |||
| z-index: 1; | |||
| position: relative; | |||
| width: 20px; | |||
| height: 20px; | |||
| fill: var(--light-grey); | |||
| } | |||
| button { | |||
| border-radius: 20px; | |||
| width: 90px; | |||
| height: 25px; | |||
| font-size: 12px; | |||
| border: 0px; | |||
| color: white; | |||
| background-color: var(--light-grey); | |||
| } | |||
| .content { | |||
| width: calc(100% - 40px - 120px); | |||
| } | |||
| label { | |||
| display: block; | |||
| font-size: 14px; | |||
| color: var(--dark-grey); | |||
| white-space: nowrap; | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| } | |||
| p { | |||
| font-size: 12px; | |||
| color: var(--light-grey); | |||
| white-space: nowrap; | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| } | |||
| } | |||
| } | |||
| .add-button { | |||
| position: fixed; | |||
| right: 5%; | |||
| bottom: 20px; | |||
| z-index: 1; | |||
| width: 50px; | |||
| height: 50px; | |||
| border-radius: 50%; | |||
| border: 0px; | |||
| background-color: var(--teal-green); | |||
| box-shadow: 0px 0px 5px var(--teal-green); | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| .icon { | |||
| width: 20px; | |||
| height: 20px; | |||
| fill: white; | |||
| } | |||
| } | |||
| @@ -1,15 +1,115 @@ | |||
| import { Component, OnInit } from '@angular/core'; | |||
| import { Location } from '@angular/common'; | |||
| @Component({ | |||
| selector: 'app-calendar', | |||
| templateUrl: './calendar.component.html', | |||
| styleUrls: ['./calendar.component.scss'] | |||
| selector: 'app-calendar', | |||
| templateUrl: './calendar.component.html', | |||
| styleUrls: ['./calendar.component.scss'] | |||
| }) | |||
| export class CalendarComponent implements OnInit { | |||
| currentDate: number; | |||
| currentMonth: string; | |||
| currentYear: number; | |||
| selectedDate: number; | |||
| selectedMonth: string; | |||
| selectedYear: number; | |||
| monthMap: Array<string> = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; | |||
| preceedingDays: Array<number> = []; | |||
| succeedingDays: Array<number> = []; | |||
| selectedMonthDays: Array<number> = []; | |||
| constructor() { } | |||
| constructor( | |||
| private location: Location | |||
| ) { } | |||
| ngOnInit(): void { | |||
| } | |||
| ngOnInit(): void { | |||
| this.selectToday(); | |||
| } | |||
| back() { | |||
| this.location.back(); | |||
| } | |||
| selectToday() { | |||
| this.selectedMonth = this.monthMap[(new Date()).getMonth()]; | |||
| this.selectedYear = (new Date()).getFullYear(); | |||
| this.selectedDate = new Date().getDate(); | |||
| this.currentYear = (new Date()).getFullYear(); | |||
| this.currentDate = new Date().getDate(); | |||
| this.currentMonth = this.monthMap[(new Date()).getMonth()]; | |||
| this.renderCalendar(); | |||
| } | |||
| getMonthNumberFromMap(month: string) { | |||
| let index = this.monthMap.findIndex((mapmonth => mapmonth === month)); | |||
| return (index + 1).toString().padStart(2, '0'); | |||
| } | |||
| renderCalendar() { | |||
| // Generate dates for the calendar | |||
| let i = 1, | |||
| no_of_preceeding_days, | |||
| no_of_days_in_selected_month, | |||
| no_of_succeeding_days, | |||
| last_date_of_previous_month, | |||
| first_date_of_selected_month, | |||
| last_date_of_selected_month; | |||
| first_date_of_selected_month = new Date(this.selectedYear, this.monthMap.indexOf(this.selectedMonth), 1); | |||
| // Add one month, and subtract one day to the selected month and year | |||
| last_date_of_selected_month = new Date(this.selectedYear, this.monthMap.indexOf(this.selectedMonth) + 1, 0); | |||
| last_date_of_previous_month = new Date(this.selectedYear, this.monthMap.indexOf(this.selectedMonth), 0); | |||
| no_of_preceeding_days = first_date_of_selected_month.getDay(); | |||
| no_of_days_in_selected_month = last_date_of_selected_month.getDate(); | |||
| no_of_succeeding_days = 6 - last_date_of_selected_month.getDay(); | |||
| this.preceedingDays = []; | |||
| this.selectedMonthDays = []; | |||
| this.succeedingDays = []; | |||
| for (i = no_of_preceeding_days - 1; i >= 0; i -= 1) { | |||
| this.preceedingDays.push(last_date_of_previous_month.getDate() - i); | |||
| } | |||
| for (i = 1; i <= no_of_days_in_selected_month; i += 1) { | |||
| this.selectedMonthDays.push(i); | |||
| } | |||
| for (i = 1; i <= no_of_succeeding_days; i += 1) { | |||
| this.succeedingDays.push(i); | |||
| } | |||
| } | |||
| selectNextMonth() { | |||
| let next_month_index = (this.monthMap.indexOf(this.selectedMonth) + 1) % this.monthMap.length; | |||
| this.selectedMonth = this.monthMap[next_month_index]; | |||
| if (next_month_index == 0) { | |||
| this.selectedYear += 1; | |||
| } | |||
| this.renderCalendar(); | |||
| } | |||
| selectPreviousMonth() { | |||
| let previous_month_index = (this.monthMap.indexOf(this.selectedMonth) + (this.monthMap.length - 1)) % this.monthMap.length; | |||
| this.selectedMonth = this.monthMap[previous_month_index]; | |||
| if (previous_month_index == (this.monthMap.length - 1)) { | |||
| this.selectedYear -= 1; | |||
| } | |||
| this.renderCalendar(); | |||
| } | |||
| selectPreviousYear() { | |||
| this.selectedYear -=1; | |||
| } | |||
| selectNextYear() { | |||
| this.selectedYear +=1; | |||
| } | |||
| } | |||
| @@ -149,6 +149,7 @@ | |||
| width: calc(100% - 180px); | |||
| border-left: 1px solid #cecece; | |||
| padding-left: 15px; | |||
| overflow: hidden; | |||
| p { | |||
| margin-top: 10px; | |||
| @@ -87,6 +87,7 @@ | |||
| width: calc(100% - 100px); | |||
| border-left: 1px solid #cecece; | |||
| padding-left: 15px; | |||
| overflow: hidden; | |||
| p { | |||
| margin-top: 10px; | |||
| @@ -0,0 +1,42 @@ | |||
| <?xml version="1.0" encoding="iso-8859-1"?> | |||
| <!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> | |||
| <svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" | |||
| viewBox="0 0 409.6 409.6" style="enable-background:new 0 0 409.6 409.6;" xml:space="preserve"> | |||
| <g> | |||
| <g> | |||
| <path d="M392.533,187.733H221.867V17.067C221.867,7.641,214.226,0,204.8,0s-17.067,7.641-17.067,17.067v170.667H17.067 | |||
| C7.641,187.733,0,195.374,0,204.8s7.641,17.067,17.067,17.067h170.667v170.667c0,9.426,7.641,17.067,17.067,17.067 | |||
| s17.067-7.641,17.067-17.067V221.867h170.667c9.426,0,17.067-7.641,17.067-17.067S401.959,187.733,392.533,187.733z"/> | |||
| </g> | |||
| </g> | |||
| <g> | |||
| </g> | |||
| <g> | |||
| </g> | |||
| <g> | |||
| </g> | |||
| <g> | |||
| </g> | |||
| <g> | |||
| </g> | |||
| <g> | |||
| </g> | |||
| <g> | |||
| </g> | |||
| <g> | |||
| </g> | |||
| <g> | |||
| </g> | |||
| <g> | |||
| </g> | |||
| <g> | |||
| </g> | |||
| <g> | |||
| </g> | |||
| <g> | |||
| </g> | |||
| <g> | |||
| </g> | |||
| <g> | |||
| </g> | |||
| </svg> | |||