import { CSSProperties } from 'react'; import { QuizResultData, NextQuestionResponse, QuizResultsResponse, QuestionOption, QuizResultsConfig, QuizzesResultsParameters, QuizzesParameters } from '@constructor-io/constructorio-client-javascript/lib/types'; import { Question } from '@constructor-io/constructorio-client-javascript/lib/types/quizzes'; import ConstructorIOClient, { GetBrowseResultsForItemIdsResponse } from '@constructor-io/constructorio-client-javascript'; import { RequestStates } from './constants'; import { QuestionTypes } from './components/CioQuiz/actions'; export type { QuestionOption, FilterQuestionOption, QuestionImages, NextQuestionResponse, QuizResultsResponse, QuizResultsConfigResponse, QuizResultsConfig, BrowseResultData, BrowseRequestType, QuizzesParameters, QuizzesResultsParameters, } from '@constructor-io/constructorio-client-javascript/lib/types/'; export type { Question } from '@constructor-io/constructorio-client-javascript/lib/types/quizzes'; export type QuizResultDataPartial = Partial; export type QuizEmailResults = { email: string; url: string; results?: Partial[]; }; export type RenderResultCard = (result: QuizResultDataPartial, getters: { getAddToCartButtonProps?: GetAddToCartButtonProps; getAddToFavoritesButtonProps?: GetAddToFavoritesButtonProps; getQuizResultLinkProps?: GetQuizResultLinkProps; getQuizResultButtonProps?: GetQuizResultButtonProps; getQuizResultSwatchProps?: GetQuizResultSwatchProps; }, resultPosition: number) => JSX.Element; export interface ResultCardOptions { resultCardSalePriceKey?: string; resultCardRegularPriceKey?: string; resultCardRatingCountKey?: string; resultCardRatingScoreKey?: string; swatchImageKey?: string; renderResultCardPriceDetails?: (result: QuizResultDataPartial) => JSX.Element; renderResultCard?: RenderResultCard; getResultCardImageUrl?: (result: QuizResultDataPartial) => string; } export declare namespace QuizResultsEventsProps { type OnQuizResultsLoaded = (results: QuizResultDataPartial) => void; type OnQuizResultClick = (result: QuizResultDataPartial, position: number) => void; type OnAddToCartClick = (result: QuizResultDataPartial) => void; type OnAddToFavoritesClick = (result: QuizResultDataPartial) => void; type OnQuizNextQuestion = (question: QuestionWithAnswer) => void; type OnQuizSkipQuestion = (question: QuestionWithAnswer) => void; type OnEmailResults = (data: QuizEmailResults) => Promise; type OnShareResultsModalOpen = () => void; type OnShareResultsModalClose = () => void; type OnQuizResultsConfigLoaded = (resultsConfig?: QuizResultsConfig | null, metadata?: object | null) => void; } export type QuizResultsRequestConfigs = Omit; export interface ResultsPageOptions { numResultsToDisplay?: number; favoriteItems?: string[]; showShareResultsButton?: boolean; requestConfigs?: QuizResultsRequestConfigs; } export interface QuestionsPageOptions { skipQuestionButtonText?: string; nextQuestionOnSingleSelect?: boolean; } export interface SessionStateOptions { showSessionModal?: boolean; showSessionModalOnResults?: boolean; sessionStateKey?: string; } export type QuestionWithAnswer = Question & { answer: AnswerInput; }; export interface Callbacks { onQuizNextQuestion?: QuizResultsEventsProps.OnQuizNextQuestion; onQuizResultsLoaded?: QuizResultsEventsProps.OnQuizResultsLoaded; onQuizResultClick?: QuizResultsEventsProps.OnQuizResultClick; onAddToCartClick: QuizResultsEventsProps.OnAddToCartClick; onAddToFavoritesClick?: QuizResultsEventsProps.OnAddToFavoritesClick; onQuizSkipQuestion?: QuizResultsEventsProps.OnQuizSkipQuestion; onEmailResults?: QuizResultsEventsProps.OnEmailResults; onShareResultsModalOpen?: QuizResultsEventsProps.OnShareResultsModalOpen; onShareResultsModalClose?: QuizResultsEventsProps.OnShareResultsModalClose; onQuizResultsConfigLoaded?: QuizResultsEventsProps.OnQuizResultsConfigLoaded; } export interface IQuizProps { apiKey?: string; cioJsClient?: ConstructorIOClient; quizId: string; quizVersionId?: string; resultsPageOptions?: ResultsPageOptions; resultCardOptions?: ResultCardOptions; sessionStateOptions?: SessionStateOptions; primaryColor?: string; enableHydration?: boolean; callbacks: Callbacks; questionsPageOptions?: QuestionsPageOptions; } export interface QuizReturnState { answers: { inputs: AnswerInputState; payload: string[][]; }; quiz: { requestState: RequestStates; versionId?: string; sessionId?: string; currentQuestion?: CurrentQuestion | undefined; results?: QuizResultsResponse | QuizSharedResultsData | undefined; selectedOptionsWithAttributes?: string[]; matchedOptions?: string[]; resultsConfig: QuizResultsConfig | null; metadata?: object | null; }; quizSessionStorageState: QuizSessionStorageState; } export type AnswerInput = { type: InputQuestionsTypes; value: string | Omit[] | null; }; export type AnswerInputState = { [key: string]: AnswerInput; }; export interface QuizSessionStorageState { key: string; skipToResults: boolean; hasSessionStorageState: () => boolean; } export type InputQuestionsTypes = QuestionTypes.OpenText | QuestionTypes.Cover | QuestionTypes.SingleSelect | QuestionTypes.MultipleSelect | QuestionTypes.SingleFilterValue | QuestionTypes.MultipleFilterValues | QuestionTypes.FreeForm; export type CurrentQuestion = NextQuestionResponse & { isFirstQuestion: boolean; isOpenQuestion: boolean; isCoverQuestion: boolean; isSingleQuestion: boolean; isMultipleQuestion: boolean; isSingleFilterQuestion: boolean; isMultipleFilterQuestion: boolean; isFreeFormQuestion: boolean; isSelectQuestion: boolean; }; export declare namespace QuizEventsReturn { type QuizAnswerChanged = (payload?: string | Omit[]) => void; type NextQuestion = () => void; type SkipQuestion = () => void; type PreviousQuestion = () => void; type ResetQuiz = () => void; type JumpToQuestion = (questionId: number) => void; type ResultClick = (result: QuizResultDataPartial, position: number) => void; type AddToCart = (e: React.MouseEvent, result: QuizResultDataPartial, price?: number | string) => void; type AddToFavorites = (e: React.MouseEvent, result: QuizResultDataPartial, price?: number | string, sendEvent?: boolean) => void; type HydrateQuiz = () => void; type ResetSessionStorageState = () => void; } export interface QuizEventsReturn { nextQuestion: QuizEventsReturn.NextQuestion; skipQuestion: QuizEventsReturn.SkipQuestion; jumpToQuestion: QuizEventsReturn.JumpToQuestion; quizAnswerChanged: QuizEventsReturn.QuizAnswerChanged; previousQuestion: QuizEventsReturn.PreviousQuestion; resetQuiz: QuizEventsReturn.ResetQuiz; resultClick: QuizEventsReturn.ResultClick; addToCart: QuizEventsReturn.AddToCart; addToFavorites: QuizEventsReturn.AddToFavorites; hydrateQuiz: QuizEventsReturn.HydrateQuiz; resetSessionStorageState: QuizEventsReturn.ResetSessionStorageState; } export interface OpenTextInputProps { className: string; placeholder: string; value: string; onChange: React.ChangeEventHandler; onKeyDown: React.KeyboardEventHandler; } export interface QuizSharedResultsData extends GetBrowseResultsForItemIdsResponse { attributes: string[]; } export interface CoverQuestionProps { } export interface NextQuestionButtonProps extends React.DetailedHTMLProps, HTMLButtonElement> { className: string; type: 'submit' | 'reset' | 'button' | undefined; disabled?: boolean; onClick: React.MouseEventHandler; } export interface SkipQuestionButtonProps { className: string; type: 'submit' | 'reset' | 'button' | undefined; disabled?: boolean; onClick: React.MouseEventHandler; } export interface PreviousQuestionButtonProps { className: string; type: 'submit' | 'reset' | 'button' | undefined; onClick: React.MouseEventHandler; style?: Record; role?: string; title?: string; } export interface ResetQuizButtonProps { className: string; type: 'submit' | 'reset' | 'button' | undefined; onClick: React.MouseEventHandler; style?: Record; } export interface ShareResultsButtonProps { className: string; onClick?: React.MouseEventHandler; style?: CSSProperties; } export interface HydrateQuizButtonProps { className: string; type: 'submit' | 'reset' | 'button' | undefined; onClick: React.MouseEventHandler; style?: Record; } export interface AddToCartButtonProps { className: string; type: 'submit' | 'reset' | 'button' | undefined; onClick: React.MouseEventHandler; style?: Record; } export interface QuizImageProps { className?: string; src?: string; alt?: string; } export interface QuizResultPropsLink { href?: string; onClick: React.MouseEventHandler; onKeyDown: React.KeyboardEventHandler; } export interface QuizResultPropsButton { className: string; role: 'button'; tabIndex: number; onClick: React.MouseEventHandler; onKeyDown: React.KeyboardEventHandler; } export type QuizResultProps = QuizResultPropsLink | QuizResultPropsButton; export interface SelectInputProps { className: string; onClick: React.MouseEventHandler; onKeyDown: React.KeyboardEventHandler; role: 'button'; tabIndex: number; key: number | string; } export interface JumpToQuestionButtonProps { className: string; onClick: React.MouseEventHandler; style?: Record; } export type GetOpenTextInputProps = () => OpenTextInputProps; export type GetCoverQuestionProps = () => CoverQuestionProps; export type GetSelectInputProps = (option: QuestionOption) => SelectInputProps; export type GetNextQuestionButtonProps = () => NextQuestionButtonProps; export type GetSkipQuestionButtonProps = () => SkipQuestionButtonProps; export type GetPreviousQuestionButtonProps = () => PreviousQuestionButtonProps; export type GetJumpToQuestionButtonProps = (id: number) => JumpToQuestionButtonProps; export type GetResetQuizButtonProps = (stylesType?: 'primary' | 'secondary') => ResetQuizButtonProps; export type GetShareResultsButtonProps = () => ShareResultsButtonProps; export type GetHydrateQuizButtonProps = () => HydrateQuizButtonProps; export type GetAddToCartButtonProps = (result: QuizResultDataPartial, price?: number | string) => AddToCartButtonProps; export type GetAddToFavoritesButtonProps = (result: QuizResultDataPartial, price?: number | string, clickHandler?: () => void) => AddToCartButtonProps; export type GetQuizImageProps = () => QuizImageProps; export type GetSelectQuestionImageProps = (option: QuestionOption) => QuizImageProps; export type GetQuizResultSwatchProps = (variation: QuizResultDataPartial) => React.DetailedHTMLProps, HTMLButtonElement>; export interface QuizResultOptions { result: QuizResultDataPartial; position: number; type?: T; } export type GetQuizResultButtonProps = (options: QuizResultOptions<'button'>) => QuizResultPropsButton; export type GetQuizResultLinkProps = (options: QuizResultOptions<'link'>) => QuizResultPropsLink; export interface PrimaryColorStyles { '--primary-color-h': string; '--primary-color-s': string; '--primary-color-l': string; } export interface UseQuizReturn { cioClient?: ConstructorIOClient; state: QuizReturnState; events: QuizEventsReturn; getOpenTextInputProps: GetOpenTextInputProps; getNextQuestionButtonProps: GetNextQuestionButtonProps; getSkipQuestionButtonProps: GetSkipQuestionButtonProps; getPreviousQuestionButtonProps: GetPreviousQuestionButtonProps; getQuizImageProps: GetQuizImageProps; getSelectQuestionImageProps: GetSelectQuestionImageProps; getSelectInputProps: GetSelectInputProps; getCoverQuestionProps: GetCoverQuestionProps; getResetQuizButtonProps: GetResetQuizButtonProps; getShareResultsButtonProps: GetShareResultsButtonProps; getHydrateQuizButtonProps: GetHydrateQuizButtonProps; getAddToCartButtonProps: GetAddToCartButtonProps; getAddToFavoritesButtonProps: GetAddToFavoritesButtonProps; getQuizResultButtonProps: GetQuizResultButtonProps; getQuizResultLinkProps: GetQuizResultLinkProps; getJumpToQuestionButtonProps: GetJumpToQuestionButtonProps; primaryColorStyles: PrimaryColorStyles; } export type UseQuiz = (quizProps: IQuizProps) => UseQuizReturn;