diff --git a/CHANGELOG.md b/CHANGELOG.md index 2be3a594..8f2a658b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,107 @@ +## [2.10.2](https://github.com/kolplattformen/skolplattformen/compare/v2.10.1...v2.10.2) (2021-12-11) + + +### Bug Fixes + +* 🐛 adjust fakeData lessons offset in ht ([#598](https://github.com/kolplattformen/skolplattformen/issues/598)) ([3f69bc8](https://github.com/kolplattformen/skolplattformen/commit/3f69bc89aaa7eb1cf4ade789551667b960ff8825)) + +## [2.10.1](https://github.com/kolplattformen/skolplattformen/compare/v2.10.0...v2.10.1) (2021-12-10) + + +### Bug Fixes + +* 🐛 scroll in timetable ([#597](https://github.com/kolplattformen/skolplattformen/issues/597)) ([f844a3c](https://github.com/kolplattformen/skolplattformen/commit/f844a3cdd4ea26b6a4b76e4236debec7e6e83986)) + +# [2.10.0](https://github.com/kolplattformen/skolplattformen/compare/v2.9.1...v2.10.0) (2021-12-10) + + +### Features + +* 🎾 Ämnesnamn syns nu i schemat i HjĂ€rntorget. ([#596](https://github.com/kolplattformen/skolplattformen/issues/596)) ([14ff985](https://github.com/kolplattformen/skolplattformen/commit/14ff985b0c7a0c9ab9c8547679caff66c7b5aa1f)) + +## [2.9.1](https://github.com/kolplattformen/skolplattformen/compare/v2.9.0...v2.9.1) (2021-12-10) + + +### Bug Fixes + +* 🐛 Felaktig sortering av lektioner ([#595](https://github.com/kolplattformen/skolplattformen/issues/595)) ([ed3a27b](https://github.com/kolplattformen/skolplattformen/commit/ed3a27bba185b39fd8581b639ac7efc03b050d6e)), closes [#591](https://github.com/kolplattformen/skolplattformen/issues/591) + +# [2.9.0](https://github.com/kolplattformen/skolplattformen/compare/v2.8.0...v2.9.0) (2021-12-10) + + +### Features + +* 🎾 HĂ€mta lĂ€rare och skolkontakter frĂ„n api-skolplattfomen och visa lĂ€rarens namn i schemat ([#589](https://github.com/kolplattformen/skolplattformen/issues/589)) ([b7dbd35](https://github.com/kolplattformen/skolplattformen/commit/b7dbd356c652bf53a9d73dd38f11744ff364470b)) + +# [2.8.0](https://github.com/kolplattformen/skolplattformen/compare/v2.7.3...v2.8.0) (2021-12-08) + + +### Bug Fixes + +* 🐛 Ingen text syns i dark mode nĂ€r inga barn hittas ([bce1165](https://github.com/kolplattformen/skolplattformen/commit/bce1165f300749502351fe28ee8f0c5f3ce7ee3c)), closes [#571](https://github.com/kolplattformen/skolplattformen/issues/571) + + +### Features + +* 🎾 bumped to 3.0.2 for new version releasea ([2af189e](https://github.com/kolplattformen/skolplattformen/commit/2af189ef0fb23723dae982382bee169e2c7ed8f6)) + +## [2.7.3](https://github.com/kolplattformen/skolplattformen/compare/v2.7.2...v2.7.3) (2021-12-07) + + +### Bug Fixes + +* 🐛 Store childs personalIdNumbers in settings ([cc3fd86](https://github.com/kolplattformen/skolplattformen/commit/cc3fd8670c37be2b5f3e9f642bb3b1882350e2f6)) + +## [2.7.2](https://github.com/kolplattformen/skolplattformen/compare/v2.7.1...v2.7.2) (2021-12-06) + + +### Bug Fixes + +* 🐛 Add missing translations for calendar ([7ada994](https://github.com/kolplattformen/skolplattformen/commit/7ada9945dfc7dd5766cd7a3208d62cf4c1a2659f)) + +## [2.7.1](https://github.com/kolplattformen/skolplattformen/compare/v2.7.0...v2.7.1) (2021-12-06) + + +### Bug Fixes + +* 🐛 Add translation to week ([cfa39de](https://github.com/kolplattformen/skolplattformen/commit/cfa39de3934e2386d90f37ad2c3dc830106e175a)) + +# [2.7.0](https://github.com/kolplattformen/skolplattformen/compare/v2.6.0...v2.7.0) (2021-12-06) + + +### Features + +* 🎾 Add week number and calendar dates to timetable ([6fbbcc8](https://github.com/kolplattformen/skolplattformen/commit/6fbbcc803e92e288904be1ffba5e380bd9523100)) + +# [2.6.0](https://github.com/kolplattformen/skolplattformen/compare/v2.5.1...v2.6.0) (2021-12-04) + + +### Features + +* Frontpage date tweaks ([#582](https://github.com/kolplattformen/skolplattformen/issues/582)) ([66e7811](https://github.com/kolplattformen/skolplattformen/commit/66e7811b83e96f9fb83aa82cb34736f38a3bf16a)) + +## [2.5.1](https://github.com/kolplattformen/skolplattformen/compare/v2.5.0...v2.5.1) (2021-12-03) + + +### Bug Fixes + +* 🐛 Show the weekday on startpage if not today ([df28066](https://github.com/kolplattformen/skolplattformen/commit/df2806648ab6b573d277a338f76fb199cdd307a2)) + +# [2.5.0](https://github.com/kolplattformen/skolplattformen/compare/v2.4.0...v2.5.0) (2021-12-03) + + +### Features + +* 🎾 Skip to the next day in calendar ([#425](https://github.com/kolplattformen/skolplattformen/issues/425)) ([fce1d98](https://github.com/kolplattformen/skolplattformen/commit/fce1d98847f4cc7c27bfa359b1d2b1bdc86e12ea)) + +# [2.4.0](https://github.com/kolplattformen/skolplattformen/compare/v2.3.2...v2.4.0) (2021-12-02) + + +### Features + +* 🎾 Clear personal cache on login and logout ([#572](https://github.com/kolplattformen/skolplattformen/issues/572)) ([bf29ab5](https://github.com/kolplattformen/skolplattformen/commit/bf29ab58edd13db62b34f873a3429d319c0e7297)) +* 🎾 Fix image load and typescript errors ([#570](https://github.com/kolplattformen/skolplattformen/issues/570)) ([933a884](https://github.com/kolplattformen/skolplattformen/commit/933a8840a3ebd049711a000ca6faf3e534f77ace)) + ## [2.3.2](https://github.com/kolplattformen/skolplattformen/compare/v2.3.1...v2.3.2) (2021-12-01) diff --git a/apps/api-test-app/src/main.js b/apps/api-test-app/src/main.js index 24f282b6..6bd0599d 100644 --- a/apps/api-test-app/src/main.js +++ b/apps/api-test-app/src/main.js @@ -14,9 +14,13 @@ const path = require('path') const fs = require('fs') const HttpProxyAgent = require('https-proxy-agent') const agentWrapper = require('./app/agentFetchWrapper') -const init = require('@skolplattformen/api-skolplattformen').default +const initSkolplattformen = require('@skolplattformen/api-skolplattformen').default +const initHjarntorget = require('@skolplattformen/api-hjarntorget').default + +const [, , personalNumber, platform] = process.argv +const isHjarntorget = platform && platform.startsWith('hj') +const init = isHjarntorget ? initHjarntorget : initSkolplattformen; -const [, , personalNumber] = process.argv process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0' const cookieJar = new CookieJar() let bankIdUsed = false @@ -136,10 +140,9 @@ async function Login(api) { try { console.log('Attempt to use saved session cookie to login') const rawContent = await readFile(`${recordFolder}/latestSessionCookie.txt`) - const sessionCookie = JSON.parse(rawContent) - - await api.setSessionCookie(`${sessionCookie.key}=${sessionCookie.value}`) - + const sessionCookies = JSON.parse(rawContent) + await api.setSessionCookie(`${sessionCookies[0].key}=${sessionCookies[0].value}`) + useBankId = false console.log('Login with old cookie succeeded') } catch (error) { @@ -177,10 +180,12 @@ function ensureDirectoryExistence(filePath) { fs.mkdirSync(dirname) } + function getSessionCookieFromCookieJar() { - const cookies = cookieJar.getCookiesSync('https://etjanst.stockholm.se') - const sessionCookie = cookies.find((c) => c.key === 'SMSESSION') - return sessionCookie + const cookieUrl = isHjarntorget ? 'https://hjarntorget.goteborg.se' : 'https://etjanst.stockholm.se' + const cookies = cookieJar.getCookiesSync(cookieUrl) + const sessionCookieKey = isHjarntorget ? 'JSESSIONID' : 'SMSESSION' + return cookies.find(c => c.key === sessionCookieKey) } const record = async (info, data) => { diff --git a/apps/skolplattformen-app/.eslintrc.json b/apps/skolplattformen-app/.eslintrc.json index 952b9695..a7fd39f6 100644 --- a/apps/skolplattformen-app/.eslintrc.json +++ b/apps/skolplattformen-app/.eslintrc.json @@ -9,7 +9,7 @@ "overrides": [ { "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], - "rules": {} + "rules": {"no-console":"warn"} }, { "files": ["*.ts", "*.tsx"], diff --git a/apps/skolplattformen-app/App.tsx b/apps/skolplattformen-app/App.tsx index 4b278c6c..df692246 100644 --- a/apps/skolplattformen-app/App.tsx +++ b/apps/skolplattformen-app/App.tsx @@ -19,13 +19,16 @@ import { translations } from './utils/translation' const reporter: Reporter | undefined = __DEV__ ? { log: (message: string) => console.log(message), - error: (error: Error, label?: string) => console.error(label, error), + error: (error: Error, label?: string) => console.log(label, error), } : undefined if (__DEV__) { // eslint-disable-next-line @typescript-eslint/no-var-requires const DevMenu = require('react-native-dev-menu') + DevMenu.addItem('Clear AsyncStorage from all contents', () => + AsyncStorage.clear().then(() => logAsyncStorage()) + ) DevMenu.addItem('Log AsyncStorage contents', () => logAsyncStorage()) } diff --git a/apps/skolplattformen-app/android/app/build.gradle b/apps/skolplattformen-app/android/app/build.gradle index aba58281..cfd8984d 100644 --- a/apps/skolplattformen-app/android/app/build.gradle +++ b/apps/skolplattformen-app/android/app/build.gradle @@ -134,7 +134,7 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode 20000 - versionName "3.0.1" + versionName "3.0.3" } splits { abi { diff --git a/apps/skolplattformen-app/components/absence.component.tsx b/apps/skolplattformen-app/components/absence.component.tsx index 4009b5f9..755ad819 100644 --- a/apps/skolplattformen-app/components/absence.component.tsx +++ b/apps/skolplattformen-app/components/absence.component.tsx @@ -18,6 +18,7 @@ import { NativeStackNavigationOptions } from 'react-native-screens/native-stack' import * as Yup from 'yup' import { defaultStackStyling } from '../design/navigationThemes' import usePersonalStorage from '../hooks/usePersonalStorage' +import useSettingsStorage from '../hooks/useSettingsStorage' import { Layout as LayoutStyle, Sizing, Typography } from '../styles' import { studentName } from '../utils/peopleHelpers' import { useSMS } from '../utils/SMS' @@ -70,12 +71,11 @@ const Absence = () => { const route = useRoute() const { sendSMS } = useSMS() const { child } = route.params - const [personalIdFromStorage, setPersonalIdInStorage] = usePersonalStorage( - user, - `@childssn.${child.id}`, - '' - ) const [personalIdentityNumber, setPersonalIdentityNumber] = React.useState('') + const [personalIdsFromStorage, setPersonalIdInStorage] = useSettingsStorage( + 'childPersonalIdentityNumber' + ) + const personalIdKey = `@childPersonalIdNumber.${child.id}` const minumumDate = moment().hours(8).minute(0) const maximumDate = moment().hours(17).minute(0) const styles = useStyleSheet(themedStyles) @@ -96,15 +96,19 @@ const Absence = () => { ) } - setPersonalIdInStorage(values.personalIdentityNumber) - setPersonalIdentityNumber(values.personalIdentityNumber) + const toStore = { + ...personalIdsFromStorage, + ...{ [personalIdKey]: personalIdNumber }, + } + setPersonalIdInStorage(toStore) }, - [sendSMS, setPersonalIdInStorage] + [personalIdKey, personalIdsFromStorage, sendSMS, setPersonalIdInStorage] ) React.useEffect(() => { + const personalIdFromStorage = personalIdsFromStorage[personalIdKey] || '' setPersonalIdentityNumber(personalIdFromStorage || '') - }, [child, personalIdFromStorage, user]) + }, [child, personalIdKey, personalIdsFromStorage, user]) const initialValues: AbsenceFormValues = { displayStartTimePicker: false, diff --git a/apps/skolplattformen-app/components/calendar.component.tsx b/apps/skolplattformen-app/components/calendar.component.tsx index b3c5f147..25c9b6d1 100644 --- a/apps/skolplattformen-app/components/calendar.component.tsx +++ b/apps/skolplattformen-app/components/calendar.component.tsx @@ -1,5 +1,5 @@ -import { CalendarItem } from '@skolplattformen/api-skolplattformen' import { useCalendar } from '@skolplattformen/hooks' +import { CalendarItem } from '@skolplattformen/api' import { Divider, List, @@ -10,8 +10,9 @@ import { } from '@ui-kitten/components' import moment from 'moment' import React from 'react' -import { ListRenderItemInfo, View } from 'react-native' -import { Typography } from '../styles' +import { ListRenderItemInfo, RefreshControl, View } from 'react-native' +import { Layout as LayoutStyle, Sizing, Typography } from '../styles' +import { translate } from '../utils/translation' import { useChild } from './childContext.component' import { CalendarOutlineIcon } from './icon.component' import { SaveToCalendar } from './saveToCalendar.component' @@ -19,7 +20,7 @@ import { Week } from './week.component' export const Calendar = () => { const child = useChild() - const { data } = useCalendar(child) + const { data, status, reload } = useCalendar(child) const styles = useStyleSheet(themedStyles) const formatStartDate = (startDate: moment.MomentInput) => { @@ -28,37 +29,55 @@ export const Calendar = () => { 'll' )} ‱ ${date.fromNow()}` - // Hack to remove yarn if it is this year + // Hack to remove year if it is this year const currentYear = moment().year().toString(10) return output.replace(currentYear, '') } + const sortedData = () => { + if (!data) return [] + + return data.sort((a, b) => + a.startDate && b.startDate ? a.startDate.localeCompare(b.startDate) : 0 + ) + } + return ( - {data && data.length > 0 && ( - - a.startDate && b.startDate - ? a.startDate.localeCompare(b.startDate) - : 0 - )} - ItemSeparatorComponent={Divider} - renderItem={({ item }: ListRenderItemInfo) => ( - ( - - {formatStartDate(item.startDate)} - - )} - accessoryLeft={CalendarOutlineIcon} - accessoryRight={() => } - /> - )} - /> - )} + + + {translate('calender.emptyHeadline')} + + + {translate('calender.emptyText')} + + + } + renderItem={({ item }: ListRenderItemInfo) => ( + ( + + {formatStartDate(item.startDate)} + + )} + accessoryLeft={CalendarOutlineIcon} + accessoryRight={() => } + /> + )} + refreshControl={ + + } + /> ) } @@ -73,4 +92,18 @@ const themedStyles = StyleService.create({ ...Typography.fontSize.xs, color: 'text-hint-color', }, + emptyState: { + ...LayoutStyle.center, + ...LayoutStyle.flex.full, + }, + emptyStateHeadline: { + ...Typography.align.center, + margin: Sizing.t4, + }, + emptyStateDescription: { + ...Typography.align.center, + lineHeight: 21, + paddingHorizontal: Sizing.t3, + margin: Sizing.t4, + }, }) diff --git a/apps/skolplattformen-app/components/childContext.component.tsx b/apps/skolplattformen-app/components/childContext.component.tsx index 555c4852..d4bbc51b 100644 --- a/apps/skolplattformen-app/components/childContext.component.tsx +++ b/apps/skolplattformen-app/components/childContext.component.tsx @@ -1,4 +1,4 @@ -import { Child } from '@skolplattformen/api-skolplattformen' +import { Child } from '@skolplattformen/api' import React, { createContext, useContext } from 'react' interface ChildProviderProps { diff --git a/apps/skolplattformen-app/components/childListItem.component.tsx b/apps/skolplattformen-app/components/childListItem.component.tsx index bac10817..8ca199f5 100644 --- a/apps/skolplattformen-app/components/childListItem.component.tsx +++ b/apps/skolplattformen-app/components/childListItem.component.tsx @@ -1,7 +1,7 @@ /* 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 { Child } from '@skolplattformen/api' import { useCalendar, useClassmates, @@ -16,11 +16,12 @@ import { Text, useStyleSheet, } from '@ui-kitten/components' -import moment from 'moment' -import React from 'react' +import moment, { Moment } from 'moment' +import React, { useEffect } from 'react' import { TouchableOpacity, useColorScheme, View } from 'react-native' import { useTranslation } from '../hooks/useTranslation' import { Colors, Layout, Sizing } from '../styles' +import { getMeaningfulStartingDate } from '../utils/calendarHelpers' import { studentName } from '../utils/peopleHelpers' import { DaySummary } from './daySummary.component' import { AlertIcon, RightArrowIcon } from './icon.component' @@ -30,13 +31,20 @@ import { StudentAvatar } from './studentAvatar.component' interface ChildListItemProps { child: Child color: string + updated: string + currentDate?: Moment } type ChildListItemNavigationProp = StackNavigationProp< RootStackParamList, 'Children' > -export const ChildListItem = ({ child, color }: ChildListItemProps) => { +export const ChildListItem = ({ + child, + color, + updated, + currentDate = moment(), +}: ChildListItemProps) => { // Forces rerender when child.id changes React.useEffect(() => { // noop @@ -44,17 +52,36 @@ export const ChildListItem = ({ child, color }: ChildListItemProps) => { 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( + const { data: notifications, reload: notificationsReload } = + useNotifications(child) + const { data: news, status: newsStatus, reload: newsReload } = useNews(child) + const { data: classmates, reload: classmatesReload } = useClassmates(child) + const { data: calendar, reload: calendarReload } = useCalendar(child) + const { data: menu, reload: menuReload } = useMenu(child) + const { data: schedule, reload: scheduleReload } = useSchedule( child, - moment().toISOString(), - moment().add(7, 'days').toISOString() + moment(currentDate).toISOString(), + moment(currentDate).add(7, 'days').toISOString() ) + useEffect(() => { + // Do not refresh if updated is empty (first render of component) + if (updated === '') return + + newsReload() + classmatesReload() + notificationsReload() + calendarReload() + menuReload() + scheduleReload() + + // Without eslint-disable below we get into a forever loop + // because the function pointers to reload functions change on every reload. + // I do not know a workaround for this. + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [updated]) + const notificationsThisWeek = notifications.filter( ({ dateCreated, dateModified }) => { const date = dateModified || dateCreated @@ -63,8 +90,8 @@ export const ChildListItem = ({ child, color }: ChildListItemProps) => { ) const newsThisWeek = news.filter(({ modified, published }) => { - const date = modified || published - return date ? moment(date).isSame(moment(), 'week') : false + const newsDate = modified || published + return newsDate ? moment(newsDate).isSame(currentDate, 'week') : false }) const scheduleAndCalendarThisWeek = [ @@ -73,14 +100,14 @@ export const ChildListItem = ({ child, color }: ChildListItemProps) => { ].filter(({ startDate }) => startDate ? moment(startDate).isBetween( - moment().startOf('day'), - moment().add(7, 'days') + moment(currentDate).startOf('day'), + moment(currentDate).add(7, 'days') ) : false ) - const displayDate = (date: moment.MomentInput) => { - return moment(date).fromNow() + const displayDate = (inputDate: moment.MomentInput) => { + return moment(inputDate).fromNow() } const getClassName = () => { @@ -118,6 +145,16 @@ export const ChildListItem = ({ child, color }: ChildListItemProps) => { const className = getClassName() const styles = useStyleSheet(themeStyles) const isDarkMode = useColorScheme() === 'dark' + const meaningfulStartingDate = getMeaningfulStartingDate(currentDate) + + // Hide menu if we want to show monday but it is not monday yet. + // The menu for next week is not available until monday + const shouldShowLunchMenu = + menu[meaningfulStartingDate.isoWeekday() - 1] && + !( + meaningfulStartingDate.isoWeekday() === 1 && + currentDate.isoWeekday() !== 1 + ) return ( { /> - + + + {scheduleAndCalendarThisWeek.slice(0, 3).map((calendarItem, i) => ( {`${calendarItem.title} (${displayDate(calendarItem.startDate)})`} ))} + {t('navigation.news')} @@ -156,11 +196,13 @@ export const ChildListItem = ({ child, color }: ChildListItemProps) => { {notification.message} ))} + {newsThisWeek.slice(0, 3).map((newsItem, i) => ( {newsItem.header ?? ''} ))} + {scheduleAndCalendarThisWeek.length || notificationsThisWeek.length || newsThisWeek.length ? null : ( @@ -168,16 +210,20 @@ export const ChildListItem = ({ child, color }: ChildListItemProps) => { {t('news.noNewNewsItemsThisWeek')} )} - - {!menu[moment().isoWeekday() - 1] ? null : ( + {shouldShowLunchMenu ? ( <> - {t('schedule.lunch')} + {meaningfulStartingDate.format( + '[' + t('schedule.lunch') + '] dddd' + )} + + + {menu[meaningfulStartingDate.isoWeekday() - 1]?.description} - {menu[moment().isoWeekday() - 1]?.description} - )} - + ) : null} + + - - - - - ) : ( - - - - {translate('general.loading')} - - - )} + + } + renderItem={({ item: child, index }: ListRenderItemInfo) => ( + + )} + /> + ) : ( + + + {status === 'error' ? ( + + {translate('children.loadingErrorHeading')} + + {translate('children.loadingErrorInformationText')} + + + + + + + + ) : ( + + + + {translate('general.loading')} + )} - + ) } @@ -187,7 +196,6 @@ const themedStyles = StyleService.create({ emptyState: { ...LayoutStyle.center, ...LayoutStyle.flex.full, - backgroundColor: Colors.neutral.white, paddingHorizontal: Sizing.t5, }, emptyStateDescription: { diff --git a/apps/skolplattformen-app/components/classmates.component.tsx b/apps/skolplattformen-app/components/classmates.component.tsx index 5d85dd58..8ae74d45 100644 --- a/apps/skolplattformen-app/components/classmates.component.tsx +++ b/apps/skolplattformen-app/components/classmates.component.tsx @@ -1,4 +1,4 @@ -import { Classmate } from '@skolplattformen/api-skolplattformen' +import { Classmate } from '@skolplattformen/api' import { useClassmates } from '@skolplattformen/hooks' import { Divider, @@ -9,7 +9,7 @@ import { Text, } from '@ui-kitten/components' import React from 'react' -import { ListRenderItemInfo, StyleSheet } from 'react-native' +import { ListRenderItemInfo, RefreshControl, StyleSheet } from 'react-native' import { fullName, guardians, sortByFirstName } from '../utils/peopleHelpers' import { translate } from '../utils/translation' import { useChild } from './childContext.component' @@ -22,7 +22,7 @@ interface ClassmatesProps { export const Classmates = () => { const child = useChild() - const { data } = useClassmates(child) + const { data, status, reload } = useClassmates(child) const renderItemIcon = (props: IconProps) => ( ) @@ -60,6 +60,9 @@ export const Classmates = () => { } renderItem={renderItem} contentContainerStyle={styles.contentContainer} + refreshControl={ + + } /> ) } diff --git a/apps/skolplattformen-app/components/contactMenu.component.tsx b/apps/skolplattformen-app/components/contactMenu.component.tsx index 3b287431..6421291a 100644 --- a/apps/skolplattformen-app/components/contactMenu.component.tsx +++ b/apps/skolplattformen-app/components/contactMenu.component.tsx @@ -1,5 +1,5 @@ /* eslint-disable react-native-a11y/has-accessibility-hint */ -import { Classmate } from '@skolplattformen/api-skolplattformen' +import { Classmate } from '@skolplattformen/api' import { Button, MenuGroup, diff --git a/apps/skolplattformen-app/components/daySummary.component.tsx b/apps/skolplattformen-app/components/daySummary.component.tsx index 592ac975..e7151c2c 100644 --- a/apps/skolplattformen-app/components/daySummary.component.tsx +++ b/apps/skolplattformen-app/components/daySummary.component.tsx @@ -1,8 +1,8 @@ -import { Child } from '@skolplattformen/api-skolplattformen' +import { Child } from '@skolplattformen/api' import { useTimetable } from '@skolplattformen/hooks' import { StyleService, Text, useStyleSheet } from '@ui-kitten/components' import moment, { Moment } from 'moment' -import React from 'react' +import React, { useCallback, useEffect, useState } from 'react' import { View } from 'react-native' import { LanguageService } from '../services/languageService' import { translate } from '../utils/translation' @@ -12,9 +12,17 @@ interface DaySummaryProps { date?: Moment } -export const DaySummary = ({ child, date = moment() }: DaySummaryProps) => { +const capitalizeFirstLetter = (string) => { + return string.charAt(0).toUpperCase() + string.slice(1) +} + +export const DaySummary = ({ + child, + date: currentDate = moment(), +}: DaySummaryProps) => { const styles = useStyleSheet(themedStyles) - const [year, week] = [moment().isoWeekYear(), moment().isoWeek()] + const [week, year] = [currentDate.isoWeek(), currentDate.isoWeekYear()] + const { data: weekLessons } = useTimetable( child, week, @@ -23,8 +31,8 @@ export const DaySummary = ({ child, date = moment() }: DaySummaryProps) => { ) const lessons = weekLessons - .filter((lesson) => lesson.dayOfWeek === date.isoWeekday()) - .sort((a, b) => a.dateStart.localeCompare(b.dateStart)) + .filter((lesson) => lesson.dayOfWeek === currentDate.isoWeekday()) + .sort((a, b) => a.timeStart.localeCompare(b.timeStart)) if (lessons.length <= 0) { return null @@ -34,6 +42,11 @@ export const DaySummary = ({ child, date = moment() }: DaySummaryProps) => { return ( + {moment().weekday() !== currentDate.weekday() ? ( + + {capitalizeFirstLetter(currentDate.format('dddd'))} + + ) : null} @@ -49,19 +62,27 @@ export const DaySummary = ({ child, date = moment() }: DaySummaryProps) => { {translate('schedule.end')} - {lessons[lessons.length - 1].timeEnd.slice(0, 5)} + {lessons + .sort((a, b) => a.timeEnd.localeCompare(b.timeEnd)) + [lessons.length - 1].timeEnd.slice(0, 5)} + + + + + + +   + + + {gymBag + ? ` đŸ€Œâ€â™€ïž ${translate('schedule.gymBag', { + defaultValue: 'GympapĂ„se', + })}` + : ''} - - - {gymBag - ? ` đŸ€Œâ€â™€ïž ${translate('schedule.gymBag', { - defaultValue: 'GympapĂ„se', - })}` - : ''} - ) } @@ -76,4 +97,11 @@ const themedStyles = StyleService.create({ label: { marginTop: 10, }, + heading: { + marginBottom: -10, + }, + weekday: { + marginBottom: -10, + padding: 0, + }, }) diff --git a/apps/skolplattformen-app/components/icon.component.tsx b/apps/skolplattformen-app/components/icon.component.tsx index e5780569..5e30dee5 100644 --- a/apps/skolplattformen-app/components/icon.component.tsx +++ b/apps/skolplattformen-app/components/icon.component.tsx @@ -32,3 +32,4 @@ export const ClipboardIcon = uiIcon('clipboard-outline') export const RightArrowIcon = uiIcon('arrow-ios-forward-outline') export const QuestionMarkIcon = uiIcon('question-mark') export const AwardIcon = uiIcon('award') +export const RefreshIcon = uiIcon('refresh') diff --git a/apps/skolplattformen-app/components/image.component.tsx b/apps/skolplattformen-app/components/image.component.tsx index 2b17b1eb..86595485 100644 --- a/apps/skolplattformen-app/components/image.component.tsx +++ b/apps/skolplattformen-app/components/image.component.tsx @@ -31,7 +31,7 @@ export const Image = ({ resizeMode = 'contain', }: ImageProps) => { const { api } = useApi() - const [headers, setHeaders] = useState() + const [headers, setHeaders] = useState<{ [index: string]: string }>() const { width: windowWidth } = useWindowDimensions() const [dimensions, setDimensions] = useState({ width: 0, height: 0 }) @@ -40,7 +40,7 @@ export const Image = ({ const prefetchImageInformation = useCallback( async (url: string) => { if (!url) return - const { headers: newHeaders } = await api.getSession(url) + const newHeaders = await api.getSessionHeaders(url) console.log('[IMAGE] Getting image dimensions with headers', { debugImageName, diff --git a/apps/skolplattformen-app/components/login.component.tsx b/apps/skolplattformen-app/components/login.component.tsx index 66dc2b8b..5f63c14d 100644 --- a/apps/skolplattformen-app/components/login.component.tsx +++ b/apps/skolplattformen-app/components/login.component.tsx @@ -34,6 +34,7 @@ import { PersonIcon, SelectIcon, } from './icon.component' +import AppStorage from '../services/appStorage' const BankId = () => ( { ] as const const loginHandler = async () => { + const user = await api.getUser() + await AppStorage.clearPersonalData(user) showModal(false) } diff --git a/apps/skolplattformen-app/components/menu.component.tsx b/apps/skolplattformen-app/components/menu.component.tsx index b1f18842..3a527adf 100644 --- a/apps/skolplattformen-app/components/menu.component.tsx +++ b/apps/skolplattformen-app/components/menu.component.tsx @@ -1,4 +1,4 @@ -import { MenuItem } from '@skolplattformen/api-skolplattformen' +import { MenuItem } from '@skolplattformen/api' import { useMenu } from '@skolplattformen/hooks' import { Divider, @@ -9,7 +9,13 @@ import { } from '@ui-kitten/components' import 'moment/locale/sv' import React from 'react' -import { Image, ImageStyle, ListRenderItemInfo, View } from 'react-native' +import { + Image, + ImageStyle, + ListRenderItemInfo, + RefreshControl, + View, +} from 'react-native' import { Layout as LayoutStyle, Sizing, Typography } from '../styles' import { translate } from '../utils/translation' import { useChild } from './childContext.component' @@ -18,7 +24,7 @@ import { MenuListItem } from './menuListItem.component' export const Menu = () => { const styles = useStyleSheet(themedStyles) const child = useChild() - const { data } = useMenu(child) + const { data, status, reload } = useMenu(child) return ( { )} style={styles.container} + refreshControl={ + + } /> ) } diff --git a/apps/skolplattformen-app/components/menuListItem.component.tsx b/apps/skolplattformen-app/components/menuListItem.component.tsx index 77556007..235d9c92 100644 --- a/apps/skolplattformen-app/components/menuListItem.component.tsx +++ b/apps/skolplattformen-app/components/menuListItem.component.tsx @@ -1,4 +1,4 @@ -import { MenuItem } from '@skolplattformen/api-skolplattformen' +import { MenuItem } from '@skolplattformen/api' import { StyleService, Text, useStyleSheet } from '@ui-kitten/components' import React from 'react' import { View } from 'react-native' diff --git a/apps/skolplattformen-app/components/modalWebView.component.tsx b/apps/skolplattformen-app/components/modalWebView.component.tsx index 6a07b923..ab4fa26f 100644 --- a/apps/skolplattformen-app/components/modalWebView.component.tsx +++ b/apps/skolplattformen-app/components/modalWebView.component.tsx @@ -20,12 +20,12 @@ export const ModalWebView = ({ const [modalVisible, setModalVisible] = React.useState(true) const { api } = useApi() const [title, setTitle] = React.useState('...') - const [headers, setHeaders] = useState() + const [headers, setHeaders] = useState<{ [index: string]: string }>() useEffect(() => { const getHeaders = async (urlToGetSessionFor: string) => { if (sharedCookiesEnabled) return - const { headers: newHeaders } = await api.getSession(urlToGetSessionFor) + const newHeaders = await api.getSessionHeaders(urlToGetSessionFor) setHeaders(newHeaders) } diff --git a/apps/skolplattformen-app/components/navigation.component.tsx b/apps/skolplattformen-app/components/navigation.component.tsx index 412c6083..ec70d41d 100644 --- a/apps/skolplattformen-app/components/navigation.component.tsx +++ b/apps/skolplattformen-app/components/navigation.component.tsx @@ -2,7 +2,7 @@ import { NavigationContainer } from '@react-navigation/native' import { Child as ChildType, NewsItem as NewsItemType, -} from '@skolplattformen/api-skolplattformen' +} from '@skolplattformen/api' import { useApi } from '@skolplattformen/hooks' import { useTheme } from '@ui-kitten/components' import { Library } from 'libraries.json' diff --git a/apps/skolplattformen-app/components/newsItem.component.tsx b/apps/skolplattformen-app/components/newsItem.component.tsx index aadda62c..edc23963 100644 --- a/apps/skolplattformen-app/components/newsItem.component.tsx +++ b/apps/skolplattformen-app/components/newsItem.component.tsx @@ -5,7 +5,13 @@ import { StyleService, Text, useStyleSheet } from '@ui-kitten/components' import moment from 'moment' import 'moment/locale/sv' import React from 'react' -import { Dimensions, ImageStyle, ScrollView, View } from 'react-native' +import { + Dimensions, + ImageStyle, + RefreshControl, + ScrollView, + View, +} from 'react-native' import { NativeStackNavigationOptions } from 'react-native-screens/native-stack' import { defaultStackStyling } from '../design/navigationThemes' import { Layout, Sizing, Typography } from '../styles' @@ -46,7 +52,7 @@ export const newsItemRouteOptions = export const NewsItem = ({ route }: NewsItemProps) => { const { newsItem, child } = route.params - const { data } = useNewsDetails(child, newsItem) + const { data, status, reload } = useNewsDetails(child, newsItem) const styles = useStyleSheet(themedStyles) const stylesMarkdown = useStyleSheet(themedStylesMarkdown) @@ -54,6 +60,9 @@ export const NewsItem = ({ route }: NewsItemProps) => { + } > {newsItem.header} diff --git a/apps/skolplattformen-app/components/newsList.component.tsx b/apps/skolplattformen-app/components/newsList.component.tsx index a5cdda48..5dc9adb8 100644 --- a/apps/skolplattformen-app/components/newsList.component.tsx +++ b/apps/skolplattformen-app/components/newsList.component.tsx @@ -1,7 +1,7 @@ import { useNews } from '@skolplattformen/hooks' import { Input, List, StyleService, useStyleSheet } from '@ui-kitten/components' import React, { useMemo, useState } from 'react' -import { TouchableOpacity, View } from 'react-native' +import { TouchableOpacity, View, RefreshControl } from 'react-native' import { Sizing } from '../styles' import { renderSearchResultPreview, @@ -15,7 +15,7 @@ import { NewsListItem } from './newsListItem.component' export const NewsList = () => { const styles = useStyleSheet(themedStyles) const child = useChild() - const { data } = useNews(child) + const { data, status, reload } = useNews(child) const [searchQuery, setSearchQuery] = useState('') const searchResults = useNewsListSearchResults(searchQuery) @@ -62,6 +62,13 @@ export const NewsList = () => { {renderSearchResultPreview(searchResult)} )} + refreshControl={ + + } /> ) } @@ -74,6 +81,13 @@ export const NewsList = () => { data={data} ListHeaderComponent={header} renderItem={({ item }) => } + refreshControl={ + + } /> ) } diff --git a/apps/skolplattformen-app/components/newsListItem.component.tsx b/apps/skolplattformen-app/components/newsListItem.component.tsx index 226d6686..1b917043 100644 --- a/apps/skolplattformen-app/components/newsListItem.component.tsx +++ b/apps/skolplattformen-app/components/newsListItem.component.tsx @@ -1,6 +1,6 @@ import { useNavigation } from '@react-navigation/native' import { StackNavigationProp } from '@react-navigation/stack' -import { NewsItem } from '@skolplattformen/api-skolplattformen' +import { NewsItem } from '@skolplattformen/api' import { StyleService, useStyleSheet } from '@ui-kitten/components' import moment from 'moment' import React, { ReactNode } from 'react' diff --git a/apps/skolplattformen-app/components/notification.component.tsx b/apps/skolplattformen-app/components/notification.component.tsx index 5c7a0354..e859d026 100644 --- a/apps/skolplattformen-app/components/notification.component.tsx +++ b/apps/skolplattformen-app/components/notification.component.tsx @@ -1,4 +1,4 @@ -import { Notification as NotificationType } from '@skolplattformen/api-skolplattformen' +import { Notification as NotificationType } from '@skolplattformen/api' import { StyleService, Text, useStyleSheet } from '@ui-kitten/components' import moment from 'moment' import React from 'react' diff --git a/apps/skolplattformen-app/components/notificationsList.component.tsx b/apps/skolplattformen-app/components/notificationsList.component.tsx index c097b756..34154747 100644 --- a/apps/skolplattformen-app/components/notificationsList.component.tsx +++ b/apps/skolplattformen-app/components/notificationsList.component.tsx @@ -1,6 +1,7 @@ import { useNotifications } from '@skolplattformen/hooks' import { List, StyleService, useStyleSheet } from '@ui-kitten/components' import React from 'react' +import { RefreshControl } from 'react-native' import { Sizing } from '../styles' import { useChild } from './childContext.component' import { Notification } from './notification.component' @@ -8,7 +9,7 @@ import { Notification } from './notification.component' export const NotificationsList = () => { const styles = useStyleSheet(themedStyles) const child = useChild() - const { data } = useNotifications(child) + const { data, status, reload } = useNotifications(child) return ( { renderItem={(info) => ( )} + refreshControl={ + + } /> ) } diff --git a/apps/skolplattformen-app/components/saveToCalendar.component.tsx b/apps/skolplattformen-app/components/saveToCalendar.component.tsx index 39118fe6..ff2491e6 100644 --- a/apps/skolplattformen-app/components/saveToCalendar.component.tsx +++ b/apps/skolplattformen-app/components/saveToCalendar.component.tsx @@ -1,4 +1,4 @@ -import { CalendarItem } from '@skolplattformen/api-skolplattformen' +import { CalendarItem } from '@skolplattformen/api' import { Button, MenuItem, OverflowMenu, Text } from '@ui-kitten/components' import React from 'react' import RNCalendarEvents from 'react-native-calendar-events' diff --git a/apps/skolplattformen-app/components/settings.component.tsx b/apps/skolplattformen-app/components/settings.component.tsx index d633202e..d2dc60e2 100644 --- a/apps/skolplattformen-app/components/settings.component.tsx +++ b/apps/skolplattformen-app/components/settings.component.tsx @@ -1,5 +1,5 @@ import { NavigationProp, useNavigation } from '@react-navigation/core' -import { useApi } from '@skolplattformen/hooks' +import { useApi, useUser } from '@skolplattformen/hooks' import React, { useCallback } from 'react' import { ScrollView } from 'react-native' import { NativeStackNavigationOptions } from 'react-native-screens/native-stack' @@ -28,14 +28,16 @@ export const SettingsScreen = () => { const langCode = LanguageService.getLanguageCode() const language = languages.find((l) => l.langCode === langCode) const { api } = useApi() + const { data: user } = useUser() const logout = useCallback(async () => { await AppStorage.clearTemporaryItems() + await AppStorage.clearPersonalData(user) await api.logout() navigation.reset({ routes: [{ name: 'Login' }], }) - }, [api, navigation]) + }, [api, navigation, user]) return ( { export const Week = ({ child }: WeekProps) => { moment.locale(LanguageService.getLocale()) const days = moment.weekdaysShort().slice(1, 6) - const currentDayIndex = Math.min(moment().isoWeekday() - 1, 5) + const displayDate = getMeaningfulStartingDate(moment()) + + const currentDayIndex = Math.min(moment(displayDate).isoWeekday() - 1, 5) const [selectedIndex, setSelectedIndex] = useState(currentDayIndex) const [showSchema, setShowSchema] = useState(false) - const [year, week] = [moment().isoWeekYear(), moment().isoWeek()] + const [year, week] = [displayDate.isoWeekYear(), displayDate.isoWeek()] const { data: lessons } = useTimetable( child, week, @@ -130,15 +130,30 @@ export const Week = ({ child }: WeekProps) => { setShowSchema(shouldShowSchema) }, [lessons]) + const getWeekText = (date = moment()) => { + return `${translate('schedule.week')} ${date.isoWeek()}` + } + return showSchema ? ( + {getWeekText(displayDate)} setSelectedIndex(index)} > - {days.map((weekDay) => ( - + {days.map((weekDay, index) => ( + ( + <> + {weekDay} + + {displayDate.startOf('week').add(index, 'day').format('D')} + + + )} + /> ))} @@ -154,7 +169,7 @@ export const Week = ({ child }: WeekProps) => { lunch={menu[index] || {}} lessons={lessons .filter((lesson) => days[lesson.dayOfWeek - 1] === weekDay) - .sort((a, b) => a.dateStart.localeCompare(b.dateStart))} + .sort((a, b) => a.timeStart.localeCompare(b.timeStart))} /> ))} @@ -166,12 +181,12 @@ export const Week = ({ child }: WeekProps) => { const themedStyles = StyleService.create({ view: { backgroundColor: 'background-basic-color-1', - maxHeight: '60%', + maxHeight: '65%', paddingBottom: 0, margin: 0, }, innerView: { - paddingBottom: 60, + paddingBottom: 170, margin: 0, }, part: { @@ -233,4 +248,15 @@ const themedStyles = StyleService.create({ lesson: { flexDirection: 'column', }, + weekNumber: { + marginLeft: 10, + marginTop: 10, + ...Typography.fontWeight.bold, + }, + tabTitle: { + textAlign: 'center', + }, + tabTitleDate: { + textAlign: 'center', + }, }) diff --git a/apps/skolplattformen-app/context/feature/featureContext.tsx b/apps/skolplattformen-app/context/feature/featureContext.tsx index 82ae6762..250f7c96 100644 --- a/apps/skolplattformen-app/context/feature/featureContext.tsx +++ b/apps/skolplattformen-app/context/feature/featureContext.tsx @@ -2,8 +2,9 @@ import { Features, FeatureType } from '@skolplattformen/api' import React from 'react' export const FeatureFlagsContext = React.createContext({ - LOGIN_BANK_ID_SAME_DEVICE: false, + LOGIN_BANK_ID_SAME_DEVICE_WITHOUT_ID: true, FOOD_MENU: false, + CLASS_LIST: true, }) interface Props { diff --git a/apps/skolplattformen-app/context/schoolPlatform/schoolPlatformContext.tsx b/apps/skolplattformen-app/context/schoolPlatform/schoolPlatformContext.tsx index e223ec41..5baece05 100644 --- a/apps/skolplattformen-app/context/schoolPlatform/schoolPlatformContext.tsx +++ b/apps/skolplattformen-app/context/schoolPlatform/schoolPlatformContext.tsx @@ -16,7 +16,7 @@ export const SchoolPlatformProvider: React.FC = ({ children }) => { 'currentSchoolPlatform' ) - const changeSchoolPlatform = (platform: string) => { + const changeSchoolPlatform = (platform) => { setCurrentSchoolPlatform(platform) } diff --git a/apps/skolplattformen-app/data/schoolPlatforms.ts b/apps/skolplattformen-app/data/schoolPlatforms.ts index 70f66019..d0d84536 100644 --- a/apps/skolplattformen-app/data/schoolPlatforms.ts +++ b/apps/skolplattformen-app/data/schoolPlatforms.ts @@ -10,13 +10,13 @@ export const schoolPlatforms = [ { id: 'stockholm-skolplattformen', displayName: 'Stockholm stad (Skolplattformen)', - api: initSkolplattformen(fetch, CookieManager), + api: initSkolplattformen(fetch as any, CookieManager), features: featuresSkolPlattformen, }, { id: 'goteborg-hjarntorget', displayName: 'Göteborg stad (HjĂ€rntorget)', - api: initHjarntorget(fetch, CookieManager), + api: initHjarntorget(fetch as any, CookieManager), features: featuresHjarntorget, }, ] diff --git a/apps/skolplattformen-app/hooks/__tests__/usePersonalStorage.tests.ts b/apps/skolplattformen-app/hooks/__tests__/usePersonalStorage.tests.ts index 4fbb2df4..754f7fde 100644 --- a/apps/skolplattformen-app/hooks/__tests__/usePersonalStorage.tests.ts +++ b/apps/skolplattformen-app/hooks/__tests__/usePersonalStorage.tests.ts @@ -1,5 +1,5 @@ import AsyncStorage from '@react-native-async-storage/async-storage' -import { User } from '@skolplattformen/api-skolplattformen' +import { User } from '@skolplattformen/api' import { act, renderHook } from '@testing-library/react-hooks' import usePersonalStorage from '../usePersonalStorage' diff --git a/apps/skolplattformen-app/hooks/useSettingsStorage.tsx b/apps/skolplattformen-app/hooks/useSettingsStorage.tsx index 7fdfb501..a976064f 100644 --- a/apps/skolplattformen-app/hooks/useSettingsStorage.tsx +++ b/apps/skolplattformen-app/hooks/useSettingsStorage.tsx @@ -2,6 +2,8 @@ import { useCallback } from 'react' import { proxy, subscribe, useSnapshot } from 'valtio' import AppStorage from '../services/appStorage' +export type ChildPersonalNumbers = Record + export const settingsState = proxy({ hydrated: false, settings: { @@ -12,6 +14,7 @@ export const settingsState = proxy({ currentSchoolPlatform: 'stockholm-skolplattformen' as | 'stockholm-skolplattformen' | 'goteborg-hjarntorget', + childPersonalIdentityNumber: {} as ChildPersonalNumbers, }, }) diff --git a/apps/skolplattformen-app/ios/Podfile.lock b/apps/skolplattformen-app/ios/Podfile.lock index fda48c7f..fef1aa99 100644 --- a/apps/skolplattformen-app/ios/Podfile.lock +++ b/apps/skolplattformen-app/ios/Podfile.lock @@ -669,4 +669,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 85f5a2dfa1de342b427eecb6e9652410ad153247 -COCOAPODS: 1.10.1 +COCOAPODS: 1.11.2 diff --git a/apps/skolplattformen-app/ios/app.xcodeproj/project.pbxproj b/apps/skolplattformen-app/ios/app.xcodeproj/project.pbxproj index 12289a08..af025c97 100644 --- a/apps/skolplattformen-app/ios/app.xcodeproj/project.pbxproj +++ b/apps/skolplattformen-app/ios/app.xcodeproj/project.pbxproj @@ -573,9 +573,9 @@ ); inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-app/Pods-app-frameworks.sh", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/double-conversion/double-conversion.framework/double-conversion", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL/OpenSSL.framework/OpenSSL", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes/hermes.framework/hermes", + "${PODS_XCFRAMEWORKS_BUILD_DIR}/Flipper-DoubleConversion/double-conversion.framework/double-conversion", + "${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL-Universal/OpenSSL.framework/OpenSSL", + "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/hermes.framework/hermes", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( @@ -595,9 +595,9 @@ ); inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-app-appTests/Pods-app-appTests-frameworks.sh", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/double-conversion/double-conversion.framework/double-conversion", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL/OpenSSL.framework/OpenSSL", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes/hermes.framework/hermes", + "${PODS_XCFRAMEWORKS_BUILD_DIR}/Flipper-DoubleConversion/double-conversion.framework/double-conversion", + "${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL-Universal/OpenSSL.framework/OpenSSL", + "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/hermes.framework/hermes", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( @@ -793,7 +793,7 @@ ENABLE_BITCODE = NO; INFOPLIST_FILE = app/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - MARKETING_VERSION = 3.0.1; + MARKETING_VERSION = 3.0.3; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", @@ -822,7 +822,7 @@ DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = app/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - MARKETING_VERSION = 3.0.1; + MARKETING_VERSION = 3.0.3; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", diff --git a/apps/skolplattformen-app/services/__tests__/appStorage.tests.ts b/apps/skolplattformen-app/services/__tests__/appStorage.tests.ts index 08946f82..230e017a 100644 --- a/apps/skolplattformen-app/services/__tests__/appStorage.tests.ts +++ b/apps/skolplattformen-app/services/__tests__/appStorage.tests.ts @@ -1,5 +1,5 @@ import AsyncStorage from '@react-native-async-storage/async-storage' -import { User } from '@skolplattformen/api-skolplattformen' +import { User } from '@skolplattformen/api' import AppStorage from '../appStorage' beforeEach(() => { diff --git a/apps/skolplattformen-app/services/appStorage.ts b/apps/skolplattformen-app/services/appStorage.ts index bbe2a6a4..c881e11e 100644 --- a/apps/skolplattformen-app/services/appStorage.ts +++ b/apps/skolplattformen-app/services/appStorage.ts @@ -1,5 +1,5 @@ import AsyncStorage from '@react-native-async-storage/async-storage' -import { User } from '@skolplattformen/api-skolplattformen' +import { User } from '@skolplattformen/api' export default class AppStorage { static settingsStorageKeyPrefix = 'appsetting_' diff --git a/apps/skolplattformen-app/translations/en.json b/apps/skolplattformen-app/translations/en.json index d85f7932..f60d16f6 100644 --- a/apps/skolplattformen-app/translations/en.json +++ b/apps/skolplattformen-app/translations/en.json @@ -58,7 +58,9 @@ "saveToCalender": "Save in calendar", "saveToCalenderError": "Something went wrong", "saveToCalenderSuccess": "✔ Saved in calendar", - "showCalenderActions": "Show calendar actions" + "showCalenderActions": "Show calendar actions", + "emptyHeadline": "The calendar looks kinda empty", + "emptyText": "Couldn't find anything to show" }, "children": { "loadingErrorHeading": "Oops!", @@ -80,7 +82,8 @@ "send": "Send", "settings": "Settings", "socialSecurityNumber": "Personal identity number", - "title": "Öppna skolplattformen" + "title": "Öppna skolplattformen", + "tomorrow": "Tomorrow" }, "language": { "changeLanguage": "Change language", @@ -128,7 +131,8 @@ "start": "Start", "end": "End", "lunch": "Lunch", - "gymBag": "Gym bag" + "gymBag": "Gym bag", + "week": "Week" }, "classmates": { "class": "Class", diff --git a/apps/skolplattformen-app/translations/fr.json b/apps/skolplattformen-app/translations/fr.json index bd57bd18..f4e6a3b1 100644 --- a/apps/skolplattformen-app/translations/fr.json +++ b/apps/skolplattformen-app/translations/fr.json @@ -10,7 +10,8 @@ "changeLanguage": "Changer de langue", "cancel": "Annuler", "logoutAndClearPersonalData": "Se dĂ©connecter et effacer les donnĂ©es personnelles", - "logoutAndClearAllDataInclSettings": "Se dĂ©connecter et effacer toutes les donnĂ©es, y compris les paramĂštres" + "logoutAndClearAllDataInclSettings": "Se dĂ©connecter et effacer toutes les donnĂ©es, y compris les paramĂštres", + "tomorrow": "Demain" }, "calender": { "saveToCalenderError": "Un problĂšme est survenu", @@ -53,7 +54,8 @@ "a11y_select_login_method": "SĂ©lectionnez la mĂ©thode de connexion", "a11y_clear_social_security_input_field": "Effacer le champ du numĂ©ro national d’identitĂ©", "a11y_image_two_boys": "Photo de deux personnes consultant leur tĂ©lĂ©phone portable", - "a11y_change_language": "SĂ©lectionnez votre langue" + "a11y_change_language": "SĂ©lectionnez votre langue", + "chooseSchoolPlatform": "Choisir la plateforme" }, "abscense": { "startTime": "Heure de dĂ©but", diff --git a/apps/skolplattformen-app/translations/nb_NO.json b/apps/skolplattformen-app/translations/nb_NO.json index 4b180d89..11755b51 100644 --- a/apps/skolplattformen-app/translations/nb_NO.json +++ b/apps/skolplattformen-app/translations/nb_NO.json @@ -50,7 +50,9 @@ "saveToCalenderSuccess": "✔ Lagret i kalender", "showCalenderActions": "Vis kalenderhandlinger", "saveToCalenderError": "Noe gikk galt", - "approveAccessToCalender": "Du mĂ„ innvilge tilgang til kalenderen din" + "approveAccessToCalender": "Du mĂ„ innvilge tilgang til kalenderen din", + "emptyHeadline": "Kalenderen ser tom ut", + "emptyText": "Ingenting Ă„ vise" }, "general": { "loading": "Laster inn 
", @@ -63,7 +65,8 @@ "send": "Send", "cancel": "Avbryt", "logoutAndClearPersonalData": "Logg ut og tĂžm personlig data", - "logoutAndClearAllDataInclSettings": "Logg ut og tĂžm all data, inkludert innstillinger" + "logoutAndClearAllDataInclSettings": "Logg ut og tĂžm all data, inkludert innstillinger", + "tomorrow": "I morgen" }, "news": { "updated": "Oppdatert", @@ -115,7 +118,8 @@ "gymBag": "Gym-bag", "lunch": "Lunsj", "end": "Slutt", - "start": "Start" + "start": "Start", + "week": "Uke" }, "contact": { "a11y_show_contact_info_button_hint": "Vis kontaktinfo", diff --git a/apps/skolplattformen-app/translations/pl.json b/apps/skolplattformen-app/translations/pl.json index dbf6841a..97c4e1c5 100644 --- a/apps/skolplattformen-app/translations/pl.json +++ b/apps/skolplattformen-app/translations/pl.json @@ -50,14 +50,17 @@ "a11y_select_login_method": "Wybierz metodę logowania", "a11y_clear_social_security_input_field": "Wyczyƛć pole z personnumerem", "a11y_image_two_boys": "Ilustracja: dwie osoby patrzą w telefony komĂłrkowe", - "a11y_change_language": "Wybierz język" + "a11y_change_language": "Wybierz język", + "chooseSchoolPlatform": "Wybierz platformę" }, "calender": { "approveAccessToCalender": "Musisz zatwierdzić dostęp do kalendarza", "saveToCalender": "Zapisz w kalendarzu", "saveToCalenderError": "Coƛ poszƂo nie tak", "saveToCalenderSuccess": "✔ Zapisano w kalendarzu", - "showCalenderActions": "PokaĆŒ opcje kalendarza" + "showCalenderActions": "PokaĆŒ opcje kalendarza", + "emptyHeadline": "Kalendarz jest pusty", + "emptyText": "Nie znaleziono nic do pokazania" }, "children": { "loadingErrorHeading": "Oj!", @@ -79,7 +82,8 @@ "title": "Öppna skolplattformen", "cancel": "Anuluj", "logoutAndClearPersonalData": "Wyloguj i skasuj dane osobowe", - "logoutAndClearAllDataInclSettings": "Wyloguj i skasuj wszystkie dane Ƃącznie z ustawieniami" + "logoutAndClearAllDataInclSettings": "Wyloguj i skasuj wszystkie dane Ƃącznie z ustawieniami", + "tomorrow": "Jutro" }, "language": { "changeLanguage": "ZmieƄ język", @@ -114,11 +118,12 @@ "gymBag": "Ubrania do WF", "lunch": "Lunch", "end": "KoƄczy", - "start": "Zaczyna" + "start": "Zaczyna", + "week": "TydzieƄ" }, "contact": { "a11y_show_contact_info_button_hint": "Pokazuje dane kontaktowe", - "home": "Dom", + "home": "Adres", "email": "E-mail", "sms": "SMS", "call": "ZadzwoƄ", diff --git a/apps/skolplattformen-app/translations/pt.json b/apps/skolplattformen-app/translations/pt.json index b288f472..ab7fb1ee 100644 --- a/apps/skolplattformen-app/translations/pt.json +++ b/apps/skolplattformen-app/translations/pt.json @@ -7,7 +7,8 @@ "selectAbscenseEndTime": "Indique a hora de fim", "endTime": "Hora de fim", "invalidPersonalNumber": "NĂșmero de identidade pessoal invĂĄlido", - "personalNumberMissing": "Falta o nĂșmero de identidade pessoal" + "personalNumberMissing": "Falta o nĂșmero de identidade pessoal", + "childsPersonalNumber": "NĂșmero de identidade pessoal da criança" }, "auth": { "bankid": { diff --git a/apps/skolplattformen-app/translations/sv.json b/apps/skolplattformen-app/translations/sv.json index 717a78f7..461557fe 100644 --- a/apps/skolplattformen-app/translations/sv.json +++ b/apps/skolplattformen-app/translations/sv.json @@ -58,7 +58,9 @@ "saveToCalender": "Spara till kalender", "saveToCalenderError": "NĂ„got gick fel", "saveToCalenderSuccess": "✔ Sparad till kalender", - "showCalenderActions": "Visa kalenderfunktioner" + "showCalenderActions": "Visa kalenderfunktioner", + "emptyText": "Hittade ingenting att visa", + "emptyHeadline": "Det ser lite tomt ut i kalendern" }, "children": { "loadingErrorHeading": "Hoppsan!", @@ -80,7 +82,8 @@ "title": "Öppna skolplattformen", "cancel": "Avbryt", "logoutAndClearAllDataInclSettings": "Logga ut och rensa all sparad data inkl instĂ€llningar", - "logoutAndClearPersonalData": "Logga ut och rensa all personlig data" + "logoutAndClearPersonalData": "Logga ut och rensa all personlig data", + "tomorrow": "Imorgon" }, "language": { "changeLanguage": "Byt sprĂ„k", @@ -128,7 +131,8 @@ "start": "Börjar", "end": "Slutar", "lunch": "Lunch", - "gymBag": "GympapĂ„se" + "gymBag": "GympapĂ„se", + "week": "Vecka" }, "classmates": { "class": "Klass", diff --git a/apps/skolplattformen-app/utils/__tests__/calendarHelpers.test.ts b/apps/skolplattformen-app/utils/__tests__/calendarHelpers.test.ts new file mode 100644 index 00000000..2e1b996e --- /dev/null +++ b/apps/skolplattformen-app/utils/__tests__/calendarHelpers.test.ts @@ -0,0 +1,47 @@ +import moment from 'moment' +import { getMeaningfulStartingDate } from '../calendarHelpers' + +const tuesdayMorning = moment('2021-11-30T08:20:00+0100') +const tuesdayEvening = moment('2021-11-30T19:20:26+0100') +const wednesdayEvening = moment('2021-12-01T19:20:26+0100') +const fridayEvening = moment('2021-12-03T19:20:26+0100') +const saturdayEvening = moment('2021-12-04T19:20:26+0100') +const sundayEvening = moment('2021-12-05T19:20:26+0100') +const mondayEvening = moment('2021-12-06T19:20:26+0100') + +describe('getMeaningfulStartingDate should not touch inputdate', () => { + const origDate = moment() + const origDateClone = origDate.clone() + getMeaningfulStartingDate(origDate) + + expect(origDate).toEqual(origDateClone) +}) + +describe('getMeaningfulStartingDate on weekends', () => { + it('should give next monday if on friday evening', () => { + const startDate = getMeaningfulStartingDate(fridayEvening) + expect(startDate.toISOString()).toEqual(mondayEvening.toISOString()) + }) + + it('should give next monday if on saturday', () => { + const startDate = getMeaningfulStartingDate(saturdayEvening) + expect(startDate.toISOString()).toEqual(mondayEvening.toISOString()) + }) + + it('should give next monday if on sunday', () => { + const startDate = getMeaningfulStartingDate(sundayEvening) + expect(startDate.toISOString()).toEqual(mondayEvening.toISOString()) + }) +}) + +describe('getMeaningfulStartingDate on weekdays', () => { + it('should give next day if on tuesday evening', () => { + const startDate = getMeaningfulStartingDate(tuesdayEvening) + expect(startDate.toISOString()).toEqual(wednesdayEvening.toISOString()) + }) + + it('should give same day if on tuesday morning', () => { + const startDate = getMeaningfulStartingDate(tuesdayMorning) + expect(startDate.toISOString()).toEqual(tuesdayMorning.toISOString()) + }) +}) diff --git a/apps/skolplattformen-app/utils/calendarHelpers.ts b/apps/skolplattformen-app/utils/calendarHelpers.ts new file mode 100644 index 00000000..26a87a5b --- /dev/null +++ b/apps/skolplattformen-app/utils/calendarHelpers.ts @@ -0,0 +1,18 @@ +import moment from 'moment' + +export const getMeaningfulStartingDate = (date = moment()) => { + const originalDate = date.clone() + let returnDate = date.clone() + // are we on the evening? + if (date.hour() > 17) returnDate.add('1', 'day') + // are we on the weekend + if (returnDate.isoWeekday() > 5) { + returnDate = returnDate.add(5, 'days').startOf('isoWeek') + returnDate + .hour(originalDate.hour()) + .minute(originalDate.minute()) + .second(originalDate.second()) + } + + return returnDate +} diff --git a/apps/skolplattformen-app/utils/peopleHelpers.ts b/apps/skolplattformen-app/utils/peopleHelpers.ts index f44d34a1..32ec3639 100644 --- a/apps/skolplattformen-app/utils/peopleHelpers.ts +++ b/apps/skolplattformen-app/utils/peopleHelpers.ts @@ -1,4 +1,4 @@ -import { Guardian } from '@skolplattformen/api-skolplattformen' +import { Guardian } from '@skolplattformen/api' export const studentName = (name?: string) => name?.replace(/\s?\(\w+\)$/, '') diff --git a/apps/skolplattformen-app/utils/search.tsx b/apps/skolplattformen-app/utils/search.tsx index 2752ef98..defa5ba6 100644 --- a/apps/skolplattformen-app/utils/search.tsx +++ b/apps/skolplattformen-app/utils/search.tsx @@ -1,4 +1,4 @@ -import { NewsItem } from '@skolplattformen/api-skolplattformen' +import { NewsItem } from '@skolplattformen/api' import { useNews } from '@skolplattformen/hooks' import { MatchData, Searcher } from 'fast-fuzzy' import React, { ReactNode, useMemo } from 'react' diff --git a/apps/skolplattformen-app/utils/testHelpers.tsx b/apps/skolplattformen-app/utils/testHelpers.tsx index c915d566..37899527 100644 --- a/apps/skolplattformen-app/utils/testHelpers.tsx +++ b/apps/skolplattformen-app/utils/testHelpers.tsx @@ -5,6 +5,7 @@ import { EvaIconsPack } from '@ui-kitten/eva-icons' import React, { ReactElement } from 'react' import { LanguageProvider } from '../context/language/languageContext' import { translations } from './translation' +import { lightTheme } from '../design/themes' export const render = ( ui: ReactElement, @@ -14,7 +15,7 @@ export const render = ( return ( <> - + {

"Öppna Skolplattformen", hĂ€danefter "appen", byggs av "Not free beer AB" som en kommersiell app. Appen hĂ€mtar all information frĂ„n - Stockholms stads skolplattform, hĂ€danefter Skolplattformen, efter + respektive skolplattform, hĂ€danefter Skolplattformen, efter inloggning via BankID. Appens funktion Ă€r dĂ€rmed direkt knuten till att Skolplattformen fungerar. Vi kan endast ta ansvar för att vĂ„r kod fungerar – inte deras. diff --git a/apps/website/components/QA.tsx b/apps/website/components/QA.tsx index 60859410..0ed1bda6 100644 --- a/apps/website/components/QA.tsx +++ b/apps/website/components/QA.tsx @@ -1,5 +1,7 @@ import Link from './Link' +import { price } from './Pricing' + const QA = () => { return (

@@ -249,7 +251,7 @@ const QA = () => { de?

- Appen kostar 12 kronor. IntÀkten registreras i aktiebolaget Not Free + Appen kostar {price} kronor. IntÀkten registreras i aktiebolaget Not Free Beer som Àgs av tre av utvecklarna och gÄr till att tÀcka kostnader för inköp. Det tÀcker inte pÄ lÄnga vÀgar den tid vi lagt ner. Med en lÄg engÄngskostnad ökar vi chansen att vi orkar syssla med underhÄll @@ -315,7 +317,7 @@ const QA = () => {

Kontakta oss

Tveka inte att kontakta oss. Skicka ett mail till{' '} - dev@skolplattformen.org. + info@skolplattformen.org.

diff --git a/apps/website/components/featureData.tsx b/apps/website/components/featureData.tsx index 6cab0425..65186aff 100644 --- a/apps/website/components/featureData.tsx +++ b/apps/website/components/featureData.tsx @@ -66,7 +66,7 @@ export const FEATURES_DATA = [ { title: 'Kan byggas ut till fler skolsystem', text: - 'Just nu stöds bara Stockholm Stads skolplattform men med din hjÀlp kan fler skolplattformar integreras sÄ att du slipper logga in i flera appar om du har barn i olika skolor.', + 'Just nu stöds Stockholms och Göteborgs stads skolplattformar. Med din hjÀlp kan fler integreras sÄ att du slipper anvÀnda flera appar om du har barn i olika skolor.', image: ( { - await this.fetch('login-cookie', hjarntorgetUrl, { - headers: { - cookie: sessionCookie, - }, - redirect: 'manual', - }) + public async getSessionHeaders(url: string): Promise<{ [index: string]: string }> { + const cookie = await this.cookieManager.getCookieString(url) + return { + cookie, + } + } + async setSessionCookie(sessionCookie: string): Promise { + this.cookieManager.setCookieString(sessionCookie, hjarntorgetUrl) + const user = await this.getUser() if (!user.isAuthenticated) { throw new Error('Session cookie is expired') @@ -247,6 +252,21 @@ export class ApiHjarntorget extends EventEmitter implements Api { return Promise.resolve([]) } + public async getTeachers(child: EtjanstChild): Promise { + if (!this.isLoggedIn) { + throw new Error('Not logged in...') + } + return Promise.resolve([]) + } + + public async getSchoolContacts(child: EtjanstChild): Promise { + if (!this.isLoggedIn) { + throw new Error('Not logged in...') + } + return Promise.resolve([]) + } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars async getNews(_child: EtjanstChild): Promise { if (!this.isLoggedIn) { @@ -452,9 +472,8 @@ export class ApiHjarntorget extends EventEmitter implements Api { zone: FixedOffsetZone.instance(l.endDate.timezoneOffsetMinutes), }) return { + ...parse(l.title, _lang), id: l.id, - code: l.title, - name: l.title, teacher: l.bookedTeacherNames && l.bookedTeacherNames[0], location: l.location, timeStart: start.toISOTime().substring(0, 5), @@ -462,7 +481,7 @@ export class ApiHjarntorget extends EventEmitter implements Api { dayOfWeek: start.toJSDate().getDay(), blockName: l.title, dateStart: start.toISODate(), - dateEnd: start.toISODate(), + dateEnd: end.toISODate(), } as TimetableEntry }) } @@ -492,13 +511,13 @@ export class ApiHjarntorget extends EventEmitter implements Api { if((beginLoginRedirectResponse as any).url.endsWith("startPage.do")) { // already logged in! - const emitter = new EventEmitter() + const emitter = new DummyStatusChecker() setTimeout(() => { this.isLoggedIn = true emitter.emit('OK') this.emit('login') }, 50) - return emitter as unknown as LoginStatusChecker; + return emitter as LoginStatusChecker; } console.log('prepping??? shibboleth') diff --git a/libs/api-hjarntorget/lib/fake/calendars.ts b/libs/api-hjarntorget/lib/fake/calendars.ts index fc7cbf7f..1657cee3 100644 --- a/libs/api-hjarntorget/lib/fake/calendars.ts +++ b/libs/api-hjarntorget/lib/fake/calendars.ts @@ -1,17 +1,17 @@ +import { Response } from '@skolplattformen/api'; /* eslint-disable no-useless-escape */ export const calendars = () => ({ "url": "https://hjarntorget.goteborg.se/pp/system/calendar/cal_events.jsp", "headers": { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36", - "cookie": "REMOVED" + "cookie": "REMOVED" }, "status": 200, "statusText": "200", "text": () => Promise.resolve("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nThe PING PONG Calendar\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\t
\n\t\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\t\n\t\n\n\t\n\n\n\n\t\t\n\n\t\t
\n\t\t\t\n\t\t\t
\n\t\t\t\t

Make a selection

\n\n\t\t\t\t

Here you get an overview of your calendars. Choose from which calendars you wish to see events. Choose if you want to search for a word. Click Show to see the result.

\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t
Show calendar events for the checked calendars
\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\n\n
\"\"
\n\n\n\n
removed checkbox
\"\"
\n\n\n\n
removed checkbox
\"\"
\n\n\t\t\t\t\t\t\t
\n\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t
Group the events per calendar\n\t\t\t\t\t\t\t\t\t
Don't group\n\t\t\t\t\t\t\t\t\t
From - to:\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t
Search for
\n\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t
\n\n\t\t\t\t\t\t
\n\t\t\t
\n\n\t\t\t

Calendar events

\n\n\t\t\t\t\n\t\t\t\t

\n\t\t\t\t\t No events was found \n\t\t\t\t\t\n\t\t\t\t

\n\t\t\t\t\n\n\t\t\t
\n\t\t
\n\t
\n\n\n\n\n") }) as any as Response -export const calendar_14241345 = () => { - return { +export const calendar_14241345 = () => ({ "url": "https://hjarntorget.goteborg.se/pp/system/calendar/cal_events.jsp?order_by=start_date&show_cal_ids=14241345&mode=separate&filter_start_date=2021-11-09&filter_end_date=2021-12-09&search_for=", "headers": { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36", @@ -19,6 +19,8 @@ export const calendar_14241345 = () => { }, "status": 200, "statusText": "200", + "json": null, + "ok": true, "text": () => { const now = new Date() const dateYearMonth = `${now.getFullYear()}-${now.getMonth() + 1}` @@ -27,7 +29,6 @@ export const calendar_14241345 = () => { const result = ` \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nThe PING PONG Calendar\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\t
\n\t\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\t\n\t\n\n\t\n\n\n\n\t\t\n\n\t\t
\n\t\t\t\n\t\t\t
\n\t\t\t\t

Make a selection

\n\n\t\t\t\t

Here you get an overview of your calendars. Choose from which calendars you wish to see events. Choose if you want to search for a word. Click Show to see the result.

\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t
Show calendar events for the checked calendars
\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\n\n
removed checkbox
\"\"
\n\n\n\n
removed checkbox
\"\"
\n\n\n\n
removed checkbox
\"\"
\n\n\t\t\t\t\t\t\t
\n\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t
Group the events per calendar\n\t\t\t\t\t\t\t\t\t
Don't group\n\t\t\t\t\t\t\t\t\t
From - to:\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t
Search for
\n\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t
\n\n\t\t\t\t\t\t
\n\t\t\t
\n\n\t\t\t

Calendar events

\n\n\t\t\t\t\n\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\n\t\t\t\t\t\t\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\t\t\tTitle\n\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\tDates\n\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\tTimes\n\n\t\t\t\t\t\t\t
138JÄTS Provschema Ă„r 8
\"\"
\nProv/komplettering franska ${dateYearMonth}-0113:00-14:00
\"\"
\nTyska lÀxförhör${dateYearMonth}-0113:00-13:30\"The
\"\"
\nLĂ€xa i franska${dateYearMonth}-0309:40-10:20\"The
\"\"
\nSpanskaprov Repasamos 1- 4${dateYearMonth}-0310:00-11:00
\"\"
\nTyska lÀxförhör${dateYearMonth}-0813:00-13:30\"The
\"\"
\nLĂ€xa i franska${dateYearMonth}-1009:40-10:20\"The
\"\"
\nDeadline engelska - Postcard from Great Britain${dateYearMonth}-1115:00-16:00\"The
\"\"
\nLĂ€xa engelska${dateYearMonth}-1408:00-09:00\"The
\"\"
\nTyska lÀxförhör${dateYearMonth}-1513:00-13:30\"The
\"\"
\nLĂ€xa i franska${dateYearMonth}-1709:40-10:20\"The
\"\"
\nLĂ€xa engelska${dateYearMonth}-1908:00-09:00\"The
\"\"
\nProv franska Ă„k 7${dateYearMonth}-2012:00-13:00
\"\"
\nLĂ€xa i franska${dateYearMonth}-2209:40-10:20\"The
\"\"
\nLĂ€xa engelska${nextMonth}-0108:00-09:00\"The
\n\n\t\t\t\t\n\n\t\t\t
\n\t\t
\n\t
\n\n\n\n\n ` - return Promise.resolve(result as any as Response) + return Promise.resolve(result) } - } -} \ No newline at end of file + }) as any as Response diff --git a/libs/api-hjarntorget/lib/fake/fakeFetcher.ts b/libs/api-hjarntorget/lib/fake/fakeFetcher.ts index 87595ba3..d9a9e6f5 100644 --- a/libs/api-hjarntorget/lib/fake/fakeFetcher.ts +++ b/libs/api-hjarntorget/lib/fake/fakeFetcher.ts @@ -28,10 +28,9 @@ const fetchMappings: { [name:string]: () => Response} = { 'event-role-members-24-821': eventRoleMembers24, 'calendars': calendars, 'calendar-14241345': calendar_14241345, - } export const fakeFetcher: Fetcher = (name: string, url: string, init?: any): Promise => { const responder = fetchMappings[name] ?? (() => {throw new Error("Request not faked for name: " + name)}) return Promise.resolve(responder()); -} +} diff --git a/libs/api-hjarntorget/lib/fake/lessons.ts b/libs/api-hjarntorget/lib/fake/lessons.ts index c6efea09..639c5af0 100644 --- a/libs/api-hjarntorget/lib/fake/lessons.ts +++ b/libs/api-hjarntorget/lib/fake/lessons.ts @@ -1,13 +1,22 @@ +import { toNamespacedPath } from "path"; + // TODO: fix the startDate/endDate of all lessons export const lessons_133700_goteborgsstad = () => { const baseTime = 1636357800000; const baseDate = new Date(baseTime) const today = new Date() + const currentHour = today.getHours() today.setHours(baseDate.getHours()) today.setMinutes(baseDate.getMinutes()) today.setSeconds(0) - const offset = Math.abs(baseTime - today.getTime()) + let offset = Math.abs(baseTime - today.getTime()) + const weekDay = today.getDay() + + if(weekDay == 6 || (weekDay == 5 && currentHour >= 18)) offset = offset + 2 * 86400000 + if(weekDay == 0) offset = offset + 86400000 + if(weekDay > 0 && weekDay < 6 && currentHour >= 18) offset = offset + 86400000 + return { "url": "https://hjarntorget.goteborg.se/api/schema/lessons?forUser=133700_goteborgsstad&startDateIso=2021-11-01&endDateIso=2021-11-08", "headers": { @@ -206,14 +215,21 @@ export const lessons_133700_goteborgsstad = () => { } export const lessons_123456_goteborgsstad = () => { - const baseTime = 1636355400000; + const baseTime = 1636357800000; const baseDate = new Date(baseTime) const today = new Date() + const currentHour = today.getHours() today.setHours(baseDate.getHours()) today.setMinutes(baseDate.getMinutes()) today.setSeconds(0) - - const offset = Math.abs(baseTime - today.getTime()) + + let offset = Math.abs(baseTime - today.getTime()) + const weekDay = today.getDay() + + if(weekDay == 6 || (weekDay == 5 && currentHour >= 18)) offset = offset + 2 * 86400000 + if(weekDay == 0) offset = offset + 86400000 + if(weekDay > 0 && weekDay < 6 && currentHour >= 18) offset = offset + 86400000 + return { "url": "https://hjarntorget.goteborg.se/api/schema/lessons?forUser=123456_goteborgsstad&startDateIso=2021-11-01&endDateIso=2021-11-08", "headers": { diff --git a/libs/api-hjarntorget/lib/loginStatus.ts b/libs/api-hjarntorget/lib/loginStatus.ts index aeeeda68..c96665f2 100644 --- a/libs/api-hjarntorget/lib/loginStatus.ts +++ b/libs/api-hjarntorget/lib/loginStatus.ts @@ -10,7 +10,7 @@ import { pollStatusUrl, } from './routes' -export class HjarntorgetChecker extends EventEmitter { +export class HjarntorgetChecker extends EventEmitter implements LoginStatusChecker { private fetcher: Fetcher private basePollingUrl: string @@ -120,3 +120,10 @@ export const checkStatus = ( fetch: Fetcher, basePollingUrl: string ): LoginStatusChecker => new HjarntorgetChecker(fetch, basePollingUrl) + +export class DummyStatusChecker extends EventEmitter implements LoginStatusChecker { + token = "" + async cancel(): Promise { + // do nothing + } +} diff --git a/libs/api-skolplattformen/README.md b/libs/api-skolplattformen/README.md index 85053458..37c23583 100644 --- a/libs/api-skolplattformen/README.md +++ b/libs/api-skolplattformen/README.md @@ -16,7 +16,7 @@ the concrete implementation of fetch and cookie handler must be injected. #### react-native ```javascript -import init from '@skolplattformen/api-skolplattformen' +import init from '@skolplattformen/api' import CookieManager from '@react-native-cookies/cookies' const api = init(fetch, () => CookieManager.clearAll()) @@ -25,7 +25,7 @@ const api = init(fetch, () => CookieManager.clearAll()) #### node ```javascript -import init from '@skolplattformen/api-skolplattformen' +import init from '@skolplattformen/api' import nodeFetch from 'node-fetch' import fetchCookie from 'fetch-cookie/node-fetch' import { CookieJar } from 'tough-cookie' diff --git a/libs/api-skolplattformen/lib/api.ts b/libs/api-skolplattformen/lib/api.ts index 427cc902..7761d717 100644 --- a/libs/api-skolplattformen/lib/api.ts +++ b/libs/api-skolplattformen/lib/api.ts @@ -17,7 +17,9 @@ import { ScheduleItem, Skola24Child, SSOSystem, + Teacher, TimetableEntry, + SchoolContact, URLSearchParams, User, wrap, @@ -28,7 +30,7 @@ import { decode } from 'he' import { DateTime } from 'luxon' import * as html from 'node-html-parser' import * as fake from './fakeData' -import { checkStatus } from './loginStatusChecker' +import { checkStatus, DummyStatusChecker } from './loginStatusChecker' import * as parse from './parse/index' import * as routes from './routes' @@ -97,6 +99,16 @@ export class ApiSkolplattformen extends EventEmitter implements Api { } } + public async getSessionHeaders(url: string): Promise<{ [index: string]: string }> { + const init = this.getRequestInit() + const cookie = await this.cookieManager.getCookieString(url) + return { + ...init.headers, + cookie, + } + } + + public async getSession( url: string, options?: RequestInit @@ -206,8 +218,7 @@ export class ApiSkolplattformen extends EventEmitter implements Api { this.emit('login') }, 50) - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const emitter: any = new EventEmitter() + const emitter = new DummyStatusChecker() emitter.token = 'fake' return emitter } @@ -265,6 +276,39 @@ export class ApiSkolplattformen extends EventEmitter implements Api { return parse.classmates(data) } + public async getTeachers(child: EtjanstChild): Promise { + if (this.isFake) return fakeResponse(fake.teachers(child)) + + const session = this.getRequestInit() + + const schoolForms = (child.status || '').split(';') + let teachers: Teacher[] = [] + + for(let i = 0; i< schoolForms.length; i+=1){ + const url = routes.teachers(child.sdsId, schoolForms[i]) + // eslint-disable-next-line no-await-in-loop + const response = await this.fetch(`teachers_${schoolForms[i]}`, url, session) + // eslint-disable-next-line no-await-in-loop + const data = await response.json() + teachers = [ + ...teachers, + ...parse.teachers(data) + ] + } + + return teachers + } + + public async getSchoolContacts(child: EtjanstChild): Promise { + if(this.isFake) return fakeResponse(fake.schoolContacts(child)) + + const url = routes.schoolContacts(child.sdsId, child.schoolId || '') + const session = this.getRequestInit() + const response = await this.fetch('schoolContacts', url, session) + const data = await response.json() + return parse.schoolContacts(data) + } + public async getSchedule( child: EtjanstChild, from: DateTime, @@ -518,6 +562,8 @@ export class ApiSkolplattformen extends EventEmitter implements Api { return parse.timetable(json, year, week, lang) } + + public async logout() { this.isFake = false this.personalNumber = undefined diff --git a/libs/api-skolplattformen/lib/fakeData.ts b/libs/api-skolplattformen/lib/fakeData.ts deleted file mode 100644 index 12c23cec..00000000 --- a/libs/api-skolplattformen/lib/fakeData.ts +++ /dev/null @@ -1,1603 +0,0 @@ -/* eslint-disable max-len */ -import { - CalendarItem, - Child, - Classmate, - EtjanstChild, - MenuItem, - NewsItem, - Notification, - ScheduleItem, - Skola24Child, - TimetableEntry, - User, -} from '@skolplattformen/api'; - -const data: any = { - '39b59e-bf4b9f-f68ac25321-977218-bf0': { - classmates: [ - { - sisId: 'd004a-98d965a-45174-d2894ca2-f74ebcb', - firstname: 'Darion', - lastname: 'Gustafsson', - guardians: [ - { - email: 'Mike_Svensson@example.net', - firstname: 'Tad', - lastname: 'Eriksson', - mobile: '07074791613', - address: 'MartinvÀgen 50', - }, - ], - className: '2B', - }, - { - sisId: '54075-284de06-5664c-750b7b13-520fb61', - firstname: 'Brock', - lastname: 'Andersson', - guardians: [ - { - email: 'Brad56@example.org', - firstname: 'Camren', - lastname: 'Eriksson', - mobile: '07075129297', - address: null, - }, - ], - className: '2B', - }, - { - sisId: 'c1fc7-285f95d-c0f37-ea48a297-281e985', - firstname: 'Eloy', - lastname: 'Karlsson', - guardians: [ - { - email: 'Samara.Larsson@example.net', - firstname: 'Ike', - lastname: 'Gustafsson', - mobile: '07077667407', - address: null, - }, - ], - className: '2B', - }, - { - sisId: '212e9-8a2609c-b29c1-97a32bd8-5f84645', - firstname: 'Kristina', - lastname: 'Eriksson', - guardians: [ - { - email: 'Doug57@example.com', - firstname: 'Rollin', - lastname: 'Olsson', - mobile: '07071720107', - address: 'HöckertsvÀgen 2', - }, - ], - className: '2B', - }, - { - sisId: '01d21-ebc6f8b-526f8-7cfba0ab-26b9956', - firstname: 'Cydney', - lastname: 'Larsson', - guardians: [ - { - email: 'Davon6@example.org', - firstname: 'Oleta', - lastname: 'Svensson', - mobile: '07079762186', - address: null, - }, - ], - className: '2B', - }, - { - sisId: 'a45bb-8a481af-0ad12-7bd1fa4c-1eed4b1', - firstname: 'Berneice', - lastname: 'Persson', - guardians: [ - { - email: 'Milford_Johansson72@example.com', - firstname: 'Arely', - lastname: 'Johansson', - mobile: '07071926019', - address: 'RoslinvÀgen 36', - }, - ], - className: '2B', - }, - { - sisId: '32f31-039fbed-9060b-2d857c46-e47177d', - firstname: 'Emory', - lastname: 'Svensson', - guardians: [ - { - email: 'Alfredo_Nilsson96@example.org', - firstname: 'Dolores', - lastname: 'Andersson', - mobile: '070752561937', - address: 'BörjesonsvÀgen 6', - }, - ], - className: '2B', - }, - { - sisId: 'c9d0a-28c371d-e7be2-9781386b-6841eb0', - firstname: 'Maryjane', - lastname: 'Eriksson', - guardians: [ - { - email: 'Eula_Olsson@example.net', - firstname: 'Wendy', - lastname: 'Andersson', - mobile: '07078513037', - address: null, - }, - { - email: 'Lesley_Persson45@example.org', - firstname: 'Erich', - lastname: 'Persson', - mobile: '070788191316', - address: null, - }, - ], - className: '2B', - }, - { - sisId: 'e0f51-3fbd0be-5a8c3-ded7bbed-1d655d5', - firstname: 'Rosendo', - lastname: 'Eriksson', - guardians: [ - { - email: 'Mitchell.Gustafsson84@example.org', - firstname: 'Mariam', - lastname: 'Johansson', - mobile: '07074537423', - address: 'MolinvÀgen 29', - }, - { - email: 'Rachelle_Olsson@example.net', - firstname: 'Shaniya', - lastname: 'Persson', - mobile: '070765878480', - address: 'MolinvÀgen 29', - }, - ], - className: '2B', - }, - { - sisId: '298c2-46a24d4-548b9-3d1f90ee-4fae0ab', - firstname: 'Sammy', - lastname: 'Persson', - guardians: [ - { - email: 'Gloria_Svensson@example.com', - firstname: 'Simeon', - lastname: 'Olsson', - mobile: '070753525610', - address: 'BörjesonsvÀgen 43', - }, - ], - className: '2B', - }, - { - sisId: 'e7628-09352ea-b5d19-1af845b7-63b3e08', - firstname: 'Abraham', - lastname: 'Svensson', - guardians: [ - { - email: 'Erica_Johansson40@example.net', - firstname: 'Carlotta', - lastname: 'Nilsson', - mobile: '070737951712', - address: 'AroseniusvÀgen 27', - }, - { - email: 'Malcolm_Gustafsson55@example.org', - firstname: 'Ramon', - lastname: 'Persson', - mobile: '07070395626', - address: 'AroseniusvÀgen 27', - }, - ], - className: '2B', - }, - { - sisId: 'ae315-4696438-b3db6-8f0a5b39-74e34bd', - firstname: 'Devante', - lastname: 'Olsson', - guardians: [ - { - email: 'Alf.Johansson39@example.com', - firstname: 'Schuyler', - lastname: 'Gustafsson', - mobile: '07070724289', - address: null, - }, - ], - className: '2B', - }, - { - sisId: '0d812-350f1d5-323aa-d5d93cdd-406e337', - firstname: 'Tyrell', - lastname: 'Eriksson', - guardians: [ - { - email: 'Brennon.Svensson@example.com', - firstname: 'Belle', - lastname: 'Nilsson', - mobile: '07070137347', - address: null, - }, - ], - className: '2B', - }, - ], - news: [ - { - id: 'asdfasdfasdfw', - author: 'VaktmÀstare Persson', - header: 'BrandslÀckare.', - intro: 'Idag hade vi en incident med en brandslÀckare.', - body: - '## Information om brandslÀckarincidenten\n\nHej, idag vid lunchtid utlöste en elev av misstag en pulverbrandslÀckare i kapprummet. En del pulver yrde runt i rummet och under saneringen fick eleverna i angrÀnsande klassrum vara i aulan istÀllet för klassrummet.\n\nFlera elever var pÄ plats i hallen nÀr detta intrÀffade men utrymdes kort dÀrefter. Pulvret Àr INTE hÀlsovÄdligt men kan ge upphov till halsirritation vid inandning.\n\nJag har pratat med berörda elever om det intrÀffade och uppmanat dem att ta hem klÀder och tillhörigheter som fanns i kapprummet eftersom de troligen blivit dammiga. Vi rekommenderar att ni tvÀttar eller vÀdrar dessa.', - imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg', - fullImageUrl: - 'https://cdn.breakit.se/assets/article/6607f9b923edb6f85aa4417bab43c0f8.jpg?d=980x500', - imageAltText: 'Nyhetsbild. Bildtext ej tillgÀnglig.', - published: '2020-08-16T21:10:00.000Z', - modified: '2021-01-22T14:49:00.000Z', - }, - { - id: 'asdfabbuasdfs', - author: 'Ada L.', - header: 'App, App, App', - intro: 'Denna vecka bygger vi appar!', - body: - '## Appar med öppen data \n\nDenna vecka har vi förmÄnen att fÄ besök av nÄgra förÀldrar som visar hur vi enkelt kan skapa appar som visar information ifrÄn öppna datakÀllor.\n\nEn fantastisk möjlighet att lÀra oss hur digitalisering skapar nya möjligheter i sÄvÀl skolan som arbetslivet.', - imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg', - fullImageUrl: - 'https://live.staticflickr.com/4063/4369776892_5cd42d27ba.jpg', - imageAltText: 'Nyhetsbild. Bildtext ej tillgÀnglig.', - published: '2020-10-13T09:10:00.000Z', - modified: '2021-02-09T15:45:00.000Z', - }, - { - id: 'asdfasdfasdfs', - author: 'Magister Svensson', - header: 'LÀxor vecka 6.', - intro: 'Alla elever mÄste göra sina lÀxor!', - body: - '## LÀxor vecka 6 \n\nFöljande lÀxor Àr obligatoriska:\n\n- Antikens historia\n- Svenska stormaktstiden\n- Statistik A\n- Flerdimensionell analys, del 1', - imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg', - fullImageUrl: - 'https://www.mitti.se/_internal/cimg!0/ejf8efxee735ymm8tm40q3hhkl36sdt.jpeg', - imageAltText: 'Nyhetsbild. Bildtext ej tillgÀnglig.', - published: '2020-08-16T21:10:00.000Z', - modified: '2021-01-22T14:49:00.000Z', - }, - ], - calendar: [ - { - title: 'Terminslut', - id: 73, - description: null, - location: null, - startDate: '2020-12-18', - endDate: '2020-12-18', - allDay: true, - }, - { - title: 'Terminen börjar', - id: 74, - description: null, - location: null, - startDate: '2021-01-12', - endDate: '2021-01-12', - allDay: true, - }, - { - title: 'APT - fritids stÀnger 15:45', - id: 75, - description: null, - location: null, - startDate: '2021-01-21', - endDate: '2021-01-21', - allDay: true, - }, - { - title: 'Utvecklingsamtal', - id: 76, - description: null, - location: null, - startDate: '2021-02-04', - endDate: '2021-02-04', - allDay: true, - }, - { - title: 'VÀnliga veckan', - id: 77, - description: null, - location: null, - startDate: '2021-02-08', - endDate: '2021-02-12', - allDay: true, - }, - { - title: 'Utvecklingsamtal', - id: 79, - description: null, - location: null, - startDate: '2021-02-09', - endDate: '2021-02-09', - allDay: true, - }, - { - title: 'Trygghetsdag', - id: 78, - description: null, - location: null, - startDate: '2021-02-12', - endDate: '2021-02-12', - allDay: true, - }, - { - title: 'APT fritids stÀnger 15:45', - id: 80, - description: null, - location: null, - startDate: '2021-02-25', - endDate: '2021-02-25', - allDay: true, - }, - { - title: 'Sportlov', - id: 81, - description: null, - location: null, - startDate: '2021-03-01', - endDate: '2021-03-05', - allDay: true, - }, - { - title: 'Studiedag', - id: 82, - description: null, - location: null, - startDate: '2021-03-22', - endDate: '2021-03-22', - allDay: true, - }, - { - title: 'APT - fritids stÀnger 15:45', - id: 83, - description: null, - location: null, - startDate: '2021-04-01', - endDate: '2021-04-01', - allDay: true, - }, - { - title: 'LÄngfredag', - id: 84, - description: null, - location: null, - startDate: '2021-04-02', - endDate: '2021-04-02', - allDay: true, - }, - { - title: 'PÄsklov', - id: 85, - description: null, - location: null, - startDate: '2021-04-05', - endDate: '2021-04-09', - allDay: true, - }, - { - title: 'FörÀldrarÄd', - id: 86, - description: null, - location: null, - startDate: '2021-04-20', - endDate: '2021-04-20', - allDay: true, - }, - { - title: 'Prao Äk 8', - id: 97, - description: null, - location: null, - startDate: '2021-04-26', - endDate: '2021-05-12', - allDay: true, - }, - { - title: 'Kristi HimmelfÀrd', - id: 87, - description: null, - location: null, - startDate: '2021-05-13', - endDate: '2021-05-13', - allDay: true, - }, - { - title: 'Lov', - id: 88, - description: null, - location: null, - startDate: '2021-05-14', - endDate: '2021-05-14', - allDay: true, - }, - { - title: 'APT Fritids stÀnger 15:45', - id: 90, - description: null, - location: null, - startDate: '2021-05-20', - endDate: '2021-05-20', - allDay: true, - }, - { - title: 'LÀsÄrsslut', - id: 91, - description: - "

 

", - location: null, - startDate: '2021-06-11', - endDate: '2021-06-11', - allDay: true, - }, - { - title: 'Fritids stÀngt', - id: 92, - description: - "

 

", - location: null, - startDate: '2021-06-14', - endDate: '2021-06-14', - allDay: true, - }, - ], - schedule: [], - menu: [ - { - title: 'MĂ„ndag - Vecka 51', - description: 'Kebabgryta ris
Ratatouille med kikÀrter', - }, - { - title: 'Tisdag - Vecka 51', - description: 'Ost-broccolisÄs pasta Fusilli', - }, - { - title: 'Onsdag - Vecka 51', - description: 'Köttbullar potatis grÀddsÄs lingon
Falafel', - }, - { - title: 'Torsdag - Vecka 51', - description: - 'Prinskorv potatis rödbetssallad +
Inlagd och senapssill', - }, - { - title: 'Fredag - Vecka 51', - description: - 'Avslutning Varmkorv bröd ketchup senap
( F-3 i matsalen frĂ„n 10:30 )', - }, - ], - notifications: [ - { - id: '9025f9-a1e685-d7c4668f09-e14bc5-0ab', - sender: 'Elevdokumentation', - dateCreated: '2020-12-10T14:31:29.966Z', - message: - 'Nu kan du ta del av ditt barns dokumentation av utvecklingssamtal', - url: - 'https://www.breakit.se/artikel/21404/kodaren-slog-larm-nu-akutstoppas-skolplattformen-i-stockholm', - category: null, - type: 'webnotify', - }, - { - id: 'bfe19b-766db3-b38d99d321-bbed3d-506', - sender: 'Planering och Bedömning', - dateCreated: '2020-11-16T13:24:00.000Z', - message: 'Ett nytt inlĂ€gg i en lĂ€rlogg har skapats.', - url: - 'https://www.breakit.se/artikel/21423/har-ar-it-bolaget-bakom-haveriet-pa-skolplattformen', - category: 'LĂ€rlogg', - type: 'avisering', - }, - { - id: 'a24061-1c9a4e-83dc479d7c-f44fe9-376', - sender: 'Planering och Bedömning', - dateCreated: '2020-06-10T12:18:00.000Z', - message: 'Nu finns det en bedömning att titta pĂ„.', - url: - 'https://www.svt.se/nyheter/lokalt/stockholm/skolplattformen-i-stockholm-beratta-om-era-erfarenheter', - category: 'Bedömning', - type: 'avisering', - }, - { - id: '79d65c-1f8240-35c94296ec-9f4bdc-cea', - sender: 'Planering och Bedömning', - dateCreated: '2020-03-24T14:28:00.000Z', - message: 'Nu finns det en bedömning att titta pĂ„.', - url: - 'https://www.breakit.se/artikel/18120/skolplattformen-kostade-700-miljoner-strid-med-entreprenor-om-varumarket', - category: 'Bedömning', - type: 'avisering', - }, - { - id: '9c5b7b-52c16d-b9fc2e8248-e4de76-279', - sender: 'Planering och Bedömning', - dateCreated: '2020-03-24T13:48:00.000Z', - message: 'Nu finns det en bedömning att titta pĂ„.', - url: - 'https://www.mitti.se/nyheter/forskolans-tur-att-fa-kritiserade-skolplattformen-app/lmsau!5338007/', - category: 'Bedömning', - type: 'avisering', - }, - ], - }, - 'eea96a-a3e045-caab589391-ed7d17-029': { - classmates: [ - { - sisId: '9ee9e-312233c-0df98-05fa5a65-a3787ec', - firstname: 'Raphael', - lastname: 'Olsson', - guardians: [ - { - email: 'Johan99@example.com', - firstname: 'Alessandra', - lastname: 'Svensson', - mobile: '070767120463', - address: 'FranklandsvĂ€gen 34', - }, - ], - className: '8C', - }, - { - sisId: 'd3a4b-16b53de-63c22-56d1ad24-4a64a2d', - firstname: 'Fanny', - lastname: 'Karlsson', - guardians: [ - { - email: 'Bernadette.Eriksson@example.org', - firstname: 'Bernadette', - lastname: 'Karlsson', - mobile: '070759877956', - address: null, - }, - { - email: 'Candice29@example.net', - firstname: 'Kelley', - lastname: 'Gustafsson', - mobile: '070748592035', - address: null, - }, - ], - className: '8C', - }, - { - sisId: '42bde-8fabd1c-7a00e-28aea88a-8481bac', - firstname: 'Jamie', - lastname: 'Persson', - guardians: [ - { - email: 'Louisa82@example.net', - firstname: 'Mose', - lastname: 'Larsson', - mobile: '07076548362', - address: null, - }, - ], - className: '8C', - }, - { - sisId: 'dad49-74308c8-83612-5eb7f3a5-e1c4047', - firstname: 'Iris', - lastname: 'Eriksson', - guardians: [ - { - email: 'Vaughn90@example.net', - firstname: 'Ezra', - lastname: 'Andersson', - mobile: '07078700165', - address: 'Björnsonsgatan 251 D Lgh 1503', - }, - { - email: 'Stephany_Svensson22@example.net', - firstname: 'Mia', - lastname: 'Larsson', - mobile: '070761752378', - address: 'Björnsonsgatan 251 D Lgh 1503', - }, - ], - className: '8C', - }, - { - sisId: 'b3425-ada6d70-d3acc-a49a12a6-8b3afdc', - firstname: 'Evans', - lastname: 'Nilsson', - guardians: [ - { - email: 'Terry_Svensson@example.com', - firstname: 'Christop', - lastname: 'Olsson', - mobile: '070767660094', - address: null, - }, - { - email: 'Johanna_Svensson30@example.org', - firstname: 'Madisen', - lastname: 'Johansson', - mobile: '07072269029', - address: null, - }, - ], - className: '8C', - }, - { - sisId: '67471-6c03979-9ef6e-bb2827c4-96d00d5', - firstname: 'Evy', - lastname: 'Larsson', - guardians: [ - { - email: 'Serenity.Gustafsson@example.net', - firstname: 'Toni', - lastname: 'Larsson', - mobile: '07075211567', - address: 'RoslinvĂ€gen 48', - }, - ], - className: '8C', - }, - { - sisId: 'f4040-516c4ed-34555-fd525183-6a2f666', - firstname: 'Maximillia', - lastname: 'Karlsson', - guardians: [ - { - email: 'Faustino.Andersson@example.com', - firstname: 'Eriberto', - lastname: 'Nilsson', - mobile: '07076024039', - address: 'BeckombergavĂ€gen 213 Lgh 1304', - }, - ], - className: '8C', - }, - { - sisId: 'a9494-75d8ca7-a5fd4-977eca3c-40edbc1', - firstname: 'Pia', - lastname: 'Karlsson', - guardians: [ - { - email: 'Arthur.Karlsson4@example.org', - firstname: 'Eldred', - lastname: 'Svensson', - mobile: '07077609534', - address: 'BörjesonsvĂ€gen 6', - }, - ], - className: '8C', - }, - { - sisId: '42a6d-3eaf407-fed01-4a9538de-b822503', - firstname: 'Logan', - lastname: 'Larsson', - guardians: [ - { - email: 'Blake4@example.org', - firstname: 'Jan', - lastname: 'Karlsson', - mobile: '070728715653', - address: 'BĂ€llstavĂ€gen 162', - }, - ], - className: '8C', - }, - { - sisId: '9077d-c323c8d-d0d29-5690abfb-d348317', - firstname: 'Torun', - lastname: 'Eriksson', - guardians: [ - { - email: 'Blanca98@example.net', - firstname: 'Dallin', - lastname: 'Eriksson', - mobile: '070766214425', - address: 'MolinvĂ€gen 1', - }, - ], - className: '8C', - }, - { - sisId: '31c68-5b86667-0701d-6b7e2471-89e6df9', - firstname: 'Izabella', - lastname: 'Johansson', - guardians: [ - { - email: 'Elouise_Johansson25@example.org', - firstname: 'Jerrold', - lastname: 'Nilsson', - mobile: '07073789274', - address: 'StobaeusvĂ€gen 11', - }, - ], - className: '8C', - }, - { - sisId: '1bb69-5f1c3a6-f0ea8-e1dbb608-2756a52', - firstname: 'Ella', - lastname: 'Persson', - guardians: [ - { - email: 'Shayna.Olsson54@example.net', - firstname: 'Onie', - lastname: 'Nilsson', - mobile: '07076957797', - address: null, - }, - ], - className: '8C', - }, - { - sisId: '348a7-2d0eccc-02981-a02ccb03-cb2a8f2', - firstname: 'Jaylen', - lastname: 'Larsson', - guardians: [ - { - email: 'Aileen_Andersson@example.net', - firstname: 'Tess', - lastname: 'Karlsson', - mobile: '070715315590', - address: 'PeringskiöldsvĂ€gen 64', - }, - ], - className: '8C', - }, - ], - news: [ - { - id: 'asdfasdfasdfa', - author: 'Rektor Gustavsson', - header: 'VĂ€lkommen till skolan!', - intro: - 'Hej alla barn och förĂ€ldrar och vĂ€lkomna till Storskolan! HĂ€r kommer en del information som kan vara bra att kĂ€nna till inför första dagen.', - body: - '## Information till förĂ€ldrar \n\nSkolan börjar kl 08.00 och slutar 18.00. Kommer man sent eller blir sjuk sĂ„ ska det anmĂ€las via Skolplattformen. Se till sĂ„ att dina barn har Ă€tit frukost. Frukt Ă€r nyttigt! \n\n## Information till barn\n\nLek Ă€r tillĂ„tet pĂ„ rasterna men enbart pĂ„ skolgĂ„rden. Medtag ej egna leksaker. TvĂ€tta hĂ€nderna.', - imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg', - fullImageUrl: - 'https://timbro.se/app/uploads/2020/10/broman-skolplattformen-1280x752.jpg', - imageAltText: 'Nyhetsbild. Bildtext ej tillgĂ€nglig.', - published: '2020-08-16T21:10:00.000Z', - modified: '2021-01-22T14:49:00.000Z', - }, - { - id: 'asdfabbuasdfs', - author: 'Ada L.', - header: 'App, App, App', - intro: 'Denna vecka bygger vi appar!', - body: - '## Appar med öppen data \n\nDenna vecka har vi förmĂ„nen att fĂ„ besök av nĂ„gra förĂ€ldrar som visar hur vi enkelt kan skapa appar som visar information ifrĂ„n öppna datakĂ€llor.\n\nEn fantastisk möjlighet att lĂ€ra oss hur digitalisering skapar nya möjligheter i sĂ„vĂ€l skolan som arbetslivet.', - imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg', - fullImageUrl: - 'https://live.staticflickr.com/4063/4369776892_5cd42d27ba.jpg', - imageAltText: 'Nyhetsbild. Bildtext ej tillgĂ€nglig.', - published: '2020-10-13T09:10:00.000Z', - modified: '2021-02-09T15:45:00.000Z', - }, - { - id: 'asdfasdfasdfs', - author: 'Magister Svensson', - header: 'LĂ€xor vecka 6.', - intro: 'Alla elever mĂ„ste göra sina lĂ€xor!', - body: - '## LĂ€xor vecka 6 \n\nFöljande lĂ€xor Ă€r obligatoriska:\n\n- Antikens historia\n- Svenska stormaktstiden\n- Statistik A\n- Flerdimensionell analys, del 1', - imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg', - fullImageUrl: - 'https://www.mitti.se/_internal/cimg!0/ejf8efxee735ymm8tm40q3hhkl36sdt.jpeg', - imageAltText: 'Nyhetsbild. Bildtext ej tillgĂ€nglig.', - published: '2020-08-16T21:10:00.000Z', - modified: '2021-01-22T14:49:00.000Z', - }, - { - id: 'asdfasdfasdfd', - author: 'Information frĂ„n Förskoleklass', - header: 'Vinteraktiviteter', - intro: - 'Vi kommer efter att förskoleklassen Ă€r slut arrangera olika vinteraktiviteter genom fridtidsverksamheten.', - body: - '## VĂ€nligen ta med hjĂ€lm, skridskor eller stjĂ€rtlapp.\n\n ![Bild](https://images.unsplash.com/photo-1495377701095-00261b767581?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=988&q=80)\n\n Alla barn mĂ„ste ha hjĂ€lm pĂ„ sig samt varma klĂ€der. Vi kommer Ă„ka i backen bakom skolbyggnaden samt anvĂ€nda isen som spolats vid Mullsjöskolan. Personal kommer finnas pĂ„ plats samt att vi erbjuda varm dryck, frukt och lek för de barn som ej har hjĂ€lm eller lĂ€mpligt Ă„kdon.', - imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg', - fullImageUrl: 'https://unsplash.com/photos/yB_aiAWkm40', - imageAltText: 'Nyhetsbild. Bildtext ej tillgĂ€nglig.', - published: '2020-08-16T21:10:00.000Z', - modified: '2021-01-22T14:49:00.000Z', - }, - { - id: 'asdfasdfasdfdsa', - author: 'Köket', - header: 'Ekologisk vecka i matsalen', - intro: 'Ekologiska veckan i matsalen vecka 11', - body: - '## Vi kommer ha tema jorden i matsalen och servera ekologisk mat frĂ„n hela vĂ€rlden med tema jorden. Detta för att belysa att man kan anvĂ€nda alla delar av rĂ„vaorna. Det kommer erbjudas rĂ€tter frĂ„n alla vĂ€rldsdelar som Ă€r producerat för jordens bĂ€sta. Smaklig spis hĂ€lsar Gunnel i köket med personal.', - imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg', - fullImageUrl: 'https://unsplash.com/photos/7K17MvT8qBg', - imageAltText: 'Nyhetsbild. Bildtext ej tillgĂ€nglig.', - published: '2021-01-16T21:10:03.000Z', - modified: '2021-01-17T14:40:00.000Z', - }, - { - id: 'asdfasdfasdfbvdsa', - author: 'VaktmĂ€staren', - header: 'Klotter i korridoren (igen)', - intro: - 'Ännu en gĂ„ng har vi rĂ„ka ut för skadegörelse i korridorerna vid Ă„k 5', - body: - '## TyvĂ€rr har flera elever klottat pĂ„ skĂ„p och vĂ€ggar vid Ă„k5 skĂ„pen. Detta Ă€r helt oacceptablet beteende och kostar skolan stora belopp att Ă„tgĂ€rda. Vi ber alla förĂ€ldrar prata med sina barn om klotter samt att det var vĂ€ldigt grovt spĂ„rkbruk. Personalen pĂ„ skolan kommer att hĂ„lla extra uppsikt och vi har Ă€ven pratat med en del av de inblandade eleverna i denna skadegörelse.\n\nPersonalen har Ă€ven börjat forska pĂ„ vad vissa av de skrivna orden betyder och Eva-Britt Ă€r förfasad över sprĂ„kbruket samt vad de innebĂ€r. Bernt kommer att pĂ„börja saneringen och Ă„terstĂ€llningen av skadegörelsen samt vakta korridorerna nogrannare för att sĂ€kerstĂ€lla att detta ej kommer ske igen.\n\n Klotter\n\nUPPDATERING: Det som Ă€r skrivet om Sara Ă€r inte sant! ', - imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg', - fullImageUrl: 'https://unsplash.com/photos/SkbEZ16VywM', - imageAltText: 'Nyhetsbild. Bildtext ej tillgĂ€nglig.', - published: '2021-02-02T14:10:03.000Z', - modified: '2021-02-02T14:15:00.000Z', - }, - ], - calendar: [ - { - title: 'Terminslut', - id: 73, - description: null, - location: null, - startDate: '2020-12-18', - endDate: '2020-12-18', - allDay: true, - }, - { - title: 'Terminen börjar', - id: 74, - description: null, - location: null, - startDate: '2021-01-12', - endDate: '2021-01-12', - allDay: true, - }, - { - title: 'APT - fritids stĂ€nger 15:45', - id: 75, - description: null, - location: null, - startDate: '2021-01-21', - endDate: '2021-01-21', - allDay: true, - }, - { - title: 'Utvecklingsamtal', - id: 76, - description: null, - location: null, - startDate: '2021-02-04', - endDate: '2021-02-04', - allDay: true, - }, - { - title: 'VĂ€nliga veckan', - id: 77, - description: null, - location: null, - startDate: '2021-02-08', - endDate: '2021-02-12', - allDay: true, - }, - { - title: 'Utvecklingsamtal', - id: 79, - description: null, - location: null, - startDate: '2021-02-09', - endDate: '2021-02-09', - allDay: true, - }, - { - title: 'Trygghetsdag', - id: 78, - description: null, - location: null, - startDate: '2021-02-12', - endDate: '2021-02-12', - allDay: true, - }, - { - title: 'APT fritids stĂ€nger 15:45', - id: 80, - description: null, - location: null, - startDate: '2021-02-25', - endDate: '2021-02-25', - allDay: true, - }, - { - title: 'Sportlov', - id: 81, - description: null, - location: null, - startDate: '2021-03-01', - endDate: '2021-03-05', - allDay: true, - }, - { - title: 'Studiedag', - id: 82, - description: null, - location: null, - startDate: '2021-03-22', - endDate: '2021-03-22', - allDay: true, - }, - { - title: 'APT - fritids stĂ€nger 15:45', - id: 83, - description: null, - location: null, - startDate: '2021-04-01', - endDate: '2021-04-01', - allDay: true, - }, - { - title: 'LĂ„ngfredag', - id: 84, - description: null, - location: null, - startDate: '2021-04-02', - endDate: '2021-04-02', - allDay: true, - }, - { - title: 'PĂ„sklov', - id: 85, - description: null, - location: null, - startDate: '2021-04-05', - endDate: '2021-04-09', - allDay: true, - }, - { - title: 'FörĂ€ldrarĂ„d', - id: 86, - description: null, - location: null, - startDate: '2021-04-20', - endDate: '2021-04-20', - allDay: true, - }, - { - title: 'Prao Ă„k 8', - id: 97, - description: null, - location: null, - startDate: '2021-04-26', - endDate: '2021-05-12', - allDay: true, - }, - { - title: 'Kristi HimmelfĂ€rd', - id: 87, - description: null, - location: null, - startDate: '2021-05-13', - endDate: '2021-05-13', - allDay: true, - }, - { - title: 'Lov', - id: 88, - description: null, - location: null, - startDate: '2021-05-14', - endDate: '2021-05-14', - allDay: true, - }, - { - title: 'APT Fritids stĂ€nger 15:45', - id: 90, - description: null, - location: null, - startDate: '2021-05-20', - endDate: '2021-05-20', - allDay: true, - }, - ], - schedule: [], - menu: [ - { - title: 'MĂ„ndag - Vecka 51', - description: 'Kebabgryta ris
Ratatouille med kikÀrter', - }, - { - title: 'Tisdag - Vecka 51', - description: 'Ost-broccolisÄs pasta Fusilli', - }, - { - title: 'Onsdag - Vecka 51', - description: 'Köttbullar potatis grÀddsÄs lingon
Falafel', - }, - { - title: 'Torsdag - Vecka 51', - description: - 'Prinskorv potatis rödbetssallad +
Inlagd och senapssill', - }, - { - title: 'Fredag - Vecka 51', - description: - 'Avslutning Varmkorv bröd ketchup senap
( F-3 i matsalen frĂ„n 10:30 )', - }, - ], - notifications: [ - { - id: 'e1b5bc-597fa8-5511794939-3614e1-615', - sender: 'Planering och Bedömning', - dateCreated: '2020-12-02T14:02:00.000Z', - message: 'Ett nytt inlĂ€gg i en lĂ€rlogg har skapats.', - url: - 'https://www.mitti.se/nyheter/rekorddyr-skolplattform-kostar-258-miljoner-till/lmsao!5381301/', - category: 'LĂ€rlogg', - messageType: 'avisering', - }, - { - id: '7dbc20-bfa1ac-e20171b865-82c1f7-f3c', - sender: 'Planering och Bedömning', - dateCreated: '2020-12-01T12:43:00.000Z', - message: 'Ett nytt inlĂ€gg i en lĂ€rlogg har skapats.', - url: - 'https://computersweden.idg.se/2.2683/1.722561/lacka-skolplattformen-datainspektionen', - category: 'LĂ€rlogg', - messageType: 'avisering', - }, - { - id: 'a6829b-ecf912-b71582e8fb-b6dc14-f60', - sender: 'Planering och Bedömning', - dateCreated: '2020-11-24T13:34:00.000Z', - message: 'Ett nytt inlĂ€gg i en lĂ€rlogg har skapats.', - url: 'https://www.dagensarena.se/redaktionen/en-systemkramare-ger-upp/', - category: 'LĂ€rlogg', - messageType: 'avisering', - }, - { - id: '3cedb4-767d24-8ccd6ac3ac-c05cb7-a3a', - sender: 'Planering och Bedömning', - dateCreated: '2020-11-16T13:24:00.000Z', - message: 'Ett nytt inlĂ€gg i en lĂ€rlogg har skapats.', - url: - 'https://www.breakit.se/artikel/27075/skolplattformen-kostade-1-miljard-att-bygga-nu-tvingas-stockholm-bota', - category: 'LĂ€rlogg', - messageType: 'avisering', - }, - { - id: '6ace13-5f99da-d1d50ac7a6-4a6108-d8e', - sender: 'Planering och Bedömning', - dateCreated: '2020-11-12T13:27:00.000Z', - message: 'Ett nytt inlĂ€gg i en lĂ€rlogg har skapats.', - url: - 'https://www.nyteknik.se/sakerhet/ygeman-om-datalackan-i-skolplattformen-det-ar-upprorande-6968853', - category: 'LĂ€rlogg', - messageType: 'avisering', - }, - ], - }, -} - -export const user = (): User => ({ - personalNumber: '195001182046', // Test personal number from Skatteverket - firstName: 'Namn', - lastName: 'Namnsson', - isAuthenticated: true -}) - -export const children = (): EtjanstChild[] => [ - { - name: 'Shanel Nilsson (elev)', - id: '39b59e-bf4b9f-f68ac25321-977218-bf0', - sdsId: '8e81a06-53f55fb-d1b93-f0e5b357ad0b7caaf1d36', - status: 'F;GR', - schoolId: '9e58434-8800-da59547-614bf0e-e09c015', - }, - { - name: 'Alan Nilsson (elev)', - id: 'eea96a-a3e045-caab589391-ed7d17-029', - sdsId: 'bc2d341-8d970cc-69526-43501c082aaa870d9fe99', - status: 'GR', - schoolId: '8e6b13b-3116-e66c39b-a4c3fa5-a1d72d9', - }, -] -export const skola24Children = (): Skola24Child[] => [ - { - firstName: 'Shanel', - lastName: 'Jonsson Nilsson', - personGuid: 'abc123', - schoolGuid: 'def456', - schoolID: 'ghi789', - timetableID: 'jkl012', - unitGuid: 'mno345' - }, -] - -export const classmates = (child: EtjanstChild): Classmate[] => - data[child.id].classmates - -export const news = (child: Child): NewsItem[] => data[child.id].news - -export const calendar = (child: Child): CalendarItem[] => - data[child.id].calendar - -export const schedule = (child: Child): ScheduleItem[] => - data[child.id].schedule - -export const menu = (child: Child): MenuItem[] => data[child.id].menu - -export const notifications = (child: Child): Notification[] => - data[child.id].notifications - -export const timetable = (child: Skola24Child): TimetableEntry[] => { - if (!child.personGuid || !child.unitGuid) return [] - return [ - { - id: 'N2FjMDc1NjYtZmM2Yy0wZDQyLTY3M2YtZWI5NGNiZDA3ZGU4', - code: 'Lunch', - name: 'Lunch', - category: '', - blockName: '', - dayOfWeek: 1, - location: 'Ö5', - teacher: '', - timeEnd: '12:05:00', - timeStart: '11:40:00', - dateStart: '2021-04-12T11:40:00.000+02:00', - dateEnd: '2021-04-12T12:05:00.000+02:00', - }, - { - id: 'ZTQ1NWE0N2EtNzAwOS0wZTAzLTQ1ZDYtNTA1NWI4Y2JhNDYw', - code: 'BL', - name: 'Bild', - category: '', - blockName: '', - dayOfWeek: 1, - location: '221', - teacher: 'KUr', - timeEnd: '11:35:00', - timeStart: '09:40:00', - dateStart: '2021-04-12T09:40:00.000+02:00', - dateEnd: '2021-04-12T11:35:00.000+02:00', - }, - { - id: 'YjAxODRmY2QtNTJjZS0wMDJlLTYxOGItYmFlNTVlNDgzZmVk', - code: 'NO', - name: 'Naturorienterande Ă€mnen', - category: '', - comment: 'a)', - blockName: '', - dayOfWeek: 1, - location: '307', - teacher: 'TBo', - timeEnd: '13:30:00', - timeStart: '12:30:00', - dateStart: '2021-04-12T12:30:00.000+02:00', - dateEnd: '2021-04-12T13:30:00.000+02:00', - }, - { - id: 'MWRiZGI1NzgtYWIzNy0wYzMwLTVkMmEtMWFjNWRkMTRmOTdh', - code: 'IDH', - name: 'Idrott & hĂ€lsa', - category: '', - blockName: '', - dayOfWeek: 1, - location: '215', - teacher: 'HAl', - timeEnd: '15:45:00', - timeStart: '14:40:00', - dateStart: '2021-04-12T14:40:00.000+02:00', - dateEnd: '2021-04-12T15:45:00.000+02:00', - }, - { - id: 'MmZkZTZiMzMtMjdjMS0wZGIzLTUzYWYtZTg0Zjc1NDRlNzQw', - code: 'M2FR', - name: 'Franska', - category: 'Moderna sprĂ„k, sprĂ„kval', - blockName: '', - dayOfWeek: 1, - location: '304', - teacher: 'DNi', - timeEnd: '14:25:00', - timeStart: '13:40:00', - dateStart: '2021-04-12T13:40:00.000+02:00', - dateEnd: '2021-04-12T14:25:00.000+02:00', - }, - { - id: 'MzAxMzU3MWItZGM1Ny0wOGVhLTVkZjUtOGFkMGIyYTY2OTAx', - code: 'SO', - name: 'SamhĂ€llsorienterande Ă€mnen', - category: '', - blockName: '', - dayOfWeek: 1, - location: '303', - teacher: 'HRr', - timeEnd: '09:25:00', - timeStart: '08:15:00', - dateStart: '2021-04-12T08:15:00.000+02:00', - dateEnd: '2021-04-12T09:25:00.000+02:00', - }, - { - id: 'NDY3MDY1MmYtOTIzYi0wZmQ0LTVlZGEtNGVhZDRkOTExNTgz', - code: 'M2FR', - name: 'Franska', - category: 'Moderna sprĂ„k, sprĂ„kval', - blockName: '', - dayOfWeek: 2, - location: '302,FjĂ€rr asd asdasd asdad aasdds', - teacher: 'DNi', - timeEnd: '09:50:00', - timeStart: '09:05:00', - dateStart: '2021-04-13T09:05:00.000+02:00', - dateEnd: '2021-04-13T09:50:00.000+02:00', - }, - { - id: 'NmE4OTU1NmItYzM0ZS0wYTI1LTYzM2QtYzBiN2M4OTVmYTQ3', - code: 'EN', - name: 'Engelska', - category: '', - blockName: '', - dayOfWeek: 2, - location: 'FjĂ€rr', - teacher: 'TPe', - timeEnd: '13:15:00', - timeStart: '12:30:00', - dateStart: '2021-04-13T12:30:00.000+02:00', - dateEnd: '2021-04-13T13:15:00.000+02:00', - }, - { - id: 'NDAxODRjOTctMmE5ZC0wMzdjLTY2NDMtODhlODEzOTQ3YTJh', - code: 'Lunch', - name: 'Lunch', - category: '', - blockName: '', - dayOfWeek: 2, - location: 'FjĂ€rr', - teacher: '', - timeEnd: '12:05:00', - timeStart: '11:40:00', - dateStart: '2021-04-13T11:40:00.000+02:00', - dateEnd: '2021-04-13T12:05:00.000+02:00', - }, - { - id: 'ZTc4YTcyZTUtMDc0NS0wNDE0LTVjODctYjY0MzQ2MGM3MDll', - code: 'MA', - name: 'Matematik', - category: '', - blockName: '', - dayOfWeek: 2, - location: 'FjĂ€rr', - teacher: 'CBr', - timeEnd: '11:20:00', - timeStart: '10:00:00', - dateStart: '2021-04-13T10:00:00.000+02:00', - dateEnd: '2021-04-13T11:20:00.000+02:00', - }, - { - id: 'MjRkMWE4YTItYTk5ZC0wYTFmLTVhMDgtMThiMmNhZDc1ZDUz', - code: 'MU', - name: 'Musik', - category: '', - blockName: '', - dayOfWeek: 2, - location: 'FjĂ€rr', - teacher: 'KBj', - timeEnd: '14:15:00', - timeStart: '13:30:00', - dateStart: '2021-04-13T13:30:00.000+02:00', - dateEnd: '2021-04-13T14:15:00.000+02:00', - }, - { - id: 'NTU4ZTc4ZTctNDQyMy0wMjVkLTRiYzktZGUwYmFmYzk2YTlj', - code: 'EN', - name: 'Engelska', - category: '', - blockName: '', - dayOfWeek: 3, - location: '303', - teacher: 'TPe', - timeEnd: '09:55:00', - timeStart: '09:10:00', - dateStart: '2021-04-14T09:10:00.000+02:00', - dateEnd: '2021-04-14T09:55:00.000+02:00', - }, - { - id: 'NDUyNjIxODItYzFiOC0wOTFjLTYwODYtZDllZjZjN2QyYzA3', - code: 'SV', - name: 'Svenska', - category: '', - comment: 'a)', - blockName: '', - dayOfWeek: 3, - location: '303', - teacher: 'JCa', - timeEnd: '14:45:00', - timeStart: '14:00:00', - dateStart: '2021-04-14T14:00:00.000+02:00', - dateEnd: '2021-04-14T14:45:00.000+02:00', - }, - { - id: 'NDdkMGI0ZjItMjkxMC0wYWI1LTQ0YWMtNDY3NTdkZTE2Njg3', - code: 'SO', - name: 'Engelska', - category: 'SamhĂ€llsorienterande Ă€mnen', - blockName: '', - dayOfWeek: 3, - location: '303', - teacher: 'HRr', - timeEnd: '11:00:00', - timeStart: '10:05:00', - dateStart: '2021-04-14T10:05:00.000+02:00', - dateEnd: '2021-04-14T11:00:00.000+02:00', - }, - { - id: 'ZTI2ZDgyNWUtM2ZlOS0wZDVmLTY5NTctNGYzZThjMTMxOTdh', - code: 'NO', - name: 'Naturorienterande Ă€mnen', - category: '', - comment: 'a)', - blockName: '', - dayOfWeek: 3, - location: '307', - teacher: 'TBo', - timeEnd: '13:50:00', - timeStart: '12:50:00', - dateStart: '2021-04-14T12:50:00.000+02:00', - dateEnd: '2021-04-14T13:50:00.000+02:00', - }, - { - id: 'NzMxNjczNGMtMmZmZi0wM2YzLTU0ZjMtODdjOTAwYzIwNTUw', - code: 'Lunch', - name: 'Lunch', - category: '', - blockName: '', - dayOfWeek: 3, - location: 'Ö5', - teacher: '', - timeEnd: '12:40:00', - timeStart: '12:15:00', - dateStart: '2021-04-14T12:15:00.000+02:00', - dateEnd: '2021-04-14T12:40:00.000+02:00', - }, - { - id: 'MWRkZjhlZTktNTBmMC0wZjNhLTQ1OTgtMWJkOWM3MjI2NWQ4', - code: 'SV', - name: 'Svenska', - category: '', - blockName: '', - dayOfWeek: 3, - location: '303', - teacher: 'JCa', - timeEnd: '12:05:00', - timeStart: '11:20:00', - dateStart: '2021-04-14T11:20:00.000+02:00', - dateEnd: '2021-04-14T12:05:00.000+02:00', - }, - { - id: 'NzM2Mjc2ZTYtY2JlYy0wOTc1LTU1ZGYtNjMwZjhjZWVjNjgy', - code: 'MA', - name: 'Matematik', - category: '', - comment: 'a)', - blockName: '', - dayOfWeek: 3, - location: '307', - teacher: 'CBr', - timeEnd: '15:45:00', - timeStart: '15:00:00', - dateStart: '2021-04-14T15:00:00.000+02:00', - dateEnd: '2021-04-14T15:45:00.000+02:00', - }, - { - id: 'YWNlZmEzZjYtM2EwNC0wYWY3LTU1N2MtMDBlMTA4MDQzMzRl', - code: 'MU', - name: 'Musik', - category: '', - blockName: '', - dayOfWeek: 3, - location: '504', - teacher: 'KBj', - timeEnd: '09:00:00', - timeStart: '08:15:00', - dateStart: '2021-04-14T08:15:00.000+02:00', - dateEnd: '2021-04-14T09:00:00.000+02:00', - }, - { - id: 'NDc4MThmMDYtYmYxYi0wZDBkLTdhNmItZGVjMjY3OWY3MmYz', - code: 'IDH', - name: 'Idrott & HĂ€lsa', - category: '', - blockName: '', - dayOfWeek: 4, - location: 'FjĂ€rr', - teacher: 'AKö,CSv,HAl', - timeEnd: '15:45:00', - timeStart: '14:35:00', - dateStart: '2021-04-15T14:35:00.000+02:00', - dateEnd: '2021-04-15T15:45:00.000+02:00', - }, - { - id: 'ZjQyZjNkOWItYWMzZi0wYWRhLTQ3YzItNTZiNTJkOTRmY2Iy', - code: 'M2FR', - name: 'Franska', - category: 'Moderna sprĂ„k, sprĂ„kval', - blockName: '', - dayOfWeek: 4, - location: 'FjĂ€rr', - teacher: 'DNi', - timeEnd: '11:55:00', - timeStart: '11:10:00', - dateStart: '2021-04-15T11:10:00.000+02:00', - dateEnd: '2021-04-15T11:55:00.000+02:00', - }, - { - id: 'YzQ2NWZlOWMtYzM3ZC0wYzBlLTQzNTQtODMyYmU3ODcxMDQ3', - code: 'MTID', - name: 'Mentorstid', - category: 'Diverse', - comment: 'ArbetslagsrĂ„d 6C', - blockName: '', - dayOfWeek: 4, - location: 'FjĂ€rr', - teacher: 'JCa,CBr', - timeEnd: '10:00:00', - timeStart: '09:15:00', - dateStart: '2021-04-15T09:15:00.000+02:00', - dateEnd: '2021-04-15T10:00:00.000+02:00', - }, - { - id: 'YzMwMGY0YzAtNjhjNi0wYzY0LTU1MjctODg2MWQ4ZTRmZTI2', - code: 'MU', - name: 'Musik', - category: '', - blockName: '', - dayOfWeek: 4, - location: 'FjĂ€rr', - teacher: 'KBj', - timeEnd: '10:55:00', - timeStart: '10:10:00', - dateStart: '2021-04-15T10:10:00.000+02:00', - dateEnd: '2021-04-15T10:55:00.000+02:00', - }, - { - id: 'ZDNlNTFhMGUtYWFlYy0wOGI0LTVlMGItOTc0MzFiZmIwODcx', - code: 'Lunch', - name: 'Lunch', - category: 'Diverse', - blockName: '', - dayOfWeek: 4, - location: 'FjĂ€rr', - teacher: '', - timeEnd: '12:25:00', - timeStart: '12:00:00', - dateStart: '2021-04-15T12:00:00.000+02:00', - dateEnd: '2021-04-15T12:25:00.000+02:00', - }, - { - id: 'MDRiZWMyODMtNjEwZC0wZDYwLTRlOWItYTY1MjAwZTc0YTZm', - code: 'SO', - name: 'SamhĂ€llsorienterande Ă€mnen', - category: '', - blockName: '', - dayOfWeek: 4, - location: 'FjĂ€rr', - teacher: 'HRr', - timeEnd: '13:10:00', - timeStart: '12:35:00', - dateStart: '2021-04-15T12:35:00.000+02:00', - dateEnd: '2021-04-15T13:10:00.000+02:00', - }, - { - id: 'YTA0ZTA2NTktYTU5MS0wMTFmLTVlYWYtNWM1MTgxNDJlMDcy', - code: 'EN', - name: 'Engelska', - category: '', - comment: 'a)', - blockName: '', - dayOfWeek: 4, - location: 'FjĂ€rr', - teacher: 'TPe', - timeEnd: '14:20:00', - timeStart: '13:35:00', - dateStart: '2021-04-15T13:35:00.000+02:00', - dateEnd: '2021-04-15T14:20:00.000+02:00', - }, - { - id: 'OGJhN2MxYTYtMDQ4NS0wNWNhLTUwZWEtZDQ5YzQyMzFhYzc5', - code: 'Lunch', - name: 'Lunch', - category: 'Diverse', - blockName: '', - dayOfWeek: 5, - location: 'Ö5', - teacher: '', - timeEnd: '12:05:00', - timeStart: '11:40:00', - dateStart: '2021-04-16T11:40:00.000+02:00', - dateEnd: '2021-04-16T12:05:00.000+02:00', - }, - { - id: 'ZmUwMGEwM2QtNTExMy0wODliLTY1ZGEtODM0YmRjNjc1NDIw', - code: 'MA', - name: 'Matematik', - category: '', - comment: 'a)', - blockName: '', - dayOfWeek: 5, - location: '303', - teacher: 'CBr', - timeEnd: '14:00:00', - timeStart: '13:15:00', - dateStart: '2021-04-16T13:15:00.000+02:00', - dateEnd: '2021-04-16T14:00:00.000+02:00', - }, - { - id: 'Y2IwYjYzZDEtODAxYi0wMTNjLTRjNDMtMDFlODgzMmY4MWEy', - code: 'MU', - name: 'Musik', - category: '', - comment: 'a)', - blockName: '', - dayOfWeek: 5, - location: '510', - teacher: 'KBj', - timeEnd: '13:05:00', - timeStart: '12:20:00', - dateStart: '2021-04-16T12:20:00.000+02:00', - dateEnd: '2021-04-16T13:05:00.000+02:00', - }, - { - id: 'N2JkMGFiOTYtMjI5OC0wMjZiLTc3OGEtN2JkN2Q4MDZkNTEy', - code: 'SL', - name: 'Slöjd', - category: '', - comment: 'tmtx)', - blockName: '', - dayOfWeek: 5, - location: '860', - teacher: 'EAl', - timeEnd: '15:10:00', - timeStart: '14:10:00', - dateStart: '2021-04-16T14:10:00.000+02:00', - dateEnd: '2021-04-16T15:10:00.000+02:00', - }, - { - id: 'NzkxMjE3MDctMWExNS0wN2RmLTQwMzQtNTEyZTczZjQyZTUw', - code: 'SV', - name: 'Svenska', - category: '', - blockName: '', - dayOfWeek: 5, - location: '303', - teacher: 'JCa', - timeEnd: '10:35:00', - timeStart: '09:20:00', - dateStart: '2021-04-16T09:20:00.000+02:00', - dateEnd: '2021-04-16T10:35:00.000+02:00', - }, - { - id: 'ZTU1ZDQxNzQtN2Q3Yy0wMDMxLTY2ZmYtZmIyNGM5MjM3ZTRj', - code: 'MA', - name: 'Matematik', - category: '', - blockName: '', - dayOfWeek: 5, - location: '303', - teacher: 'CBr', - timeEnd: '11:35:00', - timeStart: '10:40:00', - dateStart: '2021-04-16T10:40:00.000+02:00', - dateEnd: '2021-04-16T11:35:00.000+02:00', - } - ] -} diff --git a/libs/api-skolplattformen/lib/fakeData/children.ts b/libs/api-skolplattformen/lib/fakeData/children.ts new file mode 100644 index 00000000..b37bc8e2 --- /dev/null +++ b/libs/api-skolplattformen/lib/fakeData/children.ts @@ -0,0 +1,29 @@ +import { EtjanstChild, Skola24Child } from "@skolplattformen/api" + +export const children = (): EtjanstChild[] => [ + { + name: 'Shanel Nilsson (elev)', + id: '39b59e-bf4b9f-f68ac25321-977218-bf0', + sdsId: '8e81a06-53f55fb-d1b93-f0e5b357ad0b7caaf1d36', + status: 'F;GR', + schoolId: '9e58434-8800-da59547-614bf0e-e09c015', + }, + { + name: 'Alan Nilsson (elev)', + id: 'eea96a-a3e045-caab589391-ed7d17-029', + sdsId: 'bc2d341-8d970cc-69526-43501c082aaa870d9fe99', + status: 'GR', + schoolId: '8e6b13b-3116-e66c39b-a4c3fa5-a1d72d9', + }, +] +export const skola24Children = (): Skola24Child[] => [ + { + firstName: 'Shanel', + lastName: 'Jonsson Nilsson', + personGuid: 'abc123', + schoolGuid: 'def456', + schoolID: 'Superskolan', + timetableID: 'jkl012', + unitGuid: 'mno345' + }, +] diff --git a/libs/api-skolplattformen/lib/fakeData/classmates.ts b/libs/api-skolplattformen/lib/fakeData/classmates.ts new file mode 100644 index 00000000..688a12fe --- /dev/null +++ b/libs/api-skolplattformen/lib/fakeData/classmates.ts @@ -0,0 +1,448 @@ +import { Child, Classmate } from '@skolplattformen/api'; +import { children } from './children' + +export const classmates = (child: Child): Classmate[] => classmatesData.get(child.id) ?? [] + +const [child1, child2] = children() + +const classmatesData = new Map([ + [ + child1.id, [ + { + sisId: 'd004a-98d965a-45174-d2894ca2-f74ebcb', + firstname: 'Darion', + lastname: 'Gustafsson', + guardians: [ + { + email: 'Mike_Svensson@example.net', + firstname: 'Tad', + lastname: 'Eriksson', + mobile: '07074791613', + address: 'MartinvĂ€gen 50', + }, + ], + className: '2B', + }, + { + sisId: '54075-284de06-5664c-750b7b13-520fb61', + firstname: 'Brock', + lastname: 'Andersson', + guardians: [ + { + email: 'Brad56@example.org', + firstname: 'Camren', + lastname: 'Eriksson', + mobile: '07075129297', + address: undefined, + }, + ], + className: '2B', + }, + { + sisId: 'c1fc7-285f95d-c0f37-ea48a297-281e985', + firstname: 'Eloy', + lastname: 'Karlsson', + guardians: [ + { + email: 'Samara.Larsson@example.net', + firstname: 'Ike', + lastname: 'Gustafsson', + mobile: '07077667407', + address: undefined, + }, + ], + className: '2B', + }, + { + sisId: '212e9-8a2609c-b29c1-97a32bd8-5f84645', + firstname: 'Kristina', + lastname: 'Eriksson', + guardians: [ + { + email: 'Doug57@example.com', + firstname: 'Rollin', + lastname: 'Olsson', + mobile: '07071720107', + address: 'HöckertsvĂ€gen 2', + }, + ], + className: '2B', + }, + { + sisId: '01d21-ebc6f8b-526f8-7cfba0ab-26b9956', + firstname: 'Cydney', + lastname: 'Larsson', + guardians: [ + { + email: 'Davon6@example.org', + firstname: 'Oleta', + lastname: 'Svensson', + mobile: '07079762186', + address: undefined, + }, + ], + className: '2B', + }, + { + sisId: 'a45bb-8a481af-0ad12-7bd1fa4c-1eed4b1', + firstname: 'Berneice', + lastname: 'Persson', + guardians: [ + { + email: 'Milford_Johansson72@example.com', + firstname: 'Arely', + lastname: 'Johansson', + mobile: '07071926019', + address: 'RoslinvĂ€gen 36', + }, + ], + className: '2B', + }, + { + sisId: '32f31-039fbed-9060b-2d857c46-e47177d', + firstname: 'Emory', + lastname: 'Svensson', + guardians: [ + { + email: 'Alfredo_Nilsson96@example.org', + firstname: 'Dolores', + lastname: 'Andersson', + mobile: '070752561937', + address: 'BörjesonsvĂ€gen 6', + }, + ], + className: '2B', + }, + { + sisId: 'c9d0a-28c371d-e7be2-9781386b-6841eb0', + firstname: 'Maryjane', + lastname: 'Eriksson', + guardians: [ + { + email: 'Eula_Olsson@example.net', + firstname: 'Wendy', + lastname: 'Andersson', + mobile: '07078513037', + address: undefined, + }, + { + email: 'Lesley_Persson45@example.org', + firstname: 'Erich', + lastname: 'Persson', + mobile: '070788191316', + address: undefined, + }, + ], + className: '2B', + }, + { + sisId: 'e0f51-3fbd0be-5a8c3-ded7bbed-1d655d5', + firstname: 'Rosendo', + lastname: 'Eriksson', + guardians: [ + { + email: 'Mitchell.Gustafsson84@example.org', + firstname: 'Mariam', + lastname: 'Johansson', + mobile: '07074537423', + address: 'MolinvĂ€gen 29', + }, + { + email: 'Rachelle_Olsson@example.net', + firstname: 'Shaniya', + lastname: 'Persson', + mobile: '070765878480', + address: 'MolinvĂ€gen 29', + }, + ], + className: '2B', + }, + { + sisId: '298c2-46a24d4-548b9-3d1f90ee-4fae0ab', + firstname: 'Sammy', + lastname: 'Persson', + guardians: [ + { + email: 'Gloria_Svensson@example.com', + firstname: 'Simeon', + lastname: 'Olsson', + mobile: '070753525610', + address: 'BörjesonsvĂ€gen 43', + }, + ], + className: '2B', + }, + { + sisId: 'e7628-09352ea-b5d19-1af845b7-63b3e08', + firstname: 'Abraham', + lastname: 'Svensson', + guardians: [ + { + email: 'Erica_Johansson40@example.net', + firstname: 'Carlotta', + lastname: 'Nilsson', + mobile: '070737951712', + address: 'AroseniusvĂ€gen 27', + }, + { + email: 'Malcolm_Gustafsson55@example.org', + firstname: 'Ramon', + lastname: 'Persson', + mobile: '07070395626', + address: 'AroseniusvĂ€gen 27', + }, + ], + className: '2B', + }, + { + sisId: 'ae315-4696438-b3db6-8f0a5b39-74e34bd', + firstname: 'Devante', + lastname: 'Olsson', + guardians: [ + { + email: 'Alf.Johansson39@example.com', + firstname: 'Schuyler', + lastname: 'Gustafsson', + mobile: '07070724289', + address: undefined, + }, + ], + className: '2B', + }, + { + sisId: '0d812-350f1d5-323aa-d5d93cdd-406e337', + firstname: 'Tyrell', + lastname: 'Eriksson', + guardians: [ + { + email: 'Brennon.Svensson@example.com', + firstname: 'Belle', + lastname: 'Nilsson', + mobile: '07070137347', + address: undefined, + }, + ], + className: '2B', + }, + ]], + [ + child2.id, [ + { + sisId: '9ee9e-312233c-0df98-05fa5a65-a3787ec', + firstname: 'Raphael', + lastname: 'Olsson', + guardians: [ + { + email: 'Johan99@example.com', + firstname: 'Alessandra', + lastname: 'Svensson', + mobile: '070767120463', + address: 'FranklandsvĂ€gen 34', + }, + ], + className: '8C', + }, + { + sisId: 'd3a4b-16b53de-63c22-56d1ad24-4a64a2d', + firstname: 'Fanny', + lastname: 'Karlsson', + guardians: [ + { + email: 'Bernadette.Eriksson@example.org', + firstname: 'Bernadette', + lastname: 'Karlsson', + mobile: '070759877956', + address: undefined, + }, + { + email: 'Candice29@example.net', + firstname: 'Kelley', + lastname: 'Gustafsson', + mobile: '070748592035', + address: undefined, + }, + ], + className: '8C', + }, + { + sisId: '42bde-8fabd1c-7a00e-28aea88a-8481bac', + firstname: 'Jamie', + lastname: 'Persson', + guardians: [ + { + email: 'Louisa82@example.net', + firstname: 'Mose', + lastname: 'Larsson', + mobile: '07076548362', + address: undefined, + }, + ], + className: '8C', + }, + { + sisId: 'dad49-74308c8-83612-5eb7f3a5-e1c4047', + firstname: 'Iris', + lastname: 'Eriksson', + guardians: [ + { + email: 'Vaughn90@example.net', + firstname: 'Ezra', + lastname: 'Andersson', + mobile: '07078700165', + address: 'Björnsonsgatan 251 D Lgh 1503', + }, + { + email: 'Stephany_Svensson22@example.net', + firstname: 'Mia', + lastname: 'Larsson', + mobile: '070761752378', + address: 'Björnsonsgatan 251 D Lgh 1503', + }, + ], + className: '8C', + }, + { + sisId: 'b3425-ada6d70-d3acc-a49a12a6-8b3afdc', + firstname: 'Evans', + lastname: 'Nilsson', + guardians: [ + { + email: 'Terry_Svensson@example.com', + firstname: 'Christop', + lastname: 'Olsson', + mobile: '070767660094', + address: undefined, + }, + { + email: 'Johanna_Svensson30@example.org', + firstname: 'Madisen', + lastname: 'Johansson', + mobile: '07072269029', + address: undefined, + }, + ], + className: '8C', + }, + { + sisId: '67471-6c03979-9ef6e-bb2827c4-96d00d5', + firstname: 'Evy', + lastname: 'Larsson', + guardians: [ + { + email: 'Serenity.Gustafsson@example.net', + firstname: 'Toni', + lastname: 'Larsson', + mobile: '07075211567', + address: 'RoslinvĂ€gen 48', + }, + ], + className: '8C', + }, + { + sisId: 'f4040-516c4ed-34555-fd525183-6a2f666', + firstname: 'Maximillia', + lastname: 'Karlsson', + guardians: [ + { + email: 'Faustino.Andersson@example.com', + firstname: 'Eriberto', + lastname: 'Nilsson', + mobile: '07076024039', + address: 'BeckombergavĂ€gen 213 Lgh 1304', + }, + ], + className: '8C', + }, + { + sisId: 'a9494-75d8ca7-a5fd4-977eca3c-40edbc1', + firstname: 'Pia', + lastname: 'Karlsson', + guardians: [ + { + email: 'Arthur.Karlsson4@example.org', + firstname: 'Eldred', + lastname: 'Svensson', + mobile: '07077609534', + address: 'BörjesonsvĂ€gen 6', + }, + ], + className: '8C', + }, + { + sisId: '42a6d-3eaf407-fed01-4a9538de-b822503', + firstname: 'Logan', + lastname: 'Larsson', + guardians: [ + { + email: 'Blake4@example.org', + firstname: 'Jan', + lastname: 'Karlsson', + mobile: '070728715653', + address: 'BĂ€llstavĂ€gen 162', + }, + ], + className: '8C', + }, + { + sisId: '9077d-c323c8d-d0d29-5690abfb-d348317', + firstname: 'Torun', + lastname: 'Eriksson', + guardians: [ + { + email: 'Blanca98@example.net', + firstname: 'Dallin', + lastname: 'Eriksson', + mobile: '070766214425', + address: 'MolinvĂ€gen 1', + }, + ], + className: '8C', + }, + { + sisId: '31c68-5b86667-0701d-6b7e2471-89e6df9', + firstname: 'Izabella', + lastname: 'Johansson', + guardians: [ + { + email: 'Elouise_Johansson25@example.org', + firstname: 'Jerrold', + lastname: 'Nilsson', + mobile: '07073789274', + address: 'StobaeusvĂ€gen 11', + }, + ], + className: '8C', + }, + { + sisId: '1bb69-5f1c3a6-f0ea8-e1dbb608-2756a52', + firstname: 'Ella', + lastname: 'Persson', + guardians: [ + { + email: 'Shayna.Olsson54@example.net', + firstname: 'Onie', + lastname: 'Nilsson', + mobile: '07076957797', + address: undefined, + }, + ], + className: '8C', + }, + { + sisId: '348a7-2d0eccc-02981-a02ccb03-cb2a8f2', + firstname: 'Jaylen', + lastname: 'Larsson', + guardians: [ + { + email: 'Aileen_Andersson@example.net', + firstname: 'Tess', + lastname: 'Karlsson', + mobile: '070715315590', + address: 'PeringskiöldsvĂ€gen 64', + }, + ], + className: '8C', + } + ], +] +]) diff --git a/libs/api-skolplattformen/lib/fakeData/data.ts b/libs/api-skolplattformen/lib/fakeData/data.ts new file mode 100644 index 00000000..81deb8b2 --- /dev/null +++ b/libs/api-skolplattformen/lib/fakeData/data.ts @@ -0,0 +1,509 @@ +import { fourDaysAgo, oneDayAgo, oneWeekAgo } from './dates'; +/* eslint-disable max-len */ +import { + CalendarItem, + Child, + Notification, + ScheduleItem, + User, +} from '@skolplattformen/api'; +import { oneDayForward, oneWeekForward, twoDaysForward } from './dates'; + +const data: any = { + '39b59e-bf4b9f-f68ac25321-977218-bf0': { + calendar: [ + { + title: 'Terminslut', + id: 73, + description: null, + location: null, + startDate: '2020-12-18', + endDate: '2020-12-18', + allDay: true, + }, + { + title: 'Terminen börjar', + id: 74, + description: null, + location: null, + startDate: '2021-01-12', + endDate: '2021-01-12', + allDay: true, + }, + { + title: 'APT - fritids stĂ€nger 15:45', + id: 75, + description: null, + location: null, + startDate: '2021-01-21', + endDate: '2021-01-21', + allDay: true, + }, + { + title: 'Utvecklingsamtal', + id: 76, + description: null, + location: null, + startDate: '2021-02-04', + endDate: '2021-02-04', + allDay: true, + }, + { + title: 'VĂ€nliga veckan', + id: 77, + description: null, + location: null, + startDate: '2021-02-08', + endDate: '2021-02-12', + allDay: true, + }, + { + title: 'Utvecklingsamtal', + id: 79, + description: null, + location: null, + startDate: '2021-02-09', + endDate: '2021-02-09', + allDay: true, + }, + { + title: 'Trygghetsdag', + id: 78, + description: null, + location: null, + startDate: '2021-02-12', + endDate: '2021-02-12', + allDay: true, + }, + { + title: 'APT fritids stĂ€nger 15:45', + id: 80, + description: null, + location: null, + startDate: '2021-02-25', + endDate: '2021-02-25', + allDay: true, + }, + { + title: 'Sportlov', + id: 81, + description: null, + location: null, + startDate: '2021-03-01', + endDate: '2021-03-05', + allDay: true, + }, + { + title: 'Studiedag', + id: 82, + description: null, + location: null, + startDate: oneWeekForward.startOf('day').toISODate(), + endDate: oneWeekForward.endOf('day').toISODate(), + allDay: true, + }, + { + title: 'APT - fritids stĂ€nger 15:45', + id: 83, + description: null, + location: null, + startDate: '2021-04-01', + endDate: '2021-04-01', + allDay: true, + }, + { + title: 'LĂ„ngfredag', + id: 84, + description: null, + location: null, + startDate: '2021-04-02', + endDate: '2021-04-02', + allDay: true, + }, + { + title: 'PĂ„sklov', + id: 85, + description: null, + location: null, + startDate: '2021-04-05', + endDate: '2021-04-09', + allDay: true, + }, + { + title: 'FörĂ€ldrarĂ„d', + id: 86, + description: null, + location: null, + startDate: '2021-04-20', + endDate: '2021-04-20', + allDay: true, + }, + { + title: 'Prao Ă„k 8', + id: 97, + description: null, + location: null, + startDate: '2021-04-26', + endDate: '2021-05-12', + allDay: true, + }, + { + title: 'Kristi HimmelfĂ€rd', + id: 87, + description: null, + location: null, + startDate: '2021-05-13', + endDate: '2021-05-13', + allDay: true, + }, + { + title: 'Lov', + id: 88, + description: null, + location: null, + startDate: '2021-05-14', + endDate: '2021-05-14', + allDay: true, + }, + { + title: 'APT Fritids stĂ€nger 15:45', + id: 90, + description: null, + location: null, + startDate: '2021-05-20', + endDate: '2021-05-20', + allDay: true, + }, + { + title: 'LĂ€sĂ„rsslut', + id: 91, + description: + "

 

", + location: null, + startDate: '2021-06-11', + endDate: '2021-06-11', + allDay: true, + }, + { + title: 'Fritids stÀngt', + id: 92, + description: + "

 

", + location: null, + startDate: '2021-06-14', + endDate: '2021-06-14', + allDay: true, + }, + ], + schedule: [ + { + title: 'LÀslÀxan tillbaka', + description: 'Ta med boken tillbaka till skolan', + location: '', + allDayEvent: false, + startDate: oneDayForward.startOf('day').toISO(), + endDate: oneDayForward.endOf('day').toISO(), + oneDayEvent: true + } as ScheduleItem + ], + notifications: [ + { + id: 'bfe19b-766db3-b38d99d321-bbed3d-506', + sender: 'Planering och Bedömning', + dateCreated: oneDayAgo.minus({months: 6}).toISO(), + dateModified: fourDaysAgo.toISO(), + message: 'Ett nytt inlÀgg i en lÀrlogg har skapats.', + url: + 'https://www.breakit.se/artikel/21423/har-ar-it-bolaget-bakom-haveriet-pa-skolplattformen', + category: 'LÀrlogg', + type: 'avisering', + }, + { + id: '9025f9-a1e685-d7c4668f09-e14bc5-0ab', + sender: 'Elevdokumentation', + dateCreated: '2020-12-10T14:31:29.966Z', + message: + 'Nu kan du ta del av ditt barns dokumentation av utvecklingssamtal', + url: + 'https://www.breakit.se/artikel/21404/kodaren-slog-larm-nu-akutstoppas-skolplattformen-i-stockholm', + category: null, + type: 'webnotify', + }, + { + id: 'a24061-1c9a4e-83dc479d7c-f44fe9-376', + sender: 'Planering och Bedömning', + dateCreated: '2020-06-10T12:18:00.000Z', + message: 'Nu finns det en bedömning att titta pÄ.', + url: + 'https://www.svt.se/nyheter/lokalt/stockholm/skolplattformen-i-stockholm-beratta-om-era-erfarenheter', + category: 'Bedömning', + type: 'avisering', + }, + { + id: '79d65c-1f8240-35c94296ec-9f4bdc-cea', + sender: 'Planering och Bedömning', + dateCreated: '2020-03-24T14:28:00.000Z', + message: 'Nu finns det en bedömning att titta pÄ.', + url: + 'https://www.breakit.se/artikel/18120/skolplattformen-kostade-700-miljoner-strid-med-entreprenor-om-varumarket', + category: 'Bedömning', + type: 'avisering', + }, + { + id: '9c5b7b-52c16d-b9fc2e8248-e4de76-279', + sender: 'Planering och Bedömning', + dateCreated: '2020-03-24T13:48:00.000Z', + message: 'Nu finns det en bedömning att titta pÄ.', + url: + 'https://www.mitti.se/nyheter/forskolans-tur-att-fa-kritiserade-skolplattformen-app/lmsau!5338007/', + category: 'Bedömning', + type: 'avisering', + }, + ], + }, + 'eea96a-a3e045-caab589391-ed7d17-029': { + calendar: [ + { + title: 'Terminslut', + id: 73, + description: null, + location: null, + startDate: '2020-12-18', + endDate: '2020-12-18', + allDay: true, + }, + { + title: 'Terminen börjar', + id: 74, + description: null, + location: null, + startDate: '2021-01-12', + endDate: '2021-01-12', + allDay: true, + }, + { + title: 'APT - fritids stÀnger 15:45', + id: 75, + description: null, + location: null, + startDate: oneWeekForward.startOf('day').toISODate(), + endDate: oneWeekForward.endOf('day').toISODate(), + allDay: true, + }, + { + title: 'Utvecklingsamtal', + id: 76, + description: null, + location: null, + startDate: '2021-02-04', + endDate: '2021-02-04', + allDay: true, + }, + { + title: 'VÀnliga veckan', + id: 77, + description: null, + location: null, + startDate: '2021-02-08', + endDate: '2021-02-12', + allDay: true, + }, + { + title: 'Utvecklingsamtal', + id: 79, + description: null, + location: null, + startDate: '2021-02-09', + endDate: '2021-02-09', + allDay: true, + }, + { + title: 'Trygghetsdag', + id: 78, + description: null, + location: null, + startDate: '2021-02-12', + endDate: '2021-02-12', + allDay: true, + }, + { + title: 'APT fritids stÀnger 15:45', + id: 80, + description: null, + location: null, + startDate: '2021-02-25', + endDate: '2021-02-25', + allDay: true, + }, + { + title: 'Sportlov', + id: 81, + description: null, + location: null, + startDate: '2021-03-01', + endDate: '2021-03-05', + allDay: true, + }, + { + title: 'Studiedag', + id: 82, + description: null, + location: null, + startDate: '2021-03-22', + endDate: '2021-03-22', + allDay: true, + }, + { + title: 'APT - fritids stÀnger 15:45', + id: 83, + description: null, + location: null, + startDate: '2021-04-01', + endDate: '2021-04-01', + allDay: true, + }, + { + title: 'LÄngfredag', + id: 84, + description: null, + location: null, + startDate: '2021-04-02', + endDate: '2021-04-02', + allDay: true, + }, + { + title: 'PÄsklov', + id: 85, + description: null, + location: null, + startDate: '2021-04-05', + endDate: '2021-04-09', + allDay: true, + }, + { + title: 'FörÀldrarÄd', + id: 86, + description: null, + location: null, + startDate: '2021-04-20', + endDate: '2021-04-20', + allDay: true, + }, + { + title: 'Prao Äk 8', + id: 97, + description: null, + location: null, + startDate: '2021-04-26', + endDate: '2021-05-12', + allDay: true, + }, + { + title: 'Kristi HimmelfÀrd', + id: 87, + description: null, + location: null, + startDate: '2021-05-13', + endDate: '2021-05-13', + allDay: true, + }, + { + title: 'Lov', + id: 88, + description: null, + location: null, + startDate: '2021-05-14', + endDate: '2021-05-14', + allDay: true, + }, + { + title: 'APT Fritids stÀnger 15:45', + id: 90, + description: null, + location: null, + startDate: '2021-05-20', + endDate: '2021-05-20', + allDay: true, + }, + ], + schedule: [ + { + title: 'LÀxförhör franska', + description: 'LÀxförhör, glosor samt verben!', + location: 'Klassrummet', + allDayEvent: false, + startDate: twoDaysForward.startOf('day').toISO(), + endDate: twoDaysForward.endOf('day').toISO(), + oneDayEvent: false + } as ScheduleItem + ], + notifications: [ + { + id: 'e1b5bc-597fa8-5511794939-3614e1-615', + sender: 'Planering och Bedömning', + dateCreated: fourDaysAgo.toISO(), + dateModified: fourDaysAgo.toISO(), + message: 'Ett nytt inlÀgg i en lÀrlogg har skapats.', + url: + 'https://www.mitti.se/nyheter/rekorddyr-skolplattform-kostar-258-miljoner-till/lmsao!5381301/', + category: 'LÀrlogg', + messageType: 'avisering', + }, + { + id: '7dbc20-bfa1ac-e20171b865-82c1f7-f3c', + sender: 'Planering och Bedömning', + dateCreated: '2020-12-01T12:43:00.000Z', + message: 'Ett nytt inlÀgg i en lÀrlogg har skapats.', + url: + 'https://computersweden.idg.se/2.2683/1.722561/lacka-skolplattformen-datainspektionen', + category: 'LÀrlogg', + messageType: 'avisering', + }, + { + id: 'a6829b-ecf912-b71582e8fb-b6dc14-f60', + sender: 'Planering och Bedömning', + dateCreated: '2020-11-24T13:34:00.000Z', + message: 'Ett nytt inlÀgg i en lÀrlogg har skapats.', + url: 'https://www.dagensarena.se/redaktionen/en-systemkramare-ger-upp/', + category: 'LÀrlogg', + messageType: 'avisering', + }, + { + id: '3cedb4-767d24-8ccd6ac3ac-c05cb7-a3a', + sender: 'Planering och Bedömning', + dateCreated: '2020-11-16T13:24:00.000Z', + message: 'Ett nytt inlÀgg i en lÀrlogg har skapats.', + url: + 'https://www.breakit.se/artikel/27075/skolplattformen-kostade-1-miljard-att-bygga-nu-tvingas-stockholm-bota', + category: 'LÀrlogg', + messageType: 'avisering', + }, + { + id: '6ace13-5f99da-d1d50ac7a6-4a6108-d8e', + sender: 'Planering och Bedömning', + dateCreated: '2020-11-12T13:27:00.000Z', + message: 'Ett nytt inlÀgg i en lÀrlogg har skapats.', + url: + 'https://www.nyteknik.se/sakerhet/ygeman-om-datalackan-i-skolplattformen-det-ar-upprorande-6968853', + category: 'LÀrlogg', + messageType: 'avisering', + }, + ], + }, +} + +export const user = (): User => ({ + personalNumber: '195001182046', // Test personal number from Skatteverket + firstName: 'Namn', + lastName: 'Namnsson', + isAuthenticated: true +}) + +export const calendar = (child: Child): CalendarItem[] => + data[child.id].calendar + +export const schedule = (child: Child): ScheduleItem[] => + data[child.id].schedule + +export const notifications = (child: Child): Notification[] => + data[child.id].notifications diff --git a/libs/api-skolplattformen/lib/fakeData/dates.ts b/libs/api-skolplattformen/lib/fakeData/dates.ts new file mode 100644 index 00000000..9858fa50 --- /dev/null +++ b/libs/api-skolplattformen/lib/fakeData/dates.ts @@ -0,0 +1,14 @@ +import { DateTime } from "luxon" + +export const getDate = () => DateTime.now() +export const oneDayAgo = getDate().minus({days: 1}) +export const twoDaysAgo = getDate().minus({days: 2}) +export const fourDaysAgo = getDate().minus({days: 4}) +export const oneWeekAgo = getDate().minus({weeks: 1}) + +export const oneDayForward = getDate().plus({days: 1}) +export const twoDaysForward = getDate().plus({days: 2}) +export const fourDaysForward = getDate().plus({days: 4}) +export const oneWeekForward = getDate().plus({weeks: 1}) + +export const week = getDate().weekNumber.toString() diff --git a/libs/api-skolplattformen/lib/fakeData/index.ts b/libs/api-skolplattformen/lib/fakeData/index.ts new file mode 100644 index 00000000..e42df62f --- /dev/null +++ b/libs/api-skolplattformen/lib/fakeData/index.ts @@ -0,0 +1,8 @@ +export * from './data' +export * from './children' +export * from './menu' +export * from './classmates' +export * from './teachers' +export * from './timetable' +export * from './schoolContacts' +export * from './news' diff --git a/libs/api-skolplattformen/lib/fakeData/menu.ts b/libs/api-skolplattformen/lib/fakeData/menu.ts new file mode 100644 index 00000000..128f26f9 --- /dev/null +++ b/libs/api-skolplattformen/lib/fakeData/menu.ts @@ -0,0 +1,64 @@ +import { Child, MenuItem } from '@skolplattformen/api' +import { DateTime } from 'luxon' +import { children } from './children' + +export const menu = (child: Child): MenuItem[] => menuData.get(child.id) ?? [] + +const getDate = () => DateTime.now() +const week = getDate().weekNumber.toString() + +const [child1, child2] = children() + +const menuData = new Map([ +[ + child1.id, + [ + { + title: 'MÄndag - Vecka ' + week, + description: 'Kebabgryta ris
Ratatouille med kikÀrter', + }, + { + title: 'Tisdag - Vecka ' + week, + description: 'Ost-broccolisÄs pasta Fusilli', + }, + { + title: 'Onsdag - Vecka ' + week, + description: 'Köttbullar potatis grÀddsÄs lingon
Falafel', + }, + { + title: 'Torsdag - Vecka ' + week, + description: + 'Prinskorv potatis rödbetssallad +
Inlagd och senapssill', + }, + { + title: 'Fredag - Vecka ' + week, + description: + 'Avslutning Varmkorv bröd ketchup senap
( F-3 i matsalen frÄn 10:30 )', + }, + ], + ], + [child2.id, + [ + { + title: "MÄndag - Vecka " + week, + description: "ThailÀndsk kycklinggryta med kokosmjölk, rödcurry och jasminris
ThailĂ€nsk grönsaksgryta med kokosmjölk, rödcurry och jasminris" + }, + { + title: "Tisdag - Vecka " + week, + description: "Örtomlett med potatis , medelhavsost och olivtapenad" + }, + { + title: "Onsdag - Vecka " + week, + description: "Spagetti med rökt kalkon , grĂ€dde, dijon och persilja
Spagetti med rostade bönor , grÀdde , dijon och persilja" + }, + { + title: "Torsdag - Vecka " + week, + description: "Panerad flundra med dansk remoulad och koktÄotatis
morot och linsbiff med danska remoulad och koktpotatis" + }, + { + title: "Fredag - Vecka " + week, + description: "Texaschili pÄ högrev med picklad rödlök och bulgur
Texaschili pĂ„ svartabönor picklad rödlök och bulgur" + } + ], + ] +]) diff --git a/libs/api-skolplattformen/lib/fakeData/news.ts b/libs/api-skolplattformen/lib/fakeData/news.ts new file mode 100644 index 00000000..234fcab8 --- /dev/null +++ b/libs/api-skolplattformen/lib/fakeData/news.ts @@ -0,0 +1,143 @@ +import { children } from './children' +import { Child, NewsItem } from '@skolplattformen/api' +import * as dates from './dates' + +export const news = (child: Child): NewsItem[] => newsData.get(child.id) ?? [] + +const [child1, child2] = children() + +const newsData = new Map([ +[child1.id, [ + { + id: 'asdfasdfasdfw', + author: 'VaktmĂ€stare Persson', + header: 'BrandslĂ€ckare!', + intro: 'Idag hade vi en incident med en brandslĂ€ckare.', + body: + '## Information om brandslĂ€ckarincidenten\n\nHej, idag vid lunchtid utlöste en elev av misstag en pulverbrandslĂ€ckare i kapprummet. En del pulver yrde runt i rummet och under saneringen fick eleverna i angrĂ€nsande klassrum vara i aulan istĂ€llet för klassrummet.\n\nFlera elever var pĂ„ plats i hallen nĂ€r detta intrĂ€ffade men utrymdes kort dĂ€refter. Pulvret Ă€r INTE hĂ€lsovĂ„dligt men kan ge upphov till halsirritation vid inandning.\n\nJag har pratat med berörda elever om det intrĂ€ffade och uppmanat dem att ta hem klĂ€der och tillhörigheter som fanns i kapprummet eftersom de troligen blivit dammiga. Vi rekommenderar att ni tvĂ€ttar eller vĂ€drar dessa.', + imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg', + fullImageUrl: + 'https://cdn.breakit.se/assets/article/6607f9b923edb6f85aa4417bab43c0f8.jpg?d=980x500', + imageAltText: 'Nyhetsbild. Bildtext ej tillgĂ€nglig.', + published: dates.twoDaysAgo.toISO(), + modified: dates.twoDaysAgo.plus({ hours: 1 }).toISO(), + }, + { + id: 'asdfabbuasdfs', + author: 'Ada L.', + header: 'Bygg din egen app', + intro: 'Denna vecka bygger vi appar!', + body: + '## Appar med öppen data \n\nDenna vecka har vi förmĂ„nen att fĂ„ besök av nĂ„gra förĂ€ldrar som visar hur vi enkelt kan skapa appar som visar information ifrĂ„n öppna datakĂ€llor.\n\nEn fantastisk möjlighet att lĂ€ra oss hur digitalisering skapar nya möjligheter i sĂ„vĂ€l skolan som arbetslivet.', + imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg', + fullImageUrl: + 'https://live.staticflickr.com/4063/4369776892_5cd42d27ba.jpg', + imageAltText: 'Nyhetsbild. Bildtext ej tillgĂ€nglig.', + published: dates.oneWeekAgo.toISO(), + modified: dates.oneWeekAgo.toISO(), + }, + { + id: 'asdfasdfasdfs', + author: 'Magister Svensson', + header: 'LĂ€xor vecka 6.', + intro: 'Alla elever mĂ„ste göra sina lĂ€xor!', + body: + '## LĂ€xor vecka 6 \n\nFöljande lĂ€xor Ă€r obligatoriska:\n\n- Antikens historia\n- Svenska stormaktstiden\n- Statistik A\n- Flerdimensionell analys, del 1', + imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg', + fullImageUrl: + 'https://www.mitti.se/_internal/cimg!0/ejf8efxee735ymm8tm40q3hhkl36sdt.jpeg', + imageAltText: 'Nyhetsbild. Bildtext ej tillgĂ€nglig.', + published: dates.oneWeekAgo.toISO(), + modified: dates.oneWeekAgo.minus({ hours: 3 }).toISO(), + }, + ] +], + +[child2.id, [ + { + id: 'asdfasdfasdfa', + author: 'Rektor Gustavsson', + header: 'VĂ€lkommen till skolan!', + intro: + 'Hej alla barn och förĂ€ldrar och vĂ€lkomna till Storskolan! HĂ€r kommer en del information som kan vara bra att kĂ€nna till inför första dagen.', + body: + '## Information till förĂ€ldrar \n\nSkolan börjar kl 08.00 och slutar 18.00. Kommer man sent eller blir sjuk sĂ„ ska det anmĂ€las via Skolplattformen. Se till sĂ„ att dina barn har Ă€tit frukost. Frukt Ă€r nyttigt! \n\n## Information till barn\n\nLek Ă€r tillĂ„tet pĂ„ rasterna men enbart pĂ„ skolgĂ„rden. Medtag ej egna leksaker. TvĂ€tta hĂ€nderna.', + imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg', + fullImageUrl: + 'https://timbro.se/app/uploads/2020/10/broman-skolplattformen-1280x752.jpg', + imageAltText: 'Nyhetsbild. Bildtext ej tillgĂ€nglig.', + published: dates.oneWeekAgo.toISO(), + modified: dates.oneWeekAgo.toISO(), + }, + { + id: 'asdfabbuasdfs', + author: 'Ada L.', + header: 'App, App, App', + intro: 'Denna vecka bygger vi appar!', + body: + '## Appar med öppen data \n\nDenna vecka har vi förmĂ„nen att fĂ„ besök av nĂ„gra förĂ€ldrar som visar hur vi enkelt kan skapa appar som visar information ifrĂ„n öppna datakĂ€llor.\n\nEn fantastisk möjlighet att lĂ€ra oss hur digitalisering skapar nya möjligheter i sĂ„vĂ€l skolan som arbetslivet.', + imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg', + fullImageUrl: + 'https://live.staticflickr.com/4063/4369776892_5cd42d27ba.jpg', + imageAltText: 'Nyhetsbild. Bildtext ej tillgĂ€nglig.', + published: dates.fourDaysAgo.toISO(), + modified: dates.fourDaysAgo.plus({minutes: 45}).toISO(), + }, + { + id: 'asdfasdfasdfs', + author: 'Magister Svensson', + header: 'LĂ€xor i veckan', + intro: 'Alla elever mĂ„ste göra sina lĂ€xor!', + body: + '## LĂ€xor vecka 6 \n\nFöljande lĂ€xor Ă€r obligatoriska:\n\n- Antikens historia\n- Svenska stormaktstiden\n- Statistik A\n- Flerdimensionell analys, del 1', + imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg', + fullImageUrl: + 'https://www.mitti.se/_internal/cimg!0/ejf8efxee735ymm8tm40q3hhkl36sdt.jpeg', + imageAltText: 'Nyhetsbild. Bildtext ej tillgĂ€nglig.', + published: dates.oneWeekAgo.toISO(), + modified: dates.oneWeekAgo.toISO(), + }, + { + id: 'asdfasdfasdfd', + author: 'Information frĂ„n Förskoleklass', + header: 'Vinteraktiviteter', + intro: + 'Vi kommer efter att förskoleklassen Ă€r slut arrangera olika vinteraktiviteter genom fridtidsverksamheten.', + body: + '## VĂ€nligen ta med hjĂ€lm, skridskor eller stjĂ€rtlapp.\n\n ![Bild](https://images.unsplash.com/photo-1495377701095-00261b767581?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=988&q=80)\n\n Alla barn mĂ„ste ha hjĂ€lm pĂ„ sig samt varma klĂ€der. Vi kommer Ă„ka i backen bakom skolbyggnaden samt anvĂ€nda isen som spolats vid Mullsjöskolan. Personal kommer finnas pĂ„ plats samt att vi erbjuda varm dryck, frukt och lek för de barn som ej har hjĂ€lm eller lĂ€mpligt Ă„kdon.', + imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg', + fullImageUrl: 'https://unsplash.com/photos/yB_aiAWkm40', + imageAltText: 'Nyhetsbild. Bildtext ej tillgĂ€nglig.', + published: dates.oneWeekAgo.minus({weeks: 2}).toISO(), + modified: dates.oneWeekAgo.minus({weeks: 1}).toISO(), + }, + { + id: 'asdfasdfasdfdsa', + author: 'Köket', + header: 'Ekologisk vecka i matsalen', + intro: 'Ekologiska veckan i matsalen vecka 11', + body: + '## Vi kommer ha tema jorden i matsalen och servera ekologisk mat frĂ„n hela vĂ€rlden med tema jorden. Detta för att belysa att man kan anvĂ€nda alla delar av rĂ„vaorna. Det kommer erbjudas rĂ€tter frĂ„n alla vĂ€rldsdelar som Ă€r producerat för jordens bĂ€sta. Smaklig spis hĂ€lsar Gunnel i köket med personal.', + imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg', + fullImageUrl: 'https://unsplash.com/photos/7K17MvT8qBg', + imageAltText: 'Nyhetsbild. Bildtext ej tillgĂ€nglig.', + published: dates.oneWeekAgo.minus({weeks: 3}).toISO(), + modified: dates.oneWeekAgo.minus({days: 2}).toISO(), + }, + { + id: 'asdfasdfasdfbvdsa', + author: 'VaktmĂ€staren', + header: 'Klotter i korridoren (igen)', + intro: + 'Ännu en gĂ„ng har vi rĂ„ka ut för skadegörelse i korridorerna vid Ă„k 5', + body: + '## TyvĂ€rr har flera elever klottat pĂ„ skĂ„p och vĂ€ggar vid Ă„k5 skĂ„pen. Detta Ă€r helt oacceptablet beteende och kostar skolan stora belopp att Ă„tgĂ€rda. Vi ber alla förĂ€ldrar prata med sina barn om klotter samt att det var vĂ€ldigt grovt spĂ„rkbruk. Personalen pĂ„ skolan kommer att hĂ„lla extra uppsikt och vi har Ă€ven pratat med en del av de inblandade eleverna i denna skadegörelse.\n\nPersonalen har Ă€ven börjat forska pĂ„ vad vissa av de skrivna orden betyder och Eva-Britt Ă€r förfasad över sprĂ„kbruket samt vad de innebĂ€r. Bernt kommer att pĂ„börja saneringen och Ă„terstĂ€llningen av skadegörelsen samt vakta korridorerna nogrannare för att sĂ€kerstĂ€lla att detta ej kommer ske igen.\n\n Klotter\n\nUPPDATERING: Det som Ă€r skrivet om Sara Ă€r inte sant! ', + imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg', + fullImageUrl: 'https://unsplash.com/photos/SkbEZ16VywM', + imageAltText: 'Nyhetsbild. Bildtext ej tillgĂ€nglig.', + published: dates.oneWeekAgo.minus({weeks: 4}).toISO(), + modified: dates.oneWeekAgo.minus({weeks: 2}).toISO(), + }, + ] +] +]) diff --git a/libs/api-skolplattformen/lib/fakeData/schoolContacts.ts b/libs/api-skolplattformen/lib/fakeData/schoolContacts.ts new file mode 100644 index 00000000..93d0f697 --- /dev/null +++ b/libs/api-skolplattformen/lib/fakeData/schoolContacts.ts @@ -0,0 +1,47 @@ +import { SchoolContact, Child } from '@skolplattformen/api'; +import { children } from './children' + +export const schoolContacts = (child: Child): SchoolContact[] => schoolContactData.get(child.id) ?? [] + +const [child1,child2] = children() + +const schoolContactData = new Map([ + [ + child1.id, [ + { + title: "Expedition", + name: null, + phone: "508 000 00", + email: "", + schoolName: "Vallaskolan", + className: null, + }, + { + title: "Rektor", + name: "Alvar StrĂ€ng", + phone: "08-50800001", + email: "alvar.strang@edu.stockholm.se", + schoolName: null, + className: null, + } + ]], + [ + child2.id, [ + { + title: "Expedition", + name: null, + phone: "508 000 00", + email: "", + schoolName: "Vallaskolan", + className: null, + }, + { + title: "Rektor", + name: "Alvar StrĂ€ng", + phone: "08-50800001", + email: "alvar.strang@edu.stockholm.se", + schoolName: null, + className: null, + } +]] +]) diff --git a/libs/api-skolplattformen/lib/fakeData/teachers.ts b/libs/api-skolplattformen/lib/fakeData/teachers.ts new file mode 100644 index 00000000..ba22c58f --- /dev/null +++ b/libs/api-skolplattformen/lib/fakeData/teachers.ts @@ -0,0 +1,81 @@ +import { Teacher, Child } from '@skolplattformen/api'; +import { children } from './children' + +export const teachers = (child: Child): Teacher[] => teacherData.get(child.id) ?? [] + +const [child1,child2] = children() + +const teacherData = new Map([ + [ + child1.id, [ + { + id: 15662220, + firstname: "Cecilia", + sisId: null, + lastname: "Test", + email: "cecilia.test@edu.stockholm.se", + phoneWork: null, + active: true, + status: " S", + timeTableAbbreviation: 'CTE', + }, + { + id: 15662221, + firstname: "Anna", + lastname: "Test", + sisId: null, + email: "anna.test@edu.stockholm.se", + phoneWork: '08000000', + active: true, + status: " GR", + timeTableAbbreviation: 'ATE', + }, + { + id: 15662221, + firstname: "Greta", + lastname: "Test", + sisId: null, + email: null, + phoneWork: '08000001', + active: true, + status: " F", + timeTableAbbreviation: 'GTE', + }, + ]], +[ + child2.id, [ + { + id: 15662220, + firstname: "Cecilia", + sisId: null, + lastname: "Test", + email: "cecilia.test@edu.stockholm.se", + phoneWork: null, + active: true, + status: " S", + timeTableAbbreviation: 'CTE', + }, + { + id: 15662221, + firstname: "Anna", + lastname: "Test", + sisId: null, + email: "anna.test@edu.stockholm.se", + phoneWork: '08000000', + active: true, + status: " GR", + timeTableAbbreviation: 'ATE', + }, + { + id: 15662221, + firstname: "Greta", + lastname: "Test", + sisId: null, + email: null, + phoneWork: '08000001', + active: true, + status: " F", + timeTableAbbreviation: 'GTE', + }, +]], +]) diff --git a/libs/api-skolplattformen/lib/fakeData/timetable.ts b/libs/api-skolplattformen/lib/fakeData/timetable.ts new file mode 100644 index 00000000..f61bbf2c --- /dev/null +++ b/libs/api-skolplattformen/lib/fakeData/timetable.ts @@ -0,0 +1,465 @@ +import { Skola24Child, TimetableEntry } from "@skolplattformen/api" + + +export const timetable = (child: Skola24Child): TimetableEntry[] => { + if (!child.personGuid || !child.unitGuid) return [] + return [ + { + id: 'N2FjMDc1NjYtZmM2Yy0wZDQyLTY3M2YtZWI5NGNiZDA3ZGU4', + code: 'Lunch', + name: 'Lunch', + category: '', + blockName: '', + dayOfWeek: 1, + location: 'Ö5', + teacher: '', + timeEnd: '12:05:00', + timeStart: '11:40:00', + dateStart: '2021-04-12T11:40:00.000+02:00', + dateEnd: '2021-04-12T12:05:00.000+02:00', + }, + { + id: 'ZTQ1NWE0N2EtNzAwOS0wZTAzLTQ1ZDYtNTA1NWI4Y2JhNDYw', + code: 'BL', + name: 'Bild', + category: '', + blockName: '', + dayOfWeek: 1, + location: '221', + teacher: 'CTe', + timeEnd: '11:35:00', + timeStart: '09:40:00', + dateStart: '2021-04-12T09:40:00.000+02:00', + dateEnd: '2021-04-12T11:35:00.000+02:00', + }, + { + id: 'YjAxODRmY2QtNTJjZS0wMDJlLTYxOGItYmFlNTVlNDgzZmVk', + code: 'NO', + name: 'Naturorienterande Ă€mnen', + category: '', + comment: 'a)', + blockName: '', + dayOfWeek: 1, + location: '307', + teacher: 'TBo', + timeEnd: '13:30:00', + timeStart: '12:30:00', + dateStart: '2021-04-12T12:30:00.000+02:00', + dateEnd: '2021-04-12T13:30:00.000+02:00', + }, + { + id: 'MWRiZGI1NzgtYWIzNy0wYzMwLTVkMmEtMWFjNWRkMTRmOTdh', + code: 'IDH', + name: 'Idrott & hĂ€lsa', + category: '', + blockName: '', + dayOfWeek: 1, + location: '215', + teacher: 'ATe, GTe', + timeEnd: '15:45:00', + timeStart: '14:40:00', + dateStart: '2021-04-12T14:40:00.000+02:00', + dateEnd: '2021-04-12T15:45:00.000+02:00', + }, + { + id: 'MmZkZTZiMzMtMjdjMS0wZGIzLTUzYWYtZTg0Zjc1NDRlNzQw', + code: 'M2FR', + name: 'Franska', + category: 'Moderna sprĂ„k, sprĂ„kval', + blockName: '', + dayOfWeek: 1, + location: '304', + teacher: 'CTe,ATe', + timeEnd: '14:25:00', + timeStart: '13:40:00', + dateStart: '2021-04-12T13:40:00.000+02:00', + dateEnd: '2021-04-12T14:25:00.000+02:00', + }, + { + id: 'MzAxMzU3MWItZGM1Ny0wOGVhLTVkZjUtOGFkMGIyYTY2OTAx', + code: 'SO', + name: 'SamhĂ€llsorienterande Ă€mnen', + category: '', + blockName: '', + dayOfWeek: 1, + location: '303', + teacher: 'HRr', + timeEnd: '09:25:00', + timeStart: '08:15:00', + dateStart: '2021-04-12T08:15:00.000+02:00', + dateEnd: '2021-04-12T09:25:00.000+02:00', + }, + { + id: 'NDY3MDY1MmYtOTIzYi0wZmQ0LTVlZGEtNGVhZDRkOTExNTgz', + code: 'M2FR', + name: 'Franska', + category: 'Moderna sprĂ„k, sprĂ„kval', + blockName: '', + dayOfWeek: 2, + location: '302,FjĂ€rr asd asdasd asdad aasdds', + teacher: 'DNi', + timeEnd: '09:50:00', + timeStart: '09:05:00', + dateStart: '2021-04-13T09:05:00.000+02:00', + dateEnd: '2021-04-13T09:50:00.000+02:00', + }, + { + id: 'NmE4OTU1NmItYzM0ZS0wYTI1LTYzM2QtYzBiN2M4OTVmYTQ3', + code: 'EN', + name: 'Engelska', + category: '', + blockName: '', + dayOfWeek: 2, + location: 'FjĂ€rr', + teacher: 'TPe', + timeEnd: '13:15:00', + timeStart: '12:30:00', + dateStart: '2021-04-13T12:30:00.000+02:00', + dateEnd: '2021-04-13T13:15:00.000+02:00', + }, + { + id: 'NDAxODRjOTctMmE5ZC0wMzdjLTY2NDMtODhlODEzOTQ3YTJh', + code: 'Lunch', + name: 'Lunch', + category: '', + blockName: '', + dayOfWeek: 2, + location: 'FjĂ€rr', + teacher: '', + timeEnd: '12:05:00', + timeStart: '11:40:00', + dateStart: '2021-04-13T11:40:00.000+02:00', + dateEnd: '2021-04-13T12:05:00.000+02:00', + }, + { + id: 'ZTc4YTcyZTUtMDc0NS0wNDE0LTVjODctYjY0MzQ2MGM3MDll', + code: 'MA', + name: 'Matematik', + category: '', + blockName: '', + dayOfWeek: 2, + location: 'FjĂ€rr', + teacher: 'CBr', + timeEnd: '11:20:00', + timeStart: '10:00:00', + dateStart: '2021-04-13T10:00:00.000+02:00', + dateEnd: '2021-04-13T11:20:00.000+02:00', + }, + { + id: 'MjRkMWE4YTItYTk5ZC0wYTFmLTVhMDgtMThiMmNhZDc1ZDUz', + code: 'MU', + name: 'Musik', + category: '', + blockName: '', + dayOfWeek: 2, + location: 'FjĂ€rr', + teacher: 'KBj', + timeEnd: '14:15:00', + timeStart: '13:30:00', + dateStart: '2021-04-13T13:30:00.000+02:00', + dateEnd: '2021-04-13T14:15:00.000+02:00', + }, + { + id: 'NTU4ZTc4ZTctNDQyMy0wMjVkLTRiYzktZGUwYmFmYzk2YTlj', + code: 'EN', + name: 'Engelska', + category: '', + blockName: '', + dayOfWeek: 3, + location: '303', + teacher: 'TPe', + timeEnd: '09:55:00', + timeStart: '09:10:00', + dateStart: '2021-04-14T09:10:00.000+02:00', + dateEnd: '2021-04-14T09:55:00.000+02:00', + }, + { + id: 'NDUyNjIxODItYzFiOC0wOTFjLTYwODYtZDllZjZjN2QyYzA3', + code: 'SV', + name: 'Svenska', + category: '', + comment: 'a)', + blockName: '', + dayOfWeek: 3, + location: '303', + teacher: 'JCa', + timeEnd: '14:45:00', + timeStart: '14:00:00', + dateStart: '2021-04-14T14:00:00.000+02:00', + dateEnd: '2021-04-14T14:45:00.000+02:00', + }, + { + id: 'NDdkMGI0ZjItMjkxMC0wYWI1LTQ0YWMtNDY3NTdkZTE2Njg3', + code: 'SO', + name: 'Engelska', + category: 'SamhĂ€llsorienterande Ă€mnen', + blockName: '', + dayOfWeek: 3, + location: '303', + teacher: 'HRr', + timeEnd: '11:00:00', + timeStart: '10:05:00', + dateStart: '2021-04-14T10:05:00.000+02:00', + dateEnd: '2021-04-14T11:00:00.000+02:00', + }, + { + id: 'ZTI2ZDgyNWUtM2ZlOS0wZDVmLTY5NTctNGYzZThjMTMxOTdh', + code: 'NO', + name: 'Naturorienterande Ă€mnen', + category: '', + comment: 'a)', + blockName: '', + dayOfWeek: 3, + location: '307', + teacher: 'TBo', + timeEnd: '13:50:00', + timeStart: '12:50:00', + dateStart: '2021-04-14T12:50:00.000+02:00', + dateEnd: '2021-04-14T13:50:00.000+02:00', + }, + { + id: 'NzMxNjczNGMtMmZmZi0wM2YzLTU0ZjMtODdjOTAwYzIwNTUw', + code: 'Lunch', + name: 'Lunch', + category: '', + blockName: '', + dayOfWeek: 3, + location: 'Ö5', + teacher: '', + timeEnd: '12:40:00', + timeStart: '12:15:00', + dateStart: '2021-04-14T12:15:00.000+02:00', + dateEnd: '2021-04-14T12:40:00.000+02:00', + }, + { + id: 'MWRkZjhlZTktNTBmMC0wZjNhLTQ1OTgtMWJkOWM3MjI2NWQ4', + code: 'SV', + name: 'Svenska', + category: '', + blockName: '', + dayOfWeek: 3, + location: '303', + teacher: 'JCa', + timeEnd: '12:05:00', + timeStart: '11:20:00', + dateStart: '2021-04-14T11:20:00.000+02:00', + dateEnd: '2021-04-14T12:05:00.000+02:00', + }, + { + id: 'NzM2Mjc2ZTYtY2JlYy0wOTc1LTU1ZGYtNjMwZjhjZWVjNjgy', + code: 'MA', + name: 'Matematik', + category: '', + comment: 'a)', + blockName: '', + dayOfWeek: 3, + location: '307', + teacher: 'CBr', + timeEnd: '15:45:00', + timeStart: '15:00:00', + dateStart: '2021-04-14T15:00:00.000+02:00', + dateEnd: '2021-04-14T15:45:00.000+02:00', + }, + { + id: 'YWNlZmEzZjYtM2EwNC0wYWY3LTU1N2MtMDBlMTA4MDQzMzRl', + code: 'MU', + name: 'Musik', + category: '', + blockName: '', + dayOfWeek: 3, + location: '504', + teacher: 'KBj', + timeEnd: '09:00:00', + timeStart: '08:15:00', + dateStart: '2021-04-14T08:15:00.000+02:00', + dateEnd: '2021-04-14T09:00:00.000+02:00', + }, + { + id: 'NDc4MThmMDYtYmYxYi0wZDBkLTdhNmItZGVjMjY3OWY3MmYz', + code: 'IDH', + name: 'Idrott & HĂ€lsa', + category: '', + blockName: '', + dayOfWeek: 4, + location: 'FjĂ€rr', + teacher: 'AKö,CSv,HAl', + timeEnd: '15:45:00', + timeStart: '14:35:00', + dateStart: '2021-04-15T14:35:00.000+02:00', + dateEnd: '2021-04-15T15:45:00.000+02:00', + }, + { + id: 'ZjQyZjNkOWItYWMzZi0wYWRhLTQ3YzItNTZiNTJkOTRmY2Iy', + code: 'M2FR', + name: 'Franska', + category: 'Moderna sprĂ„k, sprĂ„kval', + blockName: '', + dayOfWeek: 4, + location: 'FjĂ€rr', + teacher: 'DNi', + timeEnd: '11:55:00', + timeStart: '11:10:00', + dateStart: '2021-04-15T11:10:00.000+02:00', + dateEnd: '2021-04-15T11:55:00.000+02:00', + }, + { + id: 'YzQ2NWZlOWMtYzM3ZC0wYzBlLTQzNTQtODMyYmU3ODcxMDQ3', + code: 'MTID', + name: 'Mentorstid', + category: 'Diverse', + comment: 'ArbetslagsrĂ„d 6C', + blockName: '', + dayOfWeek: 4, + location: 'FjĂ€rr', + teacher: 'JCa,CBr', + timeEnd: '10:00:00', + timeStart: '09:15:00', + dateStart: '2021-04-15T09:15:00.000+02:00', + dateEnd: '2021-04-15T10:00:00.000+02:00', + }, + { + id: 'YzMwMGY0YzAtNjhjNi0wYzY0LTU1MjctODg2MWQ4ZTRmZTI2', + code: 'MU', + name: 'Musik', + category: '', + blockName: '', + dayOfWeek: 4, + location: 'FjĂ€rr', + teacher: 'KBj', + timeEnd: '10:55:00', + timeStart: '10:10:00', + dateStart: '2021-04-15T10:10:00.000+02:00', + dateEnd: '2021-04-15T10:55:00.000+02:00', + }, + { + id: 'ZDNlNTFhMGUtYWFlYy0wOGI0LTVlMGItOTc0MzFiZmIwODcx', + code: 'Lunch', + name: 'Lunch', + category: 'Diverse', + blockName: '', + dayOfWeek: 4, + location: 'FjĂ€rr', + teacher: '', + timeEnd: '12:25:00', + timeStart: '12:00:00', + dateStart: '2021-04-15T12:00:00.000+02:00', + dateEnd: '2021-04-15T12:25:00.000+02:00', + }, + { + id: 'MDRiZWMyODMtNjEwZC0wZDYwLTRlOWItYTY1MjAwZTc0YTZm', + code: 'SO', + name: 'SamhĂ€llsorienterande Ă€mnen', + category: '', + blockName: '', + dayOfWeek: 4, + location: 'FjĂ€rr', + teacher: 'HRr', + timeEnd: '13:10:00', + timeStart: '12:35:00', + dateStart: '2021-04-15T12:35:00.000+02:00', + dateEnd: '2021-04-15T13:10:00.000+02:00', + }, + { + id: 'YTA0ZTA2NTktYTU5MS0wMTFmLTVlYWYtNWM1MTgxNDJlMDcy', + code: 'EN', + name: 'Engelska', + category: '', + comment: 'a)', + blockName: '', + dayOfWeek: 4, + location: 'FjĂ€rr', + teacher: 'TPe', + timeEnd: '14:20:00', + timeStart: '13:35:00', + dateStart: '2021-04-15T13:35:00.000+02:00', + dateEnd: '2021-04-15T14:20:00.000+02:00', + }, + { + id: 'OGJhN2MxYTYtMDQ4NS0wNWNhLTUwZWEtZDQ5YzQyMzFhYzc5', + code: 'Lunch', + name: 'Lunch', + category: 'Diverse', + blockName: '', + dayOfWeek: 5, + location: 'Ö5', + teacher: '', + timeEnd: '12:05:00', + timeStart: '11:40:00', + dateStart: '2021-04-16T11:40:00.000+02:00', + dateEnd: '2021-04-16T12:05:00.000+02:00', + }, + { + id: 'ZmUwMGEwM2QtNTExMy0wODliLTY1ZGEtODM0YmRjNjc1NDIw', + code: 'MA', + name: 'Matematik', + category: '', + comment: 'a)', + blockName: '', + dayOfWeek: 5, + location: '303', + teacher: 'CBr', + timeEnd: '14:00:00', + timeStart: '13:15:00', + dateStart: '2021-04-16T13:15:00.000+02:00', + dateEnd: '2021-04-16T14:00:00.000+02:00', + }, + { + id: 'Y2IwYjYzZDEtODAxYi0wMTNjLTRjNDMtMDFlODgzMmY4MWEy', + code: 'MU', + name: 'Musik', + category: '', + comment: 'a)', + blockName: '', + dayOfWeek: 5, + location: '510', + teacher: 'KBj', + timeEnd: '13:05:00', + timeStart: '12:20:00', + dateStart: '2021-04-16T12:20:00.000+02:00', + dateEnd: '2021-04-16T13:05:00.000+02:00', + }, + { + id: 'N2JkMGFiOTYtMjI5OC0wMjZiLTc3OGEtN2JkN2Q4MDZkNTEy', + code: 'SL', + name: 'Slöjd', + category: '', + comment: 'tmtx)', + blockName: '', + dayOfWeek: 5, + location: '860', + teacher: 'EAl', + timeEnd: '15:10:00', + timeStart: '14:10:00', + dateStart: '2021-04-16T14:10:00.000+02:00', + dateEnd: '2021-04-16T15:10:00.000+02:00', + }, + { + id: 'NzkxMjE3MDctMWExNS0wN2RmLTQwMzQtNTEyZTczZjQyZTUw', + code: 'SV', + name: 'Svenska', + category: '', + blockName: '', + dayOfWeek: 5, + location: '303', + teacher: 'JCa', + timeEnd: '10:35:00', + timeStart: '09:20:00', + dateStart: '2021-04-16T09:20:00.000+02:00', + dateEnd: '2021-04-16T10:35:00.000+02:00', + }, + { + id: 'ZTU1ZDQxNzQtN2Q3Yy0wMDMxLTY2ZmYtZmIyNGM5MjM3ZTRj', + code: 'MA', + name: 'Matematik', + category: '', + blockName: '', + dayOfWeek: 5, + location: '303', + teacher: 'CBr', + timeEnd: '11:35:00', + timeStart: '10:40:00', + dateStart: '2021-04-16T10:40:00.000+02:00', + dateEnd: '2021-04-16T11:35:00.000+02:00', + } + ] +} diff --git a/libs/api-skolplattformen/lib/loginStatusChecker.ts b/libs/api-skolplattformen/lib/loginStatusChecker.ts index a2fab185..0cdb4593 100644 --- a/libs/api-skolplattformen/lib/loginStatusChecker.ts +++ b/libs/api-skolplattformen/lib/loginStatusChecker.ts @@ -2,7 +2,7 @@ import { EventEmitter } from 'events'; import { loginStatus } from './routes'; import { AuthTicket, Fetcher, LoginStatusChecker } from '@skolplattformen/api'; -export class Checker extends EventEmitter { +export class Checker extends EventEmitter implements LoginStatusChecker { public token: string; private fetcher: Fetcher; @@ -41,3 +41,10 @@ export const checkStatus = ( fetch: Fetcher, ticket: AuthTicket ): LoginStatusChecker => new Checker(fetch, ticket) + +export class DummyStatusChecker extends EventEmitter implements LoginStatusChecker { + token = "" + async cancel(): Promise { + // do nothing + } +} diff --git a/libs/api-skolplattformen/lib/parse/__tests__/schoolContacts.test.ts b/libs/api-skolplattformen/lib/parse/__tests__/schoolContacts.test.ts new file mode 100644 index 00000000..30e60d1f --- /dev/null +++ b/libs/api-skolplattformen/lib/parse/__tests__/schoolContacts.test.ts @@ -0,0 +1,50 @@ +import { EtjanstResponse } from '../' +import { schoolContacts } from '../schoolContacts' + +let response: EtjanstResponse + +beforeEach(() => { + response = { + "Success": true, + "Error": null, + "Data": [ + { + "Title": "Expedition", + "Name": null, + "Phone": "508 000 00", + "Email": "", + "SchoolName": "PĂ„hittade skolan", + "ClassName": null + }, + { + "Title": "Rektor", + "Name": "Andersson, Anna Bella Cecilia", + "Phone": "08-508 000 00", + "Email": "anna.anderssonn@edu.stockholm.se", + "SchoolName": null, + "ClassName": null + } + ] + } +}) + +it('parses teachers correctly', () => { + expect(schoolContacts(response)).toEqual([ + { + title: 'Expedition', + name: null, + phone: '508 000 00', + email: '', + schoolName: 'PĂ„hittade skolan', + className: null + }, + { + title: 'Rektor', + name: 'Andersson, Anna Bella Cecilia', + phone: '08-508 000 00', + email: 'anna.anderssonn@edu.stockholm.se', + schoolName: null, + className: null + } + ]) +}) diff --git a/libs/api-skolplattformen/lib/parse/__tests__/teachers.test.ts b/libs/api-skolplattformen/lib/parse/__tests__/teachers.test.ts new file mode 100644 index 00000000..26d44159 --- /dev/null +++ b/libs/api-skolplattformen/lib/parse/__tests__/teachers.test.ts @@ -0,0 +1,68 @@ +import { EtjanstResponse } from '../' +import { teachers } from '../teachers' + +let response: EtjanstResponse + +beforeEach(() => { + response = { + "Success": true, + "Error": null, + "Data": [ + { + "ID": 156735, + "BATCH": "GR", + "SIS_ID": "F154239A-EA4A-4C6C-A112-0B9581132E3D", + "USERNAME": "anna.andersson", + "SCHOOL_SIS_ID": "DE2E1293-0F40-4B91-9D91-1E99355DC257", + "EMAILADDRESS": null, + "STATUS": " GR", + "ERRORCODE": 0, + "FIRSTNAME": "Anna", + "LASTNAME": "Andersson", + "ACTIVE": true, + "TELWORK": "08 508 0000000" + }, + { + "ID": 156690, + "BATCH": "GR", + "SIS_ID": "9EC59FCA-80AD-4774-AABD-427040207E33", + "USERNAME": "gunnar.grymm", + "SCHOOL_SIS_ID": "DE2E1293-0F40-4B91-9D91-1E99355DC257", + "EMAILADDRESS": "gunnar.grymm@edu.stockholm.se", + "STATUS": " F", + "ERRORCODE": 0, + "FIRSTNAME": "Gunnar", + "LASTNAME": "Grymm", + "ACTIVE": true, + "TELWORK": null + } + ] + } +}) + +it('parses teachers correctly', () => { + expect(teachers(response)).toEqual([ + { + id: 156735, + sisId: 'F154239A-EA4A-4C6C-A112-0B9581132E3D', + firstname: 'Anna', + lastname: 'Andersson', + email: null, + phoneWork: '08 508 0000000', + active: true, + status: ' GR', + timeTableAbbreviation: 'AAN' + }, + { + id: 156690, + sisId: '9EC59FCA-80AD-4774-AABD-427040207E33', + firstname: 'Gunnar', + lastname: 'Grymm', + email: 'gunnar.grymm@edu.stockholm.se', + phoneWork: null, + active: true, + status: ' F', + timeTableAbbreviation: 'GGR' + }, + ]) +}) diff --git a/libs/api-skolplattformen/lib/parse/index.ts b/libs/api-skolplattformen/lib/parse/index.ts index 89eedf11..092b94eb 100644 --- a/libs/api-skolplattformen/lib/parse/index.ts +++ b/libs/api-skolplattformen/lib/parse/index.ts @@ -6,5 +6,7 @@ export * from './menu' export * from './news' export * from './notifications' export * from './schedule' +export * from './schoolContacts' +export * from './teachers' export * from './timetable' export * from './user' diff --git a/libs/api-skolplattformen/lib/parse/schoolContacts.ts b/libs/api-skolplattformen/lib/parse/schoolContacts.ts new file mode 100644 index 00000000..e26b07ff --- /dev/null +++ b/libs/api-skolplattformen/lib/parse/schoolContacts.ts @@ -0,0 +1,22 @@ +import { etjanst } from './etjanst' +import { SchoolContact } from '@skolplattformen/api' + +export const schoolContact = ({ + title, + name, + phone, + email, + schoolName, + className, +}: any): SchoolContact => ({ + title, + name, + phone, + email, + schoolName, + className, +}) + + +export const schoolContacts = (data: any): SchoolContact[] => + etjanst(data).map(schoolContact) diff --git a/libs/api-skolplattformen/lib/parse/teachers.ts b/libs/api-skolplattformen/lib/parse/teachers.ts new file mode 100644 index 00000000..cf694358 --- /dev/null +++ b/libs/api-skolplattformen/lib/parse/teachers.ts @@ -0,0 +1,29 @@ +import { etjanst } from './etjanst' +import { Teacher } from '@skolplattformen/api' + +const abbreviate = (firstname?: string, lastname?: string): string => + `${firstname?.substr(0,1)}${lastname?.substr(0,2)}`.toUpperCase() + +export const teacher = ({ + id, + sisId, + firstname, + lastname, + emailaddress, + telwork, + active, + status, +}: any): Teacher => ({ + id, + sisId, + firstname, + lastname, + email: emailaddress, + phoneWork: telwork, + active, + status, + timeTableAbbreviation: abbreviate(firstname, lastname) +}) + +export const teachers = (data: any): Teacher[] => + etjanst(data).map(teacher) diff --git a/libs/api-skolplattformen/lib/parse/timetable.ts b/libs/api-skolplattformen/lib/parse/timetable.ts index 9be35042..3719245e 100644 --- a/libs/api-skolplattformen/lib/parse/timetable.ts +++ b/libs/api-skolplattformen/lib/parse/timetable.ts @@ -84,6 +84,11 @@ export const timetable = ( if (response.error) { throw new Error(response.error) } + + if(!response.data.lessonInfo){ + throw new Error("Empty lessonInfo received") + } + return response.data.lessonInfo.map((entry) => timetableEntry(entry, year, week, lang) ) diff --git a/libs/api-skolplattformen/lib/routes.ts b/libs/api-skolplattformen/lib/routes.ts index 1c97f3c4..b0d9e030 100644 --- a/libs/api-skolplattformen/lib/routes.ts +++ b/libs/api-skolplattformen/lib/routes.ts @@ -20,6 +20,12 @@ export const calendar = (childId: string) => export const classmates = (childId: string) => `${urlLoggedIn}/contacts/GetStudentsByClass?studentId=${childId}` +export const teachers = (childId: string, schoolForm: string) => + `${urlLoggedIn}/contacts/GetTeachersByStudent?studentId=${childId}&schoolForm=${schoolForm}` + +export const schoolContacts = (childId: string, schoolId: string) => + `${urlLoggedIn}/contacts/GetSchoolContacts?schoolId=${schoolId}&studentId=${childId}&schoolForm=Klasslista` + export const user = 'https://etjanst.stockholm.se/vardnadshavare/base/getuserdata' diff --git a/libs/api/lib/api.ts b/libs/api/lib/api.ts index 00c2abbb..50f3264a 100644 --- a/libs/api/lib/api.ts +++ b/libs/api/lib/api.ts @@ -13,6 +13,8 @@ import { EtjanstChild, TimetableEntry, ScheduleItem, + SchoolContact, + Teacher } from './types' export interface Api extends EventEmitter { @@ -21,6 +23,7 @@ export interface Api extends EventEmitter { getPersonalNumber(): string | undefined login(personalNumber?: string): Promise setSessionCookie(sessionCookie: string): Promise + getSessionHeaders(url: string): Promise<{ [index: string]: string }> getUser(): Promise getChildren(): Promise getCalendar(child: EtjanstChild): Promise @@ -29,7 +32,9 @@ export interface Api extends EventEmitter { getNewsDetails(child: EtjanstChild, item: NewsItem): Promise getMenu(child: EtjanstChild): Promise getNotifications(child: EtjanstChild): Promise + getTeachers(child: EtjanstChild): Promise getSchedule(child: EtjanstChild, from: DateTime, to: DateTime): Promise + getSchoolContacts(child: EtjanstChild): Promise getSkola24Children(): Promise getTimetable(child: Skola24Child, week: number, year: number, lang: Language): Promise registerAbscense(child: EtjanstChild, startDate: DateTime, endDate: DateTime): Promise diff --git a/libs/api/lib/types.ts b/libs/api/lib/types.ts index 185f2303..9add943e 100644 --- a/libs/api/lib/types.ts +++ b/libs/api/lib/types.ts @@ -214,3 +214,24 @@ export interface TimetableEntry extends Subject { dateStart: string dateEnd: string } + + export interface Teacher { + id: number + sisId: string + firstname: string + lastname: string + email?: string + phoneWork?: string + active: boolean + status: string + timeTableAbbreviation: string +} + +export interface SchoolContact { + title?: string + name?: string + phone?: string + email?: string + schoolName: string + className: string +} diff --git a/libs/api/lib/utils/__tests__/dateHandling.test.ts b/libs/api/lib/utils/__tests__/dateHandling.test.ts index 57232b3c..a90d1509 100644 --- a/libs/api/lib/utils/__tests__/dateHandling.test.ts +++ b/libs/api/lib/utils/__tests__/dateHandling.test.ts @@ -9,6 +9,7 @@ test.each([ ['15 oktober 2020 11:34', '2020-10-15T09:34:00.000Z'], ['2020-12-18T15:59:46.34', '2020-12-18T14:59:46.340Z'], ['2020-12-18T15:59:46.340Z', '2020-12-18T15:59:46.340Z'], + ['/Date(1637935089877)/', '2021-11-26T13:58:09.877Z'], ['This is an invalid date', undefined], ])('handles date parsing of %s', (input, expected) => { expect(parseDate(input)).toEqual(expected) diff --git a/libs/hooks/README.md b/libs/hooks/README.md index 16f570fc..2ec4bd52 100644 --- a/libs/hooks/README.md +++ b/libs/hooks/README.md @@ -18,7 +18,7 @@ In order to use api hooks, you must wrap your app in an ApiProvider ```javascript import React from 'react' import { ApiProvider } from '@skolplattformen/hooks' -import init from '@skolplattformen/api-skolplattformen' +import init from '@skolplattformen/api-skolplattformet' import { CookieManager } from '@react-native-cookies/cookies' import AsyncStorage from '@react-native-async-storage/async-storage' import { RootComponent } from './components/root' diff --git a/libs/hooks/src/__mocks__/@skolplattformen/embedded-api.js b/libs/hooks/src/__mocks__/@skolplattformen/embedded-api.js index 44d2e524..109055b6 100644 --- a/libs/hooks/src/__mocks__/@skolplattformen/embedded-api.js +++ b/libs/hooks/src/__mocks__/@skolplattformen/embedded-api.js @@ -22,6 +22,8 @@ const createApi = () => ({ getNewsDetails: jest.fn(), getNotifications: jest.fn(), getSchedule: jest.fn(), + getSchoolContacts: jest.fn(), + getTeachers: jest.fn(), getTimetable: jest.fn(), getUser: jest.fn(), }) diff --git a/libs/hooks/src/hooks.ts b/libs/hooks/src/hooks.ts index 594a0cbe..97e9168b 100644 --- a/libs/hooks/src/hooks.ts +++ b/libs/hooks/src/hooks.ts @@ -9,7 +9,9 @@ import { NewsItem, Notification, ScheduleItem, + SchoolContact, Skola24Child, + Teacher, TimetableEntry, User, } from '@skolplattformen/api' @@ -107,7 +109,7 @@ const hook = ( if (newState.error) { const description = `Error getting ${entityName} from API` - reporter.error(newState.error, description) + reporter.error && reporter.error(newState.error, description) } } } @@ -201,8 +203,26 @@ export const useSchedule = (child: Child, from: string, to: string) => api.getSchedule(child, DateTime.fromISO(from), DateTime.fromISO(to)) ) +export const useSchoolContacts = (child: Child) => + hook( + 'SCHOOL_CONTACTS', + `schoolContacts_${child.id}`, + [], + (s) => s.schoolContacts, + (api) => () => api.getSchoolContacts(child) + ) + +export const useTeachers = (child: Child) => + hook( + 'TEACHERS', + `teachers_${child.id}`, + [], + (s) => s.teachers, + (api) => () => api.getTeachers(child) + ) + export const useTimetable = ( - child: Skola24Child, + child: Child, week: number, year: number, lang: Language @@ -212,9 +232,31 @@ export const useTimetable = ( `timetable_${child.personGuid}_${week}_${year}_${lang}`, [], (s) => s.timetable, - (api) => () => api.getTimetable(child, week, year, lang) + (api) => async () => { + const tt = await api.getTimetable(child, week, year, lang) + const ts = await api.getTeachers(child) + tt.forEach((element) => { + element.teacher = replaceTeacherInitials(element.teacher, ts) + }) + return tt + } ) +const replaceTeacherInitials = ( + initials: string, + teachers: Teacher[] +): string => { + if (!initials || teachers?.length == 0) return initials + const arr = initials.split(',') || [initials] + const arr2 = arr.map((element) => { + const t = teachers.find( + (t) => t.timeTableAbbreviation === element.trim().toUpperCase() + ) + return t ? `${t.firstname} ${t.lastname}` : element + }) + return arr2.join(', ') +} + export const useUser = () => hook( 'USER', diff --git a/libs/hooks/src/reducers.ts b/libs/hooks/src/reducers.ts index 44f97b88..338773e3 100644 --- a/libs/hooks/src/reducers.ts +++ b/libs/hooks/src/reducers.ts @@ -6,7 +6,9 @@ import { NewsItem, Notification, ScheduleItem, + SchoolContact, Skola24Child, + Teacher, TimetableEntry, User, } from '@skolplattformen/api' @@ -77,3 +79,5 @@ export const newsDetails = createReducer('NEWS_DETAILS') export const notifications = createReducer('NOTIFICATIONS') export const schedule = createReducer('SCHEDULE') export const timetable = createReducer('TIMETABLE') +export const teachers = createReducer('TEACHERS') +export const schoolContacts = createReducer('SCHOOL_CONTACTS') diff --git a/libs/hooks/src/store.ts b/libs/hooks/src/store.ts index 1b9aa78a..38a9e219 100644 --- a/libs/hooks/src/store.ts +++ b/libs/hooks/src/store.ts @@ -9,7 +9,9 @@ import { newsDetails, notifications, schedule, + schoolContacts, skola24Children, + teachers, timetable, user, } from './reducers' @@ -23,7 +25,9 @@ const appReducer = combineReducers({ newsDetails, notifications, schedule, + schoolContacts, skola24Children, + teachers, timetable, user, }) diff --git a/libs/hooks/src/types.ts b/libs/hooks/src/types.ts index 9d0cfef0..9c8f8f79 100644 --- a/libs/hooks/src/types.ts +++ b/libs/hooks/src/types.ts @@ -7,7 +7,9 @@ import { NewsItem, Notification, ScheduleItem, + SchoolContact, Skola24Child, + Teacher, TimetableEntry, User, } from '@skolplattformen/api' @@ -64,6 +66,8 @@ export type EntityName = | 'NEWS_DETAILS' | 'NOTIFICATIONS' | 'SCHEDULE' + | 'SCHOOL_CONTACTS' + | 'TEACHERS' | 'TIMETABLE' | 'ALL' export interface EntityAction extends Action { @@ -88,6 +92,8 @@ export interface EntityStoreRootState { newsDetails: EntityMap notifications: EntityMap schedule: EntityMap + schoolContacts: EntityMap + teachers: EntityMap timetable: EntityMap } diff --git a/package.json b/package.json index a2b491db..20eebf52 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "skolplattformen", - "version": "2.3.2", + "version": "2.10.2", "license": "MIT", "scripts": { "start": "nx start",