ソースを参照

Quiz UI

master
kj1352 6年前
コミット
8a1d962489
9個のファイルの変更521行の追加2行の削除
  1. +2
    -0
      src/app/app-routing.module.ts
  2. +2
    -0
      src/app/app.module.ts
  3. +1
    -1
      src/app/tabs/courses/course-details/course-details.component.html
  4. +164
    -0
      src/app/tabs/courses/quiz/quiz.component.html
  5. +281
    -0
      src/app/tabs/courses/quiz/quiz.component.scss
  6. +25
    -0
      src/app/tabs/courses/quiz/quiz.component.spec.ts
  7. +44
    -0
      src/app/tabs/courses/quiz/quiz.component.ts
  8. +1
    -1
      src/app/tabs/courses/video-chapter/video-notes/video-notes.component.ts
  9. +1
    -0
      src/styles.scss

+ 2
- 0
src/app/app-routing.module.ts ファイルの表示

@@ -9,6 +9,7 @@ import { CalendarComponent } from './calendar/calendar.component';
import { AttendanceComponent } from './tabs/more/attendance/attendance.component'; import { AttendanceComponent } from './tabs/more/attendance/attendance.component';
import { ForumPageComponent } from './tabs/more/forum-page/forum-page.component'; import { ForumPageComponent } from './tabs/more/forum-page/forum-page.component';
import { ChapterNotesComponent } from './tabs/courses/chapter-notes/chapter-notes.component'; import { ChapterNotesComponent } from './tabs/courses/chapter-notes/chapter-notes.component';
import { QuizComponent } from './tabs/courses/quiz/quiz.component';


const routes: Routes = [ const routes: Routes = [
{ path: '', pathMatch: 'full', redirectTo: 'welcome' }, { path: '', pathMatch: 'full', redirectTo: 'welcome' },
@@ -19,6 +20,7 @@ const routes: Routes = [
{ component: ChapterNotesComponent, path: 'chapter-notes/:heading' }, { component: ChapterNotesComponent, path: 'chapter-notes/:heading' },
{ component: VideoChapterComponent, path: 'video-chapter/:heading' }, { component: VideoChapterComponent, path: 'video-chapter/:heading' },
{ component: VideoNotesComponent, path: 'video-notes/:heading' }, { component: VideoNotesComponent, path: 'video-notes/:heading' },
{ component: QuizComponent, path: 'quiz' },
{ component: CalendarComponent, path: 'calendar' }, { component: CalendarComponent, path: 'calendar' },
{ component: AttendanceComponent, path: 'attendance'}, { component: AttendanceComponent, path: 'attendance'},
{ component: ForumPageComponent, path: 'forum'}, { component: ForumPageComponent, path: 'forum'},


+ 2
- 0
src/app/app.module.ts ファイルの表示

@@ -24,6 +24,7 @@ import { ConfirmationPopupComponent } from './reusable-components/confirmation-p
import { VideoNotesComponent } from './tabs/courses/video-chapter/video-notes/video-notes.component'; import { VideoNotesComponent } from './tabs/courses/video-chapter/video-notes/video-notes.component';
import { ChapterNotesComponent } from './tabs/courses/chapter-notes/chapter-notes.component'; import { ChapterNotesComponent } from './tabs/courses/chapter-notes/chapter-notes.component';
import { CourseDetailsComponent } from './tabs/courses/course-details/course-details.component'; import { CourseDetailsComponent } from './tabs/courses/course-details/course-details.component';
import { QuizComponent } from './tabs/courses/quiz/quiz.component';


@NgModule({ @NgModule({
declarations: [ declarations: [
@@ -43,6 +44,7 @@ import { CourseDetailsComponent } from './tabs/courses/course-details/course-det
VideoNotesComponent, VideoNotesComponent,
ChapterNotesComponent, ChapterNotesComponent,
CourseDetailsComponent, CourseDetailsComponent,
QuizComponent,
], ],
imports: [ imports: [
BrowserModule, BrowserModule,


+ 1
- 1
src/app/tabs/courses/course-details/course-details.component.html ファイルの表示

@@ -32,7 +32,7 @@
<p> <p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quidem ab vel reiciendis. Repudiandae nobis pariatur laboriosam, natus quidem quos architecto provident similique officiis vero at cum excepturi eius, eligendi aperiam. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quidem ab vel reiciendis. Repudiandae nobis pariatur laboriosam, natus quidem quos architecto provident similique officiis vero at cum excepturi eius, eligendi aperiam.
</p> </p>
<button> Take the test now! </button>
<button [routerLink]="['/quiz']"> Take the test now! </button>
</section> </section>
</section> </section>




+ 164
- 0
src/app/tabs/courses/quiz/quiz.component.html ファイルの表示

@@ -0,0 +1,164 @@
<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/question-mark.svg"></svg-icon>
<span> Quiz </span>
</h5>
</header>

<section class="question-status">
<div class="question-number correct">
<span>
<label> 1 </label>
<svg-icon [applyClass]="true" class="icon" src="assets/custom-icons/checkmark.svg"></svg-icon>
</span>
</div>
<div class="question-number wrong">
<span>
<label> 2 </label>
<svg-icon [applyClass]="true" class="icon" src="assets/custom-icons/close.svg"></svg-icon>
</span>
</div>
<div class="question-number correct">
<span>
<label> 3 </label>
<svg-icon [applyClass]="true" class="icon" src="assets/custom-icons/checkmark.svg"></svg-icon>
</span>
</div>
<div class="question-number wrong">
<span>
<label> 4 </label>
<svg-icon [applyClass]="true" class="icon" src="assets/custom-icons/close.svg"></svg-icon>
</span>
</div>
<div class="question-number correct">
<span>
<label> 5 </label>
<svg-icon [applyClass]="true" class="icon" src="assets/custom-icons/checkmark.svg"></svg-icon>
</span>
</div>
<div class="question-number wrong">
<span>
<label> 6 </label>
<svg-icon [applyClass]="true" class="icon" src="assets/custom-icons/close.svg"></svg-icon>
</span>
</div>
<div class="question-number current">
<span>
<label> 7 </label>
<svg-icon [applyClass]="true" class="icon" src="assets/custom-icons/checkmark.svg"></svg-icon>
</span>
</div>

<div class="question-number">
<span>
<label> 8 </label>
<svg-icon [applyClass]="true" class="icon" src="assets/custom-icons/checkmark.svg"></svg-icon>
</span>
</div>

<div class="question-number">
<span>
<label> 9 </label>
<svg-icon [applyClass]="true" class="icon" src="assets/custom-icons/checkmark.svg"></svg-icon>
</span>
</div>

<div class="question-number">
<span>
<label> 10 </label>
<svg-icon [applyClass]="true" class="icon" src="assets/custom-icons/checkmark.svg"></svg-icon>
</span>
</div>
</section>

<ngx-siema [options]="options">
<ngx-siema-slide>
<p class="question">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Architecto obcaecati perferendis suscipit consequuntur labore voluptatibus vitae totam minima, tempore excepturi, cum at qui voluptas rerum nostrum odio minus, voluptatem dolores. ?
</p>

<div class="timer-holder">
<div class="timer">
<span> 00:60 </span>
<svg width="55" height="55" viewBox="0 0 55 55">
<circle cx="27.5" cy="27.5" r="21.5" fill="none" stroke="#cecece" stroke-width="3" />
<circle cx="27.5" cy="27.5" r="21.5" fill="none" stroke-width="3"
stroke-dasharray="135.2" stroke-dashoffset="52.08" id="progress" />
</svg>
</div>
</div>

<!-- 135.2 * (1 - 0.6) -->

<ol class="option-list">
<li class="wrong">
<label> 1. Option 1 </label>
<div class="icon-holder">
<svg-icon [applyClass]="true" class="icon" src="assets/custom-icons/close.svg"></svg-icon>
</div>
</li>
<li>
<label> 2. Option 2 </label>
<div class="icon-holder">
<svg-icon [applyClass]="true" class="icon" src="assets/custom-icons/checkmark.svg"></svg-icon>
</div>
</li>
<li>
<label> 3. Option 3 </label>
<div class="icon-holder">
<svg-icon [applyClass]="true" class="icon" src="assets/custom-icons/checkmark.svg"></svg-icon>
</div>
</li>
<li class="correct">
<label> 4. Option 4 </label>
<div class="icon-holder">
<svg-icon [applyClass]="true" class="icon" src="assets/custom-icons/checkmark.svg"></svg-icon>
</div>
</li>
</ol>
</ngx-siema-slide>


<ngx-siema-slide>
<p class="question">
dis suscipit consequuntur labore voluptatibus vitae totam minima, tempore excepturi, cum at qui voluptas rerum nostrum odio minus, voluptatem dolores. ?
</p>

<div class="timer-holder">
<div class="timer">
<span> 00:40 </span>
<svg width="55" height="55" viewBox="0 0 55 55">
<circle cx="27.5" cy="27.5" r="21.5" fill="none" stroke="#cecece" stroke-width="3" />
<circle cx="27.5" cy="27.5" r="21.5" fill="none" stroke-width="3"
stroke-dasharray="135.2" stroke-dashoffset="52.08" id="progress" />
</svg>
</div>
</div>

<!-- 135.2 * (1 - 0.6) -->

<ol class="option-list">
<li class="wrong">
<label> 1. Option 1 </label>
<div class="icon-holder">
<svg-icon [applyClass]="true" class="icon" src="assets/custom-icons/close.svg"></svg-icon>
</div>
</li>
<li>
<label> 2. Option 2 </label>
<div class="icon-holder">
<svg-icon [applyClass]="true" class="icon" src="assets/custom-icons/checkmark.svg"></svg-icon>
</div>
</li>
</ol>

</ngx-siema-slide>
</ngx-siema>

<button class="next-button" (click)="next()"> Next </button>

</div>

+ 281
- 0
src/app/tabs/courses/quiz/quiz.component.scss ファイルの表示

@@ -0,0 +1,281 @@
.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;
box-shadow: 0px 0px 5px var(--black);

.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;
}
}
}

.question-status {
background-color: var(--ash-black);
padding: 10px 5% 5px;
display: inline-block;
white-space: nowrap;
width: 100%;
overflow: auto;
margin-bottom: -10px;

.question-number {
width: 20px;
height: 20px;
background-color: var(--dark-grey);
color: white;
align-items: center;
justify-content: center;
display: inline-block;
margin-right: 15px;
border-radius: 50%;
overflow: hidden;
border: 1px solid var(--dark-grey);
box-sizing: content-box;

span {
display: flex;
width: 100%;
height: 100%;
align-items: center;
justify-content: center;
}

label {
font-size: 10px;
}

.icon {
width: 100%;
height: 100%;
fill: white;
display: none;
}

&.correct {
border-color: var(--green);
background-color: white;

label {
display: none;
}

.icon {
fill: var(--green);
display: block;
}
}

&.wrong {
border-color: var(--danger-dark);
background-color: var(--danger-dark);

label {
display: none;
}

.icon {
fill: white;
width: 10px;
height: 10px;
display: block;
}
}

&.current {
border-color: var(--light-grey);
}
}
}

ngx-siema-slide {
display: block;

.question {
line-height: 1.6;
color: white;
font-size: 14px;
background-color: var(--ash-black);
padding: 15px 5%;
}

.timer-holder {
background-color: var(--black);
height: 70px;
display: flex;
align-items: flex-end;
justify-content: center;
overflow: hidden;
position: relative;

&::before {
content: '';
width: 200vw;
height: 100vw;
border-radius: 50%;
position: absolute;
bottom: 25px;
background-color: var(--ash-black);
}

.timer {
width: 60px;
height: 60px;
border-radius: 50%;
background-color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
font-weight: 600;
position: relative;
color: var(--ash-black);

svg {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
transform: rotate(-90deg);

#progress {
stroke: var(--green);
}
}
}
}
}


.option-list {
width: 90%;
margin: 20px auto;
list-style: none;

li {
display: flex;
width: 100%;
border: 1px solid var(--light-grey);
color: white;
border-radius: 15px;
align-items: center;
min-height: 50px;
margin: 20px auto;
justify-content: space-between;
padding: 0 15px;

label {
font-size: 14px;
}

.icon-holder {
width: 23px;
height: 23px;
border: 1px solid var(--light-grey);
border-radius: 50%;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;

.icon {
width: 100%;
height: 100%;
fill: white;
display: none;
}
}

&.correct {
box-shadow: 0px 0px 5px var(--green);
border-color: var(--green);

label {
color: var(--green);
}

.icon-holder {
border-color: var(--green);
background-color: white;

.icon {
fill: var(--green);
display: block;
}
}
}

&.wrong {
box-shadow: 0px 0px 5px var(--danger-dark);
border-color: var(--danger-dark);

label {
color: var(--danger-dark);
}

.icon-holder {
border-color: var(--danger-dark);
background-color: var(--danger-dark);

.icon {
fill: white;
width: 10px;
height: 10px;
display: block;
}
}
}
}
}

.next-button {
width: 100px;
height: 50px;
border-radius: 30px;
background-color: var(--teal-green);
color: white;
font-size: 14px;
border: 0px;
display: block;
position: sticky;
position: -webkit-sticky;
bottom: 20px;
margin: 10px auto 40px;
box-shadow: 0px 0px 10px var(--teal-green);
}

+ 25
- 0
src/app/tabs/courses/quiz/quiz.component.spec.ts ファイルの表示

@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { QuizComponent } from './quiz.component';

describe('QuizComponent', () => {
let component: QuizComponent;
let fixture: ComponentFixture<QuizComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ QuizComponent ]
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(QuizComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});

+ 44
- 0
src/app/tabs/courses/quiz/quiz.component.ts ファイルの表示

@@ -0,0 +1,44 @@
import { Component, OnInit } from '@angular/core';
import { Location } from '@angular/common';
import { NgxSiemaOptions, NgxSiemaService } from 'ngx-siema';

@Component({
selector: 'app-quiz',
templateUrl: './quiz.component.html',
styleUrls: ['./quiz.component.scss']
})
export class QuizComponent implements OnInit {
options: NgxSiemaOptions = {
selector: '.siema',
duration: 300,
easing: 'ease-out',
perPage: 1,
startIndex: 0,
draggable: false,
threshold: 20,
loop: false,
onInit: () => {
// runs immediately after first initialization
},
onChange: () => {
// runs after slide change
},
};

constructor(
private location: Location,
private ngxSiemaService: NgxSiemaService
) { }

ngOnInit(): void {
}

next() {
this.ngxSiemaService.next(1);
}

back() {
this.location.back();
}

}

+ 1
- 1
src/app/tabs/courses/video-chapter/video-notes/video-notes.component.ts ファイルの表示

@@ -45,7 +45,7 @@ export class VideoNotesComponent implements OnInit {
} }


next() { next() {
this.ngxSiemaService.next(1).subscribe((data: any) => console.log(data));
this.ngxSiemaService.next(1);
} }


ngOnDestroy() { ngOnDestroy() {


+ 1
- 0
src/styles.scss ファイルの表示

@@ -19,6 +19,7 @@
--green: #8cc63f; --green: #8cc63f;
--teal-green: #08c17e; --teal-green: #08c17e;
--danger: #ea8b8b; --danger: #ea8b8b;
--danger-dark: #d65f5f;
} }


.confirmation-popup { .confirmation-popup {