diff --git a/README.md b/README.md index d61887bb..4019704d 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,8 @@ You will need: - `node` v22 - `npm` v10 - Install the Angular CLI globally -``` +```sh +# use Angular v20.2 npm install -g @angular/cli ``` - SSH keys @@ -26,23 +27,22 @@ npm ci ``` 3. Start the frontend server: -``` -npm run start // will run some pre-build scripts +```sh +npm run start # will run some pre-build scripts or -ng serve // only works after building +ng serve # only works after building ``` 4. Serve the app over your local network -``` -// Access the site on a device in your local network by going to `http://:8080` +```sh +# Access the site on a device in your local network by going to `http://:8080` ng serve --host=0.0.0.0 // only works after building ``` To view other npm commands, look at `package.json` under the "scripts" key. ### Local development -This project uses: - +If you'd like to contribute, you can start reading here https://github.com/CSSS/csss-site-frontend/wiki/Contributing ### Libraries used -* **FontAwesome** -* **Material CDK** -* **GSAP** +* **FontAwesome 6.7.1** https://fontawesome.com/v6/icons +* **Material CDK** https://material.angular.dev/cdk/categories +* **NGXUI** https://ngxui.com/ diff --git a/package-lock.json b/package-lock.json index abaad622..2d82ce5e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,8 @@ "@fortawesome/free-brands-svg-icons": "^6.7.1", "@fortawesome/free-regular-svg-icons": "^6.7.1", "@fortawesome/free-solid-svg-icons": "^6.7.1", - "gsap": "^3.13.0", + "@omnedia/ngx-fade": "^3.0.0", + "@omnedia/ngx-typewriter": "^3.1.1", "rxjs": "~7.8.0", "tslib": "^2.3.0" }, @@ -2979,6 +2980,33 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/@omnedia/ngx-fade": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@omnedia/ngx-fade/-/ngx-fade-3.0.0.tgz", + "integrity": "sha512-tVLiktmvHodpYxanRppz58n+u6fTTG55kQE8iTtqOdLCvSYE66SgueLgNzw2pzSfNtyC5Qq8bq7H8I1aqVe1XQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/common": "^20.0.0", + "@angular/core": "^20.0.0" + } + }, + "node_modules/@omnedia/ngx-typewriter": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@omnedia/ngx-typewriter/-/ngx-typewriter-3.1.1.tgz", + "integrity": "sha512-eQjPMSkR9whWLEsaCVgt7W9+kZdFAJBs2fXI8k+nCfKWSjsDjAFn4EkbHFPIhVYaF164a72ZlzL813xPorznxg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/common": "^20.0.0", + "@angular/core": "^20.0.0", + "rxjs": "~7.8.0" + } + }, "node_modules/@parcel/watcher": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", @@ -6179,12 +6207,6 @@ "dev": true, "license": "MIT" }, - "node_modules/gsap": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/gsap/-/gsap-3.13.0.tgz", - "integrity": "sha512-QL7MJ2WMjm1PHWsoFrAQH/J8wUeqZvMtHO58qdekHpCfhvhSL4gSiz6vJf5EeMP0LOn3ZCprL2ki/gjED8ghVw==", - "license": "Standard 'no charge' license: https://gsap.com/standard-license." - }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", diff --git a/package.json b/package.json index 3e234cda..ca42f1c3 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,8 @@ "@fortawesome/free-brands-svg-icons": "^6.7.1", "@fortawesome/free-regular-svg-icons": "^6.7.1", "@fortawesome/free-solid-svg-icons": "^6.7.1", - "gsap": "^3.13.0", + "@omnedia/ngx-fade": "^3.0.0", + "@omnedia/ngx-typewriter": "^3.1.1", "rxjs": "~7.8.0", "tslib": "^2.3.0" }, diff --git a/public/images/president.jpg b/public/images/president.jpg deleted file mode 100644 index c2f850a2..00000000 Binary files a/public/images/president.jpg and /dev/null differ diff --git a/public/images/president-mabel.png b/public/images/president.png similarity index 100% rename from public/images/president-mabel.png rename to public/images/president.png diff --git a/src/app/pages/officers/officers.component.html b/src/app/pages/officers/officers.component.html index 8251e8a3..7b1370fb 100644 --- a/src/app/pages/officers/officers.component.html +++ b/src/app/pages/officers/officers.component.html @@ -12,12 +12,14 @@

Officers

Current Executives

diff --git a/src/app/pages/officers/officers.component.scss b/src/app/pages/officers/officers.component.scss index 1e9c922c..1109680c 100644 --- a/src/app/pages/officers/officers.component.scss +++ b/src/app/pages/officers/officers.component.scss @@ -1,34 +1,8 @@ @use 'globals' as g; -@use 'theme' as t; - -.timeline { - display: flex; - column-gap: 0.2rem; - width: 100%; - margin-bottom: 2rem; - - & > .timeslot { - flex: 1 0 auto; - - & > .time-label { - text-align: right; - } - - & > .line { - min-width: 6rem; - height: 0.2rem; - background-color: aquamarine; - } - } - - & > .timeslot[aria-selected='true'] > .line { - box-shadow: 0 0 10px 3px aquamarine; - } -} .gallery { display: grid; - grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr)); + grid-template-columns: repeat(auto-fit, minmax(min(10rem, 100%), 1fr)); gap: 1.8rem; } @@ -39,17 +13,23 @@ grid-template-rows: auto auto; } -code-card > img { - width: 100%; - object-fit: contain; -} - -.card-footer { +.card__footer { position: absolute; bottom: 0; width: 100%; height: fit-content; - padding: 0.3rem; + background-color: g.$bg3; + + display: flex; + flex-direction: column; + gap: 0.5rem; +} + +.card__name, +.card__position { + width: fit-content; +} - background-color: t.$bg3; +.card__position { + color: g.$code-text; } diff --git a/src/app/pages/officers/officers.component.ts b/src/app/pages/officers/officers.component.ts index 02553b0d..653c38df 100644 --- a/src/app/pages/officers/officers.component.ts +++ b/src/app/pages/officers/officers.component.ts @@ -1,19 +1,12 @@ -import { - ChangeDetectionStrategy, - Component, - computed, - effect, - signal, - viewChildren -} from '@angular/core'; +import { ChangeDetectionStrategy, Component, computed, signal } from '@angular/core'; import { ArticleComponent } from '@csss-code/article/article.component'; import { CardComponent } from '@csss-code/card/card.component'; -import { gsap } from 'gsap'; +import { NgxFadeComponent } from '@omnedia/ngx-fade'; import { ExecutiveAdministration, executives, getRandomExecImage } from './officers.data'; @Component({ selector: 'cs-officers', - imports: [CardComponent, ArticleComponent], + imports: [CardComponent, ArticleComponent, NgxFadeComponent], templateUrl: './officers.component.html', styleUrl: './officers.component.scss', changeDetection: ChangeDetectionStrategy.OnPush @@ -47,39 +40,12 @@ export class OfficersComponent { return newAdmin; }); - private execCards = viewChildren('execCard'); - /** * Cache the admins so we don't need to fetch them each time. * Will probably need some way to remove older cached entries if memory becomes an issue. */ private cachedAdmins = new Map(); - constructor() { - effect(() => { - if (!this.currentAdministration() || !this.execCards().length) { - return; - } - - this.animateCards(); - }); - } - - private animateCards(): void { - const cards = this.execCards(); - if (!cards || !cards.length) { - return; - } - - const targets = cards.map(el => el.elementRef.nativeElement); - gsap.from(targets, { - bottom: -50, - opacity: 0, - duration: 0.3, - ease: 'power3.out' - }); - } - /** * Changes the files name to one that can be used to set the background image. * diff --git a/src/app/pages/readme/readme.component.html b/src/app/pages/readme/readme.component.html index 29b76d72..e5a3db19 100644 --- a/src/app/pages/readme/readme.component.html +++ b/src/app/pages/readme/readme.component.html @@ -1,29 +1,21 @@ -
-
+
+
Mural

Welcome to the -
Computing Science Student Society
+

- -
+ +
-
-

History

-

- Since its founding in the 1970s, the Computing Science Student Society has existed to - promote the interests of students within the School of Computing Science at Simon Fraser - University. The Society strives to support and build a vibrant community of individuals and - create an environment that produces social, academic, and professional success. The CSSS - continues this tradition today by running numerous social events throughout the school year, - as well as hosting workshops, talks by industry speakers, and development contests for - budding programmers. -

-
-
+
- President of the CSSS + President of the CSSS

President's Address

@@ -45,6 +37,18 @@

President's Address

+
+

History

+

+ Since its founding in the 1970s, the Computing Science Student Society has existed to + promote the interests of students within the School of Computing Science at Simon Fraser + University. The Society strives to support and build a vibrant community of individuals and + create an environment that produces social, academic, and professional success. The CSSS + continues this tradition today by running numerous social events throughout the school year, + as well as hosting workshops, talks by industry speakers, and development contests for + budding programmers. +

+

FAQ

How do I become a member?

diff --git a/src/app/pages/readme/readme.component.scss b/src/app/pages/readme/readme.component.scss index 8db89970..32c45e1b 100644 --- a/src/app/pages/readme/readme.component.scss +++ b/src/app/pages/readme/readme.component.scss @@ -1,13 +1,14 @@ @use 'globals' as g; -.wrapper { - height: 96svh; +.parallax { + height: 100%; overflow-y: auto; overflow-x: hidden; perspective: 10px; + scroll-behavior: smooth; } -header { +hgroup { position: relative; display: flex; justify-content: center; @@ -37,11 +38,13 @@ header { mask-repeat: no-repeat; } - & > fa-icon { - font-size: clamp(2rem, 3vw, 15rem); + & > a { position: absolute; bottom: 30svh; - filter: drop-shadow(0px 2px 5px black); + & > fa-icon { + font-size: clamp(2rem, 3vw, 15rem); + filter: drop-shadow(0px 2px 5px black); + } } } diff --git a/src/app/pages/readme/readme.component.ts b/src/app/pages/readme/readme.component.ts index f6df3139..501bb960 100644 --- a/src/app/pages/readme/readme.component.ts +++ b/src/app/pages/readme/readme.component.ts @@ -1,19 +1,11 @@ -import { - AfterViewInit, - ChangeDetectionStrategy, - Component, - computed, - ElementRef, - viewChild -} from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; 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 { NgxTypewriterComponent } from '@omnedia/ngx-typewriter'; import { ExternalLinkComponent } from 'components/url/external-link/external-link.component'; import { RouteLinkComponent } from 'components/url/route-link/route-link.component'; -import { gsap } from 'gsap'; -import { SplitText } from 'gsap/SplitText'; @Component({ selector: 'cs-readme', @@ -22,31 +14,21 @@ import { SplitText } from 'gsap/SplitText'; RouterModule, FontAwesomeModule, ExternalLinkComponent, - RouteLinkComponent + RouteLinkComponent, + NgxTypewriterComponent ], templateUrl: './readme.component.html', styleUrl: './readme.component.scss', changeDetection: ChangeDetectionStrategy.OnPush }) -export class ReadMeComponent implements AfterViewInit { +export class ReadMeComponent { protected arrowIcon = faArrowDown; protected externalLinkIcon = faArrowUpRightFromSquare; - private typedText = viewChild.required>('typeIn'); - private typedTextEl = computed(() => this.typedText().nativeElement); - - ngAfterViewInit(): void { - const split = SplitText.create(this.typedTextEl(), { - type: 'chars' - }); - - gsap.from(split.chars, { - display: 'none', - delay: 0.5, - stagger: 0.05, - onComplete() { - split.revert(); - } - }); + scrollTo(id: string): void { + const target = document.getElementById(id); + if (target) { + target.scrollIntoView({ behavior: 'smooth' }); + } } } diff --git a/src/app/services/application/application.service.ts b/src/app/services/application/application.service.ts index f24419dc..344f3f9d 100644 --- a/src/app/services/application/application.service.ts +++ b/src/app/services/application/application.service.ts @@ -34,9 +34,9 @@ export class ApplicationService { .subscribe((event: NavigationEnd) => { let route = event.urlAfterRedirects; // Discard other params. This assumes that the URLs will have the form: - // `/?=` or `//?=` + // `/?=#` or `//?=#` // or maybe they don't have any query params at all. - route = route.split('?')[0]; // Just the route params + route = route.split('?')[0].split('#')[0]; // Just the route params console.log(route); if (route === '/') { this.focusedApplication.set(null); diff --git a/src/app/services/gsap/gsap.service.spec.ts b/src/app/services/gsap/gsap.service.spec.ts deleted file mode 100644 index df19943a..00000000 --- a/src/app/services/gsap/gsap.service.spec.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { GsapService } from './gsap.service'; - -describe('GsapService', () => { - let service: GsapService; - - beforeEach(() => { - TestBed.configureTestingModule({}); - service = TestBed.inject(GsapService); - }); - - it('should be created', () => { - expect(service).toBeTruthy(); - }); -}); diff --git a/src/app/services/gsap/gsap.service.ts b/src/app/services/gsap/gsap.service.ts deleted file mode 100644 index cd6a9534..00000000 --- a/src/app/services/gsap/gsap.service.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Injectable } from '@angular/core'; -import { gsap } from 'gsap'; -import { SplitText } from 'gsap/SplitText'; - -@Injectable({ - providedIn: 'root' -}) -export class GsapService { - /** - * GSAP's Match Media singleton. - * Add animations to this that will run based on current media query conditions. - */ - private _mm?: gsap.MatchMedia; - - constructor() { - gsap.registerPlugin(SplitText); - } - - get media(): gsap.MatchMedia { - if (!this._mm) { - this._mm = gsap.matchMedia(); - } - return this._mm; - } -} diff --git a/src/styles.scss b/src/styles.scss index 37081963..f3edc364 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -1,6 +1,10 @@ /* You can add global styles to this file, and also import other style files */ @use 'globals'; +html { + scroll-behavior: smooth; +} + html, body { height: 100%; @@ -82,3 +86,7 @@ article.content { color: globals.$accent3; } } + +.typed { + margin: 0; +} diff --git a/src/ui/csss-code/card/card.component.scss b/src/ui/csss-code/card/card.component.scss index 8ccb5ab1..8464c50e 100644 --- a/src/ui/csss-code/card/card.component.scss +++ b/src/ui/csss-code/card/card.component.scss @@ -11,6 +11,6 @@ transition: transform 0.3s ease; &.hoverable:hover { - transform: scale(1.1); + transform: scale(1.05); } }