Skip to content

Commit

Permalink
feat(event): add endingDate design to events
Browse files Browse the repository at this point in the history
  • Loading branch information
mathieuher committed Jan 26, 2025
1 parent 8dd2fd0 commit 00dec08
Show file tree
Hide file tree
Showing 16 changed files with 169 additions and 29 deletions.
4 changes: 4 additions & 0 deletions src/app/common/models/online-event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,8 @@ export class OnlineEvent {
this.endingDate = endingDate;
this.startingDate = startingDate;
}

public get isClosed(): boolean {
return (this.endingDate?.getTime() || 0) < new Date().getTime();
}
}
3 changes: 3 additions & 0 deletions src/app/common/models/server-event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ export interface ServerEvent {
id: string;
name: string;
racesLimit: number;
startingDate?: Date;
endingDate?: Date;
endingDateLabel?: string;
}
4 changes: 2 additions & 2 deletions src/app/common/scss/components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -314,8 +314,8 @@
}

&.inactive {
background-color: var(--color-disabled-lightest);
color: var(--color-disabled);
background-color: var(--color-primary-lightest);
color: var(--color-primary-light);
}

.icon {
Expand Down
1 change: 1 addition & 0 deletions src/app/common/scss/variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ html {
--text-standard: 14px;
--text-subtitle: 16px;
--text-small: 12px;
--text-mini: 10px;

--icon-small: 20px;
--icon-standard: 24px;
Expand Down
4 changes: 2 additions & 2 deletions src/app/common/services/event.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ export class EventService {
record['racesLimit'],
record['server'],
record['track'],
record['endingDate'],
record['startingDate']
record['endingDate'] ? new Date(record['endingDate']) : undefined,
record['startinGate'] ? new Date(record['startingGate']) : undefined
)
)
);
Expand Down
11 changes: 10 additions & 1 deletion src/app/common/services/server.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type { Server } from '../models/server';
import type { ServerRider } from '../models/server-rider';
import type { ServerEvent } from '../models/server-event';
import type { ServerTrack } from '../models/server-track';
import { DateUtils } from '../utils/date.utils';

@Injectable({
providedIn: 'root'
Expand Down Expand Up @@ -43,10 +44,18 @@ export class ServerService {
).pipe(
map(records =>
records.map(record => {
const endingDate = record['endingDate'];
const endingDateLabel = endingDate
? DateUtils.dateDiffLabel(new Date(endingDate), new Date())
: undefined;

return {
id: record['id'],
name: record['name'],
racesLimit: record['racesLimit']
racesLimit: record['racesLimit'],
startingDate: record['startingDate'],
endingDate: record['endingDate'],
endingDateLabel: endingDateLabel
};
})
)
Expand Down
26 changes: 26 additions & 0 deletions src/app/common/utils/date.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { intervalToDuration } from 'date-fns';

export class DateUtils {
private static readonly MINUTE = 1000 * 60;
private static readonly HOUR = DateUtils.MINUTE * 60;
private static readonly DAY = DateUtils.HOUR * 24;

public static dateDiffLabel(date: Date, reference: Date): string {
const duration = intervalToDuration({ start: date, end: reference });
const timeDiff = date.getTime() - reference.getTime();
if (timeDiff < 0) {
return 'closed';
}

if (duration.years || duration.months || duration.weeks || Math.abs(duration.days!) > 1) {
return `${Math.floor(timeDiff / DateUtils.DAY)} days`;
}
if (Math.abs(duration.hours!) > 1) {
return `${Math.floor(timeDiff / DateUtils.HOUR)} hours`;
}
if (Math.abs(duration.minutes!) > 1) {
return `${Math.floor(timeDiff / DateUtils.MINUTE)} min.`;
}
return 'closing';
}
}
17 changes: 17 additions & 0 deletions src/app/pages/online-event/online-event.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,21 @@
event()!.racesLimit ? "Race" : "Time-attack"
}}</span>
</div>
@if (event()?.endingDate) { @if(event()?.isClosed) {
<div class="retro-text error">
Closed since :
<span class="">{{
event()?.endingDate | date : "d MMMM YYY HH:mm"
}}</span>
</div>
} @else {
<div class="retro-text">
Open until :
<span class="tertiary">{{
event()?.endingDate | date : "d MMMM YYY HH:mm"
}}</span>
</div>
} }
<div class="retro-subtitle">
<span
class="alternative"
Expand Down Expand Up @@ -111,6 +126,7 @@
<div class="retro-placeholder">Loading event</div>
}
</div>
@if(!event()?.isClosed) {
<div class="retro-footer">
<button
class="retro-button tertiary"
Expand All @@ -120,3 +136,4 @@
Start riding
</button>
</div>
}
4 changes: 3 additions & 1 deletion src/app/pages/online-event/online-event.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,18 @@ import type { EventResult } from '../../common/models/event-result';
import type { EventRanking } from '../../common/models/event-ranking';
import { AuthService } from '../../common/services/auth.service';
import type { User } from '../../common/models/user';
import { DatePipe } from '@angular/common';

@Component({
selector: 'app-online-event',
standalone: true,
imports: [ButtonIconComponent, ToolbarComponent, RankingLineComponent, ResultLineComponent, RouterLink],
imports: [ButtonIconComponent, DatePipe, ToolbarComponent, RankingLineComponent, ResultLineComponent, RouterLink],
templateUrl: './online-event.component.html',
styleUrl: './online-event.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class OnlineEventComponent {
protected now = new Date().getTime();
protected event: Signal<OnlineEvent | undefined>;
protected track: Signal<Track | undefined>;
protected results: Signal<EventResult[] | undefined>;
Expand Down
20 changes: 19 additions & 1 deletion src/app/pages/race/race.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,25 @@
</div>
</div>

@if(raceRanking(); as raceRanking) {
@if(rankingError()) {
<div class="error-overlay">
<div class="retro-content">
<span class="icon material-symbols-outlined"
>sentiment_dissatisfied</span
>
<div class="retro-text error">
Oops! We couldn't save your ride for this event.
</div>
<div class="retro-text error">
Make sure the event is still open and give it another shot!
</div>
<div class="retro-button error" (click)="exitRace()">
Back to the event
</div>
</div>
</div>

} @if(raceRanking(); as raceRanking) {
<div class="timing-overlay">
<div class="ranking">
<div class="position">{{ raceRanking.positionLabel }}</div>
Expand Down
35 changes: 35 additions & 0 deletions src/app/pages/race/race.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,41 @@
}
}

.error-overlay {
overflow: hidden;
display: flex;
flex-direction: column;
position: absolute;
top: 0px;
opacity: 0.95;
width: 100%;
padding: 2rem 0;
left: 0;
align-items: center;
text-align: center;
background-color: var(--color-error-lightest);
color: var(--color-error-darkest);

.icon {
font-size: var(--text-big);
margin-bottom: 1rem;
}

.retro-content {
padding: 1rem;

.retro-text {
color: var(--color-error-darkest);
}

.retro-button {
margin-top: 1rem;
background-color: var(--color-error-darkest);
color: var(--color-surface);
}
}
}

.timing-overlay {
display: flex;
flex-direction: column;
Expand Down
8 changes: 6 additions & 2 deletions src/app/pages/race/race.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { RankingLineComponent } from '../../common/components/ranking-line/ranki
import { LocalEventService } from '../../common/services/local-event.service';
import type { LocalEvent } from '../../common/models/local-event';
import { TrackService } from '../../common/services/track.service';
import { concatMap, filter, from, map, type Observable, of, takeUntil, tap } from 'rxjs';
import { catchError, concatMap, EMPTY, filter, from, map, type Observable, of, takeUntil, tap } from 'rxjs';
import { Destroyable } from '../../common/components/destroyable/destroyable.component';
import { RaceRanking } from '../../common/models/race-ranking';
import { EventService } from '../../common/services/event.service';
Expand All @@ -35,7 +35,7 @@ export class RaceComponent extends Destroyable implements OnInit {

protected raceConfig = signal<RaceConfig | undefined>(undefined);
protected raceRanking = signal<RaceRanking | undefined>(undefined);

protected rankingError = signal<boolean>(false);
private game?: Game;

private type = (this.route.snapshot.data as { type: 'local' | 'online' }).type;
Expand Down Expand Up @@ -167,6 +167,10 @@ export class RaceComponent extends Destroyable implements OnInit {
}
return of(null);
}),
catchError(() => {
this.rankingError.set(true);
return EMPTY;
}),
takeUntil(this.destroyed$)
)
.subscribe();
Expand Down
2 changes: 1 addition & 1 deletion src/app/pages/ride-online/ride-online.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
padding: 1rem;

.server-infos {
padding: 0.25rem;
padding: 0.1rem 0.3rem;
background-color: var(--color-tertiary);
color: var(--color-surface);
border-radius: var(--border-radius-large);
Expand Down
14 changes: 11 additions & 3 deletions src/app/pages/server/server.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,21 @@
>
</div>
<div class="retro-items-list">
@for (event of events(); track event.id) {
@for (event of (eventsDisplay() === 'active' ? activeEvents(): events()
); track event.id) {
<div
class="retro-item"
[class.inactive]="false"
[class.inactive]="event.endingDateLabel === 'closed'"
routerLink="/online-event/{{ event.id }}"
>
<div class="name">{{ event.name }}</div>
<div class="name">
{{ event.name }} @if(event.endingDate) {
<span class="badge"
><span class="icon material-symbols-outlined">schedule</span
>{{ event.endingDateLabel }}</span
>
}
</div>
<div class="type">
{{ event.racesLimit !== 0 ? "Race" : "Time-attack" }}
</div>
Expand Down
40 changes: 25 additions & 15 deletions src/app/pages/server/server.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,32 @@
}
}

.events-list {
display: flex;
flex-direction: column;
gap: 0.25rem;
padding: 0.5rem 0;

.event {
cursor: pointer;
.retro-item {
.badge {
display: flex;
flex-direction: row;
gap: 0.5rem;
padding: 0.5rem;
justify-content: space-between;
font-size: var(--text-standard);
border-radius: var(--border-radius);
border: 1px solid var(--color-primary);
align-items: center;
gap: 0.1rem;
padding: 0 0.3rem;
background-color: var(--color-primary-light);
color: var(--color-surface);
border-radius: var(--border-radius-large);
font-size: var(--text-mini);
text-transform: capitalize;

.icon {
scale: 0.7;
}
}

.type {
font-size: var(--text-small);
}

&.inactive {
.badge {
background-color: var(--color-error-lightest);
color: var(--color-error-darkest);
}
}
}
}
5 changes: 4 additions & 1 deletion src/app/pages/server/server.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@ export class ServerComponent {
private readonly router = inject(Router);

protected server = signal<Server | null>(null);
protected readonly now = new Date().getTime();
protected riders = signal<ServerRider[] | null>(null);
protected activeRiders = computed(() => this.riders()?.slice(0, 5));
protected events = signal<ServerEvent[] | null>(null);
protected activeEvents = computed(() => this.events());
protected activeEvents = computed(() =>
this.events()?.filter(event => !event.endingDate || new Date(event.endingDate).getTime() > this.now)
);
protected user = this.authService.getUser();
protected ridersDisplay: WritableSignal<'active' | 'all'> = signal('active');
protected eventsDisplay: WritableSignal<'active' | 'all'> = signal('active');
Expand Down

0 comments on commit 00dec08

Please sign in to comment.