import React, {
useCallback, useEffect, useMemo, useState,
} from 'react';
import { Helmet } from 'react-helmet';
import { getConfig } from '@edx/frontend-platform';
import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import {
Alert,
ActionRow,
Button,
Card,
Container,
Hyperlink,
Icon,
Stack,
Tab,
Tabs,
} from '@openedx/paragon';
import {
Cached, CheckCircle, Launch, Loop,
} from '@openedx/paragon/icons';
import sumBy from 'lodash/sumBy';
import { useSearchParams } from 'react-router-dom';
import getPageHeadTitle from '../generic/utils';
import { useModel } from '../generic/model-store';
import messages from './messages';
import SubHeader from '../generic/sub-header/SubHeader';
import { useEntityLinksSummaryByDownstreamContext } from './data/apiHooks';
import type { PublishableEntityLinkSummary } from './data/api';
import Loading from '../generic/Loading';
import { useStudioHome } from '../studio-home/hooks';
import NewsstandIcon from '../generic/NewsstandIcon';
import ReviewTabContent from './ReviewTabContent';
import { OutOfSyncAlert } from './OutOfSyncAlert';
interface Props {
courseId: string;
}
interface LibraryCardProps {
linkSummary: PublishableEntityLinkSummary;
}
export enum CourseLibraryTabs {
all = 'all',
review = 'review',
}
const LibraryCard = ({ linkSummary }: LibraryCardProps) => {
const intl = useIntl();
return (
{linkSummary.upstreamContextTitle}
)}
actions={(
)}
size="sm"
/>
{intl.formatMessage(messages.totalComponentLabel, { totalComponents: linkSummary.totalCount })}
{linkSummary.readyToSyncCount > 0 && (
{intl.formatMessage(messages.outOfSyncCountLabel, { outOfSyncCount: linkSummary.readyToSyncCount })}
)}
);
};
export const CourseLibraries: React.FC = ({ courseId }) => {
const intl = useIntl();
const courseDetails = useModel('courseDetails', courseId);
const [searchParams] = useSearchParams();
const [tabKey, setTabKey] = useState(
() => searchParams.get('tab') as CourseLibraryTabs,
);
const [showReviewAlert, setShowReviewAlert] = useState(false);
const { data: libraries, isLoading } = useEntityLinksSummaryByDownstreamContext(courseId);
const outOfSyncCount = useMemo(() => sumBy(libraries, (lib) => lib.readyToSyncCount), [libraries]);
const {
isLoadingPage: isLoadingStudioHome,
isFailedLoadingPage: isFailedLoadingStudioHome,
librariesV2Enabled,
} = useStudioHome();
const onAlertReview = () => {
setTabKey(CourseLibraryTabs.review);
};
const tabChange = useCallback((selectedTab: CourseLibraryTabs) => {
setTabKey(selectedTab);
}, []);
useEffect(() => {
setTabKey((prev) => {
if (outOfSyncCount > 0) {
return CourseLibraryTabs.review;
}
if (prev) {
return prev;
}
/* istanbul ignore next */
return CourseLibraryTabs.all;
});
}, [outOfSyncCount]);
const renderLibrariesTabContent = useCallback(() => {
if (isLoading) {
return ;
}
if (libraries?.length === 0) {
return ;
}
return (
<>
{libraries?.map((library) => (
))}
>
);
}, [libraries, isLoading]);
const renderReviewTabContent = useCallback(() => {
if (isLoading) {
return ;
}
if (tabKey !== CourseLibraryTabs.review) {
return null;
}
if (!outOfSyncCount) {
return (
);
}
return ;
}, [outOfSyncCount, isLoading, tabKey]);
if (!isLoadingStudioHome && (!librariesV2Enabled || isFailedLoadingStudioHome)) {
return (
{intl.formatMessage(messages.librariesV2DisabledError)}
);
}
return (
<>
{getPageHeadTitle(courseDetails?.name, intl.formatMessage(messages.headingTitle))}
0 && tabKey === CourseLibraryTabs.all && (
)}
hideBorder
/>
{renderLibrariesTabContent()}
{intl.formatMessage(messages.reviewTabTitle)}
)}
notification={outOfSyncCount}
className="px-2 mt-3"
>
{renderReviewTabContent()}
>
);
};