Skip to content

Commit

Permalink
Added transition for question loading and random question button
Browse files Browse the repository at this point in the history
  • Loading branch information
rimutaka committed Oct 21, 2024
1 parent 4015309 commit fe5ce43
Show file tree
Hide file tree
Showing 10 changed files with 1,469 additions and 1,434 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions vue/dist/assets/index-CKIdwo6T.css

Large diffs are not rendered by default.

1,387 changes: 0 additions & 1,387 deletions vue/dist/assets/index-DPyESFVw.js

This file was deleted.

1,387 changes: 1,387 additions & 0 deletions vue/dist/assets/index-DUEI7U6p.js

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion vue/dist/assets/index-EsK9IhNe.css

This file was deleted.

4 changes: 2 additions & 2 deletions vue/dist/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bite-sized learning</title>
<script type="module" crossorigin src="/assets/index-DPyESFVw.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-EsK9IhNe.css">
<script type="module" crossorigin src="/assets/index-DUEI7U6p.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-CKIdwo6T.css">
</head>
<body>
<div id="app"></div>
Expand Down
63 changes: 35 additions & 28 deletions vue/src/components/QuestionCard.vue
Original file line number Diff line number Diff line change
@@ -1,42 +1,47 @@
<template>
<div class="flex" v-if="questionMarkdown">
<div class="q-card">
<TransitionSlot>
<div class="flex" v-if="questionMarkdown">
<div class="q-card">

<div class="q-text" v-html="questionMarkdown?.question"></div>
<div class="q-text" v-html="questionMarkdown?.question"></div>

<div v-for="(answer, index) in questionMarkdown?.answers" :key="index">
<h3 v-if="isAnswered && index === 0 && questionMarkdown?.correct == 1" class="mb-4">Your answer</h3>
<h3 v-if="isAnswered && index === 0 && questionMarkdown?.correct > 1" class="mb-4">Your answers</h3>
<h3 v-else-if="!isAnswered && index === 0" class="mb-4">Answers</h3>
<h3 v-else-if="isAnswered && index === questionMarkdown?.correct" class="mb-4">Other options</h3>
<div v-for="(answer, index) in questionMarkdown?.answers" :key="index">
<h3 v-if="isAnswered && index === 0 && questionMarkdown?.correct == 1" class="mb-4">Your answer</h3>
<h3 v-if="isAnswered && index === 0 && questionMarkdown?.correct > 1" class="mb-4">Your answers</h3>
<h3 v-else-if="!isAnswered && index === 0" class="mb-4">Answers</h3>
<h3 v-else-if="isAnswered && index === questionMarkdown?.correct" class="mb-4">Other options</h3>

<div class="mb-8 border-2" :class="{ 'border-green-100': answer?.c, 'border-red-100': !answer?.c && isAnswered, 'border-slate-100': !isAnswered }">
<div class="flex items-center" :class="{ 'bg-green-100': answer?.c, 'bg-red-100': !answer?.c && isAnswered, 'bg-slate-100': !isAnswered }">
<div class="mb-8 border-2" :class="{ 'border-green-100': answer?.c, 'border-red-100': !answer?.c && isAnswered, 'border-slate-100': !isAnswered }">
<div class="flex items-center" :class="{ 'bg-green-100': answer?.c, 'bg-red-100': !answer?.c && isAnswered, 'bg-slate-100': !isAnswered }">

<input type="radio" v-if="questionMarkdown?.correct == 1" :name="questionMarkdown?.qid" :value="index" :disabled="isAnswered" v-model="learnerAnswerRadio" />
<input type="checkbox" v-if="questionMarkdown?.correct && questionMarkdown.correct > 1" :name="questionMarkdown?.qid" :disabled="isAnswered" :value="index" v-model="learnerAnswersCheck" />
<div class="q-answer" v-html="answer.a"></div>
<input type="radio" v-if="questionMarkdown?.correct == 1" :name="questionMarkdown?.qid" :value="index" :disabled="isAnswered" v-model="learnerAnswerRadio" />
<input type="checkbox" v-if="questionMarkdown?.correct && questionMarkdown.correct > 1" :name="questionMarkdown?.qid" :disabled="isAnswered" :value="index" v-model="learnerAnswersCheck" />
<div class="q-answer" v-html="answer.a"></div>

</div>
</div>

<div v-if="answer?.c" class="px-2">Correct.</div>
<div v-else-if="isAnswered" class="px-2">Incorrect.</div>
<div class="q-explain" v-if="answer?.e" v-html="answer.e"></div>
<div v-if="answer?.c" class="px-2">Correct.</div>
<div v-else-if="isAnswered" class="px-2">Incorrect.</div>
<div class="q-explain" v-if="answer?.e" v-html="answer.e"></div>
</div>
</div>
</div>

<div class="flex">
<div v-if="hasToken" class="flex-shrink">
<Button label="Edit" icon="pi pi-pencil" severity="secondary" rounded class="ms-4 whitespace-nowrap" @click="navigateToEditPage" />
</div>
<div v-if="!isAnswered" class="flex-grow text-end my-auto me-4">
<p class="">{{ optionsToSelect }}</p>
</div>
<div v-if="!isAnswered" class="flex-shrink text-end mx-4">
<Button label="Submit" icon="pi pi-check" raised rounded class="font-bold px-24 py-4 my-auto whitespace-nowrap" :disabled="!isQuestionReady" @click="submitQuestion()" />
<div class="flex">
<div v-if="hasToken" class="flex-shrink">
<Button label="Edit" icon="pi pi-pencil" severity="secondary" rounded class="ms-4 whitespace-nowrap" @click="navigateToEditPage" />
</div>
<div v-if="!isAnswered" class="flex-grow text-end my-auto me-4">
<p class="">{{ optionsToSelect }}</p>
</div>
<div v-if="!isAnswered" class="flex-shrink text-end mx-4">
<Button label="Submit" icon="pi pi-check" raised rounded class="font-bold px-24 py-4 my-auto whitespace-nowrap" :disabled="!isQuestionReady" @click="submitQuestion()" />
</div>
</div>
</div>
</div>
</TransitionSlot>
<div v-if="!questionMarkdown">
<p>Loading...</p>
</div>
</template>

Expand All @@ -47,12 +52,12 @@ import { QUESTION_HANDLER_URL, URL_PARAM_QID, URL_PARAM_TOPIC, TOKEN_HEADER_NAME
import { Sha256 } from '@aws-crypto/sha256-js';
import { toHex } from "uint8array-tools";
import Button from 'primevue/button';
import TransitionSlot from "./TransitionSlot.vue";
import router from "@/router";
const props = defineProps<{
topic: string,
qid?: string,
withAnswers?: boolean
}>()
// as fetched from the server
Expand Down Expand Up @@ -177,6 +182,8 @@ watchEffect(async () => {
// only fetch if topic is set
if (!props.topic) return;
questionMarkdown.value = undefined;
try {
// fetching by topic returns a random question
Expand Down
6 changes: 4 additions & 2 deletions vue/src/components/SampleQuestion.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<template>
<h3 class="mt-8 mb-4 text-start">Random question about <em class="italic">{{ findTopicById(props.topic) }}</em></h3>
<QuestionCard :topic="props.topic" />
<div class=" border-t-2 border-slate-300">
<h3 class="mt-8 mb-4 text-start">Random question about <em class="italic">{{ findTopicById(props.topic) }}</em></h3>
<QuestionCard :topic="props.topic" />
</div>
</template>


Expand Down
43 changes: 30 additions & 13 deletions vue/src/components/SignupForm.vue
Original file line number Diff line number Diff line change
@@ -1,37 +1,54 @@
<template>
<div class="card mt-12">
<h3>Topics</h3>
<h3>Select your topics of interest</h3>
<div class="flex flex-wrap items-center gap-4 justify-center my-4">
<div class="flex" v-for="topic in topics" :key="topic.id">
<Checkbox v-model="selectedTopics" name="topics" :value="topic.id" />
<div class="flex" v-for="topic in TOPICS" :key="topic.id">
<Checkbox v-model="selectedTopics" name="topics" :value="topic.id" :input-id="topic.id" />
<label :for="topic.id" class="ms-2 me-4">{{ topic.t }}</label>
</div>
</div>
<div class="flex flex-wrap items-center gap-4 justify-center my-8">
<InputText type="text" v-model="email" placeholder="Your email" />
<Button label="Subscribe" icon="pi pi-discord" raised rounded class="font-bold px-8 py-4 whitespace-nowrap" />

<div class="flex flex-wrap items-center gap-4 justify-center my-12">
<div class=" flex-grow text-start mb-auto">
<Button label="Try a random question" icon="pi pi-sparkles" severity="secondary" rounded class="whitespace-nowrap" @click="showRandomQuestion" />
</div>
<div class="flex-shrink">
<InputText type="email" v-model="email" placeholder="Your email" name="email" />
<Button label="Subscribe" icon="pi pi-envelope" raised rounded class="font-bold px-8 py-4 ms-4 whitespace-nowrap" :disabled="!canSubscribe" />
<p v-if="email && !selectedTopics.length" class="mt-2 text-sm text-start text-slate-500">Select at least one topic</p>
</div>

</div>
<SampleQuestion v-if="currentTopic" :topic="currentTopic" />
<TransitionSlot>
<SampleQuestion v-if="currentTopic" :topic="currentTopic" />
</TransitionSlot>
</div>
</template>


<script setup lang="ts">
import { ref, watch } from "vue";
import { ref, watch, computed } from "vue";
import Button from 'primevue/button';
import Checkbox from 'primevue/checkbox';
import InputText from 'primevue/inputtext';
import SampleQuestion from "./SampleQuestion.vue";
import { TOPICS } from "@/constants";
import TransitionSlot from "./TransitionSlot.vue";
const topics = ref(TOPICS);
const selectedTopics = ref<Array<string>>([]);
const email = ref("");
const currentTopic = ref<string>("");
watch(selectedTopics, (newVal, oldVal) => {
if (newVal.length > 0) currentTopic.value = newVal[newVal.length - 1];
console.log("currentTopic", currentTopic.value);
});
const canSubscribe = computed(() => selectedTopics.value.length > 0 && email.value.length > 0);
/// Show a random question from the selected topics or all topics
function showRandomQuestion() {
if (selectedTopics.value.length) {
currentTopic.value = selectedTopics.value[Math.floor(Math.random() * selectedTopics.value.length)];
} else {
currentTopic.value = TOPICS[Math.floor(Math.random() * TOPICS.length)].id;
}
}
</script>
9 changes: 9 additions & 0 deletions vue/src/components/TransitionSlot.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<template>
<Transition name="fade" enter-active-class="duration-1000 ease-out" enter-from-class="transform opacity-0" enter-to-class="opacity-100" leave-active-class="duration-1000 ease-in" leave-from-class="opacity-100" leave-to-class="transform opacity-0">
<slot></slot>
</Transition>
</template>

<script setup lang="ts">
import { Transition } from "vue";
</script>

0 comments on commit fe5ce43

Please sign in to comment.