PluginProbe ʕ •ᴥ•ʔ
Presto Player / 4.3.2
Presto Player v4.3.2
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 / BsfLearnStep.js
presto-player / src / admin / dashboard / lib / bsf-learn / components Last commit date
learn-how 2 months ago BsfLearn.js 2 months ago BsfLearnChapters.js 2 months ago BsfLearnSkeleton.js 2 months ago BsfLearnStep.js 2 months ago LearnHowDialog.js 2 months ago
BsfLearnStep.js
161 lines
1 import { __ } from '@wordpress/i18n';
2 import { Button, Text, Tooltip, Badge } from '@bsf/force-ui';
3 import { useState, useEffect } from 'react';
4 import { ArrowUpRight, Check, Info, Video } from 'lucide-react';
5
6 const BsfLearnStep = ( { step, chapterId, isLast = false, onCompletionChange, onLearnHowClick } ) => {
7 const {
8 id,
9 title,
10 description,
11 learn,
12 action,
13 completed = false,
14 isPro = false,
15 } = step;
16
17 const [ isCompleted, setIsCompleted ] = useState( completed );
18
19 // Update local state when completed prop changes
20 useEffect( () => {
21 setIsCompleted( completed );
22 }, [ completed ] );
23
24 if ( ! id || ! title ) {
25 return null;
26 }
27
28 const handleCompletion = () => {
29 const newStatus = ! isCompleted;
30 setIsCompleted( newStatus );
31
32 // Call parent callback to update state
33 if ( onCompletionChange ) {
34 onCompletionChange( chapterId, id, newStatus );
35 }
36 };
37
38 const LearnIcon = () => {
39 switch ( learn?.type ) {
40 case 'video':
41 return <Video size={ 14 } />;
42 case 'link':
43 default:
44 return <Info size={ 14 } />;
45 }
46 }
47
48 const handleLearnClick = () => {
49 if ( learn?.type === 'link' ) {
50 window.open( learn?.url, '_blank', 'noopener,noreferrer' );
51 return;
52 }
53
54 // Open learn how dialog for other types (video, content, etc.)
55 if ( onLearnHowClick && learn ) {
56 onLearnHowClick( step );
57 }
58 };
59
60 const handleActionClick = () => {
61 if ( action?.url ) {
62 if ( action?.isExternal ) {
63 window.open( action?.url, '_blank', 'noopener,noreferrer' );
64 } else {
65 // Internal navigation
66 window.location.href = action?.url;
67 }
68 return;
69 }
70
71 console.info( 'Empty or missing URL!!!' );
72 };
73
74 const statusText = isCompleted
75 ? __( 'Mark as incomplete', 'presto-player' )
76 : __( 'Mark as complete', 'presto-player' );
77
78 return (
79 <div className={`py-4 sm:py-5 flex items-center gap-2 sm:gap-3 border-solid border-0 border-border-subtle ${ isLast ? '' : 'border-b-0.5' }`}>
80 <Tooltip arrow content={ statusText } placement="top" variant="dark">
81 <span
82 className={ `self-start mt-[1px] flex justify-center items-center w-5 h-5 rounded-full cursor-pointer border-[1.25px] border-solid ${
83 isCompleted
84 ? 'bg-support-success p-[3px] sm:p-[4px] border-support-success-inverse'
85 : 'border-border-strong [&:hover>svg]:text-border-strong'
86 }` }
87 tabIndex={ 0 }
88 aria-label={ statusText }
89 onClick={ handleCompletion }
90 onKeyDown={ ( e ) => {
91 if ( e.key === 'Enter' || e.key === ' ' ) {
92 e.preventDefault();
93 handleCompletion();
94 }
95 } }
96 >
97 <Check
98 className="text-icon-on-color sm:w-3.5 sm:h-3.5 transition-all duration-200"
99 size={ 12 }
100 strokeWidth={ 1.5 }
101 />
102 </span>
103 </Tooltip>
104
105 <div className="flex-1 flex items-center gap-2">
106 <div className="flex flex-col gap-1.5">
107 <Text
108 className="flex-1"
109 size={ 14 }
110 weight={ 500 }
111 color="primary"
112 >
113 { title }
114 </Text>
115 <Text
116 className="flex-1 hidden sm:block"
117 size={ 14 }
118 color="secondary"
119 >
120 { description }
121 </Text>
122 </div>
123 { isPro && (
124 <Badge
125 label={ __( 'Pro', 'presto-player' ) }
126 size="xs"
127 type="pill"
128 variant="inverse"
129 className="uppercase"
130 />
131 ) }
132 </div>
133
134 { learn && (
135 <Tooltip arrow content={ learn?.label || __( 'Learn how', 'presto-player' ) } placement="top" variant="dark">
136 <Button
137 size="xs"
138 variant="ghost"
139 icon={ <LearnIcon /> }
140 onClick={ handleLearnClick }
141 className="text-button-primary hover:bg-transparent outline-none"
142 />
143 </Tooltip>
144 ) }
145
146 <Button
147 className="px-3 gap-0.5 min-w-40 text-button-primary hover:bg-background-button-hover hover:outline-button-secondary"
148 size="sm"
149 variant="secondary"
150 icon={ <ArrowUpRight size={ 14 } /> }
151 iconPosition="right"
152 onClick={ handleActionClick }
153 >
154 { action?.label || __( 'Set Up', 'presto-player' ) }
155 </Button>
156 </div>
157 );
158 };
159
160 export default BsfLearnStep;
161