diff --git a/src/atoms/Icons/MapIndicator.tsx b/src/atoms/Icons/MapIndicator.tsx new file mode 100644 index 00000000..0607c5ac --- /dev/null +++ b/src/atoms/Icons/MapIndicator.tsx @@ -0,0 +1,15 @@ +import { Base, BaseProps } from './Base' + +export function MapIndicator(props: BaseProps): JSX.Element { + return ( + + + + ) +} + +MapIndicator.displayName = 'MapIndicator' diff --git a/src/atoms/Icons/index.tsx b/src/atoms/Icons/index.tsx index b5c97b41..bcdf3f14 100644 --- a/src/atoms/Icons/index.tsx +++ b/src/atoms/Icons/index.tsx @@ -1,28 +1,29 @@ export * from './AcademicRecord' export * from './AlertInfo' +export * from './Alerts' export * from './ArrowRight' export * from './Calendar' export * from './Certificate' export * from './CircularCheck' export * from './CircularInformation' +export * from './Close' +export * from './DiagonalArrow' export * from './Download' export * from './GoAhead' export * from './GoBack' -export * from './Multimedia' export * from './Loader' +export * from './MapIndicator' +export * from './Multimedia' +export * from './Password' +export * from './Pen' +export * from './PlusSign' export * from './Profile' export * from './Remote' export * from './Schedule' +export * from './TextBubble' export * from './Time' -export * from './TinyAlertInfo' export * from './TinyAlertError' -export * from './TinyAlertWarning' +export * from './TinyAlertInfo' export * from './TinyAlertSuccess' -export * from './Password' -export * from './Pen' -export * from './PlusSign' +export * from './TinyAlertWarning' export * from './TrashCan' -export * from './TextBubble' -export * from './Alerts' -export * from './Close' -export * from './DiagonalArrow' diff --git a/src/documentation/pages/Organisms/CalendarDropdown.tsx b/src/documentation/pages/Organisms/CalendarDropdown.tsx index e69a5d92..a7545505 100644 --- a/src/documentation/pages/Organisms/CalendarDropdown.tsx +++ b/src/documentation/pages/Organisms/CalendarDropdown.tsx @@ -1,6 +1,7 @@ +import { Box } from '@chakra-ui/react' + import { Code, MyHeading, MyText, MyTitle } from '@/documentation/components' import { CalendarDropdown } from '@/organisms' -import { Box } from '@chakra-ui/react' import { vars } from '@theme' export const CalendarDropdownPage = (): JSX.Element => { @@ -206,34 +207,34 @@ const events = [ time: '0:01 hrs.', }, }, - { - id: 4534, - student_id: 17158893, - course_id: 40711, - class_id: 1, - status: 'SCHEDULED', - start: '2025-05-29T04:01:00.000Z', - end: '2025-05-29T05:01:00.000Z', - duration_in_minutes: 60, - type: 'evaluation-release', - id_resource: 1947886, - associated_resource: { - id: 1, - name: 'Se habilita para responder "MCH y MCV"', - description: 'MCH o MCV', - }, - url: null, - course: { - id: 40711, - name: '[Pruebas TI] - Herramientas para la Gestión Estratégica de Procesoss', - }, - translatedTitle: 'Se habilita para responder "MCH y MCV"', - formatedDate: { - day: 'jueves', - date: '29 may', - time: '0:01 hrs.', - }, - }, + // { + // id: 4534, + // student_id: 17158893, + // course_id: 40711, + // class_id: 1, + // status: 'SCHEDULED', + // start: '2025-05-29T04:01:00.000Z', + // end: '2025-05-29T05:01:00.000Z', + // duration_in_minutes: 60, + // type: 'evaluation-release', + // id_resource: 1947886, + // associated_resource: { + // id: 1, + // name: 'Se habilita para responder "MCH y MCV"', + // description: 'MCH o MCV', + // }, + // url: null, + // course: { + // id: 40711, + // name: '[Pruebas TI] - Herramientas para la Gestión Estratégica de Procesoss', + // }, + // translatedTitle: 'Se habilita para responder "MCH y MCV"', + // formatedDate: { + // day: 'jueves', + // date: '29 may', + // time: '0:01 hrs.', + // }, + // }, { id: 62947, student_id: 17158893, @@ -318,6 +319,35 @@ const events = [ time: '23:59 hrs.', }, }, + { + id: 808522222, + student_id: 17269014, + course_id: 22568, + class_id: 1, + status: 'SCHEDULED', + start: '2027-01-01T02:59:00.000Z', + end: '2027-01-01T03:59:00.000Z', + duration_in_minutes: 60, + type: 'in-person-presencial', + location_sede: 'Sede Santiago, sala 204', + id_resource: 848781, + associated_resource: { + id: 1, + name: 'CalendarEventDeadlineAnswer "Pregunta tipo archivo toma 2"', + description: 'Clase con Pruebas de Prueba', + }, + url: null, + course: { + id: 22568, + name: 'Pruebas contenido v8', + }, + translatedTitle: 'Fin del plazo para responder "Pregunta tipo archivo toma 2"', + formatedDate: { + day: 'jueves', + date: '31 dic', + time: '23:59 hrs.', + }, + }, { id: 80868, student_id: 17269014, diff --git a/src/documentation/pages/Organisms/EventsList.tsx b/src/documentation/pages/Organisms/EventsList.tsx index 36efec0f..a0ca46b5 100644 --- a/src/documentation/pages/Organisms/EventsList.tsx +++ b/src/documentation/pages/Organisms/EventsList.tsx @@ -1,7 +1,8 @@ +import { Box } from '@chakra-ui/react' + import { Code, MyHeading, MyText, MyTitle } from '@/documentation/components' import { EventsList } from '@/organisms' import { vars } from '@/theme' -import { Box } from '@chakra-ui/react' export const EventsListPage = (): JSX.Element => { return ( @@ -82,6 +83,20 @@ export const EventsListPage = (): JSX.Element => { courseName="[Pruebas TI] - Herramientas para la Gestión Estratégica de Procesos" duration={40} /> + 3. Eventos en vista curso @@ -128,6 +143,7 @@ interface IEventList { time: string // Hora name: string // Nombre del evento hasNotification?: boolean // Indica si el evento tiene notificación + locationSede?: string // Sede para eventos de tipo in-person-presencial onClick?: () => void // Permite usar el item como elemento clickeable showCourse?: boolean // Indica si se muestra el curso showUnit?: boolean // Indica si se muestra la unidad diff --git a/src/organisms/Calendar/Dropdown/CalendarDropdown/Components/EventsGroup.tsx b/src/organisms/Calendar/Dropdown/CalendarDropdown/Components/EventsGroup.tsx index 78aa75ef..01706c99 100644 --- a/src/organisms/Calendar/Dropdown/CalendarDropdown/Components/EventsGroup.tsx +++ b/src/organisms/Calendar/Dropdown/CalendarDropdown/Components/EventsGroup.tsx @@ -1,6 +1,7 @@ +import { Box, MenuGroup } from '@chakra-ui/react' + import { BtnLink } from '@/molecules' import { EventsList } from '@/organisms/Calendar' -import { Box, MenuGroup } from '@chakra-ui/react' import { vars } from '@theme' import { Event } from '../../types' @@ -29,6 +30,42 @@ export const EventsGroup = ({ }: IEventsGroupProps): JSX.Element => { if (!events || (events && events.length === 0)) return <> + const eventItems: JSX.Element[] = events.map((event) => ( + // Una vez que el evento se comporte como link, se debe cambiar Box a MenuItem y aplicar el efecto de focus + + onClickEvent(event) : undefined} + showCourse + /> + + )) + return ( <> - - {events.map((event: Event) => { - return ( - // Una vez que el evento se comporte como link, se debe cambiar Box a MenuItem y aplicar el efecto de focus - - onClickEvent(event) : undefined} - showCourse - /> - - ) - })} - + {eventItems} {hasMoreNext && ( diff --git a/src/organisms/Calendar/Dropdown/types.d.ts b/src/organisms/Calendar/Dropdown/types.d.ts index 4db64c14..18eb8cd6 100644 --- a/src/organisms/Calendar/Dropdown/types.d.ts +++ b/src/organisms/Calendar/Dropdown/types.d.ts @@ -24,6 +24,7 @@ export interface Event { formatedDate: FormattedDate id: number isNew?: boolean + location_sede?: string translatedTitle: string type: string } diff --git a/src/organisms/Calendar/EventsList/EventsList.test.tsx b/src/organisms/Calendar/EventsList/EventsList.test.tsx index 5b1defe8..1ae89dcb 100644 --- a/src/organisms/Calendar/EventsList/EventsList.test.tsx +++ b/src/organisms/Calendar/EventsList/EventsList.test.tsx @@ -52,6 +52,29 @@ describe('EventsList', () => { expect(container).toHaveTextContent(/40\s*min/) }) + it('renders location for in-person-presencial events when locationSede is provided', () => { + const { container } = renderComponent(undefined, { + duration: 40, + locationSede: 'Sede Santiago, sala 204', + type: 'in-person-presencial', + }) + + expect(screen.getByText('Sede Santiago, sala 204')).toBeInTheDocument() + expect(screen.queryByText('Link clase online')).not.toBeInTheDocument() + expect(container).toHaveTextContent(/40\s*min/) + }) + + it('does not render an empty location label for in-person-presencial events without locationSede', () => { + const { container } = renderComponent(undefined, { + duration: 40, + type: 'in-person-presencial', + }) + + expect(screen.queryByText('Link clase online')).not.toBeInTheDocument() + expect(screen.queryByTitle('icon-mapIndicator')).not.toBeInTheDocument() + expect(container).toHaveTextContent(/40\s*min/) + }) + it('does not render duration when minutes are zero', () => { renderComponent(undefined, { duration: 0 }) diff --git a/src/organisms/Calendar/EventsList/EventsList.tsx b/src/organisms/Calendar/EventsList/EventsList.tsx index 1d08b286..d6999d6a 100644 --- a/src/organisms/Calendar/EventsList/EventsList.tsx +++ b/src/organisms/Calendar/EventsList/EventsList.tsx @@ -1,7 +1,7 @@ -import { Remote, Time } from '@/atoms/Icons' import { Box } from '@chakra-ui/react' -import { vars } from '@theme' +import { vars } from '@theme' +import { MapIndicator, Remote, Time } from '@/atoms/Icons' import { NotificationIcon } from './NotificationIcon' export interface IEventList { @@ -12,6 +12,7 @@ export interface IEventList { duration?: number name: string hasNotification?: boolean + locationSede?: string onClick?: () => void showCourse?: boolean showUnit?: boolean @@ -29,6 +30,7 @@ export const EventsList = ({ duration, name, hasNotification, + locationSede, onClick, showCourse, showUnit, @@ -40,9 +42,13 @@ export const EventsList = ({ const border = `1px solid ${vars('colors-neutral-platinum') ?? '#E8E8E8'}` const hoverBg = vars('colors-neutral-cultured2') ?? '#F8F8F8' const isClickable = Boolean(onClick) + const isInPersonPresencial = type === 'in-person-presencial' + const showEventLocation = !isInPersonPresencial || Boolean(locationSede) const showEventDuration = - ['online', 'in-person'].includes(type) && duration !== undefined && duration > 0 + ['online', 'in-person', 'in-person-presencial'].includes(type) && + duration !== undefined && + duration > 0 const initOrEnd = [ 'end-course', @@ -51,30 +57,6 @@ export const EventsList = ({ 'end-course-flexible', ].includes(type) - const dateTextStyle = { - color: vars('colors-neutral-white'), - fontSize: '14px', - fontWeight: '700', - lineHeight: '100%', - } - - const detailTextStyle = { - color: vars('colors-neutral-gray') ?? '#808080', - fontSize: '14px', - alignItems: 'center', - display: 'flex', - gap: '4px', - lineHeight: 'normal', - } - - const eventIconStyle = { - alignItems: 'center', - display: 'inline-flex', - height: '24px', - justifyContent: 'center', - minWidth: '16px', - } - return ( {showCourse && !initOrEnd && ( - + {type === 'cv-events' ? <> : {text ? `${text}:` : 'Curso:'}}{' '} {courseName} @@ -138,17 +120,23 @@ export const EventsList = ({ {showEventDuration && ( - - - + {showEventLocation && ( + + + {isInPersonPresencial ? ( + + ) : ( + + )} + + {isInPersonPresencial ? locationSede : 'Link clase online'} - Link clase online - + )} ) } + +const dateTextStyle = { + color: vars('colors-neutral-white'), + fontSize: '14px', + fontWeight: '700', + lineHeight: '100%', +} + +const detailTextStyle = { + color: vars('colors-neutral-gray') ?? '#808080', + fontSize: '14px', + alignItems: 'center', + display: 'flex', + gap: '4px', + lineHeight: 'normal', +} + +const courseDetailTextStyle = { + ...detailTextStyle, + alignItems: 'flex-start', +} + +const eventIconStyle = { + alignItems: 'center', + display: 'inline-flex', + height: '24px', + justifyContent: 'center', + minWidth: '16px', +}