/* eslint-disable react-native-a11y/has-accessibility-hint */ import { useNavigation } from '@react-navigation/native' import { StackNavigationProp } from '@react-navigation/stack' import { Child } from '@skolplattformen/api-skolplattformen' import { useCalendar, useClassmates, useMenu, useNews, useNotifications, useSchedule, } from '@skolplattformen/hooks' import { Button, StyleService, Text, useStyleSheet, } from '@ui-kitten/components' import moment from 'moment' import React from 'react' import { TouchableOpacity, useColorScheme, View } from 'react-native' import { useTranslation } from '../hooks/useTranslation' import { Colors, Layout, Sizing } from '../styles' import { studentName } from '../utils/peopleHelpers' import { DaySummary } from './daySummary.component' import { AlertIcon, RightArrowIcon } from './icon.component' import { RootStackParamList } from './navigation.component' import { StudentAvatar } from './studentAvatar.component' interface ChildListItemProps { child: Child color: string } type ChildListItemNavigationProp = StackNavigationProp< RootStackParamList, 'Children' > export const ChildListItem = ({ child, color }: ChildListItemProps) => { // Forces rerender when child.id changes React.useEffect(() => { // noop }, [child.id]) const navigation = useNavigation() const { t } = useTranslation() const { data: notifications } = useNotifications(child) const { data: news } = useNews(child) const { data: classmates } = useClassmates(child) const { data: calendar } = useCalendar(child) const { data: menu } = useMenu(child) const { data: schedule } = useSchedule( child, moment().toISOString(), moment().add(7, 'days').toISOString() ) const notificationsThisWeek = notifications.filter( ({ dateCreated, dateModified }) => { const date = dateModified || dateCreated return date ? moment(date).isSame(moment(), 'week') : false } ) const newsThisWeek = news.filter(({ modified, published }) => { const date = modified || published return date ? moment(date).isSame(moment(), 'week') : false }) const scheduleAndCalendarThisWeek = [ ...(calendar ?? []), ...(schedule ?? []), ].filter(({ startDate }) => startDate ? moment(startDate).isBetween( moment().startOf('day'), moment().add(7, 'days') ) : false ) const displayDate = (date: moment.MomentInput) => { return moment(date).fromNow() } const getClassName = () => { // hack: we can find the class name (ex. 8C) from the classmates. // let's pick the first one and select theirs class // hack 2: we can find school namn in skola24 if child data is there if (classmates.length > 0) { return ( classmates[0].className + (child.schoolID == null ? '' : ' • ' + child.schoolID) ) } // Taken from Skolverket // https://www.skolverket.se/skolutveckling/anordna-och-administrera-utbildning/administrera-utbildning/skoltermer-pa-engelska const abbrevations = { G: t('abbrevations.upperSecondarySchool'), GR: t('abbrevations.compulsorySchool'), F: t('abbrevations.leisureTimeCentre'), FS: t('abbrevations.preSchool'), } return child.status ? child.status .split(';') .map((status) => { const statusAsAbbreviation = status as keyof typeof abbrevations return abbrevations[statusAsAbbreviation] || status }) .join(', ') : null } const className = getClassName() const styles = useStyleSheet(themeStyles) const isDarkMode = useColorScheme() === 'dark' return ( navigation.navigate('Child', { child, color })} > {studentName(child.name)} {className ? {className} : null} {scheduleAndCalendarThisWeek.slice(0, 3).map((calendarItem, i) => ( {`${calendarItem.title} (${displayDate(calendarItem.startDate)})`} ))} {t('navigation.news')} {notificationsThisWeek.slice(0, 3).map((notification, i) => ( {notification.message} ))} {newsThisWeek.slice(0, 3).map((newsItem, i) => ( {newsItem.header ?? ''} ))} {scheduleAndCalendarThisWeek.length || notificationsThisWeek.length || newsThisWeek.length ? null : ( {t('news.noNewNewsItemsThisWeek')} )} {!menu[moment().isoWeekday() - 1] ? null : ( <> {t('schedule.lunch')} {menu[moment().isoWeekday() - 1]?.description} )} ) } const themeStyles = StyleService.create({ card: { borderRadius: 25, padding: Sizing.t5, marginBottom: Sizing.t4, backgroundColor: 'background-basic-color-1', }, cardHeader: { ...Layout.flex.row, ...Layout.mainAxis.center, ...Layout.crossAxis.spaceBetween, marginBottom: Sizing.t4, }, cardHeaderLeft: { ...Layout.flex.row, ...Layout.mainAxis.center, flex: 10, }, cardHeaderRight: { ...Layout.flex.row, ...Layout.crossAxis.flexEnd, flex: 1, }, cardHeaderText: { marginHorizontal: Sizing.t4, flex: 10, }, icon: { width: 32, height: 32, }, label: { marginTop: 10, }, itemFooter: { ...Layout.flex.row, marginTop: Sizing.t4, }, itemFooterAbsence: { ...Layout.mainAxis.flexStart, marginTop: Sizing.t4, }, absenceButton: { marginLeft: -20, }, item: { marginRight: 12, paddingHorizontal: 2, paddingVertical: 0, marginBottom: 0, }, noNewNewsItemsText: {}, })