33 * WordPress dependencies.
44 */
55import { __ } from '@wordpress/i18n' ;
6-
6+ import { useState } from '@wordpress/element' ;
77import {
88 BaseControl ,
99 Button ,
1010 Placeholder ,
1111 Spinner ,
12+ Notice ,
1213} from '@wordpress/components' ;
13-
1414import { useSelect } from '@wordpress/data' ;
15-
1615import { store as coreStore } from '@wordpress/core-data' ;
1716
1817/**
@@ -21,6 +20,9 @@ import { store as coreStore } from '@wordpress/core-data';
2120import FeedControl from './components/FeedControl' ;
2221
2322const BlockPlaceholder = ( { attributes, setAttributes, onSaveFeed } ) => {
23+ const [ isValidating , setIsValidating ] = useState ( false ) ;
24+ const [ validationResults , setValidationResults ] = useState ( [ ] ) ;
25+
2426 const { categories, isLoading } = useSelect ( ( select ) => {
2527 const { getEntityRecords, isResolving } = select ( coreStore ) ;
2628
@@ -33,20 +35,132 @@ const BlockPlaceholder = ({ attributes, setAttributes, onSaveFeed }) => {
3335 } ;
3436 } , [ ] ) ;
3537
38+ const handleLoadFeed = async ( ) => {
39+ if ( ! attributes ?. feed ?. source ) {
40+ return ;
41+ }
42+
43+ setIsValidating ( true ) ;
44+ setValidationResults ( [ ] ) ;
45+
46+ const isCategory = categories . some (
47+ ( cat ) => cat . id === attributes . feed . source
48+ ) ;
49+
50+ if ( isCategory && 'group' === attributes . feed . type ) {
51+ onSaveFeed ( ) ;
52+ setIsValidating ( false ) ;
53+ return ;
54+ }
55+
56+ try {
57+ const formData = new FormData ( ) ;
58+ formData . append ( 'action' , 'feedzy_validate_feed' ) ;
59+ formData . append ( 'feed_url' , attributes . feed . source ) ;
60+ formData . append ( 'nonce' , window . feedzyData ?. nonce ) ;
61+
62+ const response = await fetch ( window . feedzyData ?. url , {
63+ method : 'POST' ,
64+ body : formData ,
65+ } ) ;
66+
67+ const data = await response . json ( ) ;
68+
69+ if ( data . success && data . data ?. results ) {
70+ const results = data . data . results ;
71+ setValidationResults ( results ) ;
72+
73+ const hasErrors = results . some (
74+ ( result ) => result . status === 'error'
75+ ) ;
76+
77+ if ( ! hasErrors ) {
78+ onSaveFeed ( ) ;
79+ }
80+ } else if ( ! data . success ) {
81+ setValidationResults ( [
82+ {
83+ status : 'error' ,
84+ message :
85+ data . data ?. message ||
86+ __ ( 'Validation failed' , 'feedzy-rss-feeds' ) ,
87+ } ,
88+ ] ) ;
89+ }
90+ } catch ( error ) {
91+ setValidationResults ( [
92+ {
93+ status : 'error' ,
94+ message : __ (
95+ 'Failed to validate feed. Please check your connection and try again.' ,
96+ 'feedzy-rss-feeds'
97+ ) ,
98+ } ,
99+ ] ) ;
100+ } finally {
101+ setIsValidating ( false ) ;
102+ }
103+ } ;
104+
105+ const handleFeedChange = ( value ) => {
106+ setAttributes ( { feed : value } ) ;
107+ setValidationResults ( [ ] ) ;
108+ } ;
109+
110+ const renderValidationResults = ( ) => {
111+ if ( ! validationResults || validationResults . length === 0 ) {
112+ return null ;
113+ }
114+
115+ return (
116+ < div
117+ className = "feedzy-validation-results"
118+ style = { {
119+ display : 'flex' ,
120+ flexDirection : 'column' ,
121+ gap : '10px' ,
122+ marginTop : '15px' ,
123+ } }
124+ >
125+ { validationResults . map ( ( result , index ) => (
126+ < Notice
127+ key = { `result-${ index } ` }
128+ status = { result . status }
129+ isDismissible = { false }
130+ >
131+ { result . url && (
132+ < >
133+ < strong > { result . url } </ strong >
134+ < br />
135+ </ >
136+ ) }
137+ { result . message }
138+ </ Notice >
139+ ) ) }
140+ </ div >
141+ ) ;
142+ } ;
143+
36144 return (
37145 < Placeholder
38146 key = "placeholder"
39147 icon = "rss"
40148 label = { __ ( 'Feedzy RSS Feeds' , 'feedzy-rss-feeds' ) }
41149 >
42- { isLoading && (
150+ { ( isLoading || isValidating ) && (
43151 < div key = "loading" className = "wp-block-embed is-loading" >
44152 < Spinner />
45- < p > { __ ( 'Fetching…' , 'feedzy-rss-feeds' ) } </ p >
153+ < p >
154+ { isValidating
155+ ? __ (
156+ 'Validating and fetching feed…' ,
157+ 'feedzy-rss-feeds' )
158+ : __ ( 'Loading…' , 'feedzy-rss-feeds' ) }
159+ </ p >
46160 </ div >
47161 ) }
48162
49- { ! isLoading && (
163+ { ! isLoading && ! isValidating && (
50164 < >
51165 < BaseControl
52166 label = { __ ( 'Feed Source' , 'feedzy-rss-feeds' ) }
@@ -60,9 +174,11 @@ const BlockPlaceholder = ({ attributes, setAttributes, onSaveFeed }) => {
60174 value : category . id ,
61175 } ) ) ,
62176 ] }
63- onChange = { ( value ) => setAttributes ( { feed : value } ) }
177+ onChange = { handleFeedChange }
64178 />
65179
180+ { renderValidationResults ( ) }
181+
66182 < p >
67183 { __ (
68184 'Enter the full URL of the feed source you wish to display here, or select a Feed Group. Also you can add multiple URLs separated with a comma. You can manage your feed groups from' ,
@@ -81,22 +197,11 @@ const BlockPlaceholder = ({ attributes, setAttributes, onSaveFeed }) => {
81197 < div >
82198 < Button
83199 variant = "primary"
84- onClick = { ( ) => {
85- if ( attributes ?. feed ?. source ) {
86- onSaveFeed ( ) ;
87- }
88- } }
200+ onClick = { handleLoadFeed }
201+ disabled = { ! attributes ?. feed ?. source }
89202 >
90203 { __ ( 'Load Feed' , 'feedzy-rss-feeds' ) }
91204 </ Button >
92-
93- < Button
94- variant = "link"
95- href = "https://validator.w3.org/feed/"
96- target = "_blank"
97- >
98- { __ ( 'Validate' , 'feedzy-rss-feeds' ) }
99- </ Button >
100205 </ div >
101206 </ >
102207 ) }
0 commit comments