Skip to content
Snippets Groups Projects
Commit ed8eea4b authored by pnogal's avatar pnogal
Browse files

Add and remove course from favorites

parent 7076d8c1
No related branches found
No related tags found
No related merge requests found
Showing
with 134 additions and 44 deletions
import { HttpClient } from '@angular/common/http';
import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http';
import { throwError, Observable } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { ConfigService } from './config.service';
import { Course } from './models/course';
import { DegreePlan } from './models/degree-plan';
import { Term } from './models/term';
import { FavoriteCourse } from './models/favorite-course';
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
})
};
@Injectable()
export class DataService {
......@@ -33,6 +39,21 @@ export class DataService {
.pipe(catchError(this.errorHandler));
}
getFavoriteCourses(): Observable<FavoriteCourse[]> {
return this.http.get<FavoriteCourse[]>(this.plannerApiUrl + '/favorites')
.pipe(catchError(this.errorHandler));
}
saveFavoriteCourse(subjectCode: string, courseId: string): Observable<FavoriteCourse> {
return this.http.post<FavoriteCourse>(this.plannerApiUrl + 'favorites/' + subjectCode + '/' + courseId, httpOptions)
.pipe(catchError(this.errorHandler));
}
removeFavoriteCourse(subjectCode, courseId): Observable<FavoriteCourse> {
return this.http.delete<FavoriteCourse>(this.plannerApiUrl + 'favorites/' + subjectCode + '/' + courseId, httpOptions)
.pipe(catchError(this.errorHandler));
}
private errorHandler(error: HttpErrorResponse) {
return throwError(error || 'Server Error');
}
......
export interface FavoriteCourse {
id: number;
courseId: string;
termCode: string;
topicId: number;
subjectCode: string;
title: string;
catalogNumber: string;
courseOrder: number;
}
<mat-sidenav-container id="plans-container">
<!-- Menu side nav -->
<mat-sidenav #rightSideNav position="end" mode="side" [opened]="true" disableClose>
<cse-sidenav-menu-item></cse-sidenav-menu-item>
<cse-sidenav-menu-item [favoriteDropZone]="getTermDropZone()"></cse-sidenav-menu-item>
</mat-sidenav>
<!-- Add course sidenav -->
......@@ -46,7 +46,7 @@
*ngFor="let term of termsByAcademicYear[year.key].terms | keyvalue"
[term]="termsByAcademicYear[year.key].terms[term.key]"
[courses]="termsByAcademicYear[year.key].terms[term.key]['courses']"
[termCodes]="getTermCodes()"
[termCodes]="getTermDropZone()"
fxFlex="33%"
></cse-term-container>
</div>
......
......@@ -95,12 +95,12 @@ export class DegreePlannerComponent {
return [];
}
getTermCodes() {
getTermDropZone() {
if (!this.degreePlanCourses) {
return false;
}
const termCodes = [];
const termCodes = ['favoriteCourse-dropZone'];
for (const yearCode in this.termsByAcademicYear) {
if (this.termsByAcademicYear[yearCode]) {
......
<div id="favorite-container">
My favorite courses!
</div>
\ No newline at end of file
<div class="term-container">
<div
cdkDropList
id="favoriteCourse-dropZone"
class="course-list"
[cdkDropListData]="favoriteCourses"
[cdkDropListConnectedTo]="favoriteDropZone"
(cdkDropListDropped)="drop($event)">
<div class="course-wrapper" [cdkDragData]="course" *ngFor="let course of favoriteCourses" cdkDrag>
<div class="course-wrapper-inner">
<cse-course-item [course]="course" [status]="'favorite'" class="course-favorite"></cse-course-item>
</div>
</div>
<p *ngIf="!favoriteCourses || favoriteCourses.length === 0" class="no-courses text-center semi-bold">No Favorite Courses</p>
</div>
</div>
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, Input } from '@angular/core';
import { DataService } from '../../core/data.service';
import { FavoriteCourse } from '../../core/models/favorite-course';
import { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop';
@Component({
selector: 'cse-favorites-container',
templateUrl: './favorites-container.component.html',
styleUrls: ['./favorites-container.component.scss']
})
export class FavoritesContainerComponent implements OnInit {
favoriteCourses: FavoriteCourse[];
favoriteCourse: FavoriteCourse;
@Input() favoriteDropZone: [];
constructor(private dataService: DataService) {
constructor() { }
this.dataService.getFavoriteCourses()
.subscribe(favoriteCourses => {
this.favoriteCourses = favoriteCourses;
});
}
ngOnInit() {
}
drop(event: CdkDragDrop<string[]>) {
if (event.previousContainer.id !== event.container.id) {
transferArrayItem(event.previousContainer.data,
event.container.data,
event.previousIndex,
event.currentIndex);
}
this.dataService.saveFavoriteCourse(event.item.data.subjectCode, event.item.data.courseId)
.subscribe(favoriteCourse => {
this.favoriteCourse = favoriteCourse;
});
}
}
......@@ -37,6 +37,6 @@
<h3>Favorites</h3>
</mat-panel-title>
</mat-expansion-panel-header>
<cse-favorites-container></cse-favorites-container>
<cse-favorites-container [favoriteDropZone]='favoriteDropZone'></cse-favorites-container>
</mat-expansion-panel>
</div>
\ No newline at end of file
......@@ -5,6 +5,7 @@
height: 100vh;
.mat-expansion-panel {
border-radius: 0px;
overflow: visible;
}
h3 {
font-weight: 400;
......
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: 'cse-sidenav-menu-item',
......@@ -8,6 +8,7 @@ import { Component, OnInit } from '@angular/core';
export class SidenavMenuItemComponent implements OnInit {
events: string[] = [];
opened: boolean;
@Input() favoriteDropZone: [];
constructor() { }
......
......@@ -9,9 +9,9 @@
[cdkDropListConnectedTo]="termCodes"
class="course-list"
(cdkDropListDropped)="drop($event)">
<div class="course-wrapper" *ngFor="let course of courses" cdkDrag>
<div class="coure-wrapper-inner">
<cse-course-item [course]="course" [status]="'complete'"></cse-course-item>
<div class="course-wrapper" [cdkDragData]="course" *ngFor="let course of courses" cdkDrag>
<div class="course-wrapper-inner">
<cse-course-item [course]="course" [status]="'in-progress'"></cse-course-item>
</div>
</div>
<p *ngIf="!courses || courses.length === 0" class="no-courses text-center semi-bold">No Courses Taken</p>
......
......@@ -11,29 +11,3 @@
.term-container h2 {
margin: 0 0 20px 0;
}
.no-courses {
padding: 20px 10px;
}
.cdk-drag-placeholder {
position: relative;
&:after {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: #C7CACB;
border-radius: 5px;
}
}
.cdk-drag-preview {
.coure-wrapper-inner {
transform: rotate(-3deg);
border-radius: 5px;
box-shadow: -3px 3px 3px 2px rgba(0, 0, 0, 0.26);
}
}
\ No newline at end of file
import { Component, Input } from '@angular/core';
import { Term } from '../../core/models/term';
import { Course } from '../../core/models/course';
import { FavoriteCourse } from '../../core/models/favorite-course';
import { DataService } from '../../core/data.service';
import { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop';
@Component({
......@@ -14,8 +16,9 @@ export class TermContainerComponent {
@Input() courses: Course[];
@Input() termCodes: String[];
terms: any[];
favoriteCourse: FavoriteCourse;
constructor() {}
constructor(private dataService: DataService) {}
getTotalCredits() {
if (!this.courses) {
......@@ -36,5 +39,10 @@ export class TermContainerComponent {
event.previousIndex,
event.currentIndex);
}
this.dataService.removeFavoriteCourse(event.item.data.subjectCode, event.item.data.courseId)
.subscribe(favoriteCourse => {
this.favoriteCourse = favoriteCourse;
});
}
}
......@@ -49,4 +49,40 @@ body {
.favorite-icon {
color: map-get($uw-accent, 600);
}
\ No newline at end of file
}
#favoriteCourse-dropZone {
.course-favorite {
.course-item {
border: 1px solid #b7b7b7;
border-radius: 4px;
padding: 5px 10px;
}
}
}
.cdk-drag-placeholder {
position: relative;
&:after {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: #C7CACB;
border-radius: 5px;
}
}
.cdk-drag-preview {
.course-wrapper-inner {
transform: rotate(-3deg);
border-radius: 5px;
box-shadow: -3px 3px 3px 2px rgba(0, 0, 0, 0.26);
}
}
.no-courses {
padding: 20px 10px;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment