From e051c6487960ebc50b92b0195317ecfa44dfd486 Mon Sep 17 00:00:00 2001 From: Jon Andre Briones Date: Sun, 17 Aug 2025 11:44:22 -0700 Subject: [PATCH 1/7] refactor: changed links that are used in anchors --- .../external-link/link.component.html | 4 +++- .../external-link/link.component.ts | 20 +++++++++++++++++-- src/app/components/external-link/links.ts | 3 ++- src/app/pages/events/events.component.html | 7 +++---- src/app/pages/events/events.component.ts | 6 ++++-- 5 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/app/components/external-link/link.component.html b/src/app/components/external-link/link.component.html index ced2c343..c867ab9e 100644 --- a/src/app/components/external-link/link.component.html +++ b/src/app/components/external-link/link.component.html @@ -1 +1,3 @@ - {{ _label() }} + + {{ _label() }} + diff --git a/src/app/components/external-link/link.component.ts b/src/app/components/external-link/link.component.ts index bc2ed9f7..4c6576d3 100644 --- a/src/app/components/external-link/link.component.ts +++ b/src/app/components/external-link/link.component.ts @@ -12,9 +12,25 @@ import { EXTERNAL_LINKS, ExternalLink } from './links'; changeDetection: ChangeDetectionStrategy.OnPush }) export class LinkComponent { + /** + * The link that should be used from `links.ts` + */ link = input.required(); - protected _label = computed(() => capitalize(this.link())); + + /** + * Overrides the label that is displayed. + */ + label = input(); + + /** + * Label that is displayed in the element. + */ + protected _label = computed(() => this.label() ?? capitalize(this.link())); + + /** + * The href used to move the user to the external link/route. + */ protected _href = computed(() => EXTERNAL_LINKS[this.link()]); - protected externalLink = faUpRightFromSquare; + protected externalLinkIcon = faUpRightFromSquare; } diff --git a/src/app/components/external-link/links.ts b/src/app/components/external-link/links.ts index 927a9ad4..96908687 100644 --- a/src/app/components/external-link/links.ts +++ b/src/app/components/external-link/links.ts @@ -1,7 +1,8 @@ export const EXTERNAL_LINKS = { constitution: 'https://github.com/CSSS/public-docs/blob/master/constitutions/', discord: 'https://discord.sfucsss.org', - commonRoomMap: 'https://roomfinder.sfu.ca/apps/sfuroomfinder_web/?q=ASB%209971' + commonRoomMap: 'https://roomfinder.sfu.ca/apps/sfuroomfinder_web/?q=ASB%209971', + boardgameRoomMap: 'https://roomfinder.sfu.ca/apps/sfuroomfinder_web/?q=TASC1%209204' } as const; export type ExternalLink = keyof typeof EXTERNAL_LINKS; diff --git a/src/app/pages/events/events.component.html b/src/app/pages/events/events.component.html index b4d4a91a..ed7b74d3 100644 --- a/src/app/pages/events/events.component.html +++ b/src/app/pages/events/events.component.html @@ -4,7 +4,7 @@

Events

The CSSS runs a combination of regular and yearly events. From meetings to Hackathons, we try and make sure there's something for everyone. We send out reminders through email, on our - Discord +

Regular Events

@@ -30,9 +30,8 @@

Board Game Nights

If meetings aren't exciting enough for you, join us for boardgame nights! Every other Friday we book - TASC 9204 , pull out a few board games and give out FREE FOOD. If you're down for some + + , pull out a few board games and give out FREE FOOD. If you're down for some Friday night fun, then pull up, sit down, and, maybe, just maybe, the Executives will serenade you with karaoke.

diff --git a/src/app/pages/events/events.component.ts b/src/app/pages/events/events.component.ts index 35efdd20..e0087c9f 100644 --- a/src/app/pages/events/events.component.ts +++ b/src/app/pages/events/events.component.ts @@ -2,15 +2,17 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import { ArticleComponent } from '@csss-code/article/article.component'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; import { faUpRightFromSquare } from '@fortawesome/free-solid-svg-icons'; +import { LinkComponent } from 'components/external-link/link.component'; +import { EXTERNAL_LINKS } from 'components/external-link/links'; @Component({ selector: 'cs-events', - imports: [ArticleComponent, FontAwesomeModule], + imports: [ArticleComponent, FontAwesomeModule, LinkComponent], templateUrl: './events.component.html', styleUrl: './events.component.scss', changeDetection: ChangeDetectionStrategy.OnPush }) export class EventsComponent { externalLinkIcon = faUpRightFromSquare; - roomFinderLink = 'https://roomfinder.sfu.ca/apps/sfuroomfinder_web/?q=TASC1%209204'; + roomFinderLink = EXTERNAL_LINKS['boardgameRoomMap']; } From ae615c23e5297558f85b806758b7b2df2f285292 Mon Sep 17 00:00:00 2001 From: Jon Andre Briones Date: Sun, 17 Aug 2025 16:54:00 -0700 Subject: [PATCH 2/7] refactor: abstracted out the link component type --- .../external-link/link.component.scss | 5 --- src/app/components/external-link/links.ts | 8 ---- .../base-link.component.ts} | 13 +++--- .../url/email-link/email-link.component.html | 3 ++ .../url/email-link/email-link.component.scss | 0 .../email-link/email-link.component.spec.ts | 23 +++++++++++ .../url/email-link/email-link.component.ts | 15 +++++++ .../external-link.component.html} | 0 .../external-link.component.scss | 5 +++ .../external-link.component.spec.ts} | 10 ++--- .../external-link/external-link.component.ts | 16 ++++++++ src/app/components/url/links.data.ts | 40 +++++++++++++++++++ .../url/route-link/route-link.component.html | 1 + .../url/route-link/route-link.component.scss | 0 .../route-link/route-link.component.spec.ts | 23 +++++++++++ .../url/route-link/route-link.component.ts | 12 ++++++ .../common-room/common-room.component.ts | 2 +- .../pages/elections/elections.component.ts | 4 +- src/app/pages/events/events.component.ts | 6 +-- src/app/pages/readme/readme.component.ts | 4 +- 20 files changed, 157 insertions(+), 33 deletions(-) delete mode 100644 src/app/components/external-link/link.component.scss delete mode 100644 src/app/components/external-link/links.ts rename src/app/components/{external-link/link.component.ts => url/base-link.component.ts} (67%) create mode 100644 src/app/components/url/email-link/email-link.component.html create mode 100644 src/app/components/url/email-link/email-link.component.scss create mode 100644 src/app/components/url/email-link/email-link.component.spec.ts create mode 100644 src/app/components/url/email-link/email-link.component.ts rename src/app/components/{external-link/link.component.html => url/external-link/external-link.component.html} (100%) create mode 100644 src/app/components/url/external-link/external-link.component.scss rename src/app/components/{external-link/link.component.spec.ts => url/external-link/external-link.component.spec.ts} (58%) create mode 100644 src/app/components/url/external-link/external-link.component.ts create mode 100644 src/app/components/url/links.data.ts create mode 100644 src/app/components/url/route-link/route-link.component.html create mode 100644 src/app/components/url/route-link/route-link.component.scss create mode 100644 src/app/components/url/route-link/route-link.component.spec.ts create mode 100644 src/app/components/url/route-link/route-link.component.ts diff --git a/src/app/components/external-link/link.component.scss b/src/app/components/external-link/link.component.scss deleted file mode 100644 index eb6ad8c8..00000000 --- a/src/app/components/external-link/link.component.scss +++ /dev/null @@ -1,5 +0,0 @@ -@use 'theme' as t; - -a { - color: t.$accent2; -} diff --git a/src/app/components/external-link/links.ts b/src/app/components/external-link/links.ts deleted file mode 100644 index 96908687..00000000 --- a/src/app/components/external-link/links.ts +++ /dev/null @@ -1,8 +0,0 @@ -export const EXTERNAL_LINKS = { - constitution: 'https://github.com/CSSS/public-docs/blob/master/constitutions/', - discord: 'https://discord.sfucsss.org', - commonRoomMap: 'https://roomfinder.sfu.ca/apps/sfuroomfinder_web/?q=ASB%209971', - boardgameRoomMap: 'https://roomfinder.sfu.ca/apps/sfuroomfinder_web/?q=TASC1%209204' -} as const; - -export type ExternalLink = keyof typeof EXTERNAL_LINKS; diff --git a/src/app/components/external-link/link.component.ts b/src/app/components/url/base-link.component.ts similarity index 67% rename from src/app/components/external-link/link.component.ts rename to src/app/components/url/base-link.component.ts index 4c6576d3..da902b9b 100644 --- a/src/app/components/external-link/link.component.ts +++ b/src/app/components/url/base-link.component.ts @@ -1,21 +1,20 @@ -import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core'; +import { ChangeDetectionStrategy, Component, computed, input, Signal } from '@angular/core'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; import { faUpRightFromSquare } from '@fortawesome/free-solid-svg-icons'; import { capitalize } from 'utils/string-utils'; -import { EXTERNAL_LINKS, ExternalLink } from './links'; +import { CsssLink } from './links.data'; @Component({ selector: 'cs-external-link', imports: [FontAwesomeModule], - templateUrl: './link.component.html', - styleUrl: './link.component.scss', + template: '', changeDetection: ChangeDetectionStrategy.OnPush }) -export class LinkComponent { +export abstract class BaseLinkComponent { /** * The link that should be used from `links.ts` */ - link = input.required(); + link = input.required(); /** * Overrides the label that is displayed. @@ -30,7 +29,7 @@ export class LinkComponent { /** * The href used to move the user to the external link/route. */ - protected _href = computed(() => EXTERNAL_LINKS[this.link()]); + protected abstract _href: Signal; protected externalLinkIcon = faUpRightFromSquare; } diff --git a/src/app/components/url/email-link/email-link.component.html b/src/app/components/url/email-link/email-link.component.html new file mode 100644 index 00000000..ecc329fd --- /dev/null +++ b/src/app/components/url/email-link/email-link.component.html @@ -0,0 +1,3 @@ + + {{ _label() }} + diff --git a/src/app/components/url/email-link/email-link.component.scss b/src/app/components/url/email-link/email-link.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/components/url/email-link/email-link.component.spec.ts b/src/app/components/url/email-link/email-link.component.spec.ts new file mode 100644 index 00000000..8d5f8d5b --- /dev/null +++ b/src/app/components/url/email-link/email-link.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { EmailLinkComponent } from './email-link.component'; + +describe('EmailLinkComponent', () => { + let component: EmailLinkComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [EmailLinkComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(EmailLinkComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/url/email-link/email-link.component.ts b/src/app/components/url/email-link/email-link.component.ts new file mode 100644 index 00000000..dd1a3b11 --- /dev/null +++ b/src/app/components/url/email-link/email-link.component.ts @@ -0,0 +1,15 @@ +import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core'; +import { BaseLinkComponent } from '../base-link.component'; +import { EmailLink, EMAILS } from '../links.data'; + +@Component({ + selector: 'cs-email-link', + imports: [], + templateUrl: './email-link.component.html', + styleUrl: './email-link.component.scss', + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class EmailLinkComponent extends BaseLinkComponent { + override link = input.required(); + protected override _href = computed(() => EMAILS[this.link()]); +} diff --git a/src/app/components/external-link/link.component.html b/src/app/components/url/external-link/external-link.component.html similarity index 100% rename from src/app/components/external-link/link.component.html rename to src/app/components/url/external-link/external-link.component.html diff --git a/src/app/components/url/external-link/external-link.component.scss b/src/app/components/url/external-link/external-link.component.scss new file mode 100644 index 00000000..79872786 --- /dev/null +++ b/src/app/components/url/external-link/external-link.component.scss @@ -0,0 +1,5 @@ +@use '../../../../ui/csss-code/theme' as t; + +a { + color: t.$accent2; +} diff --git a/src/app/components/external-link/link.component.spec.ts b/src/app/components/url/external-link/external-link.component.spec.ts similarity index 58% rename from src/app/components/external-link/link.component.spec.ts rename to src/app/components/url/external-link/external-link.component.spec.ts index 3cabf752..0cbbb329 100644 --- a/src/app/components/external-link/link.component.spec.ts +++ b/src/app/components/url/external-link/external-link.component.spec.ts @@ -1,17 +1,17 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { LinkComponent } from './link.component'; +import { ExternalLinkComponent } from './external-link.component'; describe('ExternalLinkComponent', () => { - let component: LinkComponent; - let fixture: ComponentFixture; + let component: ExternalLinkComponent; + let fixture: ComponentFixture; beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [LinkComponent] + imports: [ExternalLinkComponent] }).compileComponents(); - fixture = TestBed.createComponent(LinkComponent); + fixture = TestBed.createComponent(ExternalLinkComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/src/app/components/url/external-link/external-link.component.ts b/src/app/components/url/external-link/external-link.component.ts new file mode 100644 index 00000000..538f70bc --- /dev/null +++ b/src/app/components/url/external-link/external-link.component.ts @@ -0,0 +1,16 @@ +import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core'; +import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; +import { BaseLinkComponent } from '../base-link.component'; +import { EXTERNAL_LINKS, ExternalLink } from '../links.data'; + +@Component({ + selector: 'cs-external-link', + imports: [FontAwesomeModule], + templateUrl: './external-link.component.html', + styleUrl: './external-link.component.scss', + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ExternalLinkComponent extends BaseLinkComponent { + override link = input.required(); + protected override _href = computed(() => EXTERNAL_LINKS[this.link()]); +} diff --git a/src/app/components/url/links.data.ts b/src/app/components/url/links.data.ts new file mode 100644 index 00000000..f3dd20f6 --- /dev/null +++ b/src/app/components/url/links.data.ts @@ -0,0 +1,40 @@ +/** + * Links to external sites. + * Please try and keep the keys in alphabetical order. + **/ +export const EXTERNAL_LINKS = { + boardgameRoomMap: 'https://roomfinder.sfu.ca/apps/sfuroomfinder_web/?q=TASC1%209204', + commonRoomMap: 'https://roomfinder.sfu.ca/apps/sfuroomfinder_web/?q=ASB%209971', + constitution: + 'https://github.com/CSSS/public-docs/blob/master/constitutions/Constitution_July_2024.pdf', + discord: 'https://discord.sfucsss.org' +} as const; + +export type ExternalLink = keyof typeof EXTERNAL_LINKS; + +export const EMAILS = { + computingScienceOffice: 'cspc1@sfu.ca', + // CSSS + csssGeneral: 'csss@sfu.ca', + csssCurrentExec: 'csss-exec-current@sfu.ca', + csssPastExec: 'csss-exec@sfu.ca', + csssPresident: 'csss-president-current@sfu.ca', + csssVp: 'csss-vp-current@sfu.ca', + csssTreasurer: 'csss-treasurer-current@sfu.ca', + csssDoR: 'csss-dor-current@sfu.ca', + csssDoE: 'csss-doe-current@sfu.ca', + csssDoEE: 'csss-doee-current@sfu.ca', + csssADoE: 'csss-adoe-current@sfu.ca', + csssDoC: 'csss-doc-current@sfu.ca', + csssDoMM: 'csss-domm-current@sfu.ca', + csssDoA: 'csss-doa-current@sfu.ca', + csssCouncilRep: 'csss-councilrep-current@sfu.ca', + csssSysAdmin: 'csss-sysadmin@sfu.ca', + csssWebmaster: 'csss-webmaster@sfu.ca', + csssFroshChair: 'csss-froshchair@sfu.ca', + csssTechFairChair: 'csss-techfair@sfu.ca' +} as const; + +export type EmailLink = keyof typeof EMAILS; + +export type CsssLink = EmailLink | ExternalLink; diff --git a/src/app/components/url/route-link/route-link.component.html b/src/app/components/url/route-link/route-link.component.html new file mode 100644 index 00000000..7423d877 --- /dev/null +++ b/src/app/components/url/route-link/route-link.component.html @@ -0,0 +1 @@ +

route-link works!

diff --git a/src/app/components/url/route-link/route-link.component.scss b/src/app/components/url/route-link/route-link.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/components/url/route-link/route-link.component.spec.ts b/src/app/components/url/route-link/route-link.component.spec.ts new file mode 100644 index 00000000..71034fa3 --- /dev/null +++ b/src/app/components/url/route-link/route-link.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { RouteLinkComponent } from './route-link.component'; + +describe('RouteLinkComponent', () => { + let component: RouteLinkComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [RouteLinkComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(RouteLinkComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/url/route-link/route-link.component.ts b/src/app/components/url/route-link/route-link.component.ts new file mode 100644 index 00000000..4291a394 --- /dev/null +++ b/src/app/components/url/route-link/route-link.component.ts @@ -0,0 +1,12 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; + +@Component({ + selector: 'cs-route-link', + imports: [], + templateUrl: './route-link.component.html', + styleUrl: './route-link.component.scss', + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class RouteLinkComponent { + +} diff --git a/src/app/pages/common-room/common-room.component.ts b/src/app/pages/common-room/common-room.component.ts index 9f04c5fa..b4cba179 100644 --- a/src/app/pages/common-room/common-room.component.ts +++ b/src/app/pages/common-room/common-room.component.ts @@ -3,7 +3,7 @@ import { ArticleComponent } from '@csss-code/article/article.component'; import { CardComponent } from '@csss-code/card/card.component'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; import { faArrowUpRightFromSquare } from '@fortawesome/free-solid-svg-icons'; -import { EXTERNAL_LINKS } from 'components/external-link/links'; +import { EXTERNAL_LINKS } from 'components/url/links.data'; @Component({ selector: 'cs-common-room', diff --git a/src/app/pages/elections/elections.component.ts b/src/app/pages/elections/elections.component.ts index ecda63bd..07a3738b 100644 --- a/src/app/pages/elections/elections.component.ts +++ b/src/app/pages/elections/elections.component.ts @@ -5,7 +5,7 @@ import { CodeTabGroupComponent } from '@csss-code/tabs/tab-group/tab-group.compo import { CodeTabComponent } from '@csss-code/tabs/tab.component'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; import { faSquareCheck } from '@fortawesome/free-solid-svg-icons'; -import { LinkComponent } from 'components/external-link/link.component'; +import { ExternalLinkComponent } from 'components/url/external-link/external-link.component'; import { ELECTED_DESCRIPTIONS, EXEC_DESCRIPTIONS } from 'pages/officers/officers.data'; @Component({ @@ -14,7 +14,7 @@ import { ELECTED_DESCRIPTIONS, EXEC_DESCRIPTIONS } from 'pages/officers/officers NgTemplateOutlet, ArticleComponent, FontAwesomeModule, - LinkComponent, + ExternalLinkComponent, CodeTabGroupComponent, CodeTabComponent ], diff --git a/src/app/pages/events/events.component.ts b/src/app/pages/events/events.component.ts index e0087c9f..934a3687 100644 --- a/src/app/pages/events/events.component.ts +++ b/src/app/pages/events/events.component.ts @@ -2,12 +2,12 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import { ArticleComponent } from '@csss-code/article/article.component'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; import { faUpRightFromSquare } from '@fortawesome/free-solid-svg-icons'; -import { LinkComponent } from 'components/external-link/link.component'; -import { EXTERNAL_LINKS } from 'components/external-link/links'; +import { ExternalLinkComponent } from 'components/url/external-link/external-link.component'; +import { EXTERNAL_LINKS } from 'components/url/links.data'; @Component({ selector: 'cs-events', - imports: [ArticleComponent, FontAwesomeModule, LinkComponent], + imports: [ArticleComponent, FontAwesomeModule, ExternalLinkComponent], templateUrl: './events.component.html', styleUrl: './events.component.scss', changeDetection: ChangeDetectionStrategy.OnPush diff --git a/src/app/pages/readme/readme.component.ts b/src/app/pages/readme/readme.component.ts index c44e4fb3..450fe4aa 100644 --- a/src/app/pages/readme/readme.component.ts +++ b/src/app/pages/readme/readme.component.ts @@ -10,13 +10,13 @@ import { RouterModule } from '@angular/router'; import { CardComponent } from '@csss-code/card/card.component'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; import { faArrowDown, faArrowUpRightFromSquare } from '@fortawesome/free-solid-svg-icons'; -import { LinkComponent } from 'components/external-link/link.component'; +import { ExternalLinkComponent } from 'components/url/external-link/external-link.component'; import { gsap } from 'gsap'; import { SplitText } from 'gsap/SplitText'; @Component({ selector: 'cs-readme', - imports: [CardComponent, RouterModule, FontAwesomeModule, LinkComponent], + imports: [CardComponent, RouterModule, FontAwesomeModule, ExternalLinkComponent], templateUrl: './readme.component.html', styleUrl: './readme.component.scss', changeDetection: ChangeDetectionStrategy.OnPush From f5b776215cefab756efae40fad5ab2944d16ce3a Mon Sep 17 00:00:00 2001 From: Jon Andre Briones Date: Sun, 17 Aug 2025 17:24:02 -0700 Subject: [PATCH 3/7] refactor: committees page now updated to use links --- src/app/components/nav-bar/nav-entries.ts | 5 +- .../url/email-link/email-link.component.html | 2 +- .../url/email-link/email-link.component.ts | 3 +- .../external-link.component.html | 2 +- .../external-link.component.scss | 5 -- .../committees/committees.component.html | 68 +++++++++++-------- .../pages/committees/committees.component.ts | 4 +- src/styles.scss | 5 ++ 8 files changed, 54 insertions(+), 40 deletions(-) diff --git a/src/app/components/nav-bar/nav-entries.ts b/src/app/components/nav-bar/nav-entries.ts index 97cb250d..14887d8b 100644 --- a/src/app/components/nav-bar/nav-entries.ts +++ b/src/app/components/nav-bar/nav-entries.ts @@ -6,6 +6,7 @@ import { faRoadBarrier, faUpRightFromSquare } from '@fortawesome/free-solid-svg-icons'; +import { EXTERNAL_LINKS } from 'components/url/links.data'; export interface NavItem extends CodeListItem { route?: string; // Internal route @@ -129,7 +130,7 @@ export const NAVBAR_ENTRIES: NavItem[] = [ key: 'documentation.constitution', label: 'Constitution', icon: faUpRightFromSquare, - href: 'https://github.com/CSSS/public-docs/tree/master/constitutions' + href: EXTERNAL_LINKS['constitution'] }, { key: 'documentation.policies', @@ -141,7 +142,7 @@ export const NAVBAR_ENTRIES: NavItem[] = [ key: 'documentation.sfss-minutes', label: 'SFSS Minutes', icon: faUpRightFromSquare, - href: 'https://sfss.ca/about/meeting-times-minutes/council/' + href: 'https://sfss.ca/about/meeting-times-minutes/council' } ] } diff --git a/src/app/components/url/email-link/email-link.component.html b/src/app/components/url/email-link/email-link.component.html index ecc329fd..c92b9927 100644 --- a/src/app/components/url/email-link/email-link.component.html +++ b/src/app/components/url/email-link/email-link.component.html @@ -1,3 +1,3 @@ - + {{ _label() }} diff --git a/src/app/components/url/email-link/email-link.component.ts b/src/app/components/url/email-link/email-link.component.ts index dd1a3b11..dd064fa8 100644 --- a/src/app/components/url/email-link/email-link.component.ts +++ b/src/app/components/url/email-link/email-link.component.ts @@ -11,5 +11,6 @@ import { EmailLink, EMAILS } from '../links.data'; }) export class EmailLinkComponent extends BaseLinkComponent { override link = input.required(); - protected override _href = computed(() => EMAILS[this.link()]); + protected override _href = computed(() => `mailto:${EMAILS[this.link()]}`); + protected override _label = computed(() => this.label() ?? EMAILS[this.link()]); } diff --git a/src/app/components/url/external-link/external-link.component.html b/src/app/components/url/external-link/external-link.component.html index c867ab9e..dd8ea776 100644 --- a/src/app/components/url/external-link/external-link.component.html +++ b/src/app/components/url/external-link/external-link.component.html @@ -1,3 +1,3 @@ - + {{ _label() }} diff --git a/src/app/components/url/external-link/external-link.component.scss b/src/app/components/url/external-link/external-link.component.scss index 79872786..e69de29b 100644 --- a/src/app/components/url/external-link/external-link.component.scss +++ b/src/app/components/url/external-link/external-link.component.scss @@ -1,5 +0,0 @@ -@use '../../../../ui/csss-code/theme' as t; - -a { - color: t.$accent2; -} diff --git a/src/app/pages/committees/committees.component.html b/src/app/pages/committees/committees.component.html index 7a5ce0f1..f5be50ff 100644 --- a/src/app/pages/committees/committees.component.html +++ b/src/app/pages/committees/committees.component.html @@ -10,60 +10,70 @@

Committees

🎉 Events Committee

- The Events Committee meets bi-weekly to discuss and plan out the CSSS's various events such as - hackathons, workshops, socials, etc. This committee is chaired by the current Director of - Events (DoE), and can be attended either on Discord or in person. Send the current DoE a - message on Discord or reach out to them via email at - csss-doe-current@sfu.ca to join the Events - Committee! + The Events Committee meets bi-weekly to discuss and plan out the CSSS's + various events such as hackathons, workshops, + socials, etc. This committee is chaired by the current + Director of Events (DoE), and can be attended either on + or in person. Send the current DoE a message on or reach + out to them via email at + + to join the Events Committee!

🌐 W3 Committee

- The W3 committee meets asynchronously to work on the various websites and projects for the - CSSS such as the current website you're looking at, events pages, games, such as PacMacro, and - many more. This committee is chaired by both the current System Administrator (SysAdmin) and - the current Webmaster of the CSSS, and all discussion currently takes place on Discord. Send - the current SysAdmin or Webmaster a message on Discord or reach out to them via email at - csss-sysadmin@sfu.ca or - csss-webmaster@sfu.ca to join the W3 Committee! + The W3 Committee meets asynchronously to work on various websites and + projects for the CSSS such as this website, event pages, + games, and many more. This committee is chaired by both the current + System Administrator (SysAdmin) and the current Webmaster of + the CSSS, and all discussion currently takes place on . + Send the current SysAdmin or Webmaster a message on + or reach out to them via email at + or to join the W3 + Committee!

🐣 Frosh Committee

- The Frosh Committee is assembled when planning our yearly welcome week for first-year - Computing Science students! If you're interested in joining the Frosh Committee or volunteer - as a Frosh Leader, reach out to our Frosh Chairs via email at - csss-froshchair@sfu.ca! + The Frosh Committee is assembled when planning our yearly welcome week for + first-year Computing Science students! If you're interested in joining the + Frosh Committee or volunteer as a Frosh Leader, reach out to our Frosh Chairs via email at + .

🌄 Multimedia Committee

- The Multimedia Committee gets together to work on merch for the CSSS, from stickers to new - hoodie designs, and graphics for our website! This committee is chaired by the current - Director of Multimedia (DoMM), and all discussion currently takes place on Discord. Send the - current DoMM a message on Discord or reach out to them via email at - csss-domm-current@sfu.ca to join the - Multimedia Committee! + The Multimedia Committee gets together to work on + merch for the CSSS, from stickers to + new hoodie designs, and graphics for our website! This + committee is chaired by the current Director of Multimedia (DoMM), and all + discussion currently takes place on . Send the current DoMM + a message on or reach out to them via email at + + to join the Multimedia Committee.

💻 Tech Fair Committee

- The Tech Fair Committee is assembled when planning our yearly career fair, Tech Fair! If - you're interested in joining the Tech Fair Committee, reach out ot our current Tech Fair - chairs via email at csss-techfair@sfu.ca! + The Tech Fair Committee is assembled when planning our yearly career fair, + Tech Fair! If you're interested in joining the + Tech Fair Committee, reach out to our current + Tech Fair chairs via email at .

🔏 Policy Committee

- The Policy Committee starts spontaneously when our constitution or policies come into - question. If you think changes should be made, reach out to the current President or Vice - President of the CSSS to assemble the Policy Committee and put changes into motion! + The Policy Committee starts spontaneously when our + constitution or policies come into question. If you think + changes should be made, reach out to the current + or + of the CSSS to assemble the + Policy Committee and put changes into motion!

diff --git a/src/app/pages/committees/committees.component.ts b/src/app/pages/committees/committees.component.ts index 69ff336e..8edea216 100644 --- a/src/app/pages/committees/committees.component.ts +++ b/src/app/pages/committees/committees.component.ts @@ -1,9 +1,11 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import { ArticleComponent } from '@csss-code/article/article.component'; +import { EmailLinkComponent } from 'components/url/email-link/email-link.component'; +import { ExternalLinkComponent } from 'components/url/external-link/external-link.component'; @Component({ selector: 'cs-committees', - imports: [ArticleComponent], + imports: [ArticleComponent, EmailLinkComponent, ExternalLinkComponent], templateUrl: './committees.component.html', styleUrl: './committees.component.scss', changeDetection: ChangeDetectionStrategy.OnPush diff --git a/src/styles.scss b/src/styles.scss index 2a359236..d33084fd 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -31,6 +31,11 @@ a { cursor: pointer; } +a.csss-link { + color: globals.$accent2; + white-space: nowrap; // so the icons don't wrap without the link text +} + .clickable { cursor: pointer; } From d036ad17dc25d1641e9593ea8c4d5c65e090d785 Mon Sep 17 00:00:00 2001 From: Jon Andre Briones Date: Sun, 17 Aug 2025 18:40:41 -0700 Subject: [PATCH 4/7] feat: Added route links --- src/app/app.routes.ts | 26 ++++++++++++++++++- src/app/components/url/base-link.component.ts | 4 +-- .../url/email-link/email-link.component.ts | 6 ++--- .../external-link/external-link.component.ts | 4 +-- .../url/route-link/route-link.component.html | 4 ++- .../url/route-link/route-link.component.ts | 12 ++++++--- .../committees/committees.component.html | 26 +++++++++---------- .../pages/elections/elections.component.html | 2 +- src/app/pages/events/events.component.html | 4 +-- src/app/pages/readme/readme.component.html | 4 +-- src/app/pages/readme/readme.component.ts | 9 ++++++- src/app/services/application/applications.ts | 1 - src/app/utils/string-utils.ts | 18 ++++++++++--- 13 files changed, 85 insertions(+), 35 deletions(-) diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index b5dff593..83f193f3 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -1,6 +1,11 @@ import { Routes } from '@angular/router'; import { HomeComponent } from 'pages/home/home.component'; +/** + * Formats the title on the web browser's tab/window. + * @param pageTitle - Title of the page + * @returns Formatted page title. + */ function makeTitle(pageTitle: string): string { return `${pageTitle} | CSSS`; } @@ -50,5 +55,24 @@ export const routes: Routes = [ title: makeTitle('Elections') }, { path: '', component: HomeComponent, title: 'Computing Science Student Society' }, + // 404 will go down there { path: '**', component: HomeComponent } -]; +] as const; + +const BASE_ROUTES = routes.reduce((acc, route) => { + if (!route.path || route.path === '**') { + return acc; + } + acc.push(route.path); + return acc; +}, [] as string[]); + +/** + * Gets the base route as a string. + * + * @param route - Route to get + * @returns The route if it exists or 404 + */ +export function getBaseRoute(route: string): string { + return BASE_ROUTES.find(r => r === route) ?? '404'; +} diff --git a/src/app/components/url/base-link.component.ts b/src/app/components/url/base-link.component.ts index da902b9b..7e36a18c 100644 --- a/src/app/components/url/base-link.component.ts +++ b/src/app/components/url/base-link.component.ts @@ -14,7 +14,7 @@ export abstract class BaseLinkComponent { /** * The link that should be used from `links.ts` */ - link = input.required(); + key = input.required(); /** * Overrides the label that is displayed. @@ -24,7 +24,7 @@ export abstract class BaseLinkComponent { /** * Label that is displayed in the element. */ - protected _label = computed(() => this.label() ?? capitalize(this.link())); + protected _label = computed(() => this.label() ?? capitalize(this.key())); /** * The href used to move the user to the external link/route. diff --git a/src/app/components/url/email-link/email-link.component.ts b/src/app/components/url/email-link/email-link.component.ts index dd064fa8..39f52f53 100644 --- a/src/app/components/url/email-link/email-link.component.ts +++ b/src/app/components/url/email-link/email-link.component.ts @@ -10,7 +10,7 @@ import { EmailLink, EMAILS } from '../links.data'; changeDetection: ChangeDetectionStrategy.OnPush }) export class EmailLinkComponent extends BaseLinkComponent { - override link = input.required(); - protected override _href = computed(() => `mailto:${EMAILS[this.link()]}`); - protected override _label = computed(() => this.label() ?? EMAILS[this.link()]); + override key = input.required(); + protected override _href = computed(() => `mailto:${EMAILS[this.key()]}`); + protected override _label = computed(() => this.label() ?? EMAILS[this.key()]); } diff --git a/src/app/components/url/external-link/external-link.component.ts b/src/app/components/url/external-link/external-link.component.ts index 538f70bc..ed45bceb 100644 --- a/src/app/components/url/external-link/external-link.component.ts +++ b/src/app/components/url/external-link/external-link.component.ts @@ -11,6 +11,6 @@ import { EXTERNAL_LINKS, ExternalLink } from '../links.data'; changeDetection: ChangeDetectionStrategy.OnPush }) export class ExternalLinkComponent extends BaseLinkComponent { - override link = input.required(); - protected override _href = computed(() => EXTERNAL_LINKS[this.link()]); + override key = input.required(); + protected override _href = computed(() => EXTERNAL_LINKS[this.key()]); } diff --git a/src/app/components/url/route-link/route-link.component.html b/src/app/components/url/route-link/route-link.component.html index 7423d877..6aba9bce 100644 --- a/src/app/components/url/route-link/route-link.component.html +++ b/src/app/components/url/route-link/route-link.component.html @@ -1 +1,3 @@ -

route-link works!

+ + {{ label() }} + diff --git a/src/app/components/url/route-link/route-link.component.ts b/src/app/components/url/route-link/route-link.component.ts index 4291a394..fe47c820 100644 --- a/src/app/components/url/route-link/route-link.component.ts +++ b/src/app/components/url/route-link/route-link.component.ts @@ -1,12 +1,18 @@ -import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { getBaseRoute } from 'app/app.routes'; @Component({ selector: 'cs-route-link', - imports: [], + imports: [RouterModule], templateUrl: './route-link.component.html', styleUrl: './route-link.component.scss', changeDetection: ChangeDetectionStrategy.OnPush }) export class RouteLinkComponent { - + key = input.required(); + route = computed(() => { + return '/' + getBaseRoute(this.key()); + }); + label = input(); } diff --git a/src/app/pages/committees/committees.component.html b/src/app/pages/committees/committees.component.html index f5be50ff..9beda31d 100644 --- a/src/app/pages/committees/committees.component.html +++ b/src/app/pages/committees/committees.component.html @@ -14,9 +14,9 @@

🎉 Events Committee

various events such as hackathons, workshops, socials, etc. This committee is chaired by the current Director of Events (DoE), and can be attended either on - or in person. Send the current DoE a message on or reach + or in person. Send the current DoE a message on or reach out to them via email at - + to join the Events Committee!

@@ -27,10 +27,10 @@

🌐 W3 Committee

projects for the CSSS such as this website, event pages, games, and many more. This committee is chaired by both the current System Administrator (SysAdmin) and the current Webmaster of - the CSSS, and all discussion currently takes place on . - Send the current SysAdmin or Webmaster a message on - or reach out to them via email at - or to join the W3 + the CSSS, and all discussion currently takes place on . Send + the current SysAdmin or Webmaster a message on + or reach out to them via email at + or to join the W3 Committee!

@@ -40,7 +40,7 @@

🐣 Frosh Committee

The Frosh Committee is assembled when planning our yearly welcome week for first-year Computing Science students! If you're interested in joining the Frosh Committee or volunteer as a Frosh Leader, reach out to our Frosh Chairs via email at - . + .

@@ -50,9 +50,9 @@

🌄 Multimedia Committee

merch for the CSSS, from stickers to new hoodie designs, and graphics for our website! This committee is chaired by the current Director of Multimedia (DoMM), and all - discussion currently takes place on . Send the current DoMM - a message on or reach out to them via email at - + discussion currently takes place on . Send the current DoMM + a message on or reach out to them via email at + to join the Multimedia Committee.

@@ -62,7 +62,7 @@

💻 Tech Fair Committee

The Tech Fair Committee is assembled when planning our yearly career fair, Tech Fair! If you're interested in joining the Tech Fair Committee, reach out to our current - Tech Fair chairs via email at . + Tech Fair chairs via email at .

@@ -71,8 +71,8 @@

🔏 Policy Committee

The Policy Committee starts spontaneously when our constitution or policies come into question. If you think changes should be made, reach out to the current - or - of the CSSS to assemble the + or + of the CSSS to assemble the Policy Committee and put changes into motion!

diff --git a/src/app/pages/elections/elections.component.html b/src/app/pages/elections/elections.component.html index 62eca657..d792d359 100644 --- a/src/app/pages/elections/elections.component.html +++ b/src/app/pages/elections/elections.component.html @@ -5,7 +5,7 @@

Elections

The CSSS holds multiple elections a year to make sure the best people are helping our members. If you'd like to get even more involved with the CS community then running for a position is a great way to do that. Full rules for elected positions are in the - +

diff --git a/src/app/pages/events/events.component.html b/src/app/pages/events/events.component.html index ed7b74d3..7552ea0e 100644 --- a/src/app/pages/events/events.component.html +++ b/src/app/pages/events/events.component.html @@ -4,7 +4,7 @@

Events

The CSSS runs a combination of regular and yearly events. From meetings to Hackathons, we try and make sure there's something for everyone. We send out reminders through email, on our - +

Regular Events

@@ -30,7 +30,7 @@

Board Game Nights

If meetings aren't exciting enough for you, join us for boardgame nights! Every other Friday we book - + , pull out a few board games and give out FREE FOOD. If you're down for some Friday night fun, then pull up, sit down, and, maybe, just maybe, the Executives will serenade you with karaoke. diff --git a/src/app/pages/readme/readme.component.html b/src/app/pages/readme/readme.component.html index 296963a6..e19bc15e 100644 --- a/src/app/pages/readme/readme.component.html +++ b/src/app/pages/readme/readme.component.html @@ -57,8 +57,8 @@

How do I become a member?

How can we connect with you?

- You can find us at the Common Room or on - + You can find us at the or on +