@@ -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> |