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 / BsfLearnChapters.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
BsfLearnChapters.js
150 lines
1 import { __, sprintf } from '@wordpress/i18n';
2 import { Accordion, Badge, Text } from '@bsf/force-ui';
3 import { Check, ChevronRight, ExternalLink } from 'lucide-react';
4 import BsfLearnStep from './BsfLearnStep';
5
6 const BsfLearnChapters = ( { chapters, defaultValue, onStepCompletionChange, onLearnHowClick } ) => {
7
8 const handleLearnHowClick = ( event, url ) => {
9 event.stopPropagation();
10 if ( url ) {
11 window.open( url, '_blank', 'noopener,noreferrer' );
12 return;
13 }
14 };
15
16 return (
17 <Accordion
18 type="boxed"
19 autoClose={ true }
20 defaultValue={ defaultValue }
21 >
22 { chapters.map( ( chapter ) => {
23 const {
24 id,
25 title,
26 description,
27 url,
28 steps,
29 } = chapter;
30
31 const totalStepsCount = steps.length;
32 const completedStepsCount = steps.filter( ( step ) => step.completed ).length;
33 const isCompleted = totalStepsCount === completedStepsCount;
34
35 const getBadgeColor = () => {
36 if ( isCompleted ) {
37 return 'green';
38 }
39 if ( completedStepsCount > 0 ) {
40 return 'blue';
41 }
42 return 'gray';
43 };
44
45 return (
46 <Accordion.Item
47 key={ id }
48 className="bg-background-primary border-0.5 [&:hover>h3]:bg-transparent rounded-lg overflow-hidden [&:has([aria-expanded='true'])]:shadow-xs transition-all duration-200 ease-in-out"
49 value={ id }
50 >
51 <Accordion.Trigger className="group p-3 sm:p-4 hover:bg-transparent [&>svg]:hidden [&>div]:flex-grow [&[aria-expanded='true']_.learn-chevron-right]:rotate-90 [&[aria-expanded='true']_.learn-more-btn]:flex">
52 <div className="flex items-center gap-2 sm:gap-3 flex-1">
53 <ChevronRight
54 className="learn-chevron-right transition-transform duration-200 ease-in-out"
55 size={ 20 }
56 />
57
58 <div className="flex-1 text-left">
59 <Text size={ 14 } className="sm:text-base" weight={ 600 }>
60 { title }
61 </Text>
62 </div>
63
64 { url && (
65 <span
66 className="hover:underline underline-offset-2 learn-more-btn hidden transition-all cursor-pointer text-link-primary outline-link-primary items-center gap-1 text-xs px-2 py-1"
67 onClick={ ( event ) => handleLearnHowClick( event, url ) }
68 role="link"
69 tabIndex={ 0 }
70 onKeyDown={ ( e ) => {
71 if ( e.key === 'Enter' || e.key === ' ' ) {
72 handleLearnHowClick( e, url );
73 }
74 } }
75 >
76 <span className="hidden sm:inline">
77 { __( 'Learn how', 'presto-player' ) }
78 </span>
79 <ExternalLink size={ 16 } strokeWidth={ 1.25 } />
80 </span>
81 ) }
82
83 <Badge
84 className="relative overflow-hidden w-14 sm:w-[62px] text-xs"
85 label={
86 <>
87 <span className="sr-only">
88 { sprintf(
89 __( '%1$d of %2$d steps completed', 'presto-player' ),
90 completedStepsCount,
91 totalStepsCount
92 ) }
93 </span>
94
95 <span className="flex items-center">
96 { isCompleted && <Check size={ 12 } /> }
97 <span className="px-1 relative z-10">
98 { completedStepsCount }/{ totalStepsCount }
99 </span>
100 </span>
101
102 <span
103 className="absolute h-full top-0 left-0 bg-[#BAE6FD]/40 transition-[width] duration-300 ease-in-out"
104 style={ {
105 width: `${ ( completedStepsCount / totalStepsCount ) * 100 }%`,
106 } }
107 />
108 </>
109 }
110 variant={ getBadgeColor() }
111 />
112 </div>
113 </Accordion.Trigger>
114
115 <Accordion.Content className="overflow-visible [&>div]:p-0">
116 { description && (
117 <Text
118 className="px-3 sm:px-4 ml-7 mr-0 sm:mx-8 -mt-2 pb-4 max-w-full sm:max-w-[72%]"
119 size={ 14 }
120 color="secondary"
121 weight={ 400 }
122 >
123 { description }
124 </Text>
125 ) }
126
127 <span className="block w-full h-[0.5px] bg-border-subtle" />
128
129 <div className="px-3 sm:px-4 flex flex-col bg-[#FCFCFD]">
130 { steps.map( ( step, index ) => (
131 <BsfLearnStep
132 key={ step.id }
133 step={ step }
134 chapterId={ id }
135 isLast={ index === steps.length - 1 }
136 onCompletionChange={ onStepCompletionChange }
137 onLearnHowClick={ onLearnHowClick }
138 />
139 ) ) }
140 </div>
141 </Accordion.Content>
142 </Accordion.Item>
143 );
144 } ) }
145 </Accordion>
146 );
147 };
148
149 export default BsfLearnChapters;
150