diff --git a/apps/worker-app/app/components/AwardCapability.vue b/apps/worker-app/app/components/AwardCapability.vue index 6f2f01e9..959eaf6b 100644 --- a/apps/worker-app/app/components/AwardCapability.vue +++ b/apps/worker-app/app/components/AwardCapability.vue @@ -71,6 +71,7 @@ const props = defineProps({ icon: { type: String, default: "🛡" }, successText: { type: String, default: "Capability granted!" }, autoPlay: { type: Boolean, default: false }, // run animation on mount + autoNavigate: { type: Boolean, default: true }, // auto-navigate to dashboard on continue }); const emit = defineEmits(["claimed", "continue"]); @@ -129,7 +130,11 @@ function loop() { const router = useRouter(); const continueHandler = () => { - router.push("/"); + emit("continue"); + // Only route to dashboard if autoNavigate is enabled + if (props.autoNavigate) { + router.push("/"); + } }; const { awardCapability } = useCapabilities(); diff --git a/apps/worker-app/app/components/CapabilitiesListItem.vue b/apps/worker-app/app/components/CapabilitiesListItem.vue index e18ac818..41efd55a 100644 --- a/apps/worker-app/app/components/CapabilitiesListItem.vue +++ b/apps/worker-app/app/components/CapabilitiesListItem.vue @@ -15,6 +15,20 @@

{{ category }}

+
+ + {{ remainingAttempts }}/{{ maxAttempts }} + + + No attempts + +

{{ description || "No description available." }} @@ -31,11 +45,18 @@ >{{ tag }} - + + + + +

+
+
+
+
+
+ {{ index + 1 }} / {{ questions.length }} + + ⏱ {{ formatTime(timeLeft) }} + +
+
+ +
+
+ +
+ +
+
+ + +
+ +
+

Your result

+

+ Score: {{ score }} / {{ questions.length }} +

+

+ Status: {{ passed ? 'Passed' : 'Not Passed' }} +

+

{{ resultDescription }}

+ + +
+ + + + + + diff --git a/apps/worker-app/app/pages/capabilities/common-voice-validator.vue b/apps/worker-app/app/pages/capabilities/common-voice-validator.vue new file mode 100644 index 00000000..e4f289ce --- /dev/null +++ b/apps/worker-app/app/pages/capabilities/common-voice-validator.vue @@ -0,0 +1,704 @@ + + + + + diff --git a/apps/worker-app/app/pages/capabilities/halloween.vue b/apps/worker-app/app/pages/capabilities/halloween.vue index 3674665e..66260fae 100644 --- a/apps/worker-app/app/pages/capabilities/halloween.vue +++ b/apps/worker-app/app/pages/capabilities/halloween.vue @@ -76,10 +76,8 @@ -
- Claim Capability +
@@ -209,6 +207,8 @@ function next() { index.value++; } else { phase.value = "result"; + // Award capability immediately when reaching result + awardCapability(capability?.id); } } @@ -217,7 +217,7 @@ function prev() { if (index.value > 0) index.value--; } -const { availableCapabilities } = useCapabilities(); +const { availableCapabilities, awardCapability } = useCapabilities(); const capability = availableCapabilities.find((c) => c.id.startsWith("effectai/halloween-spirit") ); @@ -301,6 +301,24 @@ const capability = availableCapabilities.find((c) => gap: 10px; margin-top: 14px; } +.nav.center-align { + justify-content: center; +} +.next-btn { + background: linear-gradient(180deg, #ffffff, #fff7ed); + border: 1px solid #fed7aa; + color: #1f2937; + padding: 12px 24px; + font-weight: 600; + box-shadow: 0 8px 16px -10px rgba(249, 115, 22, 0.45); + transition: transform 0.15s ease; +} +.next-btn:hover { + transform: translateY(-1px); +} +.next-btn:active { + transform: translateY(0); +} .btn { border: 1px solid #e5e7eb; padding: 10px 14px; diff --git a/apps/worker-app/app/pages/capabilities/language-english.vue b/apps/worker-app/app/pages/capabilities/language-english.vue index 7ddd5e67..d49766cd 100644 --- a/apps/worker-app/app/pages/capabilities/language-english.vue +++ b/apps/worker-app/app/pages/capabilities/language-english.vue @@ -2,15 +2,27 @@
-

English Proficiency Quick Test

+

English Proficiency Quick Test (5-10min)

-

This short test (≈5–7 minutes) estimates your CEFR level (A1–C1).

+

This short test estimates your CEFR level (A1-C1).

+
+

The test consists of 25 questions:

    -
  • Multiple choice + a few short “type the word” questions.
  • -
  • No penalties for guessing. One point per correct answer.
  • +
  • - 12 Multiple Choice
  • +
  • - 8 Fill-in-the-Blank
  • +
  • - 5 Reading Comprehension
- +

Please note the following rules:

+
    +
  • Timed Questions: Each question has a countdown timer. If time runs out, your current answer will be automatically submitted.
  • +
  • Forward Only: Once you submit a question, you cannot return to it.
  • +
  • No Copy & Paste: Copying, pasting, or cutting text is disabled.
  • +
+
+
+ +
@@ -21,7 +33,12 @@ :style="{ width: ((index + 1) / questions.length) * 100 + '%' }" >
-
{{ index + 1 }} / {{ questions.length }}
+
+ {{ index + 1 }} / {{ questions.length }} + + ⏱ {{ formatTime(timeLeft) }} + +
@@ -45,6 +62,10 @@ class="input" :placeholder="current.placeholder || 'Type your answer'" @keydown.enter.prevent="next" + @paste.prevent + @copy.prevent + @cut.prevent + autocomplete="off" />

Hint: {{ current.hint }}

@@ -67,9 +88,8 @@ - @@ -85,7 +105,7 @@

{{ level.description }}

-
+ - + + diff --git a/apps/worker-app/app/pages/index.vue b/apps/worker-app/app/pages/index.vue index c11db40b..fd45c2ae 100644 --- a/apps/worker-app/app/pages/index.vue +++ b/apps/worker-app/app/pages/index.vue @@ -43,6 +43,7 @@