Settings.js
239 lines
| 1 | import { __ } from '@wordpress/i18n'; |
| 2 | import { Button, TextareaControl, Flex, FlexItem, Spinner, ExternalLink } from '@wordpress/components'; |
| 3 | import {useEffect, useState} from '@wordpress/element'; |
| 4 | import classnames from 'classnames'; |
| 5 | import License from '../License'; |
| 6 | |
| 7 | const Feedback = () => { |
| 8 | const feedbackStatusText = { |
| 9 | error: __( 'There was a problem submitting your feedback.', 'templates-patterns-collection' ), |
| 10 | emptyFeedback: __( 'Please provide a feedback before submitting the form.', 'templates-patterns-collection' ), |
| 11 | submitted: __( 'Thank you for helping us improve Templates Cloud!', 'templates-patterns-collection' ), |
| 12 | }; |
| 13 | |
| 14 | const { version } = window.tiobDash; |
| 15 | |
| 16 | const collectedInfo = [ |
| 17 | { |
| 18 | name: __( 'Plugin version', 'templates-patterns-collection' ), |
| 19 | value: version |
| 20 | }, |
| 21 | { |
| 22 | name: __( 'Feedback Details', 'templates-patterns-collection' ), |
| 23 | value: __( 'Text from the above text area', 'templates-patterns-collection' ) |
| 24 | } |
| 25 | ]; |
| 26 | |
| 27 | const [ showInfo, setShowInfo ] = useState( false ); |
| 28 | const [ feedbackStatus, setFeedbackStatus ] = useState( 'notSubmitted' ); |
| 29 | const [ feedbackDetails, setFeedbackDetails ] = useState( '' ); |
| 30 | |
| 31 | const submitFeedback = () => { |
| 32 | const feedback = feedbackDetails.trim(); |
| 33 | if ( 5 >= feedback.length ) { |
| 34 | setFeedbackStatus( 'emptyFeedback' ); |
| 35 | return; |
| 36 | } |
| 37 | |
| 38 | setFeedbackStatus( 'loading' ); |
| 39 | try { |
| 40 | fetch( 'https://api.themeisle.com/tracking/feedback', { |
| 41 | method: 'POST', |
| 42 | headers: { |
| 43 | 'Content-Type': 'application/json', |
| 44 | Accept: 'application/json, */*;q=0.1', |
| 45 | 'Cache-Control': 'no-cache' |
| 46 | }, |
| 47 | body: JSON.stringify({ |
| 48 | slug: 'templates-patterns-collection', |
| 49 | version, |
| 50 | feedback, |
| 51 | data: { |
| 52 | 'feedback-area': 'template-patterns-collection-page-templates', |
| 53 | 'feedback-option': 'other' |
| 54 | } |
| 55 | }) |
| 56 | }).then( r => { |
| 57 | if ( ! r.ok ) { |
| 58 | setFeedbackStatus( 'error' ); |
| 59 | return; |
| 60 | } |
| 61 | |
| 62 | setFeedbackStatus( 'submitted' ); |
| 63 | })?.catch( ( error ) => { |
| 64 | console.warn( error.message ); |
| 65 | setFeedbackStatus( 'error' ); |
| 66 | }); |
| 67 | } catch ( error ) { |
| 68 | console.warn( error.message ); |
| 69 | setFeedbackStatus( 'error' ); |
| 70 | } |
| 71 | }; |
| 72 | |
| 73 | useEffect( () => { |
| 74 | const info = document.querySelector( '.tiob_feedback_collect.info' ); |
| 75 | if ( info ) { |
| 76 | info.style.height = showInfo ? '180px' : '0'; |
| 77 | } |
| 78 | |
| 79 | }, [ showInfo ]); |
| 80 | |
| 81 | return ( |
| 82 | <div className="tiob-feedback-form"> |
| 83 | <h3>{ __( 'What\'s one thing you need in Templates Cloud?', 'templates-patterns-collection' ) }</h3> |
| 84 | <TextareaControl |
| 85 | className={ classnames({ |
| 86 | 'feedback_details': true, |
| 87 | 'invalid': 'emptyFeedback' === feedbackStatus, |
| 88 | }) } |
| 89 | placeholder={ __( 'Tell us how can we help you better with Templates Cloud', 'templates-patterns-collection' ) } |
| 90 | value={ feedbackDetails } |
| 91 | help={ feedbackStatusText[feedbackStatus] || false } |
| 92 | rows={7} |
| 93 | cols={50} |
| 94 | onChange={ value => { |
| 95 | setFeedbackDetails( value ); |
| 96 | if ( 5 < value.trim().length ) { |
| 97 | setFeedbackStatus( 'notSubmitted' ); |
| 98 | } |
| 99 | } } |
| 100 | /> |
| 101 | <div className="tiob_feedback_collect info"> |
| 102 | <div className="wrapper"> |
| 103 | <p>{ __( 'We value privacy, that\'s why no domain name, email address or IP addresses are collected after you submit the survey. Below is a detailed view of all data that Themeisle will receive if you fill in this survey.', 'templates-patterns-collection' ) }</p> |
| 104 | { collectedInfo.map( ( row, index ) => { |
| 105 | return ( |
| 106 | <div className="info-row" key={ index }> |
| 107 | <p><b>{ row.name }</b></p> |
| 108 | <p>{ row.value }</p> |
| 109 | </div> |
| 110 | ); |
| 111 | }) } |
| 112 | </div> |
| 113 | </div> |
| 114 | <Flex |
| 115 | direction="row-reverse" |
| 116 | align="left" |
| 117 | justify="space-between" |
| 118 | style={ { height: 'auto' } } |
| 119 | > |
| 120 | <FlexItem> |
| 121 | <Button |
| 122 | isPrimary |
| 123 | onClick={ submitFeedback } |
| 124 | disabled={ 'loading' === feedbackStatus } |
| 125 | > |
| 126 | { 'loading' === feedbackStatus ? <Spinner /> : __( 'Submit feedback', 'templates-patterns-collection' ) } |
| 127 | </Button> |
| 128 | </FlexItem> |
| 129 | <FlexItem> |
| 130 | <Button |
| 131 | className="toggle-info" |
| 132 | aria-expanded={ showInfo } |
| 133 | variant="link" |
| 134 | isLink |
| 135 | onClick={() => setShowInfo( ! showInfo )} |
| 136 | > |
| 137 | { __( 'What info do we collect?', 'templates-patterns-collection' ) } |
| 138 | </Button> |
| 139 | </FlexItem> |
| 140 | </Flex> |
| 141 | </div> |
| 142 | ); |
| 143 | }; |
| 144 | const Settings = () => { |
| 145 | |
| 146 | const [ currentSettingTab, setCurrentSettingTab ] = useState( 'general' ); |
| 147 | const settingsTabs = [ |
| 148 | { id: 'general', label: __( 'General', 'templates-patterns-collection' ) }, |
| 149 | { id: 'feedback', label: __( 'Feedback', 'templates-patterns-collection' ) }, |
| 150 | ]; |
| 151 | |
| 152 | const { links } = window.tiobDash; |
| 153 | |
| 154 | useEffect( () => { |
| 155 | const params = Object.fromEntries(new URLSearchParams(location.search)); |
| 156 | |
| 157 | if ( params?.tab && settingsTabs.find( ( tab ) => tab.id === params.tab ) ) { |
| 158 | setCurrentSettingTab( params.tab ); |
| 159 | } |
| 160 | }, [] ); |
| 161 | |
| 162 | return ( |
| 163 | <div className="tiob-settings"> |
| 164 | <div className="panel"> |
| 165 | <div className="setting-tabs"> |
| 166 | { |
| 167 | settingsTabs.map( ( tab ) => { |
| 168 | |
| 169 | const classes = classnames( [ |
| 170 | 'tab', |
| 171 | { active: tab.id === currentSettingTab }, |
| 172 | ] ); |
| 173 | |
| 174 | return ( |
| 175 | <Button |
| 176 | key={ tab.id } |
| 177 | className={ classes } |
| 178 | isLink |
| 179 | onClick={ () => { |
| 180 | setCurrentSettingTab( tab.id ); |
| 181 | } } |
| 182 | > |
| 183 | { tab.label } |
| 184 | </Button> |
| 185 | ); |
| 186 | } ) |
| 187 | } |
| 188 | </div> |
| 189 | <div className="tab-content"> |
| 190 | { |
| 191 | currentSettingTab === 'general' && <License /> |
| 192 | } |
| 193 | { |
| 194 | currentSettingTab === 'feedback' && <Feedback /> |
| 195 | } |
| 196 | </div> |
| 197 | </div> |
| 198 | <div className="panel is-secondary"> |
| 199 | <h3>{ __( 'Useful links', 'templates-patterns-collection' ) }</h3> |
| 200 | <div className="links"> |
| 201 | { links && links.map( ( link ) => { |
| 202 | const isButton = link?.is_button || false; |
| 203 | const isExternal = link?.is_external || false; |
| 204 | |
| 205 | return ( |
| 206 | |
| 207 | isButton ? ( |
| 208 | <Button |
| 209 | isSecondary |
| 210 | href={ link?.url || '#' } |
| 211 | > |
| 212 | { link?.label || '' } |
| 213 | </Button> |
| 214 | ) : ( |
| 215 | isExternal ? ( |
| 216 | <ExternalLink |
| 217 | href={ link?.url || '#' }> |
| 218 | { link?.label || '' } |
| 219 | </ExternalLink> |
| 220 | ) : ( |
| 221 | <a |
| 222 | href={ link?.url || '#' } |
| 223 | target={ link?.target || '_blank' } |
| 224 | > |
| 225 | { link?.label || '' } |
| 226 | </a> |
| 227 | ) |
| 228 | ) |
| 229 | ); |
| 230 | } ) |
| 231 | } |
| 232 | </div> |
| 233 | </div> |
| 234 | </div> |
| 235 | ); |
| 236 | }; |
| 237 | |
| 238 | export default Settings; |
| 239 |