@@ -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 { Component, OnInit } from '@angular/core'; | ||||
import { Location } from '@angular/common'; | |||||
@Component({ | @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 { | 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); | width: calc(100% - 180px); | ||||
border-left: 1px solid #cecece; | border-left: 1px solid #cecece; | ||||
padding-left: 15px; | padding-left: 15px; | ||||
overflow: hidden; | |||||
p { | p { | ||||
margin-top: 10px; | margin-top: 10px; | ||||
@@ -87,6 +87,7 @@ | |||||
width: calc(100% - 100px); | width: calc(100% - 100px); | ||||
border-left: 1px solid #cecece; | border-left: 1px solid #cecece; | ||||
padding-left: 15px; | padding-left: 15px; | ||||
overflow: hidden; | |||||
p { | p { | ||||
margin-top: 10px; | 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> |