From 9af25770afe94800005bd17f29dd2c30db0911d6 Mon Sep 17 00:00:00 2001 From: Hardeep Asrani Date: Mon, 12 Feb 2024 17:42:56 +0530 Subject: [PATCH] feat: add event tracking and various changes --- inc/class-api.php | 247 +++++++++++++++++++++++------- inc/class-main.php | 1 + quickwp.php | 2 +- src/App.js | 3 + src/components/TemplatePreview.js | 32 +++- src/frontend/style.scss | 1 + src/parts/ColorPalette.js | 11 +- src/parts/ImageSuggestions.js | 16 +- src/parts/Template.js | 75 ++++----- src/parts/ViewSite.js | 29 +++- src/steps.js | 10 +- src/store.js | 76 +++++++-- src/utils.js | 196 ++++++++++++++++++------ 13 files changed, 504 insertions(+), 195 deletions(-) diff --git a/inc/class-api.php b/inc/class-api.php index 64c1acf..03ceb26 100644 --- a/inc/class-api.php +++ b/inc/class-api.php @@ -62,11 +62,15 @@ public function register_routes() { 'send' => array( 'methods' => \WP_REST_Server::CREATABLE, 'args' => array( - 'step' => array( + 'step' => array( 'required' => true, 'type' => 'string', ), - 'message' => array( + 'message' => array( + 'required' => false, + 'type' => 'string', + ), + 'template' => array( 'required' => false, 'type' => 'string', ), @@ -114,9 +118,27 @@ public function register_routes() { 'required' => true, 'type' => 'string', ), + 'images' => array( + 'required' => false, + 'type' => 'array', + ), ), 'callback' => array( $this, 'templates' ), ), + 'homepage' => array( + 'methods' => \WP_REST_Server::READABLE, + 'args' => array( + 'thread_id' => array( + 'required' => true, + 'type' => 'string', + ), + 'template' => array( + 'required' => true, + 'type' => 'string', + ), + ), + 'callback' => array( $this, 'homepage' ), + ), ); foreach ( $routes as $route => $args ) { @@ -138,14 +160,20 @@ public function register_routes() { public function send( \WP_REST_Request $request ) { $data = $request->get_params(); + $params = array( + 'step' => $data['step'], + 'message' => $data['message'], + ); + + if ( isset( $data['template'] ) ) { + $params['template'] = $data['template']; + } + $request = wp_remote_post( QUICKWP_APP_API . 'wizard/send', array( 'timeout' => 20, // phpcs:ignore WordPressVIPMinimum.Performance.RemoteRequestTimeout.timeout_timeout - 'body' => array( - 'step' => $data['step'], - 'message' => $data['message'], - ), + 'body' => $params, ) ); @@ -254,6 +282,101 @@ public function get( \WP_REST_Request $request ) { return new \WP_REST_Response( $response, 200 ); } + /** + * Get homepage. + * + * @param \WP_REST_Request $request Request. + * + * @return \WP_REST_Response + */ + public function homepage( \WP_REST_Request $request ) { + $data = $request->get_params(); + + $api_url = QUICKWP_APP_API . 'wizard/get'; + + $query_params = array( + 'thread_id' => $data['thread_id'], + ); + + $request_url = add_query_arg( $query_params, $api_url ); + + $request = wp_safe_remote_get( + $request_url, + array( + 'timeout' => 20, // phpcs:ignore WordPressVIPMinimum.Performance.RemoteRequestTimeout.timeout_timeout + ) + ); + + if ( is_wp_error( $request ) ) { + return new \WP_REST_Response( array( 'error' => $request->get_error_message() ), 500 ); + } + + /** + * Holds the response as a standard class object + * + * @var \stdClass $response + */ + $response = json_decode( wp_remote_retrieve_body( $request ) ); + + if ( ! isset( $response->data ) || ! $response->data ) { + return new \WP_REST_Response( array( 'error' => __( 'Error', 'quickwp' ) ), 500 ); + } + + $items = self::process_json_from_response( $response->data ); + + if ( ! $items ) { + return new \WP_REST_Response( array( 'error' => __( 'Error Parsing JSON', 'quickwp' ) ), 500 ); + } + + self::extract_data( $items ); + + $templates = apply_filters( 'quickwp_templates', array() ); + + if ( empty( $templates ) || ! isset( $templates['homepage'] ) ) { + return new \WP_REST_Response( array( 'error' => __( 'Error', 'quickwp' ) ), 500 ); + } + + $template = $templates['homepage'][ $data['template'] ]; + + $result = array(); + + $theme_path = get_stylesheet_directory(); + + $patterns = file_get_contents( $template ); //phpcs:ignore WordPressVIPMinimum.Performance.FetchingRemoteData.FileGetContentsUnknown + + if ( ! $patterns ) { + return new \WP_REST_Response( array( 'error' => __( 'Error', 'quickwp' ) ), 500 ); + } + + preg_match_all( '/"slug":"(.*?)"/', $patterns, $matches ); + $slugs = $matches[1]; + + $filtered_patterns = array(); + + foreach ( $slugs as $slug ) { + $slug = str_replace( 'quickwp/', '', $slug ); + $pattern_path = $theme_path . '/patterns/' . $slug . '.php'; + + if ( ! file_exists( $pattern_path ) ) { + continue; + } + + ob_start(); + include $pattern_path; + $pattern_content = ob_get_clean(); + + $filtered_patterns[] = $pattern_content; + } + + return new \WP_REST_Response( + array( + 'status' => 'success', + 'data' => implode( '', $filtered_patterns ), + ), + 200 + ); + } + /** * Get templates. * @@ -300,16 +423,65 @@ public function templates( \WP_REST_Request $request ) { return new \WP_REST_Response( array( 'error' => __( 'Error Parsing JSON', 'quickwp' ) ), 500 ); } + self::extract_data( $items ); + + $templates = apply_filters( 'quickwp_templates', array() ); + + if ( empty( $templates ) || ! isset( $templates['homepage'] ) ) { + return new \WP_REST_Response( array( 'error' => __( 'Error', 'quickwp' ) ), 500 ); + } + + $items = $templates['homepage']; + $result = array(); - foreach( $items as $item ) { - $pattern = self::extract_patterns( $item ); + $theme_path = get_stylesheet_directory(); + + foreach ( $items as $item => $path ) { + $pattern = file_get_contents( $path ); //phpcs:ignore WordPressVIPMinimum.Performance.FetchingRemoteData.FileGetContentsUnknown if ( ! $pattern ) { continue; } - $result[] = $pattern; + preg_match_all( '/"slug":"(.*?)"/', $pattern, $matches ); + $slugs = $matches[1]; + + $filtered_patterns = array(); + + foreach ( $slugs as $slug ) { + $slug = str_replace( 'quickwp/', '', $slug ); + $pattern_path = $theme_path . '/patterns/' . $slug . '.php'; + + if ( ! file_exists( $pattern_path ) ) { + continue; + } + + // Check if $data param has images and it counts more than 0. + if ( isset( $data['images'] ) && count( $data['images'] ) > 0 ) { + $images = $data['images']; + + add_filter( + 'quickwp/image', + function () use( $images ) { + // Get a random image from the array. + $image = $images[ array_rand( $images ) ]; + return esc_url( $image['src'] ); + } + ); + } + + ob_start(); + include $pattern_path; + $pattern_content = ob_get_clean(); + + $filtered_patterns[] = $pattern_content; + } + + $result[] = array( + 'slug' => $item, + 'patterns' => implode( '', $filtered_patterns ), + ); } return new \WP_REST_Response( @@ -369,6 +541,8 @@ public function images( \WP_REST_Request $request ) { * * @param array $data Response. * + * @throws \Exception Exception in case of invalid JSON. + * * @return array|false */ private static function process_json_from_response( $data ) { @@ -392,8 +566,8 @@ private static function process_json_from_response( $data ) { throw new \Exception( 'Invalid JSON' ); } catch ( \Exception $e ) { if ( substr( $json_string, 0, 7 ) === '```json' && substr( trim( $json_string ), -3 ) === '```' ) { - $cleaned_json = trim( str_replace( [ '```json', '```' ], '', $json_string ) ); - $json_object = json_decode( $cleaned_json, true ); + $cleaned_json = trim( str_replace( array( '```json', '```' ), '', $json_string ) ); + $json_object = json_decode( $cleaned_json, true ); if ( is_array( $json_object ) ) { return $json_object; @@ -405,29 +579,18 @@ private static function process_json_from_response( $data ) { } /** - * Extract Patterns. + * Extract Data. * * @param array $items Items. * - * @return array + * @return void */ - private static function extract_patterns( $items ) { - if ( ! isset( $items['slug'] ) || ! isset( $items['data'] ) ) { - return; - } - - $patterns_used = array(); - - foreach ( $items['data'] as $item ) { + private static function extract_data( $items ) { + foreach ( $items as $item ) { if ( ! isset( $item['slug'] ) || ! isset( $item['order'] ) || ! isset( $item['strings'] ) ) { continue; } - $patterns_used[] = array( - 'order' => $item['order'], - 'slug' => $item['slug'], - ); - $strings = $item['strings']; foreach ( $strings as $string ) { @@ -456,37 +619,5 @@ function ( $value ) use( $image ) { } } } - - usort( - $patterns_used, - function ( $a, $b ) { - return $a['order'] <=> $b['order']; - } - ); - - $theme_path = get_stylesheet_directory(); - - $filtered_patterns = array(); - - foreach ( $patterns_used as $pattern ) { - $pattern['slug'] = str_replace( 'quickwp/', '', $pattern['slug'] ); - - $pattern_path = $theme_path . '/patterns/' . $pattern['slug'] . '.php'; - - if ( ! file_exists( $pattern_path ) ) { - continue; - } - - ob_start(); - include $pattern_path; - $pattern_content = ob_get_clean(); - - $filtered_patterns[] = $pattern_content; - } - - return array( - 'slug' => $items['slug'], - 'patterns' => implode( '', $filtered_patterns ), - ); } } diff --git a/inc/class-main.php b/inc/class-main.php index 0e57d0d..5f5d54a 100644 --- a/inc/class-main.php +++ b/inc/class-main.php @@ -87,6 +87,7 @@ public function enqueue_assets() { array( 'api' => $this->api->get_endpoint(), 'siteUrl' => get_site_url(), + 'themeSlug' => get_template(), 'isGuidedMode' => defined( 'QUICKWP_APP_GUIDED_MODE' ) && QUICKWP_APP_GUIDED_MODE, ) ); diff --git a/quickwp.php b/quickwp.php index a1c3633..9c3fd20 100644 --- a/quickwp.php +++ b/quickwp.php @@ -23,7 +23,7 @@ define( 'QUICKWP_APP_VERSION', '1.0.0' ); if ( ! defined( 'QUICKWP_APP_API' ) ) { - define( 'QUICKWP_APP_API', 'https://aaf0-103-217-244-105.ngrok-free.app/api/' ); + define( 'QUICKWP_APP_API', 'https://quickwp.com/api/' ); } if ( ! defined( 'QUICKWP_APP_GUIDED_MODE' ) ) { diff --git a/src/App.js b/src/App.js index 11aff0f..bb18326 100644 --- a/src/App.js +++ b/src/App.js @@ -16,6 +16,7 @@ import { useEffect } from '@wordpress/element'; import { useIsSiteEditorLoading } from './hooks'; import Loader from './components/Loader'; import Header from './parts/Header'; +import { recordEvent } from './utils'; const App = () => { const isEditorLoading = useIsSiteEditorLoading(); @@ -45,6 +46,8 @@ const App = () => { if ( hasWelcome ) { toggle( 'core/edit-site', 'welcomeGuide' ); } + + recordEvent(); }, [ hasWelcome ]); const StepControls = currentStep?.view || null; diff --git a/src/components/TemplatePreview.js b/src/components/TemplatePreview.js index fceaab4..29bf6e4 100644 --- a/src/components/TemplatePreview.js +++ b/src/components/TemplatePreview.js @@ -10,7 +10,10 @@ import { parse } from '@wordpress/blocks'; import { BlockPreview } from '@wordpress/block-editor'; -import { useMemo } from '@wordpress/element'; +import { + useMemo, + useRef +} from '@wordpress/element'; const TemplatePreview = ({ template, @@ -19,12 +22,39 @@ const TemplatePreview = ({ className = '', onClick }) => { + const previewRef = useRef( null ); + const parsedTemplate = useMemo( () => { return Array.isArray( template ) ? template : parse( template ); }, [ template ]); + const scrollToBottom = () => { + const contentDocument = previewRef.current; + + if ( ! canScroll && contentDocument ) { + contentDocument.scrollTo({ + top: contentDocument.scrollHeight, + behavior: 'smooth' + }); + } + }; + + const scrollToTop = () => { + const contentDocument = previewRef.current; + + if ( ! canScroll && contentDocument ) { + contentDocument.scrollTo({ + top: 0, + behavior: 'smooth' + }); + } + }; + return (
{ template, hasLoaded } = useSelect( ( select ) => { - const { getBlocks } = select( 'core/block-editor' ); - const { __experimentalGetCurrentGlobalStylesId, __experimentalGetCurrentThemeBaseGlobalStyles @@ -55,7 +53,8 @@ const ColorPalette = () => { const { getColorPalette, - getProcessStatus + getProcessStatus, + getHomepage } = select( 'quickwp/data' ); const globalStylesId = __experimentalGetCurrentGlobalStylesId(); @@ -64,8 +63,8 @@ const ColorPalette = () => { globalStylesId, defaultStyles: __experimentalGetCurrentThemeBaseGlobalStyles(), palette: getColorPalette(), - template: getBlocks(), - hasLoaded: true === getProcessStatus( 'color_palette' ) + template: getHomepage() || [], + hasLoaded: true === getProcessStatus( 'color_palette' ) && true === getProcessStatus( 'homepage' ) }; }); @@ -174,7 +173,7 @@ const ColorPalette = () => { - - { selectedHomepage && ( - - ) } -
+ - { selectedHomepage ? ( -
- template.slug === selectedHomepage ).content } - canScroll={ true } - /> -
- ) : ( -
- { templates.map( template => { - return ( - setSelectedHomepage( template.slug )} - className="aspect-vert" - /> - ); - }) } -
- ) } +
+ { templates.map( template => { + return ( + setSelectedTemplate( template.slug )} + isSelected={ template.slug === selectedTemplate } + className="aspect-vert" + /> + ); + }) } +
); }; diff --git a/src/parts/ViewSite.js b/src/parts/ViewSite.js index 10b71a8..1cd18cd 100644 --- a/src/parts/ViewSite.js +++ b/src/parts/ViewSite.js @@ -5,9 +5,15 @@ import { __ } from '@wordpress/i18n'; import apiFetch from '@wordpress/api-fetch'; -import { Button } from '@wordpress/components'; +import { + Button, + Spinner +} from '@wordpress/components'; -import { useDispatch } from '@wordpress/data'; +import { + useDispatch, + useSelect +} from '@wordpress/data'; const downloadBlob = ( filename, content, contentType = '' ) => { if ( ! filename || ! content ) { @@ -29,6 +35,17 @@ const downloadBlob = ( filename, content, contentType = '' ) => { const ViewSite = () => { const { createErrorNotice } = useDispatch( 'core/notices' ); + const { + isSaving + } = useSelect( ( select ) => { + const { isSaving } = select( 'quickwp/data' ); + + + return { + isSaving: isSaving() + }; + }, []); + const handleExport = async() => { try { const response = await apiFetch({ @@ -63,6 +80,14 @@ const ViewSite = () => { } }; + if ( isSaving ) { + return ( +
+ +
+ ); + } + return (
diff --git a/src/steps.js b/src/steps.js index eff486a..e60930d 100644 --- a/src/steps.js +++ b/src/steps.js @@ -24,11 +24,6 @@ const STEPS = [ label: __( 'Site Description', 'quickwp' ), view: SiteDescription }, - { - value: 'color_palette', - label: __( 'Color Palette', 'quickwp' ), - view: ColorPalette - }, { value: 'image_suggestions', label: __( 'Image Suggestions', 'quickwp' ), @@ -39,6 +34,11 @@ const STEPS = [ label: __( 'Front Page Template', 'quickwp' ), view: Template }, + { + value: 'color_palette', + label: __( 'Color Palette', 'quickwp' ), + view: ColorPalette + }, { value: 'view_site', label: __( 'View Site', 'quickwp' ), diff --git a/src/store.js b/src/store.js index 681298e..3f30dfe 100644 --- a/src/store.js +++ b/src/store.js @@ -1,3 +1,5 @@ +/* eslint-disable camelcase */ + /** * WordPress dependencies. */ @@ -13,7 +15,8 @@ import STEPS from './steps'; import { generateColorPalette, generateImages, - generateHomepage, + generateTemplates, + recordEvent, saveChanges } from './utils'; @@ -30,6 +33,11 @@ const DEFAULT_STATE = { 'run_id': null, hasLoaded: false }, + 'templates': { + 'thread_id': null, + 'run_id': null, + hasLoaded: false + }, 'homepage': { 'thread_id': null, 'run_id': null, @@ -41,10 +49,12 @@ const DEFAULT_STATE = { imageKeywords: [], activeImageKeyword: null, selectedImages: [], - homepage: [], - selectedHomepage: null, + templates: [], + selectedTemplate: null, + homepage: null, siteTopic: '', siteDescription: '', + sessionID: '', isSavimg: false, hasError: false }; @@ -89,6 +99,13 @@ const actions = { return ({ dispatch, select }) => { const current = select.getStep(); + const stepIndex = STEPS.findIndex( step => current.value === step.value ); + + recordEvent({ + step_id: stepIndex + 1, + step_status: 'completed' + }); + switch ( current.value ) { case 'site_topic': generateColorPalette(); @@ -96,12 +113,13 @@ const actions = { case 'site_description': generateImages(); break; - case 'color_palette': - break; case 'image_suggestions': - generateHomepage(); + generateTemplates( 'templates' ); break; case 'frontpage_template': + generateTemplates( 'homepage' ); + break; + case 'color_palette': saveChanges(); break; } @@ -169,16 +187,28 @@ const actions = { image }; }, + setTemplate( templates ) { + return { + type: 'SET_TEMPLATE', + templates + }; + }, + setSelectedTemplate( selectedTemplate ) { + return { + type: 'SET_SELECTED_TEMPLATE', + selectedTemplate + }; + }, setHomepage( homepage ) { return { type: 'SET_HOMEPAGE', homepage }; }, - setSelectedHomepage( selectedHomepage ) { + setSessionID( sessionID ) { return { - type: 'SET_SELECTED_HOMEPAGE', - selectedHomepage + type: 'SET_SESSION_ID', + sessionID }; }, setError( hasError ) { @@ -286,15 +316,20 @@ const store = createReduxStore( 'quickwp/data', { ( image ) => image !== action.image ) }; - case 'SET_HOMEPAGE': + case 'SET_TEMPLATE': return { ...state, - homepage: action.homepage + templates: action.templates + }; + case 'SET_SELECTED_TEMPLATE': + return { + ...state, + selectedTemplate: action.selectedTemplate }; - case 'SET_SELECTED_HOMEPAGE': + case 'SET_HOMEPAGE': return { ...state, - selectedHomepage: action.selectedHomepage + homepage: action.homepage }; case 'SET_THREAD_ID': return { @@ -318,6 +353,11 @@ const store = createReduxStore( 'quickwp/data', { } } }; + case 'SET_SESSION_ID': + return { + ...state, + sessionID: action.sessionID + }; case 'SET_PROCESS_STATUS': return { ...state, @@ -361,11 +401,17 @@ const store = createReduxStore( 'quickwp/data', { getSelectedImages( state ) { return state.selectedImages; }, + getTemplate( state ) { + return state.templates; + }, + getSelectedTemplate( state ) { + return state.selectedTemplate; + }, getHomepage( state ) { return state.homepage; }, - getSelectedHomepage( state ) { - return state.selectedHomepage; + getSessionID( state ) { + return state.sessionID; }, hasError( state ) { return state.hasError; diff --git a/src/utils.js b/src/utils.js index 88229fb..2a6f662 100644 --- a/src/utils.js +++ b/src/utils.js @@ -7,7 +7,6 @@ import { dispatch, select } from '@wordpress/data'; -import { home } from '@wordpress/icons'; import { Circle, @@ -116,17 +115,30 @@ const sendEvent = async( data ) => { }); setThreadID( data.step, response.thread_id ); - setRunID( data.step, response.id ); }; -const getEvent = async( type ) => { +const getEvent = async( type, params = {}) => { const threadID = select( 'quickwp/data' ).getThreadID( type ); - const route = 'homepage' !== type ? 'get' : 'templates'; + + let route = ''; + + switch ( type ) { + case 'homepage': + route = 'homepage'; + break; + case 'templates': + route = 'templates'; + break; + default: + route = 'get'; + break; + } const response = await retryApiFetch({ path: addQueryArgs( `${ window.quickwp.api }/${ route }`, { - 'thread_id': threadID + 'thread_id': threadID, + ...params }) }); @@ -273,12 +285,18 @@ export const generateImages = async() => { setProcessStatus( 'images', true ); }; -export const generateHomepage = async() => { +export const generateTemplates = async( type ) => { const siteTopic = select( 'quickwp/data' ).getSiteTopic(); const siteDescription = select( 'quickwp/data' ).getSiteDescription(); + const images = select( 'quickwp/data' ).getSelectedImages(); + const activeImageKeyword = select( 'quickwp/data' ).getActiveImageKeyword(); + const defaultImages = select( 'quickwp/data' ).getImages( activeImageKeyword ); + const homepage = select( 'quickwp/data' ).getSelectedTemplate(); + + const selectedImages = ( ! images.length && defaultImages.length ) ? defaultImages.slice( 0, 10 ) : images; - const imagesAr = images.map( image => ({ + let imagesAr = selectedImages.map( image => ({ src: image.src.original, alt: image.alt }) ); @@ -286,71 +304,93 @@ export const generateHomepage = async() => { const { setError, setProcessStatus, - setHomepage + setHomepage, + setTemplate } = dispatch( 'quickwp/data' ); - await sendEvent({ - step: 'homepage', - message: `Website topic: ${ siteTopic } | Website description: ${ siteDescription } | Images: ${ JSON.stringify( imagesAr ) }` - }); + let response; + + if ( 'homepage' === type ) { + await sendEvent({ + step: 'homepage', + message: `Website topic: ${ siteTopic } | Website description: ${ siteDescription } | Images: ${ JSON.stringify( imagesAr ) }`, + template: homepage + }); - await awaitEvent( 'homepage', 10000 ); + await awaitEvent( 'homepage', 10000 ); + + response = await getEvent( 'homepage', { + template: homepage + }); + } else { + await sendEvent({ + step: 'templates', + message: `Website topic: ${ siteTopic } | Website description: ${ siteDescription }` + }); - const response = await getEvent( 'homepage' ); + await awaitEvent( 'templates', 10000 ); + + response = await getEvent( 'templates', { + images: imagesAr + }); + } if ( 'success' !== response?.status ) { setError( true ); return; } - let homepageTemplates = []; + if ( 'homepage' === type ) { + const homepageTemplate = formatHomepage( response.data ); + + setHomepage( homepageTemplate ); + setProcessStatus( 'homepage', true ); + } else { + let homepageTemplates = []; - response.data.forEach( item => { - let homepageTemplate = formatHomepage( item.patterns ); + response.data.forEach( item => { + let homepageTemplate = formatHomepage( item.patterns ); - const template = { - slug: item.slug, - content: homepageTemplate - }; + const template = { + slug: item.slug, + content: homepageTemplate + }; - homepageTemplates.push( template ); - }); + homepageTemplates.push( template ); + }); - setHomepage( homepageTemplates ); - setProcessStatus( 'homepage', true ); + setTemplate( homepageTemplates ); + setProcessStatus( 'templates', true ); + } }; -export const saveChanges = async() => { - const { __experimentalGetDirtyEntityRecords } = select( 'core' ); - +const importTemplate = async() => { const currentTemplate = select( 'core/edit-site' ).getEditedPostId(); - const { - getHomepage, - getSelectedHomepage - } = select( 'quickwp/data' ); - - const { - editEntityRecord, - saveEditedEntityRecord - } = dispatch( 'core' ); + const { getHomepage } = select( 'quickwp/data' ); - const { setSaving } = dispatch( 'quickwp/data' ); + const { editEntityRecord } = dispatch( 'core' ); - const homepage = getSelectedHomepage(); + const homepage = getHomepage(); - const templates = getHomepage(); + await editEntityRecord( 'postType', 'wp_template', currentTemplate, { + 'content': homepage + }); +}; - const selectedHomepage = templates.find( template => template.slug === homepage ); +export const saveChanges = async() => { + const { __experimentalGetDirtyEntityRecords } = select( 'core' ); - editEntityRecord( 'postType', 'wp_template', currentTemplate, { - 'content': selectedHomepage.content - }); + const { saveEditedEntityRecord } = dispatch( 'core' ); - const edits = __experimentalGetDirtyEntityRecords(); + const { setSaving } = dispatch( 'quickwp/data' ); setSaving( true ); + importTemplate(); + + const edits = __experimentalGetDirtyEntityRecords(); + await Promise.all( edits.map( async edit => { await saveEditedEntityRecord( edit.kind, edit.name, edit?.key ); }) ); @@ -359,10 +399,72 @@ export const saveChanges = async() => { }; const formatHomepage = template => { + const slug = window.quickwp.themeSlug; let homepageTemplate = ''; - homepageTemplate += ''; + homepageTemplate += ''; homepageTemplate += template; - homepageTemplate += ''; + homepageTemplate += ''; return homepageTemplate; }; + +export const recordEvent = async( data = {}) => { + if ( ! Boolean( window.quickwp.isGuidedMode ) ) { + return; + } + + const { setSessionID } = dispatch( 'quickwp/data' ); + const { getSessionID } = select( 'quickwp/data' ); + + const trackingId = getSessionID(); + + try { + const response = await fetch( + 'https://api.themeisle.com/tracking/onboarding', + { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + _id: trackingId, + data: { + slug: 'quickwp', + // eslint-disable-next-line camelcase + license_id: 'free', + site: '', + ...data + } + }) + } + ); + + if ( ! response.ok ) { + console.error( `HTTP error! Status: ${ response.status }` ); + return false; + } + + const jsonResponse = await response.json(); + + const validCodes = [ 'success', 'invalid' ]; // Add valid codes to this array + + if ( ! validCodes.includes( jsonResponse.code ) ) { + return false; + } + + if ( 'invalid' === jsonResponse.code ) { + console.error( jsonResponse.message ); + return false; + } + const responseData = jsonResponse.data; + + if ( responseData?.id && '' === trackingId ) { + setSessionID( responseData.id ); + } + + return responseData.id || false; + } catch ( error ) { + console.error( error ); + return false; + } +};