chore: merge yarn.lock with main
This commit is contained in:
commit
038680803b
|
@ -1,20 +1,20 @@
|
|||
import React from 'react'
|
||||
import { SafeAreaProvider } from 'react-native-safe-area-context'
|
||||
import * as eva from '@eva-design/eva'
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage'
|
||||
import CookieManager from '@react-native-community/cookies'
|
||||
import { ApiProvider } from '@skolplattformen/api-hooks'
|
||||
import init from '@skolplattformen/embedded-api'
|
||||
import { ApplicationProvider, IconRegistry } from '@ui-kitten/components'
|
||||
import { EvaIconsPack } from '@ui-kitten/eva-icons'
|
||||
import * as eva from '@eva-design/eva'
|
||||
import darkTheme from './design/dark.json'
|
||||
import lightTheme from './design/light.json'
|
||||
import { AppNavigator } from './components/navigation.component'
|
||||
import init from '@skolplattformen/embedded-api'
|
||||
import { ApiProvider } from '@skolplattformen/api-hooks'
|
||||
import CookieManager from '@react-native-community/cookies'
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage'
|
||||
import React from 'react'
|
||||
import { StatusBar } from 'react-native'
|
||||
import { useBackgroundBlur } from './utils/blur'
|
||||
import { LanguageProvider } from './context/language/languageContext'
|
||||
import { translations } from './utils/translation'
|
||||
import { AppearanceProvider, useColorScheme } from 'react-native-appearance'
|
||||
import { SafeAreaProvider } from 'react-native-safe-area-context'
|
||||
import { AppNavigator } from './components/navigation.component'
|
||||
import { LanguageProvider } from './context/language/languageContext'
|
||||
import { default as customMapping } from './design/mapping.json'
|
||||
import { darkTheme, lightTheme } from './design/themes'
|
||||
import { useBackgroundBlur } from './utils/blur'
|
||||
import { translations } from './utils/translation'
|
||||
const api = init(fetch, CookieManager)
|
||||
|
||||
const reporter = __DEV__
|
||||
|
@ -43,10 +43,8 @@ export default () => {
|
|||
<IconRegistry icons={EvaIconsPack} />
|
||||
<ApplicationProvider
|
||||
{...eva}
|
||||
theme={{
|
||||
...(colorScheme === 'dark' ? eva.dark : eva.light),
|
||||
...(colorScheme === 'dark' ? darkTheme : lightTheme),
|
||||
}}
|
||||
customMapping={customMapping}
|
||||
theme={colorScheme === 'dark' ? darkTheme : lightTheme}
|
||||
>
|
||||
<LanguageProvider cache={true} data={translations}>
|
||||
<AppNavigator />
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 59 KiB |
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Lager_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 595.3 841.9" enable-background="new 0 0 595.3 841.9" xml:space="preserve">
|
||||
<g>
|
||||
<path fill="#479CBE" d="M241.9,423.6l13.2-83.2c-5.2,0-14.1,0-14.1,0c-6.6,0-15.1-3.7-17.6-10.5c-0.8-2.3-2.7-10.2,8.2-17.9
|
||||
c3.9-2.7,6.4-5.7,6.9-8c0.5-2.4-0.1-4.5-1.8-6.1c-2.4-2.3-7.1-3.6-13.1-3.6c-10.1,0-17.2,5.8-17.9,10c-0.5,3.1,1.9,5.6,4,7.2
|
||||
c6.3,4.7,7.8,11.5,3.9,17.9c-4,6.6-12.7,10.9-22,11c0,0-9.2,0-14.4,0c-1.2,8.1-20.8,132.3-22.3,142.1h78.1
|
||||
c0.7-4.4,4.3-27.9,9.2-58.9H241.9z"/>
|
||||
<path fill="#00A5C3" d="M346.5,267.6H267l-10.6,67.3l13.5,0c7.4,0,14.4-3.4,17.4-8.3c1-1.6,1.4-3,1.4-4.3c0-2.8-1.9-4.9-3.8-6.3
|
||||
c-5.2-3.9-6.3-8-6.3-10.9c0-0.6,0-1.1,0.1-1.6c1.1-7.1,10.7-14.8,23.4-14.8c7.6,0,13.4,1.8,16.9,5.1c3.1,2.9,4.3,7,3.4,11.3
|
||||
c-1.1,5.1-6.2,9.3-9.1,11.4c-7.7,5.4-6.7,10.1-6.2,11.5c1.6,4.2,7.7,6.9,12.4,6.9H340c0,0,0,0,0,0.1c28,0.2,43,13.1,38.3,43.1
|
||||
c-4.4,27.9-25.8,39.9-51.3,40.1l-10.1,64.4h14.9c62.9,0,114.3-40.4,124.4-104.2C468.7,299.2,418.5,267.6,346.5,267.6z"/>
|
||||
<path fill="#235971" d="M346.5,267.6H267l-10.6,67.3l13.5,0c7.4,0,14.4-3.4,17.4-8.3c1-1.6,1.4-3,1.4-4.3c0-2.8-1.9-4.9-3.8-6.3
|
||||
c-5.2-3.9-6.3-8-6.3-10.9c0-0.6,0-1.1,0.1-1.6c1.1-7.1,10.7-14.8,23.4-14.8c7.6,0,13.4,1.8,16.9,5.1c3.1,2.9,4.3,7,3.4,11.3
|
||||
c-1.1,5.1-6.2,9.3-9.1,11.4c-7.7,5.4-6.7,10.1-6.2,11.5c1.6,4.2,7.7,6.9,12.4,6.9H340c0,0,0,0,0,0.1c28,0.2,43,13.1,38.3,43.1
|
||||
c-4.4,27.9-25.8,39.9-51.3,40.1l-10.1,64.4h14.9c62.9,0,114.3-40.4,124.4-104.2C468.7,299.2,418.5,267.6,346.5,267.6z"/>
|
||||
<g>
|
||||
<path fill="#235971" d="M150.7,511.2h31.9c13.6,0,16.9,6.9,15.9,13.2c-0.8,5.1-4.3,8.9-10.3,11.4c7.6,2.9,10.6,7.4,9.5,14.5
|
||||
c-1.4,8.9-9.1,15.5-19.2,15.5h-36.3L150.7,511.2z M171.8,533.8c6.2,0,9.1-3.3,9.7-7.2c0.6-4.2-1.3-7.1-7.5-7.1h-5.5l-2.2,14.3
|
||||
H171.8z M168.4,557.4c6.4,0,10.1-2.6,11-7.9c0.7-4.6-1.9-7.3-8.1-7.3H165l-2.4,15.3H168.4z"/>
|
||||
<path fill="#235971" d="M242.4,566.2c-8.3,0.6-12.3-0.3-14.3-3.9c-4.4,2.7-9.3,4.1-14.5,4.1c-9.4,0-12.7-4.9-11.8-10.3
|
||||
c0.4-2.6,1.9-5.1,4.3-7.2c5.2-4.5,18-5.1,23-8.5c0.4-3.8-1.1-5.2-5.8-5.2c-5.5,0-10.1,1.8-18,7.2l1.9-12.4
|
||||
c6.8-4.9,13.4-7.2,21-7.2c9.7,0,18.3,4,16.7,14.6l-1.9,12c-0.7,4.2-0.5,5.5,4.2,5.6L242.4,566.2z M228,547.4
|
||||
c-4.4,2.8-12.6,2.3-13.5,8.1c-0.4,2.7,1.3,4.7,4,4.7c2.6,0,5.8-1.1,8.4-2.9c-0.2-1-0.1-2,0.2-3.9L228,547.4z"/>
|
||||
<path fill="#235971" d="M257.9,523.5h16.6l-0.9,5.5c5.3-4.5,9.3-6.2,14.5-6.2c9.3,0,13.6,5.7,12.1,15l-4.3,27.9h-16.6l3.6-23.1
|
||||
c0.7-4.2-0.6-6.2-3.8-6.2c-2.6,0-5,1.4-7.3,4.5l-3.8,24.7h-16.6L257.9,523.5z"/>
|
||||
<path fill="#235971" d="M313.1,511.2h16.6l-4.2,26.8l15.9-14.5h20.5l-20.4,18l16.4,24.2h-20.9l-12.6-19.5h-0.2l-3,19.5h-16.6
|
||||
L313.1,511.2z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#479CBE" d="M371.9,511.2H391l-8.4,54.5h-19.1L371.9,511.2z"/>
|
||||
<path fill="#479CBE" d="M400.3,511.2h27.3c21.1,0,27.2,15.3,25.2,28c-1.9,12.4-11.7,26.5-30.2,26.5h-30.8L400.3,511.2z M418,552.7
|
||||
c9.3,0,14.4-4.6,15.9-14.3c1.1-7.2-1.1-14.3-11.4-14.3h-5.1l-4.4,28.6H418z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.1 KiB |
|
@ -0,0 +1,93 @@
|
|||
Copyright 2020 The Poppins Project Authors (https://github.com/itfoundry/Poppins)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -37,12 +37,6 @@ beforeEach(() => {
|
|||
AsyncStorage.clear()
|
||||
})
|
||||
|
||||
test('renders title', () => {
|
||||
const screen = setup()
|
||||
|
||||
expect(screen.getByText('Anmäl frånvaro')).toBeTruthy()
|
||||
})
|
||||
|
||||
test('can fill out the form with full day absence', async () => {
|
||||
const screen = setup()
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { useApi, useNewsDetails } from '@skolplattformen/api-hooks'
|
||||
import React from 'react'
|
||||
import { render } from '../../utils/testHelpers'
|
||||
import { NewsItem } from '../newsItem.component'
|
||||
import { fireEvent } from '@testing-library/react-native'
|
||||
import { useNewsDetails, useApi } from '@skolplattformen/api-hooks'
|
||||
|
||||
jest.mock('@skolplattformen/api-hooks')
|
||||
|
||||
|
@ -89,11 +88,3 @@ test('renders an article without modified date if date is invalid', () => {
|
|||
expect(screen.getByText('Publicerad: 15 feb 2021 10:13')).toBeTruthy()
|
||||
expect(screen.queryByText('Uppdaterad: Invalid DateTime')).toBeFalsy()
|
||||
})
|
||||
|
||||
test('handles navigating back to child view', () => {
|
||||
const screen = setup()
|
||||
|
||||
fireEvent.press(screen.getByTestId('topNavBackToChild'))
|
||||
|
||||
expect(navigation.goBack).toHaveBeenCalled()
|
||||
})
|
||||
|
|
|
@ -1,35 +1,29 @@
|
|||
import AsyncStorage from '@react-native-async-storage/async-storage'
|
||||
import { RouteProp, useNavigation, useRoute } from '@react-navigation/native'
|
||||
import { StackNavigationProp } from '@react-navigation/stack'
|
||||
import { RouteProp, useRoute } from '@react-navigation/native'
|
||||
import {
|
||||
Button,
|
||||
CheckBox,
|
||||
Divider,
|
||||
Input,
|
||||
Layout,
|
||||
StyleService,
|
||||
Text,
|
||||
TopNavigation,
|
||||
TopNavigationAction,
|
||||
useStyleSheet,
|
||||
} from '@ui-kitten/components'
|
||||
import { Formik } from 'formik'
|
||||
import moment from 'moment'
|
||||
import Personnummer from 'personnummer'
|
||||
import React from 'react'
|
||||
import React, { useCallback } from 'react'
|
||||
import { View } from 'react-native'
|
||||
import DateTimePickerModal from 'react-native-modal-datetime-picker'
|
||||
import { NativeStackNavigationOptions } from 'react-native-screens/native-stack'
|
||||
import * as Yup from 'yup'
|
||||
import { Layout as LayoutStyle, Sizing, Typography } from '../styles'
|
||||
import { SafeAreaView } from '../ui/safeAreaView.component'
|
||||
import { studentName } from '../utils/peopleHelpers'
|
||||
import { useSMS } from '../utils/SMS'
|
||||
import { translate } from '../utils/translation'
|
||||
import { BackIcon, AlertIcon } from './icon.component'
|
||||
import { AlertIcon } from './icon.component'
|
||||
import { RootStackParamList } from './navigation.component'
|
||||
import { SafeAreaViewContainer } from '../ui/safeAreaViewContainer.component'
|
||||
import { NavigationTitle } from './navigationTitle.component'
|
||||
|
||||
type AbsenceNavigationProp = StackNavigationProp<RootStackParamList, 'Absence'>
|
||||
type AbsenceRouteProps = RouteProp<RootStackParamList, 'Absence'>
|
||||
|
||||
interface AbsenceFormValues {
|
||||
|
@ -41,7 +35,21 @@ interface AbsenceFormValues {
|
|||
endTime: moment.Moment
|
||||
}
|
||||
|
||||
const Alert = (props: any) => <AlertIcon {...props} />
|
||||
export const absenceRouteOptions = ({
|
||||
route,
|
||||
}: {
|
||||
route: RouteProp<RootStackParamList, 'Absence'>
|
||||
}): NativeStackNavigationOptions => {
|
||||
const child = route.params.child
|
||||
return {
|
||||
headerCenter: () => (
|
||||
<NavigationTitle
|
||||
title={translate('abscense.title')}
|
||||
subtitle={studentName(child?.name)}
|
||||
/>
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
const Absence = () => {
|
||||
const AbsenceSchema = Yup.object().shape({
|
||||
|
@ -52,7 +60,7 @@ const Absence = () => {
|
|||
),
|
||||
isFullDay: Yup.bool().required(),
|
||||
})
|
||||
const navigation = useNavigation<AbsenceNavigationProp>()
|
||||
|
||||
const route = useRoute<AbsenceRouteProps>()
|
||||
const { sendSMS } = useSMS()
|
||||
const { child } = route.params
|
||||
|
@ -61,6 +69,28 @@ const Absence = () => {
|
|||
const maximumDate = moment().hours(17).minute(0)
|
||||
const styles = useStyleSheet(themedStyles)
|
||||
|
||||
const submit = useCallback(
|
||||
async (values: AbsenceFormValues) => {
|
||||
const ssn = Personnummer.parse(values.socialSecurityNumber).format()
|
||||
|
||||
if (values.isFullDay) {
|
||||
sendSMS(ssn)
|
||||
} else {
|
||||
sendSMS(
|
||||
`${ssn} ${moment(values.startTime).format('HHmm')}-${moment(
|
||||
values.endTime
|
||||
).format('HHmm')}`
|
||||
)
|
||||
}
|
||||
|
||||
await AsyncStorage.setItem(
|
||||
`@childssn.${child.id}`,
|
||||
values.socialSecurityNumber
|
||||
)
|
||||
},
|
||||
[child.id, sendSMS]
|
||||
)
|
||||
|
||||
React.useEffect(() => {
|
||||
const getSocialSecurityNumber = async () => {
|
||||
const ssn = await AsyncStorage.getItem(`@childssn.${child.id}`)
|
||||
|
@ -80,210 +110,155 @@ const Absence = () => {
|
|||
}
|
||||
|
||||
return (
|
||||
<SafeAreaView>
|
||||
<SafeAreaViewContainer>
|
||||
<TopNavigation
|
||||
accessoryLeft={() => (
|
||||
<TopNavigationAction
|
||||
icon={BackIcon}
|
||||
onPress={() => navigation.goBack()}
|
||||
/>
|
||||
)}
|
||||
alignment="center"
|
||||
style={styles.topBar}
|
||||
title={() => (
|
||||
<Text maxFontSizeMultiplier={1.5} style={styles.topNavigationTitle}>
|
||||
{translate('abscense.title')}
|
||||
</Text>
|
||||
)}
|
||||
subtitle={() => (
|
||||
<Text
|
||||
maxFontSizeMultiplier={1.5}
|
||||
style={styles.topNavigationSubtitle}
|
||||
>
|
||||
{studentName(child.name)}
|
||||
</Text>
|
||||
)}
|
||||
/>
|
||||
<Divider />
|
||||
<Layout style={styles.wrap}>
|
||||
<Formik
|
||||
enableReinitialize
|
||||
validationSchema={AbsenceSchema}
|
||||
initialValues={initialValues}
|
||||
onSubmit={async (values) => {
|
||||
const ssn = Personnummer.parse(
|
||||
values.socialSecurityNumber
|
||||
).format()
|
||||
<Formik
|
||||
enableReinitialize
|
||||
validationSchema={AbsenceSchema}
|
||||
initialValues={initialValues}
|
||||
onSubmit={submit}
|
||||
>
|
||||
{({
|
||||
handleChange,
|
||||
handleBlur,
|
||||
handleSubmit,
|
||||
setFieldValue,
|
||||
values,
|
||||
touched,
|
||||
errors,
|
||||
}) => {
|
||||
const hasError = (field: keyof typeof values) =>
|
||||
errors[field] && touched[field]
|
||||
|
||||
if (values.isFullDay) {
|
||||
sendSMS(ssn)
|
||||
} else {
|
||||
sendSMS(
|
||||
`${ssn} ${moment(values.startTime).format('HHmm')}-${moment(
|
||||
values.endTime
|
||||
).format('HHmm')}`
|
||||
)
|
||||
}
|
||||
|
||||
await AsyncStorage.setItem(
|
||||
`@childssn.${child.id}`,
|
||||
values.socialSecurityNumber
|
||||
)
|
||||
}}
|
||||
>
|
||||
{({
|
||||
handleChange,
|
||||
handleBlur,
|
||||
handleSubmit,
|
||||
setFieldValue,
|
||||
values,
|
||||
touched,
|
||||
errors,
|
||||
}) => {
|
||||
const hasError = (field: keyof typeof values) =>
|
||||
errors[field] && touched[field]
|
||||
|
||||
return (
|
||||
<View>
|
||||
<View style={styles.field}>
|
||||
<Text style={styles.label}>
|
||||
{translate('general.socialSecurityNumber')}
|
||||
</Text>
|
||||
<Input
|
||||
testID="socialSecurityNumberInput"
|
||||
keyboardType="number-pad"
|
||||
onChangeText={handleChange('socialSecurityNumber')}
|
||||
onBlur={handleBlur('socialSecurityNumber')}
|
||||
status={
|
||||
hasError('socialSecurityNumber') ? 'danger' : 'basic'
|
||||
}
|
||||
value={values.socialSecurityNumber}
|
||||
accessoryRight={
|
||||
errors.socialSecurityNumber ? Alert : undefined
|
||||
}
|
||||
/>
|
||||
{hasError('socialSecurityNumber') && (
|
||||
<Text style={styles.error}>
|
||||
{errors.socialSecurityNumber}
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
<View style={styles.field}>
|
||||
<CheckBox
|
||||
checked={values.isFullDay}
|
||||
onChange={(checked) =>
|
||||
setFieldValue('isFullDay', checked)
|
||||
}
|
||||
>
|
||||
{translate('abscense.entireDay')}
|
||||
</CheckBox>
|
||||
</View>
|
||||
{!values.isFullDay && (
|
||||
<View style={styles.partOfDay}>
|
||||
<View style={styles.inputHalf}>
|
||||
<Text style={styles.label}>
|
||||
{translate('abscense.startTime')}
|
||||
</Text>
|
||||
<Button
|
||||
status="basic"
|
||||
onPress={() =>
|
||||
setFieldValue('displayStartTimePicker', true)
|
||||
}
|
||||
>
|
||||
{moment(values.startTime).format('LT')}
|
||||
</Button>
|
||||
<DateTimePickerModal
|
||||
cancelTextIOS={translate('general.cancel')}
|
||||
confirmTextIOS={translate('general.confirm')}
|
||||
date={moment(values.startTime).toDate()}
|
||||
isVisible={values.displayStartTimePicker}
|
||||
headerTextIOS={translate(
|
||||
'abscense.selectAbscenseStartTime'
|
||||
)}
|
||||
locale="sv-SE"
|
||||
maximumDate={maximumDate.toDate()}
|
||||
minimumDate={minumumDate.toDate()}
|
||||
minuteInterval={10}
|
||||
mode="time"
|
||||
onConfirm={(date) => {
|
||||
setFieldValue('startTime', date)
|
||||
setFieldValue('displayStartTimePicker', false)
|
||||
}}
|
||||
onCancel={() =>
|
||||
setFieldValue('displayStartTimePicker', false)
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.spacer} />
|
||||
<View style={styles.inputHalf}>
|
||||
<Text style={styles.label}>
|
||||
{translate('abscense.endTime')}
|
||||
</Text>
|
||||
<Button
|
||||
status="basic"
|
||||
onPress={() =>
|
||||
setFieldValue('displayEndTimePicker', true)
|
||||
}
|
||||
>
|
||||
{moment(values.endTime).format('LT')}
|
||||
</Button>
|
||||
<DateTimePickerModal
|
||||
cancelTextIOS={translate('general.cancel')}
|
||||
confirmTextIOS={translate('general.confirm')}
|
||||
date={moment(values.endTime).toDate()}
|
||||
isVisible={values.displayEndTimePicker}
|
||||
headerTextIOS={translate(
|
||||
'abscense.selectAbscenseEndTime'
|
||||
)}
|
||||
// Todo fix this
|
||||
locale="sv-SE"
|
||||
maximumDate={maximumDate.toDate()}
|
||||
minimumDate={minumumDate.toDate()}
|
||||
minuteInterval={10}
|
||||
mode="time"
|
||||
onConfirm={(date) => {
|
||||
setFieldValue('endTime', date)
|
||||
setFieldValue('displayEndTimePicker', false)
|
||||
}}
|
||||
onCancel={() =>
|
||||
setFieldValue('displayEndTimePicker', false)
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
<Button onPress={handleSubmit} status="primary">
|
||||
{translate('general.send')}
|
||||
return (
|
||||
<View style={styles.wrap}>
|
||||
<View style={styles.field}>
|
||||
<Text style={styles.label}>
|
||||
{translate('general.socialSecurityNumber')}
|
||||
</Text>
|
||||
<Input
|
||||
testID="socialSecurityNumberInput"
|
||||
keyboardType="number-pad"
|
||||
onChangeText={handleChange('socialSecurityNumber')}
|
||||
onBlur={handleBlur('socialSecurityNumber')}
|
||||
status={hasError('socialSecurityNumber') ? 'danger' : 'basic'}
|
||||
value={values.socialSecurityNumber}
|
||||
style={styles.input}
|
||||
accessoryRight={
|
||||
hasError('socialSecurityNumber') ? AlertIcon : undefined
|
||||
}
|
||||
/>
|
||||
{hasError('socialSecurityNumber') && (
|
||||
<Text style={styles.error}>{errors.socialSecurityNumber}</Text>
|
||||
)}
|
||||
</View>
|
||||
<View style={styles.field}>
|
||||
<CheckBox
|
||||
checked={values.isFullDay}
|
||||
onChange={(checked) => setFieldValue('isFullDay', checked)}
|
||||
>
|
||||
{translate('abscense.entireDay')}
|
||||
</CheckBox>
|
||||
</View>
|
||||
{!values.isFullDay && (
|
||||
<View style={styles.partOfDay}>
|
||||
<View style={styles.inputHalf}>
|
||||
<Text style={styles.label}>
|
||||
{translate('abscense.startTime')}
|
||||
</Text>
|
||||
<Button
|
||||
status="basic"
|
||||
style={styles.pickerButton}
|
||||
onPress={() =>
|
||||
setFieldValue('displayStartTimePicker', true)
|
||||
}
|
||||
>
|
||||
{moment(values.startTime).format('LT')}
|
||||
</Button>
|
||||
<DateTimePickerModal
|
||||
cancelTextIOS={translate('general.cancel')}
|
||||
confirmTextIOS={translate('general.confirm')}
|
||||
date={moment(values.startTime).toDate()}
|
||||
isVisible={values.displayStartTimePicker}
|
||||
headerTextIOS={translate(
|
||||
'abscense.selectAbscenseStartTime'
|
||||
)}
|
||||
locale="sv-SE"
|
||||
maximumDate={maximumDate.toDate()}
|
||||
minimumDate={minumumDate.toDate()}
|
||||
minuteInterval={10}
|
||||
mode="time"
|
||||
onConfirm={(date) => {
|
||||
setFieldValue('startTime', date)
|
||||
setFieldValue('displayStartTimePicker', false)
|
||||
}}
|
||||
onCancel={() =>
|
||||
setFieldValue('displayStartTimePicker', false)
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
}}
|
||||
</Formik>
|
||||
</Layout>
|
||||
</SafeAreaViewContainer>
|
||||
</SafeAreaView>
|
||||
<View style={styles.spacer} />
|
||||
<View style={styles.inputHalf}>
|
||||
<Text style={styles.label}>
|
||||
{translate('abscense.endTime')}
|
||||
</Text>
|
||||
<Button
|
||||
status="basic"
|
||||
style={styles.pickerButton}
|
||||
onPress={() => setFieldValue('displayEndTimePicker', true)}
|
||||
>
|
||||
{moment(values.endTime).format('LT')}
|
||||
</Button>
|
||||
<DateTimePickerModal
|
||||
cancelTextIOS={translate('general.cancel')}
|
||||
confirmTextIOS={translate('general.confirm')}
|
||||
date={moment(values.endTime).toDate()}
|
||||
isVisible={values.displayEndTimePicker}
|
||||
headerTextIOS={translate('abscense.selectAbscenseEndTime')}
|
||||
// Todo fix this
|
||||
locale="sv-SE"
|
||||
maximumDate={maximumDate.toDate()}
|
||||
minimumDate={minumumDate.toDate()}
|
||||
minuteInterval={10}
|
||||
mode="time"
|
||||
onConfirm={(date) => {
|
||||
setFieldValue('endTime', date)
|
||||
setFieldValue('displayEndTimePicker', false)
|
||||
}}
|
||||
onCancel={() =>
|
||||
setFieldValue('displayEndTimePicker', false)
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
<Button onPress={handleSubmit} status="primary">
|
||||
{translate('general.send')}
|
||||
</Button>
|
||||
</View>
|
||||
)
|
||||
}}
|
||||
</Formik>
|
||||
)
|
||||
}
|
||||
|
||||
export default Absence
|
||||
|
||||
const themedStyles = StyleService.create({
|
||||
safeArea: {
|
||||
...LayoutStyle.flex.full,
|
||||
backgroundColor: 'background-basic-color-1',
|
||||
},
|
||||
topBar: {
|
||||
backgroundColor: 'background-basic-color-1',
|
||||
},
|
||||
wrap: {
|
||||
...LayoutStyle.flex.full,
|
||||
padding: Sizing.t5,
|
||||
padding: Sizing.t4,
|
||||
backgroundColor: 'background-basic-color-2',
|
||||
},
|
||||
field: { marginBottom: Sizing.t4 },
|
||||
partOfDay: { ...LayoutStyle.flex.row, marginBottom: Sizing.t4 },
|
||||
spacer: { width: Sizing.t2 },
|
||||
inputHalf: { ...LayoutStyle.flex.full },
|
||||
input: {
|
||||
backgroundColor: 'background-basic-color-1',
|
||||
},
|
||||
// TODO: Refactor to use mapping.json in eva design
|
||||
pickerButton: {
|
||||
backgroundColor: 'background-basic-color-1',
|
||||
},
|
||||
label: {
|
||||
...Typography.fontSize.xs,
|
||||
...Typography.fontWeight.bold,
|
||||
|
@ -293,11 +268,4 @@ const themedStyles = StyleService.create({
|
|||
error: {
|
||||
color: 'color-primary-600',
|
||||
},
|
||||
topNavigationTitle: {
|
||||
...Typography.fontWeight.semibold,
|
||||
},
|
||||
topNavigationSubtitle: {
|
||||
...Typography.fontWeight.regular,
|
||||
...Typography.fontSize.sm,
|
||||
},
|
||||
})
|
||||
|
|
|
@ -1,23 +1,30 @@
|
|||
import { StackNavigationProp } from '@react-navigation/stack'
|
||||
import {
|
||||
Layout,
|
||||
Text,
|
||||
TopNavigation,
|
||||
TopNavigationAction,
|
||||
StyleService,
|
||||
Text,
|
||||
useStyleSheet,
|
||||
useTheme,
|
||||
} from '@ui-kitten/components'
|
||||
import React from 'react'
|
||||
import { Keyboard, TouchableWithoutFeedback, View } from 'react-native'
|
||||
import { Login } from './login.component'
|
||||
import { Layout as LayoutStyle, Sizing, Typography } from '../styles'
|
||||
import { SafeAreaViewContainer } from '../ui/safeAreaViewContainer.component'
|
||||
import { translate, languages } from '../utils/translation'
|
||||
import { GlobeIcon } from './icon.component'
|
||||
import { StackNavigationProp } from '@react-navigation/stack'
|
||||
import { RootStackParamList } from './navigation.component'
|
||||
import { SafeAreaView } from '../ui/safeAreaView.component'
|
||||
import { KeyboardAvoidingView } from '../ui/keyboardAvoidingView.component'
|
||||
import {
|
||||
Image,
|
||||
ImageStyle,
|
||||
Keyboard,
|
||||
TouchableWithoutFeedback,
|
||||
View,
|
||||
} from 'react-native'
|
||||
import { TouchableOpacity } from 'react-native-gesture-handler'
|
||||
import { NativeStackNavigationOptions } from 'react-native-screens/native-stack'
|
||||
import { LanguageService } from '../services/languageService'
|
||||
import { Layout as LayoutStyle, Sizing, Typography } from '../styles'
|
||||
import { fontSize } from '../styles/typography'
|
||||
import { KeyboardAvoidingView } from '../ui/keyboardAvoidingView.component'
|
||||
import { SafeAreaView } from '../ui/safeAreaView.component'
|
||||
import { SafeAreaViewContainer } from '../ui/safeAreaViewContainer.component'
|
||||
import { languages, translate } from '../utils/translation'
|
||||
import { GlobeIcon } from './icon.component'
|
||||
import { Login } from './login.component'
|
||||
import { RootStackParamList } from './navigation.component'
|
||||
|
||||
const randomWord = () => {
|
||||
const words = translate('auth.words')
|
||||
|
@ -34,8 +41,17 @@ interface AuthProps {
|
|||
navigation: StackNavigationProp<RootStackParamList, 'Login'>
|
||||
}
|
||||
|
||||
export const authRouteOptions = (): NativeStackNavigationOptions => {
|
||||
return {
|
||||
headerShown: false,
|
||||
replaceAnimation: 'push',
|
||||
stackAnimation: 'fade',
|
||||
}
|
||||
}
|
||||
|
||||
export const Auth: React.FC<AuthProps> = ({ navigation }) => {
|
||||
const styles = useStyleSheet(themeStyles)
|
||||
const colors = useTheme()
|
||||
|
||||
const currentLanguage = LanguageService.getLanguageCode()
|
||||
const currentLanguageName = languages.find(
|
||||
|
@ -43,65 +59,104 @@ export const Auth: React.FC<AuthProps> = ({ navigation }) => {
|
|||
)?.languageLocalName
|
||||
|
||||
return (
|
||||
<KeyboardAvoidingView>
|
||||
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
|
||||
<SafeAreaView>
|
||||
<SafeAreaViewContainer>
|
||||
<TopNavigation
|
||||
alignment="start"
|
||||
subtitle={currentLanguageName}
|
||||
accessoryLeft={() => (
|
||||
<TopNavigationAction
|
||||
accessibilityHint={translate(
|
||||
'auth.a11y_navigate_to_change_language',
|
||||
{
|
||||
defaultValue: 'Navigerar till vyn för att byta språk',
|
||||
}
|
||||
)}
|
||||
accessibilityLabel={translate('auth.a11y_change_language', {
|
||||
defaultValue: 'Byt språk',
|
||||
})}
|
||||
accessible={true}
|
||||
icon={GlobeIcon}
|
||||
onPress={() => navigation.navigate('SetLanguage')}
|
||||
/>
|
||||
<SafeAreaView>
|
||||
<SafeAreaViewContainer>
|
||||
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
|
||||
<View style={LayoutStyle.flex.full}>
|
||||
<TouchableOpacity
|
||||
onPress={() => navigation.navigate('SetLanguage')}
|
||||
accessibilityHint={translate(
|
||||
'auth.a11y_navigate_to_change_language',
|
||||
{
|
||||
defaultValue: 'Navigerar till vyn för att byta språk',
|
||||
}
|
||||
)}
|
||||
/>
|
||||
<View style={styles.content}>
|
||||
<Layout style={styles.container}>
|
||||
<Text category="h2" adjustsFontSizeToFit numberOfLines={1}>
|
||||
{translate('general.title')}
|
||||
</Text>
|
||||
<Text style={styles.subtitle}>
|
||||
{translate('auth.subtitle', {
|
||||
word: randomWord(),
|
||||
})}
|
||||
</Text>
|
||||
<Login />
|
||||
</Layout>
|
||||
</View>
|
||||
</SafeAreaViewContainer>
|
||||
</SafeAreaView>
|
||||
</TouchableWithoutFeedback>
|
||||
</KeyboardAvoidingView>
|
||||
accessibilityLabel={translate('auth.a11y_change_language', {
|
||||
defaultValue: 'Byt språk',
|
||||
})}
|
||||
>
|
||||
<View style={styles.language}>
|
||||
<GlobeIcon
|
||||
height={24}
|
||||
width={24}
|
||||
fill={colors['color-primary-500']}
|
||||
/>
|
||||
<Text style={styles.languageText}>{currentLanguageName}</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
<KeyboardAvoidingView>
|
||||
<View style={styles.content}>
|
||||
<View style={styles.imageWrapper}>
|
||||
<Image
|
||||
source={require('../assets/boys.png')}
|
||||
style={styles.image as ImageStyle}
|
||||
accessibilityHint={translate('login.a11y_image_two_boys', {
|
||||
defaultValue: 'Bild på två personer som kollar i mobilen',
|
||||
})}
|
||||
resizeMode="contain"
|
||||
accessibilityIgnoresInvertColors={false}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.container}>
|
||||
<Text
|
||||
category="h1"
|
||||
style={styles.header}
|
||||
adjustsFontSizeToFit
|
||||
numberOfLines={2}
|
||||
>
|
||||
{translate('general.title')}
|
||||
</Text>
|
||||
<Login />
|
||||
<Text category="c2" style={styles.subtitle}>
|
||||
{translate('auth.subtitle', {
|
||||
word: randomWord(),
|
||||
})}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</KeyboardAvoidingView>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
</SafeAreaViewContainer>
|
||||
</SafeAreaView>
|
||||
)
|
||||
}
|
||||
|
||||
const themeStyles = StyleService.create({
|
||||
container: {
|
||||
...LayoutStyle.mainAxis.center,
|
||||
...LayoutStyle.mainAxis.flexStart,
|
||||
...LayoutStyle.crossAxis.flexEnd,
|
||||
padding: Sizing.t5,
|
||||
padding: Sizing.t6,
|
||||
},
|
||||
imageWrapper: {
|
||||
flex: 1,
|
||||
justifyContent: 'flex-end',
|
||||
},
|
||||
image: {
|
||||
...Sizing.aspectRatio(1.5, Sizing.Ratio['4:3']),
|
||||
},
|
||||
content: {
|
||||
...LayoutStyle.center,
|
||||
...LayoutStyle.flex.full,
|
||||
},
|
||||
header: {
|
||||
width: '60%',
|
||||
marginBottom: Sizing.t5,
|
||||
fontFamily: 'Poppins-Black',
|
||||
fontWeight: '900',
|
||||
},
|
||||
subtitle: {
|
||||
...Typography.align.center,
|
||||
...Typography.fontSize.base,
|
||||
...Typography.fontWeight.bold,
|
||||
color: 'color-basic-500',
|
||||
marginTop: Sizing.t1,
|
||||
width: '100%',
|
||||
textAlign: 'center',
|
||||
...Typography.fontSize.xs,
|
||||
marginTop: Sizing.t5,
|
||||
},
|
||||
language: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
paddingLeft: Sizing.t4,
|
||||
},
|
||||
languageText: {
|
||||
...fontSize.xs,
|
||||
marginLeft: Sizing.t1,
|
||||
},
|
||||
})
|
||||
|
|
|
@ -65,12 +65,12 @@ export const Calendar = () => {
|
|||
|
||||
const themedStyles = StyleService.create({
|
||||
container: {
|
||||
backgroundColor: 'background-basic-color-2',
|
||||
backgroundColor: 'background-basic-color-1',
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
},
|
||||
description: {
|
||||
...Typography.fontSize.xs,
|
||||
color: 'color-basic-600',
|
||||
color: 'text-hint-color',
|
||||
},
|
||||
})
|
||||
|
|
|
@ -1,182 +1,126 @@
|
|||
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'
|
||||
import {
|
||||
BottomTabBarOptions,
|
||||
BottomTabBarProps,
|
||||
createBottomTabNavigator,
|
||||
} from '@react-navigation/bottom-tabs'
|
||||
import { RouteProp, useNavigation, useRoute } from '@react-navigation/native'
|
||||
getFocusedRouteNameFromRoute,
|
||||
RouteProp,
|
||||
useRoute,
|
||||
} from '@react-navigation/native'
|
||||
import { StackNavigationProp } from '@react-navigation/stack'
|
||||
import {
|
||||
BottomNavigation,
|
||||
BottomNavigationTab,
|
||||
Layout,
|
||||
StyleService,
|
||||
Text,
|
||||
TopNavigation,
|
||||
TopNavigationAction,
|
||||
useStyleSheet,
|
||||
} from '@ui-kitten/components'
|
||||
import { Icon } from '@ui-kitten/components'
|
||||
import React from 'react'
|
||||
import { StyleProp, TextProps } from 'react-native'
|
||||
import { studentName } from '../utils/peopleHelpers'
|
||||
import { NativeStackNavigationOptions } from 'react-native-screens/native-stack'
|
||||
import { defaultStackStyling } from '../design/navigationThemes'
|
||||
import { translate } from '../utils/translation'
|
||||
import { Calendar } from './calendar.component'
|
||||
import { ChildProvider } from './childContext.component'
|
||||
import { Menu } from './menu.component'
|
||||
import {
|
||||
BackIcon,
|
||||
CalendarOutlineIcon,
|
||||
MenuIcon,
|
||||
NewsIcon,
|
||||
NotificationsIcon,
|
||||
} from './icon.component'
|
||||
import { RootStackParamList } from './navigation.component'
|
||||
import { NewsList } from './newsList.component'
|
||||
import { NotificationsList } from './notificationsList.component'
|
||||
import { translate } from '../utils/translation'
|
||||
import { SafeAreaView } from '../ui/safeAreaView.component'
|
||||
import { SafeAreaViewContainer } from '../ui/safeAreaViewContainer.component'
|
||||
import { Typography } from '../styles'
|
||||
|
||||
type ChildNavigationProp = StackNavigationProp<RootStackParamList, 'Child'>
|
||||
type ChildRouteProps = RouteProp<RootStackParamList, 'Child'>
|
||||
|
||||
export type ChildTabParamList = {
|
||||
News: undefined
|
||||
Notifications: undefined
|
||||
Calendar: undefined
|
||||
Menu: undefined
|
||||
}
|
||||
|
||||
interface TabTitleProps {
|
||||
children: string
|
||||
style?: StyleProp<TextProps>
|
||||
}
|
||||
|
||||
const { Navigator, Screen } = createBottomTabNavigator()
|
||||
const { Navigator, Screen } = createBottomTabNavigator<ChildTabParamList>()
|
||||
|
||||
const NewsScreen = () => {
|
||||
return (
|
||||
<Layout>
|
||||
<NewsList />
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
const NewsScreen = () => <NewsList />
|
||||
const NotificationsScreen = () => <NotificationsList />
|
||||
const CalendarScreen = () => <Calendar />
|
||||
const MenuScreen = () => <Menu />
|
||||
|
||||
const NotificationsScreen = () => {
|
||||
return (
|
||||
<Layout>
|
||||
<NotificationsList />
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
||||
const CalendarScreen = () => {
|
||||
return (
|
||||
<Layout>
|
||||
<Calendar />
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
||||
const MenuScreen = () => {
|
||||
return (
|
||||
<Layout>
|
||||
<Menu />
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
||||
const TabTitle = ({ style, children }: TabTitleProps) => (
|
||||
<Text
|
||||
maxFontSizeMultiplier={1.5}
|
||||
adjustsFontSizeToFit
|
||||
numberOfLines={1}
|
||||
style={style}
|
||||
>
|
||||
{children}
|
||||
</Text>
|
||||
)
|
||||
|
||||
const BottomTabBar = ({
|
||||
navigation,
|
||||
state,
|
||||
}: BottomTabBarProps<BottomTabBarOptions>) => (
|
||||
<BottomNavigation
|
||||
accessibilityRole="menu"
|
||||
selectedIndex={state.index}
|
||||
onSelect={(index) => navigation.navigate(state.routeNames[index])}
|
||||
>
|
||||
<BottomNavigationTab
|
||||
accessibilityRole="menuitem"
|
||||
title={(props) => (
|
||||
<TabTitle {...props}>{translate('navigation.news')}</TabTitle>
|
||||
)}
|
||||
icon={NewsIcon}
|
||||
/>
|
||||
<BottomNavigationTab
|
||||
accessibilityRole="menuitem"
|
||||
title={(props) => (
|
||||
<TabTitle {...props}>{translate('navigation.notifications')}</TabTitle>
|
||||
)}
|
||||
icon={NotificationsIcon}
|
||||
/>
|
||||
<BottomNavigationTab
|
||||
accessibilityRole="menuitem"
|
||||
title={(props) => (
|
||||
<TabTitle {...props}>{translate('navigation.calender')}</TabTitle>
|
||||
)}
|
||||
icon={CalendarOutlineIcon}
|
||||
/>
|
||||
<BottomNavigationTab
|
||||
accessibilityRole="menuitem"
|
||||
title={(props) => (
|
||||
<TabTitle {...props}>{translate('navigation.menu')}</TabTitle>
|
||||
)}
|
||||
icon={MenuIcon}
|
||||
/>
|
||||
</BottomNavigation>
|
||||
)
|
||||
|
||||
const TabNavigator = ({ initialRouteName = 'Nyheter' }) => (
|
||||
const TabNavigator = ({
|
||||
initialRouteName = 'News',
|
||||
}: {
|
||||
initialRouteName: keyof ChildTabParamList
|
||||
}) => (
|
||||
<Navigator
|
||||
initialRouteName={initialRouteName}
|
||||
tabBar={(props) => <BottomTabBar {...props} />}
|
||||
screenOptions={({ route }) => {
|
||||
return {
|
||||
tabBarIcon: ({ focused, color }) => {
|
||||
let iconName = 'news'
|
||||
|
||||
if (route.name === 'News')
|
||||
iconName = focused ? 'book-open' : 'book-open-outline'
|
||||
else if (route.name === 'Notifications')
|
||||
iconName = focused ? 'alert-circle' : 'alert-circle-outline'
|
||||
else if (route.name === 'Calendar')
|
||||
iconName = focused ? 'calendar' : 'calendar-outline'
|
||||
else if (route.name === 'Menu')
|
||||
iconName = focused ? 'clipboard' : 'clipboard-outline'
|
||||
return <Icon name={iconName} fill={color} height={24} width={24} />
|
||||
},
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Screen name={'navigation.news'} component={NewsScreen} />
|
||||
<Screen name={'navigation.notifications'} component={NotificationsScreen} />
|
||||
<Screen name={'navigation.calender'} component={CalendarScreen} />
|
||||
<Screen name={'navigation.menu'} component={MenuScreen} />
|
||||
<Screen
|
||||
name="News"
|
||||
component={NewsScreen}
|
||||
options={{ title: translate('navigation.news') }}
|
||||
/>
|
||||
<Screen
|
||||
name="Notifications"
|
||||
component={NotificationsScreen}
|
||||
options={{ title: translate('navigation.notifications') }}
|
||||
/>
|
||||
<Screen
|
||||
name="Calendar"
|
||||
component={CalendarScreen}
|
||||
options={{ title: translate('navigation.calender') }}
|
||||
/>
|
||||
<Screen
|
||||
name="Menu"
|
||||
component={MenuScreen}
|
||||
options={{ title: translate('navigation.menu') }}
|
||||
/>
|
||||
</Navigator>
|
||||
)
|
||||
|
||||
export const Child = () => {
|
||||
const navigation = useNavigation<ChildNavigationProp>()
|
||||
const route = useRoute<ChildRouteProps>()
|
||||
const { child, initialRouteName } = route.params
|
||||
const styles = useStyleSheet(themedStyles)
|
||||
const getHeaderTitle = (route: any) => {
|
||||
const routeName = getFocusedRouteNameFromRoute(route) ?? 'News'
|
||||
|
||||
const BackAction = () => (
|
||||
<TopNavigationAction icon={BackIcon} onPress={navigateBack} />
|
||||
)
|
||||
|
||||
const navigateBack = () => {
|
||||
navigation.goBack()
|
||||
switch (routeName) {
|
||||
case 'News':
|
||||
return translate('navigation.news')
|
||||
case 'Notifications':
|
||||
return translate('navigation.notifications')
|
||||
case 'Calendar':
|
||||
return translate('navigation.calender')
|
||||
case 'Menu':
|
||||
return translate('navigation.menu')
|
||||
}
|
||||
|
||||
return (
|
||||
<SafeAreaView>
|
||||
<SafeAreaViewContainer>
|
||||
<ChildProvider child={child}>
|
||||
<TopNavigation
|
||||
title={() => (
|
||||
<Text maxFontSizeMultiplier={2} style={styles.topNavigationTitle}>
|
||||
{studentName(child.name)}
|
||||
</Text>
|
||||
)}
|
||||
alignment="center"
|
||||
accessoryLeft={BackAction}
|
||||
/>
|
||||
<TabNavigator initialRouteName={initialRouteName} />
|
||||
</ChildProvider>
|
||||
</SafeAreaViewContainer>
|
||||
</SafeAreaView>
|
||||
)
|
||||
}
|
||||
|
||||
const themedStyles = StyleService.create({
|
||||
topNavigationTitle: {
|
||||
...Typography.fontWeight.semibold,
|
||||
},
|
||||
})
|
||||
export const childRouteOptions = ({
|
||||
route,
|
||||
}: {
|
||||
route: RouteProp<RootStackParamList, 'Child'>
|
||||
}): NativeStackNavigationOptions => {
|
||||
return {
|
||||
...defaultStackStyling,
|
||||
title: getHeaderTitle(route),
|
||||
}
|
||||
}
|
||||
|
||||
export const Child = () => {
|
||||
const route = useRoute<ChildRouteProps>()
|
||||
const { child, initialRouteName } = route.params
|
||||
|
||||
return (
|
||||
<ChildProvider child={child}>
|
||||
<TabNavigator initialRouteName={initialRouteName as any} />
|
||||
</ChildProvider>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -3,34 +3,26 @@ import { useNavigation } from '@react-navigation/native'
|
|||
import { StackNavigationProp } from '@react-navigation/stack'
|
||||
import {
|
||||
useCalendar,
|
||||
useMenu,
|
||||
useNews,
|
||||
useNotifications,
|
||||
useSchedule,
|
||||
} from '@skolplattformen/api-hooks'
|
||||
import { Child } from '@skolplattformen/embedded-api'
|
||||
|
||||
import {
|
||||
Avatar,
|
||||
Button,
|
||||
Card,
|
||||
StyleService,
|
||||
Text,
|
||||
useStyleSheet,
|
||||
} from '@ui-kitten/components'
|
||||
import moment from 'moment'
|
||||
import React from 'react'
|
||||
import { View } from 'react-native'
|
||||
import { TouchableOpacity, View } from 'react-native'
|
||||
import { Layout, Sizing } from '../styles'
|
||||
import { studentName } from '../utils/peopleHelpers'
|
||||
import { translate } from '../utils/translation'
|
||||
import {
|
||||
CalendarOutlineIcon,
|
||||
MenuIcon,
|
||||
NewsIcon,
|
||||
NotificationsIcon,
|
||||
} from './icon.component'
|
||||
import { RootStackParamList } from './navigation.component'
|
||||
import { StudentAvatar } from './studentAvatar.component'
|
||||
import { DaySummary } from './daySummary.component'
|
||||
|
||||
interface ChildListItemProps {
|
||||
child: Child
|
||||
|
@ -40,22 +32,20 @@ type ChildListItemNavigationProp = StackNavigationProp<
|
|||
RootStackParamList,
|
||||
'Children'
|
||||
>
|
||||
|
||||
export const ChildListItem = ({ child, color }: ChildListItemProps) => {
|
||||
// Forces rerender when child.id changes
|
||||
React.useEffect(() => {}, [child.id])
|
||||
|
||||
const navigation = useNavigation<ChildListItemNavigationProp>()
|
||||
const { data: notifications, status: notificationsStatus } = useNotifications(
|
||||
child
|
||||
)
|
||||
const { data: news, status: newsStatus } = useNews(child)
|
||||
const { data: calendar, status: calendarStatus } = useCalendar(child)
|
||||
const { data: notifications } = useNotifications(child)
|
||||
const { data: news } = useNews(child)
|
||||
const { data: calendar } = useCalendar(child)
|
||||
const { data: schedule } = useSchedule(
|
||||
child,
|
||||
moment().toISOString(),
|
||||
moment().add(7, 'days').toISOString()
|
||||
)
|
||||
const { status: menuStatus } = useMenu(child)
|
||||
|
||||
const notificationsThisWeek = notifications.filter(({ dateCreated }) =>
|
||||
dateCreated ? moment(dateCreated).isSame(moment(), 'week') : false
|
||||
|
@ -105,189 +95,103 @@ export const ChildListItem = ({ child, color }: ChildListItemProps) => {
|
|||
|
||||
const className = getClassName()
|
||||
const styles = useStyleSheet(themeStyles)
|
||||
|
||||
const statusColors = {
|
||||
loading: 'basic',
|
||||
loaded: 'basic',
|
||||
error: 'error',
|
||||
pending: 'basic',
|
||||
}
|
||||
|
||||
const buttonAppearance: string = 'ghost'
|
||||
|
||||
const Footer = () => {
|
||||
return (
|
||||
<View style={styles.itemFooter}>
|
||||
<Button
|
||||
style={styles.item}
|
||||
accessible={true}
|
||||
accessibilityLabel={`${child.name}, ${translate('navigation.news')}`}
|
||||
accessibilityRole="button"
|
||||
size="small"
|
||||
appearance={buttonAppearance}
|
||||
status={statusColors[newsStatus]}
|
||||
onPress={() =>
|
||||
navigation.navigate('Child', {
|
||||
child,
|
||||
color,
|
||||
initialRouteName: 'navigation.news',
|
||||
})
|
||||
}
|
||||
accessoryLeft={NewsIcon}
|
||||
>
|
||||
{`${(news || []).length}`}
|
||||
</Button>
|
||||
<Button
|
||||
style={styles.item}
|
||||
accessible={true}
|
||||
accessibilityLabel={`${child.name}, ${translate(
|
||||
'navigation.notifications'
|
||||
)}`}
|
||||
accessibilityRole="button"
|
||||
size="small"
|
||||
appearance={buttonAppearance}
|
||||
status={statusColors[notificationsStatus]}
|
||||
onPress={() =>
|
||||
navigation.navigate('Child', {
|
||||
child,
|
||||
color,
|
||||
initialRouteName: 'navigation.notifications',
|
||||
})
|
||||
}
|
||||
accessoryLeft={NotificationsIcon}
|
||||
>
|
||||
{`${(notifications || []).length}`}
|
||||
</Button>
|
||||
<Button
|
||||
style={styles.item}
|
||||
accessible={true}
|
||||
accessibilityLabel={`${child.name}, ${translate(
|
||||
'navigation.calender'
|
||||
)}`}
|
||||
accessibilityRole="button"
|
||||
size="small"
|
||||
appearance={buttonAppearance}
|
||||
status={statusColors[calendarStatus]}
|
||||
onPress={() =>
|
||||
navigation.navigate('Child', {
|
||||
child,
|
||||
color,
|
||||
initialRouteName: 'navigation.calender',
|
||||
})
|
||||
}
|
||||
accessoryLeft={CalendarOutlineIcon}
|
||||
>
|
||||
{`${(calendar || []).length}`}
|
||||
</Button>
|
||||
<Button
|
||||
style={styles.item}
|
||||
accessible={true}
|
||||
accessibilityLabel={`${child.name}, ${translate('navigation.menu')}`}
|
||||
accessibilityRole="button"
|
||||
size="small"
|
||||
appearance={buttonAppearance}
|
||||
status={statusColors[menuStatus]}
|
||||
onPress={() =>
|
||||
navigation.navigate('Child', {
|
||||
child,
|
||||
color,
|
||||
initialRouteName: 'navigation.menu',
|
||||
})
|
||||
}
|
||||
accessoryLeft={MenuIcon}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
const date = moment()
|
||||
|
||||
return (
|
||||
<Card
|
||||
style={styles.card}
|
||||
appearance="filled"
|
||||
status={color}
|
||||
header={(props) => (
|
||||
<View {...props} style={styles.cardHeader}>
|
||||
<View style={styles.cardAvatar}>
|
||||
<Avatar source={require('../assets/avatar.png')} shape="square" />
|
||||
</View>
|
||||
<View style={styles.cardHeaderText}>
|
||||
<Text category="h6">{studentName(child.name)}</Text>
|
||||
{className ? <Text category="s1">{className}</Text> : null}
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
footer={Footer}
|
||||
<TouchableOpacity
|
||||
onPress={() => navigation.navigate('Child', { child, color })}
|
||||
>
|
||||
{scheduleAndCalendarThisWeek.slice(0, 3).map((calendarItem, i) => (
|
||||
<Text category="p1" key={i}>
|
||||
{`${calendarItem.title} (${displayDate(calendarItem.startDate)})`}
|
||||
</Text>
|
||||
))}
|
||||
{notificationsThisWeek.slice(0, 3).map((notification, i) => (
|
||||
<Text category="p1" key={i}>
|
||||
{translate('notifications.notificationTitle', {
|
||||
message: notification.message,
|
||||
dateCreated: displayDate(notification.dateCreated),
|
||||
})}
|
||||
</Text>
|
||||
))}
|
||||
{newsThisWeek.slice(0, 3).map((newsItem, i) => (
|
||||
<Text category="p1" key={i}>
|
||||
{translate('news.notificationTitle', {
|
||||
header: newsItem.header,
|
||||
published: displayDate(newsItem.published),
|
||||
})}
|
||||
</Text>
|
||||
))}
|
||||
{scheduleAndCalendarThisWeek.length ||
|
||||
notificationsThisWeek.length ||
|
||||
newsThisWeek.length ? null : (
|
||||
<Text category="p1" style={styles.noNewNewsItemsText}>
|
||||
{translate('news.noNewNewsItemsThisWeek')}
|
||||
</Text>
|
||||
)}
|
||||
<View style={styles.itemFooterAbsence}>
|
||||
<Button
|
||||
accessible={true}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={`${child.name}, ${translate('abscense.title')}`}
|
||||
size="small"
|
||||
status="primary"
|
||||
onPress={() => navigation.navigate('Absence', { child })}
|
||||
>
|
||||
{translate('abscense.title')}
|
||||
</Button>
|
||||
<View style={styles.card}>
|
||||
<View style={styles.cardHeader}>
|
||||
<View style={styles.cardHeaderLeft}>
|
||||
<StudentAvatar name={studentName(child.name)} color={color} />
|
||||
<View style={styles.cardHeaderText}>
|
||||
<Text category="h6">{studentName(child.name)}</Text>
|
||||
{className ? <Text category="s1">{className}</Text> : null}
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
{/*<DaySummary child={child} date={date} />*/}
|
||||
{scheduleAndCalendarThisWeek.slice(0, 3).map((calendarItem, i) => (
|
||||
<Text category="p1" key={i}>
|
||||
{`${calendarItem.title} (${displayDate(calendarItem.startDate)})`}
|
||||
</Text>
|
||||
))}
|
||||
{notificationsThisWeek.slice(0, 3).map((notification, i) => (
|
||||
<Text category="p1" key={i}>
|
||||
{translate('notifications.notificationTitle', {
|
||||
message: notification.message,
|
||||
dateCreated: displayDate(notification.dateCreated),
|
||||
})}
|
||||
</Text>
|
||||
))}
|
||||
{newsThisWeek.slice(0, 3).map((newsItem, i) => (
|
||||
<Text category="p1" key={i}>
|
||||
{translate('news.notificationTitle', {
|
||||
header: newsItem.header,
|
||||
published: displayDate(newsItem.published),
|
||||
})}
|
||||
</Text>
|
||||
))}
|
||||
{scheduleAndCalendarThisWeek.length ||
|
||||
notificationsThisWeek.length ||
|
||||
newsThisWeek.length ? null : (
|
||||
<Text category="p1" style={styles.noNewNewsItemsText}>
|
||||
{translate('news.noNewNewsItemsThisWeek')}
|
||||
</Text>
|
||||
)}
|
||||
<View style={styles.itemFooterAbsence}>
|
||||
<Button
|
||||
accessible
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={`${child.name}, ${translate('abscense.title')}`}
|
||||
size="small"
|
||||
status="basic"
|
||||
onPress={() => navigation.navigate('Absence', { child })}
|
||||
>
|
||||
{translate('abscense.title')}
|
||||
</Button>
|
||||
</View>
|
||||
</View>
|
||||
</Card>
|
||||
</TouchableOpacity>
|
||||
)
|
||||
}
|
||||
|
||||
const themeStyles = StyleService.create({
|
||||
card: {
|
||||
marginBottom: Sizing.t5,
|
||||
borderRadius: 25,
|
||||
padding: Sizing.t5,
|
||||
marginBottom: Sizing.t4,
|
||||
backgroundColor: 'background-basic-color-1',
|
||||
},
|
||||
cardHeader: {
|
||||
...Layout.flex.row,
|
||||
...Layout.mainAxis.center,
|
||||
...Layout.crossAxis.spaceBetween,
|
||||
marginBottom: Sizing.t4,
|
||||
},
|
||||
cardHeaderLeft: {
|
||||
...Layout.flex.row,
|
||||
...Layout.mainAxis.center,
|
||||
flex: 1,
|
||||
},
|
||||
cardHeaderText: {
|
||||
marginHorizontal: Sizing.t4,
|
||||
flex: 1,
|
||||
},
|
||||
cardAvatar: { margin: Sizing.t5, marginRight: 0 },
|
||||
cardHeaderText: { margin: Sizing.t5, flex: 1 },
|
||||
itemFooter: {
|
||||
...Layout.flex.row,
|
||||
...Layout.crossAxis.evenly,
|
||||
paddingVertical: Sizing.t2,
|
||||
borderRadius: 5,
|
||||
margin: 0,
|
||||
marginTop: Sizing.t4,
|
||||
},
|
||||
itemFooterAbsence: {
|
||||
...Layout.mainAxis.flexStart,
|
||||
marginTop: Sizing.t4,
|
||||
},
|
||||
item: {
|
||||
paddingHorizontal: 0,
|
||||
},
|
||||
noNewNewsItemsText: {
|
||||
color: 'color-basic-600',
|
||||
marginRight: 12,
|
||||
paddingHorizontal: 2,
|
||||
paddingVertical: 0,
|
||||
marginBottom: 0,
|
||||
},
|
||||
noNewNewsItemsText: {},
|
||||
})
|
||||
|
|
|
@ -1,54 +1,71 @@
|
|||
import AsyncStorage from '@react-native-async-storage/async-storage'
|
||||
|
||||
import { useNavigation } from '@react-navigation/core'
|
||||
import { useApi, useChildList } from '@skolplattformen/api-hooks'
|
||||
import { Child } from '@skolplattformen/embedded-api'
|
||||
import {
|
||||
Button,
|
||||
Divider,
|
||||
Layout,
|
||||
List,
|
||||
Spinner,
|
||||
StyleService,
|
||||
Text,
|
||||
TopNavigation,
|
||||
TopNavigationAction,
|
||||
useTheme,
|
||||
useStyleSheet,
|
||||
} from '@ui-kitten/components'
|
||||
import React from 'react'
|
||||
import React, { useCallback, useEffect, useMemo } from 'react'
|
||||
import {
|
||||
Image,
|
||||
ListRenderItemInfo,
|
||||
StyleSheet,
|
||||
View,
|
||||
ImageStyle,
|
||||
Linking,
|
||||
ListRenderItemInfo,
|
||||
View,
|
||||
} from 'react-native'
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
||||
import { NativeStackNavigationOptions } from 'react-native-screens/native-stack'
|
||||
import ActionSheet from 'rn-actionsheet-module'
|
||||
import { defaultStackStyling } from '../design/navigationThemes'
|
||||
import { Colors, Layout as LayoutStyle, Sizing, Typography } from '../styles'
|
||||
import { translate } from '../utils/translation'
|
||||
import { ChildListItem } from './childListItem.component'
|
||||
import { SettingsIcon } from './icon.component'
|
||||
import { CloseOutlineIcon } from './icon.component'
|
||||
|
||||
const colors = ['primary', 'success', 'info', 'warning', 'danger']
|
||||
|
||||
export const childenRouteOptions = (): NativeStackNavigationOptions => {
|
||||
return {
|
||||
...defaultStackStyling,
|
||||
title: translate('children.title'),
|
||||
headerLargeTitle: true,
|
||||
headerLargeTitleHideShadow: true,
|
||||
}
|
||||
}
|
||||
|
||||
export const Children = () => {
|
||||
const settingsOptions = [
|
||||
translate('general.logout'),
|
||||
translate('general.cancel'),
|
||||
]
|
||||
const theme = useTheme()
|
||||
const styles = useStyleSheet(themedStyles)
|
||||
|
||||
const navigation = useNavigation()
|
||||
|
||||
const { api } = useApi()
|
||||
const { data: childList, status, reload } = useChildList()
|
||||
const insets = useSafeAreaInsets()
|
||||
const handleSettingSelection = (index: number) => {
|
||||
switch (index) {
|
||||
case 0:
|
||||
logout()
|
||||
break
|
||||
}
|
||||
let { data: childList, status, reload } = useChildList()
|
||||
const reloadChildren = () => {
|
||||
reload()
|
||||
}
|
||||
|
||||
const settings = () => {
|
||||
const logout = useCallback(() => {
|
||||
api.logout()
|
||||
AsyncStorage.clear()
|
||||
}, [api])
|
||||
|
||||
const settingsOptions = useMemo(() => {
|
||||
return [translate('general.logout'), translate('general.cancel')]
|
||||
}, [])
|
||||
|
||||
const handleSettingSelection = useCallback(
|
||||
(index: number) => {
|
||||
if (index === 0) logout()
|
||||
},
|
||||
[logout]
|
||||
)
|
||||
|
||||
const settings = useCallback(() => {
|
||||
const options = {
|
||||
cancelButtonIndex: 1,
|
||||
title: translate('general.settings'),
|
||||
|
@ -58,126 +75,93 @@ export const Children = () => {
|
|||
}
|
||||
|
||||
ActionSheet(options, handleSettingSelection)
|
||||
}
|
||||
}, [handleSettingSelection, settingsOptions])
|
||||
|
||||
const reloadChildren = () => {
|
||||
reload()
|
||||
}
|
||||
|
||||
const logout = () => {
|
||||
api.logout()
|
||||
AsyncStorage.clear()
|
||||
}
|
||||
useEffect(() => {
|
||||
navigation.setOptions({
|
||||
headerLeft: () => {
|
||||
return <TopNavigationAction icon={CloseOutlineIcon} onPress={settings} />
|
||||
},
|
||||
})
|
||||
}, [navigation, settings])
|
||||
|
||||
// We need to skip safe area view here, due to the reason that it's adding a white border
|
||||
// when this view is actually lightgrey. Taking the padding top value from the use inset hook.
|
||||
return (
|
||||
<View
|
||||
style={[
|
||||
{
|
||||
...styles.topContainer,
|
||||
paddingTop: insets.top,
|
||||
},
|
||||
{ backgroundColor: theme['background-basic-color-1'] },
|
||||
]}
|
||||
>
|
||||
<>
|
||||
{status === 'loaded' ? (
|
||||
<>
|
||||
<TopNavigation
|
||||
title={() => (
|
||||
<Text
|
||||
maxFontSizeMultiplier={2.5}
|
||||
style={styles.topNavigationTitle}
|
||||
<>
|
||||
{status === 'loaded' ? (
|
||||
<List
|
||||
contentContainerStyle={styles.childListContainer}
|
||||
data={childList}
|
||||
style={styles.childList}
|
||||
ListEmptyComponent={
|
||||
<View style={styles.emptyState}>
|
||||
<Text category="h2">{translate('children.noKids_title')}</Text>
|
||||
<Text style={styles.emptyStateDescription}>
|
||||
{translate('children.noKids_description')}
|
||||
</Text>
|
||||
<Image
|
||||
accessibilityIgnoresInvertColors={false}
|
||||
source={require('../assets/children.png')}
|
||||
style={styles.emptyStateImage as ImageStyle}
|
||||
/>
|
||||
</View>
|
||||
}
|
||||
renderItem={({ item: child, index }: ListRenderItemInfo<Child>) => (
|
||||
<ChildListItem
|
||||
child={child}
|
||||
color={colors[index % colors.length]}
|
||||
key={child.id}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
) : (
|
||||
<View style={styles.loading}>
|
||||
<Image
|
||||
accessibilityIgnoresInvertColors={false}
|
||||
source={require('../assets/girls.png')}
|
||||
style={styles.loadingImage as ImageStyle}
|
||||
/>
|
||||
{status === 'error' ? (
|
||||
<View style={styles.errorMessage}>
|
||||
<Text category="h5">
|
||||
{translate('children.loadingErrorHeading')}
|
||||
</Text>
|
||||
<Text style={{ fontSize: Sizing.t4 }}>
|
||||
{translate('children.loadingErrorInformationText')}
|
||||
</Text>
|
||||
<View style={styles.errorButtons}>
|
||||
<Button status="success" onPress={() => reloadChildren()}>
|
||||
{translate('children.tryAgain')}
|
||||
</Button>
|
||||
<Button
|
||||
status="basic"
|
||||
onPress={() =>
|
||||
Linking.openURL('https://skolplattformen.org/status')
|
||||
}
|
||||
>
|
||||
{translate('children.title')}
|
||||
</Text>
|
||||
)}
|
||||
alignment="center"
|
||||
accessoryRight={() => (
|
||||
<TopNavigationAction icon={SettingsIcon} onPress={settings} />
|
||||
)}
|
||||
/>
|
||||
<Divider />
|
||||
<List
|
||||
contentContainerStyle={styles.childListContainer}
|
||||
data={childList}
|
||||
style={styles.childList}
|
||||
ListEmptyComponent={
|
||||
<View style={styles.emptyState}>
|
||||
<Text category="h2">
|
||||
{translate('children.noKids_title')}
|
||||
</Text>
|
||||
<Text style={styles.emptyStateDescription}>
|
||||
{translate('children.noKids_description')}
|
||||
</Text>
|
||||
<Image
|
||||
accessibilityIgnoresInvertColors={false}
|
||||
source={require('../assets/children.png')}
|
||||
style={styles.emptyStateImage}
|
||||
/>
|
||||
</View>
|
||||
}
|
||||
renderItem={({
|
||||
item: child,
|
||||
index,
|
||||
}: ListRenderItemInfo<Child>) => (
|
||||
<ChildListItem
|
||||
child={child}
|
||||
color={colors[index % colors.length]}
|
||||
key={child.id}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<Layout style={styles.loading}>
|
||||
<Image
|
||||
accessibilityIgnoresInvertColors={false}
|
||||
source={require('../assets/girls.png')}
|
||||
style={styles.loadingImage}
|
||||
/>
|
||||
{status === 'error' ? (
|
||||
<View style={styles.errorMessage}>
|
||||
<Text category="h5">
|
||||
{translate('children.loadingErrorHeading')}
|
||||
</Text>
|
||||
<Text style={{ fontSize: Sizing.t5 }}>
|
||||
{translate('children.loadingErrorInformationText')}
|
||||
</Text>
|
||||
<View style={styles.errorButtons}>
|
||||
<Button status="success" onPress={() => reloadChildren()}>
|
||||
{translate('children.tryAgain')}
|
||||
</Button>
|
||||
<Button
|
||||
status="basic"
|
||||
onPress={() =>
|
||||
Linking.openURL('https://skolplattformen.org/status')
|
||||
}
|
||||
>
|
||||
{translate('children.viewStatus')}
|
||||
</Button>
|
||||
<Button onPress={() => logout()}>
|
||||
{translate('general.logout')}
|
||||
</Button>
|
||||
</View>
|
||||
{translate('children.viewStatus')}
|
||||
</Button>
|
||||
<Button onPress={() => logout()}>
|
||||
{translate('general.logout')}
|
||||
</Button>
|
||||
</View>
|
||||
) : (
|
||||
<View style={styles.loadingMessage}>
|
||||
<Spinner size="large" status="warning" />
|
||||
<Text category="h1" style={styles.loadingText}>
|
||||
{translate('general.loading')}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
</Layout>
|
||||
)}
|
||||
</>
|
||||
</View>
|
||||
</View>
|
||||
) : (
|
||||
<View style={styles.loadingMessage}>
|
||||
<Spinner size="large" status="primary" />
|
||||
<Text category="h1" style={styles.loadingText}>
|
||||
{translate('general.loading')}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
const themedStyles = StyleService.create({
|
||||
topContainer: {
|
||||
...LayoutStyle.flex.full,
|
||||
paddingBottom: 0,
|
||||
|
@ -216,7 +200,8 @@ const styles = StyleSheet.create({
|
|||
...LayoutStyle.flex.full,
|
||||
},
|
||||
childListContainer: {
|
||||
padding: Sizing.t5,
|
||||
paddingVertical: Sizing.t4,
|
||||
paddingHorizontal: Sizing.t3,
|
||||
},
|
||||
emptyState: {
|
||||
...LayoutStyle.center,
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
import React from 'react'
|
||||
import { useTimetable } from '@skolplattformen/api-hooks'
|
||||
import { Child } from '@skolplattformen/embedded-api'
|
||||
import { StyleService, Text, useStyleSheet } from '@ui-kitten/components'
|
||||
import moment, { Moment } from 'moment'
|
||||
import { View } from 'react-native'
|
||||
import { LanguageService } from '../services/languageService'
|
||||
import { translate } from '../utils/translation'
|
||||
|
||||
interface DaySummaryProps {
|
||||
child: Child
|
||||
date: Moment
|
||||
}
|
||||
|
||||
export const DaySummary = ({ child, date }: DaySummaryProps) => {
|
||||
const styles = useStyleSheet(themedStyles)
|
||||
const [year, week] = [moment().isoWeekYear(), moment().isoWeek()]
|
||||
const { data: weekLessons } = useTimetable(
|
||||
child,
|
||||
week,
|
||||
year,
|
||||
LanguageService.getLanguageCode()
|
||||
)
|
||||
|
||||
const lessons = weekLessons
|
||||
.filter((lesson) => lesson.dayOfWeek === date.isoWeekday())
|
||||
.sort((a, b) => a.dateStart.localeCompare(b.dateStart))
|
||||
|
||||
const gymBag = lessons.some((lesson) => lesson.code === 'IDH')
|
||||
|
||||
if (lessons.length <= 0) {
|
||||
return null
|
||||
}
|
||||
return (
|
||||
<View style={styles.summary}>
|
||||
<Text category="h5">
|
||||
{lessons[0].timeStart.slice(0, 5)}-
|
||||
{lessons[lessons.length - 1].timeEnd.slice(0, 5)}
|
||||
{gymBag
|
||||
? ` (🤼♀️ ${translate('schedule.gymBag', {
|
||||
defaultValue: 'Gympapåse',
|
||||
})})`
|
||||
: ''}
|
||||
</Text>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
const themedStyles = StyleService.create({
|
||||
summary: {
|
||||
flexDirection: 'row',
|
||||
},
|
||||
})
|
|
@ -1,7 +1,9 @@
|
|||
import { Icon } from '@ui-kitten/components'
|
||||
import { Icon, IconProps } from '@ui-kitten/components'
|
||||
import React from 'react'
|
||||
|
||||
const uiIcon = (name: string) => (props: any) => <Icon {...props} name={name} />
|
||||
const uiIcon = (name: string) => (props: IconProps) => (
|
||||
<Icon {...props} name={name} />
|
||||
)
|
||||
|
||||
export const AlertIcon = uiIcon('alert-circle-outline')
|
||||
export const BackIcon = uiIcon('arrow-back')
|
||||
|
@ -26,3 +28,4 @@ export const SearchIcon = uiIcon('search-outline')
|
|||
export const BookOpenIcon = uiIcon('book-open-outline')
|
||||
export const GlobeIcon = uiIcon('globe-outline')
|
||||
export const ExternalLinkIcon = uiIcon('external-link-outline')
|
||||
export const ClipboardIcon = uiIcon('clipboard-outline')
|
||||
|
|
|
@ -1,16 +1,22 @@
|
|||
import { StyleService, useStyleSheet } from '@ui-kitten/components'
|
||||
import React from 'react'
|
||||
import { ActivityIndicator, View, StyleSheet } from 'react-native'
|
||||
import { ActivityIndicator, View } from 'react-native'
|
||||
|
||||
export const LoadingComponent = () => (
|
||||
<View style={[styles.container, styles.horizontal]}>
|
||||
<ActivityIndicator size="large" />
|
||||
</View>
|
||||
)
|
||||
export const LoadingComponent = () => {
|
||||
const styles = useStyleSheet(themedStyles)
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
return (
|
||||
<View style={[styles.container, styles.horizontal]}>
|
||||
<ActivityIndicator size="large" />
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
const themedStyles = StyleService.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
backgroundColor: 'background-basic-color-2',
|
||||
},
|
||||
horizontal: {
|
||||
flexDirection: 'row',
|
||||
|
|
|
@ -23,16 +23,23 @@ import {
|
|||
} from 'react-native'
|
||||
import { useAsyncStorage } from 'use-async-storage'
|
||||
import { schema } from '../app.json'
|
||||
import { Layout, Sizing } from '../styles'
|
||||
import { Layout } from '../styles'
|
||||
import { translate } from '../utils/translation'
|
||||
import {
|
||||
CheckIcon,
|
||||
CloseOutlineIcon,
|
||||
PersonIcon,
|
||||
SecureIcon,
|
||||
SelectIcon,
|
||||
} from './icon.component'
|
||||
|
||||
const BankId = () => (
|
||||
<Image
|
||||
style={themedStyles.icon}
|
||||
source={require('../assets/bankid_low_rgb.png')}
|
||||
accessibilityIgnoresInvertColors
|
||||
/>
|
||||
)
|
||||
|
||||
export const Login = () => {
|
||||
const { api } = useApi()
|
||||
const [cancelLoginRequest, setCancelLoginRequest] = useState<
|
||||
|
@ -54,7 +61,9 @@ export const Login = () => {
|
|||
translate('auth.bankid.OpenOnThisDevice'),
|
||||
translate('auth.bankid.OpenOnAnotherDevice'),
|
||||
translate('auth.loginAsTestUser'),
|
||||
translate('general.cancel'),
|
||||
]
|
||||
|
||||
useEffect(() => {
|
||||
if (loginMethodIndex !== parseInt(cachedLoginMethodIndex, 10)) {
|
||||
setCachedLoginMethodIndex(loginMethodIndex.toString())
|
||||
|
@ -144,15 +153,6 @@ export const Login = () => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<Image
|
||||
source={require('../assets/boys.png')}
|
||||
// @ts-expect-error Don't know why this occurs
|
||||
style={styles.image}
|
||||
accessibilityHint={translate('login.a11y_image_two_boys', {
|
||||
defaultValue: 'Bild på två personer som kollar i mobilen',
|
||||
})}
|
||||
accessibilityIgnoresInvertColors={false}
|
||||
/>
|
||||
<View style={styles.loginForm}>
|
||||
{loginMethodIndex === 1 && (
|
||||
<Input
|
||||
|
@ -183,7 +183,7 @@ export const Login = () => {
|
|||
placeholder={translate('auth.placeholder_SocialSecurityNumber')}
|
||||
/>
|
||||
)}
|
||||
<ButtonGroup style={styles.loginButtonGroup}>
|
||||
<ButtonGroup style={styles.loginButtonGroup} status="primary">
|
||||
<Button
|
||||
accessible={true}
|
||||
onPress={() => startLogin(socialSecurityNumber)}
|
||||
|
@ -191,7 +191,7 @@ export const Login = () => {
|
|||
appearance="ghost"
|
||||
disabled={loginMethodIndex === 1 && !valid}
|
||||
status="primary"
|
||||
accessoryLeft={SecureIcon}
|
||||
accessoryLeft={BankId}
|
||||
size="medium"
|
||||
>
|
||||
{loginMethods[loginMethodIndex]}
|
||||
|
@ -278,17 +278,11 @@ export const Login = () => {
|
|||
}
|
||||
|
||||
const themedStyles = StyleService.create({
|
||||
image: {
|
||||
...Sizing.aspectRatio(0.9, Sizing.Ratio['4:3']),
|
||||
marginVertical: Sizing.t4,
|
||||
},
|
||||
backdrop: {
|
||||
backgroundColor: 'color-basic-transparent-600',
|
||||
},
|
||||
loginForm: {
|
||||
...Layout.mainAxis.flexStart,
|
||||
...Layout.crossAxis.flexEnd,
|
||||
paddingHorizontal: Sizing.t4,
|
||||
},
|
||||
pnrInput: { minHeight: 70 },
|
||||
loginButtonGroup: {
|
||||
|
@ -301,4 +295,8 @@ const themedStyles = StyleService.create({
|
|||
},
|
||||
bankIdLoading: { margin: 10 },
|
||||
cancelButtonStyle: { marginTop: 15 },
|
||||
icon: {
|
||||
width: 20,
|
||||
height: 20,
|
||||
},
|
||||
})
|
||||
|
|
|
@ -1,15 +1,22 @@
|
|||
import { useMenu } from '@skolplattformen/api-hooks'
|
||||
import { MenuItem } from '@skolplattformen/embedded-api'
|
||||
import { List, Text } from '@ui-kitten/components'
|
||||
import {
|
||||
Divider,
|
||||
List,
|
||||
StyleService,
|
||||
Text,
|
||||
useStyleSheet,
|
||||
} from '@ui-kitten/components'
|
||||
import 'moment/locale/sv'
|
||||
import React from 'react'
|
||||
import { Image, ListRenderItemInfo, StyleSheet, View } from 'react-native'
|
||||
import { Sizing, Layout as LayoutStyle, Typography } from '../styles'
|
||||
import { Image, ImageStyle, ListRenderItemInfo, View } from 'react-native'
|
||||
import { Layout as LayoutStyle, Sizing, Typography } from '../styles'
|
||||
import { translate } from '../utils/translation'
|
||||
import { useChild } from './childContext.component'
|
||||
import { MenuListItem } from './menuListItem.component'
|
||||
|
||||
export const Menu = () => {
|
||||
const styles = useStyleSheet(themedStyles)
|
||||
const child = useChild()
|
||||
const { data } = useMenu(child)
|
||||
|
||||
|
@ -17,6 +24,7 @@ export const Menu = () => {
|
|||
<List
|
||||
contentContainerStyle={styles.contentContainer}
|
||||
data={data}
|
||||
ItemSeparatorComponent={Divider}
|
||||
ListEmptyComponent={
|
||||
<View style={styles.emptyState}>
|
||||
<Text category="h4">{translate('menu.emptyHeadline')}</Text>
|
||||
|
@ -26,7 +34,7 @@ export const Menu = () => {
|
|||
<Image
|
||||
accessibilityIgnoresInvertColors={false}
|
||||
source={require('../assets/children.png')}
|
||||
style={styles.emptyStateImage}
|
||||
style={styles.emptyStateImage as ImageStyle}
|
||||
/>
|
||||
</View>
|
||||
}
|
||||
|
@ -38,23 +46,26 @@ export const Menu = () => {
|
|||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
const themedStyles = StyleService.create({
|
||||
container: {
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
padding: Sizing.t3,
|
||||
},
|
||||
contentContainer: {
|
||||
padding: Sizing.t3,
|
||||
paddingHorizontal: Sizing.t5,
|
||||
paddingVertical: Sizing.t2,
|
||||
backgroundColor: 'background-basic-color-1',
|
||||
borderRadius: 25,
|
||||
},
|
||||
emptyState: {
|
||||
...LayoutStyle.center,
|
||||
...LayoutStyle.flex.full,
|
||||
paddingHorizontal: Sizing.t5,
|
||||
paddingTop: 25,
|
||||
},
|
||||
emptyStateDescription: {
|
||||
...Typography.align.center,
|
||||
lineHeight: 21,
|
||||
paddingHorizontal: Sizing.t3,
|
||||
marginTop: Sizing.t3,
|
||||
},
|
||||
emptyStateImage: {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Text, Card, StyleService, useStyleSheet } from '@ui-kitten/components'
|
||||
import { MenuItem } from '@skolplattformen/embedded-api'
|
||||
import { StyleService, Text, useStyleSheet } from '@ui-kitten/components'
|
||||
import React from 'react'
|
||||
import { View } from 'react-native'
|
||||
import { MenuItem } from '@skolplattformen/embedded-api'
|
||||
import { Sizing, Typography } from '../styles'
|
||||
|
||||
interface MenuListItemProps {
|
||||
|
@ -12,16 +12,8 @@ export const MenuListItem = ({ item }: MenuListItemProps) => {
|
|||
const styles = useStyleSheet(themedStyles)
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Card
|
||||
header={(props) => (
|
||||
<View {...props}>
|
||||
<Text style={styles.title}>{item.title}</Text>
|
||||
</View>
|
||||
)}
|
||||
style={styles.contentContainer}
|
||||
>
|
||||
<Text category="p1">{item.description}</Text>
|
||||
</Card>
|
||||
<Text style={styles.title}>{item.title}</Text>
|
||||
<Text category="p1">{item.description}</Text>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
@ -29,10 +21,7 @@ export const MenuListItem = ({ item }: MenuListItemProps) => {
|
|||
const themedStyles = StyleService.create({
|
||||
container: {
|
||||
width: '100%',
|
||||
},
|
||||
contentContainer: {
|
||||
marginBottom: Sizing.t2,
|
||||
justifyContent: 'flex-start',
|
||||
paddingVertical: Sizing.t3,
|
||||
},
|
||||
topContainer: {
|
||||
margin: Sizing.t1,
|
||||
|
@ -41,6 +30,6 @@ const themedStyles = StyleService.create({
|
|||
},
|
||||
title: {
|
||||
...Typography.header,
|
||||
color: 'color-basic-800',
|
||||
marginBottom: Sizing.t1,
|
||||
},
|
||||
})
|
||||
|
|
|
@ -88,7 +88,7 @@ export const ModalWebView = ({
|
|||
const themedStyles = StyleService.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: 'background-basic-color-1',
|
||||
backgroundColor: 'background-basic-color-2',
|
||||
},
|
||||
headerWrapper: {
|
||||
marginTop: Sizing.t1,
|
||||
|
@ -96,7 +96,7 @@ const themedStyles = StyleService.create({
|
|||
borderRadius: 2,
|
||||
borderColor: 'basic-color-200',
|
||||
borderBottomWidth: 1,
|
||||
backgroundColor: 'background-basic-color-1',
|
||||
backgroundColor: 'background-basic-color-2',
|
||||
},
|
||||
backdrop: {
|
||||
backgroundColor: 'color-basic-transparent-600',
|
||||
|
@ -111,7 +111,7 @@ const themedStyles = StyleService.create({
|
|||
...Layout.mainAxis.center,
|
||||
paddingHorizontal: Sizing.t3,
|
||||
paddingVertical: Sizing.t1,
|
||||
backgroundColor: 'background-basic-color-1',
|
||||
backgroundColor: 'background-basic-color-2',
|
||||
},
|
||||
shareIcon: {
|
||||
width: 24,
|
||||
|
|
|
@ -1,20 +1,25 @@
|
|||
import { useApi } from '@skolplattformen/api-hooks'
|
||||
import { NavigationContainer } from '@react-navigation/native'
|
||||
import { createStackNavigator } from '@react-navigation/stack'
|
||||
import React, { useEffect } from 'react'
|
||||
import { StatusBar } from 'react-native'
|
||||
import { schema } from '../app.json'
|
||||
import Absence from './absence.component'
|
||||
import { Child } from './child.component'
|
||||
import { Children } from './children.component'
|
||||
import { Auth } from './auth.component'
|
||||
import { SetLanguage } from './setLanguage.component'
|
||||
import { NewsItem } from './newsItem.component'
|
||||
import { useApi } from '@skolplattformen/api-hooks'
|
||||
import {
|
||||
Child as ChildType,
|
||||
NewsItem as NewsItemType,
|
||||
} from '@skolplattformen/embedded-api'
|
||||
import { useTheme } from '@ui-kitten/components'
|
||||
import React, { useEffect } from 'react'
|
||||
import { StatusBar, useColorScheme } from 'react-native'
|
||||
import { createNativeStackNavigator } from 'react-native-screens/native-stack'
|
||||
import { schema } from '../app.json'
|
||||
import {
|
||||
darkNavigationTheme,
|
||||
lightNavigationTheme,
|
||||
} from '../design/navigationThemes'
|
||||
import { useAppState } from '../hooks/useAppState'
|
||||
import Absence, { absenceRouteOptions } from './absence.component'
|
||||
import { Auth, authRouteOptions } from './auth.component'
|
||||
import { Child, childRouteOptions } from './child.component'
|
||||
import { childenRouteOptions, Children } from './children.component'
|
||||
import { NewsItem, newsItemRouteOptions } from './newsItem.component'
|
||||
import { SetLanguage, setLanguageRouteOptions } from './setLanguage.component'
|
||||
|
||||
export type RootStackParamList = {
|
||||
Login: undefined
|
||||
|
@ -29,7 +34,7 @@ export type RootStackParamList = {
|
|||
SetLanguage: undefined
|
||||
}
|
||||
|
||||
const { Navigator, Screen } = createStackNavigator()
|
||||
const { Navigator, Screen } = createNativeStackNavigator<RootStackParamList>()
|
||||
|
||||
const linking = {
|
||||
prefixes: [schema],
|
||||
|
@ -43,6 +48,9 @@ const linking = {
|
|||
export const AppNavigator = () => {
|
||||
const { isLoggedIn, api } = useApi()
|
||||
|
||||
const colorScheme = useColorScheme()
|
||||
const colors = useTheme()
|
||||
|
||||
const currentAppState = useAppState()
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -59,20 +67,56 @@ export const AppNavigator = () => {
|
|||
}, [currentAppState, isLoggedIn, api])
|
||||
|
||||
return (
|
||||
<NavigationContainer linking={linking}>
|
||||
<NavigationContainer
|
||||
linking={linking}
|
||||
theme={
|
||||
colorScheme === 'dark' ? darkNavigationTheme : lightNavigationTheme
|
||||
}
|
||||
>
|
||||
<StatusBar />
|
||||
<Navigator headerMode="none">
|
||||
<Navigator
|
||||
screenOptions={() => ({
|
||||
headerLargeTitle: true,
|
||||
headerLargeTitleHideShadow: true,
|
||||
headerStyle: {
|
||||
backgroundColor: colors['background-basic-color-2'],
|
||||
},
|
||||
headerLargeTitleStyle: {
|
||||
fontFamily: 'Poppins-ExtraBold',
|
||||
},
|
||||
})}
|
||||
>
|
||||
{isLoggedIn ? (
|
||||
<>
|
||||
<Screen name="Children" component={Children} />
|
||||
<Screen name="Child" component={Child} />
|
||||
<Screen name="NewsItem" component={NewsItem} />
|
||||
<Screen name="Absence" component={Absence} />
|
||||
<Screen
|
||||
name="Children"
|
||||
component={Children}
|
||||
options={childenRouteOptions}
|
||||
/>
|
||||
<Screen
|
||||
name="Child"
|
||||
component={Child}
|
||||
options={childRouteOptions}
|
||||
/>
|
||||
<Screen
|
||||
name="NewsItem"
|
||||
component={NewsItem}
|
||||
options={newsItemRouteOptions}
|
||||
/>
|
||||
<Screen
|
||||
name="Absence"
|
||||
component={Absence}
|
||||
options={absenceRouteOptions}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Screen name="Login" component={Auth} />
|
||||
<Screen name="SetLanguage" component={SetLanguage} />
|
||||
<Screen name="Login" component={Auth} options={authRouteOptions} />
|
||||
<Screen
|
||||
name="SetLanguage"
|
||||
component={SetLanguage}
|
||||
options={setLanguageRouteOptions}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Navigator>
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
import { Text } from '@ui-kitten/components'
|
||||
import React from 'react'
|
||||
import { StyleSheet, View } from 'react-native'
|
||||
import { Layout } from '../styles'
|
||||
import { fontSize } from '../styles/typography'
|
||||
|
||||
interface NavigationTitleProps {
|
||||
title?: string
|
||||
subtitle?: string
|
||||
}
|
||||
/**
|
||||
* Navigation Title with a smaller subtitle.
|
||||
*/
|
||||
export const NavigationTitle = ({ title, subtitle }: NavigationTitleProps) => {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.title}>{title}</Text>
|
||||
<Text style={styles.subtitle}>{subtitle}</Text>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
...Layout.center,
|
||||
},
|
||||
title: {
|
||||
...fontSize.base,
|
||||
fontWeight: '500',
|
||||
},
|
||||
subtitle: { ...fontSize.xs },
|
||||
})
|
|
@ -1,26 +1,18 @@
|
|||
import { RouteProp } from '@react-navigation/native'
|
||||
import { StackNavigationProp } from '@react-navigation/stack'
|
||||
import { useNewsDetails } from '@skolplattformen/api-hooks'
|
||||
import {
|
||||
Divider,
|
||||
Text,
|
||||
TopNavigation,
|
||||
TopNavigationAction,
|
||||
StyleService,
|
||||
useStyleSheet,
|
||||
} from '@ui-kitten/components'
|
||||
import { StyleService, Text, useStyleSheet } from '@ui-kitten/components'
|
||||
import moment from 'moment'
|
||||
import 'moment/locale/sv'
|
||||
import React from 'react'
|
||||
import { ScrollView, View } from 'react-native'
|
||||
import { Colors, Layout, Sizing, Typography } from '../styles'
|
||||
import { NativeStackNavigationOptions } from 'react-native-screens/native-stack'
|
||||
import { defaultStackStyling } from '../design/navigationThemes'
|
||||
import { Layout, Sizing, Typography } from '../styles'
|
||||
import { translate } from '../utils/translation'
|
||||
import { BackIcon } from './icon.component'
|
||||
import { Image } from './image.component'
|
||||
import { Markdown } from './markdown.component'
|
||||
import { RootStackParamList } from './navigation.component'
|
||||
import { SafeAreaViewContainer } from '../ui/safeAreaViewContainer.component'
|
||||
import { SafeAreaView } from '../ui/safeAreaView.component'
|
||||
|
||||
interface NewsItemProps {
|
||||
navigation: StackNavigationProp<RootStackParamList, 'NewsItem'>
|
||||
|
@ -32,111 +24,90 @@ const displayDate = (date: string | undefined) => moment(date).format('lll')
|
|||
const dateIsValid = (date: string | undefined) =>
|
||||
moment(date, moment.ISO_8601).isValid()
|
||||
|
||||
export const NewsItem = ({ navigation, route }: NewsItemProps) => {
|
||||
export const newsItemRouteOptions = ({
|
||||
route,
|
||||
}: {
|
||||
route: RouteProp<RootStackParamList, 'NewsItem'>
|
||||
}): NativeStackNavigationOptions => {
|
||||
const newsItem = route.params.newsItem
|
||||
|
||||
return {
|
||||
...defaultStackStyling,
|
||||
title: newsItem.header,
|
||||
headerLargeTitle: true,
|
||||
headerStyle: {
|
||||
// TODO: This color must come from theme for dark mode
|
||||
backgroundColor: '#fff',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export const NewsItem = ({ route }: NewsItemProps) => {
|
||||
const { newsItem, child } = route.params
|
||||
const { data } = useNewsDetails(child, newsItem)
|
||||
const styles = useStyleSheet(themedStyles)
|
||||
const stylesMarkdown = useStyleSheet(themedStylesMarkdown)
|
||||
|
||||
const navigateBack = () => {
|
||||
navigation.goBack()
|
||||
}
|
||||
|
||||
const BackAction = () => (
|
||||
<TopNavigationAction
|
||||
testID="topNavBackToChild"
|
||||
accessibilityHint={translate('news.backToChild')}
|
||||
icon={BackIcon}
|
||||
onPress={navigateBack}
|
||||
/>
|
||||
)
|
||||
|
||||
return (
|
||||
<SafeAreaView>
|
||||
<SafeAreaViewContainer>
|
||||
<TopNavigation
|
||||
title={() => (
|
||||
<Text maxFontSizeMultiplier={1.5} style={styles.topNavigationTitle}>
|
||||
{translate('news.title')}
|
||||
</Text>
|
||||
)}
|
||||
alignment="center"
|
||||
accessoryLeft={BackAction}
|
||||
/>
|
||||
<Divider />
|
||||
|
||||
<ScrollView
|
||||
contentContainerStyle={styles.article}
|
||||
style={styles.scrollView}
|
||||
<ScrollView
|
||||
contentContainerStyle={styles.article}
|
||||
style={styles.scrollView}
|
||||
>
|
||||
{dateIsValid(newsItem.published) && (
|
||||
<Text
|
||||
maxFontSizeMultiplier={2}
|
||||
style={[styles.subtitle, styles.published]}
|
||||
>
|
||||
<Text maxFontSizeMultiplier={2} style={styles.title}>
|
||||
{newsItem.header}
|
||||
</Text>
|
||||
{dateIsValid(newsItem.published) && (
|
||||
<Text
|
||||
maxFontSizeMultiplier={2}
|
||||
style={[styles.subtitle, styles.published]}
|
||||
>
|
||||
<Text style={styles.strong}>{translate('news.published')}:</Text>{' '}
|
||||
{displayDate(newsItem.published)}
|
||||
</Text>
|
||||
)}
|
||||
{dateIsValid(newsItem.modified) && (
|
||||
<Text maxFontSizeMultiplier={2} style={styles.subtitle}>
|
||||
<Text style={styles.strong}>{translate('news.updated')}:</Text>{' '}
|
||||
{displayDate(newsItem.modified)}
|
||||
</Text>
|
||||
)}
|
||||
<View style={styles.body}>
|
||||
<Markdown style={stylesMarkdown}>{data.body}</Markdown>
|
||||
{newsItem.fullImageUrl && (
|
||||
<Image
|
||||
accessibilityIgnoresInvertColors={false}
|
||||
src={newsItem.fullImageUrl}
|
||||
// @ts-expect-error Fix later on
|
||||
style={styles.image}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
</ScrollView>
|
||||
</SafeAreaViewContainer>
|
||||
</SafeAreaView>
|
||||
<Text style={styles.strong}>{translate('news.published')}:</Text>{' '}
|
||||
{displayDate(newsItem.published)}
|
||||
</Text>
|
||||
)}
|
||||
{dateIsValid(newsItem.modified) && (
|
||||
<Text maxFontSizeMultiplier={2} style={styles.subtitle}>
|
||||
<Text style={styles.strong}>{translate('news.updated')}:</Text>{' '}
|
||||
{displayDate(newsItem.modified)}
|
||||
</Text>
|
||||
)}
|
||||
<View style={styles.body}>
|
||||
<Markdown style={stylesMarkdown}>{data.body}</Markdown>
|
||||
{newsItem.fullImageUrl && (
|
||||
<Image
|
||||
accessibilityIgnoresInvertColors={false}
|
||||
src={newsItem.fullImageUrl}
|
||||
// @ts-expect-error Fix later on
|
||||
style={styles.image}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
</ScrollView>
|
||||
)
|
||||
}
|
||||
|
||||
const themedStylesMarkdown = StyleService.create({
|
||||
body: {
|
||||
...Typography.fontSize.base,
|
||||
color: 'color-basic-800',
|
||||
color: 'text-basic-color',
|
||||
lineHeight: 26,
|
||||
},
|
||||
heading1: {
|
||||
...Typography.fontSize.xl,
|
||||
color: 'color-basic-600',
|
||||
color: 'text-basic-color',
|
||||
},
|
||||
heading2: {
|
||||
...Typography.fontSize.lg,
|
||||
color: 'color-basic-800',
|
||||
color: 'text-basic-color',
|
||||
},
|
||||
code_block: {
|
||||
color: 'color-basic-800',
|
||||
color: 'text-basic-color',
|
||||
backgroundColor: 'background-basic-color-1',
|
||||
borderColor: 'color-basic-400',
|
||||
},
|
||||
})
|
||||
|
||||
const themedStyles = StyleService.create({
|
||||
safeArea: {
|
||||
...Layout.flex.full,
|
||||
backgroundColor: Colors.neutral.white,
|
||||
},
|
||||
topContainer: {
|
||||
...Layout.flex.row,
|
||||
...Layout.crossAxis.spaceBetween,
|
||||
},
|
||||
article: {
|
||||
padding: Sizing.t5,
|
||||
backgroundColor: 'background-basic-color-2',
|
||||
backgroundColor: 'background-basic-color-1',
|
||||
},
|
||||
scrollView: {
|
||||
...Layout.flex.full,
|
||||
|
@ -145,6 +116,7 @@ const themedStyles = StyleService.create({
|
|||
width: '100%',
|
||||
minHeight: 300,
|
||||
marginTop: Sizing.t4,
|
||||
borderRadius: 15,
|
||||
},
|
||||
title: {
|
||||
...Typography.fontWeight.bold,
|
||||
|
@ -153,12 +125,12 @@ const themedStyles = StyleService.create({
|
|||
},
|
||||
subtitle: {
|
||||
...Typography.fontSize.xs,
|
||||
color: 'color-basic-600',
|
||||
color: 'text-hint-color',
|
||||
},
|
||||
strong: {
|
||||
...Typography.fontSize.xs,
|
||||
...Typography.fontWeight.bold,
|
||||
color: 'color-basic-600',
|
||||
color: 'text-hint-color',
|
||||
},
|
||||
published: {
|
||||
marginBottom: Sizing.t1,
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
import React, { useState, useMemo } from 'react'
|
||||
import { useNews } from '@skolplattformen/api-hooks'
|
||||
import { List, Input } from '@ui-kitten/components'
|
||||
import { StyleSheet, TouchableWithoutFeedback } from 'react-native'
|
||||
import { Input, List, StyleService, useStyleSheet } from '@ui-kitten/components'
|
||||
import React, { useMemo, useState } from 'react'
|
||||
import { TouchableOpacity, View } from 'react-native'
|
||||
import { Sizing } from '../styles'
|
||||
import { useChild } from './childContext.component'
|
||||
import { NewsListItem } from './newsListItem.component'
|
||||
import { translate } from '../utils/translation'
|
||||
import {
|
||||
useNewsListSearchResults,
|
||||
renderSearchResultPreview,
|
||||
useNewsListSearchResults,
|
||||
} from '../utils/search'
|
||||
import { SearchIcon, CloseOutlineIcon } from './icon.component'
|
||||
import { translate } from '../utils/translation'
|
||||
import { useChild } from './childContext.component'
|
||||
import { CloseOutlineIcon, SearchIcon } from './icon.component'
|
||||
import { NewsListItem } from './newsListItem.component'
|
||||
|
||||
export const NewsList = () => {
|
||||
const styles = useStyleSheet(themedStyles)
|
||||
const child = useChild()
|
||||
const { data } = useNews(child)
|
||||
|
||||
|
@ -33,14 +34,19 @@ export const NewsList = () => {
|
|||
accessoryLeft={SearchIcon}
|
||||
onChangeText={setSearchQuery}
|
||||
value={searchQuery}
|
||||
accessoryRight={(props) => (
|
||||
<TouchableWithoutFeedback onPress={() => setSearchQuery('')}>
|
||||
<CloseOutlineIcon {...props} />
|
||||
</TouchableWithoutFeedback>
|
||||
)}
|
||||
style={styles.search}
|
||||
accessoryRight={(props) =>
|
||||
searchQuery.length > 0 ? (
|
||||
<TouchableOpacity onPress={() => setSearchQuery('')}>
|
||||
<CloseOutlineIcon {...props} />
|
||||
</TouchableOpacity>
|
||||
) : (
|
||||
<View />
|
||||
)
|
||||
}
|
||||
/>
|
||||
),
|
||||
[searchQuery]
|
||||
[searchQuery, styles.search]
|
||||
)
|
||||
|
||||
if (searchQuery) {
|
||||
|
@ -72,12 +78,18 @@ export const NewsList = () => {
|
|||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
const themedStyles = StyleService.create({
|
||||
container: {
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
},
|
||||
contentContainer: {
|
||||
padding: Sizing.t3,
|
||||
paddingVertical: Sizing.t3,
|
||||
paddingHorizontal: Sizing.t3,
|
||||
},
|
||||
search: {
|
||||
backgroundColor: 'background-basic-color-1',
|
||||
borderRadius: 40,
|
||||
marginBottom: Sizing.t2,
|
||||
},
|
||||
})
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import { useNavigation } from '@react-navigation/native'
|
||||
import { StackNavigationProp } from '@react-navigation/stack'
|
||||
import { NewsItem } from '@skolplattformen/embedded-api'
|
||||
import React, { ReactNode } from 'react'
|
||||
import { StyleService, useStyleSheet } from '@ui-kitten/components'
|
||||
import moment from 'moment'
|
||||
import React, { ReactNode } from 'react'
|
||||
import { Dimensions, Text, View } from 'react-native'
|
||||
import { TouchableOpacity } from 'react-native-gesture-handler'
|
||||
import { Layout, Sizing, Typography } from '../styles'
|
||||
import { useChild } from './childContext.component'
|
||||
import { Image } from './image.component'
|
||||
import { RootStackParamList } from './navigation.component'
|
||||
import { StyleService, useStyleSheet } from '@ui-kitten/components'
|
||||
|
||||
interface NewsListItemProps {
|
||||
item: NewsItem
|
||||
|
@ -66,15 +66,11 @@ const themedStyles = StyleService.create({
|
|||
card: {
|
||||
...Layout.flex.full,
|
||||
...Layout.flex.row,
|
||||
|
||||
borderRadius: 2,
|
||||
|
||||
borderWidth: 1,
|
||||
padding: Sizing.t5,
|
||||
marginBottom: Sizing.t2,
|
||||
|
||||
borderRadius: 15,
|
||||
paddingVertical: Sizing.t4,
|
||||
paddingHorizontal: Sizing.t4,
|
||||
marginBottom: Sizing.t3,
|
||||
backgroundColor: 'background-basic-color-1',
|
||||
borderColor: 'border-basic-color-3',
|
||||
},
|
||||
text: {
|
||||
...Layout.flex.full,
|
||||
|
@ -86,7 +82,6 @@ const themedStyles = StyleService.create({
|
|||
},
|
||||
subtitle: {
|
||||
...Typography.fontSize.xs,
|
||||
|
||||
marginBottom: Sizing.t2,
|
||||
color: 'text-hint-color',
|
||||
},
|
||||
|
@ -95,9 +90,9 @@ const themedStyles = StyleService.create({
|
|||
color: 'text-basic-color',
|
||||
},
|
||||
image: {
|
||||
borderRadius: 3,
|
||||
width: 80,
|
||||
height: 80,
|
||||
marginRight: Sizing.t5,
|
||||
borderRadius: 50,
|
||||
width: 50,
|
||||
height: 50,
|
||||
marginRight: Sizing.t3,
|
||||
},
|
||||
})
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { Notification as NotificationType } from '@skolplattformen/embedded-api'
|
||||
import { Card, StyleService, Text, useStyleSheet } from '@ui-kitten/components'
|
||||
import { StyleService, Text, useStyleSheet } from '@ui-kitten/components'
|
||||
import moment from 'moment'
|
||||
import React from 'react'
|
||||
import { View } from 'react-native'
|
||||
import { TouchableOpacity, View } from 'react-native'
|
||||
import { Layout, Sizing, Typography } from '../styles'
|
||||
import { ModalWebView } from './modalWebView.component'
|
||||
import moment from 'moment'
|
||||
|
||||
interface NotificationProps {
|
||||
item: NotificationType
|
||||
|
@ -26,11 +26,9 @@ export const Notification = ({ item }: NotificationProps) => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<Card
|
||||
style={styles.card}
|
||||
onPress={open}
|
||||
header={(headerProps) => (
|
||||
<View {...headerProps}>
|
||||
<TouchableOpacity onPress={open}>
|
||||
<View style={styles.card}>
|
||||
<View>
|
||||
<Text style={styles.title}>{item.sender}</Text>
|
||||
<Text style={styles.subtitle}>
|
||||
{item.category ? item.category : ''}
|
||||
|
@ -38,10 +36,9 @@ export const Notification = ({ item }: NotificationProps) => {
|
|||
{displayDate ? displayDate : ''}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
>
|
||||
<Text>{item.message}</Text>
|
||||
</Card>
|
||||
<Text>{item.message}</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
{isOpen && (
|
||||
<ModalWebView
|
||||
url={item.url}
|
||||
|
@ -56,13 +53,11 @@ export const Notification = ({ item }: NotificationProps) => {
|
|||
const themedStyles = StyleService.create({
|
||||
card: {
|
||||
...Layout.flex.full,
|
||||
borderRadius: 2,
|
||||
|
||||
borderWidth: 1,
|
||||
marginBottom: Sizing.t2,
|
||||
|
||||
borderRadius: 15,
|
||||
paddingVertical: Sizing.t4,
|
||||
paddingHorizontal: Sizing.t4,
|
||||
marginBottom: Sizing.t3,
|
||||
backgroundColor: 'background-basic-color-1',
|
||||
borderColor: 'border-basic-color-3',
|
||||
},
|
||||
title: {
|
||||
...Typography.header,
|
||||
|
@ -71,5 +66,6 @@ const themedStyles = StyleService.create({
|
|||
subtitle: {
|
||||
...Typography.fontSize.xs,
|
||||
color: 'text-hint-color',
|
||||
marginBottom: Sizing.t2,
|
||||
},
|
||||
})
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
import { useNotifications } from '@skolplattformen/api-hooks'
|
||||
import { List } from '@ui-kitten/components'
|
||||
import { List, StyleService, useStyleSheet } from '@ui-kitten/components'
|
||||
import React from 'react'
|
||||
import { StyleSheet } from 'react-native'
|
||||
import { Sizing } from '../styles'
|
||||
import { useChild } from './childContext.component'
|
||||
import { Notification } from './notification.component'
|
||||
|
||||
export const NotificationsList = () => {
|
||||
const styles = useStyleSheet(themedStyles)
|
||||
const child = useChild()
|
||||
const { data } = useNotifications(child)
|
||||
|
||||
return (
|
||||
<List
|
||||
style={styles.container}
|
||||
|
@ -21,12 +22,13 @@ export const NotificationsList = () => {
|
|||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
const themedStyles = StyleService.create({
|
||||
container: {
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
},
|
||||
contentContainer: {
|
||||
padding: Sizing.t3,
|
||||
paddingHorizontal: Sizing.t3,
|
||||
paddingVertical: Sizing.t3,
|
||||
},
|
||||
})
|
||||
|
|
|
@ -1,26 +1,33 @@
|
|||
import { useNavigation } from '@react-navigation/native'
|
||||
import {
|
||||
Layout,
|
||||
Text,
|
||||
Button,
|
||||
ButtonGroup,
|
||||
TopNavigationAction,
|
||||
TopNavigation,
|
||||
StyleService,
|
||||
Text,
|
||||
useStyleSheet,
|
||||
useTheme,
|
||||
} from '@ui-kitten/components'
|
||||
import React, { useState } from 'react'
|
||||
import { StyleSheet, View } from 'react-native'
|
||||
import { View } from 'react-native'
|
||||
import { ScrollView, TouchableOpacity } from 'react-native-gesture-handler'
|
||||
import RNRestart from 'react-native-restart'
|
||||
import { SafeAreaView } from 'react-native-safe-area-context'
|
||||
import { NativeStackNavigationOptions } from 'react-native-screens/native-stack'
|
||||
import { useLanguage } from '../hooks/useLanguage'
|
||||
import { isRTL, LanguageService } from '../services/languageService'
|
||||
import { Layout as LayoutStyle, Sizing } from '../styles'
|
||||
import { translate, languages } from '../utils/translation'
|
||||
import { BackIcon } from './icon.component'
|
||||
import { SafeAreaViewContainer } from '../ui/safeAreaViewContainer.component'
|
||||
import RNRestart from 'react-native-restart'
|
||||
import { SafeAreaView } from '../ui/safeAreaView.component'
|
||||
import { fontSize } from '../styles/typography'
|
||||
import { languages, translate } from '../utils/translation'
|
||||
import { CheckIcon } from './icon.component'
|
||||
|
||||
export const setLanguageRouteOptions = (): NativeStackNavigationOptions => ({
|
||||
title: translate('language.changeLanguage'),
|
||||
})
|
||||
|
||||
export const SetLanguage = () => {
|
||||
const navigation = useNavigation()
|
||||
const styles = useStyleSheet(themedStyles)
|
||||
const colors = useTheme()
|
||||
|
||||
const currentLanguage = LanguageService.getLanguageCode()
|
||||
|
||||
|
@ -56,77 +63,66 @@ export const SetLanguage = () => {
|
|||
const activeLanguages = languages.filter((language) => language.active)
|
||||
|
||||
return (
|
||||
<SafeAreaView>
|
||||
<SafeAreaViewContainer>
|
||||
<TopNavigation
|
||||
accessoryLeft={() => (
|
||||
<TopNavigationAction icon={BackIcon} onPress={() => goBack()} />
|
||||
)}
|
||||
alignment="center"
|
||||
title={translate('language.changeLanguage')}
|
||||
/>
|
||||
|
||||
<SafeAreaView style={styles.container} edges={['bottom']}>
|
||||
<ScrollView>
|
||||
<View style={styles.content}>
|
||||
<ScrollView>
|
||||
<Layout style={styles.container}>
|
||||
<View style={styles.languageList}>
|
||||
{activeLanguages.map((language) => (
|
||||
<TouchableOpacity
|
||||
key={language.langCode}
|
||||
style={styles.languageButton}
|
||||
onPress={() => setSelectedLanguage(language.langCode)}
|
||||
>
|
||||
<Text style={styles.check}>
|
||||
{isSelected(language.langCode) ? '✓' : ''}
|
||||
</Text>
|
||||
<Text>{language.languageName}</Text>
|
||||
<Text style={styles.languageButtonSubtitle}>
|
||||
{language.languageLocalName}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</View>
|
||||
</Layout>
|
||||
</ScrollView>
|
||||
|
||||
<ButtonGroup style={styles.buttonGroup}>
|
||||
<Button
|
||||
onPress={() => saveLanguage()}
|
||||
appearance="ghost"
|
||||
status="primary"
|
||||
disabled={currentLanguage === selectedLanguage}
|
||||
style={styles.button}
|
||||
size="medium"
|
||||
>
|
||||
{translate('language.changeLanguageButton')}
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
<View style={styles.languageList}>
|
||||
{activeLanguages.map((language) => (
|
||||
<TouchableOpacity
|
||||
key={language.langCode}
|
||||
style={styles.languageButton}
|
||||
onPress={() => setSelectedLanguage(language.langCode)}
|
||||
>
|
||||
<View>
|
||||
<Text style={styles.languageButtonTitle}>
|
||||
{language.languageLocalName}
|
||||
</Text>
|
||||
<Text style={styles.languageButtonSubtitle}>
|
||||
{language.languageName}
|
||||
</Text>
|
||||
</View>
|
||||
{isSelected(language.langCode) ? (
|
||||
<CheckIcon
|
||||
height={24}
|
||||
width={24}
|
||||
fill={colors['color-success-600']}
|
||||
/>
|
||||
) : null}
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
</SafeAreaViewContainer>
|
||||
</ScrollView>
|
||||
<ButtonGroup style={styles.buttonGroup}>
|
||||
<Button
|
||||
onPress={() => saveLanguage()}
|
||||
appearance="ghost"
|
||||
status="primary"
|
||||
disabled={currentLanguage === selectedLanguage}
|
||||
style={styles.button}
|
||||
size="medium"
|
||||
>
|
||||
{translate('language.changeLanguageButton')}
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
</SafeAreaView>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
const themedStyles = StyleService.create({
|
||||
languageList: {
|
||||
flex: 1,
|
||||
alignSelf: 'stretch',
|
||||
flexDirection: 'column',
|
||||
marginTop: 40,
|
||||
marginTop: 8,
|
||||
},
|
||||
icon: {
|
||||
width: 30,
|
||||
height: 30,
|
||||
},
|
||||
check: {
|
||||
position: 'absolute',
|
||||
left: -20,
|
||||
color: 'green',
|
||||
},
|
||||
container: {
|
||||
...LayoutStyle.mainAxis.center,
|
||||
...LayoutStyle.crossAxis.flexEnd,
|
||||
padding: Sizing.t5,
|
||||
flex: 1,
|
||||
backgroundColor: 'background-basic-color-2',
|
||||
},
|
||||
content: {
|
||||
...LayoutStyle.center,
|
||||
|
@ -137,12 +133,20 @@ const styles = StyleSheet.create({
|
|||
buttonGroup: {
|
||||
minHeight: 45,
|
||||
marginTop: 20,
|
||||
marginHorizontal: Sizing.t5,
|
||||
},
|
||||
languageButton: {
|
||||
minHeight: 45,
|
||||
marginBottom: 10,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
},
|
||||
languageButtonTitle: {
|
||||
...fontSize.lg,
|
||||
},
|
||||
languageButtonSubtitle: {
|
||||
...fontSize.sm,
|
||||
opacity: 0.4,
|
||||
},
|
||||
button: { ...LayoutStyle.flex.full },
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
import { Text, useTheme } from '@ui-kitten/components'
|
||||
import React from 'react'
|
||||
import { StyleSheet, View } from 'react-native'
|
||||
import { fontSize } from '../styles/typography'
|
||||
import { initials } from '../utils/peopleHelpers'
|
||||
|
||||
export type StudentAvatarProps = {
|
||||
name?: string
|
||||
color: string
|
||||
}
|
||||
|
||||
export const StudentAvatar = ({ name, color }: StudentAvatarProps) => {
|
||||
const colors = useTheme()
|
||||
const bgColor = colors[`color-${color}-100`]
|
||||
const textColor = colors[`color-${color}-900`]
|
||||
|
||||
return (
|
||||
<View style={{ ...styles.container, backgroundColor: bgColor }}>
|
||||
<Text style={{ ...styles.text, color: textColor }}>{initials(name)}</Text>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
export const styles = StyleSheet.create({
|
||||
container: {
|
||||
height: 44,
|
||||
width: 44,
|
||||
borderRadius: 300,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
text: {
|
||||
...fontSize.lg,
|
||||
fontFamily: 'Poppins-Medium',
|
||||
fontWeight: '500',
|
||||
},
|
||||
})
|
|
@ -1,22 +1,22 @@
|
|||
import { useMenu, useTimetable } from '@skolplattformen/api-hooks'
|
||||
import { Child, MenuItem, TimetableEntry } from '@skolplattformen/embedded-api'
|
||||
import {
|
||||
List,
|
||||
ListItem,
|
||||
ViewPager,
|
||||
Text,
|
||||
TabBar,
|
||||
Tab,
|
||||
StyleService,
|
||||
Tab,
|
||||
TabBar,
|
||||
Text,
|
||||
useStyleSheet,
|
||||
ViewPager,
|
||||
} from '@ui-kitten/components'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import moment from 'moment'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { View } from 'react-native'
|
||||
import { useMenu, useTimetable } from '@skolplattformen/api-hooks'
|
||||
import { TimetableEntry, Child, MenuItem } from '@skolplattformen/embedded-api'
|
||||
import { LanguageService } from '../services/languageService'
|
||||
import { Sizing, Typography } from '../styles'
|
||||
import { translate } from '../utils/translation'
|
||||
import { TransitionView } from './transitionView.component'
|
||||
import { Typography, Sizing } from '../styles'
|
||||
|
||||
interface WeekProps {
|
||||
child: Child
|
||||
|
@ -174,7 +174,7 @@ export const Week = ({ child }: WeekProps) => {
|
|||
|
||||
const themedStyles = StyleService.create({
|
||||
view: {
|
||||
backgroundColor: 'background-basic-color-2',
|
||||
backgroundColor: 'background-basic-color-1',
|
||||
},
|
||||
part: {
|
||||
backgroundColor: 'transparent',
|
||||
|
@ -186,7 +186,7 @@ const themedStyles = StyleService.create({
|
|||
},
|
||||
item: {
|
||||
height: 45,
|
||||
backgroundColor: 'background-basic-color-1',
|
||||
backgroundColor: 'background-basic-color-2',
|
||||
paddingHorizontal: 0,
|
||||
borderRadius: 2,
|
||||
margin: 2,
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
{
|
||||
"color-primary-100": "#FDD3D4",
|
||||
"color-primary-200": "#FBA7B3",
|
||||
"color-primary-300": "#F47A97",
|
||||
"color-primary-400": "#E95789",
|
||||
"color-primary-500": "#DB2575",
|
||||
"color-primary-600": "#BC1B72",
|
||||
"color-primary-700": "#9D126B",
|
||||
"color-primary-800": "#7F0B60",
|
||||
"color-primary-900": "#690759",
|
||||
"color-primary-50": "#FFECF9",
|
||||
"color-primary-100": "#FEC9EF",
|
||||
"color-primary-200": "#FD82DA",
|
||||
"color-primary-300": "#FB3CC6",
|
||||
"color-primary-400": "#EC04AB",
|
||||
"color-primary-500": "#A60378",
|
||||
"color-primary-600": "#880262",
|
||||
"color-primary-700": "#6A024D",
|
||||
"color-primary-800": "#4C0137",
|
||||
"color-primary-900": "#2E0121",
|
||||
"color-primary-transparent-100": "rgba(219, 37, 117, 0.08)",
|
||||
"color-primary-transparent-200": "rgba(219, 37, 117, 0.16)",
|
||||
"color-primary-transparent-300": "rgba(219, 37, 117, 0.24)",
|
||||
|
@ -29,30 +30,21 @@
|
|||
"color-success-transparent-400": "rgba(100, 165, 24, 0.32)",
|
||||
"color-success-transparent-500": "rgba(100, 165, 24, 0.4)",
|
||||
"color-success-transparent-600": "rgba(100, 165, 24, 0.48)",
|
||||
"color-info-100": "#D1E5FE",
|
||||
"color-info-200": "#A5C9FD",
|
||||
"color-info-300": "#77AAFB",
|
||||
"color-info-400": "#558EF7",
|
||||
"color-info-500": "#1F62F2",
|
||||
"color-info-600": "#164BD0",
|
||||
"color-info-700": "#0F37AE",
|
||||
"color-info-800": "#09268C",
|
||||
"color-info-900": "#051A74",
|
||||
"color-info-transparent-100": "rgba(31, 98, 242, 0.08)",
|
||||
"color-info-transparent-200": "rgba(31, 98, 242, 0.16)",
|
||||
"color-info-transparent-300": "rgba(31, 98, 242, 0.24)",
|
||||
"color-info-transparent-400": "rgba(31, 98, 242, 0.32)",
|
||||
"color-info-transparent-500": "rgba(31, 98, 242, 0.4)",
|
||||
"color-info-transparent-600": "rgba(31, 98, 242, 0.48)",
|
||||
"color-warning-100": "#FCF1CA",
|
||||
"color-warning-200": "#F9E097",
|
||||
"color-warning-300": "#EFC662",
|
||||
"color-warning-400": "#E0A93B",
|
||||
"color-warning-500": "#CC8204",
|
||||
"color-warning-600": "#AF6902",
|
||||
"color-warning-700": "#925202",
|
||||
"color-warning-800": "#763D01",
|
||||
"color-warning-900": "#612F00",
|
||||
"color-info-100": "#CFE3FB",
|
||||
"color-info-200": "#A1C5F8",
|
||||
"color-info-300": "#6F9EEA",
|
||||
"color-info-400": "#4A7AD5",
|
||||
"color-info-500": "#184BBA",
|
||||
"color-info-600": "#11399F",
|
||||
"color-info-700": "#0C2A85",
|
||||
"color-info-800": "#071D6B",
|
||||
"color-info-900": "#041459",
|
||||
"color-info-transparent-100": "rgba(24, 75, 186, 0.08)",
|
||||
"color-info-transparent-200": "rgba(24, 75, 186, 0.16)",
|
||||
"color-info-transparent-300": "rgba(24, 75, 186, 0.24)",
|
||||
"color-info-transparent-400": "rgba(24, 75, 186, 0.32)",
|
||||
"color-info-transparent-500": "rgba(24, 75, 186, 0.4)",
|
||||
"color-info-transparent-600": "rgba(24, 75, 186, 0.48)",
|
||||
"color-warning-transparent-100": "rgba(204, 130, 4, 0.08)",
|
||||
"color-warning-transparent-200": "rgba(204, 130, 4, 0.16)",
|
||||
"color-warning-transparent-300": "rgba(204, 130, 4, 0.24)",
|
||||
|
@ -74,14 +66,12 @@
|
|||
"color-danger-transparent-400": "rgba(186, 50, 127, 0.32)",
|
||||
"color-danger-transparent-500": "rgba(186, 50, 127, 0.4)",
|
||||
"color-danger-transparent-600": "rgba(186, 50, 127, 0.48)",
|
||||
"background-basic-color-1": "#2E3137",
|
||||
"background-basic-color-2": "#202225",
|
||||
"background-basic-color-1": "#150A12",
|
||||
"background-basic-color-2": "#030200",
|
||||
"color-control-default": "#E5E7EB",
|
||||
/* text colors */
|
||||
"color-basic-800": "#DCDDDE",
|
||||
"color-basic-600": "#DCDDDE",
|
||||
"color-basic-500": "#8E9297",
|
||||
/* basic button colors */
|
||||
"color-basic-300": "#202020",
|
||||
"color-basic-400": "gray"
|
||||
"color-basic-default": "$color-primary-800",
|
||||
"color-basic-focus": "$color-primary-700",
|
||||
"color-basic-hover": "$color-primary-700",
|
||||
"color-basic-active": "$color-primary-700",
|
||||
"color-basic-text": "$color-primary-100"
|
||||
}
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
{
|
||||
"color-primary-100": "#FDD3D4",
|
||||
"color-primary-200": "#FBA7B3",
|
||||
"color-primary-300": "#F47A97",
|
||||
"color-primary-400": "#E95789",
|
||||
"color-primary-500": "#DB2575",
|
||||
"color-primary-600": "#BC1B72",
|
||||
"color-primary-700": "#9D126B",
|
||||
"color-primary-800": "#7F0B60",
|
||||
"color-primary-900": "#690759",
|
||||
"color-primary-50": "#FFECF9",
|
||||
"color-primary-100": "#FEC9EF",
|
||||
"color-primary-200": "#FD82DA",
|
||||
"color-primary-300": "#FB3CC6",
|
||||
"color-primary-400": "#EC04AB",
|
||||
"color-primary-500": "#A60378",
|
||||
"color-primary-600": "#880262",
|
||||
"color-primary-700": "#6A024D",
|
||||
"color-primary-800": "#4C0137",
|
||||
"color-primary-900": "#2E0121",
|
||||
"color-primary-transparent-100": "rgba(219, 37, 117, 0.08)",
|
||||
"color-primary-transparent-200": "rgba(219, 37, 117, 0.16)",
|
||||
"color-primary-transparent-300": "rgba(219, 37, 117, 0.24)",
|
||||
|
@ -29,21 +30,21 @@
|
|||
"color-success-transparent-400": "rgba(100, 165, 24, 0.32)",
|
||||
"color-success-transparent-500": "rgba(100, 165, 24, 0.4)",
|
||||
"color-success-transparent-600": "rgba(100, 165, 24, 0.48)",
|
||||
"color-info-100": "#D1E5FE",
|
||||
"color-info-200": "#A5C9FD",
|
||||
"color-info-300": "#77AAFB",
|
||||
"color-info-400": "#558EF7",
|
||||
"color-info-500": "#1F62F2",
|
||||
"color-info-600": "#164BD0",
|
||||
"color-info-700": "#0F37AE",
|
||||
"color-info-800": "#09268C",
|
||||
"color-info-900": "#051A74",
|
||||
"color-info-transparent-100": "rgba(31, 98, 242, 0.08)",
|
||||
"color-info-transparent-200": "rgba(31, 98, 242, 0.16)",
|
||||
"color-info-transparent-300": "rgba(31, 98, 242, 0.24)",
|
||||
"color-info-transparent-400": "rgba(31, 98, 242, 0.32)",
|
||||
"color-info-transparent-500": "rgba(31, 98, 242, 0.4)",
|
||||
"color-info-transparent-600": "rgba(31, 98, 242, 0.48)",
|
||||
"color-info-100": "#C6EEF8",
|
||||
"color-info-200": "#90D9F1",
|
||||
"color-info-300": "#55AED5",
|
||||
"color-info-400": "#2B7DAC",
|
||||
"color-info-500": "#004475",
|
||||
"color-info-600": "#003464",
|
||||
"color-info-700": "#002754",
|
||||
"color-info-800": "#001B43",
|
||||
"color-info-900": "#001338",
|
||||
"color-info-transparent-100": "rgba(0, 68, 117, 0.08)",
|
||||
"color-info-transparent-200": "rgba(0, 68, 117, 0.16)",
|
||||
"color-info-transparent-300": "rgba(0, 68, 117, 0.24)",
|
||||
"color-info-transparent-400": "rgba(0, 68, 117, 0.32)",
|
||||
"color-info-transparent-500": "rgba(0, 68, 117, 0.4)",
|
||||
"color-info-transparent-600": "rgba(0, 68, 117, 0.48)",
|
||||
"color-warning-100": "#FCF1CA",
|
||||
"color-warning-200": "#F9E097",
|
||||
"color-warning-300": "#EFC662",
|
||||
|
@ -74,8 +75,12 @@
|
|||
"color-danger-transparent-400": "rgba(186, 50, 127, 0.32)",
|
||||
"color-danger-transparent-500": "rgba(186, 50, 127, 0.4)",
|
||||
"color-danger-transparent-600": "rgba(186, 50, 127, 0.48)",
|
||||
"color-basic-800": "#1F2937",
|
||||
"color-basic-600": "#4B5563",
|
||||
"color-basic-500": "#6B7280",
|
||||
"color-basic-400": "#E4E9F2"
|
||||
}
|
||||
"background-basic-color-1": "#fff",
|
||||
"background-basic-color-2": "$color-basic-200",
|
||||
"text-hint-color": "#4B5466",
|
||||
"color-basic-default": "$color-primary-50",
|
||||
"color-basic-focus": "$color-primary-100",
|
||||
"color-basic-hover": "$color-primary-100",
|
||||
"color-basic-active": "$color-primary-100",
|
||||
"color-basic-text": "$color-primary-800"
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"strict": {
|
||||
"border-radius": 50
|
||||
"text-font-family": "Poppins",
|
||||
"border-radius": 10
|
||||
},
|
||||
"components": {
|
||||
"Button": {
|
||||
|
@ -10,13 +11,13 @@
|
|||
"mapping": {},
|
||||
"variantGroups": {
|
||||
"status": {
|
||||
"primary": {
|
||||
"backgroundColor": "blue"
|
||||
"basic": {
|
||||
"textColor": "$color-basic-text"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
import { DarkTheme, DefaultTheme, Theme } from '@react-navigation/native'
|
||||
import { NativeStackNavigationOptions } from 'react-native-screens/native-stack'
|
||||
import { darkTheme, lightTheme } from './themes'
|
||||
|
||||
export const darkNavigationTheme: Theme = {
|
||||
...DarkTheme,
|
||||
colors: {
|
||||
...DarkTheme.colors,
|
||||
background: darkTheme['background-basic-color-2'],
|
||||
border: darkTheme['background-basic-color-1'],
|
||||
card: darkTheme['background-basic-color-1'],
|
||||
primary: darkTheme['color-primary-400'],
|
||||
text: '#ddd',
|
||||
},
|
||||
}
|
||||
|
||||
export const lightNavigationTheme: Theme = {
|
||||
...DefaultTheme,
|
||||
colors: {
|
||||
...DefaultTheme.colors,
|
||||
background: lightTheme['background-basic-color-2'],
|
||||
border: lightTheme['background-basic-color-1'],
|
||||
card: lightTheme['background-basic-color-1'],
|
||||
primary: lightTheme['color-primary-500'],
|
||||
},
|
||||
}
|
||||
|
||||
export const defaultStackStyling: NativeStackNavigationOptions = {
|
||||
headerTitleStyle: {
|
||||
fontFamily: 'Poppins-Medium',
|
||||
},
|
||||
headerBackTitleStyle: {
|
||||
fontFamily: 'Poppins-Regular',
|
||||
},
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
import * as eva from '@eva-design/eva'
|
||||
import darkJsonTheme from './dark.json'
|
||||
import lightJsonTheme from './light.json'
|
||||
|
||||
export const darkTheme = {
|
||||
...eva.dark,
|
||||
...darkJsonTheme,
|
||||
}
|
||||
export const lightTheme = {
|
||||
...eva.light,
|
||||
...lightJsonTheme,
|
||||
}
|
|
@ -1,9 +1,10 @@
|
|||
/**
|
||||
* @format
|
||||
*/
|
||||
|
||||
import 'react-native-gesture-handler'
|
||||
import { AppRegistry } from 'react-native'
|
||||
import App from './App'
|
||||
import { name as appName } from './app.json'
|
||||
|
||||
|
||||
AppRegistry.registerComponent(appName, () => App)
|
||||
|
|
|
@ -351,7 +351,7 @@ PODS:
|
|||
- React
|
||||
- RNCAsyncStorage (1.15.2):
|
||||
- React-Core
|
||||
- RNCMaskedView (0.1.10):
|
||||
- RNCMaskedView (0.1.11):
|
||||
- React
|
||||
- RNDateTimePicker (3.4.3):
|
||||
- React-Core
|
||||
|
@ -359,8 +359,38 @@ PODS:
|
|||
- React-Core
|
||||
- RNLocalize (2.0.3):
|
||||
- React-Core
|
||||
- RNScreens (2.18.1):
|
||||
- RNReanimated (2.2.0):
|
||||
- DoubleConversion
|
||||
- FBLazyVector
|
||||
- FBReactNativeSpec
|
||||
- glog
|
||||
- RCT-Folly
|
||||
- RCTRequired
|
||||
- RCTTypeSafety
|
||||
- React
|
||||
- React-callinvoker
|
||||
- React-Core
|
||||
- React-Core/DevSupport
|
||||
- React-Core/RCTWebSocket
|
||||
- React-CoreModules
|
||||
- React-cxxreact
|
||||
- React-jsi
|
||||
- React-jsiexecutor
|
||||
- React-jsinspector
|
||||
- React-RCTActionSheet
|
||||
- React-RCTAnimation
|
||||
- React-RCTBlob
|
||||
- React-RCTImage
|
||||
- React-RCTLinking
|
||||
- React-RCTNetwork
|
||||
- React-RCTSettings
|
||||
- React-RCTText
|
||||
- React-RCTVibration
|
||||
- ReactCommon/turbomodule/core
|
||||
- Yoga
|
||||
- RNScreens (3.3.0):
|
||||
- React-Core
|
||||
- React-RCTImage
|
||||
- RNSVG (12.1.0):
|
||||
- React
|
||||
- Toast (4.0.0)
|
||||
|
@ -433,6 +463,7 @@ DEPENDENCIES:
|
|||
- "RNDateTimePicker (from `../node_modules/@react-native-community/datetimepicker`)"
|
||||
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
|
||||
- RNLocalize (from `../node_modules/react-native-localize`)
|
||||
- RNReanimated (from `../node_modules/react-native-reanimated`)
|
||||
- RNScreens (from `../node_modules/react-native-screens`)
|
||||
- RNSVG (from `../node_modules/react-native-svg`)
|
||||
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
|
||||
|
@ -535,6 +566,8 @@ EXTERNAL SOURCES:
|
|||
:path: "../node_modules/react-native-gesture-handler"
|
||||
RNLocalize:
|
||||
:path: "../node_modules/react-native-localize"
|
||||
RNReanimated:
|
||||
:path: "../node_modules/react-native-reanimated"
|
||||
RNScreens:
|
||||
:path: "../node_modules/react-native-screens"
|
||||
RNSVG:
|
||||
|
@ -547,7 +580,7 @@ SPEC CHECKSUMS:
|
|||
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
|
||||
DoubleConversion: cf9b38bf0b2d048436d9a82ad2abe1404f11e7de
|
||||
FBLazyVector: 7b423f9e248eae65987838148c36eec1dbfe0b53
|
||||
FBReactNativeSpec: 04fc66100bad544f2d734662e11d7d631249fa0b
|
||||
FBReactNativeSpec: 313b66e17294041415f72c26996e9670a9f07a59
|
||||
Flipper: d3da1aa199aad94455ae725e9f3aa43f3ec17021
|
||||
Flipper-DoubleConversion: 38631e41ef4f9b12861c67d17cb5518d06badc41
|
||||
Flipper-Folly: 755929a4f851b2fb2c347d533a23f191b008554c
|
||||
|
@ -591,11 +624,12 @@ SPEC CHECKSUMS:
|
|||
ReactCommon: bedc99ed4dae329c4fcf128d0c31b9115e5365ca
|
||||
RNCalendarEvents: 7e65eb4a94f53c1744d1e275f7fafcfaa619f7a3
|
||||
RNCAsyncStorage: 9b7605e899f9acb2fba33e87952c529731265453
|
||||
RNCMaskedView: 5a8ec07677aa885546a0d98da336457e2bea557f
|
||||
RNCMaskedView: 0e1bc4bfa8365eba5fbbb71e07fbdc0555249489
|
||||
RNDateTimePicker: d943800c936fb01c352fcfb70439550d2cb57092
|
||||
RNGestureHandler: a479ebd5ed4221a810967000735517df0d2db211
|
||||
RNLocalize: 99e59cad311ca1b6872b1764514009416ccba03d
|
||||
RNScreens: f7ad633b2e0190b77b6a7aab7f914fad6f198d8d
|
||||
RNReanimated: 9c13c86454bfd54dab7505c1a054470bfecd2563
|
||||
RNScreens: bf59f17fbf001f1025243eeed5f19419d3c11ef2
|
||||
RNSVG: ce9d996113475209013317e48b05c21ee988d42e
|
||||
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
|
||||
Yoga: a7de31c64fe738607e7a3803e3f591a4b1df7393
|
||||
|
|
|
@ -8,17 +8,35 @@
|
|||
|
||||
/* Begin PBXBuildFile section */
|
||||
00E356F31AD99517003FC87E /* appTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* appTests.m */; };
|
||||
04B5A89762F9430A902416B4 /* Poppins-MediumItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 3CBFE8DBE8994C1FAF939519 /* Poppins-MediumItalic.ttf */; };
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
230E5925A9044F679B2F7C39 /* Poppins-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 7AF5677EA52D44EE97668E7A /* Poppins-Medium.ttf */; };
|
||||
2D02E4BC1E0B4A80006451C7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
|
||||
2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||
2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
2DC4DBF14540481ABF14857A /* Poppins-ExtraBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9A9C27037F0F4AF2A4CBAE78 /* Poppins-ExtraBold.ttf */; };
|
||||
2DCD954D1E0B4F2C00145EB5 /* appTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* appTests.m */; };
|
||||
417D579C3DC24A9684D24EDD /* Poppins-BlackItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 00FDE4C2522044DAAD866D5F /* Poppins-BlackItalic.ttf */; };
|
||||
41DE97CF96674977BC052462 /* Poppins-SemiBoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = A9CB7679337840D3BD256A13 /* Poppins-SemiBoldItalic.ttf */; };
|
||||
4E01D1C8DD5749C8953D3BE5 /* Poppins-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 661AE05493ED4FE780C32EF6 /* Poppins-Bold.ttf */; };
|
||||
4F931CB3182F40F580F357FF /* Poppins-ThinItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = E251C7BB03F74441B4357419 /* Poppins-ThinItalic.ttf */; };
|
||||
50AAEBD19BD24B129801C393 /* Poppins-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 977D264ECA05485EA89A2F13 /* Poppins-Italic.ttf */; };
|
||||
5257E7B8420740A2862BEEB0 /* Poppins-BoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 8E2BDC4163F1467E94E5D34C /* Poppins-BoldItalic.ttf */; };
|
||||
6D069850985349ABB76BDD0A /* Poppins-Black.ttf in Resources */ = {isa = PBXBuildFile; fileRef = B1A304CF782943E19F93DFD6 /* Poppins-Black.ttf */; };
|
||||
71436C48CDF348BE904103E9 /* Poppins-Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 231B760691854EBCA7ECD80E /* Poppins-Light.ttf */; };
|
||||
7B94D8768C6340958F2EEFFD /* Poppins-ExtraLight.ttf in Resources */ = {isa = PBXBuildFile; fileRef = C9AC377D6B7744ECBBEA0A8A /* Poppins-ExtraLight.ttf */; };
|
||||
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
|
||||
836E1F3164D8497F8C51847A /* Poppins-LightItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 7CEBAD12E8E5471AA962262A /* Poppins-LightItalic.ttf */; };
|
||||
8F8E6DB2A0AB4DF3A5ED51E7 /* Poppins-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 920F53F06E0B433DB798AC45 /* Poppins-SemiBold.ttf */; };
|
||||
9FA2A398A0264369AD50123F /* Poppins-ExtraBoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9F1539AF1544412D9662D264 /* Poppins-ExtraBoldItalic.ttf */; };
|
||||
9FC2C87C76F74B609BA3709E /* Poppins-ExtraLightItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9420B3EA5C884AFFADCAFB4C /* Poppins-ExtraLightItalic.ttf */; };
|
||||
9FDEB3BC9BEB0D9B20C40FFA /* libPods-app-appTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 198E5E1047B7B7C1FE9480E3 /* libPods-app-appTests.a */; };
|
||||
A74B9EB17CB0D9069DBDEC11 /* libPods-app.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A849643D470B360BB9710A2 /* libPods-app.a */; };
|
||||
AC5E863985C04D72B5806B58 /* Poppins-Thin.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 02B78F6C72354B2D8171239D /* Poppins-Thin.ttf */; };
|
||||
B9CA13426DF0582117265C94 /* libPods-app-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 209E1A9D464732CA3D5436BA /* libPods-app-tvOS.a */; };
|
||||
BB34E03413EB4CDFA59766B1 /* Poppins-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = EB6EB5293E4C48098CBD53C2 /* Poppins-Regular.ttf */; };
|
||||
F8EEF49F61D796445B439296 /* libPods-app-tvOSTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAD654FF33034F72E23F45E0 /* libPods-app-tvOSTests.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
|
@ -44,6 +62,8 @@
|
|||
00E356EE1AD99517003FC87E /* appTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = appTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
00E356F21AD99517003FC87E /* appTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = appTests.m; sourceTree = "<group>"; };
|
||||
00FDE4C2522044DAAD866D5F /* Poppins-BlackItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-BlackItalic.ttf"; path = "../assets/fonts/Poppins-BlackItalic.ttf"; sourceTree = "<group>"; };
|
||||
02B78F6C72354B2D8171239D /* Poppins-Thin.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-Thin.ttf"; path = "../assets/fonts/Poppins-Thin.ttf"; sourceTree = "<group>"; };
|
||||
13B07F961A680F5B00A75B9A /* app.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = app.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = app/AppDelegate.h; sourceTree = "<group>"; };
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = app/AppDelegate.m; sourceTree = "<group>"; };
|
||||
|
@ -53,18 +73,34 @@
|
|||
198E5E1047B7B7C1FE9480E3 /* libPods-app-appTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-app-appTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
1A849643D470B360BB9710A2 /* libPods-app.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-app.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
209E1A9D464732CA3D5436BA /* libPods-app-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-app-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
231B760691854EBCA7ECD80E /* Poppins-Light.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-Light.ttf"; path = "../assets/fonts/Poppins-Light.ttf"; sourceTree = "<group>"; };
|
||||
2D02E47B1E0B4A5D006451C7 /* app-tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "app-tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
2D02E4901E0B4A5D006451C7 /* app-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "app-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
3CBFE8DBE8994C1FAF939519 /* Poppins-MediumItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-MediumItalic.ttf"; path = "../assets/fonts/Poppins-MediumItalic.ttf"; sourceTree = "<group>"; };
|
||||
4F9213F90B49965FDCF003FA /* Pods-app-appTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app-appTests.release.xcconfig"; path = "Target Support Files/Pods-app-appTests/Pods-app-appTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
55AC07BDE5542A03F6AD2FE2 /* Pods-app.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app.release.xcconfig"; path = "Target Support Files/Pods-app/Pods-app.release.xcconfig"; sourceTree = "<group>"; };
|
||||
64A4BC0C882E097B17B89CAB /* Pods-app-tvOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app-tvOSTests.debug.xcconfig"; path = "Target Support Files/Pods-app-tvOSTests/Pods-app-tvOSTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
661AE05493ED4FE780C32EF6 /* Poppins-Bold.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-Bold.ttf"; path = "../assets/fonts/Poppins-Bold.ttf"; sourceTree = "<group>"; };
|
||||
78E0CED54136BD6995951328 /* Pods-app-tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app-tvOS.release.xcconfig"; path = "Target Support Files/Pods-app-tvOS/Pods-app-tvOS.release.xcconfig"; sourceTree = "<group>"; };
|
||||
7AF5677EA52D44EE97668E7A /* Poppins-Medium.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-Medium.ttf"; path = "../assets/fonts/Poppins-Medium.ttf"; sourceTree = "<group>"; };
|
||||
7CEBAD12E8E5471AA962262A /* Poppins-LightItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-LightItalic.ttf"; path = "../assets/fonts/Poppins-LightItalic.ttf"; sourceTree = "<group>"; };
|
||||
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = app/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
866817BF8B562CD61F42398B /* Pods-app-tvOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app-tvOSTests.release.xcconfig"; path = "Target Support Files/Pods-app-tvOSTests/Pods-app-tvOSTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
8E2BDC4163F1467E94E5D34C /* Poppins-BoldItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-BoldItalic.ttf"; path = "../assets/fonts/Poppins-BoldItalic.ttf"; sourceTree = "<group>"; };
|
||||
920F53F06E0B433DB798AC45 /* Poppins-SemiBold.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-SemiBold.ttf"; path = "../assets/fonts/Poppins-SemiBold.ttf"; sourceTree = "<group>"; };
|
||||
9420B3EA5C884AFFADCAFB4C /* Poppins-ExtraLightItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-ExtraLightItalic.ttf"; path = "../assets/fonts/Poppins-ExtraLightItalic.ttf"; sourceTree = "<group>"; };
|
||||
977D264ECA05485EA89A2F13 /* Poppins-Italic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-Italic.ttf"; path = "../assets/fonts/Poppins-Italic.ttf"; sourceTree = "<group>"; };
|
||||
9A9C27037F0F4AF2A4CBAE78 /* Poppins-ExtraBold.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-ExtraBold.ttf"; path = "../assets/fonts/Poppins-ExtraBold.ttf"; sourceTree = "<group>"; };
|
||||
9F1539AF1544412D9662D264 /* Poppins-ExtraBoldItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-ExtraBoldItalic.ttf"; path = "../assets/fonts/Poppins-ExtraBoldItalic.ttf"; sourceTree = "<group>"; };
|
||||
A9CB7679337840D3BD256A13 /* Poppins-SemiBoldItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-SemiBoldItalic.ttf"; path = "../assets/fonts/Poppins-SemiBoldItalic.ttf"; sourceTree = "<group>"; };
|
||||
AB8B9EC2CC8BC79836F11661 /* Pods-app-tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app-tvOS.debug.xcconfig"; path = "Target Support Files/Pods-app-tvOS/Pods-app-tvOS.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
B1A304CF782943E19F93DFD6 /* Poppins-Black.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-Black.ttf"; path = "../assets/fonts/Poppins-Black.ttf"; sourceTree = "<group>"; };
|
||||
C9AC377D6B7744ECBBEA0A8A /* Poppins-ExtraLight.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-ExtraLight.ttf"; path = "../assets/fonts/Poppins-ExtraLight.ttf"; sourceTree = "<group>"; };
|
||||
D9ABD588946E114F0E0A649D /* Pods-app.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app.debug.xcconfig"; path = "Target Support Files/Pods-app/Pods-app.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
DAD654FF33034F72E23F45E0 /* libPods-app-tvOSTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-app-tvOSTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
DE49AE0B25BD2EF3496BCE37 /* Pods-app-appTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app-appTests.debug.xcconfig"; path = "Target Support Files/Pods-app-appTests/Pods-app-appTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
E251C7BB03F74441B4357419 /* Poppins-ThinItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-ThinItalic.ttf"; path = "../assets/fonts/Poppins-ThinItalic.ttf"; sourceTree = "<group>"; };
|
||||
EB6EB5293E4C48098CBD53C2 /* Poppins-Regular.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-Regular.ttf"; path = "../assets/fonts/Poppins-Regular.ttf"; sourceTree = "<group>"; };
|
||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
||||
ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
@ -180,6 +216,7 @@
|
|||
83CBBA001A601CBA00E9B192 /* Products */,
|
||||
2D16E6871FA4F8E400B85C8A /* Frameworks */,
|
||||
678C13018B6095451BF5FE91 /* Pods */,
|
||||
86DE8D5EB35F4504B427A63A /* Resources */,
|
||||
);
|
||||
indentWidth = 2;
|
||||
sourceTree = "<group>";
|
||||
|
@ -197,6 +234,32 @@
|
|||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
86DE8D5EB35F4504B427A63A /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B1A304CF782943E19F93DFD6 /* Poppins-Black.ttf */,
|
||||
00FDE4C2522044DAAD866D5F /* Poppins-BlackItalic.ttf */,
|
||||
661AE05493ED4FE780C32EF6 /* Poppins-Bold.ttf */,
|
||||
8E2BDC4163F1467E94E5D34C /* Poppins-BoldItalic.ttf */,
|
||||
9A9C27037F0F4AF2A4CBAE78 /* Poppins-ExtraBold.ttf */,
|
||||
9F1539AF1544412D9662D264 /* Poppins-ExtraBoldItalic.ttf */,
|
||||
C9AC377D6B7744ECBBEA0A8A /* Poppins-ExtraLight.ttf */,
|
||||
9420B3EA5C884AFFADCAFB4C /* Poppins-ExtraLightItalic.ttf */,
|
||||
977D264ECA05485EA89A2F13 /* Poppins-Italic.ttf */,
|
||||
231B760691854EBCA7ECD80E /* Poppins-Light.ttf */,
|
||||
7CEBAD12E8E5471AA962262A /* Poppins-LightItalic.ttf */,
|
||||
7AF5677EA52D44EE97668E7A /* Poppins-Medium.ttf */,
|
||||
3CBFE8DBE8994C1FAF939519 /* Poppins-MediumItalic.ttf */,
|
||||
EB6EB5293E4C48098CBD53C2 /* Poppins-Regular.ttf */,
|
||||
920F53F06E0B433DB798AC45 /* Poppins-SemiBold.ttf */,
|
||||
A9CB7679337840D3BD256A13 /* Poppins-SemiBoldItalic.ttf */,
|
||||
02B78F6C72354B2D8171239D /* Poppins-Thin.ttf */,
|
||||
E251C7BB03F74441B4357419 /* Poppins-ThinItalic.ttf */,
|
||||
);
|
||||
name = Resources;
|
||||
path = "";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
|
@ -349,6 +412,24 @@
|
|||
files = (
|
||||
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */,
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
|
||||
6D069850985349ABB76BDD0A /* Poppins-Black.ttf in Resources */,
|
||||
417D579C3DC24A9684D24EDD /* Poppins-BlackItalic.ttf in Resources */,
|
||||
4E01D1C8DD5749C8953D3BE5 /* Poppins-Bold.ttf in Resources */,
|
||||
5257E7B8420740A2862BEEB0 /* Poppins-BoldItalic.ttf in Resources */,
|
||||
2DC4DBF14540481ABF14857A /* Poppins-ExtraBold.ttf in Resources */,
|
||||
9FA2A398A0264369AD50123F /* Poppins-ExtraBoldItalic.ttf in Resources */,
|
||||
7B94D8768C6340958F2EEFFD /* Poppins-ExtraLight.ttf in Resources */,
|
||||
9FC2C87C76F74B609BA3709E /* Poppins-ExtraLightItalic.ttf in Resources */,
|
||||
50AAEBD19BD24B129801C393 /* Poppins-Italic.ttf in Resources */,
|
||||
71436C48CDF348BE904103E9 /* Poppins-Light.ttf in Resources */,
|
||||
836E1F3164D8497F8C51847A /* Poppins-LightItalic.ttf in Resources */,
|
||||
230E5925A9044F679B2F7C39 /* Poppins-Medium.ttf in Resources */,
|
||||
04B5A89762F9430A902416B4 /* Poppins-MediumItalic.ttf in Resources */,
|
||||
BB34E03413EB4CDFA59766B1 /* Poppins-Regular.ttf in Resources */,
|
||||
8F8E6DB2A0AB4DF3A5ED51E7 /* Poppins-SemiBold.ttf in Resources */,
|
||||
41DE97CF96674977BC052462 /* Poppins-SemiBoldItalic.ttf in Resources */,
|
||||
AC5E863985C04D72B5806B58 /* Poppins-Thin.ttf in Resources */,
|
||||
4F931CB3182F40F580F357FF /* Poppins-ThinItalic.ttf in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -894,6 +975,7 @@
|
|||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
|
@ -954,6 +1036,7 @@
|
|||
COPY_PHASE_STRIP = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<dict>
|
||||
<key>NSExceptionDomains</key>
|
||||
<dict>
|
||||
<key>localhost</key>
|
||||
|
@ -51,7 +51,7 @@
|
|||
<key>NSCalendarsUsageDescription</key>
|
||||
<string>This app can add calendar events</string>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string></string>
|
||||
<string/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
|
@ -67,5 +67,26 @@
|
|||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
<key>UIAppFonts</key>
|
||||
<array>
|
||||
<string>Poppins-Black.ttf</string>
|
||||
<string>Poppins-BlackItalic.ttf</string>
|
||||
<string>Poppins-Bold.ttf</string>
|
||||
<string>Poppins-BoldItalic.ttf</string>
|
||||
<string>Poppins-ExtraBold.ttf</string>
|
||||
<string>Poppins-ExtraBoldItalic.ttf</string>
|
||||
<string>Poppins-ExtraLight.ttf</string>
|
||||
<string>Poppins-ExtraLightItalic.ttf</string>
|
||||
<string>Poppins-Italic.ttf</string>
|
||||
<string>Poppins-Light.ttf</string>
|
||||
<string>Poppins-LightItalic.ttf</string>
|
||||
<string>Poppins-Medium.ttf</string>
|
||||
<string>Poppins-MediumItalic.ttf</string>
|
||||
<string>Poppins-Regular.ttf</string>
|
||||
<string>Poppins-SemiBold.ttf</string>
|
||||
<string>Poppins-SemiBoldItalic.ttf</string>
|
||||
<string>Poppins-Thin.ttf</string>
|
||||
<string>Poppins-ThinItalic.ttf</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<device id="retina6_7" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
|
@ -16,41 +17,30 @@
|
|||
<rect key="frame" x="0.0" y="0.0" width="428" height="926"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Skolplattformen" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="MN2-I3-ftu">
|
||||
<rect key="frame" x="0.0" y="131" width="414" height="27.666666666666657"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="27.5" id="XcH-N0-h20"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="32"/>
|
||||
<color key="textColor" systemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="skolplattformen-logga-original" translatesAutoresizingMaskIntoConstraints="NO" id="TKh-fJ-S9X">
|
||||
<rect key="frame" x="44" y="293" width="340" height="340"/>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" image="skolplattformen-logga-original" translatesAutoresizingMaskIntoConstraints="NO" id="TKh-fJ-S9X">
|
||||
<rect key="frame" x="-147" y="54" width="819" height="819"/>
|
||||
<preferredSymbolConfiguration key="preferredSymbolConfiguration" scale="default"/>
|
||||
</imageView>
|
||||
</subviews>
|
||||
<viewLayoutGuide key="safeArea" id="Bcu-3y-fUS"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
<constraints>
|
||||
<constraint firstItem="MN2-I3-ftu" firstAttribute="leading" secondItem="Bcu-3y-fUS" secondAttribute="leading" id="122-lw-Ul7"/>
|
||||
<constraint firstItem="TKh-fJ-S9X" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="1JX-HH-pzz"/>
|
||||
<constraint firstItem="TKh-fJ-S9X" firstAttribute="leading" secondItem="Bcu-3y-fUS" secondAttribute="leading" constant="44" id="6bf-fh-uS6"/>
|
||||
<constraint firstItem="TKh-fJ-S9X" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="8Gr-KZ-pEa"/>
|
||||
<constraint firstItem="MN2-I3-ftu" firstAttribute="top" secondItem="Bcu-3y-fUS" secondAttribute="top" constant="87" id="PVH-eA-1yy"/>
|
||||
<constraint firstItem="Bcu-3y-fUS" firstAttribute="trailing" secondItem="MN2-I3-ftu" secondAttribute="trailing" constant="14" id="TcS-As-BCG"/>
|
||||
<constraint firstItem="Bcu-3y-fUS" firstAttribute="bottom" secondItem="TKh-fJ-S9X" secondAttribute="bottom" constant="259" id="pzW-T6-bKj"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="52" y="374.66266866566718"/>
|
||||
<point key="canvasLocation" x="51.86915887850467" y="374.51403887688986"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="skolplattformen-logga-original" width="1210" height="1182"/>
|
||||
<systemColor name="darkTextColor">
|
||||
<color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<systemColor name="systemBackgroundColor">
|
||||
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
</document>
|
||||
|
|
|
@ -12,6 +12,7 @@ const MetroConfig = require('@ui-kitten/metro-config')
|
|||
*/
|
||||
const evaConfig = {
|
||||
evaPackage: '@eva-design/eva',
|
||||
customMappingPath: './design/mapping.json',
|
||||
}
|
||||
|
||||
module.exports = MetroConfig.create(evaConfig, {
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
"@react-native-community/blur": "3.6.0",
|
||||
"@react-native-community/cookies": "5.0.1",
|
||||
"@react-native-community/datetimepicker": "3.4.3",
|
||||
"@react-native-community/masked-view": "0.1.10",
|
||||
"@react-native-community/masked-view": "^0.1.11",
|
||||
"@react-navigation/bottom-tabs": "5.11.9",
|
||||
"@react-navigation/native": "5.9.4",
|
||||
"@react-navigation/stack": "5.14.4",
|
||||
|
@ -47,13 +47,14 @@
|
|||
"react-native-appearance": "^0.3.4",
|
||||
"react-native-calendar-events": "2.2.0",
|
||||
"react-native-fix-image": "2.1.0",
|
||||
"react-native-gesture-handler": "1.10.3",
|
||||
"react-native-gesture-handler": "^1.10.3",
|
||||
"react-native-localize": "^2.0.2",
|
||||
"react-native-markdown-display": "7.0.0-alpha.2",
|
||||
"react-native-modal-datetime-picker": "9.2.0",
|
||||
"react-native-reanimated": "^2.2.0",
|
||||
"react-native-restart": "^0.0.22",
|
||||
"react-native-safe-area-context": "3.2.0",
|
||||
"react-native-screens": "2.18.1",
|
||||
"react-native-safe-area-context": "^3.2.0",
|
||||
"react-native-screens": "^3.3.0",
|
||||
"react-native-simple-toast": "1.1.3",
|
||||
"react-native-svg": "12.1.0",
|
||||
"react-native-svg-transformer": "0.14.3",
|
||||
|
@ -61,7 +62,7 @@
|
|||
"react-native-typography": "1.4.1",
|
||||
"react-native-webview": "11.4.2",
|
||||
"react-native-weekly-calendar": "^0.2.0",
|
||||
"rn-actionsheet-module": "https://github.com/viktorlarsson/rn-actionsheet-module",
|
||||
"rn-actionsheet-module": "^1.0.3",
|
||||
"use-async-storage": "1.2.0",
|
||||
"yup": "0.32.9"
|
||||
},
|
||||
|
@ -70,8 +71,8 @@
|
|||
"@babel/runtime": "^7.13.10",
|
||||
"@react-native-community/eslint-config": "^2.0.0",
|
||||
"@testing-library/jest-native": "^4.0.1",
|
||||
"@testing-library/react-hooks": "^5.1.1",
|
||||
"@testing-library/react-native": "7.1.0",
|
||||
"@testing-library/react-hooks": "^7.0.0",
|
||||
"@testing-library/react-native": "7.2.0",
|
||||
"@types/i18n-js": "^3.8.0",
|
||||
"@types/jest": "^26.0.22",
|
||||
"@types/jsuri": "^1.3.30",
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = {
|
||||
assets: ['./assets/fonts']
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import 'react-native-gesture-handler/jestSetup'
|
||||
import mockAsyncStorage from '@react-native-async-storage/async-storage/jest/async-storage-mock'
|
||||
import moment from 'moment'
|
||||
import 'moment/locale/sv'
|
||||
import 'react-native-gesture-handler/jestSetup'
|
||||
|
||||
moment.locale('sv')
|
||||
|
||||
|
@ -9,3 +9,13 @@ jest.mock('@react-native-async-storage/async-storage', () => mockAsyncStorage)
|
|||
|
||||
// Silence useNativeDriver error
|
||||
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper')
|
||||
|
||||
jest.mock('react-native-reanimated', () => {
|
||||
const Reanimated = require('react-native-reanimated/mock')
|
||||
|
||||
// The mock for `call` immediately calls the callback which is incorrect
|
||||
// So we override it with a no-op
|
||||
Reanimated.default.call = () => {}
|
||||
|
||||
return Reanimated
|
||||
})
|
||||
|
|
|
@ -30,13 +30,14 @@ export const aspectRatio = (
|
|||
}
|
||||
}
|
||||
|
||||
type Layout = 't1' | 't2' | 't3' | 't4' | 't5'
|
||||
type Layout = 't1' | 't2' | 't3' | 't4' | 't5' | 't6'
|
||||
export const layout: Record<Layout, number> = {
|
||||
t1: 4,
|
||||
t2: 8,
|
||||
t3: 12,
|
||||
t4: 16,
|
||||
t5: 20,
|
||||
t6: 30,
|
||||
}
|
||||
|
||||
/** 4px */
|
||||
|
@ -49,3 +50,5 @@ export const t3 = layout.t3
|
|||
export const t4 = layout.t4
|
||||
/** 20px */
|
||||
export const t5 = layout.t5
|
||||
/** 30px */
|
||||
export const t6 = layout.t6
|
||||
|
|
|
@ -30,7 +30,7 @@ export const fontWeight: Record<FontWeight, TextStyle> = {
|
|||
},
|
||||
bold: {
|
||||
...systemWeights.bold,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export const header: TextStyle = {
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
"bankid": {
|
||||
"OpenManually": "Öppna BankID manuellt",
|
||||
"OpenOnAnotherDevice": "Öppna BankID på en annan enhet",
|
||||
"OpenOnThisDevice": "Öppna BankID på denna enhet",
|
||||
"OpenOnThisDevice": "Logga in med BankID",
|
||||
"Waiting": "Väntar på BankID…"
|
||||
},
|
||||
"chooseLoginMethod": "Välj inloggningsmetod",
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { StyleService, useStyleSheet } from '@ui-kitten/components'
|
||||
import React from 'react'
|
||||
import { SafeAreaView as RNSafeAreaView, ViewProps } from 'react-native'
|
||||
import { ViewProps } from 'react-native'
|
||||
import { SafeAreaView as RNSafeAreaView } from 'react-native-safe-area-context'
|
||||
import { Layout } from '../styles'
|
||||
|
||||
export const SafeAreaView: React.FC<ViewProps> = ({ children }) => {
|
||||
|
@ -12,6 +13,6 @@ export const SafeAreaView: React.FC<ViewProps> = ({ children }) => {
|
|||
const themedStyles = StyleService.create({
|
||||
safeArea: {
|
||||
...Layout.flex.full,
|
||||
backgroundColor: 'background-basic-color-1',
|
||||
backgroundColor: 'background-basic-color-2',
|
||||
},
|
||||
})
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import {
|
||||
fullName,
|
||||
guardians,
|
||||
initials,
|
||||
sortByFirstName,
|
||||
studentName,
|
||||
} from '../peopleHelpers'
|
||||
|
@ -72,3 +73,13 @@ describe('#guardians', () => {
|
|||
).toEqual('Loras Eriksson, Margaery Eriksson')
|
||||
})
|
||||
})
|
||||
describe('#initials', () => {
|
||||
test('should extract initials from name', () => {
|
||||
expect(initials('Namn Namnsson')).toEqual('Na')
|
||||
expect(initials('Nisse Namnsson')).toEqual('Ni')
|
||||
})
|
||||
|
||||
test('handles undefined name', () => {
|
||||
expect(initials(undefined)).toBeUndefined()
|
||||
})
|
||||
})
|
|
@ -1,9 +0,0 @@
|
|||
export const studentName = (name) => name?.replace(/\s?\(\w+\)$/, '')
|
||||
|
||||
export const sortByFirstName = (data) =>
|
||||
data.sort((a, b) => a.firstname.localeCompare(b.firstname))
|
||||
|
||||
export const guardians = (data) =>
|
||||
sortByFirstName(data).map(fullName).join(', ')
|
||||
|
||||
export const fullName = (person) => `${person.firstname} ${person.lastname}`
|
|
@ -0,0 +1,16 @@
|
|||
import { Guardian } from '@skolplattformen/embedded-api'
|
||||
|
||||
export const studentName = (name?: string) => name?.replace(/\s?\(\w+\)$/, '')
|
||||
|
||||
export const sortByFirstName = (data: Guardian[]) =>
|
||||
data.sort((a, b) => a.firstname.localeCompare(b.firstname))
|
||||
|
||||
export const guardians = (data: Guardian[]) =>
|
||||
sortByFirstName(data).map(fullName).join(', ')
|
||||
|
||||
export const fullName = (person: Guardian) =>
|
||||
`${person.firstname} ${person.lastname}`
|
||||
|
||||
export const initials = (name?: string) => {
|
||||
return name?.slice(0, 2)
|
||||
}
|
|
@ -173,6 +173,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz#806526ce125aed03373bc416a828321e3a6a33af"
|
||||
integrity sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==
|
||||
|
||||
"@babel/helper-plugin-utils@^7.14.5":
|
||||
version "7.14.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9"
|
||||
integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==
|
||||
|
||||
"@babel/helper-remap-async-to-generator@^7.13.0":
|
||||
version "7.13.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.13.0.tgz#376a760d9f7b4b2077a9dd05aa9c3927cadb2209"
|
||||
|
@ -546,6 +551,13 @@
|
|||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.12.13"
|
||||
|
||||
"@babel/plugin-transform-object-assign@^7.10.4":
|
||||
version "7.14.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.14.5.tgz#62537d54b6d85de04f4df48bfdba2eebff17b760"
|
||||
integrity sha512-lvhjk4UN9xJJYB1mI5KC0/o1D5EcJXdbhVe+4fSk08D6ZN+iuAIs7LJC+71h8av9Ew4+uRq9452v9R93SFmQlQ==
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.14.5"
|
||||
|
||||
"@babel/plugin-transform-object-super@^7.0.0":
|
||||
version "7.12.13"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz#b4416a2d63b8f7be314f3d349bd55a9c1b5171f7"
|
||||
|
@ -1360,10 +1372,10 @@
|
|||
resolved "https://registry.yarnpkg.com/@react-native-community/eslint-plugin/-/eslint-plugin-1.1.0.tgz#e42b1bef12d2415411519fd528e64b593b1363dc"
|
||||
integrity sha512-W/J0fNYVO01tioHjvYWQ9m6RgndVtbElzYozBq1ZPrHO/iCzlqoySHl4gO/fpCl9QEFjvJfjPgtPMTMlsoq5DQ==
|
||||
|
||||
"@react-native-community/masked-view@0.1.10":
|
||||
version "0.1.10"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/masked-view/-/masked-view-0.1.10.tgz#5dda643e19e587793bc2034dd9bf7398ad43d401"
|
||||
integrity sha512-rk4sWFsmtOw8oyx8SD3KSvawwaK7gRBSEIy2TAwURyGt+3TizssXP1r8nx3zY+R7v2vYYHXZ+k2/GULAT/bcaQ==
|
||||
"@react-native-community/masked-view@^0.1.11":
|
||||
version "0.1.11"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/masked-view/-/masked-view-0.1.11.tgz#2f4c6e10bee0786abff4604e39a37ded6f3980ce"
|
||||
integrity sha512-rQfMIGSR/1r/SyN87+VD8xHHzDYeHaJq6elOSCAD+0iLagXkSI2pfA0LmSXP21uw5i3em7GkkRjfJ8wpqWXZNw==
|
||||
|
||||
"@react-native/assets@1.0.0":
|
||||
version "1.0.0"
|
||||
|
@ -1583,22 +1595,21 @@
|
|||
ramda "^0.26.1"
|
||||
redent "^2.0.0"
|
||||
|
||||
"@testing-library/react-hooks@^5.1.1":
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-5.1.2.tgz#36e359d992bb652a9885c6fa9aa394639cbe8dd3"
|
||||
integrity sha512-jwhtDYZ5gQUIX8cmVCVdtwNvuF5EiCOWjokRlTV+o/V0GdtRZDykUllL1OXq5PS4+J33wGLNQeeWzEHcWrH7tg==
|
||||
"@testing-library/react-hooks@^7.0.0":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-7.0.0.tgz#dd6d37a7e018f147a3b9153137f10e013be8472b"
|
||||
integrity sha512-WFBGH8DWdIGGBHt6PBtQPe2v4Kbj9vQ1sQ9qLBTmwn1PNggngint4MTE/IiWCYhPbyTW3oc/7X62DObMn/AjQQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.12.5"
|
||||
"@types/react" ">=16.9.0"
|
||||
"@types/react-dom" ">=16.9.0"
|
||||
"@types/react-test-renderer" ">=16.9.0"
|
||||
filter-console "^0.1.1"
|
||||
react-error-boundary "^3.1.0"
|
||||
|
||||
"@testing-library/react-native@7.1.0":
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@testing-library/react-native/-/react-native-7.1.0.tgz#6b168aac21522c8a5175461b350336fd79612ac9"
|
||||
integrity sha512-ljVM9KZqG7BT/NFN6CHzdF6MNmM28+k7MEybFJ7FW1wVrhpiY4+hU9ypZ+hboO+MG3KpE2aFBzP4od3gu+Zzdg==
|
||||
"@testing-library/react-native@7.2.0":
|
||||
version "7.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@testing-library/react-native/-/react-native-7.2.0.tgz#e5ec5b0974e4e5f525f8057563417d1e9f820d96"
|
||||
integrity sha512-rDKzJjAAeGgyoJT0gFQiMsIL09chdWcwZyYx6WZHMgm2c5NDqY52hUuyTkzhqddMYWmSRklFphSg7B2HX+246Q==
|
||||
dependencies:
|
||||
pretty-format "^26.0.1"
|
||||
|
||||
|
@ -4007,11 +4018,6 @@ fill-range@^7.0.1:
|
|||
dependencies:
|
||||
to-regex-range "^5.0.1"
|
||||
|
||||
filter-console@^0.1.1:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/filter-console/-/filter-console-0.1.1.tgz#6242be28982bba7415bcc6db74a79f4a294fa67c"
|
||||
integrity sha512-zrXoV1Uaz52DqPs+qEwNJWJFAWZpYJ47UNmpN9q4j+/EYsz85uV0DC9k8tRND5kYmoVzL0W+Y75q4Rg8sRJCdg==
|
||||
|
||||
filter-obj@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b"
|
||||
|
@ -6671,7 +6677,7 @@ mkdirp@^0.5.1, mkdirp@~0.5.1:
|
|||
dependencies:
|
||||
minimist "^1.2.5"
|
||||
|
||||
mockdate@^3.0.5:
|
||||
mockdate@^3.0.2, mockdate@^3.0.5:
|
||||
version "3.0.5"
|
||||
resolved "https://registry.yarnpkg.com/mockdate/-/mockdate-3.0.5.tgz#789be686deb3149e7df2b663d2bc4392bc3284fb"
|
||||
integrity sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ==
|
||||
|
@ -7594,7 +7600,7 @@ react-native-fix-image@2.1.0:
|
|||
resolved "https://registry.yarnpkg.com/react-native-fix-image/-/react-native-fix-image-2.1.0.tgz#a4677b91529be926544775faf736df6af8c4743c"
|
||||
integrity sha512-qn4xItNSKfwlSkMHgxH9cusUQuk5Lhag9aHqL9ESxnCDUDwqS6rsWuOYt/JlncaKhsCc9cANFomCLlY8+Ffuaw==
|
||||
|
||||
react-native-gesture-handler@1.10.3:
|
||||
react-native-gesture-handler@^1.10.3:
|
||||
version "1.10.3"
|
||||
resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-1.10.3.tgz#942bbf2963bbf49fa79593600ee9d7b5dab3cfc0"
|
||||
integrity sha512-cBGMi1IEsIVMgoox4RvMx7V2r6bNKw0uR1Mu1o7NbuHS6BRSVLq0dP34l2ecnPlC+jpWd3le6Yg1nrdCjby2Mw==
|
||||
|
@ -7632,20 +7638,30 @@ react-native-modal-datetime-picker@9.2.0:
|
|||
dependencies:
|
||||
prop-types "^15.7.2"
|
||||
|
||||
react-native-reanimated@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-2.2.0.tgz#a6412c56b4e591d1f00fac949f62d0c72c357c78"
|
||||
integrity sha512-lOJDd+5w1gY6DHGXG2jD1dsjzQmXQ2699HUc3IztvI2WP4zUT+UAA+zSG+5JiBS5DUnTL8YhhkmUQmr1KNGO5w==
|
||||
dependencies:
|
||||
"@babel/plugin-transform-object-assign" "^7.10.4"
|
||||
fbjs "^3.0.0"
|
||||
mockdate "^3.0.2"
|
||||
string-hash-64 "^1.0.3"
|
||||
|
||||
react-native-restart@^0.0.22:
|
||||
version "0.0.22"
|
||||
resolved "https://registry.yarnpkg.com/react-native-restart/-/react-native-restart-0.0.22.tgz#81fcb7f31e35951d85410c68b9556acf3ab88705"
|
||||
integrity sha512-XwCqAMAKsO8yCM3xACPFKvkDQZe41lcavOuO0gUEu803IuTLtciualCq/qs83ryRDCDh1jkXYRqFjsGjLMCN3Q==
|
||||
|
||||
react-native-safe-area-context@3.2.0:
|
||||
react-native-safe-area-context@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-3.2.0.tgz#06113c6b208f982d68ab5c3cebd199ca93db6941"
|
||||
integrity sha512-k2Nty4PwSnrg9HwrYeeE+EYqViYJoOFwEy9LxL5RIRfoqxAq/uQXNGwpUg2/u4gnKpBbEPa9eRh15KKMe/VHkA==
|
||||
|
||||
react-native-screens@2.18.1:
|
||||
version "2.18.1"
|
||||
resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-2.18.1.tgz#47b9991c6f762d00d0ed3233e5283d523e859885"
|
||||
integrity sha512-r5WZLpmx2hHjC1RgMdPq5YpSU9tEhBpUaZ5M1SUtNIONyiLqQVxabhRCINdebIk4depJiIl7yw2Q85zJyeX6fw==
|
||||
react-native-screens@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-3.3.0.tgz#d4464a96620b85d09e46bd6865b5f48456c244f0"
|
||||
integrity sha512-ni11jC6I9cFVXdLIDwkgafDHw/STXUNzkR5Fx3w8Wikdzi8gfTEan2kiOm7aS42d2F/LXddZ6i74Z2em0L6LPQ==
|
||||
|
||||
react-native-simple-toast@1.1.3:
|
||||
version "1.1.3"
|
||||
|
@ -8106,9 +8122,10 @@ rimraf@~2.6.2:
|
|||
dependencies:
|
||||
glob "^7.1.3"
|
||||
|
||||
"rn-actionsheet-module@https://github.com/viktorlarsson/rn-actionsheet-module":
|
||||
rn-actionsheet-module@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://github.com/viktorlarsson/rn-actionsheet-module#44ae59bff1b61177b0e63d73383bce4582008b47"
|
||||
resolved "https://registry.yarnpkg.com/rn-actionsheet-module/-/rn-actionsheet-module-1.0.3.tgz#803857999b7a74df76eebbb36910e890c9527071"
|
||||
integrity sha512-wm+VqcGEfmf5XcnyH7g98jqaAqj0EyjqaN1hIfip2qO/yMkg+ZX2gfus2kLJrvXRfEk9Rax40TnkzOEt6My5tA==
|
||||
|
||||
rsvp@^4.8.4:
|
||||
version "4.8.5"
|
||||
|
@ -8596,6 +8613,11 @@ strict-uri-encode@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546"
|
||||
integrity sha1-ucczDHBChi9rFC3CdLvMWGbONUY=
|
||||
|
||||
string-hash-64@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/string-hash-64/-/string-hash-64-1.0.3.tgz#0deb56df58678640db5c479ccbbb597aaa0de322"
|
||||
integrity sha512-D5OKWKvDhyVWWn2x5Y9b+37NUllks34q1dCDhk/vYcso9fmhs+Tl3KR/gE4v5UNj2UA35cnX4KdVVGkG1deKqw==
|
||||
|
||||
string-length@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/string-length/-/string-length-3.1.0.tgz#107ef8c23456e187a8abd4a61162ff4ac6e25837"
|
||||
|
|
|
@ -63,14 +63,14 @@ const Banner = (): JSX.Element => {
|
|||
</div>
|
||||
<H1>{intl.formatMessage({ id: 'general.title' })}</H1>
|
||||
<p>{intl.formatMessage({ id: 'general.description' })}</p>
|
||||
{!!intl.formatMessage({ id: 'general.flashtitle' }) && (
|
||||
{/*intl.formatMessage({ id: 'general.flashtitle' }) && (
|
||||
<div className="mt-5">
|
||||
<h2 className="mb-4 text-2xl font-bold leading-tight text-gray-800 dark:text-white md:text-4xl">
|
||||
{intl.formatMessage({ id: 'general.flashtitle' })}
|
||||
</h2>
|
||||
<p>{intl.formatMessage({ id: 'general.flashtext' })}</p>
|
||||
</div>
|
||||
)}
|
||||
)*/}
|
||||
<p className="flex items-center py-4 sm:flex-row space-x-2 lg:space-x-4">
|
||||
<Link.External
|
||||
className="inline-block"
|
||||
|
|
|
@ -7,6 +7,8 @@ const team = [
|
|||
{ name: 'Johan Öbrink', twitter: 'johanobrink' },
|
||||
{ name: 'Rickard Natt och Dag', twitter: 'rnattochdag' },
|
||||
{ name: 'Viktor Sarström', twitter: 'viktorsarstrom' },
|
||||
{ name: 'Kajetan Kazimierczak', twitter: 'kajetanek' },
|
||||
{ name: 'Jonathan Edenström', twitter: 'edenstroem' },
|
||||
{ name: 'Öppna skolplattformen', twitter: 'oppnaskolplatt' },
|
||||
]
|
||||
|
||||
|
@ -62,7 +64,7 @@ const Footer = (): JSX.Element => {
|
|||
|
||||
<div className="p-5 bg-white dark:bg-gray-800 shadow-md rounded-md">
|
||||
<div className="mb-3 text-gray-800 dark:text-gray-200">
|
||||
@iteam1337 Digitalisering på riktigt.
|
||||
@iteam1337 We move fast and fix things.
|
||||
</div>
|
||||
<div>
|
||||
<Link.External href="https://iteam.se" target="_blank">
|
||||
|
|
|
@ -3,7 +3,7 @@ import DownloadButtons from './DownloadButtons'
|
|||
import Icon from './Icon'
|
||||
import SectionTitle from './SectionTitle'
|
||||
|
||||
const price = 0
|
||||
const price = 12
|
||||
|
||||
const baseFeatures = [
|
||||
{
|
||||
|
@ -33,17 +33,17 @@ const Pricing = (): JSX.Element => {
|
|||
<section className="px-5 py-8 md:px-0 md:py-32" id="vad-kostar-det">
|
||||
<div className="max-w-2xl mx-auto">
|
||||
<SectionTitle
|
||||
title="Hur kan det vara gratis?"
|
||||
title="Varför inte gratis?"
|
||||
text={`
|
||||
Vi som bygger appen vill gärna fortsätta vidareutveckla den och även ha möjlighet att ge ersättning
|
||||
till de som hjälper till. Vi har dock bestämt oss för att, på försök, låta denna ersättning komma
|
||||
från frivilliga donationer via Patreon.
|
||||
till de som hjälper till. Vi gjorde ett försök att ge ut appen gratis och hoppades att fler kunde stötta oss via
|
||||
Patreon istället. Det visade sig inte vara hållbart men om vi får fler sponsorer så kommer vi göra appen gratis igen!
|
||||
`}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex">
|
||||
<div className="flex flex-col items-center inline-block px-5 py-8 mx-auto text-center shadow-lg rounded-md dark:bg-gray-800">
|
||||
<h3 className="text-3xl text-gray-800 dark:text-gray-400">Tillfälligt</h3>
|
||||
<h3 className="text-3xl text-gray-800 dark:text-gray-400">Just nu</h3>
|
||||
<div className="mt-5 text-6xl text-pink-500">
|
||||
{formatPrice(price)}
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const Privacy = (): JSX.Element => {
|
||||
return (
|
||||
<div className="header">
|
||||
<div>
|
||||
<div className="max-w-6xl mx-auto px-5 md:px-0 my-5 md:my-24 prose dark:prose-dark">
|
||||
<h1>Öppna Skolplattformen</h1>
|
||||
<h2>Integritetspolicy</h2>
|
||||
|
|
|
@ -975,13 +975,6 @@
|
|||
"resolved" "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz"
|
||||
"version" "2.0.5"
|
||||
|
||||
"abort-controller@^3.0.0":
|
||||
"integrity" "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="
|
||||
"resolved" "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz"
|
||||
"version" "3.0.0"
|
||||
dependencies:
|
||||
"event-target-shim" "^5.0.0"
|
||||
|
||||
"acorn-globals@^6.0.0":
|
||||
"integrity" "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg=="
|
||||
"resolved" "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz"
|
||||
|
@ -1014,13 +1007,6 @@
|
|||
"resolved" "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz"
|
||||
"version" "7.4.1"
|
||||
|
||||
"agent-base@6":
|
||||
"integrity" "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="
|
||||
"resolved" "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz"
|
||||
"version" "6.0.2"
|
||||
dependencies:
|
||||
"debug" "4"
|
||||
|
||||
"ajv-keywords@^3.5.2":
|
||||
"integrity" "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="
|
||||
"resolved" "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz"
|
||||
|
@ -1182,11 +1168,6 @@
|
|||
"es-abstract" "^1.18.0-next.1"
|
||||
"function-bind" "^1.1.1"
|
||||
|
||||
"arrify@^2.0.0":
|
||||
"integrity" "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug=="
|
||||
"resolved" "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz"
|
||||
"version" "2.0.1"
|
||||
|
||||
"asn1.js@^5.2.0":
|
||||
"integrity" "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA=="
|
||||
"resolved" "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz"
|
||||
|
@ -1284,13 +1265,6 @@
|
|||
"resolved" "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz"
|
||||
"version" "1.11.0"
|
||||
|
||||
"axios@^0.21.1":
|
||||
"integrity" "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA=="
|
||||
"resolved" "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz"
|
||||
"version" "0.21.1"
|
||||
dependencies:
|
||||
"follow-redirects" "^1.10.0"
|
||||
|
||||
"babel-eslint@10.1.0":
|
||||
"integrity" "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg=="
|
||||
"resolved" "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz"
|
||||
|
@ -1387,7 +1361,7 @@
|
|||
"mixin-deep" "^1.2.0"
|
||||
"pascalcase" "^0.1.1"
|
||||
|
||||
"base64-js@^1.0.2", "base64-js@^1.3.0":
|
||||
"base64-js@^1.0.2":
|
||||
"integrity" "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
|
||||
"resolved" "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz"
|
||||
"version" "1.5.1"
|
||||
|
@ -1404,11 +1378,6 @@
|
|||
"resolved" "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz"
|
||||
"version" "5.2.2"
|
||||
|
||||
"bignumber.js@^9.0.0":
|
||||
"integrity" "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA=="
|
||||
"resolved" "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz"
|
||||
"version" "9.0.1"
|
||||
|
||||
"binary-extensions@^2.0.0":
|
||||
"integrity" "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA=="
|
||||
"resolved" "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz"
|
||||
|
@ -1558,11 +1527,6 @@
|
|||
dependencies:
|
||||
"node-int64" "^0.4.0"
|
||||
|
||||
"buffer-equal-constant-time@1.0.1":
|
||||
"integrity" "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
|
||||
"resolved" "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz"
|
||||
"version" "1.0.1"
|
||||
|
||||
"buffer-from@^1.0.0":
|
||||
"integrity" "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
|
||||
"resolved" "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz"
|
||||
|
@ -2083,7 +2047,7 @@
|
|||
dependencies:
|
||||
"ms" "2.0.0"
|
||||
|
||||
"debug@^4.0.1", "debug@^4.1.0", "debug@^4.1.1", "debug@^4.3.1", "debug@4":
|
||||
"debug@^4.0.1", "debug@^4.1.0", "debug@^4.1.1", "debug@^4.3.1":
|
||||
"integrity" "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ=="
|
||||
"resolved" "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz"
|
||||
"version" "4.3.1"
|
||||
|
@ -2292,13 +2256,6 @@
|
|||
"jsbn" "~0.1.0"
|
||||
"safer-buffer" "^2.1.0"
|
||||
|
||||
"ecdsa-sig-formatter@^1.0.11", "ecdsa-sig-formatter@1.0.11":
|
||||
"integrity" "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ=="
|
||||
"resolved" "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz"
|
||||
"version" "1.0.11"
|
||||
dependencies:
|
||||
"safe-buffer" "^5.0.1"
|
||||
|
||||
"electron-to-chromium@^1.3.723":
|
||||
"integrity" "sha512-2Tg+7jSl3oPxgsBsWKh5H83QazTkmWG/cnNwJplmyZc7KcN61+I10oUgaXSVk/NwfvN3BdkKDR4FYuRBQQ2v0A=="
|
||||
"resolved" "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.752.tgz"
|
||||
|
@ -2591,11 +2548,6 @@
|
|||
"resolved" "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz"
|
||||
"version" "1.8.1"
|
||||
|
||||
"event-target-shim@^5.0.0":
|
||||
"integrity" "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="
|
||||
"resolved" "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz"
|
||||
"version" "5.0.1"
|
||||
|
||||
"events@^3.0.0":
|
||||
"integrity" "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg=="
|
||||
"resolved" "https://registry.npmjs.org/events/-/events-3.2.0.tgz"
|
||||
|
@ -2700,7 +2652,7 @@
|
|||
"assign-symbols" "^1.0.0"
|
||||
"is-extendable" "^1.0.1"
|
||||
|
||||
"extend@^3.0.2", "extend@~3.0.2":
|
||||
"extend@~3.0.2":
|
||||
"integrity" "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
|
||||
"resolved" "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz"
|
||||
"version" "3.0.2"
|
||||
|
@ -2761,11 +2713,6 @@
|
|||
"resolved" "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz"
|
||||
"version" "2.0.6"
|
||||
|
||||
"fast-text-encoding@^1.0.0":
|
||||
"integrity" "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig=="
|
||||
"resolved" "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz"
|
||||
"version" "1.0.3"
|
||||
|
||||
"fastq@^1.6.0":
|
||||
"integrity" "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g=="
|
||||
"resolved" "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz"
|
||||
|
@ -2842,11 +2789,6 @@
|
|||
"resolved" "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz"
|
||||
"version" "3.1.1"
|
||||
|
||||
"follow-redirects@^1.10.0":
|
||||
"integrity" "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg=="
|
||||
"resolved" "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz"
|
||||
"version" "1.14.1"
|
||||
|
||||
"for-in@^1.0.2":
|
||||
"integrity" "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA="
|
||||
"resolved" "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz"
|
||||
|
@ -2932,25 +2874,6 @@
|
|||
"strip-ansi" "^3.0.1"
|
||||
"wide-align" "^1.1.0"
|
||||
|
||||
"gaxios@^4.0.0":
|
||||
"integrity" "sha512-pHplNbslpwCLMyII/lHPWFQbJWOX0B3R1hwBEOvzYi1GmdKZruuEHK4N9V6f7tf1EaPYyF80mui1+344p6SmLg=="
|
||||
"resolved" "https://registry.npmjs.org/gaxios/-/gaxios-4.3.0.tgz"
|
||||
"version" "4.3.0"
|
||||
dependencies:
|
||||
"abort-controller" "^3.0.0"
|
||||
"extend" "^3.0.2"
|
||||
"https-proxy-agent" "^5.0.0"
|
||||
"is-stream" "^2.0.0"
|
||||
"node-fetch" "^2.3.0"
|
||||
|
||||
"gcp-metadata@^4.2.0":
|
||||
"integrity" "sha512-L9XQUpvKJCM76YRSmcxrR4mFPzPGsgZUH+GgHMxAET8qc6+BhRJq63RLhWakgEO2KKVgeSDVfyiNjkGSADwNTA=="
|
||||
"resolved" "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.3.0.tgz"
|
||||
"version" "4.3.0"
|
||||
dependencies:
|
||||
"gaxios" "^4.0.0"
|
||||
"json-bigint" "^1.0.0"
|
||||
|
||||
"gensync@^1.0.0-beta.1":
|
||||
"integrity" "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="
|
||||
"resolved" "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz"
|
||||
|
@ -3076,37 +2999,6 @@
|
|||
"merge2" "^1.3.0"
|
||||
"slash" "^3.0.0"
|
||||
|
||||
"google-auth-library@^6.1.3":
|
||||
"integrity" "sha512-Q+ZjUEvLQj/lrVHF/IQwRo6p3s8Nc44Zk/DALsN+ac3T4HY/g/3rrufkgtl+nZ1TW7DNAw5cTChdVp4apUXVgQ=="
|
||||
"resolved" "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.1.6.tgz"
|
||||
"version" "6.1.6"
|
||||
dependencies:
|
||||
"arrify" "^2.0.0"
|
||||
"base64-js" "^1.3.0"
|
||||
"ecdsa-sig-formatter" "^1.0.11"
|
||||
"fast-text-encoding" "^1.0.0"
|
||||
"gaxios" "^4.0.0"
|
||||
"gcp-metadata" "^4.2.0"
|
||||
"gtoken" "^5.0.4"
|
||||
"jws" "^4.0.0"
|
||||
"lru-cache" "^6.0.0"
|
||||
|
||||
"google-p12-pem@^3.0.3":
|
||||
"integrity" "sha512-e9CwdD2QYkpvJsktki3Bm8P8FSGIneF+/42a9F9QHcQvJ73C2RoYZdrwRl6BhwksWtzl65gT4OnBROhUIFw95Q=="
|
||||
"resolved" "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.1.1.tgz"
|
||||
"version" "3.1.1"
|
||||
dependencies:
|
||||
"node-forge" "^0.10.0"
|
||||
|
||||
"google-spreadsheet@^3.1.15":
|
||||
"integrity" "sha512-S5477f3Gf3Mz6AXgCw7dbaYnzu5aHou1AX4sDqrGboQWnAytkxqJGKQiXN+zzRTTcYzSTJCe0g7KqCPZO9xiOw=="
|
||||
"resolved" "https://registry.npmjs.org/google-spreadsheet/-/google-spreadsheet-3.1.15.tgz"
|
||||
"version" "3.1.15"
|
||||
dependencies:
|
||||
"axios" "^0.21.1"
|
||||
"google-auth-library" "^6.1.3"
|
||||
"lodash" "^4.17.20"
|
||||
|
||||
"graceful-fs@^4.1.2", "graceful-fs@^4.1.6", "graceful-fs@^4.2.0", "graceful-fs@^4.2.4":
|
||||
"integrity" "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ=="
|
||||
"resolved" "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz"
|
||||
|
@ -3117,15 +3009,6 @@
|
|||
"resolved" "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz"
|
||||
"version" "1.3.0"
|
||||
|
||||
"gtoken@^5.0.4":
|
||||
"integrity" "sha512-mCcISYiaRZrJpfqOs0QWa6lfEM/C1V9ASkzFmuz43XBb5s1Vynh+CZy1ECeeJXVGx2PRByjYzb4Y4/zr1byr0w=="
|
||||
"resolved" "https://registry.npmjs.org/gtoken/-/gtoken-5.3.0.tgz"
|
||||
"version" "5.3.0"
|
||||
dependencies:
|
||||
"gaxios" "^4.0.0"
|
||||
"google-p12-pem" "^3.0.3"
|
||||
"jws" "^4.0.0"
|
||||
|
||||
"har-schema@^2.0.0":
|
||||
"integrity" "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
|
||||
"resolved" "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz"
|
||||
|
@ -3292,14 +3175,6 @@
|
|||
"resolved" "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz"
|
||||
"version" "1.0.0"
|
||||
|
||||
"https-proxy-agent@^5.0.0":
|
||||
"integrity" "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA=="
|
||||
"resolved" "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz"
|
||||
"version" "5.0.0"
|
||||
dependencies:
|
||||
"agent-base" "6"
|
||||
"debug" "4"
|
||||
|
||||
"human-signals@^1.1.1":
|
||||
"integrity" "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw=="
|
||||
"resolved" "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz"
|
||||
|
@ -4233,13 +4108,6 @@
|
|||
"resolved" "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz"
|
||||
"version" "2.5.2"
|
||||
|
||||
"json-bigint@^1.0.0":
|
||||
"integrity" "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ=="
|
||||
"resolved" "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz"
|
||||
"version" "1.0.0"
|
||||
dependencies:
|
||||
"bignumber.js" "^9.0.0"
|
||||
|
||||
"json-parse-even-better-errors@^2.3.0":
|
||||
"integrity" "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
|
||||
"resolved" "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz"
|
||||
|
@ -4311,23 +4179,6 @@
|
|||
"array-includes" "^3.1.2"
|
||||
"object.assign" "^4.1.2"
|
||||
|
||||
"jwa@^2.0.0":
|
||||
"integrity" "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA=="
|
||||
"resolved" "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz"
|
||||
"version" "2.0.0"
|
||||
dependencies:
|
||||
"buffer-equal-constant-time" "1.0.1"
|
||||
"ecdsa-sig-formatter" "1.0.11"
|
||||
"safe-buffer" "^5.0.1"
|
||||
|
||||
"jws@^4.0.0":
|
||||
"integrity" "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg=="
|
||||
"resolved" "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz"
|
||||
"version" "4.0.0"
|
||||
dependencies:
|
||||
"jwa" "^2.0.0"
|
||||
"safe-buffer" "^5.0.1"
|
||||
|
||||
"kind-of@^3.0.2", "kind-of@^3.0.3", "kind-of@^3.2.0":
|
||||
"integrity" "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ="
|
||||
"resolved" "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz"
|
||||
|
@ -4777,16 +4628,11 @@
|
|||
dependencies:
|
||||
"lodash.toarray" "^4.4.0"
|
||||
|
||||
"node-fetch@^2.3.0", "node-fetch@2.6.1":
|
||||
"node-fetch@2.6.1":
|
||||
"integrity" "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
|
||||
"resolved" "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz"
|
||||
"version" "2.6.1"
|
||||
|
||||
"node-forge@^0.10.0":
|
||||
"integrity" "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA=="
|
||||
"resolved" "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz"
|
||||
"version" "0.10.0"
|
||||
|
||||
"node-html-parser@1.4.9":
|
||||
"integrity" "sha512-UVcirFD1Bn0O+TSmloHeHqZZCxHjvtIeGdVdGMhyZ8/PWlEiZaZ5iJzR189yKZr8p0FXN58BUeC7RHRkf/KYGw=="
|
||||
"resolved" "https://registry.npmjs.org/node-html-parser/-/node-html-parser-1.4.9.tgz"
|
||||
|
|
Loading…
Reference in New Issue