chore: sort list of children (#151)
* chore: sort list of children * fix: sortera klasskompisar * chore: ta bort classmates ur child De hämtas med en hook i classmates vyn * chore: uppdatera namnhelpers Co-authored-by: Rickard Natt och Dag <rickard@hey.com>
This commit is contained in:
parent
a191b450c0
commit
f0f61217d9
|
@ -0,0 +1,87 @@
|
|||
import { useClassmates } from '@skolplattformen/api-hooks'
|
||||
import React from 'react'
|
||||
import { render } from '../../utils/testHelpers'
|
||||
import { ChildProvider } from '../childContext.component'
|
||||
import { Classmates } from '../classmates.component'
|
||||
|
||||
jest.mock('@react-navigation/native')
|
||||
jest.mock('@skolplattformen/api-hooks')
|
||||
|
||||
const defaultClassmates = [
|
||||
{
|
||||
className: '2B',
|
||||
firstname: 'Tyrell',
|
||||
lastname: 'Eriksson',
|
||||
guardians: [
|
||||
{
|
||||
firstname: 'Margaery',
|
||||
lastname: 'Eriksson',
|
||||
},
|
||||
{
|
||||
firstname: 'Loras',
|
||||
lastname: 'Eriksson',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
className: '2B',
|
||||
firstname: 'Adam',
|
||||
lastname: 'Svensson',
|
||||
guardians: [
|
||||
{
|
||||
firstname: 'Eva',
|
||||
lastname: 'Svensson',
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
const setup = ({ classmates } = { classmates: defaultClassmates }) => {
|
||||
useClassmates.mockReturnValue({
|
||||
data: classmates,
|
||||
})
|
||||
|
||||
return render(
|
||||
<ChildProvider child={{ id: 1 }}>
|
||||
<Classmates />
|
||||
</ChildProvider>
|
||||
)
|
||||
}
|
||||
|
||||
test('gets the classmates for a child from context', () => {
|
||||
setup()
|
||||
|
||||
expect(useClassmates).toHaveBeenCalledWith({ id: 1 })
|
||||
})
|
||||
|
||||
test('renders class name', () => {
|
||||
const screen = setup()
|
||||
|
||||
expect(screen.getByText(/^klass 2b$/i)).toBeTruthy()
|
||||
})
|
||||
|
||||
test('renders class without name', () => {
|
||||
const screen = setup({
|
||||
classmates: [],
|
||||
})
|
||||
|
||||
expect(screen.getByText(/^klass$/i)).toBeTruthy()
|
||||
})
|
||||
|
||||
test('renders classmates sorted by first name', () => {
|
||||
const screen = setup()
|
||||
|
||||
expect(screen.getByLabelText('Barn 1')).toContainElement(
|
||||
screen.getByText(/adam svensson/i)
|
||||
)
|
||||
expect(screen.getByLabelText('Barn 2')).toContainElement(
|
||||
screen.getByText(/tyrell eriksson/i)
|
||||
)
|
||||
})
|
||||
|
||||
test('renders guardians sorted by first name', () => {
|
||||
const screen = setup()
|
||||
|
||||
expect(screen.getByText(/eva svensson/i)).toBeTruthy()
|
||||
expect(screen.getByText(/^loras eriksson, margaery eriksson$/i)).toBeTruthy()
|
||||
})
|
|
@ -19,7 +19,7 @@ import Personnummer from 'personnummer'
|
|||
import AsyncStorage from '@react-native-async-storage/async-storage'
|
||||
import DateTimePickerModal from 'react-native-modal-datetime-picker'
|
||||
import moment from 'moment'
|
||||
import { childName } from '../utils/childHelpers'
|
||||
import { studentName } from '../utils/peopleHelpers'
|
||||
|
||||
const AbsenceSchema = Yup.object().shape({
|
||||
socialSecurityNumber: Yup.string()
|
||||
|
@ -65,7 +65,7 @@ const Absence = ({ route, navigation }) => {
|
|||
alignment="center"
|
||||
style={styles.topBar}
|
||||
title="Anmäl frånvaro"
|
||||
subtitle={childName(child.name)}
|
||||
subtitle={studentName(child.name)}
|
||||
/>
|
||||
<Divider />
|
||||
<Layout style={styles.wrap}>
|
||||
|
|
|
@ -24,7 +24,7 @@ import { ChildProvider, useChild } from './childContext.component'
|
|||
import { Classmates } from './classmates.component'
|
||||
import { NewsList } from './newsList.component'
|
||||
import { NotificationsList } from './notificationsList.component'
|
||||
import { childName } from '../utils/childHelpers'
|
||||
import { studentName } from '../utils/peopleHelpers'
|
||||
|
||||
const { Navigator, Screen } = createBottomTabNavigator()
|
||||
|
||||
|
@ -72,12 +72,9 @@ const CalendarScreen = () => {
|
|||
}
|
||||
|
||||
const ClassmatesScreen = () => {
|
||||
const child = useChild()
|
||||
const { data: classmates } = useClassmates(child)
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<Classmates classmates={classmates} />
|
||||
<Classmates />
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
@ -148,7 +145,7 @@ export const Child = ({ route, navigation }) => {
|
|||
<SafeAreaView style={{ ...styles.wrap, color }}>
|
||||
<ChildProvider child={child}>
|
||||
<TopNavigation
|
||||
title={childName(child.name)}
|
||||
title={studentName(child.name)}
|
||||
alignment="center"
|
||||
accessoryLeft={BackAction}
|
||||
style={styles.topBar}
|
||||
|
|
|
@ -10,7 +10,7 @@ import { DateTime } from 'luxon'
|
|||
import moment from 'moment'
|
||||
import React, { useEffect } from 'react'
|
||||
import { StyleSheet, View } from 'react-native'
|
||||
import { childName } from '../utils/childHelpers'
|
||||
import { studentName } from '../utils/peopleHelpers'
|
||||
|
||||
const NotificationsIcon = (props) => (
|
||||
<Icon {...props} name="alert-circle-outline" />
|
||||
|
@ -71,7 +71,7 @@ export const ChildListItem = ({ navigation, child, color }) => {
|
|||
<Avatar source={require('../assets/avatar.png')} shape="square" />
|
||||
</View>
|
||||
<View style={{ margin: 20, flex: 1 }}>
|
||||
<Text category="h6">{childName(child.name)}</Text>
|
||||
<Text category="h6">{studentName(child.name)}</Text>
|
||||
<Text category="s1">{`${getClassName()}`}</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
|
|
@ -1,30 +1,24 @@
|
|||
import { useClassmates } from '@skolplattformen/api-hooks'
|
||||
import { Divider, Icon, List, ListItem, Text } from '@ui-kitten/components'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import React, { useState } from 'react'
|
||||
import { StyleSheet } from 'react-native'
|
||||
import { useChild } from './childContext.component'
|
||||
import { ContactMenu } from './contactMenu.component'
|
||||
import { fullName, guardians, sortByFirstName } from '../utils/peopleHelpers'
|
||||
|
||||
export const Classmates = () => {
|
||||
const child = useChild()
|
||||
const { data, status, reload } = useClassmates(child)
|
||||
const [refreshing, setRefreshing] = useState(status === 'loading')
|
||||
useEffect(() => {
|
||||
setRefreshing(status === 'loading')
|
||||
}, [status])
|
||||
|
||||
const refresh = () => reload()
|
||||
const { data } = useClassmates(child)
|
||||
|
||||
const renderItemIcon = (props) => <Icon {...props} name="people-outline" />
|
||||
const [selected, setSelected] = useState()
|
||||
|
||||
const renderItem = ({ item }) => (
|
||||
const renderItem = ({ item, index }) => (
|
||||
<ListItem
|
||||
title={`${item.firstname} ${item.lastname}`}
|
||||
accessibilityLabel={`Barn ${index + 1}`}
|
||||
title={fullName(item)}
|
||||
onPress={() => setSelected(item)}
|
||||
description={item.guardians
|
||||
.map((guardian) => `${guardian.firstname} ${guardian.lastname}`)
|
||||
.join(', ')}
|
||||
description={guardians(item.guardians)}
|
||||
accessoryLeft={renderItemIcon}
|
||||
accessoryRight={(props) =>
|
||||
ContactMenu({
|
||||
|
@ -39,13 +33,12 @@ export const Classmates = () => {
|
|||
|
||||
return (
|
||||
<List
|
||||
refreshing={refreshing}
|
||||
style={styles.container}
|
||||
data={data}
|
||||
data={sortByFirstName(data)}
|
||||
ItemSeparatorComponent={Divider}
|
||||
ListHeaderComponent={
|
||||
<Text category="h5" style={styles.listHeader}>
|
||||
Klass {data?.length ? data[0].className : ''}
|
||||
{data?.length ? `Klass ${data[0].className}` : 'Klass'}
|
||||
</Text>
|
||||
}
|
||||
renderItem={renderItem}
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
import { childName } from '../childHelpers'
|
||||
|
||||
describe('#childName', () => {
|
||||
test('should remove student from name', () => {
|
||||
expect(childName('Alan Nilsson (elev)')).toEqual('Alan Nilsson')
|
||||
})
|
||||
|
||||
test('should remove student without spacing from name', () => {
|
||||
expect(childName('Alan Nilsson(elev)')).toEqual('Alan Nilsson')
|
||||
})
|
||||
|
||||
test('handles undefined name', () => {
|
||||
expect(childName(undefined)).toBeUndefined()
|
||||
})
|
||||
})
|
|
@ -0,0 +1,74 @@
|
|||
import {
|
||||
fullName,
|
||||
guardians,
|
||||
sortByFirstName,
|
||||
studentName,
|
||||
} from '../peopleHelpers'
|
||||
|
||||
describe('#studentName', () => {
|
||||
test('should remove student from name', () => {
|
||||
expect(studentName('Alan Nilsson (elev)')).toEqual('Alan Nilsson')
|
||||
})
|
||||
|
||||
test('should remove student without spacing from name', () => {
|
||||
expect(studentName('Alan Nilsson(elev)')).toEqual('Alan Nilsson')
|
||||
})
|
||||
|
||||
test('handles undefined name', () => {
|
||||
expect(studentName(undefined)).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe('#fullName', () => {
|
||||
test('should', () => {
|
||||
expect(
|
||||
fullName({
|
||||
firstname: 'Margaery',
|
||||
lastname: 'Eriksson',
|
||||
})
|
||||
).toEqual('Margaery Eriksson')
|
||||
})
|
||||
})
|
||||
|
||||
describe('#sortByFirstName', () => {
|
||||
test('sort arrays by first name', () => {
|
||||
expect(
|
||||
sortByFirstName([
|
||||
{
|
||||
firstname: 'Margaery',
|
||||
lastname: 'Eriksson',
|
||||
},
|
||||
{
|
||||
firstname: 'Loras',
|
||||
lastname: 'Eriksson',
|
||||
},
|
||||
])
|
||||
).toEqual([
|
||||
{
|
||||
firstname: 'Loras',
|
||||
lastname: 'Eriksson',
|
||||
},
|
||||
{
|
||||
firstname: 'Margaery',
|
||||
lastname: 'Eriksson',
|
||||
},
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
describe('#guardians', () => {
|
||||
test('should join a list of guardians sorted by firstname', () => {
|
||||
expect(
|
||||
guardians([
|
||||
{
|
||||
firstname: 'Margaery',
|
||||
lastname: 'Eriksson',
|
||||
},
|
||||
{
|
||||
firstname: 'Loras',
|
||||
lastname: 'Eriksson',
|
||||
},
|
||||
])
|
||||
).toEqual('Loras Eriksson, Margaery Eriksson')
|
||||
})
|
||||
})
|
|
@ -1 +0,0 @@
|
|||
export const childName = (name) => name?.replace(/\s?\(\w+\)$/, '')
|
|
@ -0,0 +1,9 @@
|
|||
export const studentName = (name) => name?.replace(/\s?\(\w+\)$/, '')
|
||||
|
||||
export const sortByFirstName = (data) =>
|
||||
data.sort((a, b) => a.firstname.localeCompare(b.firstname))
|
||||
|
||||
export const guardians = (data) =>
|
||||
sortByFirstName(data).map(fullName).join(', ')
|
||||
|
||||
export const fullName = (person) => `${person.firstname} ${person.lastname}`
|
Loading…
Reference in New Issue