| @@ -3,6 +3,7 @@ import { Routes, RouterModule } from '@angular/router'; | |||||
| import { WelcomeComponent } from './welcome/welcome.component'; | import { WelcomeComponent } from './welcome/welcome.component'; | ||||
| import { TabsComponent } from './tabs/tabs.component'; | import { TabsComponent } from './tabs/tabs.component'; | ||||
| import { DetailsComponent } from './tabs/courses/details/details.component'; | import { DetailsComponent } from './tabs/courses/details/details.component'; | ||||
| import { VideoChapterComponent } from './tabs/courses/video-chapter/video-chapter.component'; | |||||
| const routes: Routes = [ | const routes: Routes = [ | ||||
| { path: '', pathMatch: 'full', redirectTo: 'welcome' }, | { path: '', pathMatch: 'full', redirectTo: 'welcome' }, | ||||
| @@ -10,7 +11,8 @@ const routes: Routes = [ | |||||
| { component: TabsComponent, path: 'tabs' }, | { component: TabsComponent, path: 'tabs' }, | ||||
| { component: TabsComponent, path: 'tabs/:subpage' }, | { component: TabsComponent, path: 'tabs/:subpage' }, | ||||
| { component: DetailsComponent, path: 'course-details' }, | { component: DetailsComponent, path: 'course-details' }, | ||||
| { component: DetailsComponent, path: 'course-details/:heading' } | |||||
| { component: DetailsComponent, path: 'course-details/:heading' }, | |||||
| { component: VideoChapterComponent, path: 'video-chapter/:heading' } | |||||
| ]; | ]; | ||||
| @NgModule({ | @NgModule({ | ||||
| @@ -12,6 +12,7 @@ import { CoursesComponent } from './tabs/courses/courses.component'; | |||||
| import { ReportsComponent } from './tabs/reports/reports.component'; | import { ReportsComponent } from './tabs/reports/reports.component'; | ||||
| import { MoreComponent } from './tabs/more/more.component'; | import { MoreComponent } from './tabs/more/more.component'; | ||||
| import { DetailsComponent } from './tabs/courses/details/details.component'; | import { DetailsComponent } from './tabs/courses/details/details.component'; | ||||
| import { VideoChapterComponent } from './tabs/courses/video-chapter/video-chapter.component'; | |||||
| @NgModule({ | @NgModule({ | ||||
| declarations: [ | declarations: [ | ||||
| @@ -23,6 +24,7 @@ import { DetailsComponent } from './tabs/courses/details/details.component'; | |||||
| ReportsComponent, | ReportsComponent, | ||||
| MoreComponent, | MoreComponent, | ||||
| DetailsComponent, | DetailsComponent, | ||||
| VideoChapterComponent, | |||||
| ], | ], | ||||
| imports: [ | imports: [ | ||||
| BrowserModule, | BrowserModule, | ||||
| @@ -53,7 +53,7 @@ | |||||
| <svg-icon [applyClass]="true" class="icon arrow" src="assets/custom-icons/down-arrow.svg"></svg-icon> | <svg-icon [applyClass]="true" class="icon arrow" src="assets/custom-icons/down-arrow.svg"></svg-icon> | ||||
| </div> | </div> | ||||
| <ul class="topic-list"> | <ul class="topic-list"> | ||||
| <li class="topic completed"> | |||||
| <li class="topic completed" [routerLink]="['/video-chapter/', 'Topic-1']"> | |||||
| <svg-icon [applyClass]="true" class="icon checkmark" src="assets/custom-icons/checkmark.svg"></svg-icon> | <svg-icon [applyClass]="true" class="icon checkmark" src="assets/custom-icons/checkmark.svg"></svg-icon> | ||||
| <div class="topic-container"> | <div class="topic-container"> | ||||
| <p> | <p> | ||||
| @@ -63,7 +63,7 @@ | |||||
| </div> | </div> | ||||
| </li> | </li> | ||||
| <li class="topic completed"> | |||||
| <li class="topic completed" [routerLink]="['/video-chapter/', 'Topic-2']"> | |||||
| <svg-icon [applyClass]="true" class="icon checkmark" src="assets/custom-icons/checkmark.svg"></svg-icon> | <svg-icon [applyClass]="true" class="icon checkmark" src="assets/custom-icons/checkmark.svg"></svg-icon> | ||||
| <div class="topic-container"> | <div class="topic-container"> | ||||
| <p> | <p> | ||||
| @@ -73,7 +73,7 @@ | |||||
| </div> | </div> | ||||
| </li> | </li> | ||||
| <li class="topic"> | |||||
| <li class="topic" [routerLink]="['/video-chapter/', 'Topic-3']"> | |||||
| <svg-icon [applyClass]="true" class="icon checkmark" src="assets/custom-icons/checkmark.svg"></svg-icon> | <svg-icon [applyClass]="true" class="icon checkmark" src="assets/custom-icons/checkmark.svg"></svg-icon> | ||||
| <div class="topic-container"> | <div class="topic-container"> | ||||
| <p> | <p> | ||||
| @@ -83,7 +83,7 @@ | |||||
| </div> | </div> | ||||
| </li> | </li> | ||||
| <li class="topic"> | |||||
| <li class="topic" [routerLink]="['/video-chapter/', 'Topic-4']"> | |||||
| <svg-icon [applyClass]="true" class="icon checkmark" src="assets/custom-icons/checkmark.svg"></svg-icon> | <svg-icon [applyClass]="true" class="icon checkmark" src="assets/custom-icons/checkmark.svg"></svg-icon> | ||||
| <div class="topic-container"> | <div class="topic-container"> | ||||
| <p> | <p> | ||||
| @@ -93,7 +93,7 @@ | |||||
| </div> | </div> | ||||
| </li> | </li> | ||||
| <li class="topic"> | |||||
| <li class="topic" [routerLink]="['/video-chapter/', 'Topic-5']"> | |||||
| <svg-icon [applyClass]="true" class="icon checkmark" src="assets/custom-icons/checkmark.svg"></svg-icon> | <svg-icon [applyClass]="true" class="icon checkmark" src="assets/custom-icons/checkmark.svg"></svg-icon> | ||||
| <div class="topic-container"> | <div class="topic-container"> | ||||
| <p> | <p> | ||||
| @@ -0,0 +1,99 @@ | |||||
| <div class="page"> | |||||
| <header class="nav-header"> | |||||
| <button class="close-button" (click)="back()"> | |||||
| <svg-icon [applyClass]="true" class="icon" src="assets/custom-icons/close.svg"></svg-icon> | |||||
| </button> | |||||
| <h5> | |||||
| <svg-icon [applyClass]="true" class="icon" src="assets/custom-icons/play-button.svg"></svg-icon> | |||||
| <span> {{ heading }} </span> | |||||
| </h5> | |||||
| </header> | |||||
| <section class="video-player"> | |||||
| <button class="play-button"> | |||||
| <svg-icon [applyClass]="true" class="icon" src="assets/custom-icons/play-button.svg"></svg-icon> | |||||
| </button> | |||||
| </section> | |||||
| <section class="segments"> | |||||
| <button (click)="selectedSegment='transcript'" | |||||
| [ngClass]="{'active': selectedSegment === 'transcript' }"> Transcript </button> | |||||
| <button (click)="selectedSegment='attachments'" | |||||
| [ngClass]="{'active': selectedSegment === 'attachments' }"> Attachments (2) </button> | |||||
| <button (click)="selectedSegment='notes'" | |||||
| [ngClass]="{'active': selectedSegment === 'notes' }"> Notes (2) </button> | |||||
| </section> | |||||
| <section class="segment-details"> | |||||
| <section *ngIf="selectedSegment === 'transcript'" class="transcript"> | |||||
| <p> | |||||
| <span class="highlight"> Lorem ipsum dolor sit amet, consectetur adipisicing elit.</span> Quis voluptates sint illum dolorem. Non beatae, illum repellendus maxime sunt nulla at inventore odit, voluptate laudantium doloribus. Atque vitae, veritatis aperiam. | |||||
| </p> | |||||
| <p> | |||||
| Lorem ipsum dolor sit amet, consectetur adipisicing elit. Expedita dolores ea facere quae temporibus. Beatae modi voluptates, dolorem, eveniet sed non a quaerat aperiam officiis voluptatibus nemo! Similique, tempora aspernatur. | |||||
| </p> | |||||
| <p> | |||||
| Lorem ipsum dolor sit amet, consectetur adipisicing elit. Hic nihil molestias perspiciatis reprehenderit, ad adipisci quas nam, minima id vitae dolore impedit iste mollitia quibusdam alias commodi quam qui voluptatibus. | |||||
| </p> | |||||
| </section> | |||||
| <ul class="attachment-list" *ngIf="selectedSegment === 'attachments'"> | |||||
| <li> | |||||
| <div class="content"> | |||||
| <label> Attachment 1 </label> | |||||
| <p> | |||||
| quidem minima dolor delectus optio, dicta. | |||||
| </p> | |||||
| </div> | |||||
| <svg-icon [applyClass]="true" class="icon" src="assets/custom-icons/delete.svg"></svg-icon> | |||||
| </li> | |||||
| <li> | |||||
| <div class="content"> | |||||
| <label> Attachment 2 </label> | |||||
| <p> | |||||
| quidem minima dolor delectus optio, dicta. | |||||
| </p> | |||||
| </div> | |||||
| <svg-icon [applyClass]="true" class="icon download" src="assets/custom-icons/download.svg"></svg-icon> | |||||
| </li> | |||||
| </ul> | |||||
| <ul class="notes-list" *ngIf="selectedSegment === 'notes'"> | |||||
| <li> | |||||
| <div class="content"> | |||||
| <label> Notes 1 </label> | |||||
| <p> | |||||
| quidem minima dolor delectus optio, dicta. | |||||
| </p> | |||||
| </div> | |||||
| <svg-icon [applyClass]="true" class="icon arrow" src="assets/custom-icons/down-arrow.svg"></svg-icon> | |||||
| </li> | |||||
| <li> | |||||
| <div class="content"> | |||||
| <label> Notes 2 </label> | |||||
| <p> | |||||
| quidem minima dolor delectus optio, dicta. | |||||
| </p> | |||||
| </div> | |||||
| <svg-icon [applyClass]="true" class="icon arrow" src="assets/custom-icons/down-arrow.svg"></svg-icon> | |||||
| </li> | |||||
| <li> | |||||
| <div class="content"> | |||||
| <label> Notes 2 </label> | |||||
| <p> | |||||
| quidem minima dolor delectus optio, dicta. | |||||
| </p> | |||||
| </div> | |||||
| <svg-icon [applyClass]="true" class="icon arrow" src="assets/custom-icons/down-arrow.svg"></svg-icon> | |||||
| </li> | |||||
| <button class="add-notes-button"> | |||||
| <svg-icon [applyClass]="true" class="icon" src="assets/custom-icons/add.svg"></svg-icon> | |||||
| <span> SAVE A NOTE </span> | |||||
| </button> | |||||
| </ul> | |||||
| </section> | |||||
| </div> | |||||
| @@ -0,0 +1,215 @@ | |||||
| .page { | |||||
| background-color: var(--black); | |||||
| height: 100vh; | |||||
| overflow: auto; | |||||
| } | |||||
| .nav-header { | |||||
| background-color: var(--ash-black); | |||||
| display: flex; | |||||
| align-items: center; | |||||
| padding: 0 5%; | |||||
| height: 60px; | |||||
| position: sticky; | |||||
| position: -webkit-sticky; | |||||
| top: 0; | |||||
| z-index: 1; | |||||
| .close-button { | |||||
| border: 0px; | |||||
| background-color: transparent; | |||||
| .icon { | |||||
| width: 16px; | |||||
| height: 16px; | |||||
| fill: var(--light-grey); | |||||
| } | |||||
| } | |||||
| h5 { | |||||
| font-size: 16px; | |||||
| color: white; | |||||
| font-weight: 400; | |||||
| margin-left: 20px; | |||||
| letter-spacing: 1px; | |||||
| .icon { | |||||
| width: 15px; | |||||
| height: 15px; | |||||
| fill: white; | |||||
| margin-right: 3px; | |||||
| vertical-align: middle; | |||||
| position: relative; | |||||
| top: -1px; | |||||
| } | |||||
| } | |||||
| } | |||||
| .video-player { | |||||
| background-color: var(--dark-grey); | |||||
| color: white; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| height: 40vh; | |||||
| width: 100%; | |||||
| .play-button { | |||||
| background-color: transparent; | |||||
| border: 0px; | |||||
| } | |||||
| .icon { | |||||
| width: 50px; | |||||
| height: 50px; | |||||
| fill: white; | |||||
| } | |||||
| } | |||||
| .segments { | |||||
| display: flex; | |||||
| align-items: stretch; | |||||
| height: 40px; | |||||
| border-radius: 7px; | |||||
| overflow: hidden; | |||||
| width: 90%; | |||||
| margin: 20px auto; | |||||
| background-color: var(--dark-grey); | |||||
| button { | |||||
| flex-grow: 1; | |||||
| border-radius: 7px; | |||||
| background-color: transparent; | |||||
| color: white; | |||||
| font-size: 13px; | |||||
| border: 0px; | |||||
| &.active { | |||||
| background-color: white; | |||||
| color: var(--teal); | |||||
| font-weight: 500; | |||||
| } | |||||
| } | |||||
| } | |||||
| .segment-details { | |||||
| padding: 0 6%; | |||||
| } | |||||
| .transcript { | |||||
| color: var(--light-grey); | |||||
| p { | |||||
| font-size: 17px; | |||||
| line-height: 2; | |||||
| margin-bottom: 20px; | |||||
| .highlight { | |||||
| color: white; | |||||
| } | |||||
| } | |||||
| } | |||||
| .attachment-list { | |||||
| list-style: none; | |||||
| li { | |||||
| padding: 15px; | |||||
| background-color: var(--ash-black); | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: space-between; | |||||
| border-radius: 10px; | |||||
| overflow: hidden; | |||||
| margin-bottom: 15px; | |||||
| } | |||||
| .content { | |||||
| width: calc(100% - 50px); | |||||
| } | |||||
| label { | |||||
| color: white; | |||||
| font-size: 15px; | |||||
| display: block; | |||||
| } | |||||
| p { | |||||
| color: var(--light-grey); | |||||
| font-size: 12px; | |||||
| } | |||||
| .icon { | |||||
| width: 20px; | |||||
| height: 20px; | |||||
| fill: var(--light-grey); | |||||
| &.download { | |||||
| fill: var(--teal-green); | |||||
| } | |||||
| } | |||||
| } | |||||
| .notes-list { | |||||
| list-style: none; | |||||
| padding-bottom: 60px; | |||||
| li { | |||||
| padding: 15px; | |||||
| background-color: var(--ash-black); | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: space-between; | |||||
| border-radius: 10px; | |||||
| overflow: hidden; | |||||
| margin-bottom: 15px; | |||||
| } | |||||
| .content { | |||||
| width: calc(100% - 50px); | |||||
| } | |||||
| label { | |||||
| color: white; | |||||
| font-size: 15px; | |||||
| display: block; | |||||
| } | |||||
| p { | |||||
| color: var(--light-grey); | |||||
| font-size: 12px; | |||||
| } | |||||
| .icon { | |||||
| width: 20px; | |||||
| height: 20px; | |||||
| fill: var(--light-grey); | |||||
| &.arrow { | |||||
| transform: rotate(-45deg); | |||||
| } | |||||
| } | |||||
| .add-notes-button { | |||||
| position: fixed; | |||||
| left: 0px; | |||||
| bottom: 0px; | |||||
| background-color: var(--ash-black); | |||||
| color: var(--light-grey); | |||||
| font-size: 14px; | |||||
| width: 100%; | |||||
| height: 50px; | |||||
| border: 0px; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| box-shadow: 0px 0px 5px var(--black); | |||||
| .icon { | |||||
| width: 20px; | |||||
| height: 20px; | |||||
| fill: var(--light-grey); | |||||
| margin-right: 5px; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,25 @@ | |||||
| import { async, ComponentFixture, TestBed } from '@angular/core/testing'; | |||||
| import { VideoChapterComponent } from './video-chapter.component'; | |||||
| describe('VideoChapterComponent', () => { | |||||
| let component: VideoChapterComponent; | |||||
| let fixture: ComponentFixture<VideoChapterComponent>; | |||||
| beforeEach(async(() => { | |||||
| TestBed.configureTestingModule({ | |||||
| declarations: [ VideoChapterComponent ] | |||||
| }) | |||||
| .compileComponents(); | |||||
| })); | |||||
| beforeEach(() => { | |||||
| fixture = TestBed.createComponent(VideoChapterComponent); | |||||
| component = fixture.componentInstance; | |||||
| fixture.detectChanges(); | |||||
| }); | |||||
| it('should create', () => { | |||||
| expect(component).toBeTruthy(); | |||||
| }); | |||||
| }); | |||||
| @@ -0,0 +1,35 @@ | |||||
| import { Component, OnInit } from '@angular/core'; | |||||
| import { ActivatedRoute } from '@angular/router'; | |||||
| import { Subscription } from 'rxjs'; | |||||
| import { Location } from '@angular/common'; | |||||
| @Component({ | |||||
| selector: 'app-video-chapter', | |||||
| templateUrl: './video-chapter.component.html', | |||||
| styleUrls: ['./video-chapter.component.scss'] | |||||
| }) | |||||
| export class VideoChapterComponent implements OnInit { | |||||
| selectedSegment: string = 'transcript'; | |||||
| heading: string; | |||||
| routeSubscription: Subscription; | |||||
| constructor( | |||||
| private route: ActivatedRoute, | |||||
| private location: Location | |||||
| ) { } | |||||
| ngOnInit(): void { | |||||
| this.routeSubscription = this.route.params.subscribe((params) => { | |||||
| this.heading = params['heading']; | |||||
| }); | |||||
| } | |||||
| ngOnDestroy() { | |||||
| this.routeSubscription.unsubscribe(); | |||||
| } | |||||
| back() { | |||||
| this.location.back(); | |||||
| } | |||||
| } | |||||