@schoolio/player 1.4.6 → 1.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -84,6 +84,8 @@ interface QuizPlayerProps {
84
84
  styles?: QuizPlayerStyles;
85
85
  forceNewAttempt?: boolean;
86
86
  hideScore?: boolean;
87
+ completionVideoUrl?: string;
88
+ perfectScoreVideoUrl?: string;
87
89
  }
88
90
  interface QuizResult {
89
91
  attemptId: string;
@@ -169,7 +171,7 @@ interface QuestionContextForChat {
169
171
  explanation?: string;
170
172
  }
171
173
 
172
- declare function QuizPlayer({ quizId, lessonId, assignLessonId, courseId, childId, parentId, apiBaseUrl, authToken, onComplete, onError, onProgress, onGenerateMoreQuestions, className, forceNewAttempt, hideScore, }: QuizPlayerProps): react_jsx_runtime.JSX.Element;
174
+ declare function QuizPlayer({ quizId, lessonId, assignLessonId, courseId, childId, parentId, apiBaseUrl, authToken, onComplete, onError, onProgress, onGenerateMoreQuestions, className, forceNewAttempt, hideScore, completionVideoUrl, perfectScoreVideoUrl, }: QuizPlayerProps): react_jsx_runtime.JSX.Element;
173
175
 
174
176
  declare function AttemptViewer({ attemptId, apiBaseUrl, authToken, onError, className, showExplanations, showConversation, title, }: AttemptViewerProps): react_jsx_runtime.JSX.Element;
175
177
 
package/dist/index.d.ts CHANGED
@@ -84,6 +84,8 @@ interface QuizPlayerProps {
84
84
  styles?: QuizPlayerStyles;
85
85
  forceNewAttempt?: boolean;
86
86
  hideScore?: boolean;
87
+ completionVideoUrl?: string;
88
+ perfectScoreVideoUrl?: string;
87
89
  }
88
90
  interface QuizResult {
89
91
  attemptId: string;
@@ -169,7 +171,7 @@ interface QuestionContextForChat {
169
171
  explanation?: string;
170
172
  }
171
173
 
172
- declare function QuizPlayer({ quizId, lessonId, assignLessonId, courseId, childId, parentId, apiBaseUrl, authToken, onComplete, onError, onProgress, onGenerateMoreQuestions, className, forceNewAttempt, hideScore, }: QuizPlayerProps): react_jsx_runtime.JSX.Element;
174
+ declare function QuizPlayer({ quizId, lessonId, assignLessonId, courseId, childId, parentId, apiBaseUrl, authToken, onComplete, onError, onProgress, onGenerateMoreQuestions, className, forceNewAttempt, hideScore, completionVideoUrl, perfectScoreVideoUrl, }: QuizPlayerProps): react_jsx_runtime.JSX.Element;
173
175
 
174
176
  declare function AttemptViewer({ attemptId, apiBaseUrl, authToken, onError, className, showExplanations, showConversation, title, }: AttemptViewerProps): react_jsx_runtime.JSX.Element;
175
177
 
package/dist/index.js CHANGED
@@ -1903,7 +1903,9 @@ function QuizPlayer({
1903
1903
  onGenerateMoreQuestions,
1904
1904
  className,
1905
1905
  forceNewAttempt = true,
1906
- hideScore = false
1906
+ hideScore = false,
1907
+ completionVideoUrl,
1908
+ perfectScoreVideoUrl
1907
1909
  }) {
1908
1910
  const [quiz, setQuiz] = (0, import_react3.useState)(null);
1909
1911
  const [attempt, setAttempt] = (0, import_react3.useState)(null);
@@ -2490,8 +2492,41 @@ function QuizPlayer({
2490
2492
  }
2491
2493
  }
2492
2494
  ` }),
2493
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: defaultStyles.results, children: [
2494
- percentage >= 60 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: defaultStyles.confettiContainer, children: confettiPieces.map((piece) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2495
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: {
2496
+ ...defaultStyles.results,
2497
+ position: "relative",
2498
+ overflow: "hidden"
2499
+ }, children: [
2500
+ (() => {
2501
+ const videoUrl = percentage === 100 && perfectScoreVideoUrl ? perfectScoreVideoUrl : completionVideoUrl;
2502
+ if (videoUrl) {
2503
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2504
+ "video",
2505
+ {
2506
+ autoPlay: true,
2507
+ playsInline: true,
2508
+ preload: "auto",
2509
+ onEnded: (e) => {
2510
+ e.currentTarget.currentTime = 0;
2511
+ e.currentTarget.pause();
2512
+ },
2513
+ style: {
2514
+ position: "absolute",
2515
+ top: 0,
2516
+ left: 0,
2517
+ width: "100%",
2518
+ height: "100%",
2519
+ objectFit: "cover",
2520
+ zIndex: 0
2521
+ },
2522
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("source", { src: videoUrl, type: "video/webm" })
2523
+ },
2524
+ videoUrl
2525
+ );
2526
+ }
2527
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { ...defaultStyles.resultsBackground, background: theme.bgGradient } });
2528
+ })(),
2529
+ percentage >= 60 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { ...defaultStyles.confettiContainer, zIndex: 1 }, children: confettiPieces.map((piece) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2495
2530
  "div",
2496
2531
  {
2497
2532
  style: {
@@ -2508,173 +2543,279 @@ function QuizPlayer({
2508
2543
  },
2509
2544
  piece.id
2510
2545
  )) }),
2511
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { ...defaultStyles.resultsBackground, background: theme.bgGradient } }),
2512
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: defaultStyles.resultsContent, children: hideScore ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
2513
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { marginBottom: "24px" }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Mascot, { mood: "happy" }) }),
2514
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2515
- "div",
2516
- {
2517
- style: {
2518
- background: "linear-gradient(135deg, #dcfce7 0%, #bbf7d0 100%)",
2519
- padding: "12px 28px",
2520
- borderRadius: "50px",
2521
- boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
2522
- marginBottom: "20px",
2523
- animation: "badgePop 0.6s ease-out 0.2s forwards",
2524
- opacity: 0,
2525
- border: "3px solid #22c55e"
2526
- },
2527
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2528
- "span",
2529
- {
2530
- style: {
2531
- fontSize: "22px",
2532
- fontWeight: "700",
2533
- color: "#1f2937",
2534
- textShadow: "0 1px 2px rgba(255,255,255,0.5)"
2535
- },
2536
- children: "All Done!"
2537
- }
2538
- )
2539
- }
2540
- ),
2541
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2542
- "div",
2543
- {
2544
- style: {
2545
- animation: "scoreSlideIn 0.5s ease-out 0.4s forwards",
2546
- opacity: 0
2547
- },
2548
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2549
- "div",
2550
- {
2551
- style: {
2552
- fontSize: "24px",
2553
- fontWeight: "600",
2554
- color: "#22c55e",
2555
- lineHeight: "1.4",
2556
- marginBottom: "12px"
2557
- },
2558
- children: "The quiz was submitted successfully!"
2559
- }
2560
- )
2561
- }
2562
- ),
2563
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { ...defaultStyles.resultDetails, marginTop: "8px" }, children: [
2564
- "Time: ",
2565
- formatTime(result.timeSpentSeconds)
2566
- ] })
2567
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
2568
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: defaultStyles.resultStars, children: [
2569
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(StarIcon, { filled: theme.stars >= 1, delay: 0.3 }),
2570
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(StarIcon, { filled: theme.stars >= 2, delay: 0.5 }),
2571
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(StarIcon, { filled: theme.stars >= 3, delay: 0.7 })
2572
- ] }),
2573
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { marginBottom: "16px" }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Mascot, { mood: theme.mascotMood }) }),
2574
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2575
- "div",
2576
- {
2577
- style: {
2578
- background: theme.badgeBg,
2579
- padding: "12px 28px",
2580
- borderRadius: "50px",
2581
- boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
2582
- marginBottom: "20px",
2583
- animation: "badgePop 0.6s ease-out 0.2s forwards",
2584
- opacity: 0,
2585
- border: `3px solid ${theme.badgeColor}`
2586
- },
2587
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2588
- "span",
2589
- {
2590
- style: {
2591
- fontSize: "22px",
2592
- fontWeight: "700",
2593
- color: "#1f2937",
2594
- textShadow: "0 1px 2px rgba(255,255,255,0.5)"
2595
- },
2596
- children: theme.badge
2597
- }
2598
- )
2599
- }
2600
- ),
2601
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2602
- "div",
2603
- {
2604
- style: {
2605
- animation: "scoreSlideIn 0.5s ease-out 0.4s forwards",
2606
- opacity: 0
2607
- },
2608
- children: [
2609
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2610
- "div",
2611
- {
2612
- style: {
2613
- fontSize: "48px",
2614
- fontWeight: "800",
2615
- color: theme.color,
2616
- lineHeight: "1",
2617
- marginBottom: "4px"
2618
- },
2619
- children: [
2620
- result.correctAnswers,
2621
- " of ",
2622
- result.totalQuestions
2623
- ]
2624
- }
2625
- ),
2626
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2627
- "div",
2628
- {
2629
- style: {
2630
- fontSize: "20px",
2631
- fontWeight: "600",
2632
- color: "#6b7280",
2633
- marginBottom: "12px"
2634
- },
2635
- children: "correct answers"
2636
- }
2637
- )
2638
- ]
2639
- }
2640
- ),
2641
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { ...defaultStyles.resultDetails, marginTop: "8px" }, children: [
2642
- "Time: ",
2643
- formatTime(result.timeSpentSeconds)
2644
- ] }),
2645
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2646
- "button",
2647
- {
2648
- style: {
2649
- marginTop: "24px",
2650
- padding: "14px 32px",
2651
- fontSize: "16px",
2652
- fontWeight: "600",
2653
- color: "#7c3aed",
2654
- background: "white",
2655
- border: "2px solid #7c3aed",
2656
- borderRadius: "12px",
2657
- cursor: "pointer",
2658
- transition: "all 0.2s ease",
2659
- animation: "buttonFadeIn 0.5s ease-out 0.8s forwards",
2660
- opacity: 0
2661
- },
2662
- onClick: handleRetryQuiz,
2663
- onMouseOver: (e) => {
2664
- e.currentTarget.style.background = "#7c3aed";
2665
- e.currentTarget.style.color = "white";
2666
- e.currentTarget.style.transform = "translateY(-2px)";
2667
- },
2668
- onMouseOut: (e) => {
2669
- e.currentTarget.style.background = "white";
2670
- e.currentTarget.style.color = "#7c3aed";
2671
- e.currentTarget.style.transform = "translateY(0)";
2672
- },
2673
- "data-testid": "button-retry-quiz",
2674
- children: "Try Again"
2675
- }
2676
- )
2677
- ] }) })
2546
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2547
+ "div",
2548
+ {
2549
+ style: {
2550
+ position: "absolute",
2551
+ top: "16px",
2552
+ left: "50%",
2553
+ transform: "translateX(-50%)",
2554
+ zIndex: 2,
2555
+ display: "flex",
2556
+ justifyContent: "center"
2557
+ },
2558
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2559
+ "div",
2560
+ {
2561
+ style: {
2562
+ background: "rgba(255, 255, 255, 0.5)",
2563
+ backdropFilter: "blur(8px)",
2564
+ borderRadius: "16px",
2565
+ padding: "12px 20px",
2566
+ display: "flex",
2567
+ flexDirection: "row",
2568
+ alignItems: "center",
2569
+ justifyContent: "center",
2570
+ gap: "16px",
2571
+ boxShadow: "0 8px 32px rgba(0, 0, 0, 0.2)",
2572
+ animation: "scoreSlideIn 0.5s ease-out forwards",
2573
+ whiteSpace: "nowrap"
2574
+ },
2575
+ children: hideScore ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
2576
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2577
+ "div",
2578
+ {
2579
+ style: {
2580
+ display: "flex",
2581
+ flexDirection: "column",
2582
+ alignItems: "center",
2583
+ gap: "8px"
2584
+ },
2585
+ children: [
2586
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2587
+ "div",
2588
+ {
2589
+ style: {
2590
+ fontSize: "24px",
2591
+ fontWeight: "700",
2592
+ color: "#22c55e"
2593
+ },
2594
+ children: "All Done!"
2595
+ }
2596
+ ),
2597
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2598
+ "div",
2599
+ {
2600
+ style: {
2601
+ fontSize: "16px",
2602
+ color: "#6b7280"
2603
+ },
2604
+ children: "Quiz submitted successfully"
2605
+ }
2606
+ )
2607
+ ]
2608
+ }
2609
+ ),
2610
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2611
+ "div",
2612
+ {
2613
+ style: {
2614
+ width: "1px",
2615
+ height: "48px",
2616
+ background: "rgba(0, 0, 0, 0.1)"
2617
+ }
2618
+ }
2619
+ ),
2620
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2621
+ "div",
2622
+ {
2623
+ style: {
2624
+ display: "flex",
2625
+ flexDirection: "column",
2626
+ alignItems: "center"
2627
+ },
2628
+ children: [
2629
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2630
+ "div",
2631
+ {
2632
+ style: {
2633
+ fontSize: "14px",
2634
+ fontWeight: "500",
2635
+ color: "#6b7280",
2636
+ marginBottom: "4px"
2637
+ },
2638
+ children: "Time"
2639
+ }
2640
+ ),
2641
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2642
+ "div",
2643
+ {
2644
+ style: {
2645
+ fontSize: "24px",
2646
+ fontWeight: "700",
2647
+ color: "#1f2937"
2648
+ },
2649
+ children: formatTime(result.timeSpentSeconds)
2650
+ }
2651
+ )
2652
+ ]
2653
+ }
2654
+ )
2655
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
2656
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2657
+ "div",
2658
+ {
2659
+ style: {
2660
+ background: theme.badgeBg,
2661
+ padding: "8px 16px",
2662
+ borderRadius: "20px",
2663
+ animation: "badgePop 0.5s ease-out 0.3s forwards",
2664
+ opacity: 0,
2665
+ transform: "scale(0.8)"
2666
+ },
2667
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2668
+ "span",
2669
+ {
2670
+ style: {
2671
+ fontSize: "14px",
2672
+ fontWeight: "700",
2673
+ color: theme.badgeColor
2674
+ },
2675
+ children: theme.badge
2676
+ }
2677
+ )
2678
+ }
2679
+ ),
2680
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2681
+ "div",
2682
+ {
2683
+ style: {
2684
+ width: "1px",
2685
+ height: "40px",
2686
+ background: "rgba(0, 0, 0, 0.1)"
2687
+ }
2688
+ }
2689
+ ),
2690
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2691
+ "div",
2692
+ {
2693
+ style: {
2694
+ display: "flex",
2695
+ flexDirection: "column",
2696
+ alignItems: "center"
2697
+ },
2698
+ children: [
2699
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2700
+ "div",
2701
+ {
2702
+ style: {
2703
+ fontSize: "12px",
2704
+ fontWeight: "500",
2705
+ color: "#6b7280",
2706
+ marginBottom: "2px"
2707
+ },
2708
+ children: "Correct Answers"
2709
+ }
2710
+ ),
2711
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2712
+ "div",
2713
+ {
2714
+ style: {
2715
+ fontSize: "24px",
2716
+ fontWeight: "800",
2717
+ color: theme.color
2718
+ },
2719
+ children: [
2720
+ result.correctAnswers,
2721
+ " / ",
2722
+ result.totalQuestions
2723
+ ]
2724
+ }
2725
+ )
2726
+ ]
2727
+ }
2728
+ ),
2729
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2730
+ "div",
2731
+ {
2732
+ style: {
2733
+ width: "1px",
2734
+ height: "40px",
2735
+ background: "rgba(0, 0, 0, 0.1)"
2736
+ }
2737
+ }
2738
+ ),
2739
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2740
+ "div",
2741
+ {
2742
+ style: {
2743
+ display: "flex",
2744
+ flexDirection: "column",
2745
+ alignItems: "center"
2746
+ },
2747
+ children: [
2748
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2749
+ "div",
2750
+ {
2751
+ style: {
2752
+ fontSize: "12px",
2753
+ fontWeight: "500",
2754
+ color: "#6b7280",
2755
+ marginBottom: "2px"
2756
+ },
2757
+ children: "Time"
2758
+ }
2759
+ ),
2760
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2761
+ "div",
2762
+ {
2763
+ style: {
2764
+ fontSize: "20px",
2765
+ fontWeight: "700",
2766
+ color: "#1f2937"
2767
+ },
2768
+ children: formatTime(result.timeSpentSeconds)
2769
+ }
2770
+ )
2771
+ ]
2772
+ }
2773
+ ),
2774
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2775
+ "div",
2776
+ {
2777
+ style: {
2778
+ width: "1px",
2779
+ height: "40px",
2780
+ background: "rgba(0, 0, 0, 0.1)"
2781
+ }
2782
+ }
2783
+ ),
2784
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2785
+ "button",
2786
+ {
2787
+ style: {
2788
+ padding: "10px 20px",
2789
+ fontSize: "14px",
2790
+ fontWeight: "600",
2791
+ color: "white",
2792
+ background: "#7c3aed",
2793
+ border: "none",
2794
+ borderRadius: "12px",
2795
+ cursor: "pointer",
2796
+ transition: "all 0.2s ease",
2797
+ boxShadow: "0 4px 12px rgba(124, 58, 237, 0.3)"
2798
+ },
2799
+ onClick: handleRetryQuiz,
2800
+ onMouseOver: (e) => {
2801
+ e.currentTarget.style.background = "#6d28d9";
2802
+ e.currentTarget.style.transform = "translateY(-2px)";
2803
+ e.currentTarget.style.boxShadow = "0 6px 16px rgba(124, 58, 237, 0.4)";
2804
+ },
2805
+ onMouseOut: (e) => {
2806
+ e.currentTarget.style.background = "#7c3aed";
2807
+ e.currentTarget.style.transform = "translateY(0)";
2808
+ e.currentTarget.style.boxShadow = "0 4px 12px rgba(124, 58, 237, 0.3)";
2809
+ },
2810
+ "data-testid": "button-retry-quiz",
2811
+ children: "Try Again"
2812
+ }
2813
+ )
2814
+ ] })
2815
+ }
2816
+ )
2817
+ }
2818
+ )
2678
2819
  ] })
2679
2820
  ] });
2680
2821
  }
@@ -2802,6 +2943,17 @@ function QuizPlayer({
2802
2943
  ] }),
2803
2944
  /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { ...defaultStyles.question, position: "relative", paddingBottom: "40px" }, children: [
2804
2945
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: defaultStyles.questionText, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(TextToSpeech, { text: currentQuestion.question, inline: true, size: "md" }) }),
2946
+ currentQuestion.type === "multiple" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: {
2947
+ marginTop: "8px",
2948
+ marginBottom: "12px",
2949
+ display: "inline-block",
2950
+ padding: "4px 10px",
2951
+ backgroundColor: "rgba(139, 92, 246, 0.1)",
2952
+ color: "#7c3aed",
2953
+ fontSize: "13px",
2954
+ fontStyle: "italic",
2955
+ borderRadius: "4px"
2956
+ }, children: "Select all that apply" }),
2805
2957
  isExtraQuestion && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2806
2958
  "button",
2807
2959
  {