Updated site to use momentum for contacting, registration, gallery and calendar, as well as some other updates to the site content
This commit is contained in:
@@ -35,7 +35,11 @@
|
||||
<li>Canadian Museum of History (formerly the Museum of Civilization), Gatineau PQ (2005)</li>
|
||||
<li>Royal Ontario Museum, Toronto ON (2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2023, 2024)</li>
|
||||
<li>RCR Museum, Wolseley Barracks, London ON (2019)</li>
|
||||
<li>Ontario Regiment RCAC Museum, Whitby, ON (2023, 2024)</li>
|
||||
<li>Ontario Regiment RCAC Museum, Whitby, ON</li>
|
||||
<ul>
|
||||
<li>Aquino Weekend (2023, 2025)</li>
|
||||
<li>The Evolution of Soldiers and Vehicles (2024)</li>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="mx-3">
|
||||
@@ -61,7 +65,8 @@
|
||||
<div class="mx-3">
|
||||
<h4 class="mb-2">Re-enactments</h4>
|
||||
<ul class="mt-0">
|
||||
<li>Fort Malden, Amherstburg ON (2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2015, 2016, 2024)</li>
|
||||
<li>Hastings Medieval Festival, Hastings, ON (2025)</li>
|
||||
<li>Fort Malden, Amherstburg ON (2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2015, 2016, 2024, 2025, 2026)</li>
|
||||
<li>Roman Market Days (2004)</li>
|
||||
<li>NE Route March, Erie Canal (2005)</li>
|
||||
<li>Roman Days (2005)</li>
|
||||
@@ -87,14 +92,14 @@
|
||||
</ul>
|
||||
<p class="mb-2">It continues to host our annual events:</p>
|
||||
<ul class="mt-0">
|
||||
<li>Castra Aestiva (2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2022, 2023, 2024, 2025)</li>
|
||||
<li>Castra Hiberna (2017, 2018, 2021, 2022, 2023)</li>
|
||||
<li>Castra Aestiva (2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2022, 2023, 2024, 2025, 2026)</li>
|
||||
<li>Castra Hiberna (2017, 2018, 2021, 2022, 2023, 2024, 2025)</li>
|
||||
</ul>
|
||||
<h2>Special Thanks</h2>
|
||||
<p>Tom Ross - Legio XXX's <em>patronus</em> (patron) providing re-enactment facilities</p>
|
||||
<p>Robert Sacco - <em>Aquilifer</em> (Eagle bearer) & Legio XXX's president</p>
|
||||
<p>David Blain - <em>Tribunus angusticlavius</em> (staff officer) & subject matter expert</p>
|
||||
<p>Robert Norton - <em>Armicustos</em> (Quartermaster) who provides equipment, repairs & <a routerLink="/diy">manuals</a></p>
|
||||
<p>Robert Norton - <em>Armicustos</em> (Quartermaster) who provides equipment, repairs & <a routerLink="/equipment">manuals</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,12 +2,105 @@
|
||||
<div class="cap-width py-5 px-3">
|
||||
<div class="d-flex align-items-end justify-content-between mb-2">
|
||||
<h1 class="mb-0">Calendar</h1>
|
||||
<a class="d-none d-print-none d-sm-flex justify-content-center text-muted" href="javascript:window.print()">
|
||||
<mat-icon class="me-1">print</mat-icon>
|
||||
Print
|
||||
</a>
|
||||
<div class="d-flex gap-3 align-items-center">
|
||||
<ng-container *ngIf="momentum.admin | async">
|
||||
<button class="d-print-none" mat-raised-button color="primary" (click)="openCreate()">
|
||||
<mat-icon>add</mat-icon> Add Event
|
||||
</button>
|
||||
</ng-container>
|
||||
<a class="d-none d-print-none d-sm-flex justify-content-center text-muted" href="javascript:window.print()">
|
||||
<mat-icon class="me-1">print</mat-icon>
|
||||
Print
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<mat-divider class="mb-4"></mat-divider>
|
||||
<iframe src="https://calendar.google.com/calendar/embed?height=600&wkst=1&bgcolor=%23ffffff&ctz=America%2FToronto&showTitle=0&showNav=1&showPrint=1&showTabs=0&showCalendars=0&src=Y18wYTIxNTM3ZDgwMWMzNTQ0MTUwYzk5YTUwNjI5Yjc5MjM0MjYyYjY0YzYyNzZiZTQ3OWJlMzA4OWU0MmM3NTQ5QGdyb3VwLmNhbGVuZGFyLmdvb2dsZS5jb20&color=%23D50000" style="border-width:0" width="100%" height="600" frameborder="0" scrolling="no"></iframe>
|
||||
|
||||
<div class="d-flex align-items-stretch mb-5 p-3" style="background:#f6eed9">
|
||||
<div style="width:3px;background:currentColor;opacity:.4" class="me-3 flex-shrink-0"></div>
|
||||
<div class="py-1">
|
||||
<div class="text-muted small text-uppercase" style="letter-spacing:.15em">Every Month</div>
|
||||
<div class="fw-bold fs-5">Monthly Online Meetup</div>
|
||||
<div class="text-muted small mb-2">Join us online for our regular group gathering</div>
|
||||
<a class="d-print-none" mat-stroked-button href="/register">Register Now</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="!loading; else spinner">
|
||||
<ng-container *ngIf="events.length">
|
||||
<div *ngFor="let group of groupedEvents" class="mb-5">
|
||||
<div class="text-uppercase small fw-bold mb-3" style="letter-spacing:.2em">{{group.month}}</div>
|
||||
|
||||
<!-- Added print-border class and edit button -->
|
||||
<div *ngFor="let event of group.events" class="d-flex align-items-stretch mb-3 p-3 event-card" style="background:#f6eed9">
|
||||
<div class="text-muted small text-end flex-shrink-0 pe-3" style="min-width:3.5rem">
|
||||
<div class="fw-bold" style="font-size:1.1rem;line-height:1">{{event.date | date:'d'}}</div>
|
||||
<div>{{event.date | date:'EEE'}}</div>
|
||||
<div *ngIf="event.endDate" class="mt-1" style="border-top:1px solid currentColor;opacity:.4;padding-top:.25rem">
|
||||
<div class="fw-bold" style="font-size:1.1rem;line-height:1">{{event.endDate | date:'d'}}</div>
|
||||
<div>{{event.endDate | date:'EEE'}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width:2px;background:currentColor;opacity:.15" class="flex-shrink-0 me-3"></div>
|
||||
<div class="flex-grow-1">
|
||||
<div class="fw-bold">{{event.title}}</div>
|
||||
<div class="text-muted small" *ngIf="event.location">{{event.location}}</div>
|
||||
<div class="text-muted small" *ngIf="!event.endDate">{{event.date | date:'h:mm a'}}</div>
|
||||
<div class="text-muted small" *ngIf="event.endDate">
|
||||
{{event.date | date:'MMM d, h:mm a'}} – {{event.endDate | date:'MMM d, h:mm a'}}
|
||||
</div>
|
||||
<div class="text-muted small fst-italic mt-1" *ngIf="event.description">{{event.description}}</div>
|
||||
</div>
|
||||
<!-- Edit button, screen only -->
|
||||
<ng-container *ngIf="momentum.admin | async">
|
||||
<button class="d-print-none align-self-start ms-2" mat-icon-button (click)="openEdit(event)">
|
||||
<mat-icon>edit</mat-icon>
|
||||
</button>
|
||||
<button class="d-print-none align-self-start" mat-icon-button (click)="deleteEvent(event)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
|
||||
<ng-template #spinner>
|
||||
<div class="text-center py-5"><mat-spinner class="mx-auto"></mat-spinner></div>
|
||||
</ng-template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Create/Edit Dialog -->
|
||||
<ng-template #createDialog>
|
||||
<h2 mat-dialog-title>{{editingId ? 'Edit Event' : 'Add Event'}}</h2>
|
||||
<mat-dialog-content>
|
||||
<mat-form-field class="w-100 mb-2">
|
||||
<mat-label>Title</mat-label>
|
||||
<input matInput [(ngModel)]="form.title" required />
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-100 mb-2">
|
||||
<mat-label>Date & Time</mat-label>
|
||||
<input matInput type="datetime-local" [(ngModel)]="form.date" required />
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-100 mb-2">
|
||||
<mat-label>End Date & Time (optional)</mat-label>
|
||||
<input matInput type="datetime-local" [(ngModel)]="form.endDate" />
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-100 mb-2">
|
||||
<mat-label>Location</mat-label>
|
||||
<input matInput [(ngModel)]="form.location" />
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>Description</mat-label>
|
||||
<textarea matInput [(ngModel)]="form.description" rows="3"></textarea>
|
||||
</mat-form-field>
|
||||
</mat-dialog-content>
|
||||
<mat-dialog-actions align="end">
|
||||
<button mat-button mat-dialog-close>Cancel</button>
|
||||
<button mat-raised-button color="primary" (click)="saveEvent()" [disabled]="saving">
|
||||
{{saving ? 'Saving...' : 'Save'}}
|
||||
</button>
|
||||
</mat-dialog-actions>
|
||||
</ng-template>
|
||||
|
||||
@@ -1,7 +1,90 @@
|
||||
import {Component} from '@angular/core';
|
||||
import {Component, OnInit, TemplateRef, ViewChild} from '@angular/core';
|
||||
import {MatDialog} from '@angular/material/dialog';
|
||||
import {MomentumService} from '../../../services/momentum.service';
|
||||
|
||||
type CalEvent = {
|
||||
_id?: string;
|
||||
title: string;
|
||||
date: string;
|
||||
endDate?: string;
|
||||
location?: string;
|
||||
description?: string;
|
||||
};
|
||||
|
||||
type EventGroup = {
|
||||
month: string;
|
||||
events: CalEvent[];
|
||||
};
|
||||
|
||||
@Component({
|
||||
selector: 'xxx-calendar',
|
||||
templateUrl: './calendar.component.html'
|
||||
})
|
||||
export class CalendarComponent { }
|
||||
export class CalendarComponent implements OnInit {
|
||||
@ViewChild('createDialog') createDialog!: TemplateRef<any>;
|
||||
|
||||
events: CalEvent[] = [];
|
||||
groupedEvents: EventGroup[] = [];
|
||||
loading = true;
|
||||
saving = false;
|
||||
form: Partial<CalEvent> = {};
|
||||
editingId: string | null = null;
|
||||
|
||||
constructor(private dialog: MatDialog, public momentum: MomentumService) {}
|
||||
|
||||
async ngOnInit() {
|
||||
await this.loadEvents();
|
||||
}
|
||||
|
||||
async deleteEvent(event: CalEvent) {
|
||||
if (!event._id || !confirm(`Delete "${event.title}"?`)) return;
|
||||
await this.momentum.api.data.delete('Events', <any>event._id);
|
||||
await this.loadEvents();
|
||||
}
|
||||
|
||||
async loadEvents() {
|
||||
this.loading = true;
|
||||
const raw = await this.momentum.api.data.read<CalEvent>('Events') as CalEvent[];
|
||||
const now = new Date();
|
||||
this.events = raw
|
||||
.filter(e => new Date(e.date) >= now)
|
||||
.sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime());
|
||||
this.groupedEvents = this.groupByMonth(this.events);
|
||||
this.loading = false;
|
||||
}
|
||||
|
||||
groupByMonth(events: CalEvent[]): EventGroup[] {
|
||||
const map = new Map<string, CalEvent[]>();
|
||||
for (const e of events) {
|
||||
const key = new Date(e.date).toLocaleDateString('en-US', {month: 'long', year: 'numeric'});
|
||||
if (!map.has(key)) map.set(key, []);
|
||||
map.get(key)!.push(e);
|
||||
}
|
||||
return Array.from(map.entries()).map(([month, events]) => ({month, events}));
|
||||
}
|
||||
|
||||
openCreate() {
|
||||
this.editingId = null;
|
||||
this.form = {};
|
||||
this.dialog.open(this.createDialog, {width: '480px'});
|
||||
}
|
||||
|
||||
openEdit(event: CalEvent) {
|
||||
this.editingId = event._id ?? null;
|
||||
this.form = {...event};
|
||||
this.dialog.open(this.createDialog, {width: '480px'});
|
||||
}
|
||||
|
||||
async saveEvent() {
|
||||
if (!this.form.title || !this.form.date) return;
|
||||
this.saving = true;
|
||||
if (this.editingId) {
|
||||
await this.momentum.api.data.update<CalEvent>('Events', <any>{_id: this.editingId, ...this.form});
|
||||
} else {
|
||||
await this.momentum.api.data.create<CalEvent>('Events', <any>this.form);
|
||||
}
|
||||
this.dialog.closeAll();
|
||||
this.saving = false;
|
||||
await this.loadEvents();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,22 @@
|
||||
<div class="invert p-5">
|
||||
<div *ngFor="let album of photos" class="mb-5">
|
||||
<h1 class="mb-0">{{album.album}}</h1>
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h1 class="display-4 mb-0">Gallery</h1>
|
||||
|
||||
<ng-container *ngIf="momentum.isLoggedIn | async">
|
||||
<button mat-raised-button color="primary" [matMenuTriggerFor]="uploadMenu">
|
||||
<mat-icon>upload</mat-icon> Upload Photos
|
||||
</button>
|
||||
|
||||
<mat-menu #uploadMenu="matMenu">
|
||||
<button mat-menu-item *ngFor="let y of uploadYears" (click)="upload(y)">{{y}}</button>
|
||||
</mat-menu>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<div *ngFor="let album of photos" class="mb-5" (inView)="loadAlbum(album)">
|
||||
<h1 class="display-6 mb-0">{{album.album}}</h1>
|
||||
<mat-divider class="mb-3"></mat-divider>
|
||||
<div *ngFor="let photo of album.photos; let i = index" class="d-inline-block me-3 mb-3">
|
||||
<div *ngFor="let photo of album.photos" class="d-inline-block me-3 mb-3">
|
||||
<xxx-placeholder [src]="photo.src" [alt]="photo.alt" height="150px" (click)="open(photo)"></xxx-placeholder>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,3 +2,17 @@ xxx-placeholder:hover ::ng-deep img {
|
||||
transform: scale(1.1);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.photo-wrap {
|
||||
.delete-btn {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
right: 4px;
|
||||
transform: scale(0.75);
|
||||
}
|
||||
|
||||
&:hover .delete-btn {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,196 +1,74 @@
|
||||
import {Component} from '@angular/core';
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {MatDialog} from '@angular/material/dialog';
|
||||
import {MomentumService} from '../../services/momentum.service';
|
||||
import {ImageViewerComponent} from '../../components/image-viewer/image-viewer.component';
|
||||
import {Photo} from '../../components/models/photo';
|
||||
|
||||
type Album = {album: string, photos: Photo[], loaded: boolean};
|
||||
|
||||
@Component({
|
||||
selector: 'xxx-gallery',
|
||||
templateUrl: './gallery.component.html',
|
||||
styleUrls: ['./gallery.component.scss'],
|
||||
})
|
||||
export class GalleryComponent {
|
||||
photos: {album: string, photos: Photo[]}[] = [
|
||||
{album: '2023', photos: [
|
||||
{alt: '', src: '/assets/img/gallery/2023/001.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2023/002.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2023/003.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2023/004.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2023/005.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2023/006.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2023/007.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2023/008.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2023/009.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2023/010.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2023/011.jpg'},
|
||||
]}, {album: '2022', photos: [
|
||||
{alt: '', src: '/assets/img/gallery/2022/001.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2022/002.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2022/003.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2022/004.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2022/005.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2022/006.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2022/007.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2022/008.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2022/009.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2022/010.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2022/011.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2022/012.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2022/013.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2022/014.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2022/015.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2022/016.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2022/017.jpg'},
|
||||
]}, {album: '2021', photos: [
|
||||
{alt: '', src: '/assets/img/gallery/2021/001.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2021/002.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2021/003.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2021/004.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2021/005.jpg'},
|
||||
]}, {album: '2019', photos: [
|
||||
{alt: '', src: '/assets/img/gallery/2019/001.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2019/002.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2019/003.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2019/004.jpg'},
|
||||
]}, {album: '2018', photos: [
|
||||
{alt: '', src: '/assets/img/gallery/2018/001.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2018/002.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2018/003.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2018/004.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2018/005.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2018/006.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2018/007.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2018/008.jpg'},
|
||||
]}, {album: '2017', photos: [
|
||||
{alt: '', src: '/assets/img/gallery/2017/001.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2017/002.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2017/003.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2017/004.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2017/005.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2017/006.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2017/007.jpg'},
|
||||
]}, {album: '2016', photos: [
|
||||
{alt: '', src: '/assets/img/gallery/2016/001.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2016/002.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2016/003.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2016/004.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2016/005.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2016/006.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2016/007.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2016/008.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2016/009.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2016/010.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2016/011.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2016/012.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2016/013.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2016/014.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2016/015.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2016/016.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2016/017.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2016/018.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2016/019.jpg'},
|
||||
]}, {album: '2014', photos: [
|
||||
{alt: '', src: '/assets/img/gallery/2014/001.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2014/002.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2014/003.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2014/004.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2014/005.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2014/006.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2014/007.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2014/008.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2014/009.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2014/010.jpg'},
|
||||
]}, {album: '2013', photos: [
|
||||
{alt: '', src: '/assets/img/gallery/2013/001.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2013/002.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2013/003.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2013/004.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2013/005.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2013/006.jpg'},
|
||||
]}, {album: '2012', photos: [
|
||||
{alt: '', src: '/assets/img/gallery/2012/001.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2012/002.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2012/003.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2012/004.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2012/005.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2012/006.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2012/007.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2012/008.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2012/009.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2012/010.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2012/011.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2012/012.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2012/013.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2012/014.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2012/015.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2012/016.jpg'},
|
||||
]}, {album: '2011', photos: [
|
||||
{alt: '', src: '/assets/img/gallery/2011/001.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2011/002.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2011/003.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2011/004.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2011/005.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2011/006.jpg'},
|
||||
]}, {album: '2010', photos: [
|
||||
{alt: '', src: '/assets/img/gallery/2010/001.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2010/002.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2010/003.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2010/004.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2010/005.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2010/006.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2010/007.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2010/008.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2010/009.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2010/010.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2010/011.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2010/012.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2010/013.jpg'},
|
||||
]}, {album: '2009', photos: [
|
||||
{alt: '', src: '/assets/img/gallery/2009/001.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2009/002.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2009/003.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2009/004.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2009/005.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2009/006.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2009/007.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2009/008.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2009/009.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2009/010.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2009/011.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2009/012.jpg'},
|
||||
]}, {album: '2008', photos: [
|
||||
{alt: '', src: '/assets/img/gallery/2008/001.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2008/002.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2008/003.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2008/004.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2008/005.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2008/006.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2008/007.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2008/008.jpg'},
|
||||
]}, {album: '2007', photos: [
|
||||
{alt: '', src: '/assets/img/gallery/2007/001.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2007/002.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2007/003.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2007/004.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2007/005.jpg'},
|
||||
{alt: '', src: '/assets/img/gallery/2007/006.jpg'},
|
||||
]}];
|
||||
export class GalleryComponent implements OnInit {
|
||||
photos: Album[] = [];
|
||||
|
||||
constructor(private dialog: MatDialog) {}
|
||||
constructor(private dialog: MatDialog, public momentum: MomentumService) {}
|
||||
|
||||
get flatten() {
|
||||
return this.photos.reduce((acc: any[], album) => {
|
||||
return [...acc, ...album.photos];
|
||||
}, []);
|
||||
uploadYears = Array.from({length: new Date().getFullYear() - 2006}, (_, i) => 2007 + i).reverse();
|
||||
|
||||
async upload(year: number) {
|
||||
await this.momentum.api.storage.upload(`Photos/Gallery/${year}`, undefined, {multiple: true, accept: 'image/*'});
|
||||
await this.loadAlbums();
|
||||
}
|
||||
|
||||
open(photo: any) {
|
||||
async ngOnInit() {
|
||||
await this.loadAlbums();
|
||||
}
|
||||
|
||||
async loadAlbums() {
|
||||
const files = await this.momentum.api.storage.all('Photos/Gallery');
|
||||
const albumMap = new Map<string, null>();
|
||||
|
||||
for (const file of files.filter((f: any) => f.mime !== 'directory')) {
|
||||
const album = file.path.split('/')[3];
|
||||
albumMap.set(album, null);
|
||||
}
|
||||
|
||||
this.photos = [...albumMap.keys()]
|
||||
.sort((a, b) => +b - +a)
|
||||
.map(album => ({album, photos: [], loaded: false}));
|
||||
}
|
||||
|
||||
async loadAlbum(album: Album) {
|
||||
if (album.loaded) return;
|
||||
album.loaded = true;
|
||||
|
||||
const files = await this.momentum.api.storage.all(`Photos/Gallery/${album.album}`);
|
||||
album.photos = files
|
||||
.filter((f: any) => f.mime !== 'directory')
|
||||
.map((file: any) => ({
|
||||
alt: file.name,
|
||||
src: this.momentum.api.storage.open(file.path, false) as string,
|
||||
path: file.path
|
||||
}));
|
||||
}
|
||||
|
||||
get flatten() {
|
||||
return this.photos.reduce((acc: Photo[], album) => [...acc, ...album.photos], []);
|
||||
}
|
||||
|
||||
open(photo: Photo) {
|
||||
const flat = this.flatten;
|
||||
const index = flat.findIndex(p => p.src == photo.src);
|
||||
const index = flat.findIndex(p => p.src === photo.src);
|
||||
this.dialog.open(ImageViewerComponent, {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
autoFocus: false,
|
||||
data: {index, photos: flat}
|
||||
}).afterClosed().subscribe(result => {
|
||||
if (result?.deleted) this.loadAlbums();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<header id="banner" style="height: calc(100vh - 64px)">
|
||||
<xxx-banner></xxx-banner>
|
||||
</header>
|
||||
|
||||
<!-- ABout -->
|
||||
<section id="about" class="d-flex flex-column flex-md-row align-items-center justify-content-center" style="height: 100vh">
|
||||
<div class="d-none d-md-inline flex-grow-1 text-end" style="flex-basis: 0">
|
||||
@@ -26,6 +27,7 @@
|
||||
<img class="mt-5" src="/assets/img/standard.png" alt="Legio XXX Standard" height="250px" width="auto">
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Discord -->
|
||||
<!--<section class="d-flex" style="background-color: #990000">-->
|
||||
<!-- <div class="d-flex flex-grow-1">-->
|
||||
@@ -48,24 +50,25 @@
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!--</section>-->
|
||||
|
||||
<!-- Meetings -->
|
||||
<section class="d-flex justify-content-center py-4" style="background-color: #990000">
|
||||
|
||||
<div class="d-flex justify-content-start align-items-center">
|
||||
<div class="d-block text-center">
|
||||
<h1 class="d-block m-0 mb-md-3 transparent-link">
|
||||
<a routerLink="/" fragment="contact">Join Our Monthly Meetings</a>
|
||||
<a routerLink="/gallery" style="font-weight: bold; text-decoration: none;">⚔️ Witness the Glory: Explore our Gallery</a>
|
||||
</h1>
|
||||
<div class="d-none d-md-inline">
|
||||
<p>
|
||||
Meet the legion, ask questions, and learn how to get involved.
|
||||
Experience the history and spirit of the legion through our photos.
|
||||
<br><br>
|
||||
Contact us to be added to the event list!
|
||||
See our gear, events, and traditions in action!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Links -->
|
||||
<section id="resources" class="d-flex flex-column flex-md-row align-items-center justify-content-center invert" style="min-height: 50vh; max-height: 100vh; background: url('/assets/img/texture.png') repeat;">
|
||||
<div class="py-5 container">
|
||||
@@ -77,7 +80,7 @@
|
||||
<div>
|
||||
<h3 class="mb-1">Legio XXX</h3>
|
||||
<p class="m-0">Learn about Legio XXX, who we are & what we do</p>
|
||||
<a routerLink="/about">About Us</a> / <a routerLink="/gallery">Gallery</a> / <a routerLink="/" fragment="contact">Contact</a>
|
||||
<a routerLink="/about">About Us</a> / <a routerLink="/" fragment="contact">Contact</a> / <a routerLink="/gallery">Gallery</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex p-3 pe-4 rounded-1 bg-light m-3 align-items-center border" style="min-width: 45%; flex: 1 0 0;">
|
||||
@@ -107,19 +110,20 @@
|
||||
<div>
|
||||
<h3 class="mb-1">Equipment</h3>
|
||||
<p class="m-0">Learn how to assemble & maintain your kit</p>
|
||||
<a routerLink="/buy">Buy Equipment</a> / <a routerLink="/diy">Build Equipment</a> / <a routerLink="/maintenance">Maintenance</a>
|
||||
<a routerLink="/equipment">Acquire Equipment</a> / <a routerLink="/maintenance">Maintenance</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Recruitment -->
|
||||
<section id="recruitment" class="d-flex flex-column flex-md-row align-items-center justify-content-center invert" style="padding: 10rem 0">
|
||||
<div class="flex-grow-1 mt-5 mt-md-0 p-5 pb-0 text-center text-md-end" style="flex-basis: 0">
|
||||
<img src="/assets/img/recruitment.png" alt="Recruitment poster" style="max-width: min(90%, 400px)">
|
||||
</div>
|
||||
<div class="d-flex flex-grow-1 justify-content-start align-items-center" style="flex-basis: 0">
|
||||
<div class="d-block text-center">
|
||||
<div class="d-block text-center d-flex flex-column align-items-center">
|
||||
<h2 class="my-3">Enlist Today!</h2>
|
||||
<p>
|
||||
Interested in any <a routerLink="/events/calendar">events</a>?
|
||||
@@ -130,13 +134,18 @@
|
||||
<br><br>
|
||||
Family participation is welcome!
|
||||
</p>
|
||||
<div class="d-flex align-items-center">
|
||||
<a [routerLink]="['/register']" class="btn btn-light btn-lg" style="background: var(--theme-primary); color: var(--theme-primary-contrast)">JOIN NOW</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Page Break-->
|
||||
<section style="background: #fff">
|
||||
<div style="height: 300px; background: 0 url('/assets/img/formation.png') repeat-x; background-size: auto 300px;"></div>
|
||||
</section>
|
||||
|
||||
<!-- Contact -->
|
||||
<section id="contact" class="d-flex flex-column align-items-center justify-content-center" style="padding: 10rem 0">
|
||||
<div class="container">
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
<div class="invert">
|
||||
<div class="cap-width py-5 px-3">
|
||||
<div class="mb-3">
|
||||
<div class="d-flex align-items-end justify-content-between mb-2">
|
||||
<h1 class="mb-0">Buy Equipment</h1>
|
||||
</div>
|
||||
<mat-divider></mat-divider>
|
||||
</div>
|
||||
<div>
|
||||
<ul>
|
||||
<li><a href="https://armae.com/en" target="_blank">Armæ</a></li>
|
||||
<li><a href="https://www.by-the-sword.com/">By The Sword</a></li>
|
||||
<li><a href="https://www.facebook.com/FabricaCacti" target="_blank">Fabrica Cacti</a></li>
|
||||
<li><a href="http://www.lawrensnest.com">La Wren's Nests</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,7 +0,0 @@
|
||||
import {Component} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'xxx-buy',
|
||||
templateUrl: './buy.component.html'
|
||||
})
|
||||
export class BuyComponent { }
|
||||
@@ -1,21 +0,0 @@
|
||||
<div class="invert">
|
||||
<div class="cap-width py-5 px-3">
|
||||
<div class="mb-3">
|
||||
<div class="d-flex align-items-end justify-content-between mb-2">
|
||||
<h1 class="mb-0">Build Equipment</h1>
|
||||
</div>
|
||||
<mat-divider></mat-divider>
|
||||
</div>
|
||||
<div>
|
||||
<ul>
|
||||
<li><em>Balteus</em> (Belt): <a href="/assets/manuals/Beltus%20Part%201%20-%20Robert%20Norton.pdf" target="_blank"> Part 1</a>, <a href="/assets/manuals/Beltus%20Part%202%20-%20Robert%20Norton.pdf" target="_blank">Part 2</a></li>
|
||||
<li><a href="/assets/manuals/Calcei%20-%20Lee%20Holeva.pdf" target="_blank"><em>Calcei</em> (Boots)</a></li>
|
||||
<li><a href="/assets/manuals/Caligae%20-%20Robert%20Norton.pdf" target="_blank"><em>Caligae</em> (Sandals)</a></li>
|
||||
<li><a href="/assets/manuals/Helmet%20Liner%20-%20Robert%20Norton.pdf" target="_blank">Helmet Liner</a></li>
|
||||
<li><a href="/assets/manuals/Loculus%20-%20Robert%20Norton.pdf" target="_blank"><em>Loculus</em> (Bag)</a></li>
|
||||
<li><em>Lorica Hamata</em> (Chain-mail): <a href="/assets/manuals/Lorica%20Hamata%20Part%201.pdf" target="_blank"> Part 1</a>, <a href="/assets/manuals/Lorica%20Hamata%20Part%202.pdf" target="_blank">Part 2</a></li>
|
||||
<li><a href="/assets/manuals/Scutum.pdf" target="_blank"><em>Scutum</em> (Shield)</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -105,7 +105,7 @@
|
||||
<td>Turn 180° to the right, pivoting on the right heal & left toes.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><em>Ad scuta transformate</em></td>
|
||||
<td><em>Ad scutum transformate</em></td>
|
||||
<td>About Face to the Left</td>
|
||||
<td>Turn 180° to the left, pivoting on the left heal & right toes.</td>
|
||||
</tr>
|
||||
@@ -153,12 +153,12 @@
|
||||
<tr>
|
||||
<td><em>Aciem formate</em></td>
|
||||
<td>Battle line</td>
|
||||
<td>Soldiers form a line with their <em>pilum</em> at the ready. This is not a shield wall, 6' spacing should be maintained between each column.</td>
|
||||
<td>Soldiers form a line with their <em>pilum</em> at the ready. Maintain 6' spacing between each column.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><em>Cuneum formate</em></td>
|
||||
<td>Wedge</td>
|
||||
<td>Centerio is placed at the tip of the wedge with soldiers trailing off his side.</td>
|
||||
<td>The centurio is placed at the tip of the wedge with soldiers trailing off his side.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><em>Orbem formate</em></td>
|
||||
@@ -172,7 +172,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td><em>Testudinem formate</em></td>
|
||||
<td><em>Testudo</em> (Tortis)</td>
|
||||
<td><em>Testudo</em> (Tortoise)</td>
|
||||
<td>First rank raises shields to eye height, the following ranks lift their shields onto their heads overlapping the rank in-front. Formation advances together using a chant to stay in step ("Ro-ma, Ro-ma" or "Dex-Sin, Dex-Sin").</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -242,7 +242,7 @@
|
||||
<tr>
|
||||
<td><em>Ballistam</em></td>
|
||||
<td>Bolt thrower</td>
|
||||
<td>Following command is for <em>scropios</em> / <em>balistas</em>.</td>
|
||||
<td>Following command is for <em>scropio</em> / <em>balista</em>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><em>Catapultam</em></td>
|
||||
@@ -304,13 +304,13 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td><em>Sin[ister]/Gladios</em></td>
|
||||
<td>Right/Sword [hand]</td>
|
||||
<td>Legio XXX prefers to use <em>gladios</em> instead of <em>sin</em>.</td>
|
||||
<td>Left/Shield [hand]</td>
|
||||
<td>Legio XXX prefers to use <em>scuta</em> instead of <em>dex</em>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><em>Dex[ter]/Scuta</em></td>
|
||||
<td>Left/Shield [hand]</td>
|
||||
<td>Legio XXX prefers to use <em>scuta</em> instead of <em>dex</em>.</td>
|
||||
<td>Right/Sword [hand]</td>
|
||||
<td>Legio XXX prefers to use <em>gladios</em> instead of <em>sin</em>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><em>Clamate</em></td>
|
||||
|
||||
40
src/app/views/reenact/equipment/equipment.component.html
Normal file
40
src/app/views/reenact/equipment/equipment.component.html
Normal file
@@ -0,0 +1,40 @@
|
||||
<div class="invert">
|
||||
<div class="cap-width py-5 px-3">
|
||||
<div class="row">
|
||||
<!-- Buy Equipment Card -->
|
||||
<div class="col-12 col-md-6 mb-4">
|
||||
<div class="p-4 border rounded shadow-sm">
|
||||
<div class="mb-3">
|
||||
<h1 class="mb-0">Buy Equipment</h1>
|
||||
<mat-divider class="mt-2"></mat-divider>
|
||||
</div>
|
||||
<ul class="mt-3">
|
||||
<li><a href="https://armae.com/en" target="_blank">Arma</a></li>
|
||||
<li><a href="https://www.by-the-sword.com/">By The Sword</a></li>
|
||||
<li><a href="https://www.facebook.com/FabricaCacti" target="_blank">Fabrica Cacti</a></li>
|
||||
<li><a href="http://www.lawrensnest.com">La Wren's Nests</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Build Equipment Card -->
|
||||
<div class="col-12 col-md-6">
|
||||
<div class="p-4 border rounded shadow-sm">
|
||||
<div class="mb-3">
|
||||
<h1 class="mb-0">Build Equipment</h1>
|
||||
<mat-divider class="mt-2"></mat-divider>
|
||||
</div>
|
||||
<ul class="mt-3">
|
||||
<li><em>Balteus</em> (Belt): <a href="/assets/manuals/Beltus%20Part%201%20-%20Robert%20Norton.pdf" target="_blank"> Part 1</a>, <a href="/assets/manuals/Beltus%20Part%202%20-%20Robert%20Norton.pdf" target="_blank">Part 2</a></li>
|
||||
<li><a href="/assets/manuals/Calcei%20-%20Lee%20Holeva.pdf" target="_blank"><em>Calcei</em> (Boots)</a></li>
|
||||
<li><a href="/assets/manuals/Caligae%20-%20Robert%20Norton.pdf" target="_blank"><em>Caligae</em> (Sandals)</a></li>
|
||||
<li><a href="/assets/manuals/Helmet%20Liner%20-%20Robert%20Norton.pdf" target="_blank">Helmet Liner</a></li>
|
||||
<li><a href="/assets/manuals/Loculus%20-%20Robert%20Norton.pdf" target="_blank"><em>Loculus</em> (Bag)</a></li>
|
||||
<li><em>Lorica Hamata</em> (Chain-mail): <a href="/assets/manuals/Lorica%20Hamata%20Part%201.pdf" target="_blank"> Part 1</a>, <a href="/assets/manuals/Lorica%20Hamata%20Part%202.pdf" target="_blank">Part 2</a></li>
|
||||
<li><a href="/assets/manuals/Scutum.pdf" target="_blank"><em>Scutum</em> (Shield)</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2,6 +2,6 @@ import {Component} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'xxx-diy',
|
||||
templateUrl: './diy.component.html'
|
||||
templateUrl: './equipment.component.html'
|
||||
})
|
||||
export class DiyComponent { }
|
||||
export class EquipmentComponent { }
|
||||
@@ -24,7 +24,7 @@
|
||||
<h2 class="mb-2">Enlisting</h2>
|
||||
<p>
|
||||
If reenacting is something you would seriously like to do, great! Interest in the history of Rome is the primary requirement and you are in the right place. This guide will walk you through everything
|
||||
you need to know to get started. Acquiring a full kit may take some time & cost a couple thousand dollars (USD/CAD) however we provide <a routerLink="/diy">manuals</a> to build equipment yourself
|
||||
you need to know to get started. Acquiring a full kit may take some time & cost a couple thousand dollars (USD/CAD) however we provide <a routerLink="/equipment">manuals</a> to build equipment yourself
|
||||
to save on costs. With enough notice we may be able to loan any equipment you are missing for an event, please let us know.
|
||||
</p>
|
||||
<p>
|
||||
@@ -35,6 +35,11 @@
|
||||
<div class="d-flex flex-column flex-md-row justify-content-md-between">
|
||||
<div class="me-md-3">
|
||||
<ul class="mt-0">
|
||||
<li>Enlist with your local reenactment group:
|
||||
<ul>
|
||||
<li><strong>Southern-Ontario</strong> - <a routerLink="/register">Enlist with Legio XXX</a></li>
|
||||
<li><em>Elsewhere</em> - <a href="" target="_blank">Find your local recruiter</a></li>
|
||||
</ul>
|
||||
<li>Familiarize yourself with our <a routerLink="/rules">Rules & Regulations</a></li>
|
||||
<li>Pick out a Roman name:</li>
|
||||
<ul>
|
||||
@@ -42,7 +47,7 @@
|
||||
<li>Can be fictional or non-fictional</li>
|
||||
<li>Avoid famous people/names</li>
|
||||
</ul>
|
||||
<li><a routerLink="/vendors">Purchase</a>, <a routerLink="/diy">build</a> or arrange for loaner equipment by reaching out. Bold items are considered the minimum camp attire:</li>
|
||||
<li><a routerLink="/equipment">Purchase, build</a> or arrange for equipment by reaching out. Bold items are minimum camp attire:</li>
|
||||
<ul>
|
||||
<li><span class="fw-bold"><em>Tunica</em> (Tunic)</span> - A large shirt/dress held at the waist by a cord or cloth belt</li>
|
||||
<li><span class="fw-bold"><em>Caligae</em> (Sandals)</span> - Modern leather sandals will do in a pinch</li>
|
||||
@@ -56,7 +61,7 @@
|
||||
<li><em>Subarmalis</em> (Padded Vest) - Worn under your armour for comfort and protection</li>
|
||||
<li><em>Lorica</em> (Armour) - Segmata, hamata or plumata/squamta</li>
|
||||
</ul>
|
||||
<li>Submit an <a href="/assets/docs/Application.pdf" target="_blank">application</a> to Robert Sacco: <a href="mailto:primuspiluslxxx@gmail.com" target="_blank">primuspiluslxxx@gmail.com</a></li>
|
||||
<li><a routerLink="/events/calendar">Go to your first event!</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="d-flex d-print-none align-items-center justify-content-center pt-4">
|
||||
|
||||
129
src/app/views/register/register.component.html
Normal file
129
src/app/views/register/register.component.html
Normal file
@@ -0,0 +1,129 @@
|
||||
<div class="invert">
|
||||
<div class="banner d-print-none"></div>
|
||||
<div class="cap-width py-5 px-3">
|
||||
<div>
|
||||
<img src="/assets/img/header.png" alt="Legio XXX" class="mx-auto d-block">
|
||||
<hr>
|
||||
</div>
|
||||
|
||||
<div *ngIf="success" class="alert alert-success">
|
||||
✅ Your registration has been submitted! We will be in touch soon.
|
||||
</div>
|
||||
<div *ngIf="error" class="alert alert-danger">
|
||||
⚠️ Something went wrong, please try again or contact us directly.
|
||||
</div>
|
||||
|
||||
<form #form="ngForm" (ngSubmit)="submit(form.value)" [class.locked]="success">
|
||||
<h3 class="fw-bold mb-2">Member Information</h3>
|
||||
<h4 class="bg-black p-2 text-center text-white fw-bold">Personal Information</h4>
|
||||
|
||||
<div class="row g-3 mb-3">
|
||||
<div class="field col-4">
|
||||
<label>Last Name <span class="required">*</span></label>
|
||||
<input ngModel name="lastName" required [disabled]="success">
|
||||
</div>
|
||||
<div class="field col-4">
|
||||
<label>First Name <span class="required">*</span></label>
|
||||
<input ngModel name="firstName" required [disabled]="success">
|
||||
</div>
|
||||
<div class="field col-4">
|
||||
<label>Date of Birth <span class="required">*</span></label>
|
||||
<input ngModel name="dateOfBirth" type="date" required [disabled]="success">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br><br><br>
|
||||
|
||||
<div class="row g-3 mb-3">
|
||||
<div class="field col-8">
|
||||
<label>Street Address</label>
|
||||
<input ngModel name="streetAddress" [disabled]="success">
|
||||
</div>
|
||||
<div class="field col-4">
|
||||
<label>Apartment/Unit #</label>
|
||||
<input ngModel name="unit" [disabled]="success">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-3 mb-3">
|
||||
<div class="field col-4">
|
||||
<label>City</label>
|
||||
<input ngModel name="city" [disabled]="success">
|
||||
</div>
|
||||
<div class="field col-4">
|
||||
<label>Province/State</label>
|
||||
<input ngModel name="province" [disabled]="success">
|
||||
</div>
|
||||
<div class="field col-4">
|
||||
<label>Postal Code</label>
|
||||
<input ngModel name="postalCode" [disabled]="success">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br><br><br>
|
||||
|
||||
<div class="row g-3 mb-3">
|
||||
<div class="field col-6">
|
||||
<label>Home Phone <span class="required">*</span></label>
|
||||
<input ngModel name="homePhone" type="tel" [disabled]="success" required>
|
||||
</div>
|
||||
<div class="field col-6">
|
||||
<label>Alternate Phone</label>
|
||||
<input ngModel name="alternatePhone" type="tel" [disabled]="success">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field mb-3">
|
||||
<label>Email <span class="required">*</span></label>
|
||||
<input ngModel name="email" type="email" required [disabled]="success">
|
||||
</div>
|
||||
|
||||
<h4 class="bg-black p-2 text-center text-white fw-bold">Reenacting</h4>
|
||||
|
||||
<div class="field mb-3">
|
||||
<label>Chosen Roman Name</label>
|
||||
<input ngModel name="romanName" [disabled]="success">
|
||||
</div>
|
||||
|
||||
<div class="row g-3 mb-3">
|
||||
<div class="field col-6">
|
||||
<label>First Choice of Position</label>
|
||||
<input ngModel name="positionFirst" [disabled]="success">
|
||||
</div>
|
||||
<div class="field col-6">
|
||||
<label>Second Choice of Position</label>
|
||||
<input ngModel name="positionSecond" [disabled]="success">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field mb-3">
|
||||
<label>Have you ever re-enacted?</label>
|
||||
<input ngModel name="previousReenacting" [disabled]="success">
|
||||
</div>
|
||||
|
||||
<br><br><br>
|
||||
|
||||
<div class="field mb-3">
|
||||
<label>Special Skills</label>
|
||||
<textarea ngModel name="specialSkills" rows="3" [disabled]="success"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="field mb-3">
|
||||
<label>Physical Limitations</label>
|
||||
<textarea ngModel name="physicalLimitations" rows="3" [disabled]="success"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="field mb-3">
|
||||
<label>Comments</label>
|
||||
<textarea ngModel name="comments" rows="5" [disabled]="success"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-end">
|
||||
<button type="submit" [disabled]="form.invalid || loading || success">
|
||||
{{ loading ? 'Submitting...' : 'Submit Registration' }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
100
src/app/views/register/register.component.ts
Normal file
100
src/app/views/register/register.component.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
import {Component} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'xxx-register',
|
||||
templateUrl: './register.component.html',
|
||||
styles: [`
|
||||
.extra-spacing li { margin-bottom: 1em }
|
||||
|
||||
form { color: #000; }
|
||||
|
||||
hr { border-color: rgba(0,0,0,0.2); }
|
||||
|
||||
h3, h4 { color: #000; }
|
||||
|
||||
.alert {
|
||||
padding: 12px 16px;
|
||||
margin-bottom: 1em;
|
||||
font-weight: 600;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.alert-success {
|
||||
background: #d4edda;
|
||||
color: #155724;
|
||||
border: 1px solid #c3e6cb;
|
||||
}
|
||||
.alert-danger {
|
||||
background: #f8d7da;
|
||||
color: #721c24;
|
||||
border: 1px solid #f5c6cb;
|
||||
}
|
||||
|
||||
.required { color: red; }
|
||||
|
||||
.field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.field label {
|
||||
font-size: 0.75em;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.field input,
|
||||
.field textarea {
|
||||
border: none;
|
||||
border-bottom: 2px solid #333;
|
||||
background: transparent;
|
||||
color: #000;
|
||||
font-size: 1em;
|
||||
padding: 4px 2px;
|
||||
outline: none;
|
||||
width: 100%;
|
||||
font-family: inherit;
|
||||
}
|
||||
.field input:focus,
|
||||
.field textarea:focus {
|
||||
border-bottom-color: #000;
|
||||
}
|
||||
.field input:disabled,
|
||||
.field textarea:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.field textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
button[type=submit] {
|
||||
background: #000;
|
||||
color: #fff;
|
||||
border: none;
|
||||
padding: 10px 28px;
|
||||
font-size: 1em;
|
||||
cursor: pointer;
|
||||
}
|
||||
button[type=submit]:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
`]
|
||||
})
|
||||
export class RegisterComponent {
|
||||
loading = false;
|
||||
success = false;
|
||||
error = false;
|
||||
|
||||
async submit(value: any) {
|
||||
this.loading = true;
|
||||
this.error = false;
|
||||
try {
|
||||
await window.momentum.data.create('Applications', value);
|
||||
this.success = true;
|
||||
} catch {
|
||||
this.error = true;
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,13 +15,16 @@
|
||||
<div>
|
||||
<h2 class="mb-2">Websites</h2>
|
||||
<ul class="mt-0">
|
||||
<li><a href="https://www.erminestreetguard.co.uk" target="_blank">The Ermine Street Guard (https://erminestreetguard.co.uk)</a></li>
|
||||
<li><a href="https://www.jstor.org/journal/jromanstudies">The Journal of Roman Studies (https://jstor.org)</a></li>
|
||||
<li><a href="https://www.larp.com/legioxx/hndbk.html" target="_blank">Legio XX Handbook (https://larp.com/legioxx)</a></li>
|
||||
<li><a href="https://principialegionis.org" target="_blank">Principia Legionis (https://principialegionis.org)</a></li>
|
||||
<li><a href="https://www.erminestreetguard.co.uk" target="_blank">The Ermine Street Guard (https://www.erminestreetguard.co.uk)</a></li>
|
||||
<li><a href="https://www.romanempire.net">Roman Empire Groups (https://romanempire.net)</a></li>
|
||||
<li><a href="https://www.romansociety.org">The Roman Society (https://romansociety.org)</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="mb-2">Modern</h2>
|
||||
<h2 class="mb-2">Modern Literature</h2>
|
||||
<h3 class="mb-2">Life</h3>
|
||||
<ul>
|
||||
<li>Adkins, Lesley and Adkins, Roy A. <strong>Handbook to Life in Ancient Rome</strong>: New York: Oxford University Press, 1994</li>
|
||||
@@ -58,7 +61,7 @@
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="mb-2">Historical</h2>
|
||||
<h2 class="mb-2">Historical Literature</h2>
|
||||
<h3 class="mb-2">Accounts</h3>
|
||||
<ul class="mt-0 extra-spacing">
|
||||
<li>
|
||||
|
||||
Reference in New Issue
Block a user