Skip to content
This repository was archived by the owner on Jan 29, 2025. It is now read-only.

Commit 4aa4b23

Browse files
authored
Merge pull request #419 from sinfo/add-dynamic-promocodes
feat: add dynamic promocodes
2 parents dc9d6c1 + 20ffff2 commit 4aa4b23

File tree

6 files changed

+127
-11
lines changed

6 files changed

+127
-11
lines changed

src/app/app.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ import { SponsorComponent } from "./sponsor/sponsor.component";
121121
import { DeleteLinkDialogComponent } from "./user/link/my-links/delete-link-dialog/delete-link-dialog.component";
122122

123123
import { marked } from 'marked';
124+
import { PromocodeService } from "./landing-page/promocodes/promocode.service";
124125

125126

126127
library.add(fas);
@@ -231,6 +232,7 @@ library.add(fas);
231232
SpeakerService,
232233
MessageService,
233234
SponsorService,
235+
PromocodeService,
234236
TeamService,
235237
AuthService,
236238
AuthGuard,

src/app/landing-page/landing-page.component.css

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
.example-card {
1111
margin: 5%;
12-
/*display: flex;*/
12+
display: flex;
1313
justify-content: center;
1414
/* align horizontal */
1515
align-items: center;
@@ -342,9 +342,15 @@
342342

343343
.offers {
344344
display: grid;
345-
/*width: 100%;*/
346-
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
345+
width: 100%;
346+
grid-template-columns: repeat(auto-fit,minmax(400px,1fr));
347347
row-gap: 2rem;
348348
column-gap: 1rem;
349-
justify-content: center;
350-
}
349+
}
350+
351+
.offers img {
352+
max-height: 20vh;
353+
max-width: 100%;
354+
height: auto;
355+
width: auto;
356+
}

src/app/landing-page/landing-page.component.html

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@
3535
About Us
3636
</a>
3737
</li>
38+
<li class="socials-nav-item">
39+
<a (click)="scroll(offers)" class="navigation-link" aria-label="Offers">
40+
Offers
41+
</a>
42+
</li>
3843
<li class="socials-nav-item">
3944
<a (click)="scroll(faq)" class="navigation-link" aria-label="FAQ">
4045
FAQ
@@ -84,6 +89,11 @@
8489
About Us
8590
</a>
8691
</li>
92+
<li class="socials-nav-item">
93+
<a (click)="scroll(offers);toggleDropdown()" class="navigation-link" aria-label="Offers">
94+
Offers
95+
</a>
96+
</li>
8797
<li class="socials-nav-item">
8898
<a (click)="scroll(faq);toggleDropdown()" class="navigation-link" aria-label="FAQ">
8999
FAQ
@@ -463,7 +473,7 @@ <h6>Target</h6>
463473
</section>
464474
<mat-divider></mat-divider>
465475

466-
<section #faq class="price-area section-padding" style="margin-bottom: 5%;" id="the-event">
476+
<section #offers class="price-area section-padding" style="margin-bottom: 5%;">
467477
<div class="container">
468478
<div class="row">
469479
<div class="text-center">
@@ -473,14 +483,22 @@ <h2 class="text-center">Offers</h2>
473483
Take advantage of exclusive offers from our partners!
474484
</p>
475485
<div class="offers">
476-
<mat-card class="example-card cursor-pointer" style="padding: 2%;width: 250px;margin-left: 40%;">
477-
<a href="https://www.flytap.com"><img src="https://static.sinfo.org/static/31-sinfo/offers/tap.jpg"/></a>
486+
<mat-card *ngFor="let offer of promocodes" class="example-card" style="padding: 5%;">
487+
<img src="{{offer.company.img}}" alt="{{offer.company.name}} logo">
488+
478489
<div class="text-alt description">
479-
<small>Official Carrier of SINFO 31</small>
490+
<small>{{offer.description}}</small>
480491
</div>
481-
<a href="https://static.sinfo.org/static/31-sinfo/offers/tap_tos.pdf" class="btn btn-rounded btn-outline-clr btn-sm" style="margin-top: 2%;">
492+
<a *ngIf="offer.link" href="{{offer.code}}" target="_blank" class="btn btn-rounded btn-outline-clr btn-sm" style="margin-top: 2%;">
482493
Claim Offer
483494
</a>
495+
<div *ngIf="!offer.link" style="display:flex; flex-direction: column; margin-top: 2%;">
496+
<span>
497+
<small>Code:</small>
498+
<p class="btn btn-rounded btn-outline-clr btn-sm">{{offer.code}}</p>
499+
</span>
500+
<small>Expires: {{offer.expire | date : "dd/MM/yyyy" : "+0100"}}</small>
501+
</div>
484502
</mat-card>
485503
</div>
486504
</div>

src/app/landing-page/landing-page.component.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { Title } from '@angular/platform-browser'
44
import { LivestreamService } from './livestream/livestream.service'
55
import { SponsorService } from './sponsors/sponsor.service'
66
import { Sponsor } from './sponsors/sponsor.model'
7+
import { PromocodeService } from './promocodes/promocode.service'
8+
import { Promocode } from './promocodes/promocode.model'
79
import { Event } from '../events/event.model'
810
import {
911
trigger,
@@ -43,12 +45,14 @@ export class LandingPageComponent implements OnInit {
4345
isLive: boolean
4446
dropdownNav: boolean = false
4547
sponsors: Sponsor[]
48+
promocodes: Promocode[]
4649

4750
constructor(
4851
private titleService: Title,
4952
private eventService: EventService,
5053
private liveStreamService: LivestreamService,
51-
private sponsorService: SponsorService
54+
private sponsorService: SponsorService,
55+
private promocodeService: PromocodeService
5256
) { }
5357

5458
ngOnInit() {
@@ -61,6 +65,7 @@ export class LandingPageComponent implements OnInit {
6165
this.end = event.end
6266

6367
this.getSponsors(event)
68+
this.getPromocodes()
6469
})
6570

6671
this.showOrHideDropdown()
@@ -79,6 +84,13 @@ export class LandingPageComponent implements OnInit {
7984
)
8085
}
8186

87+
getPromocodes(): void {
88+
this.promocodeService.getPromocodes(this.eventId)
89+
.subscribe(promocodes => {
90+
this.promocodes = promocodes
91+
})
92+
}
93+
8294
/* Beggining of Dropdown tabs actions */
8395
showOrHideDropdown(): void {
8496
this.displayAboutDropdown = window.innerWidth > 768 ? true : false
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { Sponsor } from '../sponsors/sponsor.model'
2+
3+
export class Promocode {
4+
id: string
5+
code: string
6+
company: string | Sponsor
7+
description: string
8+
edition: string
9+
expire: Date
10+
link?: boolean
11+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { Injectable } from '@angular/core'
2+
import { HttpClient } from '@angular/common/http'
3+
import { MatSnackBar } from '@angular/material/snack-bar'
4+
import { Observable, of } from 'rxjs'
5+
import { tap, catchError } from 'rxjs/operators'
6+
import { environment } from '../../../environments/environment'
7+
import { Promocode } from './promocode.model'
8+
import { SponsorService } from '../sponsors/sponsor.service'
9+
10+
@Injectable()
11+
export class PromocodeService {
12+
private promocodeUrl = environment.cannonUrl + '/promo-code'
13+
private promocodes: Promocode[]
14+
15+
constructor(
16+
private http: HttpClient,
17+
private snackBar: MatSnackBar,
18+
private sponsorService: SponsorService
19+
) { }
20+
21+
getPromocodes(eventId: string): Observable<Promocode[]> {
22+
if (this.promocodes) {
23+
return of(this.promocodes)
24+
}
25+
26+
27+
return this.http.get<Promocode[]>(this.promocodeUrl).pipe(
28+
tap(promocodes => this.sponsorService.getSponsors(eventId).subscribe(sponsors => {
29+
this.promocodes = promocodes.map(promocode => {
30+
const sponsor = sponsors.find(sponsor => sponsor.id === promocode.company)
31+
promocode.company = sponsor
32+
promocode.link = this.isLink(promocode.code)
33+
return promocode
34+
})
35+
})),
36+
catchError(this.handleError<Promocode[]>('getPromocodes', []))
37+
)
38+
}
39+
40+
isLink(code: string): boolean {
41+
return code.startsWith('http://') || code.startsWith('https://')
42+
}
43+
44+
/**
45+
* Handle Http operation that failed.
46+
* Let the app continue.
47+
* @param operation - name of the operation that failed
48+
* @param result - optional value to return as the observable result
49+
*/
50+
private handleError<T>(operation = 'operation', result?: T) {
51+
return (error: any): Observable<T> => {
52+
// this.snackBar.open(error.message, "Ok", {
53+
// panelClass: ['mat-toolbar', 'mat-warn'],
54+
// duration: 2000
55+
// })
56+
57+
this.snackBar.open("An error occurred and was sent to SINFO team.", "Ok", {
58+
panelClass: ['mat-toolbar', 'mat-warn'],
59+
duration: 2000
60+
})
61+
62+
// Let the app keep running by returning an empty result.
63+
return of(result)
64+
}
65+
}
66+
67+
}

0 commit comments

Comments
 (0)