<commit_before>/**
 * User Input Questionnaire.
 *
 * Site Kit by Google, Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * WordPress dependencies
 */
import { useCallback, useState, Fragment, useEffect } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { addQueryArgs } from '@wordpress/url';

/**
 * Internal dependencies
 */
import Data from 'googlesitekit-data';
import ProgressBar from '../ProgressBar';
import UserInputQuestionWrapper from './UserInputQuestionWrapper';
import UserInputSelectOptions from './UserInputSelectOptions';
import UserInputKeywords from './UserInputKeywords';
import UserInputPreview from './UserInputPreview';
import {
	USER_INPUT_QUESTIONS_LIST,
	USER_INPUT_QUESTION_ROLE,
	USER_INPUT_QUESTION_POST_FREQUENCY,
	USER_INPUT_QUESTION_GOALS,
	USER_INPUT_QUESTION_HELP_NEEDED,
	USER_INPUT_QUESTION_SEARCH_TERMS,
	getUserInputAnwsers,
} from './util/constants';
import useQueryArg from '../../hooks/useQueryArg';
import { STORE_NAME as CORE_USER } from '../../googlesitekit/datastore/user/constants';
import { STORE_NAME as CORE_SITE } from '../../googlesitekit/datastore/site/constants';
import { Cell, Row } from '../../material-components';
const { useSelect, useDispatch } = Data;

export default function UserInputQuestionnaire() {
	const steps = [ ...USER_INPUT_QUESTIONS_LIST, 'preview' ];

	const [ activeSlug, setActiveSlug ] = useQueryArg( 'question', steps[ 0 ] );
	const [ redirectURL ] = useQueryArg( 'redirect_url' );
	const [ single, setSingle ] = useQueryArg( 'single', false );

	const activeSlugIndex = steps.indexOf( activeSlug );

	if ( activeSlugIndex === -1 ) {
		setActiveSlug( steps[ 0 ] );
	}

	const answeredUntilIndex = useSelect( ( select ) => {
		const userInputSettings = select( CORE_USER ).getUserInputSettings();
		return USER_INPUT_QUESTIONS_LIST.findIndex( ( question ) => userInputSettings[ question ].values.length === 0 );
	} );

	useEffect( () => {
		if ( answeredUntilIndex === -1 ) {
			return;
		}
		if ( activeSlugIndex > answeredUntilIndex ) {
			setActiveSlug( steps[ answeredUntilIndex ] );
		}
	}, [ answeredUntilIndex, activeSlugIndex ] );

	const {
		USER_INPUT_ANSWERS_GOALS,
		USER_INPUT_ANSWERS_HELP_NEEDED,
		USER_INPUT_ANSWERS_POST_FREQUENCY,
		USER_INPUT_ANSWERS_ROLE,
	} = getUserInputAnwsers();

	const next = useCallback( () => {
		setActiveSlug( steps[ activeSlugIndex + 1 ] );
	}, [ activeSlugIndex ] );

	const goTo = useCallback( ( num = 1, singleType = false ) => {
		// If we're going to a single question to edit it, set the query string here.
		// We can't currently set it in the child component because the useQueryArg hook doesn't update in the parent.
		setSingle( singleType );
		if ( steps.length >= num && num > 0 ) {
			setActiveSlug( steps[ num - 1 ] );
			global.scrollTo( 0, 0 );
		}
	}, [ activeSlugIndex ] );

	const back = useCallback( () => {
		setActiveSlug( steps[ activeSlugIndex - 1 ] );
	}, [ activeSlugIndex ] );

	const [ isNavigating, setIsNavigating ] = useState( false );

	const dashboardURL = useSelect( ( select ) => select( CORE_SITE ).getAdminURL( 'googlesitekit-dashboard' ) );

	const { isSavingSettings, error } = useSelect( ( select ) => ( {
		isSavingSettings: select( CORE_USER ).isFetchingSaveUserInputSettings(),
		error: select( CORE_USER ).getErrorForAction( 'saveUserInputSettings', [] ),
	} ) );

	const { saveUserInputSettings } = useDispatch( CORE_USER );

	const submitChanges = useCallback( async () => {
		setIsNavigating( true );
		const response = await saveUserInputSettings();
		if ( ! response.error ) {
			if ( redirectURL ) {
				const url = new URL( redirectURL );
				// Here we don't use `addQueryArgs` due to a bug with how it handles hashes
				// See https://github.com/WordPress/gutenberg/issues/16655
				url.searchParams.set( 'notification', 'user_input_success' );
				global.location.assign( url.toString() );
			} else {
				global.location.assign( addQueryArgs( dashboardURL, { notification: 'user_input_success' } ) );
			}
		} else {
			setIsNavigating( false );
		}
	}, [ dashboardURL ] );

	const goToPreview = useCallback( () => {
		setActiveSlug( steps[ steps.length - 1 ] );
	}, [ activeSlugIndex ] );

	// Update the callbacks and labels for the questions if the user is editing a *single question*.
	let backCallback = back;
	let nextCallback = next;
	let nextLabel;

	if ( single === 'user-input' ) {
		backCallback = undefined;
		// When the user is editing a single question in the user-input screen send them back to the preview when they click Update.
		nextCallback = goToPreview;
		nextLabel = __( 'Update', 'google-site-kit' );
	} else if ( single === 'settings' ) {
		backCallback = undefined;
		// When the user is editing a single question from the settings screen, submit changes and send them back to the settings pages when they click Submit.
		nextCallback = submitChanges;
		nextLabel = __( 'Submit', 'google-site-kit' );
	}

	if ( isSavingSettings || isNavigating ) {
		return (
			<Fragment>
				<ProgressBar
					height={ 0 }
					indeterminate={ false }
					progress={ ( activeSlugIndex + 1 ) / USER_INPUT_QUESTIONS_LIST.length }
				/>
				<div className="googlesitekit-user-input__preview">
					<Row>
						<Cell lgSize={ 12 } mdSize={ 8 } smSize={ 4 }>
							<ProgressBar />
						</Cell>
					</Row>
				</div>
			</Fragment>
		);
	}

	return (
		<Fragment>
			<ProgressBar
				height={ 0 }
				indeterminate={ false }
				progress={ ( activeSlugIndex + 1 ) / USER_INPUT_QUESTIONS_LIST.length }
			/>

			{ activeSlugIndex <= steps.indexOf( USER_INPUT_QUESTION_ROLE ) && (
				<UserInputQuestionWrapper
					slug={ USER_INPUT_QUESTION_ROLE }
					isActive={ activeSlug === USER_INPUT_QUESTION_ROLE }
					questionNumber={ 1 }<commit_msg>Move duplicate ProgressBar into a variable.<commit_after>/**
 * User Input Questionnaire.
 *
 * Site Kit by Google, Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * WordPress dependencies
 */
import { useCallback, useState, Fragment, useEffect } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { addQueryArgs } from '@wordpress/url';

/**
 * Internal dependencies
 */
import Data from 'googlesitekit-data';
import ProgressBar from '../ProgressBar';
import UserInputQuestionWrapper from './UserInputQuestionWrapper';
import UserInputSelectOptions from './UserInputSelectOptions';
import UserInputKeywords from './UserInputKeywords';
import UserInputPreview from './UserInputPreview';
import {
	USER_INPUT_QUESTIONS_LIST,
	USER_INPUT_QUESTION_ROLE,
	USER_INPUT_QUESTION_POST_FREQUENCY,
	USER_INPUT_QUESTION_GOALS,
	USER_INPUT_QUESTION_HELP_NEEDED,
	USER_INPUT_QUESTION_SEARCH_TERMS,
	getUserInputAnwsers,
} from './util/constants';
import useQueryArg from '../../hooks/useQueryArg';
import { STORE_NAME as CORE_USER } from '../../googlesitekit/datastore/user/constants';
import { STORE_NAME as CORE_SITE } from '../../googlesitekit/datastore/site/constants';
import { Cell, Row } from '../../material-components';
const { useSelect, useDispatch } = Data;

export default function UserInputQuestionnaire() {
	const steps = [ ...USER_INPUT_QUESTIONS_LIST, 'preview' ];

	const [ activeSlug, setActiveSlug ] = useQueryArg( 'question', steps[ 0 ] );
	const [ redirectURL ] = useQueryArg( 'redirect_url' );
	const [ single, setSingle ] = useQueryArg( 'single', false );

	const activeSlugIndex = steps.indexOf( activeSlug );

	if ( activeSlugIndex === -1 ) {
		setActiveSlug( steps[ 0 ] );
	}

	const answeredUntilIndex = useSelect( ( select ) => {
		const userInputSettings = select( CORE_USER ).getUserInputSettings();
		return USER_INPUT_QUESTIONS_LIST.findIndex( ( question ) => userInputSettings[ question ].values.length === 0 );
	} );

	useEffect( () => {
		if ( answeredUntilIndex === -1 ) {
			return;
		}
		if ( activeSlugIndex > answeredUntilIndex ) {
			setActiveSlug( steps[ answeredUntilIndex ] );
		}
	}, [ answeredUntilIndex, activeSlugIndex ] );

	const {
		USER_INPUT_ANSWERS_GOALS,
		USER_INPUT_ANSWERS_HELP_NEEDED,
		USER_INPUT_ANSWERS_POST_FREQUENCY,
		USER_INPUT_ANSWERS_ROLE,
	} = getUserInputAnwsers();

	const next = useCallback( () => {
		setActiveSlug( steps[ activeSlugIndex + 1 ] );
	}, [ activeSlugIndex ] );

	const goTo = useCallback( ( num = 1, singleType = false ) => {
		// If we're going to a single question to edit it, set the query string here.
		// We can't currently set it in the child component because the useQueryArg hook doesn't update in the parent.
		setSingle( singleType );
		if ( steps.length >= num && num > 0 ) {
			setActiveSlug( steps[ num - 1 ] );
			global.scrollTo( 0, 0 );
		}
	}, [ activeSlugIndex ] );

	const back = useCallback( () => {
		setActiveSlug( steps[ activeSlugIndex - 1 ] );
	}, [ activeSlugIndex ] );

	const [ isNavigating, setIsNavigating ] = useState( false );

	const dashboardURL = useSelect( ( select ) => select( CORE_SITE ).getAdminURL( 'googlesitekit-dashboard' ) );

	const { isSavingSettings, error } = useSelect( ( select ) => ( {
		isSavingSettings: select( CORE_USER ).isFetchingSaveUserInputSettings(),
		error: select( CORE_USER ).getErrorForAction( 'saveUserInputSettings', [] ),
	} ) );

	const { saveUserInputSettings } = useDispatch( CORE_USER );

	const submitChanges = useCallback( async () => {
		setIsNavigating( true );
		const response = await saveUserInputSettings();
		if ( ! response.error ) {
			if ( redirectURL ) {
				const url = new URL( redirectURL );
				// Here we don't use `addQueryArgs` due to a bug with how it handles hashes
				// See https://github.com/WordPress/gutenberg/issues/16655
				url.searchParams.set( 'notification', 'user_input_success' );
				global.location.assign( url.toString() );
			} else {
				global.location.assign( addQueryArgs( dashboardURL, { notification: 'user_input_success' } ) );
			}
		} else {
			setIsNavigating( false );
		}
	}, [ dashboardURL ] );

	const goToPreview = useCallback( () => {
		setActiveSlug( steps[ steps.length - 1 ] );
	}, [ activeSlugIndex ] );

	// Update the callbacks and labels for the questions if the user is editing a *single question*.
	let backCallback = back;
	let nextCallback = next;
	let nextLabel;

	if ( single === 'user-input' ) {
		backCallback = undefined;
		// When the user is editing a single question in the user-input screen send them back to the preview when they click Update.
		nextCallback = goToPreview;
		nextLabel = __( 'Update', 'google-site-kit' );
	} else if ( single === 'settings' ) {
		backCallback = undefined;
		// When the user is editing a single question from the settings screen, submit changes and send them back to the settings pages when they click Submit.
		nextCallback = submitChanges;
		nextLabel = __( 'Submit', 'google-site-kit' );
	}

	const settingsProgress = (
		<ProgressBar
			height={ 0 }
			indeterminate={ false }
			progress={ ( activeSlugIndex + 1 ) / USER_INPUT_QUESTIONS_LIST.length }
		/>
	);

	if ( isSavingSettings || isNavigating ) {
		return (
			<Fragment>
				{ settingsProgress }
				<div className="googlesitekit-user-input__preview">
					<Row>
						<Cell lgSize={ 12 } mdSize={ 8 } smSize={ 4 }>
							<ProgressBar />
						</Cell>
					</Row>
				</div>
			</Fragment>
		);
	}

	return (
		<Fragment>
			{ settingsProgress }

			{ activeSlugIndex <= steps.indexOf( USER_INPUT_QUESTION_ROLE ) && (
				<UserInputQuestionWrapper
					slug={ USER_INPUT_QUESTION_ROLE }
					isActive={ activeSlug === USER_INPUT_QUESTION_ROLE }
					questionNumber={ 1 }
{'fraction_non_alphanumeric': 0.11888278825495345, 'fraction_numerical': 0.005729291000238721, 'mean_word_length': 3.9286274509803922, 'pattern_counts': {'":': 0, '<': 30, '<?xml version=': 0, '>': 52, 'https://': 4, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1788596', 'n_tokens_mistral': 4276, 'n_tokens_neox': 3831, 'n_words': 1082}