feat: 🎸 Den nygamla klasslistan (#462)
* feat: 🎸 Den nygamla klasslistan Börjar lägga tillbaka klasslistan och funktionalitet kring den ✅ Closes: #441 * feat: 🎸 Barnets klass och skola under namnet Försöker få fram namnet på klassen från klasslistan om det finns och namnet på skolan från Skola24 om det finna schema * fix: 🐛 Lade till språkstöd (svenska,engelska) till klasslistan * test: 💍 Tester fixade och tillgada * style: 💄 Linting
This commit is contained in:
parent
a480cbc48a
commit
f0d05a5000
|
@ -7,6 +7,7 @@ import {
|
|||
useSchedule,
|
||||
useMenu,
|
||||
useTimetable,
|
||||
useClassmates,
|
||||
} from '@skolplattformen/api-hooks'
|
||||
import { render } from '../../utils/testHelpers'
|
||||
import React from 'react'
|
||||
|
@ -37,6 +38,7 @@ beforeEach(() => {
|
|||
useSchedule.mockReturnValueOnce({ data: [], status: 'loaded' })
|
||||
useMenu.mockReturnValueOnce({ data: [], status: 'loaded' })
|
||||
useTimetable.mockReturnValueOnce({ data: [], status: 'loaded' })
|
||||
useClassmates.mockReturnValueOnce({ data: [], status: 'loaded' })
|
||||
useNavigation.mockReturnValue({ navigate: jest.fn(), setOptions: jest.fn() })
|
||||
})
|
||||
|
||||
|
@ -156,6 +158,33 @@ test('renders multiple children', () => {
|
|||
).toBeTruthy()
|
||||
})
|
||||
|
||||
test('renders child in class', () => {
|
||||
useChildList.mockImplementationOnce(() => ({
|
||||
data: [
|
||||
{
|
||||
name: 'Test Testsson',
|
||||
status: 'G',
|
||||
schoolID: 'Vallaskolan',
|
||||
},
|
||||
],
|
||||
status: 'loaded',
|
||||
}))
|
||||
useClassmates.mockReset()
|
||||
useClassmates.mockImplementationOnce(() => ({
|
||||
data: [
|
||||
{
|
||||
className: '8C',
|
||||
},
|
||||
],
|
||||
status: 'loaded',
|
||||
}))
|
||||
|
||||
const screen = setup()
|
||||
|
||||
expect(screen.getByText('Test Testsson')).toBeTruthy()
|
||||
expect(screen.getByText('8C • Vallaskolan')).toBeTruthy()
|
||||
})
|
||||
|
||||
test('removes any parenthesis from name', () => {
|
||||
useChildList.mockImplementationOnce(() => ({
|
||||
data: [
|
||||
|
|
|
@ -20,6 +20,7 @@ import { RootStackParamList } from './navigation.component'
|
|||
import { NavigationTitle } from './navigationTitle.component'
|
||||
import { NewsList } from './newsList.component'
|
||||
import { NotificationsList } from './notificationsList.component'
|
||||
import { Classmates } from './classmates.component'
|
||||
import { TabBarLabel } from './tabBarLabel.component'
|
||||
|
||||
type ChildNavigationProp = StackNavigationProp<RootStackParamList, 'Child'>
|
||||
|
@ -30,6 +31,7 @@ export type ChildTabParamList = {
|
|||
Notifications: undefined
|
||||
Calendar: undefined
|
||||
Menu: undefined
|
||||
Classmates: undefined
|
||||
}
|
||||
|
||||
interface TabTitleProps {
|
||||
|
@ -43,6 +45,7 @@ const NewsScreen = () => <NewsList />
|
|||
const NotificationsScreen = () => <NotificationsList />
|
||||
const CalendarScreen = () => <Calendar />
|
||||
const MenuScreen = () => <Menu />
|
||||
const ClassmatesScreen = () => <Classmates />
|
||||
|
||||
const TabNavigator = ({
|
||||
initialRouteName = 'News',
|
||||
|
@ -67,6 +70,8 @@ const TabNavigator = ({
|
|||
iconName = focused ? 'calendar' : 'calendar-outline'
|
||||
else if (route.name === 'Menu')
|
||||
iconName = focused ? 'clipboard' : 'clipboard-outline'
|
||||
else if (route.name === 'Classmates')
|
||||
iconName = focused ? 'people' : 'people-outline'
|
||||
return <Icon name={iconName} fill={color} height={24} width={24} />
|
||||
},
|
||||
}
|
||||
|
@ -92,6 +97,11 @@ const TabNavigator = ({
|
|||
component={MenuScreen}
|
||||
options={{ title: translate('navigation.menu') }}
|
||||
/>
|
||||
<Screen
|
||||
name="Classmates"
|
||||
component={ClassmatesScreen}
|
||||
options={{ title: translate('navigation.classmates') }}
|
||||
/>
|
||||
</Navigator>
|
||||
)
|
||||
|
||||
|
@ -107,6 +117,8 @@ const getHeaderTitle = (route: any) => {
|
|||
return translate('navigation.calender')
|
||||
case 'Menu':
|
||||
return translate('navigation.menu')
|
||||
case 'Classmates':
|
||||
return translate('navigation.classmates')
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import { useNavigation } from '@react-navigation/native'
|
|||
import { StackNavigationProp } from '@react-navigation/stack'
|
||||
import {
|
||||
useCalendar,
|
||||
useClassmates,
|
||||
useMenu,
|
||||
useNews,
|
||||
useNotifications,
|
||||
|
@ -42,6 +43,7 @@ export const ChildListItem = ({ child, color }: ChildListItemProps) => {
|
|||
const navigation = useNavigation<ChildListItemNavigationProp>()
|
||||
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(
|
||||
|
@ -75,6 +77,16 @@ export const ChildListItem = ({ child, color }: ChildListItemProps) => {
|
|||
}
|
||||
|
||||
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 = {
|
||||
|
|
|
@ -1,25 +1,66 @@
|
|||
import { Card, Text } from '@ui-kitten/components'
|
||||
import React from 'react'
|
||||
import { View, StyleSheet } from 'react-native'
|
||||
import { StyleSheet, ListRenderItemInfo } from 'react-native'
|
||||
import {
|
||||
Divider,
|
||||
List,
|
||||
ListItem,
|
||||
Icon,
|
||||
IconProps,
|
||||
Text,
|
||||
} from '@ui-kitten/components'
|
||||
import { fullName, guardians, sortByFirstName } from '../utils/peopleHelpers'
|
||||
import { useChild } from './childContext.component'
|
||||
import { useClassmates } from '@skolplattformen/api-hooks'
|
||||
import { ContactMenu } from './contactMenu.component'
|
||||
import { Classmate } from '@skolplattformen/embedded-api'
|
||||
import { translate } from '../utils/translation'
|
||||
|
||||
interface ClassmatesProps {
|
||||
setSelected: (value?: number | null) => void
|
||||
}
|
||||
|
||||
export const Classmates = () => {
|
||||
const cardHeader = () => {
|
||||
return (
|
||||
<View style={styles.topContainer}>
|
||||
<Text category="h6">Klasslistan ej tillgänglig</Text>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
const child = useChild()
|
||||
|
||||
const { data } = useClassmates(child)
|
||||
const renderItemIcon = (props: IconProps) => (
|
||||
<Icon {...props} name="people-outline" />
|
||||
)
|
||||
const [selected, setSelected] = React.useState()
|
||||
const renderItem = ({ item, index }: ListRenderItemInfo<Classmate>) => (
|
||||
<ListItem
|
||||
accessibilityLabel={`${translate('classmates.child')} ${index + 1}`}
|
||||
accessibilityHint={`${translate(
|
||||
'classmates.contactsForGuardianFor'
|
||||
)} ${fullName(item)}`}
|
||||
title={fullName(item)}
|
||||
onPress={() => setSelected(item)}
|
||||
description={guardians(item.guardians)}
|
||||
accessoryLeft={renderItemIcon}
|
||||
accessoryRight={() => (
|
||||
<ContactMenu
|
||||
contact={item}
|
||||
selected={item === selected}
|
||||
setSelected={setSelected}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
)
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Card header={cardHeader} style={styles.contentContainer}>
|
||||
<Text>
|
||||
Klasslista kan tyvärr inte visas längre. Vi jobbar på att lösa det,
|
||||
och återkommer med information när vi vet mer.
|
||||
<List
|
||||
style={styles.container}
|
||||
data={sortByFirstName(data)}
|
||||
ItemSeparatorComponent={Divider}
|
||||
ListHeaderComponent={
|
||||
<Text category="h5" style={styles.listHeader}>
|
||||
{data?.length
|
||||
? `${translate('classmates.class')} ${data[0].className}`
|
||||
: translate('classmates.class')}
|
||||
</Text>
|
||||
</Card>
|
||||
</View>
|
||||
}
|
||||
renderItem={renderItem}
|
||||
contentContainerStyle={styles.contentContainer}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -38,7 +79,6 @@ const styles = StyleSheet.create({
|
|||
justifyContent: 'space-between',
|
||||
},
|
||||
listHeader: {
|
||||
backgroundColor: '#fff',
|
||||
paddingTop: 10,
|
||||
paddingLeft: 15,
|
||||
},
|
||||
|
|
|
@ -77,34 +77,34 @@ export const ContactMenu = ({
|
|||
>
|
||||
<MenuItem
|
||||
testID="CallMenuItem"
|
||||
accessibilityLabel="Ring"
|
||||
accessibilityLabel={translate('contact.call')}
|
||||
accessoryLeft={CallIcon}
|
||||
style={{ display: shouldDisplay(mobile) }}
|
||||
title="Ring"
|
||||
title={translate('contact.call')}
|
||||
onPress={() => Linking.openURL(`tel:${mobile}`)}
|
||||
/>
|
||||
<MenuItem
|
||||
testID="SMSMenuItem"
|
||||
accessibilityLabel="SMS"
|
||||
accessibilityLabel={translate('contact.sms')}
|
||||
accessoryLeft={SMSIcon}
|
||||
style={{ display: shouldDisplay(mobile) }}
|
||||
title="SMS"
|
||||
title={translate('contact.sms')}
|
||||
onPress={() => Linking.openURL(`sms:${mobile}`)}
|
||||
/>
|
||||
<MenuItem
|
||||
testID="SendEmailMenuItem"
|
||||
accessibilityLabel="Maila"
|
||||
accessibilityLabel={translate('contact.email')}
|
||||
accessoryLeft={EmailIcon}
|
||||
style={{ display: shouldDisplay(email) }}
|
||||
title="Maila"
|
||||
title={translate('contact.email')}
|
||||
onPress={() => Linking.openURL(`mailto:${email}`)}
|
||||
/>
|
||||
<MenuItem
|
||||
testID="ShowHomeMenuItem"
|
||||
accessibilityLabel="Hem"
|
||||
accessibilityLabel={translate('contact.home')}
|
||||
accessoryLeft={MapIcon}
|
||||
style={{ display: shouldDisplay(address) }}
|
||||
title="Hem"
|
||||
title={translate('contact.home')}
|
||||
onPress={() =>
|
||||
Linking.openURL(`http://maps.apple.com/?daddr=${address}`)
|
||||
}
|
||||
|
|
|
@ -90,7 +90,8 @@
|
|||
"calender": "Calendar",
|
||||
"menu": "Menu",
|
||||
"news": "News",
|
||||
"notifications": "Notifications"
|
||||
"notifications": "Notifications",
|
||||
"classmates": "Classmates"
|
||||
},
|
||||
"news": {
|
||||
"backToChild": "Back to child",
|
||||
|
@ -112,7 +113,17 @@
|
|||
"lunch": "Lunch",
|
||||
"gymBag": "Gym bag"
|
||||
},
|
||||
"classmates": {
|
||||
"class": "Class",
|
||||
"child": "Child",
|
||||
"contactsForGuardiansFor": "Contact information for guardians for"
|
||||
},
|
||||
"contact": {
|
||||
"a11y_show_contact_info_button_hint": "Show contact info"
|
||||
"a11y_show_contact_info_button_hint": "Shows contact information",
|
||||
"a11y_show_contact_info_button_label": "Show contant information",
|
||||
"call": "Call",
|
||||
"sms": "SMS",
|
||||
"email": "E-mail",
|
||||
"home": "Home"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,7 +90,8 @@
|
|||
"calender": "Kalender",
|
||||
"menu": "Matsedel",
|
||||
"news": "Nyheter",
|
||||
"notifications": "Aviseringar"
|
||||
"notifications": "Aviseringar",
|
||||
"classmates": "Klassen"
|
||||
},
|
||||
"news": {
|
||||
"backToChild": "Tillbaka till barn",
|
||||
|
@ -112,7 +113,17 @@
|
|||
"lunch": "Lunch",
|
||||
"gymBag": "Gympapåse"
|
||||
},
|
||||
"classmates": {
|
||||
"class": "Klass",
|
||||
"child": "Barn",
|
||||
"contactsForGuardiansFor": "Kontaktuppgifter för vårdnadshavare till"
|
||||
},
|
||||
"contact": {
|
||||
"a11y_show_contact_info_button_hint": "Visa kontaktinfo"
|
||||
"a11y_show_contact_info_button_hint": "Visar kontaktinformation",
|
||||
"a11y_show_contact_info_button_label": "Visa kontaktinformation",
|
||||
"call": "Ring",
|
||||
"sms": "SMS",
|
||||
"email": "Maila",
|
||||
"home": "Hem"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue