@clickview/lite 0.103.1 → 0.103.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/.vite/manifest.json +271 -271
  2. package/dist/bundles.json +1 -1
  3. package/dist/en.json +1 -1
  4. package/dist/scripts/{igSDXA6g.chunk.js → 1WHinyQW.chunk.js} +2 -2
  5. package/dist/scripts/{igSDXA6g.chunk.js.map → 1WHinyQW.chunk.js.map} +1 -1
  6. package/dist/scripts/{kMWvzbRv2.chunk.js → B1ag1ah72.chunk.js} +2 -2
  7. package/dist/scripts/{kMWvzbRv2.chunk.js.map → B1ag1ah72.chunk.js.map} +1 -1
  8. package/dist/scripts/{D2_GYzlb.chunk.js → B6Pc3q-u.chunk.js} +2 -2
  9. package/dist/scripts/{D2_GYzlb.chunk.js.map → B6Pc3q-u.chunk.js.map} +1 -1
  10. package/dist/scripts/{sCuSDiER2.chunk.js → BPbjSFkC2.chunk.js} +2 -2
  11. package/dist/scripts/{sCuSDiER2.chunk.js.map → BPbjSFkC2.chunk.js.map} +1 -1
  12. package/dist/scripts/{CNm_4jj62.chunk.js → BZFomoIH2.chunk.js} +2 -2
  13. package/dist/scripts/BZFomoIH2.chunk.js.map +1 -0
  14. package/dist/scripts/{CW_rYB-i2.chunk.js → BazdM9Ah2.chunk.js} +2 -2
  15. package/dist/scripts/{CW_rYB-i2.chunk.js.map → BazdM9Ah2.chunk.js.map} +1 -1
  16. package/dist/scripts/{BcPrUEuC2.chunk.js → CNPnPJMp2.chunk.js} +2 -2
  17. package/dist/scripts/{BcPrUEuC2.chunk.js.map → CNPnPJMp2.chunk.js.map} +1 -1
  18. package/dist/scripts/{Dd23z1_x2.chunk.js → CUp7_5gE2.chunk.js} +2 -2
  19. package/dist/scripts/{Dd23z1_x2.chunk.js.map → CUp7_5gE2.chunk.js.map} +1 -1
  20. package/dist/scripts/{C-zUHAyD.chunk.js → CajcIz6S.chunk.js} +2 -2
  21. package/dist/scripts/{C-zUHAyD.chunk.js.map → CajcIz6S.chunk.js.map} +1 -1
  22. package/dist/scripts/{Drx3PvJj.chunk.js → Cc9f2ux0.chunk.js} +2 -2
  23. package/dist/scripts/{Drx3PvJj.chunk.js.map → Cc9f2ux0.chunk.js.map} +1 -1
  24. package/dist/scripts/Cj_F4Lv92.chunk.js +2 -0
  25. package/dist/scripts/{C8l37H7t2.chunk.js.map → Cj_F4Lv92.chunk.js.map} +1 -1
  26. package/dist/scripts/{DFrz_upP2.chunk.js → CtBGtgb32.chunk.js} +2 -2
  27. package/dist/scripts/{DFrz_upP2.chunk.js.map → CtBGtgb32.chunk.js.map} +1 -1
  28. package/dist/scripts/{BpiZZWnJ2.chunk.js → CtWAorP42.chunk.js} +2 -2
  29. package/dist/scripts/{BpiZZWnJ2.chunk.js.map → CtWAorP42.chunk.js.map} +1 -1
  30. package/dist/scripts/{C3Qd_bbV2.chunk.js → D8mi6CVp2.chunk.js} +2 -2
  31. package/dist/scripts/{C3Qd_bbV2.chunk.js.map → D8mi6CVp2.chunk.js.map} +1 -1
  32. package/dist/scripts/{3K2h5K5-.chunk.js → DJfIirut.chunk.js} +2 -2
  33. package/dist/scripts/{3K2h5K5-.chunk.js.map → DJfIirut.chunk.js.map} +1 -1
  34. package/dist/scripts/{Cc63s6rS2.chunk.js → DaaQ5htA2.chunk.js} +2 -2
  35. package/dist/scripts/{Cc63s6rS2.chunk.js.map → DaaQ5htA2.chunk.js.map} +1 -1
  36. package/dist/scripts/{CHwPLUZK.chunk.js → DkFP4cXM.chunk.js} +2 -2
  37. package/dist/scripts/{CHwPLUZK.chunk.js.map → DkFP4cXM.chunk.js.map} +1 -1
  38. package/dist/scripts/{izXlxhJf.chunk.js → Dzy1nQk7.chunk.js} +2 -2
  39. package/dist/scripts/{izXlxhJf.chunk.js.map → Dzy1nQk7.chunk.js.map} +1 -1
  40. package/dist/scripts/{DGy8Ldlr.chunk.js → FIUOppmy.chunk.js} +2 -2
  41. package/dist/scripts/{DGy8Ldlr.chunk.js.map → FIUOppmy.chunk.js.map} +1 -1
  42. package/dist/scripts/{CPBvCqVK.chunk.js → H511PXuG.chunk.js} +2 -2
  43. package/dist/scripts/{CPBvCqVK.chunk.js.map → H511PXuG.chunk.js.map} +1 -1
  44. package/dist/scripts/{D8Op6EUa2.chunk.js → IYIY9hIU2.chunk.js} +2 -2
  45. package/dist/scripts/{D8Op6EUa2.chunk.js.map → IYIY9hIU2.chunk.js.map} +1 -1
  46. package/dist/scripts/{app-BHlllGhO.js → app-DvYKGw_S.js} +3 -3
  47. package/dist/scripts/{app-BHlllGhO.js.map → app-DvYKGw_S.js.map} +1 -1
  48. package/dist/scripts/{2HZlmQRs2.chunk.js → lJ6ZVpyv2.chunk.js} +2 -2
  49. package/dist/scripts/{2HZlmQRs2.chunk.js.map → lJ6ZVpyv2.chunk.js.map} +1 -1
  50. package/package.json +1 -1
  51. package/dist/scripts/C8l37H7t2.chunk.js +0 -2
  52. package/dist/scripts/CNm_4jj62.chunk.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Cc63s6rS2.chunk.js","names":[],"sources":["../../../../libs/shared/src/apps/discover/components/tutorial-videos/TutorialVideoWidget.tsx","../../../../libs/shared/src/components/widgets/countdown/countdown.module.scss","../../../../libs/shared/src/components/widgets/countdown/CountdownWidget.tsx","../../../../libs/shared/src/components/widgets/countdown/CountdownContainer.tsx","../../../../libs/shared/src/components/widgets/countdown/events/commonwealth-game.ts","../../../../libs/shared/src/apps/discover/components/discover-dashboard/empty-state/DiscoverDashboardEmptyState.tsx","../../../../libs/shared/src/apps/discover/components/discover-dashboard/DiscoverDashboard.tsx","../../src/shared/components/upsell-footer-banner/upsell-footer-banner.module.scss","../../src/shared/components/upsell-footer-banner/UpsellFooterBanner.tsx","../../src/shared/utils/UpsellWidgetHelper.ts","../../src/apps/dashboard/views/dashboard/curated-discover/CuratedDiscoverView.tsx","../../../../libs/shared/src/apps/streamable-learning/components/dashboard/empty-state/StreamableDiscoverDashboardEmptyState.tsx","../../../../libs/shared/src/apps/streamable-learning/components/dashboard/StreamableDiscoverDashboard.tsx","../../src/apps/dashboard/views/dashboard/live-discover/LiveDiscoverView.tsx","../../src/apps/dashboard/views/dashboard/BaseDiscoverView.tsx"],"sourcesContent":["import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/react/index';\n\nimport { FixedWidget } from 'libs/shared/components/widgets/fixed-widget';\nimport { VideoWidgetItemV2 } from 'libs/shared/components/widgets/items/video-widget-item/v2/VideoWidgetItemV2';\nimport { WidgetContents } from 'libs/shared/enums/WidgetContents';\nimport { PlaylistRequests } from 'libs/shared/flight-requests/PlaylistRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { CurrentUser, Following, PresentationAudience, Video, VideoTypes } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\n\nconst namespace = 'discover.tutorials';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport interface TutorialVideosContext {\n playlistId: string;\n videos?: VideoTypes[];\n shouldShowPanel: boolean;\n readyToShowPanel: boolean;\n shouldShowProductTip: boolean;\n dismissPanel?: () => void;\n appLink?: Core.AppLink;\n getVideoAppLink?: (child: Video) => Core.AppLink;\n}\n\ninterface TutorialVideoWidgetProps {\n commonVideoProps: CommonVideoProps;\n audiences: PresentationAudience[];\n context: TutorialVideosContext;\n}\n\nexport function TutorialVideoWidget(props: TutorialVideoWidgetProps) {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n \n const following = Flight.useBasicFetch<Following>(\n currentUser.data?.id &&\n PlaylistRequests.getIsFollowingPlaylist(props.context.playlistId, currentUser.data?.id)\n );\n\n const [ isFollowing, setIsFollowing ] = React.useState(null);\n const [ showSpinner, setShowSpinner ] = React.useState(false);\n const alerts = useAlerts();\n const fetchAsync = Flight.useGetFetchAsync();\n\n React.useEffect(() => {\n if (following.hasCompleted) {\n setIsFollowing(following.data?.isFollowing);\n }\n }, [following.data?.isFollowing]);\n\n const follow = async (shouldFollow: boolean) => {\n setShowSpinner(true);\n\n const req = shouldFollow ?\n PlaylistRequests.followPlaylist :\n PlaylistRequests.unfollowPlaylist;\n\n const error = () => {\n alerts.error(getPhrase(shouldFollow ? 'followError' : 'unfollowError'));\n setShowSpinner(false);\n };\n\n const success = () => {\n alerts.success(getPhrase(shouldFollow ? 'followSuccess' : 'unfollowSuccess'));\n setIsFollowing(shouldFollow);\n setShowSpinner(false);\n };\n\n await fetchAsync(req(props.context.playlistId, currentUser.data?.id, success, error));\n };\n \n return (\n <FixedWidget\n name={getPhrase('heading')}\n contents={WidgetContents.Videos}\n appLink={props.context.appLink}\n getChildAppLink={props.context.getVideoAppLink}\n collection={props.context.videos}\n childComponent={VideoWidgetItemV2}\n extraChildComponentProps={{\n commonVideoProps: props.commonVideoProps,\n presentationAudiences: props.audiences\n }}\n showSeeMoreLink={false}\n onClose={props.context.dismissPanel}\n onFollow={follow}\n isFollowing={isFollowing}\n showFollowSpinner={showSpinner}\n prefetched\n />\n );\n}\n","@import '~styles/utils/include-media';\n\n:local {\n .container {\n background-size: cover;\n }\n\n .eventLogo {\n width: 2.0625rem; //32px + 1px border\n height: 2.0625rem;\n }\n\n .cvLogoContainer {\n width: 2.0625rem;\n height: 2.0625rem;\n }\n\n .cvLogo {\n width: 0.625rem;\n // ClickView logo looks better when positioned slightly further to the right\n left: 53%;\n top: 50%;\n transform: translate(-50%, -50%);\n }\n\n .countdownGrid {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: map-get($spacers, 1);\n\n @include media('<=md') {\n margin-top: map-get($spacers, 2);\n }\n }\n\n .timeBox {\n width: 4.3125rem;\n height: 4.3125rem;\n border: 0.125rem solid $light-blue;\n }\n\n .timeLabel {\n font-size: 0.75rem; //12px\n }\n}\n","import React from 'react';\n\nimport { AppLink } from 'libs/common/backbone/core';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { AppLink as AppLinkComponent } from 'libs/shared/components/app-link/AppLink';\nimport { ClickViewPlayLogo } from 'libs/shared/components/svgs/clickview-logo/ClickViewLogo';\nimport { CountdownImageUrls } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\n\nimport styles from './countdown.module.scss';\n\nconst timeUnitNamespace = 'shared.countdown';\n\ninterface TimeBoxProps {\n value: number;\n label: string;\n shouldFormat: boolean;\n}\n\nfunction formatNumber(num: number) {\n return num.toString().padStart(2, '0');\n}\n\nfunction TimeBox(props: TimeBoxProps) {\n return (\n <div className={`bg-white d-flex rounded-3 flex-column align-items-center justify-content-center p-1 ${styles.timeBox}`}>\n <div className='fs-5 h6 mb-0 flex-grow-1 align-content-center'>\n {props.shouldFormat ? formatNumber(props.value) : props.value}\n </div>\n <div className={styles.timeLabel}>{props.label}</div>\n </div>\n );\n}\n\nexport interface CountdownWidgetProps {\n targetDate: Date;\n endDate: Date;\n imageUrls: CountdownImageUrls;\n langNamespace: string;\n appLink?: AppLink;\n onCtaClick?: () => void;\n /** When true, the event has ended but is still shown (due to showDaysAfter). */\n hasEnded?: boolean;\n}\n\nexport function CountdownWidget(props: CountdownWidgetProps): JSX.Element | null {\n const [ timeLeft, setTimeLeft ] = React.useState({\n days: 0,\n hours: 0,\n minutes: 0,\n seconds: 0\n });\n const [ isEventEnded, setIsEventEnded ] = React.useState(false);\n const shouldShowLogos = props.imageUrls.logo;\n\n React.useEffect(() => {\n let timer: number = 0;\n\n const calculateTimeLeft = () => {\n const now = new Date().getTime();\n const targetTime = props.targetDate.getTime();\n const endTime = props.endDate.getTime();\n\n if (now >= endTime) {\n setIsEventEnded(true);\n clearInterval(timer);\n return;\n }\n\n const difference = targetTime - now;\n\n if (difference > 0) {\n setTimeLeft({\n days: Math.floor(difference / (1000 * 60 * 60 * 24)),\n hours: Math.floor((difference / (1000 * 60 * 60)) % 24),\n minutes: Math.floor((difference / 1000 / 60) % 60),\n seconds: Math.floor((difference / 1000) % 60)\n });\n } else {\n setTimeLeft({ days: 0, hours: 0, minutes: 0, seconds: 0 });\n clearInterval(timer);\n }\n };\n\n calculateTimeLeft();\n timer = window.setInterval(calculateTimeLeft, 1000);\n\n return () => clearInterval(timer);\n }, [ props.targetDate, props.endDate ]);\n\n if (isEventEnded && !props.hasEnded) {\n return null;\n }\n\n const timeUnits = [\n { value: timeLeft.days, label: LanguageService.getPhrase(timeUnitNamespace, 'days'), format: false },\n { value: timeLeft.hours, label: LanguageService.getPhrase(timeUnitNamespace, 'hours'), format: true },\n { value: timeLeft.minutes, label: LanguageService.getPhrase(timeUnitNamespace, 'minutes'), format: true },\n { value: timeLeft.seconds, label: LanguageService.getPhrase(timeUnitNamespace, 'seconds'), format: true }\n ];\n\n const isCountdownFinished = timeLeft.days === 0\n && timeLeft.hours === 0\n && timeLeft.minutes === 0\n && timeLeft.seconds === 0;\n\n return (\n <div\n className={`${styles.container} position-relative d-flex flex-md-row justify-content-md-between flex-column justify-content-center align-items-center p-3 mb-4 rounded`}\n style={{\n backgroundImage: `url('${props.imageUrls.background}')`\n }}\n >\n <div className='d-flex flex-column gap-2 align-items-md-start align-items-center w-md-auto w-100'>\n <div className='d-flex flex-md-row align-items-center flex-column gap-2'>\n {shouldShowLogos && (\n <ul className='list-unstyled d-flex mb-0'>\n <li className={`bg-white rounded-circle z-1 ${styles.eventLogo} border`}>\n <img src={props.imageUrls.logo} className='rounded-circle img-fluid' />\n </li>\n <li className={`bg-white rounded-circle position-relative ms-n1 ${styles.cvLogoContainer} border`}>\n <div className={`position-absolute d-flex align-items-center justify-content-center ${styles.cvLogo}`}>\n <ClickViewPlayLogo />\n </div>\n </li>\n </ul>\n )}\n <h2 className='h4 text-white text-shadow mb-0 lh-1 my-3 my-md-0'>\n {props.hasEnded ?\n LanguageService.getPhrase(props.langNamespace, 'titleAfter') :\n isCountdownFinished ?\n LanguageService.getPhrase(props.langNamespace, 'titleStarted') :\n LanguageService.getPhrase(props.langNamespace, 'title')}\n </h2>\n </div>\n {props.appLink &&\n <AppLinkComponent\n appLink={props.appLink}\n className='btn btn-outline-dark w-fit d-none d-md-flex'\n onClick={props.onCtaClick}\n >\n {LanguageService.getPhrase(props.langNamespace, 'cta')}\n </AppLinkComponent>\n }\n </div>\n\n {!isCountdownFinished &&\n <div className={styles.countdownGrid}>\n {timeUnits.map(unit => <TimeBox key={unit.label} {...unit} shouldFormat={unit.format} />)}\n </div>\n }\n\n {props.appLink &&\n <AppLinkComponent\n appLink={props.appLink}\n className='btn btn-outline-dark w-fit mt-3 d-md-none d-flex'\n onClick={props.onCtaClick}\n >\n {LanguageService.getPhrase(props.langNamespace, 'ctaMobile')}\n </AppLinkComponent>\n }\n </div>\n );\n}\n","import React from 'react';\n\nimport { AppLink } from 'libs/common/backbone/core';\n\nimport { CountdownImageUrls } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\n\nimport { CountdownWidget } from './CountdownWidget';\n\ninterface ImageUrlMap {\n [key: string]: ImageUrlMap | string;\n}\n\nexport interface CountdownExternalContext {\n // Map of image URL constants from the consuming project\n imageUrls: ImageUrlMap;\n getAppLink: (presentationId: string, eventTopicKey: string) => AppLink | null;\n}\n\ninterface ResolvedEventData {\n imageUrls: CountdownImageUrls | null;\n appLink?: AppLink | null;\n}\n\nexport interface CountdownEventConfig {\n key: string;\n // countdown will count towards this date\n targetDate: Date;\n // event is hidden after this date\n endDate: Date;\n langNamespace: string;\n allowedPresentationIds: string[];\n // key used to look up event topics in HardCoded (e.g. 'OlympicsTopics', 'CommonwealthGameTopics')\n eventTopicKey: string;\n getEventConfig: (presentationId: string, context: CountdownExternalContext) => ResolvedEventData;\n /** \n * Number of days before targetDate to start showing the countdown.\n * If not provided, the countdown is shown immediately (as long as now < endDate).\n * Make sure to set up phrase 'titleStarted' for your event.\n */\n showDaysBefore?: number;\n /**\n * Number of days after endDate to keep showing the countdown.\n * If not provided, the countdown is hidden immediately after endDate.\n * Make sure to set up phrase 'tittleAfter' for your event.\n */\n showDaysAfter?: number;\n}\n\ninterface CountdownContainerProps {\n presentationId: string;\n // List of countdown event configs, ordered by priority\n events: CountdownEventConfig[];\n // External context passed from the consuming component\n context: CountdownExternalContext;\n}\n\nfunction getActiveEvent(\n events: CountdownEventConfig[],\n presentationId: string\n): CountdownEventConfig | undefined {\n const now = new Date().getTime();\n\n return events.find(event => {\n if (!event.allowedPresentationIds.includes(presentationId)) {\n return false;\n }\n\n const effectiveEndDate = event.showDaysAfter !== undefined ?\n event.endDate.getTime() + event.showDaysAfter * 24 * 60 * 60 * 1000 :\n event.endDate.getTime();\n\n if (now >= effectiveEndDate) {\n return false;\n }\n\n if (event.showDaysBefore !== undefined) {\n const showFromDate = new Date(event.targetDate.getTime() - event.showDaysBefore * 24 * 60 * 60 * 1000);\n if (now < showFromDate.getTime()) {\n return false;\n }\n }\n\n return true;\n });\n}\n\nexport function CountdownContainer(props: CountdownContainerProps): JSX.Element | null {\n const activeEvent = getActiveEvent(props.events, props.presentationId);\n\n if (!activeEvent) {\n return null;\n }\n\n const config = activeEvent.getEventConfig(props.presentationId, props.context);\n\n if (!config.imageUrls) {\n return null;\n }\n\n const hasEnded = new Date().getTime() >= activeEvent.endDate.getTime();\n\n return (\n <CountdownWidget\n key={activeEvent.key}\n targetDate={activeEvent.targetDate}\n endDate={activeEvent.endDate}\n imageUrls={config.imageUrls}\n langNamespace={activeEvent.langNamespace}\n appLink={config.appLink}\n hasEnded={hasEnded}\n />\n );\n}\n","import { HardCoded } from 'libs/shared/constants/HardCoded';\n\nimport { CountdownEventConfig } from '../CountdownContainer';\n\nconst COMMONWEALTH_GAME_START_DATE_UTC = new Date('2026-07-23T00:00:00Z');\nconst COMMONWEALTH_GAME_END_DATE_UTC = new Date('2026-08-02T23:59:59Z');\n\nconst COMMONWEALTH_GAME_PRESENTATION_IDS = [\n HardCoded.PresentationIds.SCT_PRIMARY,\n HardCoded.PresentationIds.SCT_SECONDARY,\n HardCoded.PresentationIds.ENG_PRIMARY,\n HardCoded.PresentationIds.ENG_SECONDARY,\n HardCoded.PresentationIds.AU_PRIMARY,\n HardCoded.PresentationIds.AU_SECONDARY\n].map(id => id.toString());\n\nconst PRESENTATION_TO_IMAGE_KEY: Record<string, string> = {\n [HardCoded.PresentationIds.SCT_PRIMARY]: 'SCT_PRIMARY',\n [HardCoded.PresentationIds.SCT_SECONDARY]: 'SCT_SECONDARY',\n [HardCoded.PresentationIds.ENG_PRIMARY]: 'ENG_PRIMARY',\n [HardCoded.PresentationIds.ENG_SECONDARY]: 'ENG_SECONDARY',\n [HardCoded.PresentationIds.AU_PRIMARY]: 'AU_PRIMARY',\n [HardCoded.PresentationIds.AU_SECONDARY]: 'AU_SECONDARY'\n};\n\nexport const commonwealthGameCountdownEvent: CountdownEventConfig = {\n key: 'commonwealth-games-2026',\n targetDate: COMMONWEALTH_GAME_START_DATE_UTC,\n endDate: COMMONWEALTH_GAME_END_DATE_UTC,\n langNamespace: 'shared.commonwealthGameCountdown',\n allowedPresentationIds: COMMONWEALTH_GAME_PRESENTATION_IDS,\n eventTopicKey: 'CommonwealthGameTopics',\n // we want to show the event for 30 days before the start\n showDaysBefore: 30,\n // we want to show the event for 7 days after the end day\n showDaysAfter: 7,\n\n getEventConfig: (presentationId, context) => {\n const images = context.imageUrls.CommonwealthGamesCountdown as Record<string, string> | undefined;\n\n if (!images) {\n return { imageUrls: null };\n }\n\n const imageKey = PRESENTATION_TO_IMAGE_KEY[presentationId];\n const background = imageKey ? images[imageKey] as string : null;\n\n if (!background) {\n return { imageUrls: null };\n }\n\n const appLink = context.getAppLink(presentationId, 'CommonwealthGameTopics');\n\n return {\n // we don't show logos for this event\n imageUrls: { background },\n appLink\n };\n }\n};\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { PlusSvg } from 'libs/shared/images/svg/actions/PlusSvg';\nimport { CuratedDashboard, DashboardStatus } from 'libs/shared/interfaces';\n\nconst namespace = 'subjects.discoverDashboardEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface DiscoverDashboardEmptyStateProps {\n dashboard: CuratedDashboard;\n imageUrl: string;\n isReadonly: boolean;\n addWidgetApplink?: () => Core.AppLink;\n}\n\nexport function DiscoverDashboardEmptyState(props: DiscoverDashboardEmptyStateProps): JSX.Element {\n const isArchived = props.dashboard?.status === DashboardStatus.Archived;\n\n return (\n <EmptyState>\n <EmptyState.Image src={props.imageUrl} altText={getPhrase('info')} />\n <EmptyState.Heading>\n <Text namespace={namespace} phrase='heading' />\n </EmptyState.Heading>\n <EmptyState.Info>\n <Text namespace={namespace} phrase='info' />\n </EmptyState.Info>\n <Tooltip title={isArchived ? LanguageService.getPhrase(namespace, 'archivedCtaTooltip') : ''} spanHack>\n <EmptyState.Cta\n text={LanguageService.getPhrase(namespace, 'add')}\n appLink={props.addWidgetApplink?.()}\n className='btn btn-dark'\n icon={PlusSvg}\n disabled={isArchived}\n />\n </Tooltip>\n </EmptyState>\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { Flight } from 'libs/common/flight';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { DiscoverHeader, DiscoverHeaderAppLinks } from 'libs/shared/apps/discover/components/header/DiscoverHeader';\nimport { TutorialVideosContext, TutorialVideoWidget } from 'libs/shared/apps/discover/components/tutorial-videos/TutorialVideoWidget';\nimport { DashboardFeedbackData } from 'libs/shared/components/feedback-form/FeedbackForm';\nimport { CountdownContainer, CountdownExternalContext } from 'libs/shared/components/widgets/countdown/CountdownContainer';\nimport { commonwealthGameCountdownEvent } from 'libs/shared/components/widgets/countdown/events/commonwealth-game';\nimport { PartialPopoutThumbnailSlidingListSmallWidgetTemplate } from 'libs/shared/components/widgets/curated-widgets/templates/popout_thumbnail_sliding_list_small/partial-loading/PartialPopoutThumbnailSlidingListSmall';\nimport { WidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/WidgetContainerView';\nimport { AllDiscoverWidgetTemplates } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { HasLocalPermissionsFunc, HasPermissionsFunc } from 'libs/shared/hooks/usePermissions';\nimport { SettingsHash } from 'libs/shared/hooks/useSettings';\nimport { CalendarEventContentType, CuratedDashboard, CuratedWidgetQueryParams, DashboardTargetType, Presentation, PresentationAudience, WidgetPreference } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\n\nimport { DiscoverDashboardEmptyState } from './empty-state/DiscoverDashboardEmptyState';\n\nexport interface DiscoverDashboardProps {\n dashboard: CuratedDashboard;\n getWidgetContentRequest: (\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate,\n presentation: Presentation\n ) => Flight.Request;\n audiences: PresentationAudience[];\n hasPermissions: HasPermissionsFunc;\n hasLocalPermissions: HasLocalPermissionsFunc;\n emptyImageUrl?: string;\n presentation: Presentation;\n widgetAppLinks?: AllDiscoverWidgetTemplates['appLinks'] & {\n widgetWizard: () => Core.AppLink\n };\n headerAppLinks?: DiscoverHeaderAppLinks;\n scrollToWidgetId?: string;\n updatePreferences?: (\n widgetId: string,\n widgetTypeId: WidgetTypeId,\n oldPreferences: WidgetPreference[],\n newPreferences: WidgetPreference[]\n ) => Promise<void>;\n onSubmitFeedback?: (feedback: DashboardFeedbackData) => Promise<void>;\n removeFromVideoHistory: (videoId: string, videoName: string, widgetId: string, widgetTypeId: WidgetTypeId) => void;\n isReadonly?: boolean;\n lazyLoad?: boolean;\n showCalendar: boolean;\n settings: SettingsHash;\n availablePresentations: Presentation[];\n isTertiaryCustomerWithoutExchange: boolean;\n commonVideoProps: CommonVideoProps;\n countdownContext?: CountdownExternalContext;\n tutorialVideosContext?: TutorialVideosContext;\n contentType?: CalendarEventContentType;\n isUpselling?: boolean;\n reminderComponent?: JSX.Element;\n}\n\nexport function DiscoverDashboard(props: DiscoverDashboardProps): JSX.Element {\n const widgets = ArrayHelper.sortBy(props.dashboard?.widgets, 'index');\n\n function getWidgetContentRequest(id: string, widgetTypeId: WidgetTypeId, template: WidgetTemplate): Flight.Request {\n const params = CuratedDashboardHelper.getWidgetParams(\n widgetTypeId,\n template,\n CuratedDashboardHelper.getDashboardTargetType(props.dashboard)\n );\n\n return props.getWidgetContentRequest(id, params, template, props.presentation);\n }\n\n const showEmptyState = props.isReadonly && !widgets?.length;\n\n return (\n <>\n <DiscoverHeader\n type={props.dashboard?.userType}\n appLinks={props.headerAppLinks}\n hasStudentExperience={props.hasPermissions(PermissionName.StudentExperience)}\n showCalendar={props.showCalendar}\n active='forYou'\n isUpselling={props.isUpselling}\n />\n\n {props.tutorialVideosContext?.shouldShowPanel && (\n <div className='curated-widget rounded-3 mb-3 mx-n4 px-4 py-3 overflow-hidden'>\n {\n props.tutorialVideosContext.readyToShowPanel ?\n <TutorialVideoWidget\n commonVideoProps={props.commonVideoProps}\n audiences={props.audiences}\n context={props.tutorialVideosContext}\n /> :\n <PartialPopoutThumbnailSlidingListSmallWidgetTemplate\n hideDescription\n />\n }\n </div>\n )}\n\n {props.countdownContext && props.presentation?.id && (\n <CountdownContainer\n presentationId={props.presentation.id.toString()}\n events={[commonwealthGameCountdownEvent]}\n context={props.countdownContext}\n />\n )}\n\n {widgets.map((widget, idx) => {\n return (\n <WidgetContainerView\n widgetCollection={DashboardTargetType.Discover}\n key={widget.id}\n id={widget.id}\n getContentRequest={getWidgetContentRequest}\n audiences={props.audiences}\n name={widget.name}\n description={widget.description}\n templateId={widget.templateId}\n metadata={widget.metadata}\n presentation={props.presentation}\n preferences={widget.preferences}\n appLinks={props.widgetAppLinks}\n isScrollToTargetWidget={props?.scrollToWidgetId === widget.id}\n widgetTypeId={widget.widgetId}\n hasPermissions={props.hasPermissions}\n hasLocalPermissions={props.hasLocalPermissions}\n onSubmitFeedback={props.onSubmitFeedback}\n updatePreferences={props.updatePreferences}\n lazyLoad={props.lazyLoad}\n dashboardTarget={DashboardTargetType.Discover}\n widgetIndex={idx}\n isPreviewing={props.isReadonly}\n settings={{\n hasTopicDirectories: props.settings?.hasTopicDirectories\n }}\n availablePresentations={props.availablePresentations}\n imageCdnUrl={props.commonVideoProps.imageCdnUrl}\n commonVideoProps={props.commonVideoProps}\n settingsHash={props.settings}\n contentType={props.contentType}\n isUpselling={props.isUpselling}\n\n // TODO: Ideally we don't have to do this\n classification={undefined}\n hasTableOfContents={false}\n limitTotalItems={false}\n isTertiaryCustomerWithoutExchange={props.isTertiaryCustomerWithoutExchange}\n seeMoreLink={undefined}\n onClickRemoveItem={props.removeFromVideoHistory}\n badgeComponent={null}\n reminderComponent={props.reminderComponent}\n />\n );\n })}\n\n {showEmptyState && (\n <DiscoverDashboardEmptyState\n dashboard={props.dashboard}\n isReadonly={props.isReadonly}\n imageUrl={props.emptyImageUrl}\n addWidgetApplink={props.widgetAppLinks.widgetWizard}\n />\n )}\n </>\n );\n}\n",":local {\n .image {\n max-height: 11.25rem; // 180px\n width: auto;\n }\n\n .successSvg {\n svg {\n color: $green-500;\n }\n }\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { EntityType, LocationContext, UpsellBannerDescriptor, UserAction } from 'libs/analytics/interfaces';\n\nimport { ActionButton } from 'libs/shared/components/actions/ActionButton';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { CheckCircleSvg } from 'libs/shared/images/svg/status/CheckCircleSvg';\n\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { OnClickRequestAccessButton } from 'shared/hooks/useRequestAccessApplink';\nimport { UpsellKind } from 'shared/utils/UpsellHelper';\n\nimport styles from './upsell-footer-banner.module.scss';\n\nconst namespace = 'shared.upsellFooterBanner';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface UpsellBannerOptions {\n backgroundClass: string;\n imageUrl: string;\n headingPhrase: string;\n descriptionPhrase: string;\n ctaPhrase: string;\n}\n\nconst VARIANTS: Record<UpsellKind, UpsellBannerOptions> = {\n [UpsellKind.StartCvTrial]: {\n backgroundClass: 'bg-light-orange border border-orange',\n imageUrl: ImageUrls.Upsell.CLICKVIEW_FOOTER_BANNER,\n headingPhrase: 'headingClickView',\n descriptionPhrase: 'descriptionTrialClickView',\n ctaPhrase: 'startTrial'\n },\n [UpsellKind.StartLiveTrial]: {\n backgroundClass: 'bg-light-green border border-green',\n imageUrl: ImageUrls.Upsell.CLICKVIEW_LIVE_FOOTER_BANNER,\n headingPhrase: 'headingClickViewLive',\n descriptionPhrase: 'descriptionTrialClickViewLive',\n ctaPhrase: 'startTrial'\n },\n [UpsellKind.RequestCvPilot]: {\n backgroundClass: 'bg-light-orange border border-orange',\n imageUrl: ImageUrls.Upsell.CLICKVIEW_FOOTER_BANNER,\n headingPhrase: 'headingClickView',\n descriptionPhrase: 'descriptionPilot',\n ctaPhrase: 'requestAccess'\n },\n [UpsellKind.RequestLivePilot]: {\n backgroundClass: 'bg-light-green border border-green',\n imageUrl: ImageUrls.Upsell.CLICKVIEW_LIVE_FOOTER_BANNER,\n headingPhrase: 'headingClickViewLive',\n descriptionPhrase: 'descriptionPilot',\n ctaPhrase: 'requestAccess'\n }\n};\n\ninterface UpsellFooterBannerProps {\n upsellKind: UpsellKind;\n onClickRequestAccessButton: OnClickRequestAccessButton;\n}\n\nexport function UpsellFooterBanner(props: UpsellFooterBannerProps): JSX.Element {\n const [ requestState, setRequestState ] = React.useState<'idle' | 'success' | 'loading' | 'error'>('idle');\n const alerts = useAlerts();\n \n const variant = VARIANTS[props.upsellKind];\n\n async function onClickRequestAccessButton() {\n await props.onClickRequestAccessButton({\n setRequestState: state => {\n if (state === 'error')\n alerts.error(getPhrase('errorRequestingAccess'));\n\n setRequestState(state);\n }\n });\n }\n\n function getButtonText() {\n if (requestState === 'loading')\n return getPhrase('loading');\n\n if (requestState === 'success')\n return getPhrase('requestSent');\n\n return getPhrase(variant.ctaPhrase);\n }\n \n const buttonText = getButtonText();\n const buttonIcon = requestState === 'success' ? CheckCircleSvg : undefined;\n const buttonClassName = classNames('btn btn-dark', !!buttonIcon && styles.successSvg);\n\n return (\n <div className={classNames(\n 'd-flex align-items-center justify-content-between overflow-hidden rounded-3 mb-4',\n variant.backgroundClass\n )}>\n <div className='p-4'>\n <h3 className='mb-3'>{getPhrase(variant.headingPhrase)}</h3>\n <p className='mb-4'>\n <Text namespace={namespace} phrase={variant.descriptionPhrase}/>\n </p>\n <ActionButton\n analyticsData={{ upsellKind: props.upsellKind }}\n analyticsOptions={{\n actionType: UserAction.Click,\n entity: EntityType.AppLink,\n location: LocationContext.UpsellBanner,\n descriptor: UpsellBannerDescriptor.StartTrial\n }}\n svg={buttonIcon}\n className={buttonClassName}\n onClick={onClickRequestAccessButton}\n disabled={[ 'success', 'loading' ].includes(requestState)}\n >\n {buttonText}\n </ActionButton>\n </div>\n <img\n className={classNames('d-none d-md-block align-self-end', styles.image)}\n src={variant.imageUrl}\n alt='Envelope'\n />\n </div>\n );\n}\n","import { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { BaseWidget, CuratedDashboard } from 'libs/shared/interfaces';\n\nconst ALL_TEMPLATES = 'all' as const;\n\nconst MIN_UPSELL_WIDGETS = 3;\n\nconst UPSELL_WIDGET_WHITELIST: Partial<Record<WidgetTypeId, WidgetTemplate[] | typeof ALL_TEMPLATES>> = {\n // New to ClickView\n [WidgetTypeId.ClassificationLatestReleasedVideosV2]: [WidgetTemplate.PopoutThumbnailSlidingListLarge],\n\n // New topics\n [WidgetTypeId.LatestReleasedClassifications]: [WidgetTemplate.ThumbnailFixedListSmall],\n\n // Upcoming livestreams\n [WidgetTypeId.UpcomingLivestreams]: [WidgetTemplate.EventIconSlidingList],\n\n // Upcoming events\n [WidgetTypeId.SpecialEventClassifications]: [WidgetTemplate.EventIconSlidingList],\n\n // ClickView original productions (Subject) / Recently streamed (Live)\n // This is not guarenteed. But we only take one of each type, so we might end up with another video list\n // if the curation team is doing their job, it should be relevant content - Sha\n [WidgetTypeId.CuratedMedia]: [\n WidgetTemplate.PopoutThumbnailSlidingListLarge,\n WidgetTemplate.PopoutThumbnailSlidingListSmall\n ],\n\n // Zoos and Wildlife Parks\n [WidgetTypeId.CuratedCompanies]: [WidgetTemplate.CircleLogoSlidingList],\n\n // Browse all subjects — not the editable \"Explore my subjects\" variant, which writes follow state\n [WidgetTypeId.Classifications]: [WidgetTemplate.CoverFixedPillListXSmall]\n};\n\nfunction isUpsellWidgetAllowed(widget: BaseWidget): boolean {\n const allowedTemplates = UPSELL_WIDGET_WHITELIST[widget.widgetId];\n\n if (!allowedTemplates)\n return false;\n\n return allowedTemplates === ALL_TEMPLATES || allowedTemplates.includes(widget.templateId);\n}\n\n/**\n * Narrows a dashboard to one widget per whitelisted type, lowest index first. Falls back to the full\n * dashboard when the user isn't being upsold, or when too few widgets match to make a decent page.\n */\nexport function filterUpsellWidgets(dashboard: CuratedDashboard, isUpselling: boolean): CuratedDashboard {\n if (!dashboard || !isUpselling)\n return dashboard;\n\n const usedTypes = new Set<WidgetTypeId>();\n\n const widgets = ArrayHelper.sortBy(dashboard.widgets ?? [], 'index')\n .filter(widget => {\n if (!isUpsellWidgetAllowed(widget) || usedTypes.has(widget.widgetId))\n return false;\n\n usedTypes.add(widget.widgetId);\n\n return true;\n });\n\n if (widgets.length < MIN_UPSELL_WIDGETS)\n return dashboard;\n\n return { ...dashboard, widgets };\n}\n","import React from 'react';\n\nimport { AppLink, LocationUtils } from 'libs/common/backbone/core';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { StorageType } from 'libs/common/backbone/utils/LocalStorageHelper';\nimport { Flight } from 'libs/common/flight';\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { EntityType, LocationContext, UserAction, VideoActionDescriptor, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { DiscoverDashboard } from 'libs/shared/apps/discover/components/discover-dashboard/DiscoverDashboard';\nimport { LibraryHelper } from 'libs/shared/apps/libraries/utils/LibraryHelper';\nimport { DashboardFeedbackData } from 'libs/shared/components/feedback-form/FeedbackForm';\nimport { CountdownExternalContext } from 'libs/shared/components/widgets/countdown/CountdownContainer';\nimport { HardCoded } from 'libs/shared/constants/HardCoded';\nimport { SharedViewModelKeys } from 'libs/shared/constants/SharedViewModelKeys';\nimport { FeedbackType } from 'libs/shared/enums/FeedbackType';\nimport { LocalPermissionName, PermissionName } from 'libs/shared/enums/PermissionName';\nimport { PresentationLearningLevel } from 'libs/shared/enums/PresentationLearningLevel';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { CustomerRequests } from 'libs/shared/flight-requests/CustomerRequests';\nimport { DashboardRequests } from 'libs/shared/flight-requests/DashboardRequests';\nimport { FeedbackRequests } from 'libs/shared/flight-requests/FeedbackRequests';\nimport { LibraryRequests } from 'libs/shared/flight-requests/LibraryRequests';\nimport { PreferenceRequests } from 'libs/shared/flight-requests/PreferenceRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { useProducts } from 'libs/shared/hooks/UseProducts';\nimport { useSetPageMetadata } from 'libs/shared/hooks/useSetPageMetadata';\nimport { useSettings } from 'libs/shared/hooks/useSettings';\nimport { Classification, CuratedWidgetQueryParams, CurrentUser, Customer, DashboardTargetType, Library, Presentation, PresentationAudience, WidgetPreference } from 'libs/shared/interfaces';\nimport { AudienceHelper } from 'libs/shared/utils/audience-helper/AudienceHelper';\nimport { FeedbackFormHelper } from 'libs/shared/utils/FeedbackFormHelper';\nimport { PageMetadataHelper } from 'libs/shared/utils/PageMetadataHelper';\n\nimport { SchoolLevelReminder } from 'shared/components/school-level-reminder/SchoolLevelReminder';\nimport { UpsellFooterBanner } from 'shared/components/upsell-footer-banner/UpsellFooterBanner';\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { useActivePresentation } from 'shared/hooks/presentations/useActivePresentation';\nimport { useAvailablePresentations } from 'shared/hooks/presentations/useAvailablePresentations';\nimport { useCommonVideoProps } from 'shared/hooks/useCommonVideoProps';\nimport { useRequestAccess } from 'shared/hooks/useRequestAccess';\nimport { useTeachingLevelBanner } from 'shared/hooks/useTeachingLevelBanner';\nimport { useUpsellContext } from 'shared/hooks/useUpsellContext';\nimport { DashboardViewQueryParams } from 'shared/interfaces/query-params/DashboardViewQueryParams';\nimport { ClassificationAppLinkHelper } from 'shared/utils/ClassificationAppLinkHelper';\nimport { useFetchCuratedDashboard } from 'shared/utils/DashboardHelper';\nimport { SeoHelper } from 'shared/utils/SeoHelper';\nimport { filterUpsellWidgets } from 'shared/utils/UpsellWidgetHelper';\n\nimport { useTutorialVideos } from 'apps/dashboard/hooks/useTutorialVideos';\nimport { getDiscoverHeaderAppLinks, getDiscoverWidgetAppLinks } from 'apps/dashboard/views/dashboard/DiscoverViewUtils';\nimport { useIsTertiary } from 'apps/onboarding/hooks/useIsTertiary';\nimport { VideoHistoryRequests } from 'apps/watch-history/flight-requests/VideoHistoryRequests';\n\nconst namespace = 'dashboard.dashboard';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction getPhraseVariant(presentation: Presentation): string {\n const learningLevel = PresentationLearningLevel[presentation?.learningLevel];\n\n return +learningLevel === PresentationLearningLevel.Level_1 ?\n 'VariantOne' :\n 'VariantTwo';\n}\n\ntype TopicMap = Record<string, { id: string, name: string }>;\n\nconst countdownContext: CountdownExternalContext = {\n imageUrls: ImageUrls,\n getAppLink: (presentationId: string, eventTopicKey: string): AppLink | null => {\n const topicMap = HardCoded[eventTopicKey as keyof typeof HardCoded] as TopicMap | undefined;\n\n if (!topicMap) {\n return null;\n }\n\n const topic = topicMap[presentationId];\n\n if (!topic) {\n return null;\n }\n\n return ClassificationAppLinkHelper.getAppLink(\n { id: topic.id, name: topic.name } as Classification,\n undefined,\n null\n );\n }\n};\n\ninterface CuratedDiscoverViewProps {\n presentationSlug: string | null;\n queryParams?: DashboardViewQueryParams;\n}\n\nexport function CuratedDiscoverView(props: CuratedDiscoverViewProps): JSX.Element {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const { hasLocalPermissions, hasPermissions } = usePermissions();\n const alerts = useAlerts();\n \n const customer = Flight.useBasicFetch<Customer>(\n hasLocalPermissions(LocalPermissionName.ManageDiscoverPreferences) &&\n currentUser.data?.isAuthenticated &&\n CustomerRequests.customer(currentUser.data.customerId)\n );\n \n const libraries = Flight.useBasicFetch<Library[]>(\n currentUser.data?.isAuthenticated &&\n LibraryRequests.libraries()\n );\n\n const { activePresentation } = useActivePresentation();\n const { availablePresentations } = useAvailablePresentations();\n \n const teachLevelBannerContext = useTeachingLevelBanner();\n\n function getTeachingLevelReminderType() {\n if (!teachLevelBannerContext.showBanner)\n return null;\n\n if (!teachLevelBannerContext.teachingLevelPresentation)\n return 'set-level';\n\n return 'switch-level';\n }\n\n const { upsellKind } = useUpsellContext();\n\n const isTertiary = useIsTertiary();\n const products = useProducts();\n\n const tutorialVideoContext = useTutorialVideos();\n\n const {\n dashboard,\n presentation,\n audiences\n } = useFetchCuratedDashboard({\n targetType: DashboardTargetType.Discover,\n queryParams: props.queryParams\n });\n\n const fetchAsync = Flight.useGetFetchAsync();\n const settings = useSettings(null);\n\n const [activeAudiences] = useViewModel<PresentationAudience[]>(\n SharedViewModelKeys.AUDIENCE_FILTER,\n undefined,\n { storage: StorageType.SessionStorage }\n );\n\n const { applinks: widgetAppLinks, requestAccessApplink, isUpselling, onClickRequestAccessButton } = useRequestAccess({\n applinks: getDiscoverWidgetAppLinks(\n AudienceHelper.getAudienceParams(activeAudiences),\n currentUser.data,\n props.presentationSlug,\n availablePresentations\n )\n });\n\n const { commonVideoProps } = useCommonVideoProps({\n locationContext: LocationContext.Dashboard,\n hoverToPlay: !isUpselling(activePresentation),\n subTextAppLink: isUpselling(activePresentation) ? requestAccessApplink : null\n });\n\n const phraseVariant = getPhraseVariant(presentation);\n\n useSetPageMetadata(PageMetadataHelper.getDiscoverMetadata({\n content: presentation,\n phraseContext: {\n phraseHandler: getPhrase,\n titlePhrase: `pageTitle${phraseVariant}`,\n descriptionPhrase: `pageDescription${phraseVariant}`\n },\n canonicalLink: SeoHelper.getCanonicalLink(),\n allowIndexing: SeoHelper.allowIndexing(),\n hrefLang: SeoHelper.getStaticRouteHrefLang(\n presentation?.learningLevel,\n widgetAppLinks.discover\n )\n }));\n\n async function onSubmitFeedback(feedback: DashboardFeedbackData): Promise<void> {\n const promise = await fetchAsync<void>(FeedbackRequests.submitFeedback({\n type: FeedbackType.Footer,\n user: FeedbackFormHelper.getUserInfo(currentUser.data, customer.data),\n tags: FeedbackFormHelper.getTags(\n currentUser.data,\n ProductId.Primary,\n hasPermissions(PermissionName.StudentExperience),\n [ 'discover', 'in product feedback' ]\n )\n }, {\n reaction: feedback.type,\n feedback: feedback.content,\n location: 'Discover Footer',\n presentationName: presentation.description,\n presentationId: presentation.id,\n dashboardName: dashboard.data.name,\n dashboardId: dashboard.data.id,\n currentPageUrl: LocationUtils.GetCurrentUrl()\n }));\n\n AnalyticsHelper.logUserAction({\n feedbackType: feedback.type,\n content: feedback.content,\n presentationId: presentation.id,\n dashboardId: dashboard.data.id\n }, {\n actionType: UserAction.Submit,\n location: LocationContext.DiscoverFooter,\n entity: EntityType.Feedback,\n workflowPhase: WorkflowPhase.Complete\n });\n\n return promise;\n }\n\n async function removeFromVideoHistory(\n videoId: string,\n videoName: string,\n widgetId: string,\n widgetTypeId: WidgetTypeId\n ): Promise<void> {\n if (widgetTypeId !== WidgetTypeId.ContinueWatching)\n return;\n\n try {\n await fetchAsync<void>(VideoHistoryRequests.removeFromHistory(videoId, [`widget:${widgetId}`]));\n\n alerts.success(LanguageService.getPhrase(namespace, 'removeFromHistorySuccess'));\n\n AnalyticsHelper.logUserAction({\n id: videoId,\n name: videoName,\n widgetId\n }, {\n entity: EntityType.Video,\n actionType: UserAction.Click,\n descriptor: VideoActionDescriptor.RemoveFromWatchHistory,\n location: LocationContext.SlidingListItem\n });\n } catch {\n alerts.error(LanguageService.getPhrase(namespace, 'removeFromHistoryError', { name: videoName }));\n }\n }\n\n async function updateWidgetPreferences(\n widgetId: string,\n widgetTypeId: WidgetTypeId,\n oldPreferences: WidgetPreference[],\n newPreferences: WidgetPreference[]\n ): Promise<void> {\n const addedSubjects = newPreferences.filter(p => {\n if (p.hidden)\n return false;\n\n const oldPreference = oldPreferences.find(o => o.id === p.id);\n\n return oldPreference.hidden;\n });\n const removedSubjects = newPreferences.filter(p => {\n if (!p.hidden)\n return false;\n \n const oldPreference = oldPreferences.find(o => o.id === p.id);\n\n return !oldPreference.hidden;\n });\n\n if (addedSubjects?.length)\n await fetchAsync<void>(PreferenceRequests.followSubjects(addedSubjects.map(s => s.id)));\n\n if (removedSubjects?.length)\n await fetchAsync<void>(PreferenceRequests.unfollowSubjects(removedSubjects.map(s => s.id)));\n\n return fetchAsync<void>(DashboardRequests.updateWidgetPreferences(\n widgetId,\n newPreferences.map(p => ({\n id: p.id,\n index: p.index\n })),\n currentUser.data\n ));\n }\n return (\n <div className='bg-white px-4'>\n <DiscoverDashboard\n dashboard={filterUpsellWidgets(dashboard.data, isUpselling(activePresentation))}\n widgetAppLinks={widgetAppLinks}\n headerAppLinks={getDiscoverHeaderAppLinks(presentation?.vanitySlug ?? null)}\n presentation={presentation}\n getWidgetContentRequest={(\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate,\n presentation: Presentation\n ) => {\n const { hasTwig, hasTigtag } = LibraryHelper.hasTwigOrTigtag(libraries.data, currentUser.data);\n\n return DashboardRequests.dashboardWidgetContent(\n id,\n params,\n widgetTemplate,\n presentation,\n { hideTigTag: !hasTigtag, hideTwig: !hasTwig }\n );\n }}\n audiences={audiences.data}\n updatePreferences={updateWidgetPreferences}\n hasPermissions={hasPermissions}\n hasLocalPermissions={hasLocalPermissions}\n onSubmitFeedback={\n hasPermissions(PermissionName.CanSubmitFeedback) &&\n onSubmitFeedback\n }\n removeFromVideoHistory={removeFromVideoHistory}\n lazyLoad={!SeoHelper.isBot()}\n showCalendar={false}\n settings={settings}\n availablePresentations={availablePresentations}\n isTertiaryCustomerWithoutExchange={isTertiary && !products?.hasProduct(ProductId.Exchange)}\n commonVideoProps={commonVideoProps}\n countdownContext={countdownContext}\n tutorialVideosContext={isUpselling(activePresentation) ? null : tutorialVideoContext}\n isUpselling={isUpselling(activePresentation)}\n\n reminderComponent={\n <SchoolLevelReminder\n type={getTeachingLevelReminderType()}\n className='mb-2'\n setLevel={teachLevelBannerContext.teachingLevelPresentation?.name}\n currLevel={activePresentation?.name}\n />\n }\n />\n {isUpselling(activePresentation) &&\n <UpsellFooterBanner upsellKind={upsellKind} onClickRequestAccessButton={onClickRequestAccessButton} />\n }\n </div>\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { PlusSvg } from 'libs/shared/images/svg/actions/PlusSvg';\nimport { CuratedDashboard, DashboardStatus } from 'libs/shared/interfaces';\n\nconst namespace = 'streamable.dashboardEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface StreamableDiscoverDashboardEmptyStateProps {\n dashboard: CuratedDashboard;\n imageUrl: string;\n isReadonly: boolean;\n addWidgetApplink?: () => Core.AppLink;\n}\n\nexport function StreamableDiscoverDashboardEmptyState(props: StreamableDiscoverDashboardEmptyStateProps): JSX.Element {\n const isArchived = props.dashboard?.status === DashboardStatus.Archived;\n\n return (\n <EmptyState>\n <EmptyState.Image src={props.imageUrl} altText={getPhrase('info')} />\n <EmptyState.Heading>\n <Text namespace={namespace} phrase='heading' />\n </EmptyState.Heading>\n <EmptyState.Info>\n <Text namespace={namespace} phrase='info' />\n </EmptyState.Info>\n <Tooltip title={isArchived ? LanguageService.getPhrase(namespace, 'archivedCtaTooltip') : ''} spanHack>\n <EmptyState.Cta\n text={LanguageService.getPhrase(namespace, 'add')}\n appLink={props.addWidgetApplink?.()}\n className='btn btn-dark'\n icon={PlusSvg}\n disabled={isArchived}\n />\n </Tooltip>\n </EmptyState>\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { Flight } from 'libs/common/flight';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { TutorialVideosContext, TutorialVideoWidget } from 'libs/shared/apps/discover/components/tutorial-videos/TutorialVideoWidget';\nimport { StreamableHeader, StreamableHeaderAppLinks } from 'libs/shared/apps/streamable-learning/components/header/StreamableHeader';\nimport { PartialPopoutThumbnailSlidingListSmallWidgetTemplate } from 'libs/shared/components/widgets/curated-widgets/templates/popout_thumbnail_sliding_list_small/partial-loading/PartialPopoutThumbnailSlidingListSmall';\nimport { WidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/WidgetContainerView';\nimport { AllDiscoverWidgetTemplates } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { CalendarEventContentType, CuratedDashboard, CuratedWidgetQueryParams, DashboardTargetType, Presentation, PresentationAudience } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\n\nimport { StreamableDiscoverDashboardEmptyState } from './empty-state/StreamableDiscoverDashboardEmptyState';\n\nexport interface StreamableDiscoverDashboardProps {\n dashboard: CuratedDashboard;\n getWidgetContentRequest: (\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate\n ) => Flight.Request;\n\n audiences?: PresentationAudience[];\n emptyImageUrl?: string;\n presentation: Presentation;\n widgetAppLinks?: AllDiscoverWidgetTemplates['appLinks'] & {\n widgetWizard: () => Core.AppLink\n };\n headerAppLinks?: StreamableHeaderAppLinks;\n scrollToWidgetId?: string;\n isReadonly?: boolean;\n lazyLoad?: boolean;\n commonVideoProps: CommonVideoProps;\n tutorialVideosContext?: TutorialVideosContext;\n isUpselling?: boolean;\n}\n\nexport function StreamableDiscoverDashboard(props: StreamableDiscoverDashboardProps): JSX.Element {\n const widgets = ArrayHelper.sortBy(props.dashboard?.widgets, 'index');\n\n const { hasPermissions, hasLocalPermissions } = usePermissions();\n\n function getWidgetContentRequest(id: string, widgetTypeId: WidgetTypeId, template: WidgetTemplate): Flight.Request {\n const params = CuratedDashboardHelper.getWidgetParams(\n widgetTypeId,\n template,\n CuratedDashboardHelper.getDashboardTargetType(props.dashboard)\n );\n\n return props.getWidgetContentRequest(id, params, template);\n }\n\n const showEmptyState = props.isReadonly && !widgets?.length;\n\n return (\n <>\n <StreamableHeader\n active='discover'\n appLinks={props.headerAppLinks}\n isUpselling={props.isUpselling}\n />\n\n {props.tutorialVideosContext?.shouldShowPanel && (\n <div className='curated-widget rounded-3 mb-3 mx-n4 px-4 py-3 overflow-hidden'>\n {\n props.tutorialVideosContext.readyToShowPanel ?\n <TutorialVideoWidget\n commonVideoProps={props.commonVideoProps}\n audiences={props.audiences}\n context={props.tutorialVideosContext}\n /> :\n <PartialPopoutThumbnailSlidingListSmallWidgetTemplate\n hideDescription\n />\n }\n </div>\n )}\n\n {widgets.map((widget, idx) => {\n return (\n <WidgetContainerView\n widgetCollection={DashboardTargetType.Discover}\n key={widget.id}\n id={widget.id}\n getContentRequest={getWidgetContentRequest}\n audiences={props.audiences}\n name={widget.name}\n description={widget.description}\n templateId={widget.templateId}\n metadata={widget.metadata}\n presentation={props.presentation}\n appLinks={props.widgetAppLinks}\n isScrollToTargetWidget={props?.scrollToWidgetId === widget.id}\n widgetTypeId={widget.widgetId}\n lazyLoad={props.lazyLoad}\n dashboardTarget={DashboardTargetType.Discover}\n widgetIndex={idx}\n isPreviewing={props.isReadonly}\n contentType={CalendarEventContentType.Livestream}\n preferences={widget.preferences}\n hasPermissions={hasPermissions}\n hasLocalPermissions={hasLocalPermissions}\n isTertiaryCustomerWithoutExchange={false}\n preventPopout\n imageCdnUrl={props.commonVideoProps.imageCdnUrl}\n commonVideoProps={props.commonVideoProps}\n isUpselling={props.isUpselling}\n\n availablePresentations={undefined}\n classification={undefined}\n hasTableOfContents={undefined}\n onSubmitFeedback={undefined}\n settings={undefined}\n updatePreferences={undefined}\n seeMoreLink={undefined}\n onClickRemoveItem={undefined}\n badgeComponent={undefined}\n\n />\n );\n })}\n\n {showEmptyState && (\n <StreamableDiscoverDashboardEmptyState\n dashboard={props.dashboard}\n isReadonly={props.isReadonly}\n imageUrl={props.emptyImageUrl}\n addWidgetApplink={props.widgetAppLinks.widgetWizard}\n />\n )}\n </>\n );\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { StorageType } from 'libs/common/backbone/utils/LocalStorageHelper';\nimport { Flight } from 'libs/common/flight';\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\n\nimport { LocationContext } from 'libs/analytics/interfaces';\n\nimport { StreamableDiscoverDashboard } from 'libs/shared/apps/streamable-learning/components/dashboard/StreamableDiscoverDashboard';\nimport { SharedViewModelKeys } from 'libs/shared/constants/SharedViewModelKeys';\nimport { PresentationType } from 'libs/shared/enums/PresentationType';\nimport { AudienceRequests } from 'libs/shared/flight-requests/AudienceRequests';\nimport { DashboardRequests } from 'libs/shared/flight-requests/DashboardRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useSetPageMetadata } from 'libs/shared/hooks/useSetPageMetadata';\nimport { CurrentUser, DashboardTargetType, PresentationAudience } from 'libs/shared/interfaces';\nimport { AudienceHelper } from 'libs/shared/utils/audience-helper/AudienceHelper';\nimport { PageMetadataHelper } from 'libs/shared/utils/PageMetadataHelper';\n\nimport { UpsellFooterBanner } from 'shared/components/upsell-footer-banner/UpsellFooterBanner';\nimport { useActivePresentation } from 'shared/hooks/presentations/useActivePresentation';\nimport { useAvailablePresentations } from 'shared/hooks/presentations/useAvailablePresentations';\nimport { useCommonVideoProps } from 'shared/hooks/useCommonVideoProps';\nimport { useRequestAccess } from 'shared/hooks/useRequestAccess';\nimport { useUpsellContext } from 'shared/hooks/useUpsellContext';\nimport { DashboardViewQueryParams } from 'shared/interfaces/query-params/DashboardViewQueryParams';\nimport { useFetchCuratedDashboard } from 'shared/utils/DashboardHelper';\nimport { SeoHelper } from 'shared/utils/SeoHelper';\nimport { filterUpsellWidgets } from 'shared/utils/UpsellWidgetHelper';\n\nimport { useTutorialVideos } from 'apps/dashboard/hooks/useTutorialVideos';\nimport { getLiveExperiencesDiscoverWidgetAppLinks, getLiveHeaderAppLinks } from 'apps/dashboard/views/dashboard/DiscoverViewUtils';\n\nconst namespace = 'liveDiscover.discover';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface LiveDiscoverViewProps {\n presentationSlug: string | null;\n queryParams?: DashboardViewQueryParams;\n}\n\nexport function LiveDiscoverView(props: LiveDiscoverViewProps): JSX.Element {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const { availablePresentations } = useAvailablePresentations();\n const { activePresentation } = useActivePresentation();\n\n const [activeAudiences] = useViewModel<PresentationAudience[]>(\n SharedViewModelKeys.AUDIENCE_FILTER,\n undefined,\n { storage: StorageType.SessionStorage }\n );\n \n const { upsellKind } = useUpsellContext();\n\n const { applinks: widgetAppLinks, requestAccessApplink, isUpselling, onClickRequestAccessButton } = useRequestAccess({\n applinks: getLiveExperiencesDiscoverWidgetAppLinks(\n AudienceHelper.getAudienceParams(activeAudiences),\n currentUser.data,\n props.presentationSlug,\n availablePresentations\n )\n });\n\n const { commonVideoProps } = useCommonVideoProps({\n locationContext: LocationContext.Dashboard,\n hoverToPlay: !isUpselling(activePresentation),\n subTextAppLink: isUpselling(activePresentation) ? requestAccessApplink : null\n });\n\n const tutorialVideoContext = useTutorialVideos('live');\n\n const {\n dashboard,\n presentation\n } = useFetchCuratedDashboard({\n targetType: DashboardTargetType.Discover,\n queryParams: props.queryParams\n });\n\n // ClickView Live audiences are typed differently from Subject audiences for the same presentation id;\n // Fetch with the explicit Live type so we get the correct grade set.\n const audiences = Flight.useBasicFetch<PresentationAudience[]>(\n presentation &&\n AudienceRequests.presentationAudiences(PresentationType.StreamableLearning, presentation.id)\n );\n\n useSetPageMetadata(PageMetadataHelper.getDiscoverMetadata({\n content: presentation,\n phraseContext: {\n phraseHandler: getPhrase,\n titlePhrase: 'pageTitle',\n descriptionPhrase: 'pageDescription'\n },\n canonicalLink: SeoHelper.getCanonicalLink(),\n allowIndexing: true\n }));\n\n const hasLoaded = (\n dashboard.hasCompleted &&\n !!presentation &&\n audiences.hasCompleted\n );\n\n if (!hasLoaded)\n return <></>;\n\n return (\n <div className='bg-white px-4'>\n <StreamableDiscoverDashboard\n dashboard={filterUpsellWidgets(dashboard.data, isUpselling(activePresentation))}\n widgetAppLinks={widgetAppLinks}\n headerAppLinks={getLiveHeaderAppLinks(props.presentationSlug)}\n presentation={presentation}\n getWidgetContentRequest={DashboardRequests.dashboardWidgetContent}\n audiences={audiences.data}\n lazyLoad={!SeoHelper.isBot()}\n commonVideoProps={commonVideoProps}\n tutorialVideosContext={isUpselling(activePresentation) ? null : tutorialVideoContext}\n isUpselling={isUpselling(activePresentation)}\n />\n {isUpselling(activePresentation) &&\n <UpsellFooterBanner\n upsellKind={upsellKind}\n onClickRequestAccessButton={onClickRequestAccessButton}\n />\n }\n </div>\n );\n}\n","import React from 'react';\n\nimport { PresentationType } from 'libs/shared/enums/PresentationType';\n\nimport { DashboardViewQueryParams } from 'shared/interfaces/query-params/DashboardViewQueryParams';\nimport { createPresentationDispatcherView } from 'shared/utils/createPresentationDispatcherView';\n\nimport { CuratedDiscoverView } from 'apps/dashboard/views/dashboard/curated-discover/CuratedDiscoverView';\nimport { LiveDiscoverView } from 'apps/dashboard/views/dashboard/live-discover/LiveDiscoverView';\n\ninterface DiscoverRouteProps {\n queryParams?: DashboardViewQueryParams;\n presentationSlug: string | null;\n}\n\nexport const BaseDiscoverView = createPresentationDispatcherView<DiscoverRouteProps>({\n [PresentationType.Subject]: ctx => (\n <CuratedDiscoverView presentationSlug={ctx.presentationSlug} queryParams={ctx.queryParams} />\n ),\n [PresentationType.StreamableLearning]: ctx => (\n <LiveDiscoverView presentationSlug={ctx.presentationSlug} queryParams={ctx.queryParams} />\n )\n});\n\nBaseDiscoverView.displayName = 'BaseDiscoverView';\n"],"mappings":"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"}
1
+ {"version":3,"file":"DaaQ5htA2.chunk.js","names":[],"sources":["../../../../libs/shared/src/apps/discover/components/tutorial-videos/TutorialVideoWidget.tsx","../../../../libs/shared/src/components/widgets/countdown/countdown.module.scss","../../../../libs/shared/src/components/widgets/countdown/CountdownWidget.tsx","../../../../libs/shared/src/components/widgets/countdown/CountdownContainer.tsx","../../../../libs/shared/src/components/widgets/countdown/events/commonwealth-game.ts","../../../../libs/shared/src/apps/discover/components/discover-dashboard/empty-state/DiscoverDashboardEmptyState.tsx","../../../../libs/shared/src/apps/discover/components/discover-dashboard/DiscoverDashboard.tsx","../../src/shared/components/upsell-footer-banner/upsell-footer-banner.module.scss","../../src/shared/components/upsell-footer-banner/UpsellFooterBanner.tsx","../../src/shared/utils/UpsellWidgetHelper.ts","../../src/apps/dashboard/views/dashboard/curated-discover/CuratedDiscoverView.tsx","../../../../libs/shared/src/apps/streamable-learning/components/dashboard/empty-state/StreamableDiscoverDashboardEmptyState.tsx","../../../../libs/shared/src/apps/streamable-learning/components/dashboard/StreamableDiscoverDashboard.tsx","../../src/apps/dashboard/views/dashboard/live-discover/LiveDiscoverView.tsx","../../src/apps/dashboard/views/dashboard/BaseDiscoverView.tsx"],"sourcesContent":["import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/react/index';\n\nimport { FixedWidget } from 'libs/shared/components/widgets/fixed-widget';\nimport { VideoWidgetItemV2 } from 'libs/shared/components/widgets/items/video-widget-item/v2/VideoWidgetItemV2';\nimport { WidgetContents } from 'libs/shared/enums/WidgetContents';\nimport { PlaylistRequests } from 'libs/shared/flight-requests/PlaylistRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { CurrentUser, Following, PresentationAudience, Video, VideoTypes } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\n\nconst namespace = 'discover.tutorials';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport interface TutorialVideosContext {\n playlistId: string;\n videos?: VideoTypes[];\n shouldShowPanel: boolean;\n readyToShowPanel: boolean;\n shouldShowProductTip: boolean;\n dismissPanel?: () => void;\n appLink?: Core.AppLink;\n getVideoAppLink?: (child: Video) => Core.AppLink;\n}\n\ninterface TutorialVideoWidgetProps {\n commonVideoProps: CommonVideoProps;\n audiences: PresentationAudience[];\n context: TutorialVideosContext;\n}\n\nexport function TutorialVideoWidget(props: TutorialVideoWidgetProps) {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n \n const following = Flight.useBasicFetch<Following>(\n currentUser.data?.id &&\n PlaylistRequests.getIsFollowingPlaylist(props.context.playlistId, currentUser.data?.id)\n );\n\n const [ isFollowing, setIsFollowing ] = React.useState(null);\n const [ showSpinner, setShowSpinner ] = React.useState(false);\n const alerts = useAlerts();\n const fetchAsync = Flight.useGetFetchAsync();\n\n React.useEffect(() => {\n if (following.hasCompleted) {\n setIsFollowing(following.data?.isFollowing);\n }\n }, [following.data?.isFollowing]);\n\n const follow = async (shouldFollow: boolean) => {\n setShowSpinner(true);\n\n const req = shouldFollow ?\n PlaylistRequests.followPlaylist :\n PlaylistRequests.unfollowPlaylist;\n\n const error = () => {\n alerts.error(getPhrase(shouldFollow ? 'followError' : 'unfollowError'));\n setShowSpinner(false);\n };\n\n const success = () => {\n alerts.success(getPhrase(shouldFollow ? 'followSuccess' : 'unfollowSuccess'));\n setIsFollowing(shouldFollow);\n setShowSpinner(false);\n };\n\n await fetchAsync(req(props.context.playlistId, currentUser.data?.id, success, error));\n };\n \n return (\n <FixedWidget\n name={getPhrase('heading')}\n contents={WidgetContents.Videos}\n appLink={props.context.appLink}\n getChildAppLink={props.context.getVideoAppLink}\n collection={props.context.videos}\n childComponent={VideoWidgetItemV2}\n extraChildComponentProps={{\n commonVideoProps: props.commonVideoProps,\n presentationAudiences: props.audiences\n }}\n showSeeMoreLink={false}\n onClose={props.context.dismissPanel}\n onFollow={follow}\n isFollowing={isFollowing}\n showFollowSpinner={showSpinner}\n prefetched\n />\n );\n}\n","@import '~styles/utils/include-media';\n\n:local {\n .container {\n background-size: cover;\n }\n\n .eventLogo {\n width: 2.0625rem; //32px + 1px border\n height: 2.0625rem;\n }\n\n .cvLogoContainer {\n width: 2.0625rem;\n height: 2.0625rem;\n }\n\n .cvLogo {\n width: 0.625rem;\n // ClickView logo looks better when positioned slightly further to the right\n left: 53%;\n top: 50%;\n transform: translate(-50%, -50%);\n }\n\n .countdownGrid {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: map-get($spacers, 1);\n\n @include media('<=md') {\n margin-top: map-get($spacers, 2);\n }\n }\n\n .timeBox {\n width: 4.3125rem;\n height: 4.3125rem;\n border: 0.125rem solid $light-blue;\n }\n\n .timeLabel {\n font-size: 0.75rem; //12px\n }\n}\n","import React from 'react';\n\nimport { AppLink } from 'libs/common/backbone/core';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { AppLink as AppLinkComponent } from 'libs/shared/components/app-link/AppLink';\nimport { ClickViewPlayLogo } from 'libs/shared/components/svgs/clickview-logo/ClickViewLogo';\nimport { CountdownImageUrls } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\n\nimport styles from './countdown.module.scss';\n\nconst timeUnitNamespace = 'shared.countdown';\n\ninterface TimeBoxProps {\n value: number;\n label: string;\n shouldFormat: boolean;\n}\n\nfunction formatNumber(num: number) {\n return num.toString().padStart(2, '0');\n}\n\nfunction TimeBox(props: TimeBoxProps) {\n return (\n <div className={`bg-white d-flex rounded-3 flex-column align-items-center justify-content-center p-1 ${styles.timeBox}`}>\n <div className='fs-5 h6 mb-0 flex-grow-1 align-content-center'>\n {props.shouldFormat ? formatNumber(props.value) : props.value}\n </div>\n <div className={styles.timeLabel}>{props.label}</div>\n </div>\n );\n}\n\nexport interface CountdownWidgetProps {\n targetDate: Date;\n endDate: Date;\n imageUrls: CountdownImageUrls;\n langNamespace: string;\n appLink?: AppLink;\n onCtaClick?: () => void;\n /** When true, the event has ended but is still shown (due to showDaysAfter). */\n hasEnded?: boolean;\n}\n\nexport function CountdownWidget(props: CountdownWidgetProps): JSX.Element | null {\n const [ timeLeft, setTimeLeft ] = React.useState({\n days: 0,\n hours: 0,\n minutes: 0,\n seconds: 0\n });\n const [ isEventEnded, setIsEventEnded ] = React.useState(false);\n const shouldShowLogos = props.imageUrls.logo;\n\n React.useEffect(() => {\n let timer: number = 0;\n\n const calculateTimeLeft = () => {\n const now = new Date().getTime();\n const targetTime = props.targetDate.getTime();\n const endTime = props.endDate.getTime();\n\n if (now >= endTime) {\n setIsEventEnded(true);\n clearInterval(timer);\n return;\n }\n\n const difference = targetTime - now;\n\n if (difference > 0) {\n setTimeLeft({\n days: Math.floor(difference / (1000 * 60 * 60 * 24)),\n hours: Math.floor((difference / (1000 * 60 * 60)) % 24),\n minutes: Math.floor((difference / 1000 / 60) % 60),\n seconds: Math.floor((difference / 1000) % 60)\n });\n } else {\n setTimeLeft({ days: 0, hours: 0, minutes: 0, seconds: 0 });\n clearInterval(timer);\n }\n };\n\n calculateTimeLeft();\n timer = window.setInterval(calculateTimeLeft, 1000);\n\n return () => clearInterval(timer);\n }, [ props.targetDate, props.endDate ]);\n\n if (isEventEnded && !props.hasEnded) {\n return null;\n }\n\n const timeUnits = [\n { value: timeLeft.days, label: LanguageService.getPhrase(timeUnitNamespace, 'days'), format: false },\n { value: timeLeft.hours, label: LanguageService.getPhrase(timeUnitNamespace, 'hours'), format: true },\n { value: timeLeft.minutes, label: LanguageService.getPhrase(timeUnitNamespace, 'minutes'), format: true },\n { value: timeLeft.seconds, label: LanguageService.getPhrase(timeUnitNamespace, 'seconds'), format: true }\n ];\n\n const isCountdownFinished = timeLeft.days === 0\n && timeLeft.hours === 0\n && timeLeft.minutes === 0\n && timeLeft.seconds === 0;\n\n return (\n <div\n className={`${styles.container} position-relative d-flex flex-md-row justify-content-md-between flex-column justify-content-center align-items-center p-3 mb-4 rounded`}\n style={{\n backgroundImage: `url('${props.imageUrls.background}')`\n }}\n >\n <div className='d-flex flex-column gap-2 align-items-md-start align-items-center w-md-auto w-100'>\n <div className='d-flex flex-md-row align-items-center flex-column gap-2'>\n {shouldShowLogos && (\n <ul className='list-unstyled d-flex mb-0'>\n <li className={`bg-white rounded-circle z-1 ${styles.eventLogo} border`}>\n <img src={props.imageUrls.logo} className='rounded-circle img-fluid' />\n </li>\n <li className={`bg-white rounded-circle position-relative ms-n1 ${styles.cvLogoContainer} border`}>\n <div className={`position-absolute d-flex align-items-center justify-content-center ${styles.cvLogo}`}>\n <ClickViewPlayLogo />\n </div>\n </li>\n </ul>\n )}\n <h2 className='h4 text-white text-shadow mb-0 lh-1 my-3 my-md-0'>\n {props.hasEnded ?\n LanguageService.getPhrase(props.langNamespace, 'titleAfter') :\n isCountdownFinished ?\n LanguageService.getPhrase(props.langNamespace, 'titleStarted') :\n LanguageService.getPhrase(props.langNamespace, 'title')}\n </h2>\n </div>\n {props.appLink &&\n <AppLinkComponent\n appLink={props.appLink}\n className='btn btn-outline-dark w-fit d-none d-md-flex'\n onClick={props.onCtaClick}\n >\n {LanguageService.getPhrase(props.langNamespace, 'cta')}\n </AppLinkComponent>\n }\n </div>\n\n {!isCountdownFinished &&\n <div className={styles.countdownGrid}>\n {timeUnits.map(unit => <TimeBox key={unit.label} {...unit} shouldFormat={unit.format} />)}\n </div>\n }\n\n {props.appLink &&\n <AppLinkComponent\n appLink={props.appLink}\n className='btn btn-outline-dark w-fit mt-3 d-md-none d-flex'\n onClick={props.onCtaClick}\n >\n {LanguageService.getPhrase(props.langNamespace, 'ctaMobile')}\n </AppLinkComponent>\n }\n </div>\n );\n}\n","import React from 'react';\n\nimport { AppLink } from 'libs/common/backbone/core';\n\nimport { CountdownImageUrls } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\n\nimport { CountdownWidget } from './CountdownWidget';\n\ninterface ImageUrlMap {\n [key: string]: ImageUrlMap | string;\n}\n\nexport interface CountdownExternalContext {\n // Map of image URL constants from the consuming project\n imageUrls: ImageUrlMap;\n getAppLink: (presentationId: string, eventTopicKey: string) => AppLink | null;\n}\n\ninterface ResolvedEventData {\n imageUrls: CountdownImageUrls | null;\n appLink?: AppLink | null;\n}\n\nexport interface CountdownEventConfig {\n key: string;\n // countdown will count towards this date\n targetDate: Date;\n // event is hidden after this date\n endDate: Date;\n langNamespace: string;\n allowedPresentationIds: string[];\n // key used to look up event topics in HardCoded (e.g. 'OlympicsTopics', 'CommonwealthGameTopics')\n eventTopicKey: string;\n getEventConfig: (presentationId: string, context: CountdownExternalContext) => ResolvedEventData;\n /** \n * Number of days before targetDate to start showing the countdown.\n * If not provided, the countdown is shown immediately (as long as now < endDate).\n * Make sure to set up phrase 'titleStarted' for your event.\n */\n showDaysBefore?: number;\n /**\n * Number of days after endDate to keep showing the countdown.\n * If not provided, the countdown is hidden immediately after endDate.\n * Make sure to set up phrase 'tittleAfter' for your event.\n */\n showDaysAfter?: number;\n}\n\ninterface CountdownContainerProps {\n presentationId: string;\n // List of countdown event configs, ordered by priority\n events: CountdownEventConfig[];\n // External context passed from the consuming component\n context: CountdownExternalContext;\n}\n\nfunction getActiveEvent(\n events: CountdownEventConfig[],\n presentationId: string\n): CountdownEventConfig | undefined {\n const now = new Date().getTime();\n\n return events.find(event => {\n if (!event.allowedPresentationIds.includes(presentationId)) {\n return false;\n }\n\n const effectiveEndDate = event.showDaysAfter !== undefined ?\n event.endDate.getTime() + event.showDaysAfter * 24 * 60 * 60 * 1000 :\n event.endDate.getTime();\n\n if (now >= effectiveEndDate) {\n return false;\n }\n\n if (event.showDaysBefore !== undefined) {\n const showFromDate = new Date(event.targetDate.getTime() - event.showDaysBefore * 24 * 60 * 60 * 1000);\n if (now < showFromDate.getTime()) {\n return false;\n }\n }\n\n return true;\n });\n}\n\nexport function CountdownContainer(props: CountdownContainerProps): JSX.Element | null {\n const activeEvent = getActiveEvent(props.events, props.presentationId);\n\n if (!activeEvent) {\n return null;\n }\n\n const config = activeEvent.getEventConfig(props.presentationId, props.context);\n\n if (!config.imageUrls) {\n return null;\n }\n\n const hasEnded = new Date().getTime() >= activeEvent.endDate.getTime();\n\n return (\n <CountdownWidget\n key={activeEvent.key}\n targetDate={activeEvent.targetDate}\n endDate={activeEvent.endDate}\n imageUrls={config.imageUrls}\n langNamespace={activeEvent.langNamespace}\n appLink={config.appLink}\n hasEnded={hasEnded}\n />\n );\n}\n","import { HardCoded } from 'libs/shared/constants/HardCoded';\n\nimport { CountdownEventConfig } from '../CountdownContainer';\n\nconst COMMONWEALTH_GAME_START_DATE_UTC = new Date('2026-07-23T00:00:00Z');\nconst COMMONWEALTH_GAME_END_DATE_UTC = new Date('2026-08-02T23:59:59Z');\n\nconst COMMONWEALTH_GAME_PRESENTATION_IDS = [\n HardCoded.PresentationIds.SCT_PRIMARY,\n HardCoded.PresentationIds.SCT_SECONDARY,\n HardCoded.PresentationIds.ENG_PRIMARY,\n HardCoded.PresentationIds.ENG_SECONDARY,\n HardCoded.PresentationIds.AU_PRIMARY,\n HardCoded.PresentationIds.AU_SECONDARY\n].map(id => id.toString());\n\nconst PRESENTATION_TO_IMAGE_KEY: Record<string, string> = {\n [HardCoded.PresentationIds.SCT_PRIMARY]: 'SCT_PRIMARY',\n [HardCoded.PresentationIds.SCT_SECONDARY]: 'SCT_SECONDARY',\n [HardCoded.PresentationIds.ENG_PRIMARY]: 'ENG_PRIMARY',\n [HardCoded.PresentationIds.ENG_SECONDARY]: 'ENG_SECONDARY',\n [HardCoded.PresentationIds.AU_PRIMARY]: 'AU_PRIMARY',\n [HardCoded.PresentationIds.AU_SECONDARY]: 'AU_SECONDARY'\n};\n\nexport const commonwealthGameCountdownEvent: CountdownEventConfig = {\n key: 'commonwealth-games-2026',\n targetDate: COMMONWEALTH_GAME_START_DATE_UTC,\n endDate: COMMONWEALTH_GAME_END_DATE_UTC,\n langNamespace: 'shared.commonwealthGameCountdown',\n allowedPresentationIds: COMMONWEALTH_GAME_PRESENTATION_IDS,\n eventTopicKey: 'CommonwealthGameTopics',\n // we want to show the event for 30 days before the start\n showDaysBefore: 30,\n // we want to show the event for 7 days after the end day\n showDaysAfter: 7,\n\n getEventConfig: (presentationId, context) => {\n const images = context.imageUrls.CommonwealthGamesCountdown as Record<string, string> | undefined;\n\n if (!images) {\n return { imageUrls: null };\n }\n\n const imageKey = PRESENTATION_TO_IMAGE_KEY[presentationId];\n const background = imageKey ? images[imageKey] as string : null;\n\n if (!background) {\n return { imageUrls: null };\n }\n\n const appLink = context.getAppLink(presentationId, 'CommonwealthGameTopics');\n\n return {\n // we don't show logos for this event\n imageUrls: { background },\n appLink\n };\n }\n};\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { PlusSvg } from 'libs/shared/images/svg/actions/PlusSvg';\nimport { CuratedDashboard, DashboardStatus } from 'libs/shared/interfaces';\n\nconst namespace = 'subjects.discoverDashboardEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface DiscoverDashboardEmptyStateProps {\n dashboard: CuratedDashboard;\n imageUrl: string;\n isReadonly: boolean;\n addWidgetApplink?: () => Core.AppLink;\n}\n\nexport function DiscoverDashboardEmptyState(props: DiscoverDashboardEmptyStateProps): JSX.Element {\n const isArchived = props.dashboard?.status === DashboardStatus.Archived;\n\n return (\n <EmptyState>\n <EmptyState.Image src={props.imageUrl} altText={getPhrase('info')} />\n <EmptyState.Heading>\n <Text namespace={namespace} phrase='heading' />\n </EmptyState.Heading>\n <EmptyState.Info>\n <Text namespace={namespace} phrase='info' />\n </EmptyState.Info>\n <Tooltip title={isArchived ? LanguageService.getPhrase(namespace, 'archivedCtaTooltip') : ''} spanHack>\n <EmptyState.Cta\n text={LanguageService.getPhrase(namespace, 'add')}\n appLink={props.addWidgetApplink?.()}\n className='btn btn-dark'\n icon={PlusSvg}\n disabled={isArchived}\n />\n </Tooltip>\n </EmptyState>\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { Flight } from 'libs/common/flight';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { DiscoverHeader, DiscoverHeaderAppLinks } from 'libs/shared/apps/discover/components/header/DiscoverHeader';\nimport { TutorialVideosContext, TutorialVideoWidget } from 'libs/shared/apps/discover/components/tutorial-videos/TutorialVideoWidget';\nimport { DashboardFeedbackData } from 'libs/shared/components/feedback-form/FeedbackForm';\nimport { CountdownContainer, CountdownExternalContext } from 'libs/shared/components/widgets/countdown/CountdownContainer';\nimport { commonwealthGameCountdownEvent } from 'libs/shared/components/widgets/countdown/events/commonwealth-game';\nimport { PartialPopoutThumbnailSlidingListSmallWidgetTemplate } from 'libs/shared/components/widgets/curated-widgets/templates/popout_thumbnail_sliding_list_small/partial-loading/PartialPopoutThumbnailSlidingListSmall';\nimport { WidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/WidgetContainerView';\nimport { AllDiscoverWidgetTemplates } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { HasLocalPermissionsFunc, HasPermissionsFunc } from 'libs/shared/hooks/usePermissions';\nimport { SettingsHash } from 'libs/shared/hooks/useSettings';\nimport { CalendarEventContentType, CuratedDashboard, CuratedWidgetQueryParams, DashboardTargetType, Presentation, PresentationAudience, WidgetPreference } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\n\nimport { DiscoverDashboardEmptyState } from './empty-state/DiscoverDashboardEmptyState';\n\nexport interface DiscoverDashboardProps {\n dashboard: CuratedDashboard;\n getWidgetContentRequest: (\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate,\n presentation: Presentation\n ) => Flight.Request;\n audiences: PresentationAudience[];\n hasPermissions: HasPermissionsFunc;\n hasLocalPermissions: HasLocalPermissionsFunc;\n emptyImageUrl?: string;\n presentation: Presentation;\n widgetAppLinks?: AllDiscoverWidgetTemplates['appLinks'] & {\n widgetWizard: () => Core.AppLink\n };\n headerAppLinks?: DiscoverHeaderAppLinks;\n scrollToWidgetId?: string;\n updatePreferences?: (\n widgetId: string,\n widgetTypeId: WidgetTypeId,\n oldPreferences: WidgetPreference[],\n newPreferences: WidgetPreference[]\n ) => Promise<void>;\n onSubmitFeedback?: (feedback: DashboardFeedbackData) => Promise<void>;\n removeFromVideoHistory: (videoId: string, videoName: string, widgetId: string, widgetTypeId: WidgetTypeId) => void;\n isReadonly?: boolean;\n lazyLoad?: boolean;\n showCalendar: boolean;\n settings: SettingsHash;\n availablePresentations: Presentation[];\n isTertiaryCustomerWithoutExchange: boolean;\n commonVideoProps: CommonVideoProps;\n countdownContext?: CountdownExternalContext;\n tutorialVideosContext?: TutorialVideosContext;\n contentType?: CalendarEventContentType;\n isUpselling?: boolean;\n reminderComponent?: JSX.Element;\n}\n\nexport function DiscoverDashboard(props: DiscoverDashboardProps): JSX.Element {\n const widgets = ArrayHelper.sortBy(props.dashboard?.widgets, 'index');\n\n function getWidgetContentRequest(id: string, widgetTypeId: WidgetTypeId, template: WidgetTemplate): Flight.Request {\n const params = CuratedDashboardHelper.getWidgetParams(\n widgetTypeId,\n template,\n CuratedDashboardHelper.getDashboardTargetType(props.dashboard)\n );\n\n return props.getWidgetContentRequest(id, params, template, props.presentation);\n }\n\n const showEmptyState = props.isReadonly && !widgets?.length;\n\n return (\n <>\n <DiscoverHeader\n type={props.dashboard?.userType}\n appLinks={props.headerAppLinks}\n hasStudentExperience={props.hasPermissions(PermissionName.StudentExperience)}\n showCalendar={props.showCalendar}\n active='forYou'\n isUpselling={props.isUpselling}\n />\n\n {props.tutorialVideosContext?.shouldShowPanel && (\n <div className='curated-widget rounded-3 mb-3 mx-n4 px-4 py-3 overflow-hidden'>\n {\n props.tutorialVideosContext.readyToShowPanel ?\n <TutorialVideoWidget\n commonVideoProps={props.commonVideoProps}\n audiences={props.audiences}\n context={props.tutorialVideosContext}\n /> :\n <PartialPopoutThumbnailSlidingListSmallWidgetTemplate\n hideDescription\n />\n }\n </div>\n )}\n\n {props.countdownContext && props.presentation?.id && (\n <CountdownContainer\n presentationId={props.presentation.id.toString()}\n events={[commonwealthGameCountdownEvent]}\n context={props.countdownContext}\n />\n )}\n\n {widgets.map((widget, idx) => {\n return (\n <WidgetContainerView\n widgetCollection={DashboardTargetType.Discover}\n key={widget.id}\n id={widget.id}\n getContentRequest={getWidgetContentRequest}\n audiences={props.audiences}\n name={widget.name}\n description={widget.description}\n templateId={widget.templateId}\n metadata={widget.metadata}\n presentation={props.presentation}\n preferences={widget.preferences}\n appLinks={props.widgetAppLinks}\n isScrollToTargetWidget={props?.scrollToWidgetId === widget.id}\n widgetTypeId={widget.widgetId}\n hasPermissions={props.hasPermissions}\n hasLocalPermissions={props.hasLocalPermissions}\n onSubmitFeedback={props.onSubmitFeedback}\n updatePreferences={props.updatePreferences}\n lazyLoad={props.lazyLoad}\n dashboardTarget={DashboardTargetType.Discover}\n widgetIndex={idx}\n isPreviewing={props.isReadonly}\n settings={{\n hasTopicDirectories: props.settings?.hasTopicDirectories\n }}\n availablePresentations={props.availablePresentations}\n imageCdnUrl={props.commonVideoProps.imageCdnUrl}\n commonVideoProps={props.commonVideoProps}\n settingsHash={props.settings}\n contentType={props.contentType}\n isUpselling={props.isUpselling}\n\n // TODO: Ideally we don't have to do this\n classification={undefined}\n hasTableOfContents={false}\n limitTotalItems={false}\n isTertiaryCustomerWithoutExchange={props.isTertiaryCustomerWithoutExchange}\n seeMoreLink={undefined}\n onClickRemoveItem={props.removeFromVideoHistory}\n badgeComponent={null}\n reminderComponent={props.reminderComponent}\n />\n );\n })}\n\n {showEmptyState && (\n <DiscoverDashboardEmptyState\n dashboard={props.dashboard}\n isReadonly={props.isReadonly}\n imageUrl={props.emptyImageUrl}\n addWidgetApplink={props.widgetAppLinks.widgetWizard}\n />\n )}\n </>\n );\n}\n",":local {\n .image {\n max-height: 11.25rem; // 180px\n width: auto;\n }\n\n .successSvg {\n svg {\n color: $green-500;\n }\n }\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { EntityType, LocationContext, UpsellBannerDescriptor, UserAction } from 'libs/analytics/interfaces';\n\nimport { ActionButton } from 'libs/shared/components/actions/ActionButton';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { CheckCircleSvg } from 'libs/shared/images/svg/status/CheckCircleSvg';\n\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { OnClickRequestAccessButton } from 'shared/hooks/useRequestAccessApplink';\nimport { UpsellKind } from 'shared/utils/UpsellHelper';\n\nimport styles from './upsell-footer-banner.module.scss';\n\nconst namespace = 'shared.upsellFooterBanner';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface UpsellBannerOptions {\n backgroundClass: string;\n imageUrl: string;\n headingPhrase: string;\n descriptionPhrase: string;\n ctaPhrase: string;\n}\n\nconst VARIANTS: Record<UpsellKind, UpsellBannerOptions> = {\n [UpsellKind.StartCvTrial]: {\n backgroundClass: 'bg-light-orange border border-orange',\n imageUrl: ImageUrls.Upsell.CLICKVIEW_FOOTER_BANNER,\n headingPhrase: 'headingClickView',\n descriptionPhrase: 'descriptionTrialClickView',\n ctaPhrase: 'startTrial'\n },\n [UpsellKind.StartLiveTrial]: {\n backgroundClass: 'bg-light-green border border-green',\n imageUrl: ImageUrls.Upsell.CLICKVIEW_LIVE_FOOTER_BANNER,\n headingPhrase: 'headingClickViewLive',\n descriptionPhrase: 'descriptionTrialClickViewLive',\n ctaPhrase: 'startTrial'\n },\n [UpsellKind.RequestCvPilot]: {\n backgroundClass: 'bg-light-orange border border-orange',\n imageUrl: ImageUrls.Upsell.CLICKVIEW_FOOTER_BANNER,\n headingPhrase: 'headingClickView',\n descriptionPhrase: 'descriptionPilot',\n ctaPhrase: 'requestAccess'\n },\n [UpsellKind.RequestLivePilot]: {\n backgroundClass: 'bg-light-green border border-green',\n imageUrl: ImageUrls.Upsell.CLICKVIEW_LIVE_FOOTER_BANNER,\n headingPhrase: 'headingClickViewLive',\n descriptionPhrase: 'descriptionPilot',\n ctaPhrase: 'requestAccess'\n }\n};\n\ninterface UpsellFooterBannerProps {\n upsellKind: UpsellKind;\n onClickRequestAccessButton: OnClickRequestAccessButton;\n}\n\nexport function UpsellFooterBanner(props: UpsellFooterBannerProps): JSX.Element {\n const [ requestState, setRequestState ] = React.useState<'idle' | 'success' | 'loading' | 'error'>('idle');\n const alerts = useAlerts();\n \n const variant = VARIANTS[props.upsellKind];\n\n async function onClickRequestAccessButton() {\n await props.onClickRequestAccessButton({\n setRequestState: state => {\n if (state === 'error')\n alerts.error(getPhrase('errorRequestingAccess'));\n\n setRequestState(state);\n }\n });\n }\n\n function getButtonText() {\n if (requestState === 'loading')\n return getPhrase('loading');\n\n if (requestState === 'success')\n return getPhrase('requestSent');\n\n return getPhrase(variant.ctaPhrase);\n }\n \n const buttonText = getButtonText();\n const buttonIcon = requestState === 'success' ? CheckCircleSvg : undefined;\n const buttonClassName = classNames('btn btn-dark', !!buttonIcon && styles.successSvg);\n\n return (\n <div className={classNames(\n 'd-flex align-items-center justify-content-between overflow-hidden rounded-3 mb-4',\n variant.backgroundClass\n )}>\n <div className='p-4'>\n <h3 className='mb-3'>{getPhrase(variant.headingPhrase)}</h3>\n <p className='mb-4'>\n <Text namespace={namespace} phrase={variant.descriptionPhrase}/>\n </p>\n <ActionButton\n analyticsData={{ upsellKind: props.upsellKind }}\n analyticsOptions={{\n actionType: UserAction.Click,\n entity: EntityType.AppLink,\n location: LocationContext.UpsellBanner,\n descriptor: UpsellBannerDescriptor.StartTrial\n }}\n svg={buttonIcon}\n className={buttonClassName}\n onClick={onClickRequestAccessButton}\n disabled={[ 'success', 'loading' ].includes(requestState)}\n >\n {buttonText}\n </ActionButton>\n </div>\n <img\n className={classNames('d-none d-md-block align-self-end', styles.image)}\n src={variant.imageUrl}\n alt='Envelope'\n />\n </div>\n );\n}\n","import { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { BaseWidget, CuratedDashboard } from 'libs/shared/interfaces';\n\nconst ALL_TEMPLATES = 'all' as const;\n\nconst MIN_UPSELL_WIDGETS = 3;\n\nconst UPSELL_WIDGET_WHITELIST: Partial<Record<WidgetTypeId, WidgetTemplate[] | typeof ALL_TEMPLATES>> = {\n // New to ClickView\n [WidgetTypeId.ClassificationLatestReleasedVideosV2]: [WidgetTemplate.PopoutThumbnailSlidingListLarge],\n\n // New topics\n [WidgetTypeId.LatestReleasedClassifications]: [WidgetTemplate.ThumbnailFixedListSmall],\n\n // Upcoming livestreams\n [WidgetTypeId.UpcomingLivestreams]: [WidgetTemplate.EventIconSlidingList],\n\n // Upcoming events\n [WidgetTypeId.SpecialEventClassifications]: [WidgetTemplate.EventIconSlidingList],\n\n // ClickView original productions (Subject) / Recently streamed (Live)\n // This is not guarenteed. But we only take one of each type, so we might end up with another video list\n // if the curation team is doing their job, it should be relevant content - Sha\n [WidgetTypeId.CuratedMedia]: [\n WidgetTemplate.PopoutThumbnailSlidingListLarge,\n WidgetTemplate.PopoutThumbnailSlidingListSmall\n ],\n\n // Zoos and Wildlife Parks\n [WidgetTypeId.CuratedCompanies]: [WidgetTemplate.CircleLogoSlidingList],\n\n // Browse all subjects — not the editable \"Explore my subjects\" variant, which writes follow state\n [WidgetTypeId.Classifications]: [WidgetTemplate.CoverFixedPillListXSmall]\n};\n\nfunction isUpsellWidgetAllowed(widget: BaseWidget): boolean {\n const allowedTemplates = UPSELL_WIDGET_WHITELIST[widget.widgetId];\n\n if (!allowedTemplates)\n return false;\n\n return allowedTemplates === ALL_TEMPLATES || allowedTemplates.includes(widget.templateId);\n}\n\n/**\n * Narrows a dashboard to one widget per whitelisted type, lowest index first. Falls back to the full\n * dashboard when the user isn't being upsold, or when too few widgets match to make a decent page.\n */\nexport function filterUpsellWidgets(dashboard: CuratedDashboard, isUpselling: boolean): CuratedDashboard {\n if (!dashboard || !isUpselling)\n return dashboard;\n\n const usedTypes = new Set<WidgetTypeId>();\n\n const widgets = ArrayHelper.sortBy(dashboard.widgets ?? [], 'index')\n .filter(widget => {\n if (!isUpsellWidgetAllowed(widget) || usedTypes.has(widget.widgetId))\n return false;\n\n usedTypes.add(widget.widgetId);\n\n return true;\n });\n\n if (widgets.length < MIN_UPSELL_WIDGETS)\n return dashboard;\n\n return { ...dashboard, widgets };\n}\n","import React from 'react';\n\nimport { AppLink, LocationUtils } from 'libs/common/backbone/core';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { StorageType } from 'libs/common/backbone/utils/LocalStorageHelper';\nimport { Flight } from 'libs/common/flight';\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { EntityType, LocationContext, UserAction, VideoActionDescriptor, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { DiscoverDashboard } from 'libs/shared/apps/discover/components/discover-dashboard/DiscoverDashboard';\nimport { LibraryHelper } from 'libs/shared/apps/libraries/utils/LibraryHelper';\nimport { DashboardFeedbackData } from 'libs/shared/components/feedback-form/FeedbackForm';\nimport { CountdownExternalContext } from 'libs/shared/components/widgets/countdown/CountdownContainer';\nimport { HardCoded } from 'libs/shared/constants/HardCoded';\nimport { SharedViewModelKeys } from 'libs/shared/constants/SharedViewModelKeys';\nimport { FeedbackType } from 'libs/shared/enums/FeedbackType';\nimport { LocalPermissionName, PermissionName } from 'libs/shared/enums/PermissionName';\nimport { PresentationLearningLevel } from 'libs/shared/enums/PresentationLearningLevel';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { CustomerRequests } from 'libs/shared/flight-requests/CustomerRequests';\nimport { DashboardRequests } from 'libs/shared/flight-requests/DashboardRequests';\nimport { FeedbackRequests } from 'libs/shared/flight-requests/FeedbackRequests';\nimport { LibraryRequests } from 'libs/shared/flight-requests/LibraryRequests';\nimport { PreferenceRequests } from 'libs/shared/flight-requests/PreferenceRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { useProducts } from 'libs/shared/hooks/UseProducts';\nimport { useSetPageMetadata } from 'libs/shared/hooks/useSetPageMetadata';\nimport { useSettings } from 'libs/shared/hooks/useSettings';\nimport { Classification, CuratedWidgetQueryParams, CurrentUser, Customer, DashboardTargetType, Library, Presentation, PresentationAudience, WidgetPreference } from 'libs/shared/interfaces';\nimport { AudienceHelper } from 'libs/shared/utils/audience-helper/AudienceHelper';\nimport { FeedbackFormHelper } from 'libs/shared/utils/FeedbackFormHelper';\nimport { PageMetadataHelper } from 'libs/shared/utils/PageMetadataHelper';\n\nimport { SchoolLevelReminder } from 'shared/components/school-level-reminder/SchoolLevelReminder';\nimport { UpsellFooterBanner } from 'shared/components/upsell-footer-banner/UpsellFooterBanner';\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { useActivePresentation } from 'shared/hooks/presentations/useActivePresentation';\nimport { useAvailablePresentations } from 'shared/hooks/presentations/useAvailablePresentations';\nimport { useCommonVideoProps } from 'shared/hooks/useCommonVideoProps';\nimport { useRequestAccess } from 'shared/hooks/useRequestAccess';\nimport { useTeachingLevelBanner } from 'shared/hooks/useTeachingLevelBanner';\nimport { useUpsellContext } from 'shared/hooks/useUpsellContext';\nimport { DashboardViewQueryParams } from 'shared/interfaces/query-params/DashboardViewQueryParams';\nimport { ClassificationAppLinkHelper } from 'shared/utils/ClassificationAppLinkHelper';\nimport { useFetchCuratedDashboard } from 'shared/utils/DashboardHelper';\nimport { SeoHelper } from 'shared/utils/SeoHelper';\nimport { filterUpsellWidgets } from 'shared/utils/UpsellWidgetHelper';\n\nimport { useTutorialVideos } from 'apps/dashboard/hooks/useTutorialVideos';\nimport { getDiscoverHeaderAppLinks, getDiscoverWidgetAppLinks } from 'apps/dashboard/views/dashboard/DiscoverViewUtils';\nimport { useIsTertiary } from 'apps/onboarding/hooks/useIsTertiary';\nimport { VideoHistoryRequests } from 'apps/watch-history/flight-requests/VideoHistoryRequests';\n\nconst namespace = 'dashboard.dashboard';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction getPhraseVariant(presentation: Presentation): string {\n const learningLevel = PresentationLearningLevel[presentation?.learningLevel];\n\n return +learningLevel === PresentationLearningLevel.Level_1 ?\n 'VariantOne' :\n 'VariantTwo';\n}\n\ntype TopicMap = Record<string, { id: string, name: string }>;\n\nconst countdownContext: CountdownExternalContext = {\n imageUrls: ImageUrls,\n getAppLink: (presentationId: string, eventTopicKey: string): AppLink | null => {\n const topicMap = HardCoded[eventTopicKey as keyof typeof HardCoded] as TopicMap | undefined;\n\n if (!topicMap) {\n return null;\n }\n\n const topic = topicMap[presentationId];\n\n if (!topic) {\n return null;\n }\n\n return ClassificationAppLinkHelper.getAppLink(\n { id: topic.id, name: topic.name } as Classification,\n undefined,\n null\n );\n }\n};\n\ninterface CuratedDiscoverViewProps {\n presentationSlug: string | null;\n queryParams?: DashboardViewQueryParams;\n}\n\nexport function CuratedDiscoverView(props: CuratedDiscoverViewProps): JSX.Element {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const { hasLocalPermissions, hasPermissions } = usePermissions();\n const alerts = useAlerts();\n \n const customer = Flight.useBasicFetch<Customer>(\n hasLocalPermissions(LocalPermissionName.ManageDiscoverPreferences) &&\n currentUser.data?.isAuthenticated &&\n CustomerRequests.customer(currentUser.data.customerId)\n );\n \n const libraries = Flight.useBasicFetch<Library[]>(\n currentUser.data?.isAuthenticated &&\n LibraryRequests.libraries()\n );\n\n const { activePresentation } = useActivePresentation();\n const { availablePresentations } = useAvailablePresentations();\n \n const teachLevelBannerContext = useTeachingLevelBanner();\n\n function getTeachingLevelReminderType() {\n if (!teachLevelBannerContext.showBanner)\n return null;\n\n if (!teachLevelBannerContext.teachingLevelPresentation)\n return 'set-level';\n\n return 'switch-level';\n }\n\n const { upsellKind } = useUpsellContext();\n\n const isTertiary = useIsTertiary();\n const products = useProducts();\n\n const tutorialVideoContext = useTutorialVideos();\n\n const {\n dashboard,\n presentation,\n audiences\n } = useFetchCuratedDashboard({\n targetType: DashboardTargetType.Discover,\n queryParams: props.queryParams\n });\n\n const fetchAsync = Flight.useGetFetchAsync();\n const settings = useSettings(null);\n\n const [activeAudiences] = useViewModel<PresentationAudience[]>(\n SharedViewModelKeys.AUDIENCE_FILTER,\n undefined,\n { storage: StorageType.SessionStorage }\n );\n\n const { applinks: widgetAppLinks, requestAccessApplink, isUpselling, onClickRequestAccessButton } = useRequestAccess({\n applinks: getDiscoverWidgetAppLinks(\n AudienceHelper.getAudienceParams(activeAudiences),\n currentUser.data,\n props.presentationSlug,\n availablePresentations\n )\n });\n\n const { commonVideoProps } = useCommonVideoProps({\n locationContext: LocationContext.Dashboard,\n hoverToPlay: !isUpselling(activePresentation),\n subTextAppLink: isUpselling(activePresentation) ? requestAccessApplink : null\n });\n\n const phraseVariant = getPhraseVariant(presentation);\n\n useSetPageMetadata(PageMetadataHelper.getDiscoverMetadata({\n content: presentation,\n phraseContext: {\n phraseHandler: getPhrase,\n titlePhrase: `pageTitle${phraseVariant}`,\n descriptionPhrase: `pageDescription${phraseVariant}`\n },\n canonicalLink: SeoHelper.getCanonicalLink(),\n allowIndexing: SeoHelper.allowIndexing(),\n hrefLang: SeoHelper.getStaticRouteHrefLang(\n presentation?.learningLevel,\n widgetAppLinks.discover\n )\n }));\n\n async function onSubmitFeedback(feedback: DashboardFeedbackData): Promise<void> {\n const promise = await fetchAsync<void>(FeedbackRequests.submitFeedback({\n type: FeedbackType.Footer,\n user: FeedbackFormHelper.getUserInfo(currentUser.data, customer.data),\n tags: FeedbackFormHelper.getTags(\n currentUser.data,\n ProductId.Primary,\n hasPermissions(PermissionName.StudentExperience),\n [ 'discover', 'in product feedback' ]\n )\n }, {\n reaction: feedback.type,\n feedback: feedback.content,\n location: 'Discover Footer',\n presentationName: presentation.description,\n presentationId: presentation.id,\n dashboardName: dashboard.data.name,\n dashboardId: dashboard.data.id,\n currentPageUrl: LocationUtils.GetCurrentUrl()\n }));\n\n AnalyticsHelper.logUserAction({\n feedbackType: feedback.type,\n content: feedback.content,\n presentationId: presentation.id,\n dashboardId: dashboard.data.id\n }, {\n actionType: UserAction.Submit,\n location: LocationContext.DiscoverFooter,\n entity: EntityType.Feedback,\n workflowPhase: WorkflowPhase.Complete\n });\n\n return promise;\n }\n\n async function removeFromVideoHistory(\n videoId: string,\n videoName: string,\n widgetId: string,\n widgetTypeId: WidgetTypeId\n ): Promise<void> {\n if (widgetTypeId !== WidgetTypeId.ContinueWatching)\n return;\n\n try {\n await fetchAsync<void>(VideoHistoryRequests.removeFromHistory(videoId, [`widget:${widgetId}`]));\n\n alerts.success(LanguageService.getPhrase(namespace, 'removeFromHistorySuccess'));\n\n AnalyticsHelper.logUserAction({\n id: videoId,\n name: videoName,\n widgetId\n }, {\n entity: EntityType.Video,\n actionType: UserAction.Click,\n descriptor: VideoActionDescriptor.RemoveFromWatchHistory,\n location: LocationContext.SlidingListItem\n });\n } catch {\n alerts.error(LanguageService.getPhrase(namespace, 'removeFromHistoryError', { name: videoName }));\n }\n }\n\n async function updateWidgetPreferences(\n widgetId: string,\n widgetTypeId: WidgetTypeId,\n oldPreferences: WidgetPreference[],\n newPreferences: WidgetPreference[]\n ): Promise<void> {\n const addedSubjects = newPreferences.filter(p => {\n if (p.hidden)\n return false;\n\n const oldPreference = oldPreferences.find(o => o.id === p.id);\n\n return oldPreference.hidden;\n });\n const removedSubjects = newPreferences.filter(p => {\n if (!p.hidden)\n return false;\n \n const oldPreference = oldPreferences.find(o => o.id === p.id);\n\n return !oldPreference.hidden;\n });\n\n if (addedSubjects?.length)\n await fetchAsync<void>(PreferenceRequests.followSubjects(addedSubjects.map(s => s.id)));\n\n if (removedSubjects?.length)\n await fetchAsync<void>(PreferenceRequests.unfollowSubjects(removedSubjects.map(s => s.id)));\n\n return fetchAsync<void>(DashboardRequests.updateWidgetPreferences(\n widgetId,\n newPreferences.map(p => ({\n id: p.id,\n index: p.index\n })),\n currentUser.data\n ));\n }\n return (\n <div className='bg-white px-4'>\n <DiscoverDashboard\n dashboard={filterUpsellWidgets(dashboard.data, isUpselling(activePresentation))}\n widgetAppLinks={widgetAppLinks}\n headerAppLinks={getDiscoverHeaderAppLinks(presentation?.vanitySlug ?? null)}\n presentation={presentation}\n getWidgetContentRequest={(\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate,\n presentation: Presentation\n ) => {\n const { hasTwig, hasTigtag } = LibraryHelper.hasTwigOrTigtag(libraries.data, currentUser.data);\n\n return DashboardRequests.dashboardWidgetContent(\n id,\n params,\n widgetTemplate,\n presentation,\n { hideTigTag: !hasTigtag, hideTwig: !hasTwig }\n );\n }}\n audiences={audiences.data}\n updatePreferences={updateWidgetPreferences}\n hasPermissions={hasPermissions}\n hasLocalPermissions={hasLocalPermissions}\n onSubmitFeedback={\n hasPermissions(PermissionName.CanSubmitFeedback) &&\n onSubmitFeedback\n }\n removeFromVideoHistory={removeFromVideoHistory}\n lazyLoad={!SeoHelper.isBot()}\n showCalendar={false}\n settings={settings}\n availablePresentations={availablePresentations}\n isTertiaryCustomerWithoutExchange={isTertiary && !products?.hasProduct(ProductId.Exchange)}\n commonVideoProps={commonVideoProps}\n countdownContext={countdownContext}\n tutorialVideosContext={isUpselling(activePresentation) ? null : tutorialVideoContext}\n isUpselling={isUpselling(activePresentation)}\n\n reminderComponent={\n <SchoolLevelReminder\n type={getTeachingLevelReminderType()}\n className='mb-2'\n setLevel={teachLevelBannerContext.teachingLevelPresentation?.name}\n currLevel={activePresentation?.name}\n />\n }\n />\n {isUpselling(activePresentation) &&\n <UpsellFooterBanner upsellKind={upsellKind} onClickRequestAccessButton={onClickRequestAccessButton} />\n }\n </div>\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { PlusSvg } from 'libs/shared/images/svg/actions/PlusSvg';\nimport { CuratedDashboard, DashboardStatus } from 'libs/shared/interfaces';\n\nconst namespace = 'streamable.dashboardEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface StreamableDiscoverDashboardEmptyStateProps {\n dashboard: CuratedDashboard;\n imageUrl: string;\n isReadonly: boolean;\n addWidgetApplink?: () => Core.AppLink;\n}\n\nexport function StreamableDiscoverDashboardEmptyState(props: StreamableDiscoverDashboardEmptyStateProps): JSX.Element {\n const isArchived = props.dashboard?.status === DashboardStatus.Archived;\n\n return (\n <EmptyState>\n <EmptyState.Image src={props.imageUrl} altText={getPhrase('info')} />\n <EmptyState.Heading>\n <Text namespace={namespace} phrase='heading' />\n </EmptyState.Heading>\n <EmptyState.Info>\n <Text namespace={namespace} phrase='info' />\n </EmptyState.Info>\n <Tooltip title={isArchived ? LanguageService.getPhrase(namespace, 'archivedCtaTooltip') : ''} spanHack>\n <EmptyState.Cta\n text={LanguageService.getPhrase(namespace, 'add')}\n appLink={props.addWidgetApplink?.()}\n className='btn btn-dark'\n icon={PlusSvg}\n disabled={isArchived}\n />\n </Tooltip>\n </EmptyState>\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { Flight } from 'libs/common/flight';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { TutorialVideosContext, TutorialVideoWidget } from 'libs/shared/apps/discover/components/tutorial-videos/TutorialVideoWidget';\nimport { StreamableHeader, StreamableHeaderAppLinks } from 'libs/shared/apps/streamable-learning/components/header/StreamableHeader';\nimport { PartialPopoutThumbnailSlidingListSmallWidgetTemplate } from 'libs/shared/components/widgets/curated-widgets/templates/popout_thumbnail_sliding_list_small/partial-loading/PartialPopoutThumbnailSlidingListSmall';\nimport { WidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/WidgetContainerView';\nimport { AllDiscoverWidgetTemplates } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { CalendarEventContentType, CuratedDashboard, CuratedWidgetQueryParams, DashboardTargetType, Presentation, PresentationAudience } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\n\nimport { StreamableDiscoverDashboardEmptyState } from './empty-state/StreamableDiscoverDashboardEmptyState';\n\nexport interface StreamableDiscoverDashboardProps {\n dashboard: CuratedDashboard;\n getWidgetContentRequest: (\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate\n ) => Flight.Request;\n\n audiences?: PresentationAudience[];\n emptyImageUrl?: string;\n presentation: Presentation;\n widgetAppLinks?: AllDiscoverWidgetTemplates['appLinks'] & {\n widgetWizard: () => Core.AppLink\n };\n headerAppLinks?: StreamableHeaderAppLinks;\n scrollToWidgetId?: string;\n isReadonly?: boolean;\n lazyLoad?: boolean;\n commonVideoProps: CommonVideoProps;\n tutorialVideosContext?: TutorialVideosContext;\n isUpselling?: boolean;\n}\n\nexport function StreamableDiscoverDashboard(props: StreamableDiscoverDashboardProps): JSX.Element {\n const widgets = ArrayHelper.sortBy(props.dashboard?.widgets, 'index');\n\n const { hasPermissions, hasLocalPermissions } = usePermissions();\n\n function getWidgetContentRequest(id: string, widgetTypeId: WidgetTypeId, template: WidgetTemplate): Flight.Request {\n const params = CuratedDashboardHelper.getWidgetParams(\n widgetTypeId,\n template,\n CuratedDashboardHelper.getDashboardTargetType(props.dashboard)\n );\n\n return props.getWidgetContentRequest(id, params, template);\n }\n\n const showEmptyState = props.isReadonly && !widgets?.length;\n\n return (\n <>\n <StreamableHeader\n active='discover'\n appLinks={props.headerAppLinks}\n isUpselling={props.isUpselling}\n />\n\n {props.tutorialVideosContext?.shouldShowPanel && (\n <div className='curated-widget rounded-3 mb-3 mx-n4 px-4 py-3 overflow-hidden'>\n {\n props.tutorialVideosContext.readyToShowPanel ?\n <TutorialVideoWidget\n commonVideoProps={props.commonVideoProps}\n audiences={props.audiences}\n context={props.tutorialVideosContext}\n /> :\n <PartialPopoutThumbnailSlidingListSmallWidgetTemplate\n hideDescription\n />\n }\n </div>\n )}\n\n {widgets.map((widget, idx) => {\n return (\n <WidgetContainerView\n widgetCollection={DashboardTargetType.Discover}\n key={widget.id}\n id={widget.id}\n getContentRequest={getWidgetContentRequest}\n audiences={props.audiences}\n name={widget.name}\n description={widget.description}\n templateId={widget.templateId}\n metadata={widget.metadata}\n presentation={props.presentation}\n appLinks={props.widgetAppLinks}\n isScrollToTargetWidget={props?.scrollToWidgetId === widget.id}\n widgetTypeId={widget.widgetId}\n lazyLoad={props.lazyLoad}\n dashboardTarget={DashboardTargetType.Discover}\n widgetIndex={idx}\n isPreviewing={props.isReadonly}\n contentType={CalendarEventContentType.Livestream}\n preferences={widget.preferences}\n hasPermissions={hasPermissions}\n hasLocalPermissions={hasLocalPermissions}\n isTertiaryCustomerWithoutExchange={false}\n preventPopout\n imageCdnUrl={props.commonVideoProps.imageCdnUrl}\n commonVideoProps={props.commonVideoProps}\n isUpselling={props.isUpselling}\n\n availablePresentations={undefined}\n classification={undefined}\n hasTableOfContents={undefined}\n onSubmitFeedback={undefined}\n settings={undefined}\n updatePreferences={undefined}\n seeMoreLink={undefined}\n onClickRemoveItem={undefined}\n badgeComponent={undefined}\n\n />\n );\n })}\n\n {showEmptyState && (\n <StreamableDiscoverDashboardEmptyState\n dashboard={props.dashboard}\n isReadonly={props.isReadonly}\n imageUrl={props.emptyImageUrl}\n addWidgetApplink={props.widgetAppLinks.widgetWizard}\n />\n )}\n </>\n );\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { StorageType } from 'libs/common/backbone/utils/LocalStorageHelper';\nimport { Flight } from 'libs/common/flight';\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\n\nimport { LocationContext } from 'libs/analytics/interfaces';\n\nimport { StreamableDiscoverDashboard } from 'libs/shared/apps/streamable-learning/components/dashboard/StreamableDiscoverDashboard';\nimport { SharedViewModelKeys } from 'libs/shared/constants/SharedViewModelKeys';\nimport { PresentationType } from 'libs/shared/enums/PresentationType';\nimport { AudienceRequests } from 'libs/shared/flight-requests/AudienceRequests';\nimport { DashboardRequests } from 'libs/shared/flight-requests/DashboardRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useSetPageMetadata } from 'libs/shared/hooks/useSetPageMetadata';\nimport { CurrentUser, DashboardTargetType, PresentationAudience } from 'libs/shared/interfaces';\nimport { AudienceHelper } from 'libs/shared/utils/audience-helper/AudienceHelper';\nimport { PageMetadataHelper } from 'libs/shared/utils/PageMetadataHelper';\n\nimport { UpsellFooterBanner } from 'shared/components/upsell-footer-banner/UpsellFooterBanner';\nimport { useActivePresentation } from 'shared/hooks/presentations/useActivePresentation';\nimport { useAvailablePresentations } from 'shared/hooks/presentations/useAvailablePresentations';\nimport { useCommonVideoProps } from 'shared/hooks/useCommonVideoProps';\nimport { useRequestAccess } from 'shared/hooks/useRequestAccess';\nimport { useUpsellContext } from 'shared/hooks/useUpsellContext';\nimport { DashboardViewQueryParams } from 'shared/interfaces/query-params/DashboardViewQueryParams';\nimport { useFetchCuratedDashboard } from 'shared/utils/DashboardHelper';\nimport { SeoHelper } from 'shared/utils/SeoHelper';\nimport { filterUpsellWidgets } from 'shared/utils/UpsellWidgetHelper';\n\nimport { useTutorialVideos } from 'apps/dashboard/hooks/useTutorialVideos';\nimport { getLiveExperiencesDiscoverWidgetAppLinks, getLiveHeaderAppLinks } from 'apps/dashboard/views/dashboard/DiscoverViewUtils';\n\nconst namespace = 'liveDiscover.discover';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface LiveDiscoverViewProps {\n presentationSlug: string | null;\n queryParams?: DashboardViewQueryParams;\n}\n\nexport function LiveDiscoverView(props: LiveDiscoverViewProps): JSX.Element {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const { availablePresentations } = useAvailablePresentations();\n const { activePresentation } = useActivePresentation();\n\n const [activeAudiences] = useViewModel<PresentationAudience[]>(\n SharedViewModelKeys.AUDIENCE_FILTER,\n undefined,\n { storage: StorageType.SessionStorage }\n );\n \n const { upsellKind } = useUpsellContext();\n\n const { applinks: widgetAppLinks, requestAccessApplink, isUpselling, onClickRequestAccessButton } = useRequestAccess({\n applinks: getLiveExperiencesDiscoverWidgetAppLinks(\n AudienceHelper.getAudienceParams(activeAudiences),\n currentUser.data,\n props.presentationSlug,\n availablePresentations\n )\n });\n\n const { commonVideoProps } = useCommonVideoProps({\n locationContext: LocationContext.Dashboard,\n hoverToPlay: !isUpselling(activePresentation),\n subTextAppLink: isUpselling(activePresentation) ? requestAccessApplink : null\n });\n\n const tutorialVideoContext = useTutorialVideos('live');\n\n const {\n dashboard,\n presentation\n } = useFetchCuratedDashboard({\n targetType: DashboardTargetType.Discover,\n queryParams: props.queryParams\n });\n\n // ClickView Live audiences are typed differently from Subject audiences for the same presentation id;\n // Fetch with the explicit Live type so we get the correct grade set.\n const audiences = Flight.useBasicFetch<PresentationAudience[]>(\n presentation &&\n AudienceRequests.presentationAudiences(PresentationType.StreamableLearning, presentation.id)\n );\n\n useSetPageMetadata(PageMetadataHelper.getDiscoverMetadata({\n content: presentation,\n phraseContext: {\n phraseHandler: getPhrase,\n titlePhrase: 'pageTitle',\n descriptionPhrase: 'pageDescription'\n },\n canonicalLink: SeoHelper.getCanonicalLink(),\n allowIndexing: true\n }));\n\n const hasLoaded = (\n dashboard.hasCompleted &&\n !!presentation &&\n audiences.hasCompleted\n );\n\n if (!hasLoaded)\n return <></>;\n\n return (\n <div className='bg-white px-4'>\n <StreamableDiscoverDashboard\n dashboard={filterUpsellWidgets(dashboard.data, isUpselling(activePresentation))}\n widgetAppLinks={widgetAppLinks}\n headerAppLinks={getLiveHeaderAppLinks(props.presentationSlug)}\n presentation={presentation}\n getWidgetContentRequest={DashboardRequests.dashboardWidgetContent}\n audiences={audiences.data}\n lazyLoad={!SeoHelper.isBot()}\n commonVideoProps={commonVideoProps}\n tutorialVideosContext={isUpselling(activePresentation) ? null : tutorialVideoContext}\n isUpselling={isUpselling(activePresentation)}\n />\n {isUpselling(activePresentation) &&\n <UpsellFooterBanner\n upsellKind={upsellKind}\n onClickRequestAccessButton={onClickRequestAccessButton}\n />\n }\n </div>\n );\n}\n","import React from 'react';\n\nimport { PresentationType } from 'libs/shared/enums/PresentationType';\n\nimport { DashboardViewQueryParams } from 'shared/interfaces/query-params/DashboardViewQueryParams';\nimport { createPresentationDispatcherView } from 'shared/utils/createPresentationDispatcherView';\n\nimport { CuratedDiscoverView } from 'apps/dashboard/views/dashboard/curated-discover/CuratedDiscoverView';\nimport { LiveDiscoverView } from 'apps/dashboard/views/dashboard/live-discover/LiveDiscoverView';\n\ninterface DiscoverRouteProps {\n queryParams?: DashboardViewQueryParams;\n presentationSlug: string | null;\n}\n\nexport const BaseDiscoverView = createPresentationDispatcherView<DiscoverRouteProps>({\n [PresentationType.Subject]: ctx => (\n <CuratedDiscoverView presentationSlug={ctx.presentationSlug} queryParams={ctx.queryParams} />\n ),\n [PresentationType.StreamableLearning]: ctx => (\n <LiveDiscoverView presentationSlug={ctx.presentationSlug} queryParams={ctx.queryParams} />\n )\n});\n\nBaseDiscoverView.displayName = 'BaseDiscoverView';\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{o as e}from"./DAXXjFlN.chunk.js";import{n as t,t as n}from"./D8uRDrkd.chunk.js";import{y as r}from"./BftnFbcr.chunk.js";import{n as i}from"./B785hxeE.chunk.js";import{t as a}from"./CQyJ7YGa.chunk.js";import{t as o}from"./e57H3T-k.chunk.js";import{t as s}from"./C2w0pmFW.chunk.js";import{t as c}from"./wrLrTezN.chunk.js";import{i as l}from"./BYSskNbK.chunk.js";import{u}from"./BX0wDJmp.chunk.js";import{n as d}from"./BVnMI-dl.chunk.js";import{t as f}from"./C1SLt-ar.chunk.js";import{t as p}from"./CjA4Q5pm.chunk.js";import{i as m,l as h,y as g,z as _}from"./NlCAcBdo.chunk.js";import{t as ee}from"./DIqO2TFN.chunk.js";import{t as v}from"./DTGfiG8Y.chunk.js";import{t as y}from"./oPIkfKWW2.chunk.js";import{t as b}from"./ZwDDc8Zd.chunk.js";import{t as te}from"./C5rBgkQH.chunk.js";import{t as ne}from"./B0aLOQEJ2.chunk.js";import{n as x}from"./BRcHS92O2.chunk.js";import{t as S}from"./Tr5-kahg2.chunk.js";import{t as C}from"./Ci5E3nqm2.chunk.js";import{t as w}from"./DCBtWC6W.chunk.js";import{t as T}from"./9LNlP5yJ.chunk.js";import{t as E}from"./Vp01-r6R.chunk.js";import{n as D,t as O}from"./A8xLZrSw.chunk.js";import{t as k}from"./BQKcAczf.chunk.js";import{r as A,t as j}from"./DR9DEoQL.chunk.js";import{n as M,t as N}from"./CpFtf-tI2.chunk.js";import{t as P}from"./5ONJSThP.chunk.js";import{t as re}from"./CQnnMJiM.chunk.js";import{t as ie}from"./DOnmTMfX.chunk.js";import{t as ae}from"./C-THHyTP.chunk.js";import{t as oe}from"./BA-ImKky.chunk.js";import{t as se}from"./DMaQV7L2.chunk.js";import{t as ce}from"./CfwSprmF.chunk.js";import{a as F,n as le,o as ue,r as I,s as L,t as de}from"./s8Ijob0J2.chunk.js";import{t as fe}from"./Dg1mFtY2.chunk.js";import{t as pe}from"./D7UO1XFN2.chunk.js";import{n as me}from"./CNm_4jj62.chunk.js";import{n as he,t as R}from"./sCuSDiER2.chunk.js";import{t as z}from"./nNE51iyg2.chunk.js";import{t as B}from"./DFrz_upP2.chunk.js";import{a as ge,i as V,n as _e,o as H,r as ve,s as ye,t as U}from"./BcPrUEuC2.chunk.js";import{t as be}from"./DELN_PAD2.chunk.js";import{t as W}from"./AEt1phMH2.chunk.js";import{t as G}from"./JPQU1BEu2.chunk.js";import{t as xe}from"./CQIkxqO12.chunk.js";import{t as Se}from"./DhGA1di32.chunk.js";var K=e(s());function Ce(e){return e?d.pick(e,[`year`,`classification`,`yearGroup`]):{}}var we={wrapper:`_wrapper_gw22e_1`,weekend:`_weekend_gw22e_4`},q=c();function Te(e){return p.getWeekday(e)===0||p.getWeekday(e)===6}function Ee(e){let{date:t,notCurrentMonth:n}=e,[r,i]=K.useState(0),a=`position-relative border ${e.theme.border} ${we.wrapper}`;Te(t)&&(a+=` ${we.weekend}`),n&&(a+=`opacity-50`);let o=z.getEventsForDay(t,e.events||[],e.crossMonthEvents||[],e.viewingMonth),s={...e,eventsOnDay:o,sliderStep:r,setSliderStep:i};return(0,q.jsx)(`td`,{className:a,children:o?.length>0?(0,q.jsx)(re,{hoverableComponent:R,componentProps:s,hoverScale:1.35}):(0,q.jsx)(R,{...s,isHovering:!1})})}var J=`specialEvent.eventsEmptyState`,De=a.encloseNamespace(J);function Oe(e){return(0,q.jsx)(N.Provider,{value:J,children:(0,q.jsxs)(E,{children:[(0,q.jsx)(E.Image,{src:e.imageUrl,altText:De(`info`)}),(0,q.jsx)(E.Heading,{children:e.heading||(0,q.jsx)(M,{phrase:`heading`})}),e.appLink&&(0,q.jsx)(E.Info,{children:(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(M,{namespace:J,phrase:`info`}),(0,q.jsx)(C,{appLink:e.appLink,children:(0,q.jsx)(`span`,{className:`text-info`,children:De(`link`)})})]})})]})})}var ke={date:`_date_ez4o2_1`,first:`_first_ez4o2_4`};function Ae(e){let t={};e.events.forEach(e=>{let n=e.startDate;t[n]?t[n].push(e):t[n]=[e]});let n=Object.keys(t);return n.sort((e,t)=>p.isBefore(e,t)?-1:0),(0,q.jsx)(`div`,{className:`py-1`,children:n.map((n,r)=>{let i=``,a=``;return(0,q.jsxs)(`div`,{children:[(0,q.jsx)(`div`,{className:`h4 mt-4 ${ke.date} ${r===0?ke.first:``}`,children:z.getOrdinalDate(n)}),t[n].map(t=>(i=a,a=e.getStartTime?.(t.content),(0,q.jsx)(ye,{getAppLink:(t,n)=>e.appLink(t,o.slugify(n)),event:t,presentationId:e.presentationId,getIconUrl:e.getIconUrl,getBannerUrl:e.getBannerUrl,getBackgroundColor:e.getBackgroundColor,getActionLabel:()=>e.getActionLabel(t.content),getStartTime:e.getStartTime&&i!==a?e.getStartTime:null,isPastEvent:e.isPastEvent},t.content.id)))]},n)})})}var je={header:`_header_dbicu_1`,thead:`_thead_dbicu_4`};Y.defaultProps={theme:{border:`border-light-blue`,background:`bg-light-blue`}};function Y(e){let{appLinks:t,imageUrls:n}=e,r=P(),i=z.getEventsInMonth(e.events||[],e.viewingMonth),a=K.useMemo(()=>{let t=new Set(e.weekDays.reduce((e,t)=>e.concat(t),[]).map(e=>p.format(e,`YYYY-MM-DD`)));return(e.events||[]).filter(n=>{if(!n.startDate)return!1;let r=z.isEventFromPreviousMonth(n,e.viewingMonth),i=t.has(p.format(n.startDate,`YYYY-MM-DD`));return r&&!i})},[e.weekDays,e.events]),o=e.viewMode!==`list`&&!r.xs&&!r.sm&&!r.md,[s,c]=K.useState(!1),[l,u]=K.useState(null);return K.useEffect(()=>{if(e.eventsLoaded&&!s){let t=e.weekDays.length-1,n=window.setTimeout(()=>c(!0),he(t));return()=>window.clearTimeout(n)}},[e.eventsLoaded]),e.eventsLoaded&&!i?.length?(0,q.jsx)(Oe,{imageUrl:n.emptyState,appLink:t.emptyStateRedirect?.(),heading:e.emptyStateHeading}):o?(0,q.jsxs)(`table`,{className:`user-select-none w-100 mt-3 overflow-hidden rounded-top-lg`,children:[(0,q.jsx)(`thead`,{className:`border ${e.theme.border} ${je.thead}`,children:(0,q.jsx)(`tr`,{className:`fw-semibold ${e.theme.background} ${je.header}`,children:e.weekDaysHeader.map(e=>(0,q.jsx)(`th`,{className:`px-2 h4`,scope:`col`,children:e},e))})}),(0,q.jsx)(`tbody`,{children:e.weekDays.map((t,n)=>(0,q.jsx)(`tr`,{children:t.map(t=>(0,q.jsx)(Ee,{rowIndex:n,date:t,notCurrentMonth:!!t.notCurrentMonth,events:e.events,crossMonthEvents:a,viewingMonth:e.viewingMonth,monthQuery:e.monthQuery,hasInitialized:s,presentationId:e.presentationId,hoveredEvent:l,theme:e.theme,setHoveredEvent:u,getEventsListAppLink:()=>e.appLinks.eventList(e.monthQuery,t,e.presentationId),getTopicAppLink:(t,n)=>e.appLinks.event(t,n),getIconUrl:e.getIconUrl,getBackgroundColor:e.getBackgroundColor,getCoverUrl:e.getCoverUrl,getHardCodedEvent:e.getHardCodedEvent,fadePastEvents:e.fadePastEvents,timezone:e.timezone},t.toString()))},t[0].toString()))})]}):e.eventsLoaded?(0,q.jsx)(Ae,{events:i,presentationId:e.presentationId,appLink:e.appLinks.event,getIconUrl:e.getIconUrl,getBannerUrl:e.getBannerUrl,getBackgroundColor:e.getBackgroundColor,getActionLabel:e.getActionLabel,getStartTime:e.getStartTime,isPastEvent:e.isPastEvent}):(0,q.jsx)(`div`,{className:`d-flex justify-content-center align-items-center mb-4`,children:(0,q.jsx)(w,{as:`div`,animation:`border`,role:`status`})})}var X={chevron:`_chevron_d411m_1`,left:`_left_d411m_4`,right:`_right_d411m_10`,viewModeContainer:`_viewModeContainer_d411m_16`},Me=`specialEventCalendar.calendarNav`;function Ne(e){return(0,q.jsxs)(`div`,{className:`${X.viewModeContainer} d-none d-lg-block`,children:[(0,q.jsx)(T,{svg:ce,className:`${e.viewMode===`calendar`?`bg-dark text-white`:``} btn btn-outline-dark rounded-start rounded-end-0 border-end-0 px-3 h-100`,onClick:()=>e.setViewMode(`calendar`),analyticsData:{},analyticsOptions:{entity:h.AppLink,actionType:_.Click,descriptor:m.Calendar,location:g.CalendarNav}}),(0,q.jsx)(T,{svg:be,className:`${e.viewMode===`list`?`bg-dark text-white`:``} btn btn-outline-dark rounded-end rounded-start-0 border-start-0 px-3 h-100`,onClick:()=>e.setViewMode(`list`),analyticsData:{},analyticsOptions:{entity:h.AppLink,actionType:_.Click,descriptor:m.List,location:g.CalendarNav}})]})}function Pe(e){let i=e.action===`previous`?ae:fe,a=e.action===`previous`?X.left:X.right;function o(){r.trigger(e.appLink),e.onClick()}return(0,q.jsx)(C,{appLink:e.appLink,analyticsData:e.analyticsData,analyticsOptions:e.analyticsOptions,className:`${X.chevron} ${a} border border-dark rounded-circle bg-white d-flex align-items-center justify-content-center`,onClick:o,children:(0,q.jsx)(n,{svg:i,size:t.Medium,className:`svg-container d-inline-block ${X.svg}`})})}var Fe=new Date;function Ie(e){let{appLinks:t}=e,n=P();function r(n){let r=p.format(n,`MMMM`).toLocaleLowerCase(),i=t.month(r),a={};if(n){let e=new Date().getFullYear(),t=n.getFullYear();e!==t&&(a.year=t)}return e.queryParams?.classification&&(a.classification=e.queryParams.classification),e.queryParams?.yearGroup&&(a.yearGroup=e.queryParams.yearGroup),i.params=a,i}function i(){let t=p.add(e.monthDate,1,`month`);e.setViewingMonthDate(t)}function o(){let t=p.subtract(e.monthDate,1,`month`);e.setViewingMonthDate(t)}function s(){p.format(Fe,`M YY`)!==p.format(e.monthDate,`M YY`)&&e.setViewingMonthDate()}let{showPrev:c,showNext:l}=le(e.monthDate),u={actionType:_.Click,entity:h.SpecialEvent,location:g.CalendarNav};function d(e){return p.format(e,`YYYY-MM-DD`)}return(0,q.jsxs)(`div`,{className:`d-flex flex-wrap gap-3 justify-content-end align-items-center`,children:[(0,q.jsx)(`h1`,{className:`mb-0 h2 me-auto`,children:p.format(e.monthDate,n.xs?`MMM YYYY`:`MMMM YYYY`)}),e.children,e.setViewMode&&(0,q.jsx)(Ne,{viewMode:e.viewMode,setViewMode:e.setViewMode}),(0,q.jsxs)(`div`,{className:`d-flex gap-3`,children:[c&&(0,q.jsx)(Pe,{appLink:r(p.startOf(p.subtract(e.monthDate,1,`month`),`month`)),action:`previous`,onClick:o,analyticsOptions:u,analyticsData:{action:`previous`,date:d(p.startOf(p.add(e.monthDate,1,`month`),`month`))}}),(0,q.jsx)(C,{appLink:r(),className:`${X.todayWrapper} btn btn-outline-dark fw-semibold`,onClick:s,analyticsOptions:u,analyticsData:{action:`today`,date:d(p.startOf(Fe,`month`))},children:a.getPhrase(Me,`today`)}),l&&(0,q.jsx)(Pe,{appLink:r(p.startOf(p.add(e.monthDate,1,`month`),`month`)),analyticsOptions:u,analyticsData:{action:`next`,date:d(p.startOf(p.add(e.monthDate,1,`month`),`month`))},action:`next`,onClick:i})]})]})}var Z=`specialEvent.eventsErrorState`,Le=a.encloseNamespace(Z);function Re(e){return(0,q.jsx)(N.Provider,{value:Z,children:(0,q.jsxs)(E,{children:[(0,q.jsx)(E.Image,{src:e.imageUrl}),(0,q.jsx)(E.Heading,{children:(0,q.jsx)(M,{phrase:`heading`})}),(0,q.jsxs)(E.Info,{children:[(0,q.jsx)(M,{namespace:Z,phrase:`info`}),(0,q.jsx)(`br`,{}),(0,q.jsx)(C,{appLink:e.appLink,children:(0,q.jsx)(`span`,{className:`text-info`,children:Le(`link`)})})]})]})})}function ze(e,t){let n=t,[r,i]=I(e),[a,o]=I(p.add(e,1,`month`)),[s,c]=I(p.subtract(e,1,`month`)),l=u(r&&i&&n&&W.calendarEvents(p.format(r,`YYYY-MM-DD`),p.format(i,`YYYY-MM-DD`),n)),d=u(a&&o&&n&&W.calendarEvents(p.format(a,`YYYY-MM-DD`),p.format(o,`YYYY-MM-DD`),n)),m=u(s&&c&&n&&W.calendarEvents(p.format(s,`YYYY-MM-DD`),p.format(c,`YYYY-MM-DD`),n));return{events:f.uniq([...m.data||[],...l.data||[],...d.data||[]],e=>e.specialEventPolicyId),loaded:l.hasCompleted}}var Be=new Date;function Ve(e=Be,t,n=!0){let i=ue(n),a=K.useRef({}),o=p.format(e,`YYYY-MM`),s=K.useMemo(()=>{let t=a.current[o];if(!t){let{weeksTable:t,datePositionMap:r}=de(e,n);return a.current[o]={weeksTable:t,datePositionMap:r},t}return t.weeksTable},[o,n]);function c(n){if(!n){r.trigger(t.calendar());return}if(o!==p.format(n,`YYYY-MM`)){let i=p.format(n,`MMMM`).toLocaleLowerCase(),a=new Date().getFullYear(),o=e.getFullYear(),s=t.month(i);a!==o&&(s.params={year:o}),r.trigger(s)}}return{weekDaysHeader:i,weekDays:s,monthDate:e,setMonthDate:c,startDate:f.first(f.first(s)),endDate:f.last(f.last(s))}}var Q=a.encloseNamespace(`specialEventCalendar.calendarView`);function He(e){let t=P(),{showCalendar:n,isLoading:i}=oe(),a=u(y.currentUser()),{availablePresentations:o}=ie(),{activePresentation:s}=b(),{applinks:c}=G({applinks:ve(e.presentationSlug??null,o),exceptions:[`month`]}),l=F(e.month);K.useEffect(()=>{!i&&!n&&r.trigger(xe(s?.vanitySlug??e.presentationSlug).forYou,{replace:!0})},[n,i]);let d=L(e.month),{monthDate:f,setMonthDate:m,weekDays:h,weekDaysHeader:g,startDate:_,endDate:v}=Ve(d,c),{events:te,loaded:ne}=ze(d,s.id),C=p.format(f,`MMMM YYYY`);if(O(D.getDefaultMetadata({title:C,phraseContext:{phraseHandler:Q,titlePhrase:`pageTitle`,descriptionPhrase:`pageDescription`},canonicalLink:j.getCanonicalLink({allowedParams:[`year`]}),allowIndexing:j.allowIndexing(),hrefLang:j.getStaticRouteHrefLang(s?.learningLevel,c.calendar,A)})),e.month!==null&&!l)return(0,q.jsx)(Re,{imageUrl:V().errorState,appLink:c.calendar()});function w(e,t){return t?S.createUrl(t.iconUrl,{size:x.Medium}):S.createUrl(e.icon?.url,{size:x.Small})}function T(e){return S.createUrl(e.cover?.url,{size:x.Small})}function E(){return t.xs?Q(`mobileButtonLabel`):Q(`buttonLabel`)}function k(e){return ee.SpecialEvents[e.id]}return i||!n||!s?.id||!a.data.countryCode?(0,q.jsx)(q.Fragment,{}):(0,q.jsxs)(`div`,{className:`bg-white px-3`,children:[(0,q.jsx)(Ie,{monthDate:f,setViewingMonthDate:m,appLinks:c}),(0,q.jsx)(Y,{weekDays:h,weekDaysHeader:g,events:te,monthQuery:{from:_?.toString(),to:v?.toString()},viewingMonth:d,eventsLoaded:ne,presentationId:s.id,appLinks:c,imageUrls:V(a.data.countryCode),getIconUrl:e=>w(e,k(e)),getCoverUrl:T,getBackgroundColor:e=>e.metadata?.backgroundColor,getBannerUrl:e=>e.banner?.url,getActionLabel:E,getHardCodedEvent:k})]})}function Ue(e,t){let[n,r]=I(e),[i,a]=I(p.add(e,1,`month`)),[o,s]=I(p.subtract(e,1,`month`)),c={};t.yearGroup&&(c.audienceId=t.yearGroup),t.classification&&(c.topicId=t.classification,c.includeChildrenTopics=!0);let l=u(n&&r&&B.calendarLivestreams({from:p.format(n,`YYYY-MM-DD`),to:p.format(r,`YYYY-MM-DD`),...c})),d=u(i&&a&&B.calendarLivestreams({from:p.format(i,`YYYY-MM-DD`),to:p.format(a,`YYYY-MM-DD`),...c})),m=u(o&&s&&B.calendarLivestreams({from:p.format(o,`YYYY-MM-DD`),to:p.format(s,`YYYY-MM-DD`),...c}));return{events:f.uniq([...m.data||[],...l.data||[],...d.data||[]],e=>e.id),loaded:l.hasCompleted}}var $=a.encloseNamespace(`liveCalendar.calendarView`);We.defaultProps={queryParams:{}};function We(e){let[{viewMode:t},n]=te(`calendar:mode`,{viewMode:`calendar`},{storage:l.LocalStorage}),{hasPermissions:r}=k(),a=r(i.StudentExperience),{activePresentation:o}=b(),{applinks:s}=G({applinks:ge(e.presentationSlug),exceptions:[`month`]}),c=u(o&&se.presentationAudiences(v.StreamableLearning,o.id)),f=u(o&&ne.topicsFromAllAvailablePresentations([o.id])),m=F(e.month),h=L(e.month),{monthDate:g,setMonthDate:_,weekDays:ee,weekDaysHeader:y,startDate:C,endDate:w}=Ve(h,s),{events:T,loaded:E}=Ue(h,e.queryParams),A=p.format(g,`MMMM YYYY`);if(O(D.getDefaultMetadata({title:A,phraseContext:{phraseHandler:$,titlePhrase:`pageTitle`,descriptionPhrase:`pageDescription`},canonicalLink:j.getCanonicalLink({allowedParams:[`year`]}),allowIndexing:!0})),e.month!==null&&!m)return(0,q.jsx)(Re,{imageUrl:H().errorState,appLink:s.calendar()});let M=[{id:`classification`,name:$(`subjectFilter`),options:f.data?.topics.map(e=>({name:e.name,id:e.topicIds.join(`:`)})),type:`checkbox`,compatibleIndices:[]},{id:`yearGroup`,name:$(`gradeFilter`),type:`checkbox`,options:c.data?.map(e=>({name:e.name,id:e.masterId})),compatibleIndices:[]}];function N(){let t=p.format(g,`MMMM`).toLocaleLowerCase(),n=new Date().getFullYear(),r=g.getFullYear(),i=s.month(t),a={};return n!==r&&(a.year=r),e.queryParams.classification&&(a.classification=e.queryParams.classification),e.queryParams.yearGroup&&(a.yearGroup=e.queryParams.yearGroup),i}function P(e){return a||p.isBefore(e.endDateTime,new Date)?`pastActionLabel`:`actionLabel`}function re(){if(!z.getEventsInMonth(T||[],h).length&&(e.queryParams.yearGroup||e.queryParams.classification))return $(`emptyStateText`)}function ie(e){return S.createUrl(e.company.logo?.url,{size:x.Small})}function ae(e){return S.createUrl(e.company.banner?.url,{size:x.Large})}return o?(0,q.jsxs)(`div`,{className:`bg-white px-4`,children:[(0,q.jsx)(Ie,{monthDate:g,setViewingMonthDate:_,appLinks:s,queryParams:e.queryParams,viewMode:t,setViewMode:e=>n({viewMode:e}),children:(0,q.jsx)(`div`,{className:`mx-n1 order-1 order-sm-0`,children:(0,q.jsx)(Se,{queryParams:d.omit(e.queryParams,[`year`]),mainFilters:M,appLink:N(),isFetchingOptions:!f.data||!o||!c.data,alignResetButtonLeft:!0,hideDivider:!0,hideHeading:!0,hideCaret:!1,noContainerPaddingBottom:!0})})}),(0,q.jsxs)(`div`,{className:`position-relative mt-3 ${t===`list`?``:`mt-lg-0`}`,children:[(0,q.jsx)(`div`,{className:`d-block ${t===`list`?``:`d-lg-none`} position-absolute top-0 end-0 mt-2`,children:(0,q.jsx)(_e,{})}),(0,q.jsx)(Y,{weekDays:ee,weekDaysHeader:y,events:T,monthQuery:{from:C?.toString(),to:w?.toString()},viewingMonth:h,eventsLoaded:E,presentationId:o.id,appLinks:s,imageUrls:H(),viewMode:t,getActionLabel:e=>$(P(e)),getBackgroundColor:e=>e.company.metadata?.colour,getBannerUrl:ae,getIconUrl:ie,getStartTime:U.getStartTime,theme:{background:`bg-light-green`,border:`border-light-green`},emptyStateHeading:re(),fadePastEvents:!0,timezone:me.ET,isPastEvent:U.isPastEvent})]})]}):(0,q.jsx)(q.Fragment,{})}var Ge=pe({[v.Subject]:e=>(0,q.jsx)(He,{month:e.month,presentationSlug:e.presentationSlug}),[v.StreamableLearning]:e=>(0,q.jsx)(We,{month:e.month,presentationSlug:e.presentationSlug,queryParams:Ce(e.queryParams)})});Ge.displayName=`BaseCalendarView`;export{Ge as BaseCalendarView};
2
- //# sourceMappingURL=CHwPLUZK.chunk.js.map
1
+ import{o as e}from"./DAXXjFlN.chunk.js";import{n as t,t as n}from"./D8uRDrkd.chunk.js";import{y as r}from"./BftnFbcr.chunk.js";import{n as i}from"./B785hxeE.chunk.js";import{t as a}from"./CQyJ7YGa.chunk.js";import{t as o}from"./e57H3T-k.chunk.js";import{t as s}from"./C2w0pmFW.chunk.js";import{t as c}from"./wrLrTezN.chunk.js";import{i as l}from"./BYSskNbK.chunk.js";import{u}from"./BX0wDJmp.chunk.js";import{n as d}from"./BVnMI-dl.chunk.js";import{t as f}from"./C1SLt-ar.chunk.js";import{t as p}from"./CjA4Q5pm.chunk.js";import{i as m,l as h,y as g,z as _}from"./NlCAcBdo.chunk.js";import{t as ee}from"./DIqO2TFN.chunk.js";import{t as v}from"./DTGfiG8Y.chunk.js";import{t as y}from"./oPIkfKWW2.chunk.js";import{t as b}from"./ZwDDc8Zd.chunk.js";import{t as te}from"./C5rBgkQH.chunk.js";import{t as ne}from"./B0aLOQEJ2.chunk.js";import{n as x}from"./BRcHS92O2.chunk.js";import{t as S}from"./Tr5-kahg2.chunk.js";import{t as C}from"./Ci5E3nqm2.chunk.js";import{t as w}from"./DCBtWC6W.chunk.js";import{t as T}from"./9LNlP5yJ.chunk.js";import{t as E}from"./Vp01-r6R.chunk.js";import{n as D,t as O}from"./A8xLZrSw.chunk.js";import{t as k}from"./BQKcAczf.chunk.js";import{r as A,t as j}from"./DR9DEoQL.chunk.js";import{n as M,t as N}from"./CpFtf-tI2.chunk.js";import{t as P}from"./5ONJSThP.chunk.js";import{t as re}from"./CQnnMJiM.chunk.js";import{t as ie}from"./DOnmTMfX.chunk.js";import{t as ae}from"./C-THHyTP.chunk.js";import{t as oe}from"./BA-ImKky.chunk.js";import{t as se}from"./DMaQV7L2.chunk.js";import{t as ce}from"./CfwSprmF.chunk.js";import{a as F,n as le,o as ue,r as I,s as L,t as de}from"./s8Ijob0J2.chunk.js";import{t as fe}from"./Dg1mFtY2.chunk.js";import{t as pe}from"./D7UO1XFN2.chunk.js";import{n as me}from"./BZFomoIH2.chunk.js";import{n as he,t as R}from"./BPbjSFkC2.chunk.js";import{t as z}from"./nNE51iyg2.chunk.js";import{t as B}from"./CtBGtgb32.chunk.js";import{a as ge,i as V,n as _e,o as H,r as ve,s as ye,t as U}from"./CNPnPJMp2.chunk.js";import{t as be}from"./DELN_PAD2.chunk.js";import{t as W}from"./AEt1phMH2.chunk.js";import{t as G}from"./JPQU1BEu2.chunk.js";import{t as xe}from"./CQIkxqO12.chunk.js";import{t as Se}from"./DhGA1di32.chunk.js";var K=e(s());function Ce(e){return e?d.pick(e,[`year`,`classification`,`yearGroup`]):{}}var we={wrapper:`_wrapper_gw22e_1`,weekend:`_weekend_gw22e_4`},q=c();function Te(e){return p.getWeekday(e)===0||p.getWeekday(e)===6}function Ee(e){let{date:t,notCurrentMonth:n}=e,[r,i]=K.useState(0),a=`position-relative border ${e.theme.border} ${we.wrapper}`;Te(t)&&(a+=` ${we.weekend}`),n&&(a+=`opacity-50`);let o=z.getEventsForDay(t,e.events||[],e.crossMonthEvents||[],e.viewingMonth),s={...e,eventsOnDay:o,sliderStep:r,setSliderStep:i};return(0,q.jsx)(`td`,{className:a,children:o?.length>0?(0,q.jsx)(re,{hoverableComponent:R,componentProps:s,hoverScale:1.35}):(0,q.jsx)(R,{...s,isHovering:!1})})}var J=`specialEvent.eventsEmptyState`,De=a.encloseNamespace(J);function Oe(e){return(0,q.jsx)(N.Provider,{value:J,children:(0,q.jsxs)(E,{children:[(0,q.jsx)(E.Image,{src:e.imageUrl,altText:De(`info`)}),(0,q.jsx)(E.Heading,{children:e.heading||(0,q.jsx)(M,{phrase:`heading`})}),e.appLink&&(0,q.jsx)(E.Info,{children:(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(M,{namespace:J,phrase:`info`}),(0,q.jsx)(C,{appLink:e.appLink,children:(0,q.jsx)(`span`,{className:`text-info`,children:De(`link`)})})]})})]})})}var ke={date:`_date_ez4o2_1`,first:`_first_ez4o2_4`};function Ae(e){let t={};e.events.forEach(e=>{let n=e.startDate;t[n]?t[n].push(e):t[n]=[e]});let n=Object.keys(t);return n.sort((e,t)=>p.isBefore(e,t)?-1:0),(0,q.jsx)(`div`,{className:`py-1`,children:n.map((n,r)=>{let i=``,a=``;return(0,q.jsxs)(`div`,{children:[(0,q.jsx)(`div`,{className:`h4 mt-4 ${ke.date} ${r===0?ke.first:``}`,children:z.getOrdinalDate(n)}),t[n].map(t=>(i=a,a=e.getStartTime?.(t.content),(0,q.jsx)(ye,{getAppLink:(t,n)=>e.appLink(t,o.slugify(n)),event:t,presentationId:e.presentationId,getIconUrl:e.getIconUrl,getBannerUrl:e.getBannerUrl,getBackgroundColor:e.getBackgroundColor,getActionLabel:()=>e.getActionLabel(t.content),getStartTime:e.getStartTime&&i!==a?e.getStartTime:null,isPastEvent:e.isPastEvent},t.content.id)))]},n)})})}var je={header:`_header_dbicu_1`,thead:`_thead_dbicu_4`};Y.defaultProps={theme:{border:`border-light-blue`,background:`bg-light-blue`}};function Y(e){let{appLinks:t,imageUrls:n}=e,r=P(),i=z.getEventsInMonth(e.events||[],e.viewingMonth),a=K.useMemo(()=>{let t=new Set(e.weekDays.reduce((e,t)=>e.concat(t),[]).map(e=>p.format(e,`YYYY-MM-DD`)));return(e.events||[]).filter(n=>{if(!n.startDate)return!1;let r=z.isEventFromPreviousMonth(n,e.viewingMonth),i=t.has(p.format(n.startDate,`YYYY-MM-DD`));return r&&!i})},[e.weekDays,e.events]),o=e.viewMode!==`list`&&!r.xs&&!r.sm&&!r.md,[s,c]=K.useState(!1),[l,u]=K.useState(null);return K.useEffect(()=>{if(e.eventsLoaded&&!s){let t=e.weekDays.length-1,n=window.setTimeout(()=>c(!0),he(t));return()=>window.clearTimeout(n)}},[e.eventsLoaded]),e.eventsLoaded&&!i?.length?(0,q.jsx)(Oe,{imageUrl:n.emptyState,appLink:t.emptyStateRedirect?.(),heading:e.emptyStateHeading}):o?(0,q.jsxs)(`table`,{className:`user-select-none w-100 mt-3 overflow-hidden rounded-top-lg`,children:[(0,q.jsx)(`thead`,{className:`border ${e.theme.border} ${je.thead}`,children:(0,q.jsx)(`tr`,{className:`fw-semibold ${e.theme.background} ${je.header}`,children:e.weekDaysHeader.map(e=>(0,q.jsx)(`th`,{className:`px-2 h4`,scope:`col`,children:e},e))})}),(0,q.jsx)(`tbody`,{children:e.weekDays.map((t,n)=>(0,q.jsx)(`tr`,{children:t.map(t=>(0,q.jsx)(Ee,{rowIndex:n,date:t,notCurrentMonth:!!t.notCurrentMonth,events:e.events,crossMonthEvents:a,viewingMonth:e.viewingMonth,monthQuery:e.monthQuery,hasInitialized:s,presentationId:e.presentationId,hoveredEvent:l,theme:e.theme,setHoveredEvent:u,getEventsListAppLink:()=>e.appLinks.eventList(e.monthQuery,t,e.presentationId),getTopicAppLink:(t,n)=>e.appLinks.event(t,n),getIconUrl:e.getIconUrl,getBackgroundColor:e.getBackgroundColor,getCoverUrl:e.getCoverUrl,getHardCodedEvent:e.getHardCodedEvent,fadePastEvents:e.fadePastEvents,timezone:e.timezone},t.toString()))},t[0].toString()))})]}):e.eventsLoaded?(0,q.jsx)(Ae,{events:i,presentationId:e.presentationId,appLink:e.appLinks.event,getIconUrl:e.getIconUrl,getBannerUrl:e.getBannerUrl,getBackgroundColor:e.getBackgroundColor,getActionLabel:e.getActionLabel,getStartTime:e.getStartTime,isPastEvent:e.isPastEvent}):(0,q.jsx)(`div`,{className:`d-flex justify-content-center align-items-center mb-4`,children:(0,q.jsx)(w,{as:`div`,animation:`border`,role:`status`})})}var X={chevron:`_chevron_d411m_1`,left:`_left_d411m_4`,right:`_right_d411m_10`,viewModeContainer:`_viewModeContainer_d411m_16`},Me=`specialEventCalendar.calendarNav`;function Ne(e){return(0,q.jsxs)(`div`,{className:`${X.viewModeContainer} d-none d-lg-block`,children:[(0,q.jsx)(T,{svg:ce,className:`${e.viewMode===`calendar`?`bg-dark text-white`:``} btn btn-outline-dark rounded-start rounded-end-0 border-end-0 px-3 h-100`,onClick:()=>e.setViewMode(`calendar`),analyticsData:{},analyticsOptions:{entity:h.AppLink,actionType:_.Click,descriptor:m.Calendar,location:g.CalendarNav}}),(0,q.jsx)(T,{svg:be,className:`${e.viewMode===`list`?`bg-dark text-white`:``} btn btn-outline-dark rounded-end rounded-start-0 border-start-0 px-3 h-100`,onClick:()=>e.setViewMode(`list`),analyticsData:{},analyticsOptions:{entity:h.AppLink,actionType:_.Click,descriptor:m.List,location:g.CalendarNav}})]})}function Pe(e){let i=e.action===`previous`?ae:fe,a=e.action===`previous`?X.left:X.right;function o(){r.trigger(e.appLink),e.onClick()}return(0,q.jsx)(C,{appLink:e.appLink,analyticsData:e.analyticsData,analyticsOptions:e.analyticsOptions,className:`${X.chevron} ${a} border border-dark rounded-circle bg-white d-flex align-items-center justify-content-center`,onClick:o,children:(0,q.jsx)(n,{svg:i,size:t.Medium,className:`svg-container d-inline-block ${X.svg}`})})}var Fe=new Date;function Ie(e){let{appLinks:t}=e,n=P();function r(n){let r=p.format(n,`MMMM`).toLocaleLowerCase(),i=t.month(r),a={};if(n){let e=new Date().getFullYear(),t=n.getFullYear();e!==t&&(a.year=t)}return e.queryParams?.classification&&(a.classification=e.queryParams.classification),e.queryParams?.yearGroup&&(a.yearGroup=e.queryParams.yearGroup),i.params=a,i}function i(){let t=p.add(e.monthDate,1,`month`);e.setViewingMonthDate(t)}function o(){let t=p.subtract(e.monthDate,1,`month`);e.setViewingMonthDate(t)}function s(){p.format(Fe,`M YY`)!==p.format(e.monthDate,`M YY`)&&e.setViewingMonthDate()}let{showPrev:c,showNext:l}=le(e.monthDate),u={actionType:_.Click,entity:h.SpecialEvent,location:g.CalendarNav};function d(e){return p.format(e,`YYYY-MM-DD`)}return(0,q.jsxs)(`div`,{className:`d-flex flex-wrap gap-3 justify-content-end align-items-center`,children:[(0,q.jsx)(`h1`,{className:`mb-0 h2 me-auto`,children:p.format(e.monthDate,n.xs?`MMM YYYY`:`MMMM YYYY`)}),e.children,e.setViewMode&&(0,q.jsx)(Ne,{viewMode:e.viewMode,setViewMode:e.setViewMode}),(0,q.jsxs)(`div`,{className:`d-flex gap-3`,children:[c&&(0,q.jsx)(Pe,{appLink:r(p.startOf(p.subtract(e.monthDate,1,`month`),`month`)),action:`previous`,onClick:o,analyticsOptions:u,analyticsData:{action:`previous`,date:d(p.startOf(p.add(e.monthDate,1,`month`),`month`))}}),(0,q.jsx)(C,{appLink:r(),className:`${X.todayWrapper} btn btn-outline-dark fw-semibold`,onClick:s,analyticsOptions:u,analyticsData:{action:`today`,date:d(p.startOf(Fe,`month`))},children:a.getPhrase(Me,`today`)}),l&&(0,q.jsx)(Pe,{appLink:r(p.startOf(p.add(e.monthDate,1,`month`),`month`)),analyticsOptions:u,analyticsData:{action:`next`,date:d(p.startOf(p.add(e.monthDate,1,`month`),`month`))},action:`next`,onClick:i})]})]})}var Z=`specialEvent.eventsErrorState`,Le=a.encloseNamespace(Z);function Re(e){return(0,q.jsx)(N.Provider,{value:Z,children:(0,q.jsxs)(E,{children:[(0,q.jsx)(E.Image,{src:e.imageUrl}),(0,q.jsx)(E.Heading,{children:(0,q.jsx)(M,{phrase:`heading`})}),(0,q.jsxs)(E.Info,{children:[(0,q.jsx)(M,{namespace:Z,phrase:`info`}),(0,q.jsx)(`br`,{}),(0,q.jsx)(C,{appLink:e.appLink,children:(0,q.jsx)(`span`,{className:`text-info`,children:Le(`link`)})})]})]})})}function ze(e,t){let n=t,[r,i]=I(e),[a,o]=I(p.add(e,1,`month`)),[s,c]=I(p.subtract(e,1,`month`)),l=u(r&&i&&n&&W.calendarEvents(p.format(r,`YYYY-MM-DD`),p.format(i,`YYYY-MM-DD`),n)),d=u(a&&o&&n&&W.calendarEvents(p.format(a,`YYYY-MM-DD`),p.format(o,`YYYY-MM-DD`),n)),m=u(s&&c&&n&&W.calendarEvents(p.format(s,`YYYY-MM-DD`),p.format(c,`YYYY-MM-DD`),n));return{events:f.uniq([...m.data||[],...l.data||[],...d.data||[]],e=>e.specialEventPolicyId),loaded:l.hasCompleted}}var Be=new Date;function Ve(e=Be,t,n=!0){let i=ue(n),a=K.useRef({}),o=p.format(e,`YYYY-MM`),s=K.useMemo(()=>{let t=a.current[o];if(!t){let{weeksTable:t,datePositionMap:r}=de(e,n);return a.current[o]={weeksTable:t,datePositionMap:r},t}return t.weeksTable},[o,n]);function c(n){if(!n){r.trigger(t.calendar());return}if(o!==p.format(n,`YYYY-MM`)){let i=p.format(n,`MMMM`).toLocaleLowerCase(),a=new Date().getFullYear(),o=e.getFullYear(),s=t.month(i);a!==o&&(s.params={year:o}),r.trigger(s)}}return{weekDaysHeader:i,weekDays:s,monthDate:e,setMonthDate:c,startDate:f.first(f.first(s)),endDate:f.last(f.last(s))}}var Q=a.encloseNamespace(`specialEventCalendar.calendarView`);function He(e){let t=P(),{showCalendar:n,isLoading:i}=oe(),a=u(y.currentUser()),{availablePresentations:o}=ie(),{activePresentation:s}=b(),{applinks:c}=G({applinks:ve(e.presentationSlug??null,o),exceptions:[`month`]}),l=F(e.month);K.useEffect(()=>{!i&&!n&&r.trigger(xe(s?.vanitySlug??e.presentationSlug).forYou,{replace:!0})},[n,i]);let d=L(e.month),{monthDate:f,setMonthDate:m,weekDays:h,weekDaysHeader:g,startDate:_,endDate:v}=Ve(d,c),{events:te,loaded:ne}=ze(d,s.id),C=p.format(f,`MMMM YYYY`);if(O(D.getDefaultMetadata({title:C,phraseContext:{phraseHandler:Q,titlePhrase:`pageTitle`,descriptionPhrase:`pageDescription`},canonicalLink:j.getCanonicalLink({allowedParams:[`year`]}),allowIndexing:j.allowIndexing(),hrefLang:j.getStaticRouteHrefLang(s?.learningLevel,c.calendar,A)})),e.month!==null&&!l)return(0,q.jsx)(Re,{imageUrl:V().errorState,appLink:c.calendar()});function w(e,t){return t?S.createUrl(t.iconUrl,{size:x.Medium}):S.createUrl(e.icon?.url,{size:x.Small})}function T(e){return S.createUrl(e.cover?.url,{size:x.Small})}function E(){return t.xs?Q(`mobileButtonLabel`):Q(`buttonLabel`)}function k(e){return ee.SpecialEvents[e.id]}return i||!n||!s?.id||!a.data.countryCode?(0,q.jsx)(q.Fragment,{}):(0,q.jsxs)(`div`,{className:`bg-white px-3`,children:[(0,q.jsx)(Ie,{monthDate:f,setViewingMonthDate:m,appLinks:c}),(0,q.jsx)(Y,{weekDays:h,weekDaysHeader:g,events:te,monthQuery:{from:_?.toString(),to:v?.toString()},viewingMonth:d,eventsLoaded:ne,presentationId:s.id,appLinks:c,imageUrls:V(a.data.countryCode),getIconUrl:e=>w(e,k(e)),getCoverUrl:T,getBackgroundColor:e=>e.metadata?.backgroundColor,getBannerUrl:e=>e.banner?.url,getActionLabel:E,getHardCodedEvent:k})]})}function Ue(e,t){let[n,r]=I(e),[i,a]=I(p.add(e,1,`month`)),[o,s]=I(p.subtract(e,1,`month`)),c={};t.yearGroup&&(c.audienceId=t.yearGroup),t.classification&&(c.topicId=t.classification,c.includeChildrenTopics=!0);let l=u(n&&r&&B.calendarLivestreams({from:p.format(n,`YYYY-MM-DD`),to:p.format(r,`YYYY-MM-DD`),...c})),d=u(i&&a&&B.calendarLivestreams({from:p.format(i,`YYYY-MM-DD`),to:p.format(a,`YYYY-MM-DD`),...c})),m=u(o&&s&&B.calendarLivestreams({from:p.format(o,`YYYY-MM-DD`),to:p.format(s,`YYYY-MM-DD`),...c}));return{events:f.uniq([...m.data||[],...l.data||[],...d.data||[]],e=>e.id),loaded:l.hasCompleted}}var $=a.encloseNamespace(`liveCalendar.calendarView`);We.defaultProps={queryParams:{}};function We(e){let[{viewMode:t},n]=te(`calendar:mode`,{viewMode:`calendar`},{storage:l.LocalStorage}),{hasPermissions:r}=k(),a=r(i.StudentExperience),{activePresentation:o}=b(),{applinks:s}=G({applinks:ge(e.presentationSlug),exceptions:[`month`]}),c=u(o&&se.presentationAudiences(v.StreamableLearning,o.id)),f=u(o&&ne.topicsFromAllAvailablePresentations([o.id])),m=F(e.month),h=L(e.month),{monthDate:g,setMonthDate:_,weekDays:ee,weekDaysHeader:y,startDate:C,endDate:w}=Ve(h,s),{events:T,loaded:E}=Ue(h,e.queryParams),A=p.format(g,`MMMM YYYY`);if(O(D.getDefaultMetadata({title:A,phraseContext:{phraseHandler:$,titlePhrase:`pageTitle`,descriptionPhrase:`pageDescription`},canonicalLink:j.getCanonicalLink({allowedParams:[`year`]}),allowIndexing:!0})),e.month!==null&&!m)return(0,q.jsx)(Re,{imageUrl:H().errorState,appLink:s.calendar()});let M=[{id:`classification`,name:$(`subjectFilter`),options:f.data?.topics.map(e=>({name:e.name,id:e.topicIds.join(`:`)})),type:`checkbox`,compatibleIndices:[]},{id:`yearGroup`,name:$(`gradeFilter`),type:`checkbox`,options:c.data?.map(e=>({name:e.name,id:e.masterId})),compatibleIndices:[]}];function N(){let t=p.format(g,`MMMM`).toLocaleLowerCase(),n=new Date().getFullYear(),r=g.getFullYear(),i=s.month(t),a={};return n!==r&&(a.year=r),e.queryParams.classification&&(a.classification=e.queryParams.classification),e.queryParams.yearGroup&&(a.yearGroup=e.queryParams.yearGroup),i}function P(e){return a||p.isBefore(e.endDateTime,new Date)?`pastActionLabel`:`actionLabel`}function re(){if(!z.getEventsInMonth(T||[],h).length&&(e.queryParams.yearGroup||e.queryParams.classification))return $(`emptyStateText`)}function ie(e){return S.createUrl(e.company.logo?.url,{size:x.Small})}function ae(e){return S.createUrl(e.company.banner?.url,{size:x.Large})}return o?(0,q.jsxs)(`div`,{className:`bg-white px-4`,children:[(0,q.jsx)(Ie,{monthDate:g,setViewingMonthDate:_,appLinks:s,queryParams:e.queryParams,viewMode:t,setViewMode:e=>n({viewMode:e}),children:(0,q.jsx)(`div`,{className:`mx-n1 order-1 order-sm-0`,children:(0,q.jsx)(Se,{queryParams:d.omit(e.queryParams,[`year`]),mainFilters:M,appLink:N(),isFetchingOptions:!f.data||!o||!c.data,alignResetButtonLeft:!0,hideDivider:!0,hideHeading:!0,hideCaret:!1,noContainerPaddingBottom:!0})})}),(0,q.jsxs)(`div`,{className:`position-relative mt-3 ${t===`list`?``:`mt-lg-0`}`,children:[(0,q.jsx)(`div`,{className:`d-block ${t===`list`?``:`d-lg-none`} position-absolute top-0 end-0 mt-2`,children:(0,q.jsx)(_e,{})}),(0,q.jsx)(Y,{weekDays:ee,weekDaysHeader:y,events:T,monthQuery:{from:C?.toString(),to:w?.toString()},viewingMonth:h,eventsLoaded:E,presentationId:o.id,appLinks:s,imageUrls:H(),viewMode:t,getActionLabel:e=>$(P(e)),getBackgroundColor:e=>e.company.metadata?.colour,getBannerUrl:ae,getIconUrl:ie,getStartTime:U.getStartTime,theme:{background:`bg-light-green`,border:`border-light-green`},emptyStateHeading:re(),fadePastEvents:!0,timezone:me.ET,isPastEvent:U.isPastEvent})]})]}):(0,q.jsx)(q.Fragment,{})}var Ge=pe({[v.Subject]:e=>(0,q.jsx)(He,{month:e.month,presentationSlug:e.presentationSlug}),[v.StreamableLearning]:e=>(0,q.jsx)(We,{month:e.month,presentationSlug:e.presentationSlug,queryParams:Ce(e.queryParams)})});Ge.displayName=`BaseCalendarView`;export{Ge as BaseCalendarView};
2
+ //# sourceMappingURL=DkFP4cXM.chunk.js.map