1 |
- {"version":3,"file":"static/chunks/70303-a0c4b54a578e5639.js","mappings":"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","sources":["webpack://_N_E/./public/icons/book.svg","webpack://_N_E/./public/icons/caret-down.svg","webpack://_N_E/./public/icons/clock.svg","webpack://_N_E/./src/components/Auth/RedirectToLoginPage.tsx","webpack://_N_E/./src/components/Auth/withAuth.tsx","webpack://_N_E/./src/components/DataFetcher/index.tsx","webpack://_N_E/./public/icons/retry.svg","webpack://_N_E/./src/components/Error/index.tsx","webpack://_N_E/./src/components/NextSeoWrapper.tsx","webpack://_N_E/./src/components/ReadingGoal/ReadingGoalInput/VerseRangeInput.tsx","webpack://_N_E/./src/components/ReadingGoal/ReadingGoalInput/index.tsx","webpack://_N_E/./src/components/ReadingGoalPage/utils/validator.ts","webpack://_N_E/./src/components/dls/Forms/Input/index.tsx","webpack://_N_E/./src/components/dls/Forms/Select/index.tsx","webpack://_N_E/./src/components/dls/Popover/HoverablePopover/index.tsx","webpack://_N_E/./src/components/dls/Popover/index.tsx","webpack://_N_E/./src/hooks/useGetMushaf.ts","webpack://_N_E/./src/utils/generators.ts","webpack://_N_E/./src/utils/page.ts","webpack://_N_E/./src/utils/string.ts","webpack://_N_E/./src/utils/validator.ts","webpack://_N_E/./src/components/Error/Error.module.scss","webpack://_N_E/./src/components/ReadingGoal/ReadingGoalInput/ReadingGoalInput.module.scss","webpack://_N_E/./src/components/dls/Forms/Input/Input.module.scss","webpack://_N_E/./src/components/dls/Forms/Select/Select.module.scss","webpack://_N_E/./src/components/dls/Popover/Popover.module.scss"],"sourcesContent":["var _path, _path2;\nfunction _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }\nimport * as React from \"react\";\nvar SvgBook = function SvgBook(props) {\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n xmlns: \"http://www.w3.org/2000/svg\",\n width: 24,\n height: 24,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n className: \"feather feather-book\"\n }, props), _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M4 19.5A2.5 2.5 0 0 1 6.5 17H20\"\n })), _path2 || (_path2 = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z\"\n })));\n};\nexport default SvgBook;","var _path;\nfunction _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }\nimport * as React from \"react\";\nvar SvgCaretDown = function SvgCaretDown(props) {\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n viewBox: \"0 0 24 24\",\n width: 18,\n height: 18,\n stroke: \"currentColor\",\n strokeWidth: 1.5,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n fill: \"none\",\n shapeRendering: \"geometricPrecision\",\n style: {\n color: \"currentcolor\"\n }\n }, props), _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n d: \"m6 9 6 6 6-6\"\n })));\n};\nexport default SvgCaretDown;","var _path;\nfunction _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }\nimport * as React from \"react\";\nvar SvgClock = function SvgClock(props) {\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n className: \"w-6 h-6\"\n }, props), _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0z\"\n })));\n};\nexport default SvgClock;","import React, { useEffect } from 'react';\n\nimport { useRouter } from 'next/router';\n\nimport { getLoginNavigationUrl } from '@/utils/navigation';\n\nconst RedirectToLoginPage = () => {\n const router = useRouter();\n useEffect(() => {\n const { asPath } = router;\n router.replace(getLoginNavigationUrl(asPath));\n }, [router]);\n\n return <></>;\n};\n\nexport default RedirectToLoginPage;\n","import { JSX, useEffect, useState } from 'react';\n\nimport RedirectToLoginPage from './RedirectToLoginPage';\n\nimport { isLoggedIn } from '@/utils/auth/login';\n/**\n * withAuth is a Higher-Order Component (HOC) that wraps a component and checks if the user is authenticated.\n * If the user is authenticated, it renders the wrapped component.\n * If the user is not authenticated, it redirects the user to the login page.\n *\n * @param {React.ComponentType} WrappedComponent - The component to wrap and protect with authentication check.\n *\n * @returns {React.ComponentType} If the user is authenticated, returns the WrappedComponent.\n * If not, returns RedirectToLoginPage component.\n *\n * @example\n * const ProtectedComponent = withAuth(MyComponent);\n */\nconst withAuth = (WrappedComponent: React.ComponentType): React.ComponentType => {\n const WithAuth = (props: JSX.IntrinsicAttributes) => {\n const [isReady, setIsReady] = useState(false);\n\n /**\n * we need to wait for the initial render to check if the user is authenticated\n * because when it's server-side rendered, the user is not authenticated yet\n */\n useEffect(() => {\n setIsReady(true);\n }, []);\n\n if (!isReady) {\n return null; // or return a loading spinner\n }\n\n return isLoggedIn() ? <WrappedComponent {...props} /> : <RedirectToLoginPage />;\n };\n\n return WithAuth;\n};\n\nexport default withAuth;\n","import React, { memo } from 'react';\n\nimport useSWRImmutable from 'swr/immutable';\n\nimport Error from '@/components/Error';\nimport Spinner from '@/dls/Spinner/Spinner';\nimport { fetcher } from 'src/api';\nimport { BaseResponse } from 'types/ApiResponses';\n\ninterface Props {\n queryKey: string;\n render: (data: BaseResponse) => JSX.Element;\n renderError?: (error: any) => JSX.Element | undefined;\n initialData?: BaseResponse;\n loading?: () => JSX.Element;\n fetcher?: (queryKey: string) => Promise<BaseResponse>;\n showSpinnerOnRevalidate?: boolean;\n onFetchSuccess?: (data: BaseResponse) => void;\n}\n\n/**\n * Data fetcher is a dynamic component that serves as a container for a component\n * that depends on data from a remote API to render. This component handles:\n * 1. Calling the API.\n * 2. Caching the response (due to using useSwr).\n * 3. Handling errors if any by showing an error message.\n * 4. Handling when the user is offline while trying to fetch the API response.\n * 5. Dynamically passing the response data through render-props to the parent.\n *\n * @param {Props} props\n * @returns {JSX.Element}\n */\nconst DataFetcher: React.FC<Props> = ({\n queryKey,\n render,\n renderError,\n initialData,\n loading = () => <Spinner />,\n fetcher: dataFetcher = fetcher,\n showSpinnerOnRevalidate = true,\n onFetchSuccess,\n}: Props): JSX.Element => {\n const { data, error, isValidating, mutate } = useSWRImmutable(\n queryKey,\n () =>\n dataFetcher(queryKey)\n .then((res) => {\n onFetchSuccess?.(res);\n return Promise.resolve(res);\n })\n .catch((err) => Promise.reject(err)),\n {\n fallbackData: initialData,\n },\n );\n\n // if showSpinnerOnRevalidate is true, we should show the spinner if we are revalidating the data.\n // otherwise, we should only show the spinner on initial loads.\n if (showSpinnerOnRevalidate ? isValidating : isValidating && !data) {\n return loading();\n }\n\n const onRetryClicked = () => {\n mutate();\n };\n\n /**\n * if we haven't fetched the data yet and the device is not online (because we don't want to show an offline message if the data already exists).\n * or if we had an error when calling the API.\n */\n if (error) {\n // if there is a custom error renderer, use it.\n if (renderError) {\n const errorComponent = renderError(error);\n // if the custom error renderer returns false, it means that it doesn't want to render anything special.\n if (typeof errorComponent !== 'undefined') {\n return errorComponent;\n }\n }\n return <Error onRetryClicked={onRetryClicked} error={error} />;\n }\n\n return render(data);\n};\n\nexport default memo(DataFetcher);\n","var _path;\nfunction _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }\nimport * as React from \"react\";\nvar SvgRetry = function SvgRetry(props) {\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n width: 15,\n height: 15,\n viewBox: \"0 0 15 15\",\n fill: \"none\",\n xmlns: \"http://www.w3.org/2000/svg\"\n }, props), _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M1.85 7.5c0-2.835 2.21-5.65 5.65-5.65 2.778 0 4.152 2.056 4.737 3.15H10.5a.5.5 0 0 0 0 1h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-1 0v1.813C12.296 3.071 10.666.85 7.5.85 3.437.85.85 4.185.85 7.5c0 3.315 2.587 6.65 6.65 6.65 1.944 0 3.562-.77 4.714-1.942a6.77 6.77 0 0 0 1.428-2.167.5.5 0 1 0-.925-.38 5.77 5.77 0 0 1-1.216 1.846c-.971.99-2.336 1.643-4.001 1.643-3.44 0-5.65-2.815-5.65-5.65Z\",\n fill: \"currentColor\",\n fillRule: \"evenodd\",\n clipRule: \"evenodd\"\n })));\n};\nexport default SvgRetry;","import React from 'react';\n\nimport useTranslation from 'next-translate/useTranslation';\n\nimport styles from './Error.module.scss';\n\nimport Button, { ButtonSize, ButtonType } from '@/dls/Button/Button';\nimport RetryIcon from '@/icons/retry.svg';\nimport { OFFLINE_ERROR } from 'src/api';\n\ninterface Props {\n onRetryClicked: () => void;\n error: Error;\n}\n\nconst Error: React.FC<Props> = ({ onRetryClicked, error }) => {\n const { t } = useTranslation('common');\n return (\n <div className={styles.container}>\n <p className={styles.text}>\n {error.message !== OFFLINE_ERROR ? t('error.general') : t('error.offline')}\n </p>\n <Button\n prefix={<RetryIcon />}\n size={ButtonSize.Small}\n type={ButtonType.Secondary}\n onClick={onRetryClicked}\n >\n {t('retry')}\n </Button>\n </div>\n );\n};\n\nexport default Error;\n","import React from 'react';\n\nimport { NextSeo } from 'next-seo';\n\nimport { SEOProps } from '@/utils/seo';\nimport { truncateString } from '@/utils/string';\n\ninterface Props extends SEOProps {\n url?: string;\n image?: string;\n imageAlt?: string;\n imageWidth?: number;\n imageHeight?: number;\n}\n\nconst NextSeoWrapper: React.FC<Props> = (props) => {\n const { url, image, imageAlt, imageHeight, imageWidth, openGraph, description, ...rest } = props;\n const openGraphParams = {\n ...(openGraph && { openGraph }),\n ...(url && { url }),\n ...(image && {\n images: [{ url: image, width: imageWidth, height: imageHeight, alt: imageAlt }],\n }),\n };\n const params = {\n ...rest,\n ...(description && { description: truncateString(description, 150) }),\n };\n return <NextSeo {...params} openGraph={openGraphParams} />;\n};\n\nexport default NextSeoWrapper;\n","/* eslint-disable max-lines */\nimport { useContext, useMemo, useState } from 'react';\n\nimport useTranslation from 'next-translate/useTranslation';\n\nimport styles from './ReadingGoalInput.module.scss';\n\nimport DataContext from '@/contexts/DataContext';\nimport Combobox from '@/dls/Forms/Combobox';\nimport ComboboxSize from '@/dls/Forms/Combobox/types/ComboboxSize';\nimport { RangeItem, RangeItemPosition } from '@/types/Range';\nimport { generateChapterOptions, generateVerseOptions } from '@/utils/generators';\nimport { getChapterNumberFromKey, getVerseNumberFromKey, makeVerseKey } from '@/utils/verse';\n\ninterface VerseRangesInputProps {\n rangeStartVerse?: string;\n rangeEndVerse?: string;\n onRangeChange: (range: { startVerse: string | null; endVerse: string | null }) => void;\n\n logChange?: (\n field: 'start_verse' | 'end_verse',\n data: { currentValue: string | null; newValue: string | null },\n extraData?: {\n chapter: string | null;\n verse: string | null;\n },\n ) => void;\n}\n\nconst VerseRangeInput = ({\n rangeStartVerse,\n rangeEndVerse,\n onRangeChange,\n logChange,\n}: VerseRangesInputProps) => {\n const { t, lang } = useTranslation('reading-goal');\n const chaptersData = useContext(DataContext);\n\n const [startChapter, setStartChapter] = useState<string>(\n rangeStartVerse ? getChapterNumberFromKey(rangeStartVerse).toString() : undefined,\n );\n\n const [endChapter, setEndChapter] = useState<string>(\n rangeEndVerse ? getChapterNumberFromKey(rangeEndVerse).toString() : undefined,\n );\n\n const chapterOptions = useMemo(\n () => generateChapterOptions(chaptersData, lang),\n [chaptersData, lang],\n );\n\n const startingVerseOptions = useMemo(\n () => generateVerseOptions(chaptersData, t, lang, startChapter),\n [t, lang, chaptersData, startChapter],\n );\n\n const endingVerseOptions = useMemo(\n () => generateVerseOptions(chaptersData, t, lang, endChapter),\n [t, lang, chaptersData, endChapter],\n );\n\n // useEffect(() => {\n // if (!rangeStartVerse) {\n // setStartChapter(undefined);\n // }\n // }, [rangeStartVerse]);\n\n // useEffect(() => {\n // if (!rangeEndVerse) {\n // setEndChapter(undefined);\n // }\n // }, [rangeEndVerse]);\n\n const endingVerse = useMemo(() => {\n if (!rangeEndVerse) return undefined;\n return getVerseNumberFromKey(rangeEndVerse).toString();\n }, [rangeEndVerse]);\n\n const startingVerse = useMemo(() => {\n if (!rangeStartVerse) return undefined;\n return getVerseNumberFromKey(rangeStartVerse).toString();\n }, [rangeStartVerse]);\n\n // eslint-disable-next-line react-func/max-lines-per-function\n const onChapterChange = (chapterPosition: RangeItemPosition) => (chapterId: string) => {\n const isStartChapter = chapterPosition === RangeItemPosition.Start;\n const oldChapterId = isStartChapter ? startChapter : endChapter;\n const setChapter = isStartChapter ? setStartChapter : setEndChapter;\n\n if (!chapterId || chapterId !== oldChapterId) {\n onRangeChange(\n isStartChapter\n ? { startVerse: null, endVerse: rangeEndVerse }\n : {\n startVerse: rangeStartVerse,\n endVerse: null,\n },\n );\n }\n\n // if the current value is null, we don't need to log it\n const currentVerse = isStartChapter ? rangeStartVerse : rangeEndVerse;\n if (currentVerse && logChange) {\n logChange(\n isStartChapter ? 'start_verse' : 'end_verse',\n {\n currentValue: currentVerse,\n newValue: null,\n },\n {\n chapter: chapterId || null,\n verse: (isStartChapter ? startingVerse : endingVerse) || null,\n },\n );\n }\n\n if (!chapterId) {\n setChapter(undefined);\n } else {\n setChapter(chapterId);\n }\n };\n\n const startChapterOptions = useMemo(() => {\n if (!endChapter) return chapterOptions;\n\n const endChapterIdx = Number(endChapter) - 1;\n\n return chapterOptions.slice(0, endChapterIdx + 1);\n }, [chapterOptions, endChapter]);\n\n const endChapterOptions = useMemo(() => {\n if (!startChapter) return chapterOptions;\n\n const startChapterIdx = Number(startChapter) - 1;\n\n return chapterOptions.slice(startChapterIdx);\n }, [chapterOptions, startChapter]);\n\n const onVerseChange = (versePosition: RangeItemPosition) => (verseId: string) => {\n const isStartVerse = versePosition === RangeItemPosition.Start;\n\n const newVerseKey = verseId\n ? makeVerseKey(isStartVerse ? startChapter : endChapter, verseId)\n : null;\n\n onRangeChange(\n isStartVerse\n ? { startVerse: newVerseKey, endVerse: rangeEndVerse }\n : {\n startVerse: rangeStartVerse,\n endVerse: newVerseKey,\n },\n );\n\n if (logChange) {\n logChange(\n isStartVerse ? 'start_verse' : 'end_verse',\n {\n currentValue: isStartVerse ? rangeStartVerse : rangeEndVerse,\n newValue: newVerseKey,\n },\n {\n chapter: (isStartVerse ? startChapter : endChapter) || null,\n verse: verseId || null,\n },\n );\n }\n };\n\n const getInitialInputValue = (inputType: RangeItem) => {\n if (inputType === RangeItem.StartingChapter || inputType === RangeItem.EndingChapter) {\n const chapterId = inputType === RangeItem.StartingChapter ? startChapter : endChapter;\n if (!chapterId) return undefined;\n\n return chapterOptions[Number(chapterId) - 1]?.label;\n }\n\n const verseId = inputType === RangeItem.StartingVerse ? startingVerse : endingVerse;\n if (!verseId) return '';\n\n const verseOptions =\n inputType === RangeItem.StartingVerse ? startingVerseOptions : endingVerseOptions;\n return verseOptions[Number(verseId) - 1]?.label;\n };\n\n return (\n <>\n <div className={styles.rangeInputContainer}>\n <div>\n <Combobox\n id=\"start-chapter\"\n size={ComboboxSize.Large}\n fixedWidth={false}\n label={<p className={styles.label}>{t('starting-chapter')}</p>}\n items={startChapterOptions}\n value={startChapter}\n initialInputValue={getInitialInputValue(RangeItem.StartingChapter)}\n onChange={onChapterChange(RangeItemPosition.Start)}\n />\n </div>\n\n <div>\n <Combobox\n id=\"starting-verse\"\n size={ComboboxSize.Large}\n fixedWidth={false}\n disabled={!startChapter}\n label={<p className={styles.label}>{t('starting-verse')}</p>}\n items={startingVerseOptions}\n value={startingVerse}\n initialInputValue={getInitialInputValue(RangeItem.StartingVerse)}\n onChange={onVerseChange(RangeItemPosition.Start)}\n />\n </div>\n </div>\n <div className={styles.rangeInputContainer}>\n <div>\n <Combobox\n id=\"end-chapter\"\n size={ComboboxSize.Large}\n fixedWidth={false}\n label={<p className={styles.label}>{t('ending-chapter')}</p>}\n items={endChapterOptions}\n value={endChapter}\n initialInputValue={getInitialInputValue(RangeItem.EndingChapter)}\n onChange={onChapterChange(RangeItemPosition.End)}\n />\n </div>\n\n <div>\n <Combobox\n id=\"end-verse\"\n size={ComboboxSize.Large}\n fixedWidth={false}\n label={<p className={styles.label}>{t('ending-verse')}</p>}\n items={endingVerseOptions}\n value={endingVerse}\n disabled={!endChapter}\n initialInputValue={getInitialInputValue(RangeItem.EndingVerse)}\n onChange={onVerseChange(RangeItemPosition.End)}\n />\n </div>\n </div>\n </>\n );\n};\n\nexport default VerseRangeInput;\n","/* eslint-disable react-func/max-lines-per-function */\n/* eslint-disable max-lines */\nimport { useMemo } from 'react';\n\nimport classNames from 'classnames';\nimport useTranslation from 'next-translate/useTranslation';\n\nimport styles from './ReadingGoalInput.module.scss';\nimport VerseRangeInput from './VerseRangeInput';\n\nimport { ReadingGoalTabProps } from '@/components/ReadingGoalPage/hooks/useReadingGoalReducer';\nimport Input, { InputSize } from '@/dls/Forms/Input';\nimport Select, { SelectSize } from '@/dls/Forms/Select';\nimport { GoalType } from '@/types/auth/Goal';\nimport { generateTimeOptions } from '@/utils/generators';\n\nexport interface ReadingGoalInputProps {\n type: GoalType;\n\n rangeStartVerse?: string;\n rangeEndVerse?: string;\n pages?: number;\n seconds?: number;\n widthFull?: boolean;\n\n onRangeChange: (range: { startVerse: string | null; endVerse: string | null }) => void;\n onPagesChange: (pages: number) => void;\n onSecondsChange: (seconds: number) => void;\n\n logChange: ReadingGoalTabProps['logChange'];\n}\n\nconst ReadingGoalInput: React.FC<ReadingGoalInputProps> = ({\n type,\n rangeStartVerse,\n rangeEndVerse,\n pages,\n seconds,\n onRangeChange,\n onPagesChange,\n onSecondsChange,\n widthFull = true,\n logChange,\n}) => {\n const { t, lang } = useTranslation('reading-goal');\n const timeOptions = useMemo(() => generateTimeOptions(t, lang), [t, lang]);\n\n if (type === GoalType.RANGE) {\n return (\n <VerseRangeInput\n rangeStartVerse={rangeStartVerse}\n rangeEndVerse={rangeEndVerse}\n onRangeChange={onRangeChange}\n logChange={logChange}\n />\n );\n }\n\n if (type === GoalType.PAGES) {\n return (\n <div className={styles.inputContainer}>\n <label htmlFor=\"pages\" className={styles.label}>\n {t('goal-types.pages.title')}\n </label>\n <Input\n id=\"pages\"\n containerClassName={classNames(styles.input, widthFull && styles.fullWidth)}\n size={InputSize.Large}\n value={pages.toString()}\n fixedWidth={false}\n htmlType=\"number\"\n // prevent users from entering decimal value\n onKeyDown={(e) => e.key === '.' && e.preventDefault()}\n inputMode=\"numeric\"\n onChange={(p) => {\n const parsedPages = Number(p);\n onPagesChange(parsedPages);\n logChange('pages', { currentValue: pages, newValue: parsedPages });\n }}\n />\n </div>\n );\n }\n\n return (\n <div className={styles.inputContainer}>\n <label htmlFor=\"seconds\" className={styles.label}>\n {t('goal-types.time.title')}\n </label>\n <Select\n id=\"seconds\"\n name=\"seconds\"\n size={SelectSize.Large}\n className={styles.input}\n options={timeOptions}\n value={seconds.toString()}\n onChange={(s) => {\n const parsedSeconds = Number(s);\n onSecondsChange(parsedSeconds);\n\n logChange('seconds', { currentValue: seconds, newValue: parsedSeconds });\n }}\n />\n </div>\n );\n};\n\nexport default ReadingGoalInput;\n","/* eslint-disable import/prefer-default-export */\nimport { isValidPageNumber, isValidVerseKey } from '@/utils/validator';\nimport { getVerseAndChapterNumbersFromKey } from '@/utils/verse';\nimport { GoalType } from 'types/auth/Goal';\nimport ChaptersData from 'types/ChaptersData';\nimport { Mushaf } from 'types/QuranReader';\n\nconst SECONDS_LIMIT = 4 * 60 * 60; // 4 hours\nconst MIN_SECONDS = 60; // 1 minute\n\ninterface Range {\n startVerse: string;\n endVerse: string;\n}\n\ninterface ReadingGoalPayload {\n type: GoalType;\n pages?: number;\n seconds?: number;\n range?: Range;\n}\n\n/**\n * A utility function to validate the reading goal data\n *\n * @param {ChaptersData} chaptersData\n * @param {ReadingGoalPayload} payload\n * @returns {boolean} is the payload valid\n */\nexport const validateReadingGoalData = (\n chaptersData: ChaptersData,\n { type, pages, seconds, range }: ReadingGoalPayload,\n mushafId: Mushaf,\n): boolean => {\n // if the user selected a pages goal and didn't enter a valid amount of pages, disable the next button\n if (type === GoalType.PAGES && !isValidPageNumber(pages, mushafId)) return false;\n\n // if the user selected a time goal and didn't enter a valid amount of seconds, disable the next button\n // in theory, this should never happen because the input is a select, but just in case\n if (\n type === GoalType.TIME &&\n (Number.isNaN(seconds) || seconds > SECONDS_LIMIT || seconds < MIN_SECONDS)\n ) {\n return false;\n }\n\n // if the user selected a range goal and didn't enter a valid range, disable the next button\n if (type === GoalType.RANGE) {\n return isValidVerseRange(chaptersData, range);\n }\n\n return true;\n};\n\n/**\n * Check wether the ranges are valid or not.\n *\n * @param {ChaptersData} chaptersData\n * @param {Range} range\n * @returns {boolean}\n */\nexport const isValidVerseRange = (chaptersData: ChaptersData, range?: Range): boolean => {\n if (!range?.startVerse || !range?.endVerse) return false;\n if (\n !isValidVerseKey(chaptersData, range.startVerse) ||\n !isValidVerseKey(chaptersData, range.endVerse)\n ) {\n return false;\n }\n\n // check if the starting verse key is greater than the ending verse key\n const [startingChapter, startingVerse] = getVerseAndChapterNumbersFromKey(range.startVerse);\n const [endingChapter, endingVerse] = getVerseAndChapterNumbersFromKey(range.endVerse);\n // if it's the same Surah but in reverse order\n if (startingChapter === endingChapter && Number(startingVerse) > Number(endingVerse)) {\n return false;\n }\n // if it's the range Surahs are in reverse order\n if (Number(startingChapter) > Number(endingChapter)) {\n return false;\n }\n return true;\n};\n","/* eslint-disable max-lines */\nimport React, {\n ReactNode,\n useState,\n useEffect,\n ChangeEvent,\n RefObject,\n KeyboardEvent,\n HTMLAttributes,\n} from 'react';\n\nimport classNames from 'classnames';\n\nimport Button, { ButtonShape, ButtonSize, ButtonVariant } from '../../Button/Button';\n\nimport styles from './Input.module.scss';\n\nimport ClearIcon from '@/icons/close.svg';\n\nexport enum InputSize {\n Small = 'small',\n Medium = 'medium',\n Large = 'large',\n}\n\nexport enum InputType {\n Error = 'error',\n Warning = 'warning',\n Success = 'success',\n}\n\nexport enum InputVariant {\n Default = 'default',\n Main = 'main',\n}\ninterface Props {\n id: string;\n name?: string;\n size?: InputSize;\n placeholder?: string;\n fixedWidth?: boolean;\n disabled?: boolean;\n clearable?: boolean;\n prefix?: ReactNode;\n suffix?: ReactNode;\n onClearClicked?: () => void;\n onChange?: (value: string) => void;\n onKeyDown?: (event: KeyboardEvent<HTMLInputElement>) => void;\n inputMode?: HTMLAttributes<HTMLInputElement>['inputMode'];\n value?: string;\n label?: string | JSX.Element;\n type?: InputType;\n shouldFlipOnRTL?: boolean;\n variant?: InputVariant;\n containerClassName?: string;\n htmlType?: React.HTMLInputTypeAttribute;\n isRequired?: boolean;\n inputRef?: RefObject<HTMLInputElement>;\n}\n\nconst Input: React.FC<Props> = ({\n id,\n name,\n label,\n placeholder,\n size = InputSize.Medium,\n fixedWidth = true,\n disabled = false,\n clearable = false,\n type,\n variant,\n prefix,\n suffix,\n onClearClicked,\n onChange,\n onKeyDown,\n inputMode,\n value = '',\n shouldFlipOnRTL = true,\n containerClassName,\n htmlType,\n isRequired,\n inputRef,\n}) => {\n const [inputValue, setInputValue] = useState(value);\n // listen to any change in value in-case the value gets populated after and API call.\n useEffect(() => {\n setInputValue(value);\n }, [value]);\n\n const onValueChange = (event: ChangeEvent<HTMLInputElement>) => {\n const newValue = event.target.value;\n setInputValue(newValue);\n if (onChange) {\n onChange(newValue);\n }\n };\n\n return (\n <>\n {label && <p className={styles.label}>{label}</p>}\n <div\n className={classNames(styles.container, containerClassName, {\n [styles.smallContainer]: size === InputSize.Small,\n [styles.mediumContainer]: size === InputSize.Medium,\n [styles.largeContainer]: size === InputSize.Large,\n [styles.fixedWidth]: fixedWidth,\n [styles.disabled]: disabled,\n [styles.error]: type === InputType.Error,\n [styles.success]: type === InputType.Success,\n [styles.warning]: type === InputType.Warning,\n [styles.main]: variant === InputVariant.Main,\n })}\n >\n {prefix && (\n <div className={classNames(styles.prefix, styles.prefixSuffixContainer)}>{prefix}</div>\n )}\n <input\n className={classNames(styles.input, {\n [styles.error]: type === InputType.Error,\n [styles.success]: type === InputType.Success,\n [styles.warning]: type === InputType.Warning,\n [styles.rtlInput]: shouldFlipOnRTL,\n })}\n type={htmlType}\n required={isRequired}\n dir=\"auto\"\n id={id}\n ref={inputRef}\n disabled={disabled}\n onChange={onValueChange}\n value={inputValue}\n onKeyDown={onKeyDown}\n inputMode={inputMode}\n {...(placeholder && { placeholder })}\n {...(name && { name })}\n />\n {clearable ? (\n <>\n {inputValue && (\n <div className={styles.clearContainer}>\n <Button\n shape={ButtonShape.Circle}\n variant={ButtonVariant.Ghost}\n size={ButtonSize.Small}\n onClick={onClearClicked}\n >\n <ClearIcon />\n </Button>\n </div>\n )}\n </>\n ) : (\n <>\n {suffix && (\n <div className={classNames(styles.suffix, styles.prefixSuffixContainer)}>\n {suffix}\n </div>\n )}\n </>\n )}\n </div>\n </>\n );\n};\n\nexport default Input;\n","import React, { ChangeEvent, useCallback } from 'react';\n\nimport classNames from 'classnames';\n\nimport styles from './Select.module.scss';\n\nimport CaretIcon from '@/icons/caret-down.svg';\n\nexport interface SelectOption {\n label: string;\n value: string | number;\n disabled?: boolean;\n}\n\nexport enum SelectSize {\n Small = 'small',\n Medium = 'medium',\n Large = 'large',\n}\n\ninterface Props {\n id: string;\n name: string;\n options: SelectOption[];\n disabled?: boolean;\n required?: boolean;\n size?: SelectSize;\n value?: string;\n placeholder?: string;\n onChange?: (value: string | number) => void;\n defaultStyle?: boolean;\n className?: string;\n withBackground?: boolean;\n}\n\nconst Select: React.FC<Props> = ({\n name,\n id,\n onChange,\n options,\n value,\n disabled = false,\n required = false,\n size = SelectSize.Medium,\n placeholder = 'Select an option',\n defaultStyle = true,\n className,\n withBackground = true,\n}) => {\n const onSelectChange = useCallback(\n (e: ChangeEvent<HTMLSelectElement>) => {\n if (onChange) {\n onChange(e.target.value);\n }\n },\n [onChange],\n );\n\n return (\n <div\n className={classNames(styles.container, {\n [styles.defaultStyledContainer]: defaultStyle,\n [className]: className,\n [styles.disabledContainer]: disabled,\n [styles.smallContainer]: size === SelectSize.Small,\n [styles.mediumContainer]: size === SelectSize.Medium,\n [styles.largeContainer]: size === SelectSize.Large,\n [styles.withBackground]: withBackground,\n })}\n >\n <select\n className={classNames(styles.select, {\n [styles.defaultStyledSelect]: defaultStyle,\n [styles.disabledSelect]: disabled,\n })}\n name={name}\n id={id}\n onChange={onSelectChange}\n disabled={disabled}\n required={required}\n {...(value ? { value } : { defaultValue: '' })}\n >\n <option value=\"\" disabled hidden>\n {placeholder}\n </option>\n {options.map((option) => (\n <option key={option.value} value={option.value} disabled={option.disabled || false}>\n {option.label}\n </option>\n ))}\n </select>\n <div className={classNames(styles.arrow, { [styles.disabledArrow]: disabled })}>\n <CaretIcon />\n </div>\n </div>\n );\n};\n\nexport default Select;\n","import React, { ReactNode } from 'react';\n\nimport Popover, { ContentSide } from '@/dls/Popover';\nimport Tooltip from '@/dls/Tooltip';\n\ninterface Props {\n content: ReactNode;\n children: ReactNode | ReactNode[];\n contentSide?: ContentSide;\n tip?: boolean;\n tooltipDelay?: number;\n onOpenChange?: (open: boolean) => void;\n defaultStyling?: boolean;\n isOpen?: boolean;\n triggerStyles?: string;\n isContainerSpan?: boolean;\n}\n\n/**\n * A component that combines the functionality of a Popover and a Tooltip together.\n * This is needed to handle the case when we want to show a Tooltip on mobile but\n * since Tooltip is only hoverable and there is no hovering on mobile devices,\n * we provide the same functionality by using a Popover which handles clicking.\n *\n * @param {Props} props\n * @returns {JSX.Element}\n */\nconst HoverablePopover: React.FC<Props> = ({\n content,\n children,\n onOpenChange,\n contentSide = ContentSide.TOP,\n tip = true,\n tooltipDelay = 0,\n defaultStyling = true,\n isOpen,\n triggerStyles,\n isContainerSpan = false,\n}: Props): JSX.Element => (\n <Popover\n open={isOpen}\n triggerStyles={triggerStyles}\n contentSide={contentSide}\n useTooltipStyles\n {...(onOpenChange && { onOpenChange })}\n defaultStyling={defaultStyling}\n isContainerSpan={isContainerSpan}\n trigger={\n <Tooltip\n open={isOpen}\n tip={tip}\n text={content}\n contentSide={contentSide}\n delay={tooltipDelay}\n {...(onOpenChange && { onOpenChange })}\n >\n {children}\n </Tooltip>\n }\n tip={tip}\n >\n {content}\n </Popover>\n);\n\nexport default HoverablePopover;\n","import React, { ReactNode } from 'react';\n\nimport * as RadixPopover from '@radix-ui/react-popover';\nimport classNames from 'classnames';\n\nimport styles from './Popover.module.scss';\n\nexport enum ContentSide {\n TOP = 'top',\n RIGHT = 'right',\n BOTTOM = 'bottom',\n LEFT = 'left',\n}\n\nexport enum ContentAlign {\n START = 'start',\n CENTER = 'center',\n END = 'end',\n}\n\ninterface Props {\n trigger: ReactNode;\n children: ReactNode | ReactNode[];\n onOpenChange?: (open: boolean) => void;\n open?: boolean;\n isModal?: boolean;\n contentSide?: ContentSide;\n contentAlign?: ContentAlign;\n tip?: boolean;\n avoidCollisions?: boolean;\n useTooltipStyles?: boolean;\n defaultStyling?: boolean;\n isPortalled?: boolean;\n triggerStyles?: string;\n contentStyles?: string;\n contentSideOffset?: number;\n isContainerSpan?: boolean;\n}\n\nconst Popover: React.FC<Props> = ({\n children,\n trigger,\n onOpenChange,\n open,\n isModal = false,\n contentSide = ContentSide.BOTTOM,\n contentAlign = ContentAlign.CENTER,\n avoidCollisions = true,\n tip = false,\n useTooltipStyles = false,\n defaultStyling = true,\n isPortalled = true,\n contentSideOffset = 2,\n triggerStyles,\n contentStyles,\n isContainerSpan = false,\n}) => {\n const content = (\n <RadixPopover.Content\n sideOffset={contentSideOffset}\n side={contentSide}\n align={contentAlign}\n avoidCollisions={avoidCollisions}\n className={classNames(styles.content, {\n [styles.tooltipContent]: useTooltipStyles,\n [contentStyles]: contentStyles,\n })}\n >\n {children}\n {tip && <RadixPopover.Arrow />}\n </RadixPopover.Content>\n );\n\n const containerChild = (\n <RadixPopover.Root\n modal={isModal}\n {...(typeof open !== 'undefined' && { open })}\n {...(onOpenChange && { onOpenChange })}\n >\n <RadixPopover.Trigger aria-label=\"Open popover\" asChild>\n <span\n className={classNames(styles.trigger, {\n [triggerStyles]: triggerStyles,\n })}\n >\n {trigger}\n </span>\n </RadixPopover.Trigger>\n {isPortalled ? <RadixPopover.Portal>{content}</RadixPopover.Portal> : content}\n </RadixPopover.Root>\n );\n\n if (isContainerSpan) {\n return (\n <span className={classNames({ [styles.container]: defaultStyling })}>{containerChild}</span>\n );\n }\n\n return <div className={classNames({ [styles.container]: defaultStyling })}>{containerChild}</div>;\n};\n\nexport default Popover;\n","import { shallowEqual, useSelector } from 'react-redux';\n\nimport { selectQuranFont, selectQuranMushafLines } from '@/redux/slices/QuranReader/styles';\nimport { Mushaf } from '@/types/QuranReader';\nimport { getMushafId } from '@/utils/api';\n\n/**\n * Instead of repeating using multiple selectors to get the MushafId\n * in multiple components, we are introducing this hook to keep it DRY.\n *\n * TODO: apply it to everywhere using the mushafId\n *\n * @returns {Mushaf}\n */\nconst useGetMushaf = (): Mushaf => {\n const quranFont = useSelector(selectQuranFont, shallowEqual);\n const mushafLines = useSelector(selectQuranMushafLines, shallowEqual);\n const { mushaf } = getMushafId(quranFont, mushafLines);\n return mushaf;\n};\n\nexport default useGetMushaf;\n","/* eslint-disable import/prefer-default-export */\nimport { Translate } from 'next-translate';\n\nimport { DropdownItem } from '@/dls/Forms/Combobox/ComboboxItem';\nimport { SelectOption } from '@/dls/Forms/Select';\nimport ChaptersData from '@/types/ChaptersData';\nimport { getChapterData } from '@/utils/chapter';\nimport { secondsToReadableFormat } from '@/utils/datetime';\nimport { toLocalizedNumber } from '@/utils/locale';\n\nconst TIME_OPTIONS_LIMIT = 4 * 60; // 4 hours\nconst DURATION_DAYS_LIMIT = 365; // 1 year, 365 days\n\n/**\n * Generates options for the reading goal time input.\n *\n * The options are within a range of 1 minute to 4 hours.\n * - From 1 to 10 minutes (first 10 options), increment by 1 minute\n * - From > 10 minutes to 4 hours, increment by 5 minutes\n *\n * @param {Translate} t\n * @param {string} locale\n * @returns {SelectOption[]}\n */\nexport const generateTimeOptions = (t: Translate, locale: string): SelectOption[] => {\n // for the first 10 minutes, we want to show 1 until 10\n // but after that, we want to increment by 5 minutes\n // and our limit is TIME_OPTIONS_LIMIT\n const options: SelectOption[] = new Array(10 + (TIME_OPTIONS_LIMIT - 10) / 5)\n .fill(null)\n // eslint-disable-next-line @typescript-eslint/naming-convention\n .map((_, i) => {\n let minutes: number;\n\n if (i < 10) {\n minutes = i + 1;\n } else {\n minutes = (i - 9) * 5 + 10;\n }\n\n const seconds = minutes * 60;\n\n return {\n value: seconds,\n label: secondsToReadableFormat(seconds, t, locale),\n };\n });\n\n return options;\n};\n\n/**\n * Generates options for the reading goal chapter input.\n *\n * @param {ChaptersData} chaptersData\n * @param {string} locale\n * @returns {DropdownItem[]}\n */\nexport const generateChapterOptions = (\n chaptersData: ChaptersData,\n locale: string,\n): DropdownItem[] => {\n const data: DropdownItem[] = Object.keys(chaptersData).map((chapterId) => {\n const chapter = getChapterData(chaptersData, chapterId);\n const localizedChapterId = toLocalizedNumber(Number(chapterId), locale);\n\n return {\n id: chapterId,\n name: chapterId,\n value: chapterId,\n label: `${localizedChapterId} - ${chapter.transliteratedName}`,\n };\n });\n\n return data;\n};\n\n/**\n * Generates verse options for a certain chapter in the reading goal verse input.\n *\n * @param {ChaptersData} chaptersData\n * @param {Translate} t\n * @param {string} locale\n * @param {string?} chapterId\n * @returns {DropdownItem[]}\n */\nexport const generateVerseOptions = (\n chaptersData: ChaptersData,\n t: Translate,\n locale: string,\n chapterId?: string,\n): DropdownItem[] => {\n if (!chapterId) return [];\n\n const chapter = getChapterData(chaptersData, chapterId);\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n const options: DropdownItem[] = new Array(chapter.versesCount).fill(null).map((_, index) => {\n const localizedVerseId = toLocalizedNumber(index + 1, locale);\n const verseId = String(index + 1);\n\n return {\n id: verseId,\n name: verseId,\n value: verseId,\n label: `${t('common:ayah')} ${localizedVerseId}`,\n };\n });\n\n return options;\n};\n\n/**\n * Generates options for the reading goal duration input.\n *\n * The options are within a range of 1 day to 365 days in this format:\n * \"1 day\", \"2 days\", \"3 days\", etc...\n *\n * @param {Translate} t\n * @param {string} locale\n * @returns {SelectOption[]}\n */\nexport const generateDurationDaysOptions = (t: Translate, locale: string): SelectOption[] => {\n // for the first 10 days, we want to show 1 until 10\n // but after that, we want to increment by 5 days\n // and our limit is DURATION_DAYS_LIMIT\n const options: SelectOption[] = new Array(10 + (DURATION_DAYS_LIMIT - 10) / 5)\n .fill(null)\n // eslint-disable-next-line @typescript-eslint/naming-convention\n .map((_, i) => {\n let day: number;\n if (i < 10) {\n day = i + 1;\n } else {\n day = (i - 9) * 5 + 10;\n }\n\n return {\n value: day.toString(),\n label: t('reading-goal:x-days', { count: day, days: toLocalizedNumber(day, locale) }),\n };\n });\n\n return options;\n};\n","import { toLocalizedNumber } from './locale';\n\nimport { Mushaf, MushafLines, QuranFont, QuranFontMushaf } from 'types/QuranReader';\n\nconst DEFAULT_NUMBER_OF_PAGES = 604;\n\n// a map between the mushafId and the number of pages it has\nexport const PAGES_MUSHAF_MAP = {\n [Mushaf.Indopak]: 604,\n [Mushaf.KFGQPCHAFS]: 604,\n [Mushaf.QCFV1]: 604,\n [Mushaf.QCFV2]: 604,\n [Mushaf.UthmaniHafs]: 604,\n [Mushaf.Indopak16Lines]: 548,\n [Mushaf.Indopak15Lines]: 610,\n [Mushaf.Tajweeed]: 604,\n};\n\n/**\n * Whether the current page is the first page.\n *\n * @param {number} surahNumber\n * @returns {boolean}\n */\nexport const isFirstPage = (surahNumber: number): boolean => surahNumber === 1;\n\n/**\n * Whether the current page is the last page.\n *\n * @param {number} pageNumber\n * @param {QuranFont} quranFont\n * @param {MushafLines} mushafLines\n * @returns {boolean}\n */\nexport const isLastPage = (\n pageNumber: number,\n quranFont?: QuranFont,\n mushafLines?: MushafLines,\n): boolean => pageNumber === getMushafTotalPageNumber(quranFont, mushafLines);\n\n/**\n * Get the number of pages of the current mushaf based on the selected font\n * and the number of line (in the case of IndoPak).\n *\n * @param {QuranFont} quranFont\n * @param {MushafLines} mushafLines\n * @returns {number}\n */\nconst getMushafTotalPageNumber = (quranFont?: QuranFont, mushafLines?: MushafLines): number => {\n let mushafTotalPages = 0;\n // this is when we are SSR the page because those 2 values won't be there since they come from Redux\n if (!quranFont || !mushafLines) {\n mushafTotalPages = DEFAULT_NUMBER_OF_PAGES;\n } else if (quranFont === QuranFont.IndoPak) {\n mushafTotalPages =\n mushafLines === MushafLines.SixteenLines\n ? PAGES_MUSHAF_MAP[Mushaf.Indopak16Lines]\n : PAGES_MUSHAF_MAP[Mushaf.Indopak15Lines];\n } else {\n mushafTotalPages = PAGES_MUSHAF_MAP[QuranFontMushaf[quranFont]];\n }\n return mushafTotalPages;\n};\n\n/**\n * Return array of page id\n *\n * @returns {{value: number, label: string}[]}\n */\nexport const getPageIdsByMushaf = (\n lang: string,\n quranFont?: QuranFont,\n mushafLines?: MushafLines,\n): { value: number; label: string }[] =>\n [...Array(getMushafTotalPageNumber(quranFont, mushafLines))].map((n, index) => {\n const page = index + 1;\n return { value: page, label: toLocalizedNumber(page, lang) };\n });\n\n/**\n * Get the number of lines in a Mushaf page based on the Mushaf.\n * All Mushafs have 15 lines except for Indopak 16-line one.\n *\n * @param {QuranFont} quranFont\n * @param {MushafLines} mushafLines\n * @returns {number}\n */\nexport const getMushafLinesNumber = (quranFont: QuranFont, mushafLines: MushafLines): number => {\n if (\n quranFont !== QuranFont.IndoPak ||\n (quranFont === QuranFont.IndoPak && mushafLines === MushafLines.FifteenLines)\n ) {\n return 15;\n }\n return 16;\n};\n","/**\n * Shorten a text by setting the maximum number of characters\n * by the value of the parameter and adding \"...\" at the end.\n *\n * @param {string} rawString\n * @param {number} length\n * @param {string} suffix\n * @returns {string}\n */\nexport const truncateString = (rawString: string, length: number, suffix = '...'): string => {\n const characters = rawString.split('', length);\n let shortenedText = '';\n for (let index = 0; index < characters.length; index += 1) {\n const character = characters[index];\n if (shortenedText.length === length - 1) {\n shortenedText = `${shortenedText}${character}${suffix}`;\n break;\n }\n shortenedText = `${shortenedText}${character}`;\n }\n return shortenedText;\n};\n\n/**\n * Strip HTML tags from a string.\n *\n * @param {string} rawString\n * @returns {string}\n */\nexport const stripHTMLTags = (rawString: string): string => rawString.replace(/(<([^>]+)>)/gi, '');\n\n/**\n * Convert a slugified collection id to collection id only after\n * removing the slug.\n *\n * @param {string} slugifiedCollectionId\n * @returns {string}\n */\nexport const slugifiedCollectionIdToCollectionId = (slugifiedCollectionId: string): string => {\n if (!slugifiedCollectionId) {\n return '';\n }\n const splits = slugifiedCollectionId.split('-');\n // if there is no slug in the url (collections with a name that cannot be slugified e.g. emoticons)\n if (splits.length === 1) {\n return splits[0];\n }\n return splits[splits.length - 1];\n};\n","import { getChapterData } from './chapter';\nimport { PAGES_MUSHAF_MAP } from './page';\nimport { parseVerseRange } from './verseKeys';\n\nimport ChaptersData from 'types/ChaptersData';\nimport { Mushaf } from 'types/QuranReader';\n\n/**\n * Validate a chapterId which can be in-valid in 2 cases:\n *\n * 1. if it's a string that is not numeric e.g. \"test\".\n * 2. if it's a numeric string but lies outside the range 1->114.\n *\n * @param {string} chapterId\n * @returns {boolean}\n */\nexport const isValidChapterId = (chapterId: string): boolean => {\n const chapterIdNumber = Number(chapterId);\n // if it's not a numeric string or it's numeric but out of the range of chapter 1->114\n if (Number.isNaN(chapterIdNumber) || chapterIdNumber > 114 || chapterIdNumber < 1) {\n return false;\n }\n return true;\n};\n\n/**\n * Check whether the verse number is valid by trying to convert it\n * into a number.\n *\n * @param {string} verseId\n * @returns {boolean}\n */\nexport const isValidVerseNumber = (verseId: string): boolean => {\n const verseIdNumber = Number(verseId);\n return !Number.isNaN(verseIdNumber);\n};\n\n/**\n * Validate a verseId which can be in-valid in 3 cases:\n *\n * 1. if it's a string that is not numeric e.g. \"test\".\n * 2. if it's a numeric string but below 1.\n * 3. if it's a numeric string but above the maximum number of verses for the chapter. e.g. verseId 8 for chapterId 1 (Alfatiha) is invalid since it only has 7 verses.\n *\n * @param {ChaptersData} chaptersData\n * @param {string} chapterId the chapter id. We will assume it's valid since we already validated it.\n * @param {string} verseId the verse id being validated.\n * @returns {boolean}\n */\nexport const isValidVerseId = (\n chaptersData: ChaptersData,\n chapterId: string,\n verseId: string,\n): boolean => {\n const verseIdNumber = Number(verseId);\n // is not a valid number, below 1 or above the maximum number of verses for the chapter.\n if (Number.isNaN(verseIdNumber) || verseIdNumber < 1) {\n return false;\n }\n if (\n !getChapterData(chaptersData, chapterId) ||\n verseIdNumber > getChapterData(chaptersData, chapterId).versesCount\n ) {\n return false;\n }\n return true;\n};\n\n/**\n * Validate a juzId which can be in-valid in 2 cases:\n *\n * 1. if it's a string that is not numeric e.g. \"test\".\n * 2. if it's a numeric string but lies outside the range 1->30.\n *\n * @param {string} juzId\n * @returns {boolean}\n */\nexport const isValidJuzId = (juzId: string): boolean => {\n const juzIdNumber = Number(juzId);\n // if it's not a numeric string or it's numeric but out of the range of chapter 1->30\n if (Number.isNaN(juzIdNumber) || juzIdNumber > 30 || juzIdNumber < 1) {\n return false;\n }\n return true;\n};\n\n/**\n * Validate a rubId which can be in-valid in 2 cases:\n *\n * 1. if it's a string that is not numeric e.g. \"test\".\n * 2. if it's a numeric string but lies outside the range 1->240.\n *\n * @param {string} rubId\n * @returns {boolean}\n */\nexport const isValidRubId = (rubId: string): boolean => {\n const rubIdNumber = Number(rubId);\n // if it's not a numeric string or it's numeric but out of the range of chapter 1->240\n if (Number.isNaN(rubIdNumber) || rubIdNumber > 240 || rubIdNumber < 1) {\n return false;\n }\n return true;\n};\n\n/**\n * Validate a hizbId which can be in-valid in 2 cases:\n *\n * 1. if it's a string that is not numeric e.g. \"test\".\n * 2. if it's a numeric string but lies outside the range 1->60.\n *\n * @param {string} hizbId\n * @returns {boolean}\n */\nexport const isValidHizbId = (hizbId: string): boolean => {\n const hizbIdNumber = Number(hizbId);\n // if it's not a numeric string or it's numeric but out of the range of chapter 1->30\n if (Number.isNaN(hizbIdNumber) || hizbIdNumber > 60 || hizbIdNumber < 1) {\n return false;\n }\n return true;\n};\n\n/**\n * Validate a pageId which can be in-valid in 2 cases:\n *\n * 1. if it's a string that is not numeric e.g. \"test\".\n * 2. if it's a numeric string but lies outside the range of the selected Mushaf.\n *\n * @param {string | number} pageId\n * @returns {boolean}\n */\nexport const isValidPageNumber = (pageId: string | number, mushafId: Mushaf): boolean => {\n const pageIdNumber = Number(pageId);\n const MUSHAF_COUNT = PAGES_MUSHAF_MAP[mushafId];\n // if it's not a numeric string or it's numeric but out of the range of the selected Mushaf\n if (Number.isNaN(pageIdNumber) || pageIdNumber > MUSHAF_COUNT || pageIdNumber < 1) {\n return false;\n }\n return true;\n};\n\n/**\n * Extract the to and from verse by splitting the range by '-'.\n *\n * @param {string} range\n * @returns {string[]}\n */\nexport const getToAndFromFromRange = (range: string): string[] => range.split('-');\n\n/**\n * This is to check if the range passed is valid or not. It won't be valid if:\n *\n * 1. The format is not a range's format and this is known if after splitting the range string\n * by '-', we don't have 2 parts for the range representing the from verse and to verse.\n * e.g. 'one'\n * 2. If after splitting them, either of the 2 parts are not a valid number e.g. 'one-two'\n * or '1-two' or 'one-2'.\n * 3. If the from verse number exceeds the to verse number. e.g. '8-7'.\n * 4. If either the from verse number of to verse number exceeds the total number of verses\n * for the current chapter e.g. for chapter 1: '7-8' or '8-8'.\n *\n * @param {ChaptersData} chaptersData\n * @param {string} chapterId\n * @param {string} range\n * @returns {boolean}\n */\nexport const isValidVerseRange = (\n chaptersData: ChaptersData,\n chapterId: string,\n range: string,\n): boolean => {\n const rangeSplits = getToAndFromFromRange(range);\n // if the splits are not 2, it means it's not in the right format.\n if (rangeSplits.length !== 2) {\n return false;\n }\n const [from, to] = rangeSplits;\n const fromNumber = Number(from);\n const toNumber = Number(to);\n // if the range is in the right format but either value is not a number e.g. 'one-two'\n if (Number.isNaN(fromNumber) || Number.isNaN(toNumber)) {\n return false;\n }\n // 0 is not a valid verse number\n if (fromNumber === 0 || toNumber === 0) {\n return false;\n }\n // if the from verse number is bigger than the to verse number\n if (fromNumber > toNumber) {\n return false;\n }\n // if the chapterId is not a valid chapterId e.g. \"word\"\n if (!getChapterData(chaptersData, chapterId)) {\n return false;\n }\n const chapterVersesCount = getChapterData(chaptersData, chapterId).versesCount;\n // if either the from verse number of to verse number exceeds the chapter's total number.\n if (fromNumber > chapterVersesCount || toNumber > chapterVersesCount) {\n return false;\n }\n\n return true;\n};\n\n/**\n * Check if a string range is valid or not.\n * A valid range looks like this: \"1:1-1:2\" or \"1:1-2:3\".\n *\n * @param {ChaptersData} chaptersData\n * @param {string} rangesString\n * @returns {boolean}\n */\nexport const isRangesStringValid = (chaptersData: ChaptersData, rangesString: string): boolean => {\n const parsedVerseRange = parseVerseRange(rangesString);\n // 1. if the range is not in the right format\n if (!parsedVerseRange) {\n return false;\n }\n const [fromRange, toRange] = parsedVerseRange;\n // if both ranges are in the same chapter\n if (fromRange.chapter === toRange.chapter) {\n const verseRange = `${fromRange.verse}-${toRange.verse}`;\n // 2. if range within same surah is not valid\n if (!isValidVerseRange(chaptersData, fromRange.chapter, verseRange)) {\n return false;\n }\n } else {\n // 2. if start of range verse key is not valid\n if (!isValidVerseKey(chaptersData, fromRange.verseKey)) {\n return false;\n }\n // 3. if end of range verse key is not valid\n if (!isValidVerseKey(chaptersData, toRange.verseKey)) {\n return false;\n }\n // 4. if the fromRange chapter is bigger than the toRange chapter e.g. 2:1-1:1\n if (Number(fromRange.chapter) > Number(toRange.chapter)) {\n return false;\n }\n }\n\n return true;\n};\n\n/**\n * Check if a verse key is valid. An invalid verse key can be:\n *\n * 1. it's in a wrong format e.g. \"verseKey\"\n * 2. if the number of parts is bigger than 2 e.g. \"1:2:3\"\n * 3. if it's not a valid chapter id {@see isValidChapterId}\n * 4. if it's not a valid verse ID {@see isValidVerseId}\n *\n * @param {ChaptersData} chaptersData\n * @param {string} verseKey\n * @returns {boolean}\n */\nexport const isValidVerseKey = (chaptersData: ChaptersData, verseKey: string): boolean => {\n const splits = verseKey.split(':');\n // if the splits are not 2, it means it's not in the right format.\n if (splits.length !== 2) {\n return false;\n }\n const [chapterId, verseId] = splits;\n // if either value is not a number e.g. 'one:2' or if the verseNumber is below 0\n if (!isValidChapterId(chapterId) || !isValidVerseId(chaptersData, chapterId, verseId)) {\n return false;\n }\n\n return true;\n};\n\n/**\n * Check whether a tafsir id is valid or not. An invalid tafsirId can be:\n * 1. A non numeric value.\n * 2. A numeric value that is less than 0.\n *\n * @param {string} tafsirId\n * @returns {boolean}\n */\nexport const isValidTafsirId = (tafsirId: string): boolean => {\n const tafsirIdNumber = Number(tafsirId);\n // if the tafsir Id is not a number of if it's below 1\n if (Number.isNaN(tafsirIdNumber) || tafsirIdNumber < 1) {\n return false;\n }\n return true;\n};\n","// extracted by mini-css-extract-plugin\nmodule.exports = {\"container\":\"Error_container__1m9XV\",\"text\":\"Error_text__yg4kD\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"rangeInputContainer\":\"ReadingGoalInput_rangeInputContainer__ZEAD_\",\"inputContainer\":\"ReadingGoalInput_inputContainer__I_R3M\",\"fullWidth\":\"ReadingGoalInput_fullWidth__MyI06\",\"input\":\"ReadingGoalInput_input__PtUNh\",\"label\":\"ReadingGoalInput_label__lxzo1\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"container\":\"Input_container__5BNOH\",\"fixedWidth\":\"Input_fixedWidth__MZoNx\",\"disabled\":\"Input_disabled__AFA4l\",\"error\":\"Input_error__cfc8q\",\"success\":\"Input_success__qb_Ue\",\"warning\":\"Input_warning__KwRSJ\",\"main\":\"Input_main__K4bVL\",\"input\":\"Input_input__za7E9\",\"rtlInput\":\"Input_rtlInput__8Yg1Q\",\"smallContainer\":\"Input_smallContainer__bxyYT\",\"mediumContainer\":\"Input_mediumContainer__jEOpT\",\"largeContainer\":\"Input_largeContainer__yafZ8\",\"label\":\"Input_label__loZWW\",\"clearContainer\":\"Input_clearContainer__3LxT4\",\"prefixSuffixContainer\":\"Input_prefixSuffixContainer__n84F6\",\"prefix\":\"Input_prefix__jYhnp\",\"suffix\":\"Input_suffix__v_BvR\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"container\":\"Select_container___DCC_\",\"withBackground\":\"Select_withBackground__rpdEL\",\"defaultStyledContainer\":\"Select_defaultStyledContainer__b32Mm\",\"smallContainer\":\"Select_smallContainer__L2Lff\",\"mediumContainer\":\"Select_mediumContainer__MF_Vq\",\"largeContainer\":\"Select_largeContainer___qGs0\",\"disabledContainer\":\"Select_disabledContainer__gi7YD\",\"arrow\":\"Select_arrow__WAbAk\",\"disabledArrow\":\"Select_disabledArrow__V4nEO\",\"select\":\"Select_select__BnH2G\",\"defaultStyledSelect\":\"Select_defaultStyledSelect__LmeKj\",\"disabledSelect\":\"Select_disabledSelect___R3Jd\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"container\":\"Popover_container__GOha0\",\"trigger\":\"Popover_trigger__qKXNN\",\"content\":\"Popover_content__gu5L4\",\"tooltipContent\":\"Popover_tooltipContent__AMPpT\"};"],"names":["_path","_path2","_extends","Object","assign","bind","n","e","arguments","length","t","r","hasOwnProperty","call","apply","props","xmlns","width","height","viewBox","fill","stroke","strokeWidth","strokeLinecap","strokeLinejoin","className","d","shapeRendering","style","color","router","useRouter","useEffect","asPath","replace","getLoginNavigationUrl","WrappedComponent","useState","isReady","setIsReady","isLoggedIn","RedirectToLoginPage","DataFetcher","queryKey","render","renderError","initialData","loading","Spinner","dataFetcher","fetcher","showSpinnerOnRevalidate","onFetchSuccess","useSWRImmutable","then","res","Promise","resolve","catch","err","reject","fallbackData","data","error","isValidating","mutate","errorComponent","Error","onRetryClicked","memo","fillRule","clipRule","useTranslation","div","styles","p","message","OFFLINE_ERROR","Button","prefix","RetryIcon","size","ButtonSize","type","ButtonType","onClick","url","image","imageAlt","imageHeight","imageWidth","openGraph","description","rest","openGraphParams","images","alt","params","truncateString","NextSeo","rangeStartVerse","rangeEndVerse","onRangeChange","logChange","lang","chaptersData","useContext","DataContext","getChapterNumberFromKey","toString","undefined","startChapter","setStartChapter","endChapter","setEndChapter","chapterOptions","useMemo","generateChapterOptions","startingVerseOptions","generateVerseOptions","endingVerseOptions","endingVerse","getVerseNumberFromKey","startingVerse","onChapterChange","chapterPosition","chapterId","isStartChapter","RangeItemPosition","setChapter","startVerse","endVerse","currentVerse","currentValue","newValue","chapter","verse","startChapterOptions","endChapterIdx","Number","slice","endChapterOptions","startChapterIdx","onVerseChange","versePosition","verseId","isStartVerse","newVerseKey","makeVerseKey","getInitialInputValue","inputType","verseOptions","RangeItem","label","Combobox","id","ComboboxSize","fixedWidth","items","value","initialInputValue","onChange","disabled","pages","seconds","onPagesChange","onSecondsChange","widthFull","timeOptions","generateTimeOptions","GoalType","VerseRangeInput","htmlFor","Input","containerClassName","classNames","InputSize","htmlType","onKeyDown","key","preventDefault","inputMode","parsedPages","Select","name","SelectSize","options","s","parsedSeconds","validateReadingGoalData","mushafId","range","isValidPageNumber","isNaN","isValidVerseRange","isValidVerseKey","getVerseAndChapterNumbersFromKey","startingChapter","endingChapter","InputType","InputVariant","placeholder","Medium","clearable","variant","suffix","onClearClicked","shouldFlipOnRTL","isRequired","inputRef","inputValue","setInputValue","Small","Large","Success","Warning","Main","input","required","dir","ref","event","target","shape","ButtonShape","ButtonVariant","ClearIcon","defaultStyle","withBackground","onSelectChange","useCallback","select","defaultValue","option","hidden","map","CaretIcon","content","children","onOpenChange","contentSide","ContentSide","tip","tooltipDelay","defaultStyling","isOpen","triggerStyles","isContainerSpan","Popover","open","useTooltipStyles","trigger","Tooltip","text","delay","ContentAlign","isModal","BOTTOM","contentAlign","CENTER","avoidCollisions","isPortalled","contentSideOffset","contentStyles","RadixPopover","sideOffset","side","align","containerChild","modal","aria-label","asChild","span","quranFont","useSelector","selectQuranFont","shallowEqual","mushafLines","selectQuranMushafLines","getMushafId","mushaf","locale","Array","_","i","secondsToReadableFormat","keys","getChapterData","localizedChapterId","toLocalizedNumber","transliteratedName","versesCount","index","localizedVerseId","String","generateDurationDaysOptions","day","count","days","PAGES_MUSHAF_MAP","Mushaf","isFirstPage","surahNumber","isLastPage","pageNumber","getMushafTotalPageNumber","QuranFont","MushafLines","QuranFontMushaf","getPageIdsByMushaf","page","getMushafLinesNumber","rawString","characters","split","shortenedText","character","stripHTMLTags","slugifiedCollectionIdToCollectionId","slugifiedCollectionId","splits","isValidChapterId","chapterIdNumber","isValidVerseId","verseIdNumber","pageId","pageIdNumber","MUSHAF_COUNT","verseKey","module","exports"],"sourceRoot":""}
|