Skip to content

Commit

Permalink
Merge pull request #173 from e-picsa/ft-homepage-intro
Browse files Browse the repository at this point in the history
Homepage guided tour
  • Loading branch information
chrismclarke authored Sep 12, 2023
2 parents 9fc6ef2 + c3720c6 commit 8c74e0e
Show file tree
Hide file tree
Showing 13 changed files with 192 additions and 15 deletions.
7 changes: 5 additions & 2 deletions apps/picsa-apps/extension-app/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,12 @@
"apps/picsa-tools/budget-tool/src/styles.scss",
"apps/picsa-tools/resources-tool/src/styles.scss",
"libs/theme/src/_index.scss",
"apps/picsa-apps/extension-app/src/styles.scss"
"apps/picsa-apps/extension-app/src/styles.scss",
"node_modules/intro.js/introjs.css"
],
"scripts": []
"scripts": [
"node_modules/intro.js/intro.js"
]
},
"configurations": {
"production": {
Expand Down
1 change: 1 addition & 0 deletions apps/picsa-apps/extension-app/src/app/material.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export class ExtensionToolkitMaterialModule {
play_store: 'play_store',
probability_tool: 'probability_tool',
resources_tool: 'resources_tool',
tutorial: 'tutorial',
whatsapp: 'whatsapp',
};
for (const [key, value] of Object.entries(icons)) {
Expand Down
14 changes: 13 additions & 1 deletion apps/picsa-apps/extension-app/src/app/pages/home/home.page.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,24 @@

<div class="page-content background-image">
<div class="link-grid">
<div *ngFor="let link of links" data-cy="link" class="grid-tile" (click)="linkClicked(link)">
<div
*ngFor="let link of links"
[attr.data-tour-id]="link.tourId"
data-cy="link"
class="grid-tile"
(click)="linkClicked(link)"
>
<div style="text-align: center">
<mat-icon [svgIcon]="link.icon" class="nav-icon"></mat-icon>
<div class="nav-text">{{ link.name | translate }}</div>
</div>
</div>
<div class="grid-tile" (click)="startTour()" style="position: relative">
<div style="text-align: center">
<mat-icon svgIcon="picsa_tutorial" class="nav-icon"></mat-icon>
<div class="nav-text">{{ 'Take App Tour' | translate }}</div>
</div>
</div>
</div>

<footer>
Expand Down
33 changes: 32 additions & 1 deletion apps/picsa-apps/extension-app/src/app/pages/home/home.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,48 +4,62 @@ import { Router } from '@angular/router';
import { marker as translateMarker } from '@biesbjerg/ngx-translate-extract-marker';
import { PicsaCommonComponentsService } from '@picsa/components/src';
import { APP_VERSION } from '@picsa/environments';
import { TourService } from '@picsa/shared/services/core/tour.service';
import { CommunicationService } from '@picsa/shared/services/promptToHomePageService.service';
import { Subscription } from 'rxjs';

import { HOME_TOUR } from './home.tour';

interface IPageLink {
name: string;
icon: string;
url: string;
/** Element ID used in tours */
tourId: string;
}

const PAGE_LINKS: IPageLink[] = [
{
name: translateMarker('Manual'),
icon: 'picsa_manual_tool',
url: '/manual',
tourId: 'manual',
},
{
name: translateMarker('Resources'),
icon: 'picsa_resources_tool',
url: '/resources',
tourId: 'resources',
},
{
name: translateMarker('Monitoring'),
icon: 'picsa_data_collection',
url: '/monitoring',
tourId: 'monitoring',
},
{
name: translateMarker('Climate'),
icon: 'picsa_climate_tool',
url: '/climate',
tourId: 'climate',
},
{
name: translateMarker('Budget'),
icon: 'picsa_budget_tool',
url: '/budget',
tourId: 'budget',
},
{
name: translateMarker('Probability'),
icon: 'picsa_probability_tool',
url: '/crop-probability',
tourId: 'crop-probability',
},
{
name: translateMarker('Options'),
icon: 'picsa_option_tool',
url: '/option',
tourId: 'option',
},

// {
Expand All @@ -70,21 +84,38 @@ export class HomePage implements OnDestroy, AfterViewInit {
public links = PAGE_LINKS;
public version = APP_VERSION;

private userEventSubscription: Subscription;

@ViewChild('headerContent')
headerContent: ElementRef<HTMLElement>;

constructor(private router: Router, private componentsService: PicsaCommonComponentsService) {}
constructor(
private router: Router,
private componentsService: PicsaCommonComponentsService,
private communicationService: CommunicationService,
private tourService: TourService
) {}

linkClicked(link: IPageLink) {
this.router.navigate([link.url]);
}

ngOnDestroy(): void {
this.componentsService.patchHeader({ endContent: undefined });
this.userEventSubscription.unsubscribe();
}

ngAfterViewInit() {
this.componentsService.patchHeader({
endContent: new DomPortal(this.headerContent),
});
this.userEventSubscription = this.communicationService.userEvent$.subscribe(() => {
// Trigger the guided tour when the prompt event occurs
this.startTour();
});
}

public startTour() {
this.tourService.startTour(HOME_TOUR);
}
}
32 changes: 32 additions & 0 deletions apps/picsa-apps/extension-app/src/app/pages/home/home.tour.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { ITourStep } from '@picsa/shared/services/core/tour.service';

export const HOME_TOUR: ITourStep[] = [
{
id: 'manual',
text: 'This is the EPICSA Manual. A step-by-step guide to using PICSA with farmers.',
},
{
id: 'resources',
text: 'This is where you’ll find helpful resources that will guide your work.',
},
{
id: 'monitoring',
text: 'In here, field staff can make records of visits with farmers and provide data on everything they monitored.',
},
{
id: 'climate',
text: 'This is the climate tool which provides automatically updated, locally specific climate information graphs. A way for you to analyse the changing climate in your region.',
},
{
id: 'budget',
text: 'This budget tool is fully interactive and provides a way for farmers to make extensive budgets with respect to different options in their agro-businesses.',
},
{
id: 'crop-probability',
text: 'This is the crop-probability tool. It provides immediate calculations on which crops and varieties have the best chance to succeed, according to regions.',
},
{
id: 'option',
text: 'This is the options tool that supports farmers to consider a range of options aimed at increasing production, income and resilience.',
},
];
1 change: 1 addition & 0 deletions apps/picsa-apps/extension-app/src/assets/svgs/tutorial.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@
"covers/facebook.svg": {
"relativePath": "covers/facebook.svg",
"size_kb": 1.1,
"md5Checksum": "8626bc9119bd6b8bc0fa04e8a20b6e74",
"modifiedTime": "2022-09-28T20:19:52.986Z"
"md5Checksum": "a09b2f44f6b44b5b6e29aedba9f92029",
"modifiedTime": "2023-06-18T17:09:19.897Z"
},
"covers/gap.jpg": {
"relativePath": "covers/gap.jpg",
Expand All @@ -61,9 +61,9 @@
},
"covers/gender-equality.svg": {
"relativePath": "covers/gender-equality.svg",
"size_kb": 5.5,
"md5Checksum": "0b6599c4d8b3a87b787910b18a9d8851",
"modifiedTime": "2022-11-01T20:27:18.286Z"
"size_kb": 5.4,
"md5Checksum": "95af38f37c2179d4ad0c5288cbb236ed",
"modifiedTime": "2023-06-18T17:09:19.897Z"
},
"covers/gras-nelk.jpg": {
"relativePath": "covers/gras-nelk.jpg",
Expand Down Expand Up @@ -110,8 +110,8 @@
"covers/spreadsheet.svg": {
"relativePath": "covers/spreadsheet.svg",
"size_kb": 2.8,
"md5Checksum": "a03a4bfb0a1791fda8e232a8b032715b",
"modifiedTime": "2022-09-30T09:35:53.529Z"
"md5Checksum": "0a1bc91188bbc03fda0a7cb2bc1aa6ce",
"modifiedTime": "2023-06-18T17:09:19.898Z"
},
"covers/twitter.png": {
"relativePath": "covers/twitter.png",
Expand All @@ -122,8 +122,8 @@
"covers/weather.svg": {
"relativePath": "covers/weather.svg",
"size_kb": 3.1,
"md5Checksum": "db07c7d20d9520124c251c810c5817fd",
"modifiedTime": "2022-09-28T19:22:58.064Z"
"md5Checksum": "ca87f24916d258b8b8b5dd8343d4305b",
"modifiedTime": "2023-06-18T17:09:19.898Z"
},
"covers/whatsapp.svg": {
"relativePath": "covers/whatsapp.svg",
Expand Down
12 changes: 10 additions & 2 deletions libs/shared/src/modules/deep-links/app-open-prompt.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Component } from '@angular/core';
import { MatBottomSheet } from '@angular/material/bottom-sheet';

import { CommunicationService } from '../../services/promptToHomePageService.service';
import { DeepLinksService } from './deep-links.service';

/**
Expand All @@ -15,7 +16,7 @@ import { DeepLinksService } from './deep-links.service';
<div class="open-option">
<div class="picsa-app-icon">PICSA</div>
<h3>PICSA App</h3>
<button mat-raised-button color="primary">Open</button>
<button mat-raised-button color="primary" (click)="triggerTour()">Open</button>
</div>
</a>
<div class="open-option" (click)="dismiss()">
Expand Down Expand Up @@ -72,12 +73,19 @@ export class AppOpenPromptComponent {
appDynamicLink: string;
constructor(
deepLinksService: DeepLinksService,
private bottomSheet: MatBottomSheet
private bottomSheet: MatBottomSheet,
private communicationService: CommunicationService
) {
this.appDynamicLink = deepLinksService.config.appDynamicLink;
}

triggerTour(){
this.communicationService.triggerUserEvent();
}

dismiss() {
this.bottomSheet.dismiss();
// trigger homepage tour
this.triggerTour();
}
}
41 changes: 41 additions & 0 deletions libs/shared/src/services/core/tour.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Injectable } from '@angular/core';
import introJs, { IntroJs, Options, Step } from 'intro.js';

export interface ITourStep extends Omit<Step, 'intro'> {
id: string;
text: string;
}

@Injectable({ providedIn: 'root' })
/**
* Interact with Intro.JS tours
*/
export class TourService {
private intro: IntroJs;
constructor() {
this.intro = introJs();
}

public startTour(tourSteps: ITourStep[], tourOptions: Partial<Options> = {}): void {
// map passed tourId to data attribute selector
const steps = tourSteps.map((step) => {
const mappedStep: Step = {
...step,
element: `[data-tour-id="${step.id}"]`,
intro: step.text,
};
return mappedStep;
});
console.log('starting tour', steps);

this.intro
.setOptions({
hidePrev: true,
exitOnOverlayClick: false,
tooltipClass: 'picsa-tooltip',
steps,
...tourOptions,
})
.start();
}
}
17 changes: 17 additions & 0 deletions libs/shared/src/services/promptToHomePageService.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Service to facilitate communication between the app-open-prompt and homepage

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';

@Injectable({
providedIn: 'root',
})
export class CommunicationService {
private userEventSubject = new Subject<void>();

userEvent$ = this.userEventSubject.asObservable();

triggerUserEvent(): void {
this.userEventSubject.next();
}
}
13 changes: 13 additions & 0 deletions libs/theme/src/_overrides.scss
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,16 @@ enketo-webform {
width: 100%;
}
}
/******************************************************************
Intro.JS Tour
*******************************************************************/
.introjs-tooltip.picsa-tooltip {
.introjs-tooltip-header {
background: var(--color-primary);
color: white;
}
.introjs-skipbutton {
color: white;
line-height: 36px;
}
}
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
"form-data": "^4.0.0",
"glob": "^8.1.0",
"html2canvas": "^1.4.1",
"intro.js": "^7.0.1",
"leaflet": "^1.9.3",
"leaflet-draw": "github:enketo/Leaflet.draw#ff730785db7fcccbf2485ffcf4dffe1238a7c617",
"lottie-web": "^5.10.2",
Expand Down Expand Up @@ -125,6 +126,7 @@
"@stencil/sass": "^3.0.2",
"@types/c3": "^0.7.8",
"@types/hammerjs": "^2.0.41",
"@types/intro.js": "^5.1.1",
"@types/jest": "28.1.1",
"@types/leaflet": "^1.8.0",
"@types/node": "^18.14.2",
Expand Down
Loading

0 comments on commit 8c74e0e

Please sign in to comment.