1- import moment from 'moment/moment' ;
1+ import moment , { Moment } from 'moment/moment' ;
22import { FormattedDate , useIntl } from '@edx/frontend-platform/i18n' ;
33import { getConfig } from '@edx/frontend-platform/config' ;
4- import {
5- Button , Hyperlink , Stack ,
6- } from '@openedx/paragon' ;
4+ import { Badge , Icon , Stack } from '@openedx/paragon' ;
75import { Link } from 'react-router-dom' ;
86
9- import { useHelpUrls } from '../../help-urls/hooks' ;
107import { useWaffleFlags } from '../../data/apiHooks' ;
118import messages from './messages' ;
12- import { ReactNode } from 'react' ;
9+ import { useMemo } from 'react' ;
1310import { CourseOutlineStatusBar } from '@src/course-outline/data/types' ;
11+ import { ChecklistRtl , NotificationsNone } from '@openedx/paragon/icons' ;
1412
15- interface StatusBarItemProps {
16- title : string ,
17- children : ReactNode ,
18- } ;
13+ const CourseDatesAndStatus = ( { startDate, endDate, startDateRaw, datesLink } : {
14+ startDate : Moment ;
15+ endDate : Moment ;
16+ startDateRaw : string ;
17+ datesLink : string ;
18+ } ) => {
19+ if ( ! startDate . isValid ( ) ) {
20+ // Returns string contained in startDate, i.e. `Set Date`
21+ return < > { startDateRaw } </ > ;
22+ }
1923
20- const StatusBarItem = ( { title, children } : StatusBarItemProps ) => (
21- < div className = "d-flex flex-column justify-content-between" >
22- < h5 > { title } </ h5 >
23- < div className = "d-flex align-items-center" >
24- { children }
25- </ div >
26- </ div >
27- ) ;
24+ const courseStatus = useMemo ( ( ) => {
25+ const now = moment ( ) . utc ( ) ;
26+ return {
27+ active : now . isBetween ( startDate , endDate . isValid ( ) ? endDate : undefined , undefined , '[]' ) ,
28+ upcoming : now . isBefore ( startDate ) ,
29+ archived : endDate . isValid ( ) && endDate . isBefore ( now ) ,
30+ }
31+ } , [ startDate , endDate ] ) ;
32+
33+ return (
34+ < Stack direction = 'horizontal' gap = { 3 } >
35+ { courseStatus . active
36+ ? < Badge className = "px-3 py-1" variant = "success" > Active</ Badge >
37+ : courseStatus . upcoming
38+ ? < Badge className = "px-3 py-1 bg-white text-success-400 border border-success-500" variant = "success" > Upcoming</ Badge >
39+ : courseStatus . archived &&
40+ < Badge className = "px-3 py-1" variant = "light" > Archived</ Badge >
41+ }
42+ < Link
43+ className = "small text-gray-700"
44+ to = { datesLink }
45+ >
46+ < FormattedDate
47+ value = { startDate . toString ( ) }
48+ year = "numeric"
49+ month = "short"
50+ day = "2-digit"
51+ />
52+ { endDate . isValid ( ) && (
53+ < >
54+ { " - " }
55+ < FormattedDate
56+ value = { endDate . toString ( ) }
57+ year = "numeric"
58+ month = "short"
59+ day = "2-digit"
60+ />
61+ </ >
62+ ) }
63+ </ Link >
64+ </ Stack >
65+ )
66+ } ;
2867
2968interface StatusBarProps {
30- courseId : string ,
31- isLoading : boolean ,
32- openEnableHighlightsModal : ( ) => void ,
33- handleVideoSharingOptionChange : ( ) => void ,
34- statusBarData : CourseOutlineStatusBar ,
69+ courseId : string ;
70+ isLoading : boolean ;
71+ statusBarData : CourseOutlineStatusBar ;
72+ notificationCount ?: number ;
3573} ;
3674
3775const StatusBar = ( {
3876 statusBarData,
3977 isLoading,
4078 courseId,
41- openEnableHighlightsModal ,
79+ notificationCount ,
4280} : StatusBarProps ) => {
4381 const intl = useIntl ( ) ;
4482 const waffleFlags = useWaffleFlags ( courseId ) ;
4583
4684 const {
4785 endDate,
4886 courseReleaseDate,
49- highlightsEnabledForMessaging,
5087 checklist,
51- isSelfPaced,
5288 } = statusBarData ;
5389
5490 const {
@@ -63,70 +99,30 @@ const StatusBar = ({
6399 const checkListTitle = `${ completedCourseLaunchChecks + completedCourseBestPracticesChecks } /${ totalCourseLaunchChecks + totalCourseBestPracticesChecks } ` ;
64100 const scheduleDestination = ( ) => new URL ( `settings/details/${ courseId } #schedule` , getConfig ( ) . STUDIO_BASE_URL ) . href ;
65101
66- const {
67- contentHighlights : contentHighlightsUrl ,
68- } = useHelpUrls ( [ 'contentHighlights' , 'socialSharing' ] ) ;
69-
70102 if ( isLoading ) {
71103 return null ;
72104 }
73105
74106 return (
75- < >
76- < Stack direction = "horizontal" gap = { 3.5 } className = "d-flex align-items-stretch outline-status-bar" data-testid = "outline-status-bar" >
77- < StatusBarItem title = { intl . formatMessage ( messages . startDateTitle ) } >
78- < Link
79- className = "small"
80- to = { waffleFlags . useNewScheduleDetailsPage ? `/course/${ courseId } /settings/details/#schedule` : scheduleDestination ( ) }
81- >
82- { courseReleaseDateObj . isValid ( ) ? (
83- < FormattedDate
84- value = { courseReleaseDateObj . toString ( ) }
85- year = "numeric"
86- month = "short"
87- day = "2-digit"
88- />
89- ) : courseReleaseDate }
90- </ Link >
91- </ StatusBarItem >
92- < StatusBarItem title = { intl . formatMessage ( messages . pacingTypeTitle ) } >
93- < span className = "small" >
94- { isSelfPaced
95- ? intl . formatMessage ( messages . pacingTypeSelfPaced )
96- : intl . formatMessage ( messages . pacingTypeInstructorPaced ) }
97- </ span >
98- </ StatusBarItem >
99- < StatusBarItem title = { intl . formatMessage ( messages . checklistTitle ) } >
100- < Link
101- className = "small"
102- to = { `/course/${ courseId } /checklists` }
103- >
104- { checkListTitle } { intl . formatMessage ( messages . checklistCompleted ) }
105- </ Link >
106- </ StatusBarItem >
107- < StatusBarItem title = { intl . formatMessage ( messages . highlightEmailsTitle ) } >
108- < div className = "d-flex align-items-center" >
109- { highlightsEnabledForMessaging ? (
110- < span data-testid = "highlights-enabled-span" className = "small" >
111- { intl . formatMessage ( messages . highlightEmailsEnabled ) }
112- </ span >
113- ) : (
114- < Button data-testid = "highlights-enable-button" size = "sm" onClick = { openEnableHighlightsModal } >
115- { intl . formatMessage ( messages . highlightEmailsButton ) }
116- </ Button >
117- ) }
118- < Hyperlink
119- className = "small ml-2"
120- destination = { contentHighlightsUrl }
121- target = "_blank"
122- showLaunchIcon = { false }
123- >
124- { intl . formatMessage ( messages . highlightEmailsLink ) }
125- </ Hyperlink >
126- </ div >
127- </ StatusBarItem >
128- </ Stack >
129- </ >
107+ < Stack direction = "horizontal" gap = { 4 } >
108+ < CourseDatesAndStatus
109+ startDate = { courseReleaseDateObj }
110+ endDate = { endDateObj }
111+ startDateRaw = { courseReleaseDate }
112+ datesLink = { waffleFlags . useNewScheduleDetailsPage ? `/course/${ courseId } /settings/details/#schedule` : scheduleDestination ( ) }
113+ />
114+ { ( notificationCount || 0 ) > 0 && < small className = "d-flex" >
115+ < Icon className = "mr-2" size = "md" src = { NotificationsNone } />
116+ { intl . formatMessage ( messages . notificationMetadataTitle , { count : notificationCount } ) }
117+ </ small > }
118+ < Link
119+ className = "small text-primary-500 d-flex"
120+ to = { `/course/${ courseId } /checklists` }
121+ >
122+ < Icon src = { ChecklistRtl } size = "md" className = "mr-2" />
123+ { checkListTitle } { intl . formatMessage ( messages . checklistCompleted ) }
124+ </ Link >
125+ </ Stack >
130126 ) ;
131127} ;
132128
0 commit comments