{"version":3,"file":"static/chunks/pages/articles-49565722b37361fd.js","mappings":"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","sources":["webpack://_N_E/?9871","webpack://_N_E/./src/components/layouts/InfiniteQueryLayout/InfiniteQueryLayout.tsx","webpack://_N_E/./src/lib/analytics/handlers/eventLogHandler.ts","webpack://_N_E/./src/lib/analytics/handlers/klaviyoEventHandler.ts","webpack://_N_E/./src/lib/analytics/commonEmitter.ts","webpack://_N_E/./src/lib/analytics/eventEmitter.ts","webpack://_N_E/./src/lib/analytics/handlers/abstractAnalyticsHandler.ts","webpack://_N_E/./src/lib/analytics/handlers/googleTagManagerHandler.ts","webpack://_N_E/./src/lib/dataSource/content/content-base.ts","webpack://_N_E/./src/lib/dataSource/content/article.ts","webpack://_N_E/./src/lib/dataSource/contentful/contentful-data-source.ts","webpack://_N_E/./src/lib/dataSource/lostApi/common.ts","webpack://_N_E/./src/lib/hooks/paginate/usePagination.ts","webpack://_N_E/./src/lib/dataSource/lostApi/chat/conversations/totalUnread.ts","webpack://_N_E/./src/lib/hooks/userContext/UserContext.tsx","webpack://_N_E/./src/lib/utils/helpers/dateHelpers/dates.ts","webpack://_N_E/./src/lib/utils/storage/local-storage.ts","webpack://_N_E/./src/lib/utils/helpers/ObjectsHelpers/getExpirationDate.ts","webpack://_N_E/./src/lib/utils/helpers/stringHelpers/parseToJSONSafe.ts","webpack://_N_E/./src/lib/utils/storage/session-storage.ts","webpack://_N_E/./src/pages/articles.tsx","webpack://_N_E/./node_modules/@tanstack/query-core/build/modern/infiniteQueryObserver.js","webpack://_N_E/./node_modules/@tanstack/react-query/build/modern/useInfiniteQuery.js","webpack://_N_E/<anon>"],"sourcesContent":["\n (window.__NEXT_P = window.__NEXT_P || []).push([\n \"/articles\",\n function () {\n return require(\"private-next-pages/articles.tsx\");\n }\n ]);\n if(module.hot) {\n module.hot.dispose(function () {\n window.__NEXT_P.push([\"/articles\"])\n });\n }\n ","import { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { ReactNode } from 'react';\n\n/**\n * The tanstack/react-query QueryClient\n *\n * @constant {QueryClient}\n */\nconst queryClient = new QueryClient();\n\n/**\n * IProviderLayout\n *\n * @interface IInfiniteQueryLayout\n */\nexport interface IInfiniteQueryLayout {\n /**\n * Content of the Layout\n *\n * @memberof IInfiniteQueryLayout\n * @member {ReactNode} children\n */\n children: ReactNode;\n}\n\n/**\n * Pet Search Layout Used to provide all required to perform pet searches to the\n * top level providers to the application\n *\n * @param {IInfiniteQueryLayout} props - The props for the ProviderLayout\n * component.\n * @returns {React.FC<IInfiniteQueryLayout>} ProviderLayout Component\n */\nconst InfiniteQueryLayout: React.FC<IInfiniteQueryLayout> = ({\n children,\n}: IInfiniteQueryLayout) => {\n return (\n <QueryClientProvider client={queryClient}>\n {children}\n {/*\n * ReactQueryDevtools is a dev tool that allows you to inspect the cache and It\n * should be uncommented to be used in local development ONLY It should not be\n * used in production\n */}\n {/* <ReactQueryDevtools initialIsOpen={false} /> */}\n </QueryClientProvider>\n );\n};\n\nexport default InfiniteQueryLayout;\n","import AbstractAnalyticsHandler, { IEvent } from './abstractAnalyticsHandler';\n/**\n * EventLogHandler\n *\n * This will console log all the event data\n *\n * YOU WILL NEED TO UPDATE THE next.config.js TO ALLOW CONSOLE LOGS\n *\n * @augments AbstractAnalyticsHandler\n * @class\n */\nexport default class EventLogHandler extends AbstractAnalyticsHandler {\n /**\n * @memberof EventLogHandler\n * @param {IEvent} data - The data to be sent with the event\n */\n send(data: IEvent) {\n const analyticFeature = this.getAnalyticsFeature();\n\n /**\n * The data object to be sent to the console\n *\n * @memberof EventLogHandler\n * @member {object} dataObject\n */\n const dataObject: {\n /** The data associated with the event */\n data: object;\n /** The feature flags that are enabled */\n feature: string;\n } = {\n data: data.data,\n feature: analyticFeature,\n };\n\n console.log('EventLogHandler:', dataObject);\n }\n}\n","import getBasePath from '@/lib/utils/getBasePath/getBasePath';\nimport axios from 'axios';\nimport AbstractAnalyticsHandler, { IEvent } from './abstractAnalyticsHandler';\n\n/**\n * KlaviyoEventHandler\n *\n * @augments AbstractAnalyticsHandler\n */\nexport default class KlaviyoEventHandler extends AbstractAnalyticsHandler {\n /** @param {IEvent} data - The data to be sent with the event */\n async send(data: IEvent) {\n const eventData = {\n data: {\n type: 'event',\n attributes: {\n properties: data.data.attributes,\n time: new Date(),\n metric: {\n data: {\n type: 'metric',\n attributes: {\n name: data.name,\n },\n },\n },\n profile: {\n data: {\n type: 'profile',\n attributes: data.data.profile,\n },\n },\n },\n },\n };\n axios.post(`${getBasePath()}/api/klaviyo/events`, eventData);\n }\n}\n","import { googleTagManagerBrand } from '../constants/constants/analytics';\nimport EventEmitter from './eventEmitter';\nimport EventLogHandler from './handlers/eventLogHandler';\nimport GoogleTagManagerHandler from './handlers/googleTagManagerHandler';\nimport KlaviyoEventHandler from './handlers/klaviyoEventHandler';\n\n/** Instances of each handler class */\nconst logEventHandler = new EventLogHandler(googleTagManagerBrand);\nconst gtmEventHandler = new GoogleTagManagerHandler(googleTagManagerBrand);\nconst klaviyoEventHandler = new KlaviyoEventHandler(googleTagManagerBrand);\n\n/** Instances of each emitter */\nexport const logEventEmitter = new EventEmitter([logEventHandler]);\nexport const gtmEventEmitter = new EventEmitter([gtmEventHandler]);\n\n/** DefaultEventEmitter to contain all handlers */\nexport const defaultEventEmitter = new EventEmitter([\n logEventHandler,\n gtmEventHandler,\n]);\n\n/** KlaviyoEventEmitter to contain Klaviyo related handlers */\nexport const klaviyoEventEmitter = new EventEmitter([\n logEventHandler,\n klaviyoEventHandler,\n]);\n","import AbstractAnalyticsHandler, {\n IEvent,\n} from './handlers/abstractAnalyticsHandler';\n\n/**\n * EventEmitter\n *\n * This will be used to dispatch each event to the appropriate handler\n *\n * @class\n */\nexport default class EventEmitter {\n /**\n * The handlers to be used for each event\n *\n * @memberof EventEmitter\n * @member {AbstractAnalyticsHandler[]} handlers\n */\n private handlers: AbstractAnalyticsHandler[];\n\n /** @param {AbstractAnalyticsHandler[]} handlers - Instances of handlerClasses */\n constructor(handlers: AbstractAnalyticsHandler[]) {\n this.handlers = handlers;\n }\n\n /**\n * The event handler\n *\n * @param {IEvent} data - Information about the event\n */\n handleEvent(data: IEvent) {\n this.handlers.forEach((handler) => {\n handler.send(data);\n });\n }\n}\n","import { notApplicableString } from '@/lib/constants/constants/analytics';\nimport { analyticsFeatureKey } from '@/lib/utils/featureFlags/optimizely/featureFlagOverride';\nimport CookieStorage from '@/lib/utils/storage/cookie-storage';\n\n/** @typedef validTypes - Valid types for event data */\ntype ValidTypes = string | number | boolean | object | null | undefined;\n\n/** @typedef eventData - How to pass the data within the event */\ntype EventData = { [key: string]: ValidTypes };\n\n/**\n * Describes the base event structure\n *\n * @interface IEvent\n */\nexport interface IEvent {\n /**\n * The name of the event\n *\n * @memberof IEvent\n * @member {string} name\n */\n name: string;\n /**\n * The data associated with the event\n *\n * @memberof IEvent\n * @member {EventData} data - The data associated with the event\n */\n data: EventData;\n}\n\n/**\n * Provides an abstract class for analytics handlers\n *\n * @abstract\n * @class\n * @name analyticsHandler\n */\nexport default abstract class AbstractAnalyticsHandler {\n /**\n * The source platform of the event data\n *\n * @memberof AbstractAnalyticsHandler\n * @member {string} brand\n */\n brand: string;\n\n /**\n * @memberof AbstractAnalyticsHandler\n * @param {string} brand - The source platform of the event data\n */\n constructor(brand: string) {\n this.brand = brand;\n }\n\n /**\n * @memberof AbstractAnalyticsHandler\n * @returns {string} - The analytic feature that is enabled\n * @protected\n */\n protected getAnalyticsFeature(): string {\n const cookies = new CookieStorage();\n const optimizelyDecision = cookies.get(analyticsFeatureKey) as {\n /** The analytic feature that is enabled */\n analytic: string;\n };\n let feature: string = notApplicableString;\n if (optimizelyDecision && optimizelyDecision.analytic) {\n // Split the string into an array\n feature = optimizelyDecision.analytic;\n }\n return feature;\n }\n\n /**\n * @memberof AbstractAnalyticsHandler\n * @abstract\n * @param {IEvent} data - The data to be sent with the event\n */\n abstract send(data: IEvent): void;\n}\n","import AbstractAnalyticsHandler, { IEvent } from './abstractAnalyticsHandler';\n\n/**\n * GoogleTagManagerHandler\n *\n * @augments AbstractAnalyticsHandler\n */\nexport default class GoogleTagManagerHandler extends AbstractAnalyticsHandler {\n /** @param {IEvent} data - The data to be sent with the event */\n send(data: IEvent) {\n const feature = this.getAnalyticsFeature();\n /** The data object to be sent to Google Tag Manager */\n const dataObject: { [key: string]: string | string[] } = {\n brand: this.brand,\n ...data.data,\n feature,\n };\n gtag('event', data.name, dataObject);\n }\n}\n","/**\n * Content Type Enum for content types\n *\n * @enum\n */\nexport enum ContentType {\n Article,\n Author,\n}\n\n/**\n * Content Status Enum for content statuses\n *\n * @enum\n */\nexport enum ContentStatus {\n Draft,\n Published,\n}\n\n/**\n * Content Base Abstract Class for Content Types\n *\n * @abstract\n * @class\n * @property {ContentType} type - The type of content\n * @property {ContentStatus} status - The status of the content\n */\nexport default abstract class Content {\n type: ContentType;\n\n status: ContentStatus;\n\n /**\n * @param {ContentType} type - The type of content\n * @param {ContentStatus} status - The status of the content\n */\n constructor(type: ContentType, status: ContentStatus) {\n this.type = type;\n this.status = status;\n }\n}\n","import { ICardArticle } from '@/components/molecules/CardArticle/CardArticle';\nimport Content, { ContentStatus, ContentType } from './content-base';\n\n/**\n * Article Interface for Article Content Type\n *\n * @interface\n */\nexport interface IContent {\n /** Title of the Article */\n title: string;\n /** Author of the Article */\n authorName: string;\n /** Author Slug of the Article */\n authorSlug: string;\n /** Date the Article was published */\n publishedDate: Date;\n /** Slug of the Article */\n slug: string;\n /** Featured Photo of the Article */\n featuredPhoto: string;\n /** Body Content of the Article */\n contentBody: string;\n /** Excerpt of the Article */\n excerpt: string;\n /** Category of the Article */\n categoryId: string;\n}\n\n/**\n * Article Class for Article Content Type\n *\n * @class\n * @property {string} title - The title of the article\n * @property {Date} publishedDate - The date the article was published\n * @property {string} slug - The slug of the article\n * @property {string} featuredPhoto - The featured photo of the article\n * @property {string} contentBody - The content of the article\n * @requires Content\n */\nexport default class Article extends Content {\n /**\n * Title of the Article\n *\n * @memberof Article\n * @member {string} title\n */\n title: string;\n\n /**\n * Author of the Article\n *\n * @memberof Article\n * @member {string} authorName\n */\n authorName: string;\n\n /**\n * Author slug of the Article\n *\n * @memberof Article\n * @member {string} authorSlug\n */\n authorSlug: string;\n\n /**\n * Date the Article was published\n *\n * @memberof Article\n * @member {Date} publishedDate\n */\n publishedDate: Date;\n\n /**\n * Slug of the Article\n *\n * @memberof Article\n * @member {string} slug\n */\n slug: string;\n\n /**\n * Featured Photo of the Article\n *\n * @memberof Article\n * @member {string} featuredPhoto\n */\n featuredPhoto: string;\n\n /**\n * Content Body of the Article\n *\n * @memberof Article\n * @member {string} contentBody\n */\n contentBody: string;\n\n /**\n * Excerpt of the Article\n *\n * @memberof Article\n * @member {string} excerpt\n */\n excerpt: string;\n\n /**\n * Category id of the Article\n *\n * @memberof Article\n * @member {string} category\n */\n categoryId: string;\n\n /**\n * The base path for articles\n *\n * @memberof Article\n * @member {'/articles'} articlesBasePath\n */\n articlesBasePath: `/${string}` = '/articles';\n\n /**\n * The base path for authors\n *\n * @memberof Article\n * @member {'/author'} authorBasePath\n */\n authorBasePath = '/author';\n\n /**\n * Article Data Constructor\n *\n * @param {IContent} content - The content data\n */\n constructor({\n title,\n authorName,\n authorSlug,\n slug,\n featuredPhoto,\n contentBody,\n excerpt,\n categoryId,\n publishedDate,\n }: IContent) {\n super(ContentType.Article, ContentStatus.Published);\n\n this.title = title;\n this.authorName = authorName;\n this.authorSlug = authorSlug;\n this.publishedDate = publishedDate;\n this.slug = slug;\n this.contentBody = contentBody;\n this.excerpt = excerpt;\n this.featuredPhoto = featuredPhoto;\n this.categoryId = categoryId;\n }\n\n /**\n * Get Title Returns the Title of the Article\n *\n * @returns {string} - Title of the Article\n */\n getTitle(): string {\n return this.title;\n }\n\n /**\n * Get Featured Photo Returns the Featured Photo of the Article\n *\n * @returns {string} - Featured Photo URL of the Article\n */\n getFeaturedPhoto(): string {\n return this.featuredPhoto;\n }\n\n /**\n * Get Slug Returns the Slug of the Article\n *\n * @returns {string} - Slug of the Article\n */\n getSlug(): string {\n return this.slug;\n }\n\n /**\n * Get Author Link Returns the link to the Author of the Article\n *\n * @returns {string} - Author link\n */\n getAuthorUrl(): string {\n return `${this.authorBasePath}/${this.authorSlug}`;\n }\n\n /**\n * Get Content of the Article Returns the Content of the Article\n *\n * @returns {string} - Content of the Article\n */\n getContent(): string {\n return this.contentBody;\n }\n\n /**\n * Get Formatted Publication Date of the Article\n *\n * @returns {string} - Formatted Publication Date of the Article\n */\n getFormattedPublishedDate(): string {\n const date = new Date(this.publishedDate);\n\n return date.toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n });\n }\n\n /**\n * Get the article url\n *\n * @returns {string} - Url of the Article\n */\n getArticleUrl(): `/${string}` {\n return `${this.articlesBasePath}/${this.slug}`;\n }\n\n /**\n * Get the card article for the Articles Display component\n *\n * @returns {string} - Article card of the Article\n */\n getCardArticle(): ICardArticle {\n return {\n title: this.title,\n excerpt: this.excerpt,\n url: this.getArticleUrl(),\n image: this.featuredPhoto,\n };\n }\n}\n","import Article, { IContent } from '@/lib/dataSource/content/article';\nimport IFetchArticles from '@/lib/interfaces/fetch-articles';\nimport getBasePath from '@/lib/utils/getBasePath/getBasePath';\nimport { addHttps } from '@/lib/utils/stringReplace/addHttps';\nimport { ArticleProps } from '@/pages/articles/[slug]';\nimport { documentToReactComponents } from '@contentful/rich-text-react-renderer';\n\n/**\n * Contentful Data Class for Contentful Data Source API\n *\n * @class\n * @requires axios\n * @requires ContentfulItemResponse\n * @requires Item\n */\nexport default class ContentfulData implements IFetchArticles {\n path: string;\n\n /** Contentful Data Constructor */\n constructor() {\n this.path = `${\n process.env.NEXT_PUBLIC_BASE_URL\n }${getBasePath()}/api/articles/`;\n }\n\n /**\n * Get Article From Slug Fetches an article from the Contentful CMS API by its\n * slug\n *\n * @param {string} slug - The slug of the article\n * @returns {Promise<Article>} Promise<Article>\n */\n async getArticleFromSlug(slug: string): Promise<Article> {\n try {\n const params = {\n limit: '1',\n skip: '0',\n slug: slug,\n };\n const response = await fetch(\n `${this.path}?${new URLSearchParams(params)}`\n );\n const contentfulData = await response.json();\n const responseItem = contentfulData.items[0];\n const displayDate = new Date(responseItem.fields.publishDate);\n const articleContent = {\n title: responseItem.fields.headline,\n slug: responseItem.fields.slugs,\n contentBody: documentToReactComponents(responseItem.fields.copy),\n excerpt: responseItem.fields.excerpt,\n authorName: responseItem.fields.author?.fields.name,\n authorSlug: responseItem.fields.author?.fields.slugs,\n categoryId: responseItem.fields.context,\n featuredPhoto: addHttps(\n responseItem.fields.featuredImage?.fields?.file?.url\n ),\n publishedDate: displayDate,\n } as IContent;\n return new Article(articleContent);\n } catch (err) {\n console.error(err);\n throw new Error('Error fetching article from slug for Contentful CMS');\n }\n }\n\n /**\n * Get Articles Fetches a list of articles from Contentful CMS\n *\n * @param {number} limit - The number of articles to fetch\n * @param {number} skip - The number of articles to skip\n * @returns {Promise<Article[]>} Promise<Article[]>\n */\n async getArticles(limit: number, skip: number): Promise<Article[]> {\n try {\n const params = {\n skip: skip?.toString(),\n limit: limit?.toString(),\n parent: '/lost',\n };\n\n const response = await fetch(\n `${this.path}?${new URLSearchParams(params)}`\n );\n const contentfulData = await response.json();\n const articles = contentfulData.items.map((item: ArticleProps) => {\n const displayDate = new Date(item.fields.publishDate);\n const articleContent = {\n title: item.fields.headline,\n slug: item.fields.slugs,\n contentBody: documentToReactComponents(item.fields.copy),\n excerpt: item.fields.excerpt,\n authorName: item.fields.author?.fields.name,\n authorSlug: item.fields.author?.fields.slugs,\n categoryId: item.fields.context,\n featuredPhoto: addHttps(item.fields.featuredImage?.fields?.file?.url),\n publishedDate: displayDate,\n } as IContent;\n return new Article(articleContent);\n });\n return articles;\n } catch (err) {\n console.error(err);\n throw new Error('Error fetching articles for Contentful CMS');\n }\n }\n\n /**\n * Get Total Articles Fetches the total number of articles from Contentful CMS\n * by Author\n *\n * @param {string} authorContentID - The content ID of the author\n * @param {number} limit - The number of articles to fetch\n * @param {number} skip - The number of articles to skip\n * @returns {Promise<Article[]>} Promise<Article[]>\n */\n async getArticlesByAuthor(\n authorContentID: number,\n limit?: number,\n skip?: number\n ): Promise<Article[]> {\n try {\n const params = {\n skip: skip?.toString() || '0',\n limit: limit?.toString() || '10',\n author: authorContentID.toString(),\n };\n\n const response = await fetch(\n `${this.path}?${new URLSearchParams(params)}`\n );\n const contentfulData = await response.json();\n const articles: Article[] = contentfulData.items.map(\n (item: ArticleProps) => {\n const displayDate = new Date(item.fields.publishDate);\n const articleContent = {\n title: item.fields.headline,\n slug: item.fields.slugs,\n contentBody: documentToReactComponents(item.fields.copy),\n excerpt: item.fields.excerpt,\n authorName: item.fields.author?.fields.name,\n authorSlug: item.fields.author?.fields.slugs,\n categoryId: item.fields.context,\n featuredPhoto: addHttps(\n item.fields.featuredImage?.fields?.file?.url\n ),\n publishedDate: displayDate,\n } as IContent;\n return new Article(articleContent);\n }\n );\n return articles;\n } catch (err) {\n console.error(err);\n throw new Error('Error fetching articles by author for Contentful CMS');\n }\n }\n\n /**\n * Get Articles By Category Fetches a list of articles from Contentful CMS by\n * Category\n *\n * @param {string} categoryId - The category id of the article\n * @param {number} limit - The number of articles to fetch\n * @param {number} skip - The number of articles to skip\n * @returns {Promise<Article[]>} Promise<Article[]>\n */\n async getArticlesByCategory(\n categoryId: string,\n limit?: number,\n skip?: number\n ): Promise<Article[]> {\n try {\n const params = {\n skip: skip?.toString() || '0',\n limit: limit?.toString() || '10',\n parent: categoryId,\n };\n\n const response = await fetch(\n `${this.path}?${new URLSearchParams(params)}`\n );\n const contentfulData = await response.json();\n const articles: Article[] = contentfulData.items.map(\n (item: ArticleProps) => {\n const displayDate = new Date(item.fields.publishDate);\n const articleContent = {\n title: item.fields.headline,\n slug: item.fields.slugs,\n contentBody: documentToReactComponents(item.fields.copy),\n excerpt: item.fields.excerpt,\n authorName: item.fields.author?.fields.name,\n authorSlug: item.fields.author?.fields.slugs,\n categoryId: item.fields.context,\n featuredPhoto: addHttps(\n item.fields.featuredImage?.fields?.file?.url\n ),\n publishedDate: displayDate,\n } as IContent;\n return new Article(articleContent);\n }\n );\n return articles;\n } catch (err) {\n console.error(err);\n throw new Error('Error fetching articles by category Contentful CMS');\n }\n }\n}\n","import { PetcoLoveSDK } from '@petcolove/lost--client--api-sdk';\n\n/**\n * Initialize the SDK\n *\n * @returns {PetcoLoveSDK} The SDK instance\n */\nexport function initSDK(): PetcoLoveSDK {\n /**\n * The PLL API base URL\n *\n * @constant {string | undefined} pllApiBaseUrl\n */\n const pllApiBaseUrl =\n process.env.NEXT_PUBLIC_PLL_API_BASE_URL ??\n process.env.STORYBOOK_PLL_API_BASE_URL;\n /**\n * The PLL Websocket base URL\n *\n * @constant {string | undefined} pllWebsocketBaseUrl\n */\n const pllWebsocketBaseUrl =\n process.env.NEXT_PUBLIC_PLL_WEBSOCKET_BASE_URL ??\n process.env.STORYBOOK_PLL_WEBSOCKET_BASE_URL;\n\n if (!pllApiBaseUrl) {\n throw new Error('NEXT_PUBLIC_PLL_API_BASE_URL is not defined');\n }\n\n if (!pllWebsocketBaseUrl) {\n throw new Error('NEXT_PUBLIC_PLL_WEBSOCKET_BASE_URL is not defined');\n }\n\n const sdk = new PetcoLoveSDK(pllApiBaseUrl, pllWebsocketBaseUrl);\n\n return sdk;\n}\n\nexport const sdk: PetcoLoveSDK = initSDK();\n","/* eslint-disable react-hooks/exhaustive-deps, jsdoc/tag-lines */\nimport { IResultsForPagination } from '@/lib/interfaces/pagination';\nimport {\n GetNextPageParamFunction,\n InfiniteData,\n useInfiniteQuery,\n UseInfiniteQueryResult,\n} from '@tanstack/react-query';\nimport { useCallback, useMemo, useState } from 'react';\n\n/**\n * This is the options object for the usePagination hook.\n *\n * @template TRequestData,TResponseData\n * @interface\n */\nexport interface IUsePaginationOptions<TRequestData, TResponseData> {\n /**\n * Load the initial page of data when the hook is first called.\n *\n * @type {boolean}\n */\n loadInitial?: boolean;\n /**\n * A callback function to call after the data is fetched.\n *\n * We can use this callback to send analytics once the data is fetched.\n *\n * @param {number} page - The page number that was fetched.\n * @param {TRequestData} params - The request parameters that were used.\n * @param {TResponseData} results - The results from the fetch.\n * @returns {Promise<void>} - A promise that resolves when the callback is\n * done.\n */\n postDataFetchCallback?: (\n params: TRequestData,\n results: TResponseData\n ) => Promise<void>;\n}\n\n/**\n * This is the interface for the usePagination hook.\n *\n * @interface IUsePagination\n */\nexport interface IUsePagination<TResponseData, TResponseDataItem> {\n /** The accumulated data from all pages for display */\n dataForDisplay: TResponseDataItem[];\n /**\n * The function to update the request params\n *\n * @template TRequestData,TResponseData\n * @param {TResponseData} params - The new request params\n * @returns {void} - No return value\n */\n setRequestParams: (params: TResponseData) => void;\n}\n\n/**\n * This is the interface for the query function parameters.\n *\n * @interface IQueryFnParams\n */\ninterface IQueryFnParams {\n /** The page parameter to pass to the query function. */\n pageParam: number;\n}\n\n/**\n * The function to get the next page parameter for tanstack/react-query.\n *\n * It should return null or undefined if there are no more pages to fetch.\n *\n * @param {IResultsForPagination} lastPage - The last page of data.\n * @returns {number | null} - The next page parameter.\n * @see {@link https://tanstack.com/query/latest/docs/framework/react/guides/infinite-queries}\n */\nfunction getNextPageParamFunction<TResponseDataItem>(\n lastPage: IResultsForPagination<TResponseDataItem>\n): number | null {\n /**\n * Whether if the last page exists or not.\n *\n * @constant {boolean} lastPageExists\n */\n const lastPageExists = lastPage?.data;\n /**\n * Whether if the last page is not empty.\n *\n * @constant {boolean} lastPageIsNotEmpty\n */\n const lastPageIsNotEmpty = lastPage?.data.length > 0;\n\n if (lastPageExists && lastPageIsNotEmpty) {\n return lastPage.page + 1;\n }\n // Explicit null return to indicate no more pages\n return null;\n}\n\n/**\n * This is hook to handle pagination for pet searches using tanstack.\n *\n * @example <caption>Example of the usePagination hook to get image search pets </caption> ```typescript\n * const { data, fetchNextPage, hasNextPage, isFetching, refetch, setRequestParams } = usePagination<\n * IGetImageSearchParams, IImageSearchResultsResponse\n * >(\n * petSearchRequestParams, getImageSearchResults, { postDataFetchCallback: sendToAnalytics },\n * );\n * ```typescript\n *\n * @example <caption>Example of the petSearchFunction return type </caption> ```typescript\n * return { data: [...], page: 1 }\n * ```typescript\n *\n * @template TRequestData,TResponseData, TResponseDataItem\n * @param {function(number, TRequestData): Promise<TResponseData>} petSearchFunction\n * - The function that will be used to get the pet search results. It should\n * return a promise that resolves to an object with a data property that\n * is an array of the data for the requested page. It should also return\n * the requested page number as page\n *\n * @param {TRequestData} params - The params to pass to the API call for the pet\n * search.\n * @param {IUsePaginationOptions} options - Optional object options for the\n * hook.\n * @returns {UseInfiniteQueryResult<\n * InfiniteData<TResponseData, unknown>,\n * Error\n * > &\n * IUsePagination<TRequestData>}\n * - The state of the hook.\n */\nexport function usePagination<\n TRequestData,\n TResponseData extends IResultsForPagination<TResponseDataItem>,\n TResponseDataItem = object\n>(\n /**\n * - The function that will be used to get the pet search results. It should\n * return a promise that resolves to an object with a data property that is\n * an array of the data for the requested page. It should also return the\n * requested page number as page\n *\n * @param {number} page - The page number to fetch.\n * @param {TRequestData} params - The data that will be passed to the\n * @returns {Promise<{ data: TResponseData[] }>} - This is a promise that\n * resolves to the data\n */\n petSearchFunction: (\n pageParam: number,\n requestParams: TRequestData\n ) => Promise<TResponseData>,\n params: TRequestData,\n options?: IUsePaginationOptions<TRequestData, TResponseData>\n): UseInfiniteQueryResult<InfiniteData<TResponseData, unknown>, Error> &\n IUsePagination<TRequestData, TResponseDataItem> {\n /**\n * The parameters for the request.\n *\n * @constant {TRequestData} requestParams\n */\n const [requestParams, setRequestParams] = useState<TRequestData>(params);\n\n /**\n * The function to get the next page parameter for tanstack/react-query.\n *\n * It should return null or undefined if there are no more pages to fetch.\n *\n * @param {TResponseData} lastPage - The last page of data.\n * @returns {number | null} - The next page parameter.\n * @see {@link https://tanstack.com/query/latest/docs/framework/react/guides/infinite-queries}\n */\n const getNextPageParam: GetNextPageParamFunction<number, TResponseData> = (\n lastPage: TResponseData\n ): number | null => getNextPageParamFunction<TResponseDataItem>(lastPage);\n\n /**\n * The query function to get the image search results using\n * tanstack/react-query.\n *\n * @param {IQueryFnParams} params - The parameters for the query function.\n * @returns {Promise<TRequestData>} - The search results.\n * @see {@link https://tanstack.com/query/latest/docs/framework/react/guides/infinite-queries}\n */\n const queryFn = useCallback(\n async ({ pageParam }: IQueryFnParams): Promise<TResponseData> => {\n /**\n * The results from the search.\n *\n * @constant {TRequestData} results\n */\n const results = await petSearchFunction(pageParam, requestParams);\n\n // Call the post data fetch callback if it exists with the parameters, the page and the results\n await options?.postDataFetchCallback?.(requestParams, results);\n\n return results;\n },\n [options, petSearchFunction, requestParams]\n );\n\n /**\n * The infinite query object from tanstack/react-query.\n *\n * @constant {UseInfiniteQueryResult<\n * InfiniteData<TRequestData, unknown>,\n * Error\n * >} infiniteQuery\n * @see {@link https://tanstack.com/query/latest/docs/framework/react/guides/infinite-queries}\n */\n const infiniteQuery: UseInfiniteQueryResult<\n InfiniteData<TResponseData, unknown>,\n Error\n > = useInfiniteQuery({\n queryKey: ['petSearch', requestParams, options],\n queryFn,\n initialPageParam: 1,\n getNextPageParam,\n refetchOnWindowFocus: false,\n });\n\n /**\n * The data for display.\n *\n * @constant {TResponseDataItem[]} dataForDisplay\n */\n const dataForDisplay = useMemo(\n () =>\n infiniteQuery.data?.pages.reduce(\n /**\n * Reduce function to combine the data from all pages into a single\n * array for display.\n *\n * @param {TResponseDataItem[]} acc - The accumulator for the reduce\n * function.\n * @param {TRequestData} page - The page of data to add to the\n * accumulator.\n * @returns {TResponseDataItem[]} - The accumulator with all the page\n * data added.\n */\n (\n acc: TResponseDataItem[],\n page: TResponseData\n ): TResponseDataItem[] => [...acc, ...page.data],\n [] as TResponseDataItem[]\n ),\n [infiniteQuery.data]\n );\n\n return {\n ...infiniteQuery,\n dataForDisplay: dataForDisplay\n ? (dataForDisplay as TResponseDataItem[])\n : [],\n setRequestParams,\n };\n}\n","import { sdk } from '@/lib/dataSource/lostApi/common';\nimport { IConversationTotalUnreadCountResponseData } from '@petcolove/lost--client--api-sdk/dist/concrete/sdks/interfaces/chat';\n\n/**\n * The params for the total unread conversation\n *\n * @interface IConversationTotalUnreadCountParams\n */\ninterface IConversationTotalUnreadCountParams {\n /** The auth token */\n authToken: string;\n /** The user entity id */\n userEntityId: number;\n}\n\n/**\n * Get the total of unread conversation\n *\n * @param {IConversationTotalUnreadCountParams} params - The params for the total unread function\n * @returns {Promise<IConversationTotalUnreadCountResponseData>} The list of all\n * conversations\n */\nexport async function totalUnread({\n authToken,\n userEntityId,\n}: IConversationTotalUnreadCountParams): Promise<IConversationTotalUnreadCountResponseData> {\n try {\n const conversations = await sdk\n .conversationsTotalUnread({\n contextId: userEntityId,\n authToken,\n })\n .read();\n return conversations.data;\n } catch (error) {\n console.error(error);\n throw error;\n }\n}\n","import { totalUnread } from '@/lib/dataSource/lostApi/chat/conversations/totalUnread';\nimport useMe, { IUseMe } from '@/lib/hooks/me/useMe';\nimport {\n Context,\n Dispatch,\n ReactNode,\n SetStateAction,\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from 'react';\n\n/** The types of users that can be returned */\nexport type UserType = 'shelter' | 'user';\n\n/**\n * The type used to create the context\n *\n * @interface\n */\nexport interface IUserContext extends IUseMe {\n /** If the user has unread messages */\n hasMessage: boolean;\n /** A method for returning the user type */\n userType: UserType | null;\n /** The number of unread messages for the user */\n unreadMessageCount: number;\n /** The fetch state of unread messages count */\n fetchingUnreadMessageCount: boolean;\n /** The logged in state of the user */\n isLoggedIn: boolean;\n /** Whether if the logged in user is a shelter or not */\n isShelter: boolean;\n /** The function to get unread messages for user */\n getUnreadMessagesForUser: () => Promise<void>;\n /** The unreadMessageCount setter */\n setUnreadMessageCount: Dispatch<SetStateAction<number>>;\n}\n\n/**\n * The default user context\n *\n * @constant {IUserContext}\n */\nexport const defaultUserContext: IUserContext = {\n hasMessage: false,\n userType: null,\n isFetchingUser: true,\n isLoggedIn: false,\n isShelter: true,\n unreadMessageCount: 0,\n fetchingUnreadMessageCount: false,\n getUnreadMessagesForUser:\n /** The default function to get unread messages for user */\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n async () => {},\n setUnreadMessageCount:\n /** The default function to set the unread message count */\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n () => {},\n};\n\n/**\n * The UserContext\n *\n * @constant {Context<IUserContext>}\n */\nconst UserContext: Context<IUserContext> =\n createContext<IUserContext>(defaultUserContext);\n\n/**\n * The interface for the UserProvider props\n *\n * @interface\n */\nexport interface IUserProvider {\n /** The children wrapped by the provider */\n children: ReactNode;\n}\n\n/**\n * The UserContextProvider component.\n *\n * @param {IUserProvider} props - The props for the UserContextProvider.\n * @returns {Element} - The UserContextProvider.\n */\nexport function UserContextProvider({ children }: IUserProvider): JSX.Element {\n /**\n * The data from the me hook\n *\n * @see useMe\n */\n const { idToken, me, isFetchingUser, isError, errorMessage } = useMe();\n /**\n * The total unread message count\n *\n * @constant {number}\n */\n const [unreadMessageCount, setUnreadMessageCount] = useState<number>(0);\n /**\n * The fetch state of unread messages count\n *\n * @constant {boolean}\n */\n const [fetchingUnreadMessageCount, setFetchingUnreadMessageCount] =\n useState(true);\n /**\n * If the user has unread messages\n *\n * @constant {boolean}\n */\n const hasMessage = useMemo(\n () => unreadMessageCount > 0,\n [unreadMessageCount]\n );\n\n /** This will determine the type of user that is currently logged in. */\n const userType = useMemo(() => {\n let userType: UserType | null = null;\n\n if (me?.awos) {\n userType = 'shelter';\n } else if (me?.user && !me?.awos) {\n userType = 'user';\n }\n return userType;\n }, [me?.awos, me?.user]);\n\n /**\n * The logged in state of the user We get it by checking if we are able to get\n * a user type from the me object\n *\n * @constant {boolean}\n */\n const isLoggedIn = useMemo(() => {\n return !isFetchingUser && userType !== null;\n }, [isFetchingUser, userType]);\n\n /**\n * Whether if the logged in user is a shelter or not\n *\n * We explicitly check if the user type is of type 'user' so we do not show\n * user specific options while we determine the user type\n *\n * @constant {boolean}\n */\n const isShelter = useMemo(() => {\n if (userType === 'user') {\n return false;\n }\n return true;\n }, [userType]);\n\n /**\n * Callback to get the total unread messages for a user\n *\n * @returns {void}\n */\n const getUnreadMessagesForUser = useCallback(async () => {\n if (!me || !idToken || userType === 'shelter')\n return setUnreadMessageCount(0);\n /**\n * @property {string} id - The user id\n * @property {string} idToken - The user idToken\n */\n const {\n user: { id },\n } = me;\n try {\n /**\n * The response from the totalUnread function\n *\n * @property {number} unread - The total unread messages for a user\n */\n const { unread } = await totalUnread({\n authToken: idToken,\n userEntityId: id,\n });\n\n if (unread !== unreadMessageCount) {\n setUnreadMessageCount(unread);\n }\n } catch (error) {\n console.error('Error fetching unread messages', error);\n } finally {\n setFetchingUnreadMessageCount(false);\n }\n }, [idToken, me, unreadMessageCount, userType]);\n\n /** Make initial call for unread messages */\n useEffect(() => {\n getUnreadMessagesForUser();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [idToken, me]);\n\n return (\n <UserContext.Provider\n value={{\n idToken,\n hasMessage,\n me,\n userType,\n isLoggedIn,\n isShelter,\n isFetchingUser,\n getUnreadMessagesForUser,\n unreadMessageCount,\n setUnreadMessageCount,\n fetchingUnreadMessageCount,\n isError,\n errorMessage,\n }}\n >\n {children}\n </UserContext.Provider>\n );\n}\n\n/**\n * A hook to access the UserContext\n *\n * @returns {IUserContext} - The UserContext\n */\nexport const useUserContext = (): IUserContext => useContext(UserContext);\n","// Today's date\nexport const today = new Date();\n// Tomorrow's Date\nexport const tomorrow = new Date(today.getTime() + 86400000);\n\n/**\n * Get a date object that is X minutes from now\n *\n * @param {number} minutes - Time in minutes\n * @returns {Date} A date object that is X minutes from now\n */\nexport const getDateXMinutesFromNow = (minutes: number) => {\n return new Date(new Date().getTime() + minutes * 60 * 1000);\n};\n\n/**\n * Check if a date is valid\n *\n * @param {string} date - The date to check\n * @returns {boolean} - True if the date is valid, false otherwise\n */\nexport const isDateValid = (date: string) => {\n return !isNaN(new Date(date).getTime());\n};\n","import AbstractStorage, { IStorageConfig } from './abstract-storage';\n\n/**\n * LocalStorage Local Storage is available across all browser tabs. It is not\n * cleared when the tab is closed.\n *\n * @augments AbstractStorage\n * @class\n */\nexport default class LocalStorage extends AbstractStorage {\n /**\n * Get Get the data from the local storage.\n *\n * @param {string} id - The id of the data to get.\n * @returns {object | null} - The data or null if not found.\n */\n get(id: string): object | string | null {\n if (typeof window === 'undefined') {\n return null;\n }\n const data = localStorage.getItem(id);\n\n if (!data) return null;\n // Parse the data and check if the expiration date is passed\n let parsedData = null;\n\n parsedData = JSON.parse(data);\n if (parsedData.expiration && new Date(parsedData.expiration) < new Date()) {\n this.delete(id);\n return null;\n }\n return parsedData;\n }\n\n /**\n * Set Set the data in the local storage.\n *\n * @param {string} id - The id of the data to set.\n * @param {object | string} data - The data to set.\n * @param {IStorageConfig} [config] - The configuration for the local storage.\n */\n set(id: string, data: object | string, config?: IStorageConfig): void {\n if (config?.expires) {\n if (typeof data === 'string') {\n data = { data, expiration: config.expires };\n } else {\n data = { ...data, expiration: config.expires };\n }\n }\n localStorage.setItem(id, JSON.stringify(data));\n }\n\n /**\n * Delete Delete the data from the local storage.\n *\n * @param {string} id - The id of the data to delete.\n */\n delete(id: string): void {\n localStorage.removeItem(id);\n }\n}\n","/**\n * Get the expiration date from the data.\n *\n * @param {object | null} data - The data.\n * @returns {Date | null} - The expiration date or null if not found.\n */\nfunction getExpirationDate(\n data: { [key: string]: unknown } | null\n): Date | null {\n if (\n data !== null &&\n 'expiration' in data &&\n data?.expiration &&\n typeof data.expiration === 'string'\n ) {\n /**\n * The expiration date from the data.\n *\n * @constant {Date} expirationDate\n */\n const expirationDate = new Date(data.expiration);\n\n if (!isNaN(expirationDate.getTime())) {\n return expirationDate;\n }\n console.error('Invalid expiration date: ', data.expiration);\n }\n\n return null;\n}\n\nexport default getExpirationDate;\n","/**\n * A helper function to parse a JSON string safely\n *\n * @param {string} str - The string to parse\n * @returns {string | object} - The parsed JSON object or the string\n */\nfunction parseToJSONSafe(str: string): string | { [key: string]: unknown } {\n try {\n return JSON.parse(str);\n } catch (error) {\n console.error('Unable to parse string to JSON: ', str);\n }\n return str;\n}\n\nexport default parseToJSONSafe;\n","import getExpirationDate from '../helpers/ObjectsHelpers/getExpirationDate';\nimport parseToJSONSafe from '../helpers/stringHelpers/parseToJSONSafe';\nimport AbstractStorage, { IStorageConfig } from './abstract-storage';\n\n/**\n * SessionStorage Session Storage is a storage that is available only in the\n * current browser tab. It is cleared when the tab is closed. It is not shared\n * between tabs.\n *\n * @augments AbstractStorage\n * @class\n */\nexport default class SessionStorage extends AbstractStorage {\n /**\n * Whether the session storage is available.\n *\n * @returns {boolean} - Whether the session storage is available.\n */\n private isAvailable(): boolean {\n return typeof window !== 'undefined';\n }\n\n /**\n * Get Get the data from the session storage.\n *\n * @param {string} id - The id of the data to get.\n * @returns {object | null} - The data or null if not found.\n */\n get(id: string): object | string | null {\n if (!this.isAvailable()) {\n return null;\n }\n const data = sessionStorage.getItem(id);\n\n if (!data) {\n return null;\n }\n\n // Parse the data and check if the expiration date is passed\n const parsedData = parseToJSONSafe(data);\n\n if (typeof parsedData === 'string') {\n return parsedData;\n }\n /**\n * The data expiration date.\n *\n * @constant {Date | null} expirationDate\n */\n const expirationDate = getExpirationDate(parsedData);\n\n if (expirationDate && expirationDate < new Date()) {\n this.delete(id);\n return null;\n }\n return parsedData;\n }\n\n /**\n * Set Set the data in the session storage.\n *\n * @param {string} id - The id of the data to set.\n * @param {object | string} data - The data to set.\n * @param {IStorageConfig} [config] - The session configuration.\n */\n set(id: string, data: object | string, config?: IStorageConfig): void {\n if (!this.isAvailable()) {\n return;\n }\n if (config?.expires) {\n if (typeof data === 'string') {\n data = { data, expiration: config.expires };\n } else {\n data = { ...data, expiration: config.expires };\n }\n }\n sessionStorage.setItem(id, JSON.stringify(data));\n }\n\n /**\n * Delete Delete the data from the session storage.\n *\n * @param {string} id - The id of the data to delete.\n */\n delete(id: string): void {\n sessionStorage.removeItem(id);\n }\n}\n","import InfiniteQueryLayout from '@/components/layouts/InfiniteQueryLayout/InfiniteQueryLayout';\nimport PrimaryLayout from '@/components/layouts/PrimaryLayout/PrimaryLayout';\nimport { ICardArticle } from '@/components/molecules/CardArticle/CardArticle';\nimport { IArticlesTemplateContent } from '@/components/templates/ArticlesTemplate/ArticlesTemplate';\nimport Head from '@/components/templates/Head/Head';\nimport Article from '@/lib/dataSource/content/article';\nimport ContentfulData from '@/lib/dataSource/contentful/contentful-data-source';\nimport { usePagination } from '@/lib/hooks/paginate/usePagination';\nimport { IResultsForPagination } from '@/lib/interfaces/pagination';\nimport { default as staticContent } from '@/locales/en/pages/ArticlesTemplate.json';\nimport { NextPage } from 'next';\n\nimport dynamic from 'next/dynamic';\nimport { ReactElement, ReactNode } from 'react';\n\nconst ArticlesTemplate = dynamic(\n import('@/components/templates/ArticlesTemplate/ArticlesTemplate')\n);\n\n/** The static text used in the page */\nconst content: IArticlesTemplateContent = staticContent.components;\n\n/**\n * The initial parameters for the fetchArticles function\n *\n * @constant {IFetchArticlesParams}\n */\nconst fetchArticlesInitialRequest = {\n limit: 6,\n skip: 0,\n};\n\n/**\n * The parameters for the fetchArticles function\n *\n * @interface IFetchArticlesParams\n */\ninterface IFetchArticlesParams {\n /** The limit of articles */\n limit: number;\n /** The number of articles to skip */\n skip: number;\n}\n\n/**\n * The response data for the fetchArticles function\n *\n * @interface IResponseData\n */\nexport interface IResponseData extends IResultsForPagination<ICardArticle> {\n /** The card articles for display */\n data: ICardArticle[];\n /** The requested page number */\n page: number;\n}\n\n/**\n * The instance of the Contentful Data Source\n *\n * @constant {ContentfulData}\n */\nconst contentfulData = new ContentfulData();\n\n/**\n * Fetches the articles and returns the data for display\n *\n * @param {number} page - The page number\n * @param {IFetchArticlesParams} params - The parameters for the fetchArticles\n * function\n * @returns {Promise<IResponseData>} Articles for display\n */\nexport const fetchArticles = async (\n page: number,\n params: IFetchArticlesParams\n): Promise<IResponseData> => {\n const { limit } = params;\n /**\n * The number of articles to skip\n *\n * @returns {number} The number of articles to skip\n */\n const skip =\n /** Start with the initial skip passed in params */\n params.skip +\n /**\n * Accomplish page increase by multiplying the limit per each page by the\n * page number\n */\n limit *\n /**\n * The usePagination hook will initialize the page to 1, subtract 1 so the\n * skip of the first request is 0\n */\n (page - 1);\n\n const articles = await contentfulData.getArticles(limit, skip);\n return {\n data: articles.map((article: Article) => article.getCardArticle()),\n page,\n };\n};\n\n/**\n * Page for all articles\n *\n * @returns {NextPage} Page\n */\nconst ArticlesPage: NextPage = () => {\n /**\n * Pagination Hook to provide the pagination functionality\n *\n * @see usePagination\n */\n const { dataForDisplay, isFetching, hasNextPage, fetchNextPage } =\n usePagination<IFetchArticlesParams, IResponseData, ICardArticle>(\n fetchArticles,\n fetchArticlesInitialRequest,\n {\n loadInitial: true,\n }\n );\n\n return (\n <section data-testid=\"articles-page\">\n <Head\n title=\"Articles and Resources\"\n description=\"Visit Petco Love Lost for articles, videos, tips, and more about reuniting lost pest with their families.\"\n />\n <ArticlesTemplate\n articles={dataForDisplay}\n content={{ ...content }}\n isFetching={isFetching}\n hasMore={hasNextPage}\n requestNextPage={fetchNextPage}\n />\n </section>\n );\n};\n\n/**\n * Get Pet Search Layout\n *\n * @param {ReactElement} page - The page content\n * @returns {ReactNode} Page Results\n */\nArticlesPage.getLayout = (page: ReactElement): ReactNode => {\n return (\n <PrimaryLayout>\n <InfiniteQueryLayout>{page}</InfiniteQueryLayout>\n </PrimaryLayout>\n );\n};\n\nexport default ArticlesPage;\n","// src/infiniteQueryObserver.ts\nimport { QueryObserver } from \"./queryObserver.js\";\nimport {\n hasNextPage,\n hasPreviousPage,\n infiniteQueryBehavior\n} from \"./infiniteQueryBehavior.js\";\nvar InfiniteQueryObserver = class extends QueryObserver {\n constructor(client, options) {\n super(client, options);\n }\n bindMethods() {\n super.bindMethods();\n this.fetchNextPage = this.fetchNextPage.bind(this);\n this.fetchPreviousPage = this.fetchPreviousPage.bind(this);\n }\n setOptions(options, notifyOptions) {\n super.setOptions(\n {\n ...options,\n behavior: infiniteQueryBehavior()\n },\n notifyOptions\n );\n }\n getOptimisticResult(options) {\n options.behavior = infiniteQueryBehavior();\n return super.getOptimisticResult(options);\n }\n fetchNextPage(options) {\n return this.fetch({\n ...options,\n meta: {\n fetchMore: { direction: \"forward\" }\n }\n });\n }\n fetchPreviousPage(options) {\n return this.fetch({\n ...options,\n meta: {\n fetchMore: { direction: \"backward\" }\n }\n });\n }\n createResult(query, options) {\n const { state } = query;\n const parentResult = super.createResult(query, options);\n const { isFetching, isRefetching, isError, isRefetchError } = parentResult;\n const fetchDirection = state.fetchMeta?.fetchMore?.direction;\n const isFetchNextPageError = isError && fetchDirection === \"forward\";\n const isFetchingNextPage = isFetching && fetchDirection === \"forward\";\n const isFetchPreviousPageError = isError && fetchDirection === \"backward\";\n const isFetchingPreviousPage = isFetching && fetchDirection === \"backward\";\n const result = {\n ...parentResult,\n fetchNextPage: this.fetchNextPage,\n fetchPreviousPage: this.fetchPreviousPage,\n hasNextPage: hasNextPage(options, state.data),\n hasPreviousPage: hasPreviousPage(options, state.data),\n isFetchNextPageError,\n isFetchingNextPage,\n isFetchPreviousPageError,\n isFetchingPreviousPage,\n isRefetchError: isRefetchError && !isFetchNextPageError && !isFetchPreviousPageError,\n isRefetching: isRefetching && !isFetchingNextPage && !isFetchingPreviousPage\n };\n return result;\n }\n};\nexport {\n InfiniteQueryObserver\n};\n//# sourceMappingURL=infiniteQueryObserver.js.map","\"use client\";\n\n// src/useInfiniteQuery.ts\nimport { InfiniteQueryObserver } from \"@tanstack/query-core\";\nimport { useBaseQuery } from \"./useBaseQuery.js\";\nfunction useInfiniteQuery(options, queryClient) {\n return useBaseQuery(\n options,\n InfiniteQueryObserver,\n queryClient\n );\n}\nexport {\n useInfiniteQuery\n};\n//# sourceMappingURL=useInfiniteQuery.js.map"],"names":["window","__NEXT_P","push","__webpack_require__","queryClient","QueryClient","__webpack_exports__","Z","children","param","react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__","jsx","QueryClientProvider","client","EventLogHandler","AbstractAnalyticsHandler","send","data","getAnalyticsFeature","KlaviyoEventHandler","eventData","type","attributes","properties","time","Date","metric","name","profile","axios","concat","getBasePath","logEventHandler","googleTagManagerBrand","gtmEventHandler","GoogleTagManagerHandler","klaviyoEventHandler","EventEmitter","defaultEventEmitter","handleEvent","handlers","forEach","handler","constructor","cookies","CookieStorage","optimizelyDecision","get","analyticsFeatureKey","feature","notApplicableString","analytic","brand","dataObject","gtag","ContentType","ContentStatus","Content","status","Article","getTitle","title","getFeaturedPhoto","featuredPhoto","getSlug","slug","getAuthorUrl","authorBasePath","authorSlug","getContent","contentBody","getFormattedPublishedDate","date","publishedDate","toLocaleDateString","year","month","day","getArticleUrl","articlesBasePath","getCardArticle","excerpt","url","image","authorName","categoryId","Published","ContentfulData","getArticleFromSlug","responseItem","response","fetch","path","URLSearchParams","limit","skip","contentfulData","json","items","displayDate","fields","publishDate","articleContent","headline","slugs","documentToReactComponents","copy","author","context","addHttps","featuredImage","file","err","getArticles","params","toString","parent","articles","map","item","getArticlesByAuthor","authorContentID","getArticlesByCategory","process","sdk","initSDK","pllApiBaseUrl","pllWebsocketBaseUrl","PetcoLoveSDK","usePagination","petSearchFunction","options","requestParams","setRequestParams","useState","queryFn","useCallback","pageParam","results","postDataFetchCallback","infiniteQuery","useInfiniteQuery","queryKey","initialPageParam","getNextPageParam","getNextPageParamFunction","lastPage","lastPageExists","lastPageIsNotEmpty","length","page","refetchOnWindowFocus","dataForDisplay","useMemo","pages","reduce","acc","totalUnread","authToken","userEntityId","conversations","conversationsTotalUnread","contextId","read","error","UserContext","createContext","hasMessage","userType","isFetchingUser","isLoggedIn","isShelter","unreadMessageCount","fetchingUnreadMessageCount","getUnreadMessagesForUser","setUnreadMessageCount","UserContextProvider","idToken","me","isError","errorMessage","useMe","setFetchingUnreadMessageCount","awos","user","id","unread","useEffect","jsx_runtime","Provider","value","useUserContext","useContext","today","tomorrow","getTime","getDateXMinutesFromNow","minutes","isDateValid","isNaN","LocalStorage","AbstractStorage","localStorage","getItem","parsedData","JSON","parse","expiration","delete","set","config","expires","setItem","stringify","removeItem","ObjectsHelpers_getExpirationDate","expirationDate","stringHelpers_parseToJSONSafe","str","SessionStorage","isAvailable","sessionStorage","parseToJSONSafe","getExpirationDate","ArticlesTemplate","dynamic","Promise","all","e","then","bind","content","staticContent","fetchArticlesInitialRequest","fetchArticles","article","ArticlesPage","isFetching","hasNextPage","fetchNextPage","loadInitial","jsxs","section","Head","description","hasMore","requestNextPage","getLayout","PrimaryLayout","InfiniteQueryLayout","InfiniteQueryObserver","queryObserver","z","bindMethods","fetchPreviousPage","setOptions","notifyOptions","behavior","infiniteQueryBehavior","Gm","getOptimisticResult","meta","fetchMore","direction","createResult","query","state","parentResult","isRefetching","isRefetchError","fetchDirection","fetchMeta","isFetchNextPageError","isFetchingNextPage","isFetchPreviousPageError","isFetchingPreviousPage","result","Qy","hasPreviousPage","ZF","useBaseQuery","r"],"sourceRoot":""}