[A] profile, channe-list, channel, dashboard, standup.service

This commit is contained in:
Jan 2020-10-29 18:27:33 +01:00
parent a5531c5cdf
commit e1aa1342c2
27 changed files with 393 additions and 18 deletions

View file

@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { StandupService } from './standup.service';
describe('StandupService', () => {
let service: StandupService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(StandupService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View file

@ -0,0 +1,55 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
import { StandUp } from './standup';
import { SupaService } from './supa.service';
@Injectable({
providedIn: 'root'
})
export class StandupService {
// standupMap: Map<number, StandUp> = new Map();
standupMap = {};
standups: BehaviorSubject<any> = new BehaviorSubject([]);
constructor(
private supa: SupaService,
) { }
getStandUps(): Observable<StandUp[]> {
if (Object.values(this.standupMap).length === 0) {
console.log('getStandUps - REFRESH')
return this.refreshStandUps();
} else {
console.log('getStandUps - LOCAL')
return this.standups.asObservable();
}
}
refreshStandUps(): Observable<StandUp[]> {
this.supa.client.from<StandUp>('standup').select('id, name, description')
.then(standups => this.updateStore(standups.body))
.catch(error => console.log('Error: ', error));
return this.standups.asObservable();
}
updateStore(standups: StandUp[]) {
standups.forEach(e => {
// this.standupMap.set(e.id, e);
this.standupMap[e.id] = e;
});
this.standups.next(Object.values(this.standupMap));
}
updateOne(standup: StandUp) {
}
deleteOne(standup: StandUp) {
}
addOne(standup: StandUp) {
}
}

View file

@ -0,0 +1,5 @@
export class StandUp {
id: number;
name: string;
description: string;
}

View file

@ -6,12 +6,29 @@ import { HuddleComponent } from './huddle/huddle.component';
import { LoginComponent } from './login/login.component'; import { LoginComponent } from './login/login.component';
import { SignupComponent } from './signup/signup.component'; import { SignupComponent } from './signup/signup.component';
import { AuthGuard } from './authguard.service'; import { AuthGuard } from './authguard.service';
import { ProfileComponent } from './profile/profile.component';
import { DashboardComponent } from './dashboard/dashboard.component';
import { ChannelComponent } from './channel/channel.component';
const routes: Routes = [ const routes: Routes = [
{ {
path: 'huddle', path: 'huddle/:id',
component: HuddleComponent, component: HuddleComponent,
canActivate: [AuthGuard] canActivate: [AuthGuard]
},{
path: 'channel/:id',
component: ChannelComponent,
canActivate: [AuthGuard]
},
{
path: 'profile',
component: ProfileComponent,
canActivate: [AuthGuard]
},
{
path: 'home',
component: DashboardComponent,
canActivate: [AuthGuard]
}, },
{ {
path: 'login', path: 'login',
@ -21,7 +38,7 @@ const routes: Routes = [
path: 'signup', path: 'signup',
component: SignupComponent, component: SignupComponent,
}, },
{ path: '**', redirectTo: '/huddle', pathMatch: 'full' }, { path: '**', redirectTo: '/home', pathMatch: 'full' },
] ]
@NgModule({ @NgModule({

View file

@ -1,7 +1,14 @@
<nav class="navbar navbar-light bg-light"> <nav class="navbar navbar-dark bg-dark">
<a class="navbar-brand" href="#" style="margin: 0 auto;">ASYNC HUDDLE</a> <a class="navbar-brand" href="#" style="margin: 0 auto;">ASYNC HUDDLE</a>
<span *ngIf="supa.user | async" (click)="logout()">Logout</span> <span *ngIf="supa.user | async" (click)="logout()" class="cursor-pointer">Logout</span>
</nav> </nav>
<div class="container"> <div class="container-fluid p-0">
<div class="myContainer d-flex">
<div class="menu">
<app-channel-list></app-channel-list>
</div>
<div class="container content">
<router-outlet></router-outlet> <router-outlet></router-outlet>
</div>
</div>
</div> </div>

View file

@ -0,0 +1,24 @@
.cursor-pointer {
cursor: pointer;
font-weight: 500;
color: white;
&:hover {
color: lightseagreen;
}
}
.container-fluid {
height: calc(100% - 56px);
}
.container.content {
padding-top: 15px;
height: 100%;
max-width: 100%;
// overflow-x: scroll;
}
.myContainer {
min-height: 100%;
max-width: 100%;
}

View file

@ -6,6 +6,7 @@ import { AppRoutingModule } from './app-routing.module';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { SupaService } from './api/supabase/supa.service'; import { SupaService } from './api/supabase/supa.service';
import { StandupService } from './api/supabase/standup.service';
import { AuthGuard } from './authguard.service'; import { AuthGuard } from './authguard.service';
import { AppComponent } from "./app.component"; import { AppComponent } from "./app.component";
@ -13,6 +14,10 @@ import { RecorderComponent } from './recorder/recorder.component';
import { LoginComponent } from './login/login.component'; import { LoginComponent } from './login/login.component';
import { SignupComponent } from './signup/signup.component'; import { SignupComponent } from './signup/signup.component';
import { HuddleComponent } from './huddle/huddle.component'; import { HuddleComponent } from './huddle/huddle.component';
import { ProfileComponent } from './profile/profile.component';
import { ChannelComponent } from './channel/channel.component';
import { ChannelListComponent } from './channel-list/channel-list.component';
import { DashboardComponent } from './dashboard/dashboard.component';
@NgModule({ @NgModule({
declarations: [ declarations: [
@ -20,7 +25,11 @@ import { HuddleComponent } from './huddle/huddle.component';
RecorderComponent, RecorderComponent,
HuddleComponent, HuddleComponent,
LoginComponent, LoginComponent,
SignupComponent SignupComponent,
ProfileComponent,
ChannelComponent,
ChannelListComponent,
DashboardComponent
], ],
imports: [ imports: [
BrowserModule, BrowserModule,
@ -30,6 +39,7 @@ import { HuddleComponent } from './huddle/huddle.component';
], ],
providers: [ providers: [
SupaService, SupaService,
StandupService,
AuthGuard, AuthGuard,
], ],
bootstrap: [ bootstrap: [

View file

@ -0,0 +1,17 @@
<div class="list bg-dark text-white p-3">
<p><strong>Standup</strong> <strong class="newBtn">+</strong></p>
<ul class="list-unstyled">
<li *ngFor="let s of standups" [title]="s.description" [routerLink]="'/huddle/'+s.id">{{s.name}}</li>
</ul>
<p><strong>Channel</strong> <strong class="newBtn">+</strong></p>
<ul class="list-unstyled">
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
</ul>
<p><strong>Settings</strong></p>
<ul class="list-unstyled">
<li [routerLink]="'/profile'">Profile</li>
</ul>
</div>

View file

@ -0,0 +1,22 @@
.list {
height: 100%;
max-width: 300px;
border-top: 1px dashed lightgray;
li {
padding: 5px 10px;
border-radius: 5px;
&:hover {
color: lightseagreen;
// -webkit-box-shadow: inset 0px 0px 4px 4px rgba(211, 211, 211, 0.4);
// box-shadow: inset 0px 0px 4px 4px rgba(211, 211, 211, 0.4);
cursor: pointer;
}
}
.newBtn {
margin-left:5px;
&:hover {
cursor: pointer;
color: lightseagreen;
}
}
}

View file

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

View file

@ -0,0 +1,29 @@
import { Component, OnInit } from '@angular/core';
import { Observable, throwError } from 'rxjs';
import { StandUp } from '../api/supabase/standup';
import { StandupService } from '../api/supabase/standup.service';
@Component({
selector: 'app-channel-list',
templateUrl: './channel-list.component.html',
styleUrls: ['./channel-list.component.scss']
})
export class ChannelListComponent implements OnInit {
standups: StandUp[] = [];
constructor(
private standupSevice: StandupService,
) { }
ngOnInit() {
this.loadStandUps().subscribe(standups => {
console.log('ChannelListComponent - StandUps', standups);
this.standups = standups;
});
}
loadStandUps(): Observable<StandUp[]> {
return this.standupSevice.getStandUps();
}
}

View file

@ -0,0 +1 @@
<p>channel works!</p>

View file

View file

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

View file

@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-channel',
templateUrl: './channel.component.html',
styleUrls: ['./channel.component.scss']
})
export class ChannelComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}

View file

@ -0,0 +1 @@
<p>dashboard works!</p>

View file

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

View file

@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.scss']
})
export class DashboardComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}

View file

@ -1,5 +1,6 @@
import { Component, OnInit, ViewChild } from "@angular/core"; import { Component, OnInit, ViewChild } from "@angular/core";
import { NgbModal, NgbModalRef } from "@ng-bootstrap/ng-bootstrap"; import { NgbModal, NgbModalRef } from "@ng-bootstrap/ng-bootstrap";
import { SupaService } from '../api/supabase/supa.service';
@Component({ @Component({
selector: 'app-huddle', selector: 'app-huddle',
@ -33,10 +34,12 @@ export class HuddleComponent implements OnInit {
]; ];
selectedUser; selectedUser;
constructor(private modalService: NgbModal) {} constructor(
private modalService: NgbModal,
public supa: SupaService,
) {}
ngOnInit() { ngOnInit() {
} }
playStory(user) { playStory(user) {

View file

@ -0,0 +1,6 @@
<legend>Profile</legend>
<pre>
<code *ngIf="user">
{{ user | json }}
</code>
</pre>

View file

View file

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

View file

@ -0,0 +1,24 @@
import { Component, OnInit } from '@angular/core';
import { SupabaseAuthUser } from '@supabase/supabase-js';
import { SupaService } from '../api/supabase/supa.service';
@Component({
selector: 'app-profile',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.scss']
})
export class ProfileComponent implements OnInit {
user: SupabaseAuthUser;
constructor(
public supa: SupaService,
) { }
ngOnInit(): void {
this.supa.client.auth.user().then(user => {
console.log('user', user)
this.user = user;
});
}
}

View file

@ -2,9 +2,9 @@
<ng-template #content let-modal> <ng-template #content let-modal>
<div class="modal-body d-flex flex-column"> <div class="modal-header">
<div> <strong>Record a stoy</strong>
<span class="float-right" (click)="modal.dismiss('Cross click')"> <span class="float-right cursor-pointer" (click)="modal.dismiss('Cross click')">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path <path
d="M6.2253 4.81108C5.83477 4.42056 5.20161 4.42056 4.81108 4.81108C4.42056 5.20161 4.42056 5.83477 4.81108 6.2253L10.5858 12L4.81114 17.7747C4.42062 18.1652 4.42062 18.7984 4.81114 19.1889C5.20167 19.5794 5.83483 19.5794 6.22535 19.1889L12 13.4142L17.7747 19.1889C18.1652 19.5794 18.7984 19.5794 19.1889 19.1889C19.5794 18.7984 19.5794 18.1652 19.1889 17.7747L13.4142 12L19.189 6.2253C19.5795 5.83477 19.5795 5.20161 19.189 4.81108C18.7985 4.42056 18.1653 4.42056 17.7748 4.81108L12 10.5858L6.2253 4.81108Z" d="M6.2253 4.81108C5.83477 4.42056 5.20161 4.42056 4.81108 4.81108C4.42056 5.20161 4.42056 5.83477 4.81108 6.2253L10.5858 12L4.81114 17.7747C4.42062 18.1652 4.42062 18.7984 4.81114 19.1889C5.20167 19.5794 5.83483 19.5794 6.22535 19.1889L12 13.4142L17.7747 19.1889C18.1652 19.5794 18.7984 19.5794 19.1889 19.1889C19.5794 18.7984 19.5794 18.1652 19.1889 17.7747L13.4142 12L19.189 6.2253C19.5795 5.83477 19.5795 5.20161 19.189 4.81108C18.7985 4.42056 18.1653 4.42056 17.7748 4.81108L12 10.5858L6.2253 4.81108Z"
@ -12,6 +12,7 @@
</svg> </svg>
</span> </span>
</div> </div>
<div class="modal-body d-flex flex-column">
<video *ngIf="stream" [id]="id" [srcObject]="stream" class="video-recorder" autoplay muted volume="0"></video> <video *ngIf="stream" [id]="id" [srcObject]="stream" class="video-recorder" autoplay muted volume="0"></video>
<button *ngIf="!isRecording" class="btn btn-success" (click)="startRecording()"> <button *ngIf="!isRecording" class="btn btn-success" (click)="startRecording()">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">

View file

@ -2,3 +2,9 @@
max-height: 50vh; max-height: 50vh;
max-width: 90vw; max-width: 90vw;
} }
.cursor-pointer {
cursor: pointer;
&:hover {
color: lightseagreen;
}
}

View file

@ -3,4 +3,5 @@
html, html,
body { body {
font-family: sans-serif; font-family: sans-serif;
height: 100%;
} }