import { InnerBlocks, useBlockProps, BlockContextProvider, useInnerBlocksProps, InspectorControls, // eslint-disable-next-line @wordpress/no-unsafe-wp-apis __experimentalUseBlockPreview as useBlockPreview, store as blockEditorStore, } from '@wordpress/block-editor'; import classnames from 'classnames'; import { useSelect } from '@wordpress/data'; import { memo, useMemo, useState, useEffect } from '@wordpress/element'; import { PanelBody, __experimentalToggleGroupControl as ToggleGroupControl, __experimentalToggleGroupControlOption as ToggleGroupControlOption, RangeControl, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import * as lpUtils from 'lpAssetsJsPath/utils.js'; import API from 'lpAssetsJsPath/api.js'; const TEMPLATE_DEFAULT = [ [ 'learnpress/course-image' ], [ 'learnpress/course-title' ], [ 'learnpress/course-price' ], ]; function PostTemplateInnerBlocks( { classList } ) { const innerBlocksProps = useInnerBlocksProps( { className: classnames( 'wp-block-learnpress-course-item-template' ) }, { template: TEMPLATE_DEFAULT } ); return (
  • ); } function PostTemplateBlockPreview( { blocks, blockContextId, classList, isHidden, setActiveBlockContextId, } ) { const blockPreviewProps = useBlockPreview( { blocks, } ); const handleOnClick = () => { setActiveBlockContextId( blockContextId ); }; const style = { display: isHidden ? 'none' : undefined, }; return (
  • ); } const fetchLearnPressCourses = async ( courseQuery, signal ) => { let url = API.apiEditCoursesArchiveBlock; url = lpUtils.lpAddQueryArgs( url, courseQuery ); const response = await fetch( url, { method: 'GET', signal, } ); if ( ! response.ok ) { throw new Error( `HTTP error! Status: ${ response.status }` ); } return await response.json(); }; const MemoizedPostTemplateBlockPreview = memo( PostTemplateBlockPreview ); const Edit = ( { clientId, context, attributes, setAttributes } ) => { const blockProps = useBlockProps( { className: classnames( 'learn-press-courses' ), } ); const [ activeBlockContextId, setActiveBlockContextId ] = useState(); const [ coursesData, setCoursesData ] = useState(); const [ listCourses, setListCourses ] = useState( [] ); const [ loadingAPI, setLoadingAPI ] = useState( 0 ); // const [ totalPages, setTotalPages ] = useState( 1 ); const { columns } = attributes; const layoutPagination = context.lpCourseQuery?.pagination_type || 'number'; // Fetch courses when query parameters change useEffect( () => { const courseQuery = context.lpCourseQuery ?? {}; let signal, controller; const fetchCourses = async () => { try { setLoadingAPI( 1 ); controller = new AbortController(); signal = controller.signal; const response = await fetchLearnPressCourses( courseQuery, signal ); const { data } = response; const { courses, page, total, total_pages } = data; setCoursesData( response ); setListCourses( courses ); // setTotalPages( total_pages ); } catch ( error ) { if ( error.name !== 'AbortError' ) { console.error( 'Failed to fetch courses:', error ); } } finally { setLoadingAPI( 0 ); } }; fetchCourses(); return () => { controller.abort(); }; }, [ context.lpCourseQuery?.order_by, context.lpCourseQuery?.limit ] ); const { blocks } = useSelect( ( select ) => { const { getBlocks } = select( blockEditorStore ); return { blocks: getBlocks( clientId ), }; }, [ clientId ] ); const blockContexts = useMemo( () => listCourses?.map( ( course ) => ( { lpCourseData: course, courseId: course?.ID, } ) ), [ listCourses ] ); if ( loadingAPI ) { return ( ); } if ( listCourses.length === 0 && ! loadingAPI ) { const dataDummy = [ { ID: 1, post_title: __( 'Course One', 'learnpress' ), }, { ID: 2, post_title: __( 'Course two', 'learnpress' ), }, ]; setListCourses( dataDummy ); } function paginationTypeDisplay( type ) { switch ( type ) { case 'load-more': return ( ); case 'infinite': return ''; default: return ( ); } } return ( <> { setAttributes( { layout: value || 'gird', } ); } } isBlock={ true } > { attributes.layout === 'grid' && ( { setAttributes( { columns: value, } ); } } min={ 2 } max={ 6 } step={ 1 } marks={ [ { value: 2, label: '2' }, { value: 3, label: '3' }, { value: 4, label: '4' }, { value: 5, label: '5' }, { value: 6, label: '6' }, ] } withInputField={ true } /> ) } { context.lpCourseQuery?.pagination ? paginationTypeDisplay( layoutPagination ) : null } ); }; export default Edit;