Skip to content
This repository was archived by the owner on Dec 8, 2022. It is now read-only.
Merged
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
2 changes: 1 addition & 1 deletion CodeChallenge/api/questions.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def json_error(reason, status=400):

@bp.before_request
def end_code_challenge():
if core.challenge_ended():
if core.challenge_ended() and request.path != "/api/v1/questions/leaderboard":
r = jsonify(status="error",
reason="code challenge has ended")
r.status_code = 403
Expand Down
111 changes: 51 additions & 60 deletions src/components/QuizBar.vue
Original file line number Diff line number Diff line change
@@ -1,77 +1,68 @@
<template>
<v-toolbar
color="dark2 quiz-bar"
flat
class="secondary--text"
:height="60"
:max-height="60"
>
<div class="quiz-bar-rank" v-show="User.isAuthorized">
<div class="level-display">Level</div>
<div class="rank">{{ User.rank }}</div>
</div>
<v-container>
<v-row>
<v-col>
<span v-if="User.isAuthorized" class="barrow-bold"
>Welcome pilgrim {{ User.displayName }}</span
>
<v-toolbar color="dark2 quiz-bar" flat class="secondary--text" :height="60" :max-height="60">
<div class="quiz-bar-rank" v-show="User.isAuthorized && Quiz.quizHasStarted && !Quiz.quizHasEnded">
<div class="level-display">Level</div>
<div class="rank">{{ User.rank }}</div>
</div>
<v-container>
<v-row>
<v-col>
<span
v-if="User.isAuthorized"
class="barrow-bold"
>Welcome pilgrim {{ User.displayName }}</span>

<router-link
v-else
color="secondary"
text
x-large
active-class="none"
:to="{ name: 'register' }"
>Start your journey</router-link
>
</v-col>
<router-link
v-else
color="secondary"
text
x-large
active-class="none"
:to="{ name: 'register' }"
>Start your journey</router-link>
</v-col>

<v-col class="text-right">
<v-menu offset-y>
<template v-slot:activator="{ on: menu }">
<a href="#" v-on="menu">Get Help</a>
</template>
<v-list class="list">
<v-list-item :to="{ name: 'faq' }">
<v-list-item-title>Check The FAQ</v-list-item-title>
</v-list-item>
<v-list-item href="https://discord.gg/fDWbCj9" target="_blank">
<v-list-item-title>Get Help On Discord</v-list-item-title>
</v-list-item>
<v-list-item href="https://www.facebook.com" target="_blank">
<v-list-item-title>Get Help On Facebook</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
<v-col class="text-right">
<v-menu offset-y>
<template v-slot:activator="{ on: menu }">
<a href="#" v-on="menu">Get Help</a>
</template>
<v-list class="list">
<!-- <v-list-item :to="{ name: 'faq' }">
<v-list-item-title>Check The FAQ</v-list-item-title>
</v-list-item> -->
<v-list-item href="https://discord.gg/fDWbCj9" target="_blank">
<v-list-item-title>Get Help On Discord</v-list-item-title>
</v-list-item>
<v-list-item href="https://www.facebook.com" target="_blank">
<v-list-item-title>Get Help On Facebook</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>

<router-link v-if="!User.isAuthorized" :to="{ name: 'login' }"
>Sign In</router-link
>
<router-link v-if="!User.isAuthorized" :to="{ name: 'login' }">Sign In</router-link>

<router-link v-if="User.isAuthorized" :to="{ name: 'logout' }"
>Sign Out</router-link
>
</v-col>
</v-row>
</v-container>
</v-toolbar>
<router-link v-if="User.isAuthorized" :to="{ name: 'logout' }">Sign Out</router-link>
</v-col>
</v-row>
</v-container>
</v-toolbar>
</template>

<script>
import { User } from "@/store";
import { User, Quiz } from "@/store";

export default {
name: "quizBar",
computed: {
...User.mapState()
}
name: "quizBar",
computed: {
...User.mapState(),
...Quiz.mapState()
}
};
</script>

<style lang="scss" scoped>
.list {
padding: 20px;
padding: 20px;
}
</style>
101 changes: 78 additions & 23 deletions src/plugins/router.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,36 @@
import Vue from "vue";
import VueRouter from "vue-router";
import { auth } from "@/api";
import { auth, quiz } from "@/api";
import store from "@/store";

Vue.use(VueRouter);

function isChallengeOpen() {
return store.state.Quiz.quizHasStarted && !store.state.Quiz.quizHasEnded;
}

function isChallengePending() {
return !store.state.Quiz.quizHasStarted && !store.state.Quiz.quizHasEnded;
}

function isChallengeClosed() {
return store.state.Quiz.quizHasEnded;
}

const routes = [
{
path: "/home",
name: "home",
redirect: {
name: "quiz"
beforeEnter(to, from, next) {
if (isChallengeOpen() || isChallengePending()) {
next({ name: 'quiz' });
return;
}

if (isChallengeClosed()) {
next({ name: 'voting' })
return;
}
}
},
{
Expand Down Expand Up @@ -63,7 +83,10 @@ const routes = [
{
path: "/voting",
name: "voting",
component: () => import("@/views/Voting/Ballot.vue")
component: () => import("@/views/Voting/Ballot.vue"),
meta: {
challengeOver: true
}
},
{
// dev only
Expand All @@ -82,13 +105,8 @@ const routes = [
component: async () => {
await store.dispatch("Quiz/refresh");

// CHALLENGE IS OVER
if (store.state.Quiz.quizHasEnded) {
return import("@/views/Quiz/QuizFinished");
}

// CHALLENGE HAS NOT STARTED
if (!store.state.Quiz.quizHasStarted) {
if (!isChallengeOpen()) {
return import("@/views/Quiz/QuizCountdown");
}

Expand All @@ -106,28 +124,30 @@ const routes = [
if (store.state.Quiz.isLastQuestion) {
return import("@/views/Quiz/QuizFinalQuestion");
}

// NORMAL QUIZ MODE
return import("@/views/Quiz/Quiz");
},
beforeEnter(from, to, next) {
// USER MUST SEE INTRO VIDEO
if (!store.state.Quiz.hasSeenIntro && store.state.User.rank == 1) {
if (isChallengeOpen() && !store.state.Quiz.hasSeenIntro && store.state.User.rank == 1) {
next({ name: "quiz-intro" });
return;
}
next();
},
meta: {
secured: true
secured: true,
challengeOpenOrPending: true
}
},
{
path: "/quiz/intro",
name: "quiz-intro",
component: () => import("@/views/Quiz/QuizIntro"),
async beforeEnter(to, from, next) {
await store.dispatch("Quiz/refresh");
next();
meta: {
secured: true,
challengeOpenOrPending: true
}
},
{
Expand All @@ -144,19 +164,54 @@ const router = new VueRouter({
routes
});

router.beforeEach((to, from, next) => {
const isAuthenticated = !!auth.currentUser().auth;
router.beforeEach(async (to, from, next) => {
const requireAuth = to.matched.some(record => record.meta.secured);
const requireAnon = to.matched.some(record => record.meta.anon);
const requireChallengePending = to.matched.some(record => record.meta.challengePending);
const requireChallengeOpen = to.matched.some(record => record.meta.challengeOpen);
const requireChallengeClosed = to.matched.some(record => record.meta.challengeOver);
const requireChallengeOpenPending = to.matched.some(record => (record.meta.challengeOpenOrPending));

if (requireChallengePending || requireChallengeOpen || requireChallengeClosed || requireChallengeOpenPending) {
await store.dispatch("Quiz/refresh");

const challengeIsClosed = isChallengeClosed();
const challengeIsPending = isChallengePending();
const challengeIsOpen = isChallengeOpen();

if (!challengeIsClosed && requireChallengeClosed) {
next({ name: 'home' });
return;
}

if (!challengeIsOpen && requireChallengeOpen) {
next({ name: 'home' });
return;
}

if (!challengeIsPending && requireChallengePending) {
next({ name: 'home' });
return;
}

if (!isAuthenticated && requireAuth) {
next({ name: "register" });
return;
if ((!challengeIsOpen && !challengeIsPending) && requireChallengeOpenPending) {
next({ name: 'home' });
return;
}
}

if (isAuthenticated && requireAnon) {
next({ name: "home" });
return;
if (requireAuth || requireAnon) {
const isAuthenticated = !!auth.currentUser().auth;

if (!isAuthenticated && requireAuth) {
next({ name: "register" });
return;
}

if (isAuthenticated && requireAnon) {
next({ name: "home" });
return;
}
}

next();
Expand Down
2 changes: 1 addition & 1 deletion src/views/Quiz/QuizFinalQuestion.vue
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ output = calculateAnswer()`;
async makeRequest(checkOnly) {
const response = await api.quiz.submitFinal(
this.fields.code.value,
this.fields.language.value === "javascript" ? "js" : "py",
this.fields.language.value === "javascript" ? "js" : "python",
checkOnly
);
const isCorrect = response.correct;
Expand Down