Skip to content

Commit

Permalink
Slack Invitation in Nav Sidebar (#257)
Browse files Browse the repository at this point in the history
Users are now able to join the XL Slack via the sidebar, with community agreement opt-in. Additionally, this links to the GitHub project of the CSXL website.

---------

Co-authored-by: Kris Jordan <[email protected]>
  • Loading branch information
krohan03 and KrisJordan authored Feb 11, 2024
1 parent 5e506dc commit 93b4320
Show file tree
Hide file tree
Showing 11 changed files with 227 additions and 46 deletions.
4 changes: 4 additions & 0 deletions frontend/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@ import { MatSliderModule } from '@angular/material/slider';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { MatTabsModule } from '@angular/material/tabs';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatCheckboxModule } from '@angular/material/checkbox';

/* Application Specific */
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { NavigationComponent } from './navigation/navigation.component';
import { SlackInviteBox } from './navigation/widgets/slack-invite-box/slack-invite-box.widget';
import { ErrorDialogComponent } from './navigation/error-dialog/error-dialog.component';
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';
Expand All @@ -43,6 +45,7 @@ import { EventFilterPipe } from './event/event-filter/event-filter.pipe';
declarations: [
AppComponent,
NavigationComponent,
SlackInviteBox,
ErrorDialogComponent,
HomeComponent,
AboutComponent,
Expand Down Expand Up @@ -73,6 +76,7 @@ import { EventFilterPipe } from './event/event-filter/event-filter.pipe';
MatSnackBarModule,
MatTabsModule,
MatToolbarModule,
MatCheckboxModule,
FormsModule,
RouterModule,
JwtModule.forRoot({
Expand Down
32 changes: 32 additions & 0 deletions frontend/src/app/navigation/navigation.component.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,36 @@
text-align: center;
}

.logo-icon {
display: block;
margin-left: auto;
margin-right: auto;
width: 90%;
}

.logo {
margin: 0;
height: 32px;
}

.bottom-button {
height: 36px;
width: 36px;
min-width: 36px;
margin-right: 3px;
margin-left: 3px;
padding: 0;
}

.bottom-button-container {
width: 100%;
margin-bottom: 6px;
margin-top: auto;
display: flex;
align-items: center;
justify-content: center;
}

.sidenav-container {
height: 100%;
}
Expand All @@ -18,6 +43,13 @@
width: 200px;
}

.inner-sidenav-container {
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}

.sidenav .mat-toolbar {
background: inherit;
}
Expand Down
128 changes: 83 additions & 45 deletions frontend/src/app/navigation/navigation.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,55 +6,93 @@
[attr.role]="isHandset ? 'dialog' : 'navigation'"
[mode]="isHandset ? 'over' : 'side'"
[opened]="isHandset === false">
<mat-nav-list (click)="hideMobileSidenav(drawer)">
<a
mat-list-item
class="logo-item"
routerLink="/"
routerLinkActive="active">
<picture>
<source
class="logo"
srcset="/assets/lil-logo.png"
media="(prefers-color-scheme: dark)"
alt="Computer Science Experience Labs Logo" />
<img
class="logo"
src="/assets/lil-logo-light.png"
alt="Computer Science Experience Labs Logo" />
</picture>
</a>
<div *ngIf="profile$ | async as profile; else unauthenticated">
<a mat-list-item routerLink="/coworking">Coworking</a>
<a mat-list-item routerLink="/events">Events</a>
<a mat-list-item routerLink="/organizations">Organizations</a>
<a mat-list-item routerLink="/academics">Academics</a>
<a mat-list-item routerLink="/about">About the XL</a>
<mat-divider></mat-divider>
<div *ngIf="ambassadorPermission$ | async">
<a mat-list-item routerLink="/coworking/ambassador">XL Ambassador</a>
</div>
<div *ngIf="adminPermission$ | async">
<a mat-list-item routerLink="/admin/users">User Admin</a>
</div>
<div class="inner-sidenav-container">
<mat-nav-list (click)="hideMobileSidenav(drawer)">
<a
mat-list-item
routerLink="/profile"
*ngIf="profile.first_name !== ''; else new_user"
>{{ profile.first_name }} {{ profile.last_name }}</a
>
<ng-template #new_user>
<a mat-list-item routerLink="/profile">Profile</a>
class="logo-item"
routerLink="/"
routerLinkActive="active">
<picture>
<source
class="logo"
srcset="/assets/lil-logo.png"
media="(prefers-color-scheme: dark)"
alt="Computer Science Experience Labs Logo" />
<img
class="logo"
src="/assets/lil-logo-light.png"
alt="Computer Science Experience Labs Logo" />
</picture>
</a>
<div *ngIf="profile$ | async as profile; else unauthenticated">
<a mat-list-item routerLink="/coworking">Coworking</a>
<a mat-list-item routerLink="/events">Events</a>
<a mat-list-item routerLink="/organizations">Organizations</a>
<a mat-list-item routerLink="/academics">Academics</a>
<a mat-list-item routerLink="/about">About the XL</a>
<mat-divider></mat-divider>
<div *ngIf="ambassadorPermission$ | async">
<a mat-list-item routerLink="/coworking/ambassador">
XL Ambassador
</a>
</div>
<div *ngIf="adminPermission$ | async">
<a mat-list-item routerLink="/admin/users">User Admin</a>
</div>
<a
mat-list-item
routerLink="/profile"
*ngIf="profile.first_name !== ''; else new_user"
>{{ profile.first_name }} {{ profile.last_name }}</a
>
<ng-template #new_user>
<a mat-list-item routerLink="/profile">Profile</a>
</ng-template>
<a mat-list-item (click)="auth.signOut()">Sign out</a>
</div>
<ng-template #unauthenticated>
<a mat-list-item routerLink="/organizations">Organizations</a>
<a mat-list-item routerLink="/events">Events</a>
<a mat-list-item routerLink="/about">About the XL</a>
<a mat-list-item href="/auth?continue_to={{ router.url }}">Sign in</a>
</ng-template>
<a mat-list-item (click)="auth.signOut()">Sign out</a>
</mat-nav-list>
<div
mat-list-item
class="bottom-button-container"
*ngIf="profile$ | async as profile">
<button
mat-button
class="bottom-button"
(click)="onSlackInviteClick()"
type="button">
<picture>
<img
class="logo-icon"
src="/assets/slack-logo-monochrome.png"
alt="Slack Logo" />
</picture>
</button>
<button
mat-button
class="bottom-button"
onclick="window.open('https://github.com/unc-csxl/csxl.unc.edu','_blank')"
type="button">
<picture>
<source
class="logo-icon"
srcset="/assets/github-logo-dark.png"
media="(prefers-color-scheme: dark)"
alt="GitHub Logo" />
<img
class="logo-icon"
src="/assets/github-logo-light.png"
alt="GitHub Logo" />
</picture>
</button>
</div>
<ng-template #unauthenticated>
<a mat-list-item routerLink="/organizations">Organizations</a>
<a mat-list-item routerLink="/events">Events</a>
<a mat-list-item routerLink="/about">About the XL</a>
<a mat-list-item href="/auth?continue_to={{ router.url }}">Sign in</a>
</ng-template>
</mat-nav-list>
</div>
</mat-sidenav>
<mat-sidenav-content>
<mat-toolbar color="primary">
Expand Down
11 changes: 10 additions & 1 deletion frontend/src/app/navigation/navigation.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { ActivatedRoute, Router, RouterEvent } from '@angular/router';
import { Profile, ProfileService } from '../profile/profile.service';
import { PermissionService } from '../permission.service';
import { NagivationAdminGearService } from './navigation-admin-gear.service';
import { SlackInviteBox } from './widgets/slack-invite-box/slack-invite-box.widget';

@Component({
selector: 'app-navigation',
Expand All @@ -36,7 +37,8 @@ export class NavigationComponent implements OnInit, OnDestroy {
private breakpointObserver: BreakpointObserver,
protected navigationService: NavigationTitleService,
protected navigationAdminGearService: NagivationAdminGearService,
protected errorDialog: MatDialog
protected errorDialog: MatDialog,
protected slackDialog: MatDialog
) {
this.profile$ = this.profileService.profile$;
this.checkinPermission$ = this.permission.check(
Expand Down Expand Up @@ -73,6 +75,13 @@ export class NavigationComponent implements OnInit, OnDestroy {
}
}

onSlackInviteClick(): void {
const dialogRef = this.slackDialog.open(SlackInviteBox, {
autoFocus: 'dialog'
});
dialogRef.afterClosed().subscribe();
}

private initErrorDialog() {
return this.navigationService.error$.subscribe((message) => {
if (message !== null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.slack-dialog {
max-width: 100%;
max-height: 90vh;
overflow: auto;
scroll-behavior: auto;
}

@media (prefers-color-scheme: dark) {
.slack-dialog {
color: white;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<mat-card class="slack-dialog" appearance="outlined" #dialogContainer>
<mat-card-content class="content-container">
<h2>Join the CS Experience Labs' Slack Community</h2>
<p>
The CSXL Slack to get updates about the XL, learn about new opportunities
for CS students, and connect with fellow CS majors!
</p>
<h3>XL Slack Community Agreements</h3>
<p>
Please read and accept the following expectations of the XL Slack
Community:
</p>
<p>
<mat-checkbox [(ngModel)]="realName"
>I will use my <strong>real first and last names</strong> in my XL Slack
Profile.</mat-checkbox
>
</p>
<p>
<mat-checkbox [(ngModel)]="profilePicture"
>I will add set my <strong>profile picture</strong> to
<strong>include my face</strong>, and <em>no one else's face</em>, upon
joining.</mat-checkbox
>
</p>
<p>
<mat-checkbox [(ngModel)]="communityStandards"
>I will abide by the rules and standards detailed in the
<strong>CSXL Community Standards Agreement</strong>.</mat-checkbox
>
</p>
<p>
<mat-checkbox [(ngModel)]="fAroundFindOut"
>I understand my
<strong>failure to comply to these community standards</strong> may
result in <strong>being removed from the XL Slack community</strong> and
<strong>unable to make use of CS XL facilities</strong> in Sitterson
Hall and the Fred Brooks Building.</mat-checkbox
>
</p>
<mat-card-actions align="end">
<button
mat-button
(click)="openSlackInvite()"
*ngIf="acceptAll; else pleaseAcceptAll">
Join the XL Slack
</button>
<ng-template #pleaseAcceptAll>
<button mat-button disabled="disabled">
Accept All XL Slack Community Agreements to Join
</button>
</ng-template>
</mat-card-actions>
</mat-card-content>
</mat-card>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Component } from '@angular/core';

@Component({
selector: 'slack-invite-box',
templateUrl: './slack-invite-box.widget.html',
styleUrls: ['./slack-invite-box.widget.css']
})
export class SlackInviteBox {
public realName: boolean = false;
public profilePicture: boolean = false;
public communityStandards: boolean = false;
public fAroundFindOut: boolean = false;

public get acceptAll(): boolean {
return (
this.realName &&
this.profilePicture &&
this.communityStandards &&
this.fAroundFindOut
);
}

constructor() {}

public openSlackInvite() {
window.open(
'https://join.slack.com/t/csxl/shared_invite/zt-1mvfaiqme-fXXw9cKjaXOfhXVBfgXVCA',
'_blank'
);
}
}
Binary file added frontend/src/assets/github-logo-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/src/assets/github-logo-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/src/assets/slack-logo-monochrome.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/src/assets/slack-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 93b4320

Please sign in to comment.