Compare commits

...

2 Commits

9 changed files with 230 additions and 138 deletions

View File

@ -9,34 +9,74 @@
<main> <main>
<section class="darkmodeSection"> <section class="darkmodeSection">
<div class="customContainer"> <div class="container teamContainer">
<h2>Current Nitro Boosters</h2> <h2 class="sectionTitle">Current Nitro Boosters</h2>
@for (member of getTeamMembers('discord') | async; track member) {
<div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2>
<p>Nitro booster</p>
</div>
}
</div> </div>
</section> </section>
<section id="social" class="darkmodeSectionThree"> <section id="social" class="darkmodeSectionThree">
<div class="container" style="padding: 50px 0 0 0; justify-content: center;"> <div class="container teamContainer">
<h2 class="sectionTitle">Social Media</h2> <h2 class="sectionTitle">Social Media</h2>
@for (member of getTeamMembers('socialmedia') | async; track member) {
<div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2>
<p>Social media</p>
</div>
}
</div> </div>
<div style="display: flex; justify-content: center; padding-bottom: 30px;"> <div style="display: flex; justify-content: center; padding-bottom: 30px;">
<p style="text-align: center;">We're currently not looking for more people to help manage our socials.</p> <p style="text-align: center;">We're currently not looking for more people to help manage our socials.</p>
</div> </div>
</section> </section>
<section id="crateTeam" class="darkmodeSection"> <section id="crateTeam" class="darkmodeSection">
<div class="container" style="padding: 50px 0 0 0; justify-content: center;"> <div class="container teamContainer">
<h2 class="sectionTitle">Crate Team</h2> <h2 class="sectionTitle">Crate Team</h2>
@for (member of getTeamMembers('crate') | async; track member) {
<div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2>
<p>Crate team</p>
</div>
}
</div> </div>
</section> </section>
<section class="darkmodeSectionThree"> <section class="darkmodeSectionThree">
<div class="container" style="padding: 50px 0 0 0; justify-content: center;"> <div class="container teamContainer">
<h2 class="sectionTitle">Event Leaders</h2> <h2 class="sectionTitle">Event Leaders</h2>
@for (member of getTeamMembers('eventleader') | async; track member) {
<div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2>
<p>Event leaders</p>
</div>
}
</div> </div>
<div style="display: flex; justify-content: center; padding-bottom: 30px;"> <div style="display: flex; justify-content: center; padding-bottom: 30px;">
<p style="text-align: center;">We're currently not looking for more Event Leaders.</p> <p style="text-align: center;">We're currently not looking for more Event Leaders.</p>
</div> </div>
</section> </section>
<section class="darkmodeSection"> <section class="darkmodeSection">
<div class="container" style="padding: 50px 0 0 0; justify-content: center;"> <div class="container teamContainer">
<h2 class="sectionTitle">Event Team</h2> <h2 class="sectionTitle">Event Team</h2>
@for (member of getTeamMembers('eventteam') | async; track member) {
<div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2>
<p>Event team</p>
</div>
}
</div> </div>
<div style="display: flex; justify-content: center; padding-bottom: 30px;"> <div style="display: flex; justify-content: center; padding-bottom: 30px;">
<div style="flex-direction: column;"> <div style="flex-direction: column;">
@ -47,15 +87,32 @@
</div> </div>
</section> </section>
<section class="darkmodeSectionThree"> <section class="darkmodeSectionThree">
<div class="container" style="padding: 50px 0 0 0; justify-content: center;"> <div class="container teamContainer">
<h2 class="sectionTitle">YouTubers & Streamers</h2> <h2 class="sectionTitle">YouTubers & Streamers</h2>
@for (member of getTeamMembers('youtube') | async; track member) {
<div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2>
<p>Youtuber</p>
</div>
}
@for (member of getTeamMembers('twitch') | async; track member) {
<div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2>
<p>Streamer</p>
</div>
}
</div> </div>
<div style="display: flex; justify-content: center; padding-bottom: 30px;"> <div style="display: flex; justify-content: center; padding-bottom: 30px;">
<div style="flex-direction: column;"> <div style="flex-direction: column;">
<p style="text-align: center;"><a style="cursor: pointer;" id="reqButton">Show Requirements...</a></p> <p style="text-align: center;"><a style="cursor: pointer;" (click)="toggleSection('yt-stream-req')"
id="reqButton">{{ getTextForSection('yt-stream-req') }}</a></p>
</div> </div>
</div> </div>
<div id="req" class="hide" style="display: flex; justify-content: center; padding-bottom: 30px;"> <div [hidden]="!isToggled('yt-stream-req')" [class.requirementSection]="isToggled('yt-stream-req')">
<div style="flex-direction: column; justify-content: center; max-width: 800px;"> <div style="flex-direction: column; justify-content: center; max-width: 800px;">
<p style="text-align: center;"><span style="font-family: 'opensans-bold', sans-serif;">Requirements:</span> <p style="text-align: center;"><span style="font-family: 'opensans-bold', sans-serif;">Requirements:</span>
</p> </p>

View File

@ -1,12 +1,32 @@
.customContainer { .sectionTitle {
width: 80%; flex: 0 0 100%;
max-width: 1020px; text-align: center;
margin: auto; padding-bottom: 20px;
padding: 80px 0; font-size: 2em;
}
.member {
width: 33%;
min-width: 250px;
padding-bottom: 50px;
text-align: center; text-align: center;
} }
.hide { .member img {
display: none !important; padding-bottom: 15px;
} }
.member p {
font-family: 'opensans-bold', sans-serif;
}
.teamContainer {
padding: 50px 0 0 0;
justify-content: center;
}
.requirementSection {
display: flex;
justify-content: center;
padding-bottom: 30px;
}

View File

@ -1,23 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { CommunityComponent } from './community.component';
describe('CommunityComponent', () => {
let component: CommunityComponent;
let fixture: ComponentFixture<CommunityComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [CommunityComponent]
})
.compileComponents();
fixture = TestBed.createComponent(CommunityComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -1,14 +1,66 @@
import {Component} from '@angular/core'; import {Component, inject} from '@angular/core';
import {HeaderComponent} from "@header/header.component"; import {HeaderComponent} from "@header/header.component";
import {map, Observable, shareReplay} from 'rxjs';
import {Player, TeamService} from '@api';
import {ScrollService} from '@services/scroll.service';
import {AsyncPipe, NgOptimizedImage} from '@angular/common';
@Component({ @Component({
selector: 'app-community', selector: 'app-community',
imports: [ imports: [
HeaderComponent HeaderComponent,
AsyncPipe,
NgOptimizedImage
], ],
templateUrl: './community.component.html', templateUrl: './community.component.html',
styleUrl: './community.component.scss' styleUrl: './community.component.scss'
}) })
export class CommunityComponent { export class CommunityComponent {
private teamMembersCache: { [key: string]: Observable<Player[]> } = {};
protected scrollService: ScrollService = inject(ScrollService)
protected teamService: TeamService = inject(TeamService)
public getTeamMembers(team: string): Observable<Player[]> {
if (!this.teamMembersCache[team]) {
this.teamMembersCache[team] = this.teamService.getTeamMembers(team).pipe(
map(res => this.removeDuplicates(res)),
shareReplay(1)
);
}
return this.teamMembersCache[team];
}
private removeDuplicates(array: Player[]): Player[] {
return array.filter((player, index, self) =>
index === self.findIndex((p) => p.uuid === player.uuid)
);
}
public getAvatarUrl(entry: Player): string {
let uuid = entry.uuid.replace('-', '');
return `https://crafatar.com/avatars/${uuid}?overlay`;
}
public toggledSections: string[] = [];
public isToggled(section: string) {
return this.toggledSections.includes(section);
}
public toggleSection(section: string) {
if (this.isToggled(section)) {
this.toggledSections = this.toggledSections.filter(s => s !== section);
} else {
this.toggledSections.push(section);
}
}
public getTextForSection(section: string) {
if (this.isToggled(section)) {
return 'Hide Requirements...';
} else {
return 'Show Requirements...';
}
}
} }

View File

@ -1,10 +1,10 @@
<ng-container> <ng-container>
<app-header [current_page]="'team'" height="450px" background_image="/public/img/backgrounds/staff.png" <app-header [current_page]="'team'" height="450px" background_image="/public/img/backgrounds/staff.png"
[overlay_gradient]="0.5">> [overlay_gradient]="0.5">>
<div class="title" header-content> <div class="title" header-content>
<h1>Staffing Team</h1> <h1>Staffing Team</h1>
<h2>The team that makes Altitude happen. Your owners, admins, moderators, and trainees are all working together to <h2>The team that makes Altitude happen. Your owners, admins, moderators, and trainees are all working together to
create Altitude, to create home. This is where the magic happens.</h2> create Altitude, to create home. This is where the magic happens.</h2>
</div> </div>
</app-header> </app-header>
@ -15,72 +15,72 @@
@for (member of getTeamMembers('owner') | async; track member) { @for (member of getTeamMembers('owner') | async; track member) {
<div class="member"> <div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin" <img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;"> height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2> <h2>{{ member.name }}</h2>
<p>Owner</p> <p>Owner</p>
</div> </div>
} }
@for (member of getTeamMembers('manager') | async; track member) { @for (member of getTeamMembers('manager') | async; track member) {
<div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2>
<p>Manager</p>
</div>
}
</div>
</section>
<section class="darkmodeSectionThree">
<div class="container teamContainer">
<h2 class="sectionTitle">Admins</h2>
@for (member of getTeamMembers('admin') | async; track member) {
<div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2>
<p>Admin</p>
</div>
}
</div>
</section>
<section class="darkmodeSection">
<div class="container teamContainer">
<h2 class="sectionTitle">Head Moderators</h2>
@for (member of getTeamMembers('headmod') | async; track member) {
<div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2>
<p>Head Mod</p>
</div>
}
</div>
</section>
<section class="darkmodeSectionThree">
<div class="container teamContainer">
<h2 class="sectionTitle">Moderators</h2>
@for (member of getTeamMembers('moderator') | async; track member) {
<div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2>
</div>
}
</div>
</section>
@if ((getTeamMembers('trainee') | async)?.length ?? 0 > 0) {
<section class="darkmodeSection">
<div class="container teamContainer">
<h2 class="sectionTitle">Trainees</h2>
@for (member of getTeamMembers('trainee') | async; track member) {
<div class="member"> <div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin" <img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;"> height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2> <h2>{{ member.name }}</h2>
<p>Manager</p>
</div>
}
</div>
</section>
<section class="darkmodeSectionThree">
<div class="container teamContainer">
<h2 class="sectionTitle">Admins</h2>
@for (member of getTeamMembers('admin') | async; track member) {
<div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2>
<p>Admin</p>
</div>
}
</div> </div>
</section> }
<section class="darkmodeSection"> </div>
<div class="container teamContainer"> </section>
<h2 class="sectionTitle">Head Moderators</h2> }
@for (member of getTeamMembers('headmod') | async; track member) { </main>
<div class="member"> </ng-container>
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2>
<p>Head Mod</p>
</div>
}
</div>
</section>
<section class="darkmodeSectionThree">
<div class="container teamContainer">
<h2 class="sectionTitle">Moderators</h2>
@for (member of getTeamMembers('moderator') | async; track member) {
<div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2>
</div>
}
</div>
</section>
@if ((getTeamMembers('trainee') | async)?.length ?? 0 > 0) {
<section class="darkmodeSection">
<div class="container teamContainer">
<h2 class="sectionTitle">Trainees</h2>
@for (member of getTeamMembers('trainee') | async; track member) {
<div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2>
</div>
}
</div>
</section>
}
</main>
</ng-container>

View File

@ -197,27 +197,32 @@
<tbody> <tbody>
<tr> <tr>
<td data-label="Rank" class="rankTitle">[<span class="rank5">Social Media</span>]</td> <td data-label="Rank" class="rankTitle">[<span class="rank5">Social Media</span>]</td>
<td data-label="Requirements">See requirements on the <a href="/community.php">Community</a> page</td> <td data-label="Requirements">See requirements on the <a [routerLink]="['/community']">Community</a> page
</td>
<td data-label="Perks" class="perks">/record<br>/ptime<br>/pweather</td> <td data-label="Perks" class="perks">/record<br>/ptime<br>/pweather</td>
</tr> </tr>
<tr> <tr>
<td data-label="Rank" class="rankTitle">[<span class="rank5">Streamer</span>]</td> <td data-label="Rank" class="rankTitle">[<span class="rank5">Streamer</span>]</td>
<td data-label="Requirements">See requirements on the <a href="/community.php">Community</a> page</td> <td data-label="Requirements">See requirements on the <a [routerLink]="['/community']">Community</a> page
</td>
<td data-label="Perks" class="perks">/record<br>/ptime<br>/pweather</td> <td data-label="Perks" class="perks">/record<br>/ptime<br>/pweather</td>
</tr> </tr>
<tr> <tr>
<td data-label="Rank" class="rankTitle">[<span class="rank5">YouTube</span>]</td> <td data-label="Rank" class="rankTitle">[<span class="rank5">YouTube</span>]</td>
<td data-label="Requirements">See requirements on the <a href="/community.php">Community</a> page</td> <td data-label="Requirements">See requirements on the <a [routerLink]="['/community']">Community</a> page
</td>
<td data-label="Perks" class="perks">/record<br>/ptime<br>/pweather</td> <td data-label="Perks" class="perks">/record<br>/ptime<br>/pweather</td>
</tr> </tr>
<tr> <tr>
<td data-label="Rank" class="rankTitle">[<span class="rank5">Event Leader</span>]</td> <td data-label="Rank" class="rankTitle">[<span class="rank5">Event Leader</span>]</td>
<td data-label="Requirements">See requirements on the <a href="/community.php">Community</a> page</td> <td data-label="Requirements">See requirements on the <a [routerLink]="['/community']">Community</a> page
</td>
<td data-label="Perks" class="perks">Build perms on event server</td> <td data-label="Perks" class="perks">Build perms on event server</td>
</tr> </tr>
<tr> <tr>
<td data-label="Rank" class="rankTitle">[<span class="rank5">Event Team</span>]</td> <td data-label="Rank" class="rankTitle">[<span class="rank5">Event Team</span>]</td>
<td data-label="Requirements">See requirements on the <a href="/community.php">Community</a> page</td> <td data-label="Requirements">See requirements on the <a [routerLink]="['/community']">Community</a> page
</td>
<td data-label="Perks" class="perks">Build perms on event server</td> <td data-label="Perks" class="perks">Build perms on event server</td>
</tr> </tr>
</tbody> </tbody>

View File

@ -1,23 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RanksComponent } from './ranks.component';
describe('RanksComponent', () => {
let component: RanksComponent;
let fixture: ComponentFixture<RanksComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [RanksComponent]
})
.compileComponents();
fixture = TestBed.createComponent(RanksComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -1,10 +1,12 @@
import {Component} from '@angular/core'; import {Component} from '@angular/core';
import {HeaderComponent} from "@header/header.component"; import {HeaderComponent} from "@header/header.component";
import {RouterLink} from '@angular/router';
@Component({ @Component({
selector: 'app-ranks', selector: 'app-ranks',
imports: [ imports: [
HeaderComponent HeaderComponent,
RouterLink
], ],
templateUrl: './ranks.component.html', templateUrl: './ranks.component.html',
styleUrl: './ranks.component.scss' styleUrl: './ranks.component.scss'

View File

@ -12,6 +12,8 @@ getTeam:
description: The group name of the team description: The group name of the team
schema: schema:
type: string type: string
example: owner
maxLength: 32
responses: responses:
'200': '200':
description: successful operation description: successful operation