diff --git a/CHANGELOG.md b/CHANGELOG.md
index e2611773..e7d89961 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
- Added search bar inside navbar with autocomplete suggested results. - [#403](https://github.com/DigitalExcellence/dex-frontend/issues/403)
- Refactored the home page. [#380](https://github.com/DigitalExcellence/dex-frontend/issues/380)
+- Added project recommendations on the home page. [#497](https://github.com/DigitalExcellence/dex-frontend/issues/497)
### Changed
diff --git a/package-lock.json b/package-lock.json
index 71ad6e76..ce025374 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3966,7 +3966,7 @@
"colorette": "^1.2.2",
"electron-to-chromium": "^1.3.723",
"escalade": "^3.1.1",
- "node-releases": "^1.1.69"
+ "node-releases": "^1.1.71"
},
"dependencies": {
"colorette": {
diff --git a/src/app/components/app-layout/app-layout.component.ts b/src/app/components/app-layout/app-layout.component.ts
index 5ff82fca..f1c279c4 100644
--- a/src/app/components/app-layout/app-layout.component.ts
+++ b/src/app/components/app-layout/app-layout.component.ts
@@ -64,7 +64,7 @@ export class AppLayoutComponent implements OnInit {
});
this.router.events.subscribe((event) => {
- if (event instanceof NavigationStart) {
+ if (event instanceof NavigationEnd) {
if ((event.url === '/home' || event.url === '/')) {
this.showSearchbar = true;
} else {
diff --git a/src/app/modules/home/home.module.ts b/src/app/modules/home/home.module.ts
index 14c4d1ea..7ba1feb9 100644
--- a/src/app/modules/home/home.module.ts
+++ b/src/app/modules/home/home.module.ts
@@ -11,7 +11,8 @@ import { StripHtmlPipe } from 'src/app/utils/striptags.pipe';
import { PopoverModule } from 'ngx-bootstrap/popover';
import { ModalModule } from 'ngx-bootstrap/modal';
import { TooltipModule } from 'ngx-bootstrap/tooltip';
-import { ProjectModule } from 'src/app/modules/project/project.module';
+import { RecommendationCardsComponent } from './recommendations/recommendations.component';
+import { ProjectModule } from '../project/project.module';
@NgModule({
declarations: [
@@ -22,7 +23,9 @@ import { ProjectModule } from 'src/app/modules/project/project.module';
PartnersComponent,
ContainerLeftComponent,
ContainerRightComponent,
- StripHtmlPipe
+ StripHtmlPipe,
+ RecommendationCardsComponent
+
],
imports: [
CommonModule,
diff --git a/src/app/modules/home/main/main.component.html b/src/app/modules/home/main/main.component.html
index c6135143..8c176d29 100644
--- a/src/app/modules/home/main/main.component.html
+++ b/src/app/modules/home/main/main.component.html
@@ -1,6 +1,7 @@
-
+
+
diff --git a/src/app/modules/home/recommendations/recommendations.component.html b/src/app/modules/home/recommendations/recommendations.component.html
new file mode 100644
index 00000000..886d1d9e
--- /dev/null
+++ b/src/app/modules/home/recommendations/recommendations.component.html
@@ -0,0 +1,38 @@
+
+
+
0">
+
+
+
+
Your recommended projects
+
+ Your top {{recommendations.length}} recommendations
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/app/modules/home/recommendations/recommendations.component.scss b/src/app/modules/home/recommendations/recommendations.component.scss
new file mode 100644
index 00000000..90e1e314
--- /dev/null
+++ b/src/app/modules/home/recommendations/recommendations.component.scss
@@ -0,0 +1,68 @@
+/*
+ *
+ * Digital Excellence Copyright (C) 2020 Brend Smits
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * You can find a copy of the GNU Lesser General Public License
+ * along with this program, in the LICENSE.md file in the root project directory.
+ * If not, see https://www.gnu.org/licenses/lgpl-3.0.txt
+ *
+ */
+
+ @import "assets/styles/variables";
+
+ //project recommendations
+ .recommendedProjects {
+ // margin-top: 220px;
+ padding: 40px 60px 20px 60px;
+ background-color: $light-mode-grey-quaternary;
+ margin: 0 -39px;
+ justify-content: center;
+ align-items: center;
+
+ .inner {
+ max-width: 1750px;
+ margin: auto;
+ width: 100%;
+ .text {
+ .large{
+ margin: 0 0 5px 0;
+ }
+ }
+ }
+
+
+ .cards {
+ display: grid;
+ gap: 30px;
+ max-width: 100%;
+ grid-auto-columns: 310px;
+ grid-auto-flow: column;
+ overflow-x: auto;
+ overflow-y: hidden;
+ padding: 20px 0;
+
+ //scrollbar stylingbody
+ &::-webkit-scrollbar {
+ height: 4px;
+ }
+
+ &::-webkit-scrollbar-track {
+ }
+
+ &::-webkit-scrollbar-thumb {
+ border-radius: 999px;
+ background-color: white;
+ }
+
+
+ }
+}
\ No newline at end of file
diff --git a/src/app/modules/home/recommendations/recommendations.component.ts b/src/app/modules/home/recommendations/recommendations.component.ts
new file mode 100644
index 00000000..3089317f
--- /dev/null
+++ b/src/app/modules/home/recommendations/recommendations.component.ts
@@ -0,0 +1,86 @@
+/*
+ * Digital Excellence Copyright (C) 2020 Brend Smits
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * You can find a copy of the GNU Lesser General Public License
+ * along with this program, in the LICENSE.md file in the root project directory.
+ * If not, see https://www.gnu.org/licenses/lgpl-3.0.txt
+ */
+
+import { Component, OnInit } from '@angular/core';
+import { SafeUrl } from '@angular/platform-browser';
+import { finalize } from 'rxjs/operators';
+import { Project } from 'src/app/models/domain/project';
+import { AuthService } from 'src/app/services/auth.service';
+import { FileRetrieverService } from 'src/app/services/file-retriever.service';
+import { RecommendationService } from 'src/app/services/recommendation.service';
+import { ProjectDetailModalUtility } from 'src/app/utils/project-detail-modal.util';
+
+@Component({
+ selector: 'app-recommended-project-cards',
+ templateUrl: './recommendations.component.html',
+ styleUrls: ['./recommendations.component.scss'],
+})
+export class RecommendationCardsComponent implements OnInit {
+
+ public isAuthenticated: boolean;
+
+ /**
+ * Array to receive and store the projects from the api.
+ */
+ public recommendations: Project[] = [];
+
+ /**
+ * Boolean to determine whether the component is loading the information from the api.
+ */
+ public recommendationsLoading = true;
+
+ constructor(private recommendationService: RecommendationService,
+ private fileRetrieverService: FileRetrieverService,
+ private modalUtility: ProjectDetailModalUtility,
+ private authService: AuthService) {}
+
+ ngOnInit(): void {
+ this.authService.authNavStatus$.subscribe((status) => {
+ this.isAuthenticated = status;
+ if (status) {
+ this.recommendationService.getRecommendations(8)
+ .pipe(finalize(() => (this.recommendationsLoading = false)))
+ .subscribe((result) => {
+ this.recommendations = result;
+ this.recommendations.forEach(element => {
+ element.likeCount = element.likes.length;
+ });
+ });
+ }
+ });
+ }
+
+ /**
+* Triggers on project click in the list.
+* @param id project id.
+* @param name project name
+*/
+ public onClickRecommendedProject(id: number, name: string): void {
+ name = name.split(' ').join('-');
+ this.modalUtility.openProjectModal(id, name, '/home');
+ }
+
+ /**
+ * Method to get the url of the icon of the project. This is retrieved
+ * from the file retriever service
+ */
+ public getIconUrl(project: Project): SafeUrl {
+ return this.fileRetrieverService.getIconUrl(project.projectIcon);
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/app/services/recommendation.service.ts b/src/app/services/recommendation.service.ts
new file mode 100644
index 00000000..e0f86d06
--- /dev/null
+++ b/src/app/services/recommendation.service.ts
@@ -0,0 +1,39 @@
+/*
+ * Digital Excellence Copyright (C) 2020 Brend Smits
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * You can find a copy of the GNU Lesser General Public License
+ * along with this program, in the LICENSE.md file in the root project directory.
+ * If not, see https://www.gnu.org/licenses/lgpl-3.0.txt
+ */
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+import { API_CONFIG } from 'src/app/config/api-config';
+import { Observable } from 'rxjs';
+import { Project } from '../models/domain/project';
+
+/**
+ * Service to retrieve autocompleted project suggestions based on typed.
+ */
+@Injectable({
+ providedIn: 'root',
+})
+export class RecommendationService {
+
+ protected readonly url = API_CONFIG.url + API_CONFIG.userRoute;
+
+ constructor(private http: HttpClient) {}
+
+ public getRecommendations(amountOfRecommendations): Observable> {
+ return this.http.get>(this.url + "/projectrecommendations/" + amountOfRecommendations);
+ }
+
+}