Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: sort list of children #151

Merged
merged 4 commits into from
Feb 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions packages/app/components/__tests__/Classmates.test.js
Original file line number Diff line number Diff line change
@@ -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()
})
4 changes: 2 additions & 2 deletions packages/app/components/absence.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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}>
Expand Down
9 changes: 3 additions & 6 deletions packages/app/components/child.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down Expand Up @@ -72,12 +72,9 @@ const CalendarScreen = () => {
}

const ClassmatesScreen = () => {
const child = useChild()
const { data: classmates } = useClassmates(child)

return (
<Layout>
<Classmates classmates={classmates} />
<Classmates />
</Layout>
)
}
Expand Down Expand Up @@ -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}
Expand Down
4 changes: 2 additions & 2 deletions packages/app/components/childListItem.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -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" />
Expand Down Expand Up @@ -62,7 +62,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>
Expand Down
25 changes: 9 additions & 16 deletions packages/app/components/classmates.component.js
Original file line number Diff line number Diff line change
@@ -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({
Expand All @@ -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}
Expand Down
15 changes: 0 additions & 15 deletions packages/app/utils/__tests__/childHelpers.test.js

This file was deleted.

74 changes: 74 additions & 0 deletions packages/app/utils/__tests__/peopleHelpers.test.js
Original file line number Diff line number Diff line change
@@ -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 change: 0 additions & 1 deletion packages/app/utils/childHelpers.js

This file was deleted.

9 changes: 9 additions & 0 deletions packages/app/utils/peopleHelpers.js
Original file line number Diff line number Diff line change
@@ -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}`