Skip to content

QUIZ-05 Creates SummaryStats component #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions src/components/ProgressBar.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<template>
<progress
:max="max"
:aria-valuemax="max"
:aria-valuemin="min"
:value="value"
:aria-valuenow="value"
:aria-labelledby="label"
>
<div
class="progress-bar"
:aria-valuemax="max"
:aria-valuemin="min"
:aria-valuenow="value"
:aria-labelledby="label"
>
<div :style="styleObject"></div>
</div>
</progress>
</template>

<script>
export default {
props: {
value: {
type: Number,
required: true,
},
min: {
type: Number,
default: 0,
},
max: {
type: Number,
default: 100,
},
label: {
type: String,
default: '',
},
},
data() {
return {
styleObject: {
width: this.value + '%',
},
};
},
};
</script>

<style lang="scss" scoped>
@mixin default-bar-styles {
background-color: $color-mystic;
box-shadow: inset 0 1px 2px 0 $color-regent-gray;
width: 100%;
}
$bar-color: $color-salem;

progress {
@include default-bar-styles();
appearance: none;
border: none;
color: $bar-color;
}

progress::-webkit-progress-bar {
@include default-bar-styles();
}

progress::-webkit-progress-value {
background-color: $bar-color;
}

progress::-moz-progress-bar {
background-color: $bar-color;
}

.progress-bar {
@include default-bar-styles();
> div {
background-color: $bar-color;
height: 100%;
}
}

progress,
.progress-bar {
height: 24px;
}
</style>
125 changes: 125 additions & 0 deletions src/components/SummaryStats.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<template>
<h2>Summary</h2>
<div class="summary u-padding-horizontal-sm u-padding-vertical u-margin-bottom-lg">
<h3 class="u-margin-top-none u-margin-bottom-sm">Your Score</h3>
<ProgressBar :value="getScore" label="quiz-score" />
<span id="quiz-score" class="grade-details progress-bar-label u-margin-left-xs">{{
displayScoreAsPercent
}}</span>
<span class="meta meta--duration">Time Spent: {{ formattedDuration }}</span>
<SvgIconContainer width="24" height="24" icon-name="Success" aria-hidden>
<IconCheckmark />
</SvgIconContainer>
<span class="grade-details is-graded">
Score recorded as grade
</span>
<span class="meta meta--time">Finished: {{ formattedDate }}</span>
</div>
</template>

<script>
import { mapGetters } from 'vuex';
import SvgIconContainer from './SvgIconContainer.vue';
import IconCheckmark from './icons/IconCheckmark.vue';
import ProgressBar from './ProgressBar';
export default {
components: {
SvgIconContainer,
IconCheckmark,
ProgressBar,
},
props: {
data: {
type: Object,
required: true,
},
},
computed: {
...mapGetters({
listQuestions: 'quiz/listQuestions',
countQuestions: 'quiz/countQuestions',
countCorrect: 'quiz/countCorrect',
getScore: 'quiz/calcScore',
}),
displayScoreAsPercent() {
return this.getScore + '%';
},
formattedDuration() {
const durationArray = this.data.timeSpent.split(':');
const duration = [];
const labels = ['hrs', 'mins', 'secs'];
durationArray.forEach((time, i) => {
time = time.toString();
duration.push(time + ' ' + labels[i]);
});
return duration.join(' ');
},
formattedDate() {
const timeCompleted = new Date(this.data.completed);
const dateTimeOptions = {
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
};
return new Intl.DateTimeFormat('en-US', dateTimeOptions).format(timeCompleted);
},
},
};
</script>

<style lang="scss" scoped>
$border-style: 1px solid $color-loblolly;

h2 {
font: {
size: $text-size-up-3;
weight: 400;
}
}
.summary {
align-items: center;
border: $border-style;
border-radius: 4px;
display: grid;
grid-template-areas:
'title title title title'
'progressBar stats icon grade'
'durationMeta . . timeMeta';
grid-template-columns: 1fr 80px 28px 1fr;
width: 96%;
}
h3 {
font: {
size: $text-size-up-1;
weight: 400;
}
grid-area: title;
}
.grade-details {
font-size: $text-size-up-1;
}
.progress-bar-label {
letter-spacing: 1px;
}
svg {
color: $color-salem;
}
.is-graded {
grid-area: grade;
}
.meta {
font: {
size: $text-size-down-1;
weight: 400;
}
margin-top: $spacing-unit-xs;
&--duration {
grid-area: durationMeta;
}
&--time {
grid-area: timeMeta;
}
}
</style>
6 changes: 6 additions & 0 deletions src/components/icons/IconCheckmark.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<template>
<path
fill-rule="evenodd"
d="M12 2C6.486 2 2 6.486 2 12s4.486 10 10 10 10-4.486 10-10S17.514 2 12 2m2.293 7.293L11 12.586l-1.293-1.293a.999.999 0 10-1.414 1.414l2 2a.997.997 0 001.414 0l4-4a.999.999 0 10-1.414-1.414"
/>
</template>
4 changes: 2 additions & 2 deletions src/store/modules/quiz.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type Getters = {
listQuestions(state: QuizStateInterface): Quiz['questions'];
countQuestions(state: QuizStateInterface): number;
countCorrect(state: QuizStateInterface): number;
calcScore(state: QuizStateInterface): string;
calcScore(state: QuizStateInterface): number;
};

const getters: GetterTree<QuizStateInterface, StateInterface> & Getters = {
Expand Down Expand Up @@ -53,7 +53,7 @@ const getters: GetterTree<QuizStateInterface, StateInterface> & Getters = {
const totalQ = getters.countQuestions(state);
const correctQ = getters.countCorrect(state);
const score = (correctQ / totalQ) * 100;
return Math.floor(score) + '%';
return Math.floor(score);
},
};

Expand Down
26 changes: 4 additions & 22 deletions src/views/Summary.vue
Original file line number Diff line number Diff line change
@@ -1,40 +1,22 @@
<template>
<h2>Your Score</h2>
<h3 class="u-margin-top-none u-margin-bottom-lg u-margin-left">{{ getScore }}</h3>
<SummaryStats :data="quizData" />
<QuestionList :data="quizData" />
</template>

<script>
import { mapGetters } from 'vuex';
import SummaryStats from '@/components/SummaryStats.vue';
import QuestionList from '@/components/QuestionList.vue';
export default {
components: {
SummaryStats,
QuestionList,
},
data() {
return {
quizData: this.$store.state.quiz.quizData,
};
},
computed: {
...mapGetters({
listQuestions: 'quiz/listQuestions',
countQuestions: 'quiz/countQuestions',
countCorrect: 'quiz/countCorrect',
getScore: 'quiz/calcScore',
}),
},
};
</script>

<style lang="scss" scoped>
h2 {
font: {
size: $text-size-up-3;
weight: 400;
}
}
h3 {
font-size: $text-size-up-4;
}
</style>
<style lang="scss" scoped></style>