PluginProbe
Image Optimizer – Compress Images and Convert to WebP or AVIF / 1.7.4
Image Optimizer – Compress Images and Convert to WebP or AVIF v1.7.4
1.7.7 1.7.6 1.7.5 1.7.4 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.2.0 1.2.1 1.3.0 1.4.0 1.4.1 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 All 33 releases
image-optimization / modules / reviews / assets / src / layouts / user-feedback-form.js

user-feedback-form.js in Image Optimizer – Compress Images and Convert to WebP or AVIF 1.7.4, at modules/reviews/assets/src/layouts/user-feedback-form.js

154 lines 4.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import Box from '@elementor/ui/Box';
2 import Popover from '@elementor/ui/Popover';
3 import Typography from '@elementor/ui/Typography';
4 import { styled } from '@elementor/ui/styles';
5 import { useEffect, useRef } from '@wordpress/element';
6 import { escapeHTML } from '@wordpress/escape-html';
7 import { __ } from '@wordpress/i18n';
8 import useStorage from '../hooks/use-storage';
9 import API from '../api';
10 import DismissButton from '../components/dismiss-button';
11 import FeedbackForm from '../components/feedback-form';
12 import RatingForm from '../components/rating-form';
13 import ReviewForm from '../components/review-form';
14 import { useNotifications, useSettings } from '../hooks/use-settings';
15
16 const UserFeedbackForm = ( ) => {
17 const { success, error } = useNotifications();
18 const { save, get } = useStorage();
19 const anchorEl = useRef( null );
20 const {
21 rating,
22 setRating,
23 feedback,
24 isOpened,
25 setIsOpened,
26 setCurrentPage,
27 } = useSettings();
28
29 useEffect( () => {
30 /**
31 * Show the popover if the user has not submitted repo feedback.
32 */
33 if ( window?.imageOptimizerReviewData?.reviewData?.rating > 3 && ! window?.imageOptimizerReviewData?.reviewData?.repo_review_clicked ) {
34 setCurrentPage( 'review' );
35 setRating( window?.imageOptimizerReviewData?.reviewData?.rating ); // re-add the saved rating
36 }
37 }, [] );
38
39 /**
40 * Close the popover.
41 * @param {Object} event
42 * @param {string} reason
43 */
44 const handleClose = ( event, reason ) => {
45 if ( 'backdropClick' !== reason ) {
46 setIsOpened( false );
47 }
48 };
49
50 const id = isOpened ? 'reviews-popover' : undefined;
51
52 const { currentPage } = useSettings();
53
54 const headerMessage = {
55 ratings: __( 'How would you rate Image Optimizer so far?', 'image-optimization' ),
56 feedback: __( 'We’re thrilled to hear that! What would make it even better?', 'image-optimization' ),
57 review: __( "We're thrilled you're enjoying Image Optimizer", 'image-optimization' ),
58 };
59
60 const handleSubmit = async ( close, avoidClosing = false ) => {
61 try {
62 const response = await API.sendFeedback( { rating, feedback } ).then( async ( res ) => {
63 await save( {
64 image_optimizer_review_data: {
65 ...get.data.image_optimizer_review_data,
66 rating: parseInt( rating ),
67 feedback: escapeHTML( feedback ),
68 submitted: true,
69 },
70 } );
71
72 return res;
73 } );
74
75 if ( ! response?.success && parseInt( rating ) < 4 ) {
76 /**
77 * Show success message if the feedback was already submitted.
78 */
79 success( __( 'Feedback already submitted', 'image-optimization' ) );
80 } else if ( response?.success && parseInt( rating ) < 4 ) {
81 success( __( 'Thank you for your feedback!', 'image-optimization' ) );
82 }
83
84 if ( ! avoidClosing ) {
85 await close();
86 }
87
88 return true;
89 } catch ( e ) {
90 error( __( 'Failed to submit!', 'image-optimization' ) );
91 console.log( e );
92 return false;
93 }
94 };
95
96 return (
97 <Popover
98 open={ isOpened }
99 anchorOrigin={ { vertical: 'bottom', horizontal: 'right' } }
100 anchorReference="anchorPosition"
101 anchorPosition={ {
102 top: window.innerHeight - 10,
103 left: window.innerWidth - 10,
104 } }
105 id={ id }
106 onClose={ handleClose }
107 anchorEl={ anchorEl.current }
108 disableEscapeKeyDown
109 disableScrollLock
110 disablePortal
111 slotProps={ {
112 paper: {
113 sx: {
114 pointerEvents: 'auto', // allow interactions inside popover
115 },
116 },
117 } }
118 sx={ {
119 pointerEvents: 'none', // allow click-through behind
120 } }
121 >
122 <StyledBox>
123 <Header>
124 <Typography
125 variant="subtitle1"
126 color="text.primary"
127 >
128 { headerMessage?.[ currentPage ] }
129 </Typography>
130 <DismissButton close={ close } />
131 </Header>
132 { 'ratings' === currentPage && <RatingForm close={ handleClose } handleSubmitForm={ handleSubmit } /> }
133 { 'feedback' === currentPage && <FeedbackForm close={ handleClose } handleSubmitForm={ handleSubmit } /> }
134 { 'review' === currentPage && <ReviewForm close={ handleClose } /> }
135 </StyledBox>
136 </Popover>
137 );
138 };
139
140 export default UserFeedbackForm;
141
142 const StyledBox = styled( Box )`
143 width: 350px;
144 padding: ${ ( { theme } ) => theme.spacing( 1.5 ) };
145 `;
146
147 const Header = styled( Box )`
148 display: flex;
149 flex-direction: row;
150 justify-content: space-between;
151 align-items: center;
152 margin-bottom: ${ ( { theme } ) => theme.spacing( 2 ) };
153 `;
154