PluginProbe ʕ •ᴥ•ʔ
Presto Player / 4.3.3
Presto Player v4.3.3
4.4.0 4.3.3 4.3.2 4.3.1 4.3.0 4.2.4 4.2.3 4.2.2 4.2.0 4.2.1 trunk 1.10.0 1.10.1 1.10.2 1.11.0 1.12.0 1.13.0 1.14.0 1.14.1 1.5.10 1.5.11 1.5.12 1.5.13 1.5.14 1.5.15 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.10 1.6.11 1.6.12 1.6.13 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.11 2.0.12 2.0.13 2.0.14 2.0.15 2.0.16 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.2.0 2.2.1 2.2.2 2.2.3 2.2.3-beta1 2.3.0 2.3.1 2.3.2 2.3.3 3.0.0 3.0.0-beta1 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.1.0 3.1.1 3.1.2 3.1.3 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4
presto-player / src / admin / dashboard / lib / bsf-learn / components / BsfLearn.js
presto-player / src / admin / dashboard / lib / bsf-learn / components Last commit date
learn-how 3 months ago BsfLearn.js 3 months ago BsfLearnChapters.js 3 months ago BsfLearnSkeleton.js 3 months ago BsfLearnStep.js 3 months ago LearnHowDialog.js 3 months ago
BsfLearn.js
110 lines
1 import { useState, useEffect } from 'react';
2 import apiFetch from '@wordpress/api-fetch';
3 import useBsfLearn from '../useBsfLearn';
4 import BsfLearnChapters from './BsfLearnChapters';
5 import BsfLearnSkeleton from './BsfLearnSkeleton';
6 import LearnHowDialog from './LearnHowDialog';
7
8 const BsfLearn = ( {
9 chapters: initialChapters = [],
10 endpoints = null,
11 className = '',
12 onProgressChange,
13 } ) => {
14 const [ apiChapters, setApiChapters ] = useState( [] );
15 const [ isLoading, setIsLoading ] = useState( false );
16 const [ error, setError ] = useState( null );
17
18 // Fetch chapters from API if endpoint is provided
19 useEffect( () => {
20 if ( ! endpoints?.get ) {
21 return;
22 }
23
24 const abortController = new AbortController();
25
26 setIsLoading( true );
27 setError( null );
28
29 apiFetch( {
30 path: endpoints.get,
31 signal: abortController.signal,
32 } )
33 .then( ( response ) => {
34 setApiChapters( response );
35 setIsLoading( false );
36 } )
37 .catch( ( err ) => {
38 setError( err.message || 'Failed to load chapters' );
39 setIsLoading( false );
40 } );
41
42 return () => {
43 abortController.abort();
44 };
45 }, [ endpoints?.get ] );
46
47 // Determine which chapters to use - API data or prop data
48 const chaptersToUse = endpoints?.get ? apiChapters : initialChapters;
49
50 const {
51 chapters,
52 updateStepCompletion,
53 firstIncompleteChapterId,
54 progressStats,
55 learnHowDialogOpen,
56 currentLearnHowItem,
57 openLearnHowDialog,
58 setLearnHowDialogOpen,
59 } = useBsfLearn( {
60 initialChapters: chaptersToUse,
61 saveEndpoint: endpoints?.set,
62 } );
63
64 // Call progress change callback if provided
65 if ( onProgressChange && typeof onProgressChange === 'function' ) {
66 onProgressChange( progressStats );
67 }
68
69 if ( isLoading ) {
70 return (
71 <div className={ `flex flex-col gap-2 ${ className } !bg-transparent` }>
72 <BsfLearnSkeleton />
73 </div>
74 );
75 }
76
77 if ( error ) {
78 return (
79 <div className={ className }>
80 <div className="text-error p-4">
81 { error }
82 </div>
83 </div>
84 );
85 }
86
87 if ( ! chapters || chapters.length === 0 ) {
88 return null;
89 }
90
91 return (
92 <div className={ className }>
93 <BsfLearnChapters
94 chapters={ chapters }
95 defaultValue={ firstIncompleteChapterId }
96 onStepCompletionChange={ updateStepCompletion }
97 onLearnHowClick={ openLearnHowDialog }
98 />
99
100 <LearnHowDialog
101 open={ learnHowDialogOpen }
102 setOpen={ setLearnHowDialogOpen }
103 item={ currentLearnHowItem }
104 />
105 </div>
106 );
107 };
108
109 export default BsfLearn;
110