Compare commits
203 Commits
Author | SHA1 | Date |
---|---|---|
Christian Landgren | a8281d4370 | |
Christian Landgren | 098bc544f2 | |
Christian Landgren | c16d60c2e2 | |
Christian Landgren | a7fa22cd54 | |
Christian Landgren | a7b9d81714 | |
Christian Landgren | b8ed895e52 | |
Christian Landgren | caafb59f8d | |
Christian Landgren | 81e448c035 | |
Christian Landgren | 62de54ef80 | |
Christian Landgren | d5e4bfd149 | |
Christian Landgren | 28e1481e3f | |
semantic-release-bot | f2a87117ba | |
Kajetan Kazimierczak | 6eb6d3a6e3 | |
Kajetan Kazimierczak | c0e6ce9e06 | |
Weblate (bot) | c9907a68b6 | |
Kajetan Kazimierczak | 320ab1f1f5 | |
Kajetan Kazimierczak | 7962234e26 | |
Kajetan Kazimierczak | b66f56b312 | |
Kajetan Kazimierczak | 442aad7fda | |
semantic-release-bot | 1f2c7ee762 | |
Kajetan Kazimierczak | d51cfe36fe | |
Kajetan Kazimierczak | c93e27bec0 | |
Kajetan Kazimierczak | 84ddda3f46 | |
semantic-release-bot | ab90b944ae | |
Sebastian Palmqvist | 34c376a727 | |
Sergio Avalos | ce535518a9 | |
Kajetan Kazimierczak | 09ae4f0eaa | |
Kajetan Kazimierczak | b5a2943fbb | |
Kajetan Kazimierczak | 4d3f940171 | |
Kajetan Kazimierczak | 6d9325c20c | |
Kajetan Kazimierczak | 27e9fb8cf7 | |
Kajetan Kazimierczak | c26b118ad0 | |
Kajetan Kazimierczak | 4e51bb8de7 | |
Kajetan Kazimierczak | 5d61cd150a | |
Kajetan Kazimierczak | 7e5013e7ca | |
semantic-release-bot | 394d0d973d | |
Kajetan Kazimierczak | e6ba622fa9 | |
semantic-release-bot | bee6d59283 | |
Mohammed Chammam | 20ae87fee1 | |
Christian Landgren | 565c27e6fb | |
semantic-release-bot | 6589d85ab0 | |
Sebastian Palmqvist | fef71c7923 | |
semantic-release-bot | ae5fd0624c | |
Oskar Strömberg | 61d47b4440 | |
semantic-release-bot | ee35ba7108 | |
Kajetan Kazimierczak | 25a2d7f3f5 | |
Kajetan Kazimierczak | 0db53ca046 | |
Kajetan Kazimierczak | f7493767b0 | |
Kajetan Kazimierczak | 7b3dfb91e7 | |
Kajetan Kazimierczak | 52c491213c | |
Viktor Sarström | 3a9c337bdd | |
Viktor Sarström | 68249e849a | |
semantic-release-bot | e77054fa60 | |
Viktor Sarström | 10e993ab9d | |
semantic-release-bot | 8a1123d640 | |
Kajetan Kazimierczak | 6d49e4767c | |
Kajetan Kazimierczak | ea6b385b4f | |
semantic-release-bot | 3acd27cc1f | |
Kajetan Kazimierczak | 7e8ee956f4 | |
Kajetan Kazimierczak | 7d8662ff09 | |
Theo Haglund | 1c0ea08056 | |
Lorentz Lasson | b1504fa181 | |
Kajetan Kazimierczak | e44c0cc392 | |
Theo O | aa9bb8c41a | |
Lage Linnarsson | b09d888f4a | |
Kajetan Kazimierczak | a314b7ab78 | |
Kajetan Kazimierczak | 23e6fe0919 | |
Kajetan Kazimierczak | 17b5d8ab40 | |
WhiredPlanck | 1684126446 | |
Kajetan Kazimierczak | e00bd6ad45 | |
Kajetan Kazimierczak | c7c170aa83 | |
Kajetan Kazimierczak | 8de7192003 | |
Luna Jernberg | 689f6c685d | |
Weblate (bot) | 63fbd3042a | |
Andreas Eriksson | 20ee509c28 | |
Weblate (bot) | 0508329998 | |
semantic-release-bot | 778823cc92 | |
Andreas Eriksson | 051df2da39 | |
semantic-release-bot | 46485dd3eb | |
Andreas Eriksson | 5577c7fe42 | |
semantic-release-bot | 1731d16c28 | |
Andreas Eriksson | 8724fa46b7 | |
Kajetan Kazimierczak | 022e422089 | |
Andreas Eriksson | dcb6d23976 | |
Andreas Eriksson | 498bdc500c | |
Andreas Eriksson | a63373caaf | |
Kajetan Kazimierczak | bc2625dc59 | |
Kajetan Kazimierczak | d8c6441c63 | |
Kajetan Kazimierczak | 8b2b680c17 | |
Kajetan Kazimierczak | 6806847d7d | |
Kajetan Kazimierczak | 8e3a9c1390 | |
Serhii Halchenko | bb9006b6ce | |
Andreas Eriksson | d1e659be42 | |
Kajetan Kazimierczak | 30b5bbb51e | |
Kajetan Kazimierczak | a6114608ed | |
Kajetan Kazimierczak | be22fd8cd3 | |
Kajetan Kazimierczak | 38cc7626ad | |
Kajetan Kazimierczak | 0c64f5ae35 | |
Kajetan Kazimierczak | 170b4da39a | |
Kajetan Kazimierczak | c5bec5f9ee | |
Kajetan Kazimierczak | 2b898854dd | |
Hosted Weblate | 0ae304633d | |
semantic-release-bot | f8de3cf741 | |
Kajetan Kazimierczak | bd02b378c0 | |
semantic-release-bot | f105629f58 | |
Kajetan Kazimierczak | 9e2f94d853 | |
Weblate (bot) | fd226ff397 | |
Kajetan Kazimierczak | c5302b0dff | |
Nuanla-ong Monfong | 72cc6efe33 | |
Adam Nybäck | 850831c16b | |
Nuanla-ong Monfong | dd4fa4e565 | |
Kajetan Kazimierczak | d9c62a6d91 | |
Adam Nybäck | a719fb5170 | |
Adam Nybäck | d566628189 | |
Adam Nybäck | a142468910 | |
Anna Babaryka | 4f26b541a4 | |
Marcus Dansarie | 88daf52014 | |
Lage Linnarsson | 0be6811dec | |
Lage Linnarsson | 9517a25353 | |
Lage Linnarsson | 162b0a2f0b | |
semantic-release-bot | 948568dd7c | |
Kajetan Kazimierczak | 1d1e8713f4 | |
semantic-release-bot | 1caf661895 | |
Kajetan Kazimierczak | 8d1ad62839 | |
Weblate (bot) | ac233ba33b | |
Andreas Eriksson | 623f7ac7ea | |
Andreas Eriksson | 92839bc292 | |
Andreas Eriksson | c510683373 | |
Andreas Eriksson | 7d3ad3c7a8 | |
Andreas Eriksson | 63de271323 | |
Andreas Eriksson | d3b347f6e3 | |
Andreas Eriksson | d8dbc1a7e1 | |
Andreas Eriksson | c31be2c704 | |
Andreas Eriksson | 55ab6bbf89 | |
Andreas Eriksson | 410b9ebe97 | |
Andreas Eriksson | c1de51242c | |
Andreas Eriksson | 963301b3f5 | |
semantic-release-bot | 1d4a34bf6c | |
Kajetan Kazimierczak | a40af3e94d | |
semantic-release-bot | 9e9833bc8a | |
Kajetan Kazimierczak | 93c1c2d0b0 | |
Christian Landgren | d636f787d6 | |
Rickard Natt och Dag | cd0a04ab83 | |
Viktor Sarström | 316dfed562 | |
webberian | c243c3e6f1 | |
semantic-release-bot | 15753fa2cc | |
Viktor Sarström | c202ca2af5 | |
Jonathan Edenström | e50b991f54 | |
Jonathan Edenström | 57f38f5b84 | |
Jonathan Edenström | e6f213a89f | |
Jonathan Edenström | ffd73e8362 | |
Erik Eng | 01a26b8dc3 | |
Erik Eng | 5debb9a555 | |
Erik Eng | 1598a7e9c8 | |
Erik Eng | 8033ce89ad | |
semantic-release-bot | 8d3293eec8 | |
Erik Hellman | f05ff64687 | |
Viktor Sarström | 22f57465fa | |
semantic-release-bot | 15d3d94182 | |
Kajetan Kazimierczak | 3f69bc89aa | |
semantic-release-bot | cce01b7242 | |
Kajetan Kazimierczak | f844a3cdd4 | |
Weblate (bot) | 66286ae9b8 | |
semantic-release-bot | 099d1facc6 | |
Kajetan Kazimierczak | 14ff985b0c | |
semantic-release-bot | 555ba0fb0f | |
Kajetan Kazimierczak | ed3a27bba1 | |
semantic-release-bot | 69e21ac68f | |
Kajetan Kazimierczak | b7dbd356c6 | |
semantic-release-bot | 0e95486e5d | |
Viktor Sarström | d24f65900e | |
Viktor Sarström | 2af189ef0f | |
Kajetan Kazimierczak | bce1165f30 | |
semantic-release-bot | fde9d95149 | |
Viktor Sarström | a85f37f148 | |
Andreas Eriksson | cc3fd8670c | |
Weblate (bot) | 86dfb4fb8d | |
semantic-release-bot | d61bc25468 | |
Andreas Eriksson | 7ada9945df | |
semantic-release-bot | ce01f54ead | |
Andreas Eriksson | cfa39de393 | |
Viktor Sarström | f7aa4675a4 | |
Viktor Sarström | 75cf634420 | |
semantic-release-bot | e4f4a83f1c | |
Viktor Sarström | 4e2e26b756 | |
Andreas Eriksson | 6fbbcc803e | |
Andreas Eriksson | 3b39c47230 | |
Emil Lindqvist | 601e92b230 | |
Emil Lindqvist | 5c477e1cf1 | |
Andreas Eriksson | 3359ba85f4 | |
semantic-release-bot | d66e87f5db | |
Andreas Eriksson | 66e7811b83 | |
semantic-release-bot | 7c017e460b | |
Viktor Sarström | 09558115d1 | |
Andreas Eriksson | df2806648a | |
semantic-release-bot | 3fbd08c794 | |
Christian Landgren | fce1d98847 | |
Viktor Sarström | 7bee08a550 | |
Andreas Eriksson | c92b352a6d | |
Viktor Sarström | 9754ba9194 | |
Viktor Sarström | 1589c88428 | |
Erik Eng | bf4ed46c2b | |
Erik Eng | 7fb6710ead |
|
@ -4,6 +4,8 @@ on:
|
|||
push:
|
||||
branches:
|
||||
- main
|
||||
paths-ignore:
|
||||
- 'apps/website/**'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
name: Docker
|
||||
|
||||
# Build to docker registry. This will trigger an update event from the Kubernetes cluster
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
# Publish semver tags as releases.
|
||||
tags: [ 'v*.*.*' ]
|
||||
paths:
|
||||
- 'apps/website/**'
|
||||
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
|
||||
env:
|
||||
# Use docker.io for Docker Hub if empty
|
||||
REGISTRY: ghcr.io
|
||||
# github.repository as <account>/<repo>
|
||||
IMAGE_NAME: ${{ github.repository }}
|
||||
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
# This is used to complete the identity challenge
|
||||
# with sigstore/fulcio when running outside of PRs.
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- run: |
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git config --global user.name "github-actions[bot]"
|
||||
if [[ $GITHUB_REF == refs/tags/production* ]]; then
|
||||
npm version major
|
||||
elif [[ $GITHUB_REF == refs/tags/staging* ]]; then
|
||||
npm version minor
|
||||
else
|
||||
npm version patch
|
||||
fi
|
||||
|
||||
- name: 📝 Get Current Version
|
||||
id: package-version
|
||||
uses: martinbeentjes/npm-get-version-action@main
|
||||
|
||||
# Set up BuildKit Docker container builder to be able to build
|
||||
# multi-platform images and export cache
|
||||
# https://github.com/docker/setup-buildx-action
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
|
||||
|
||||
# Login against a Docker registry except on PR
|
||||
# https://github.com/docker/login-action
|
||||
- name: Log into registry ${{ env.REGISTRY }}
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Build and push Docker image with Buildx (don't push on PR)
|
||||
# https://github.com/docker/build-push-action
|
||||
- name: Build and push Docker image
|
||||
id: build-and-push
|
||||
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
|
||||
with:
|
||||
context: apps/website
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: |
|
||||
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.package-version.outputs.current-version}},
|
||||
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
|
@ -108,4 +108,5 @@ secrets.yaml
|
|||
requests
|
||||
xcshareddata
|
||||
xcuserdata
|
||||
/.vs
|
||||
/.vs
|
||||
*.hprof
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
16.19.1
|
1328
CHANGELOG.md
1328
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
25
README.md
25
README.md
|
@ -8,9 +8,7 @@ Give us a ⭐ if you appreciate what we do!
|
|||
[![Translation status](https://hosted.weblate.org/widgets/skolplattformen/-/svg-badge.svg)](https://hosted.weblate.org/engage/skolplattformen/)
|
||||
[![Build Status](https://app.bitrise.io/app/8e56bd02bc602da5/status.svg?token=h8gI2dB_jXLurj9EO_fXWw)](https://app.bitrise.io/app/8e56bd02bc602da5)
|
||||
|
||||
We are parents who got fed up with Skolplattformen, the City of Stockholm's school administration platform. \ We reverse-engineered the platform's API to create a simpler, faster, more consistent, and secure experience for parents and guardians.
|
||||
P
|
||||
If you're simply looking for information about the app, our website can be found at [https://skolplattformen.org/](https://skolplattformen.org/). \
|
||||
We are parents who got fed up with Skolplattformen, the City of Stockholm's school administration platform. \ We reverse-engineered the platform's API to create a simpler, faster, more consistent, and secure experience for parents and guardians. If you're simply looking for information about the app, our website can be found at [https://skolplattformen.org/](https://skolplattformen.org/). \
|
||||
Check out [the changelog](CHANGELOG.md) to see what new features are added, and a list of fixed bugs.
|
||||
|
||||
This main repository for the project contains the source code for both the [app](apps/skolplattformen-app) and its [website](https://skolplattformen.org/). \
|
||||
|
@ -29,6 +27,7 @@ The respective README files there contain more detailed descriptions.
|
|||
* [api](#api)
|
||||
* [api-skolplattformen](#api-skolplattformen)
|
||||
* [api-hjarntorget](#api-hjarntorget)
|
||||
* [api-vklass](#api-vklass)
|
||||
* [curriculum](#curriculum)
|
||||
* [hooks](#hooks)
|
||||
* [Getting started with development](#getting-started-with-development)
|
||||
|
@ -46,8 +45,8 @@ The respective README files there contain more detailed descriptions.
|
|||
|
||||
The project consists of several apps and libraries inside [a NX](https://nx.dev/) monorepo.
|
||||
|
||||
### Apps
|
||||
/apps/ contains the application projects. This is the main entry point for a runnable application.
|
||||
### Apps
|
||||
/apps/ contains the application projects. This is the main entry point for a runnable application.
|
||||
|
||||
#### skolplattformen
|
||||
|
||||
|
@ -64,7 +63,7 @@ For more information, check out the [source code](apps/skolplattformen-app).
|
|||
The code for the website at https://skolplattformen.org/. It's built using Next.js.
|
||||
|
||||
For more information, check out the [source code](apps/website).
|
||||
### Libs
|
||||
### Libs
|
||||
|
||||
/libs/ contains the library projects. There are many different kinds of libraries, and each library defines its own external API so that boundaries between libraries remain clear.
|
||||
|
||||
|
@ -74,7 +73,11 @@ The base for all api implementations
|
|||
|
||||
#### api-hjarntorget
|
||||
|
||||
The implementation for the school platform in Gothenburg called Hjärntorget
|
||||
The implementation for the school platform in Gothenburg called Hjärntorget.
|
||||
|
||||
#### api-vklass
|
||||
|
||||
The implementation for the school platform Vklass.
|
||||
|
||||
#### api-skolplattformen
|
||||
|
||||
|
@ -84,6 +87,7 @@ It also makes it easier for others to develop their own applications for the Sko
|
|||
**Pro tip:** If you don't want the API to make requests to the back-end, you can turn on _fake mode_ to return static data instead. \
|
||||
Do so by logging in using 12121212121212 or 1212121212 as your personal identity number.
|
||||
Check out the documentation [here](libs/api-skolplattformen).
|
||||
|
||||
#### curriculum
|
||||
|
||||
Translations of curriculum codes (sv: ämneskoder på schemat) to clear text descriptions
|
||||
|
@ -95,7 +99,7 @@ Check out the documentation [here](libs/hooks).
|
|||
|
||||
## Getting started with Development
|
||||
|
||||
To clone and build the project, you first need to install [git](https://git-scm.com/), [node](https://nodejs.org/en/) and [yarn](https://classic.yarnpkg.com/lang/en/docs/install/).
|
||||
To clone and build the project, you first need to install [git](https://git-scm.com/), [node](https://nodejs.org/en/) and [yarn](https://classic.yarnpkg.com/lang/en/docs/install/).
|
||||
|
||||
Clone the repo with
|
||||
```bash
|
||||
|
@ -157,7 +161,7 @@ Once done, create a _pull request_ where you explain why we should incorporate y
|
|||
If you're new to GitHub, there's a number of excellent guides available, such as [this one on forking projects and making pull requests](https://guides.github.com/activities/forking/).
|
||||
|
||||
There are many ways to contribute to the project. \
|
||||
If you don't know how to program and want help, you can [file an issue](https://github.com/kolplattformen/skolplattformen-app/issues/new) to let us know when something isn't working properly. \
|
||||
If you don't know how to program and want help, you can [file an issue](https://github.com/kolplattformen/skolplattformen/issues/new) to let us know when something isn't working properly. \
|
||||
We're super duper happy for both issues and pull requests, and we try to answer all of them as soon as humanly possible.
|
||||
|
||||
Another way to contribute is by helping translate Öppna skolplattformen [on Hosted Weblate](https://hosted.weblate.org/engage/skolplattformen-app/) into a new language, or to improve existing translations.
|
||||
|
@ -180,7 +184,6 @@ If you're offended by this initiative, rest assured there is no reason to be —
|
|||
- [Christian Landgren](https://github.com/irony)
|
||||
- [Johan Öbrink](https://github.com/JohanObrink)
|
||||
- [Erik Hellman](https://github.com/ErikHellman)
|
||||
- [Rickard Natt och Dag](https://github.com/believer)
|
||||
- [Viktor Sarström](https://github.com/viktorlarsson)
|
||||
- [Andreas Eriksson](https://github.com/whyer)
|
||||
- [Kajetan Kazimierczak](https://github.com/kajetan-kazimierczak)
|
||||
|
@ -191,7 +194,7 @@ If you're offended by this initiative, rest assured there is no reason to be —
|
|||
|
||||
## License
|
||||
|
||||
Öppna skolplattformen is copyright 2020–2021 Not Free Beer AB.
|
||||
Öppna skolplattformen is copyright 2020–2024 Not Free Beer AB.
|
||||
|
||||
Licensed under the [Apache License, Version 2.0](LICENSE) (the "License"); you may use Öppna skolplattformen in compliance with the License. A copy of the License is included with this repository.
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# To run the app use the following command line.
|
||||
# The arg is your personal id number for bankId identification
|
||||
# Observe the trailing comma! (it must be there, nx thing)
|
||||
|
||||
nx serve api-test-app --args=19XXXXXXXX,
|
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
"root": "apps/api-test-app",
|
||||
"sourceRoot": "apps/api-test-app/src",
|
||||
"projectType": "application",
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@nrwl/node:build",
|
||||
"outputs": ["{options.outputPath}"],
|
||||
"options": {
|
||||
"outputPath": "dist/apps/api-test-app",
|
||||
"main": "apps/api-test-app/src/main.js",
|
||||
"tsConfig": "apps/api-test-app/tsconfig.app.json",
|
||||
"assets": ["apps/api-test-app/src/assets"]
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"optimization": true,
|
||||
"extractLicenses": true,
|
||||
"inspect": false,
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "apps/api-test-app/src/environments/environment.js",
|
||||
"with": "apps/api-test-app/src/environments/environment.prod.js"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"executor": "@nrwl/node:execute",
|
||||
"options": {
|
||||
"buildTarget": "api-test-app:build",
|
||||
"watch": false,
|
||||
"inspect": false
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nrwl/linter:eslint",
|
||||
"outputs": ["{options.outputFile}"],
|
||||
"options": {
|
||||
"lintFilePatterns": ["apps/api-test-app/**/*.js"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
}
|
|
@ -14,9 +14,13 @@ const path = require('path')
|
|||
const fs = require('fs')
|
||||
const HttpProxyAgent = require('https-proxy-agent')
|
||||
const agentWrapper = require('./app/agentFetchWrapper')
|
||||
const init = require('@skolplattformen/api-skolplattformen').default
|
||||
const initSkolplattformen = require('@skolplattformen/api-skolplattformen').default
|
||||
const initHjarntorget = require('@skolplattformen/api-hjarntorget').default
|
||||
|
||||
const [, , personalNumber, platform] = process.argv
|
||||
const isHjarntorget = platform && platform.startsWith('hj')
|
||||
const init = isHjarntorget ? initHjarntorget : initSkolplattformen;
|
||||
|
||||
const [, , personalNumber] = process.argv
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
|
||||
const cookieJar = new CookieJar()
|
||||
let bankIdUsed = false
|
||||
|
@ -136,10 +140,9 @@ async function Login(api) {
|
|||
try {
|
||||
console.log('Attempt to use saved session cookie to login')
|
||||
const rawContent = await readFile(`${recordFolder}/latestSessionCookie.txt`)
|
||||
const sessionCookie = JSON.parse(rawContent)
|
||||
|
||||
await api.setSessionCookie(`${sessionCookie.key}=${sessionCookie.value}`)
|
||||
|
||||
const sessionCookies = JSON.parse(rawContent)
|
||||
await api.setSessionCookie(`${sessionCookies[0].key}=${sessionCookies[0].value}`)
|
||||
|
||||
useBankId = false
|
||||
console.log('Login with old cookie succeeded')
|
||||
} catch (error) {
|
||||
|
@ -177,10 +180,12 @@ function ensureDirectoryExistence(filePath) {
|
|||
fs.mkdirSync(dirname)
|
||||
}
|
||||
|
||||
|
||||
function getSessionCookieFromCookieJar() {
|
||||
const cookies = cookieJar.getCookiesSync('https://etjanst.stockholm.se')
|
||||
const sessionCookie = cookies.find((c) => c.key === 'SMSESSION')
|
||||
return sessionCookie
|
||||
const cookieUrl = isHjarntorget ? 'https://hjarntorget.goteborg.se' : 'https://etjanst.stockholm.se'
|
||||
const cookies = cookieJar.getCookiesSync(cookieUrl)
|
||||
const sessionCookieKey = isHjarntorget ? 'JSESSIONID' : 'SMSESSION'
|
||||
return cookies.find(c => c.key === sessionCookieKey)
|
||||
}
|
||||
|
||||
const record = async (info, data) => {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
"rules": {"no-console":"warn"}
|
||||
},
|
||||
{
|
||||
"files": ["*.ts", "*.tsx"],
|
||||
|
|
|
@ -67,4 +67,4 @@ untyped-import
|
|||
untyped-type-import
|
||||
|
||||
[version]
|
||||
^0.137.0
|
||||
^0.158.0
|
||||
|
|
|
@ -19,13 +19,16 @@ import { translations } from './utils/translation'
|
|||
const reporter: Reporter | undefined = __DEV__
|
||||
? {
|
||||
log: (message: string) => console.log(message),
|
||||
error: (error: Error, label?: string) => console.error(label, error),
|
||||
error: (error: Error, label?: string) => console.log(label, error),
|
||||
}
|
||||
: undefined
|
||||
|
||||
if (__DEV__) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const DevMenu = require('react-native-dev-menu')
|
||||
DevMenu.addItem('Clear AsyncStorage from all contents', () =>
|
||||
AsyncStorage.clear().then(() => logAsyncStorage())
|
||||
)
|
||||
DevMenu.addItem('Log AsyncStorage contents', () => logAsyncStorage())
|
||||
}
|
||||
|
||||
|
|
|
@ -121,6 +121,11 @@ def jscFlavor = 'org.webkit:android-jsc:+'
|
|||
*/
|
||||
def enableHermes = project.ext.react.get("enableHermes", false);
|
||||
|
||||
/**
|
||||
* Architectures to build native code for in debug.
|
||||
*/
|
||||
def nativeArchitectures = project.getProperties().get("reactNativeDebugArchitectures")
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
|
||||
|
@ -134,7 +139,7 @@ android {
|
|||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 20000
|
||||
versionName "3.0.1"
|
||||
versionName "3.0.10"
|
||||
}
|
||||
splits {
|
||||
abi {
|
||||
|
@ -161,6 +166,12 @@ android {
|
|||
buildTypes {
|
||||
debug {
|
||||
signingConfig signingConfigs.debug
|
||||
if (nativeArchitectures) {
|
||||
ndk {
|
||||
abiFilters nativeArchitectures.split(',')
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
release {
|
||||
// Caution! In production, you need to generate your own keystore file.
|
||||
|
@ -195,7 +206,7 @@ dependencies {
|
|||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
|
||||
|
||||
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
|
||||
exclude group:'com.facebook.fbjni'
|
||||
exclude group:'com.facebook.fbjni'
|
||||
}
|
||||
|
||||
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
android:theme="@style/AppTheme">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
|
||||
android:launchMode="singleTask"
|
||||
|
|
|
@ -4,16 +4,17 @@ buildscript {
|
|||
ext {
|
||||
buildToolsVersion = "30.0.2"
|
||||
minSdkVersion = 21
|
||||
compileSdkVersion = 30
|
||||
targetSdkVersion = 30
|
||||
ndkVersion = "20.1.5948944"
|
||||
compileSdkVersion = 33
|
||||
targetSdkVersion = 33
|
||||
ndkVersion = "21.4.7075529"
|
||||
kotlinVersion = "1.6.0"
|
||||
}
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath("com.android.tools.build:gradle:4.2.1")
|
||||
classpath("com.android.tools.build:gradle:4.2.2")
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
|
@ -43,4 +44,4 @@ subprojects {
|
|||
force 'androidx.vectordrawable:vectordrawable-animated:1.1.0'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
#Thu Apr 01 10:00:57 CEST 2021
|
||||
FLIPPER_VERSION=0.93.0
|
||||
FLIPPER_VERSION=0.99.0
|
||||
android.enableJetifier=true
|
||||
android.useAndroidX=true
|
||||
org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M"
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 9.6 KiB |
|
@ -1,4 +1,5 @@
|
|||
import { RouteProp, useRoute } from '@react-navigation/native'
|
||||
import { NativeStackNavigationOptions } from '@react-navigation/native-stack'
|
||||
import { useUser } from '@skolplattformen/hooks'
|
||||
import {
|
||||
Button,
|
||||
|
@ -14,10 +15,10 @@ import Personnummer from 'personnummer'
|
|||
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 { defaultStackStyling } from '../design/navigationThemes'
|
||||
import usePersonalStorage from '../hooks/usePersonalStorage'
|
||||
import useSettingsStorage from '../hooks/useSettingsStorage'
|
||||
import { Layout as LayoutStyle, Sizing, Typography } from '../styles'
|
||||
import { studentName } from '../utils/peopleHelpers'
|
||||
import { useSMS } from '../utils/SMS'
|
||||
|
@ -47,7 +48,7 @@ export const absenceRouteOptions =
|
|||
const child = route.params.child
|
||||
return {
|
||||
...defaultStackStyling(darkMode),
|
||||
headerCenter: () => (
|
||||
headerTitle: () => (
|
||||
<NavigationTitle
|
||||
title={translate('abscense.title')}
|
||||
subtitle={studentName(child?.name)}
|
||||
|
@ -70,12 +71,11 @@ const Absence = () => {
|
|||
const route = useRoute<AbsenceRouteProps>()
|
||||
const { sendSMS } = useSMS()
|
||||
const { child } = route.params
|
||||
const [personalIdFromStorage, setPersonalIdInStorage] = usePersonalStorage(
|
||||
user,
|
||||
`@childssn.${child.id}`,
|
||||
''
|
||||
)
|
||||
const [personalIdentityNumber, setPersonalIdentityNumber] = React.useState('')
|
||||
const [personalIdsFromStorage, setPersonalIdInStorage] = useSettingsStorage(
|
||||
'childPersonalIdentityNumber'
|
||||
)
|
||||
const personalIdKey = `@childPersonalIdNumber.${child.id}`
|
||||
const minumumDate = moment().hours(8).minute(0)
|
||||
const maximumDate = moment().hours(17).minute(0)
|
||||
const styles = useStyleSheet(themedStyles)
|
||||
|
@ -96,15 +96,19 @@ const Absence = () => {
|
|||
)
|
||||
}
|
||||
|
||||
setPersonalIdInStorage(values.personalIdentityNumber)
|
||||
setPersonalIdentityNumber(values.personalIdentityNumber)
|
||||
const toStore = {
|
||||
...personalIdsFromStorage,
|
||||
...{ [personalIdKey]: personalIdNumber },
|
||||
}
|
||||
setPersonalIdInStorage(toStore)
|
||||
},
|
||||
[sendSMS, setPersonalIdInStorage]
|
||||
[personalIdKey, personalIdsFromStorage, sendSMS, setPersonalIdInStorage]
|
||||
)
|
||||
|
||||
React.useEffect(() => {
|
||||
const personalIdFromStorage = personalIdsFromStorage[personalIdKey] || ''
|
||||
setPersonalIdentityNumber(personalIdFromStorage || '')
|
||||
}, [child, personalIdFromStorage, user])
|
||||
}, [child, personalIdKey, personalIdsFromStorage, user])
|
||||
|
||||
const initialValues: AbsenceFormValues = {
|
||||
displayStartTimePicker: false,
|
||||
|
@ -187,9 +191,6 @@ const Absence = () => {
|
|||
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()}
|
||||
|
@ -221,7 +222,6 @@ const Absence = () => {
|
|||
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()}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { NativeStackNavigationOptions } from '@react-navigation/native-stack'
|
||||
import { StackNavigationProp } from '@react-navigation/stack'
|
||||
import {
|
||||
StyleService,
|
||||
|
@ -14,7 +15,6 @@ import {
|
|||
TouchableWithoutFeedback,
|
||||
View,
|
||||
} from 'react-native'
|
||||
import { NativeStackNavigationOptions } from 'react-native-screens/native-stack'
|
||||
import { useTranslation } from '../hooks/useTranslation'
|
||||
import { Layout as LayoutStyle, Sizing, Typography } from '../styles'
|
||||
import { fontSize } from '../styles/typography'
|
||||
|
@ -43,8 +43,8 @@ interface AuthProps {
|
|||
export const authRouteOptions = (): NativeStackNavigationOptions => {
|
||||
return {
|
||||
headerShown: false,
|
||||
replaceAnimation: 'push',
|
||||
stackAnimation: 'fade',
|
||||
animationTypeForReplace: 'push',
|
||||
animation: 'fade',
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { CalendarItem } from '@skolplattformen/api'
|
||||
import { useCalendar } from '@skolplattformen/hooks'
|
||||
import { CalendarItem } from '@skolplattformen/api'
|
||||
import {
|
||||
Divider,
|
||||
List,
|
||||
|
@ -10,8 +10,9 @@ import {
|
|||
} from '@ui-kitten/components'
|
||||
import moment from 'moment'
|
||||
import React from 'react'
|
||||
import { ListRenderItemInfo, View } from 'react-native'
|
||||
import { Typography } from '../styles'
|
||||
import { ListRenderItemInfo, RefreshControl, View } from 'react-native'
|
||||
import { Layout as LayoutStyle, Sizing, Typography } from '../styles'
|
||||
import { translate } from '../utils/translation'
|
||||
import { useChild } from './childContext.component'
|
||||
import { CalendarOutlineIcon } from './icon.component'
|
||||
import { SaveToCalendar } from './saveToCalendar.component'
|
||||
|
@ -19,7 +20,7 @@ import { Week } from './week.component'
|
|||
|
||||
export const Calendar = () => {
|
||||
const child = useChild()
|
||||
const { data } = useCalendar(child)
|
||||
const { data, status, reload } = useCalendar(child)
|
||||
const styles = useStyleSheet(themedStyles)
|
||||
|
||||
const formatStartDate = (startDate: moment.MomentInput) => {
|
||||
|
@ -28,37 +29,55 @@ export const Calendar = () => {
|
|||
'll'
|
||||
)} • ${date.fromNow()}`
|
||||
|
||||
// Hack to remove yarn if it is this year
|
||||
// Hack to remove year if it is this year
|
||||
const currentYear = moment().year().toString(10)
|
||||
return output.replace(currentYear, '')
|
||||
}
|
||||
|
||||
const sortedData = () => {
|
||||
if (!data) return []
|
||||
|
||||
return data.sort((a, b) =>
|
||||
a.startDate && b.startDate ? a.startDate.localeCompare(b.startDate) : 0
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Week child={child} />
|
||||
{data && data.length > 0 && (
|
||||
<List
|
||||
data={data.sort((a, b) =>
|
||||
a.startDate && b.startDate
|
||||
? a.startDate.localeCompare(b.startDate)
|
||||
: 0
|
||||
)}
|
||||
ItemSeparatorComponent={Divider}
|
||||
renderItem={({ item }: ListRenderItemInfo<CalendarItem>) => (
|
||||
<ListItem
|
||||
disabled={true}
|
||||
title={`${item.title}`}
|
||||
description={(props) => (
|
||||
<Text style={[props?.style, styles.description]}>
|
||||
{formatStartDate(item.startDate)}
|
||||
</Text>
|
||||
)}
|
||||
accessoryLeft={CalendarOutlineIcon}
|
||||
accessoryRight={() => <SaveToCalendar event={item} />}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
<List
|
||||
data={sortedData()}
|
||||
ItemSeparatorComponent={Divider}
|
||||
ListEmptyComponent={
|
||||
<View style={styles.emptyState}>
|
||||
<Text style={styles.emptyStateHeadline} category="h6">
|
||||
{translate('calender.emptyHeadline')}
|
||||
</Text>
|
||||
<Text style={styles.emptyStateDescription}>
|
||||
{translate('calender.emptyText')}
|
||||
</Text>
|
||||
</View>
|
||||
}
|
||||
renderItem={({ item }: ListRenderItemInfo<CalendarItem>) => (
|
||||
<ListItem
|
||||
disabled={true}
|
||||
title={`${item.title}`}
|
||||
description={(props) => (
|
||||
<Text style={[props?.style, styles.description]}>
|
||||
{formatStartDate(item.startDate)}
|
||||
</Text>
|
||||
)}
|
||||
accessoryLeft={CalendarOutlineIcon}
|
||||
accessoryRight={() => <SaveToCalendar event={item} />}
|
||||
/>
|
||||
)}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
refreshing={status === 'loading'}
|
||||
onRefresh={reload}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
@ -73,4 +92,18 @@ const themedStyles = StyleService.create({
|
|||
...Typography.fontSize.xs,
|
||||
color: 'text-hint-color',
|
||||
},
|
||||
emptyState: {
|
||||
...LayoutStyle.center,
|
||||
...LayoutStyle.flex.full,
|
||||
},
|
||||
emptyStateHeadline: {
|
||||
...Typography.align.center,
|
||||
margin: Sizing.t4,
|
||||
},
|
||||
emptyStateDescription: {
|
||||
...Typography.align.center,
|
||||
lineHeight: 21,
|
||||
paddingHorizontal: Sizing.t3,
|
||||
margin: Sizing.t4,
|
||||
},
|
||||
})
|
||||
|
|
|
@ -5,24 +5,24 @@ import {
|
|||
useNavigation,
|
||||
useRoute,
|
||||
} from '@react-navigation/native'
|
||||
import { NativeStackNavigationOptions } from '@react-navigation/native-stack'
|
||||
import { StackNavigationProp } from '@react-navigation/stack'
|
||||
import { Icon } from '@ui-kitten/components'
|
||||
import React, { useEffect } from 'react'
|
||||
import { StyleProp, TextProps } from 'react-native'
|
||||
import { NativeStackNavigationOptions } from 'react-native-screens/native-stack'
|
||||
import { defaultStackStyling } from '../design/navigationThemes'
|
||||
import { useFeature } from '../hooks/useFeature'
|
||||
import { studentName } from '../utils/peopleHelpers'
|
||||
import { translate } from '../utils/translation'
|
||||
import { Calendar } from './calendar.component'
|
||||
import { ChildProvider } from './childContext.component'
|
||||
import { Classmates } from './classmates.component'
|
||||
import { Menu } from './menu.component'
|
||||
import { RootStackParamList } from './navigation.component'
|
||||
import { NavigationTitle } from './navigationTitle.component'
|
||||
import { NewsList } from './newsList.component'
|
||||
import { NotificationsList } from './notificationsList.component'
|
||||
import { Classmates } from './classmates.component'
|
||||
import { TabBarLabel } from './tabBarLabel.component'
|
||||
import { useFeature } from '../hooks/useFeature'
|
||||
|
||||
type ChildNavigationProp = StackNavigationProp<RootStackParamList, 'Child'>
|
||||
type ChildRouteProps = RouteProp<RootStackParamList, 'Child'>
|
||||
|
@ -95,42 +95,54 @@ const TabNavigator = ({
|
|||
<Screen
|
||||
name="News"
|
||||
component={NewsScreen}
|
||||
options={{ title: translate('navigation.news') }}
|
||||
options={{ title: translate('navigation.news'), headerShown: false }}
|
||||
/>
|
||||
)}
|
||||
{screenSettings.NOTIFICATIONS_SCREEN && (
|
||||
<Screen
|
||||
name="Notifications"
|
||||
component={NotificationsScreen}
|
||||
options={{ title: translate('navigation.notifications') }}
|
||||
options={{
|
||||
title: translate('navigation.notifications'),
|
||||
headerShown: false,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{screenSettings.CALENDER_SCREEN && (
|
||||
<Screen
|
||||
name="Calendar"
|
||||
component={CalendarScreen}
|
||||
options={{ title: translate('navigation.calender') }}
|
||||
options={{
|
||||
title: translate('navigation.calender'),
|
||||
headerShown: false,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{screenSettings.MENU_SCREEN && (
|
||||
<Screen
|
||||
name="Menu"
|
||||
component={MenuScreen}
|
||||
options={{ title: translate('navigation.menu') }}
|
||||
options={{ title: translate('navigation.menu'), headerShown: false }}
|
||||
/>
|
||||
)}
|
||||
{screenSettings.CLASSMATES_SCREEN && (
|
||||
<Screen
|
||||
name="Classmates"
|
||||
component={ClassmatesScreen}
|
||||
options={{ title: translate('navigation.classmates') }}
|
||||
options={{
|
||||
title: translate('navigation.classmates'),
|
||||
headerShown: false,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Navigator>
|
||||
)
|
||||
|
||||
const getHeaderTitle = (route: any) => {
|
||||
const routeName = getFocusedRouteNameFromRoute(route) ?? 'News'
|
||||
const routeName =
|
||||
getFocusedRouteNameFromRoute(route) ??
|
||||
route.params.initialRouteName ??
|
||||
'News'
|
||||
return getRouteTitleFromName(routeName)
|
||||
}
|
||||
|
||||
|
@ -162,7 +174,7 @@ export const childRouteOptions =
|
|||
|
||||
return {
|
||||
...defaultStackStyling(darkMode),
|
||||
headerCenter: () => (
|
||||
headerTitle: () => (
|
||||
<NavigationTitle
|
||||
title={getHeaderTitle(route)}
|
||||
subtitle={studentName(child?.name)}
|
||||
|
|
|
@ -16,11 +16,12 @@ import {
|
|||
Text,
|
||||
useStyleSheet,
|
||||
} from '@ui-kitten/components'
|
||||
import moment from 'moment'
|
||||
import React from 'react'
|
||||
import { TouchableOpacity, useColorScheme, View } from 'react-native'
|
||||
import moment, { Moment } from 'moment'
|
||||
import React, { useEffect } from 'react'
|
||||
import { Pressable, useColorScheme, View } from 'react-native'
|
||||
import { useTranslation } from '../hooks/useTranslation'
|
||||
import { Colors, Layout, Sizing } from '../styles'
|
||||
import { getMeaningfulStartingDate } from '../utils/calendarHelpers'
|
||||
import { studentName } from '../utils/peopleHelpers'
|
||||
import { DaySummary } from './daySummary.component'
|
||||
import { AlertIcon, RightArrowIcon } from './icon.component'
|
||||
|
@ -30,13 +31,20 @@ import { StudentAvatar } from './studentAvatar.component'
|
|||
interface ChildListItemProps {
|
||||
child: Child
|
||||
color: string
|
||||
updated: string
|
||||
currentDate?: Moment
|
||||
}
|
||||
type ChildListItemNavigationProp = StackNavigationProp<
|
||||
RootStackParamList,
|
||||
'Children'
|
||||
>
|
||||
|
||||
export const ChildListItem = ({ child, color }: ChildListItemProps) => {
|
||||
export const ChildListItem = ({
|
||||
child,
|
||||
color,
|
||||
updated,
|
||||
currentDate = moment(),
|
||||
}: ChildListItemProps) => {
|
||||
// Forces rerender when child.id changes
|
||||
React.useEffect(() => {
|
||||
// noop
|
||||
|
@ -44,17 +52,36 @@ export const ChildListItem = ({ child, color }: ChildListItemProps) => {
|
|||
|
||||
const navigation = useNavigation<ChildListItemNavigationProp>()
|
||||
const { t } = useTranslation()
|
||||
const { data: notifications } = useNotifications(child)
|
||||
const { data: news } = useNews(child)
|
||||
const { data: classmates } = useClassmates(child)
|
||||
const { data: calendar } = useCalendar(child)
|
||||
const { data: menu } = useMenu(child)
|
||||
const { data: schedule } = useSchedule(
|
||||
const { data: notifications, reload: notificationsReload } =
|
||||
useNotifications(child)
|
||||
const { data: news, status: newsStatus, reload: newsReload } = useNews(child)
|
||||
const { data: classmates, reload: classmatesReload } = useClassmates(child)
|
||||
const { data: calendar, reload: calendarReload } = useCalendar(child)
|
||||
const { data: menu, reload: menuReload } = useMenu(child)
|
||||
const { data: schedule, reload: scheduleReload } = useSchedule(
|
||||
child,
|
||||
moment().toISOString(),
|
||||
moment().add(7, 'days').toISOString()
|
||||
moment(currentDate).toISOString(),
|
||||
moment(currentDate).add(7, 'days').toISOString()
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
// Do not refresh if updated is empty (first render of component)
|
||||
if (updated === '') return
|
||||
|
||||
newsReload()
|
||||
classmatesReload()
|
||||
notificationsReload()
|
||||
calendarReload()
|
||||
menuReload()
|
||||
scheduleReload()
|
||||
|
||||
// Without eslint-disable below we get into a forever loop
|
||||
// because the function pointers to reload functions change on every reload.
|
||||
// I do not know a workaround for this.
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [updated])
|
||||
|
||||
const notificationsThisWeek = notifications.filter(
|
||||
({ dateCreated, dateModified }) => {
|
||||
const date = dateModified || dateCreated
|
||||
|
@ -63,8 +90,8 @@ export const ChildListItem = ({ child, color }: ChildListItemProps) => {
|
|||
)
|
||||
|
||||
const newsThisWeek = news.filter(({ modified, published }) => {
|
||||
const date = modified || published
|
||||
return date ? moment(date).isSame(moment(), 'week') : false
|
||||
const newsDate = modified || published
|
||||
return newsDate ? moment(newsDate).isSame(currentDate, 'week') : false
|
||||
})
|
||||
|
||||
const scheduleAndCalendarThisWeek = [
|
||||
|
@ -73,14 +100,14 @@ export const ChildListItem = ({ child, color }: ChildListItemProps) => {
|
|||
].filter(({ startDate }) =>
|
||||
startDate
|
||||
? moment(startDate).isBetween(
|
||||
moment().startOf('day'),
|
||||
moment().add(7, 'days')
|
||||
moment(currentDate).startOf('day'),
|
||||
moment(currentDate).add(7, 'days')
|
||||
)
|
||||
: false
|
||||
)
|
||||
|
||||
const displayDate = (date: moment.MomentInput) => {
|
||||
return moment(date).fromNow()
|
||||
const displayDate = (inputDate: moment.MomentInput) => {
|
||||
return moment(inputDate).fromNow()
|
||||
}
|
||||
|
||||
const getClassName = () => {
|
||||
|
@ -118,13 +145,27 @@ export const ChildListItem = ({ child, color }: ChildListItemProps) => {
|
|||
const className = getClassName()
|
||||
const styles = useStyleSheet(themeStyles)
|
||||
const isDarkMode = useColorScheme() === 'dark'
|
||||
const meaningfulStartingDate = getMeaningfulStartingDate(currentDate)
|
||||
|
||||
// Hide menu if we want to show monday but it is not monday yet.
|
||||
// The menu for next week is not available until monday
|
||||
const shouldShowLunchMenu =
|
||||
menu[meaningfulStartingDate.isoWeekday() - 1] &&
|
||||
!(
|
||||
meaningfulStartingDate.isoWeekday() === 1 &&
|
||||
currentDate.isoWeekday() !== 1
|
||||
)
|
||||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
onPress={() => navigation.navigate('Child', { child, color })}
|
||||
>
|
||||
<View style={styles.card}>
|
||||
<View style={styles.cardHeader}>
|
||||
<View style={styles.card}>
|
||||
<View style={styles.cardHeader}>
|
||||
<Pressable
|
||||
style={({ pressed }) => [
|
||||
styles.cardHeaderLeft || {},
|
||||
{ opacity: pressed ? 0.5 : 1 },
|
||||
]}
|
||||
onPress={() => navigation.navigate('Child', { child, color })}
|
||||
>
|
||||
<View style={styles.cardHeaderLeft}>
|
||||
<StudentAvatar name={studentName(child.name)} color={color} />
|
||||
<View style={styles.cardHeaderText}>
|
||||
|
@ -141,13 +182,37 @@ export const ChildListItem = ({ child, color }: ChildListItemProps) => {
|
|||
name="star"
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
<DaySummary child={child} />
|
||||
</Pressable>
|
||||
</View>
|
||||
|
||||
<Pressable
|
||||
style={({ pressed }) => ['' || {}, { opacity: pressed ? 0.5 : 1 }]}
|
||||
onPress={() =>
|
||||
navigation.navigate('Child', {
|
||||
child,
|
||||
color,
|
||||
initialRouteName: 'Calendar',
|
||||
})
|
||||
}
|
||||
>
|
||||
<DaySummary child={child} date={meaningfulStartingDate} />
|
||||
{scheduleAndCalendarThisWeek.slice(0, 3).map((calendarItem, i) => (
|
||||
<Text category="p1" key={i}>
|
||||
{`${calendarItem.title} (${displayDate(calendarItem.startDate)})`}
|
||||
</Text>
|
||||
))}
|
||||
</Pressable>
|
||||
|
||||
<Pressable
|
||||
style={({ pressed }) => ['' || {}, { opacity: pressed ? 0.5 : 1 }]}
|
||||
onPress={() =>
|
||||
navigation.navigate('Child', {
|
||||
child,
|
||||
color,
|
||||
initialRouteName: 'News',
|
||||
})
|
||||
}
|
||||
>
|
||||
<Text category="c2" style={styles.label}>
|
||||
{t('navigation.news')}
|
||||
</Text>
|
||||
|
@ -156,43 +221,58 @@ export const ChildListItem = ({ child, color }: ChildListItemProps) => {
|
|||
{notification.message}
|
||||
</Text>
|
||||
))}
|
||||
|
||||
{newsThisWeek.slice(0, 3).map((newsItem, i) => (
|
||||
<Text category="p1" key={i}>
|
||||
{newsItem.header ?? ''}
|
||||
</Text>
|
||||
))}
|
||||
{scheduleAndCalendarThisWeek.length ||
|
||||
notificationsThisWeek.length ||
|
||||
newsThisWeek.length ? null : (
|
||||
<Text category="p1" style={styles.noNewNewsItemsText}>
|
||||
{t('news.noNewNewsItemsThisWeek')}
|
||||
</Text>
|
||||
)}
|
||||
</Pressable>
|
||||
|
||||
{!menu[moment().isoWeekday() - 1] ? null : (
|
||||
<>
|
||||
<Text category="c2" style={styles.label}>
|
||||
{t('schedule.lunch')}
|
||||
</Text>
|
||||
<Text>{menu[moment().isoWeekday() - 1]?.description}</Text>
|
||||
</>
|
||||
)}
|
||||
<View style={styles.itemFooterAbsence}>
|
||||
<Button
|
||||
accessible
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={`${child.name}, ${t('abscense.title')}`}
|
||||
appearance="ghost"
|
||||
accessoryLeft={AlertIcon}
|
||||
status="primary"
|
||||
style={styles.absenceButton}
|
||||
onPress={() => navigation.navigate('Absence', { child })}
|
||||
>
|
||||
{t('abscense.title')}
|
||||
</Button>
|
||||
</View>
|
||||
{scheduleAndCalendarThisWeek.length ||
|
||||
notificationsThisWeek.length ||
|
||||
newsThisWeek.length ? null : (
|
||||
<Text category="p1" style={styles.noNewNewsItemsText}>
|
||||
{t('news.noNewNewsItemsThisWeek')}
|
||||
</Text>
|
||||
)}
|
||||
{shouldShowLunchMenu ? (
|
||||
<Pressable
|
||||
style={({ pressed }) => ['' || {}, { opacity: pressed ? 0.5 : 1 }]}
|
||||
onPress={() =>
|
||||
navigation.navigate('Child', {
|
||||
child,
|
||||
color,
|
||||
initialRouteName: 'Menu',
|
||||
})
|
||||
}
|
||||
>
|
||||
<Text category="c2" style={styles.label}>
|
||||
{meaningfulStartingDate.format(
|
||||
'[' + t('schedule.lunch') + '] dddd'
|
||||
)}
|
||||
</Text>
|
||||
<Text>
|
||||
{menu[meaningfulStartingDate.isoWeekday() - 1]?.description}
|
||||
</Text>
|
||||
</Pressable>
|
||||
) : null}
|
||||
|
||||
<View style={styles.itemFooter}>
|
||||
<Button
|
||||
accessible
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={`${child.name}, ${t('abscense.title')}`}
|
||||
appearance="ghost"
|
||||
accessoryLeft={AlertIcon}
|
||||
status="primary"
|
||||
style={styles.absenceButton}
|
||||
onPress={() => navigation.navigate('Absence', { child })}
|
||||
>
|
||||
{t('abscense.title')}
|
||||
</Button>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -232,15 +312,16 @@ const themeStyles = StyleService.create({
|
|||
},
|
||||
itemFooter: {
|
||||
...Layout.flex.row,
|
||||
marginTop: Sizing.t4,
|
||||
},
|
||||
itemFooterAbsence: {
|
||||
...Layout.mainAxis.flexStart,
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'flex-end',
|
||||
marginTop: Sizing.t4,
|
||||
},
|
||||
absenceButton: {
|
||||
marginLeft: -20,
|
||||
},
|
||||
itemFooterSpinner: {
|
||||
alignSelf: 'flex-end',
|
||||
},
|
||||
item: {
|
||||
marginRight: 12,
|
||||
paddingHorizontal: 2,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { useNavigation } from '@react-navigation/core'
|
||||
import { NavigationProp, useNavigation } from '@react-navigation/core'
|
||||
import { NativeStackNavigationOptions } from '@react-navigation/native-stack'
|
||||
import { Child } from '@skolplattformen/api'
|
||||
import { useApi, useChildList } from '@skolplattformen/hooks'
|
||||
import {
|
||||
|
@ -10,7 +11,8 @@ import {
|
|||
TopNavigationAction,
|
||||
useStyleSheet,
|
||||
} from '@ui-kitten/components'
|
||||
import React, { useCallback, useEffect } from 'react'
|
||||
import moment from 'moment'
|
||||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
import {
|
||||
Image,
|
||||
ImageStyle,
|
||||
|
@ -18,13 +20,13 @@ import {
|
|||
ListRenderItemInfo,
|
||||
View,
|
||||
} from 'react-native'
|
||||
import { NativeStackNavigationOptions } from 'react-native-screens/native-stack'
|
||||
import { defaultStackStyling } from '../design/navigationThemes'
|
||||
import AppStorage from '../services/appStorage'
|
||||
import { Colors, Layout as LayoutStyle, Sizing, Typography } from '../styles'
|
||||
import { Layout as LayoutStyle, Sizing, Typography } from '../styles'
|
||||
import { translate } from '../utils/translation'
|
||||
import { ChildListItem } from './childListItem.component'
|
||||
import { SettingsIcon } from './icon.component'
|
||||
import { RefreshIcon, SettingsIcon } from './icon.component'
|
||||
import { RootStackParamList } from './navigation.component'
|
||||
|
||||
const colors = ['primary', 'success', 'info', 'warning', 'danger']
|
||||
|
||||
|
@ -34,20 +36,23 @@ export const childenRouteOptions =
|
|||
...defaultStackStyling(darkMode),
|
||||
title: translate('children.title'),
|
||||
headerLargeTitle: true,
|
||||
headerLargeTitleHideShadow: true,
|
||||
headerLargeTitleShadowVisible: false,
|
||||
}
|
||||
}
|
||||
|
||||
export const Children = () => {
|
||||
const styles = useStyleSheet(themedStyles)
|
||||
|
||||
const navigation = useNavigation()
|
||||
const navigation = useNavigation<NavigationProp<RootStackParamList>>()
|
||||
|
||||
const { api } = useApi()
|
||||
const { data: childList, status, reload } = useChildList()
|
||||
const reloadChildren = () => {
|
||||
const reloadChildren = useCallback(() => {
|
||||
reload()
|
||||
}
|
||||
setUpdated(moment().toISOString())
|
||||
}, [reload])
|
||||
|
||||
const [updatedAt, setUpdated] = useState('')
|
||||
|
||||
const logout = useCallback(() => {
|
||||
AppStorage.clearTemporaryItems().then(() => api.logout())
|
||||
|
@ -63,82 +68,87 @@ export const Children = () => {
|
|||
/>
|
||||
)
|
||||
},
|
||||
headerRight: () => {
|
||||
return (
|
||||
<TopNavigationAction
|
||||
icon={RefreshIcon}
|
||||
onPress={() => reloadChildren()}
|
||||
accessibilityHint="Reload"
|
||||
accessibilityLabel="Reload"
|
||||
/>
|
||||
)
|
||||
},
|
||||
})
|
||||
}, [navigation])
|
||||
}, [navigation, reloadChildren])
|
||||
|
||||
// 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 (
|
||||
<>
|
||||
{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}>
|
||||
return 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/girls.png')}
|
||||
style={styles.loadingImage as ImageStyle}
|
||||
source={require('../assets/children.png')}
|
||||
style={styles.emptyStateImage 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.viewStatus')}
|
||||
</Button>
|
||||
<Button onPress={() => logout()}>
|
||||
{translate('general.logout')}
|
||||
</Button>
|
||||
</View>
|
||||
</View>
|
||||
) : (
|
||||
<View style={styles.loadingMessage}>
|
||||
<Spinner size="large" status="primary" />
|
||||
<Text category="h1" style={styles.loadingText}>
|
||||
{translate('general.loading')}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
}
|
||||
renderItem={({ item: child, index }: ListRenderItemInfo<Child>) => (
|
||||
<ChildListItem
|
||||
child={child}
|
||||
color={colors[index % colors.length]}
|
||||
updated={updatedAt}
|
||||
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.viewStatus')}
|
||||
</Button>
|
||||
<Button onPress={() => logout()}>
|
||||
{translate('general.logout')}
|
||||
</Button>
|
||||
</View>
|
||||
</View>
|
||||
) : (
|
||||
<View style={styles.loadingMessage}>
|
||||
<Spinner size="large" status="primary" />
|
||||
<Text category="h1" style={styles.loadingText}>
|
||||
{translate('general.loading')}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
</>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -187,7 +197,6 @@ const themedStyles = StyleService.create({
|
|||
emptyState: {
|
||||
...LayoutStyle.center,
|
||||
...LayoutStyle.flex.full,
|
||||
backgroundColor: Colors.neutral.white,
|
||||
paddingHorizontal: Sizing.t5,
|
||||
},
|
||||
emptyStateDescription: {
|
||||
|
|
|
@ -9,7 +9,7 @@ import {
|
|||
Text,
|
||||
} from '@ui-kitten/components'
|
||||
import React from 'react'
|
||||
import { ListRenderItemInfo, StyleSheet } from 'react-native'
|
||||
import { ListRenderItemInfo, RefreshControl, StyleSheet } from 'react-native'
|
||||
import { fullName, guardians, sortByFirstName } from '../utils/peopleHelpers'
|
||||
import { translate } from '../utils/translation'
|
||||
import { useChild } from './childContext.component'
|
||||
|
@ -22,7 +22,7 @@ interface ClassmatesProps {
|
|||
export const Classmates = () => {
|
||||
const child = useChild()
|
||||
|
||||
const { data } = useClassmates(child)
|
||||
const { data, status, reload } = useClassmates(child)
|
||||
const renderItemIcon = (props: IconProps) => (
|
||||
<Icon {...props} name="people-outline" />
|
||||
)
|
||||
|
@ -60,6 +60,9 @@ export const Classmates = () => {
|
|||
}
|
||||
renderItem={renderItem}
|
||||
contentContainerStyle={styles.contentContainer}
|
||||
refreshControl={
|
||||
<RefreshControl refreshing={status === 'loading'} onRefresh={reload} />
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import { Child } from '@skolplattformen/api'
|
|||
import { useTimetable } from '@skolplattformen/hooks'
|
||||
import { StyleService, Text, useStyleSheet } from '@ui-kitten/components'
|
||||
import moment, { Moment } from 'moment'
|
||||
import React from 'react'
|
||||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
import { View } from 'react-native'
|
||||
import { LanguageService } from '../services/languageService'
|
||||
import { translate } from '../utils/translation'
|
||||
|
@ -12,9 +12,17 @@ interface DaySummaryProps {
|
|||
date?: Moment
|
||||
}
|
||||
|
||||
export const DaySummary = ({ child, date = moment() }: DaySummaryProps) => {
|
||||
const capitalizeFirstLetter = (string) => {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1)
|
||||
}
|
||||
|
||||
export const DaySummary = ({
|
||||
child,
|
||||
date: currentDate = moment(),
|
||||
}: DaySummaryProps) => {
|
||||
const styles = useStyleSheet(themedStyles)
|
||||
const [year, week] = [moment().isoWeekYear(), moment().isoWeek()]
|
||||
const [week, year] = [currentDate.isoWeek(), currentDate.isoWeekYear()]
|
||||
|
||||
const { data: weekLessons } = useTimetable(
|
||||
child,
|
||||
week,
|
||||
|
@ -23,8 +31,8 @@ export const DaySummary = ({ child, date = moment() }: DaySummaryProps) => {
|
|||
)
|
||||
|
||||
const lessons = weekLessons
|
||||
.filter((lesson) => lesson.dayOfWeek === date.isoWeekday())
|
||||
.sort((a, b) => a.dateStart.localeCompare(b.dateStart))
|
||||
.filter((lesson) => lesson.dayOfWeek === currentDate.isoWeekday())
|
||||
.sort((a, b) => a.timeStart.localeCompare(b.timeStart))
|
||||
|
||||
if (lessons.length <= 0) {
|
||||
return null
|
||||
|
@ -34,6 +42,11 @@ export const DaySummary = ({ child, date = moment() }: DaySummaryProps) => {
|
|||
|
||||
return (
|
||||
<View>
|
||||
{moment().weekday() !== currentDate.weekday() ? (
|
||||
<Text category="c2" style={styles.weekday}>
|
||||
{capitalizeFirstLetter(currentDate.format('dddd'))}
|
||||
</Text>
|
||||
) : null}
|
||||
<View style={styles.summary}>
|
||||
<View style={styles.part}>
|
||||
<View>
|
||||
|
@ -49,19 +62,27 @@ export const DaySummary = ({ child, date = moment() }: DaySummaryProps) => {
|
|||
{translate('schedule.end')}
|
||||
</Text>
|
||||
<Text category="h5">
|
||||
{lessons[lessons.length - 1].timeEnd.slice(0, 5)}
|
||||
{lessons
|
||||
.sort((a, b) => a.timeEnd.localeCompare(b.timeEnd))
|
||||
[lessons.length - 1].timeEnd.slice(0, 5)}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.part}>
|
||||
<View>
|
||||
<Text category="c2" style={styles.label}>
|
||||
|
||||
</Text>
|
||||
<Text category="s2">
|
||||
{gymBag
|
||||
? ` 🤼♀️ ${translate('schedule.gymBag', {
|
||||
defaultValue: 'Gympapåse',
|
||||
})}`
|
||||
: ''}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<Text category="s2">
|
||||
{gymBag
|
||||
? ` 🤼♀️ ${translate('schedule.gymBag', {
|
||||
defaultValue: 'Gympapåse',
|
||||
})}`
|
||||
: ''}
|
||||
</Text>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
@ -76,4 +97,11 @@ const themedStyles = StyleService.create({
|
|||
label: {
|
||||
marginTop: 10,
|
||||
},
|
||||
heading: {
|
||||
marginBottom: -10,
|
||||
},
|
||||
weekday: {
|
||||
marginBottom: -10,
|
||||
padding: 0,
|
||||
},
|
||||
})
|
||||
|
|
|
@ -32,3 +32,4 @@ export const ClipboardIcon = uiIcon('clipboard-outline')
|
|||
export const RightArrowIcon = uiIcon('arrow-ios-forward-outline')
|
||||
export const QuestionMarkIcon = uiIcon('question-mark')
|
||||
export const AwardIcon = uiIcon('award')
|
||||
export const RefreshIcon = uiIcon('refresh')
|
||||
|
|
|
@ -42,20 +42,23 @@ export const Image = ({
|
|||
if (!url) return
|
||||
const newHeaders = await api.getSessionHeaders(url)
|
||||
|
||||
/*
|
||||
console.log('[IMAGE] Getting image dimensions with headers', {
|
||||
debugImageName,
|
||||
newHeaders,
|
||||
})
|
||||
|
||||
*/
|
||||
ImageBase.getSizeWithHeaders(
|
||||
url,
|
||||
newHeaders,
|
||||
(w, h) => {
|
||||
/*
|
||||
console.log('[IMAGE] Received image dimensions', {
|
||||
debugImageName,
|
||||
w,
|
||||
h,
|
||||
})
|
||||
*/
|
||||
setDimensions({ width: w, height: h })
|
||||
setHeaders(newHeaders)
|
||||
},
|
||||
|
|
|
@ -3,7 +3,7 @@ import { StyleService, Text, useStyleSheet } from '@ui-kitten/components'
|
|||
import React from 'react'
|
||||
import { Linking, Platform } from 'react-native'
|
||||
import { ScrollView } from 'react-native-gesture-handler'
|
||||
import { NativeStackNavigationOptions } from 'react-native-screens/native-stack'
|
||||
import { NativeStackNavigationOptions } from '@react-navigation/native-stack'
|
||||
import { Layout, Sizing, Typography } from '../styles'
|
||||
import { fontSize } from '../styles/typography'
|
||||
import { RootStackParamList } from './navigation.component'
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint-disable no-console */
|
||||
import { useApi } from '@skolplattformen/hooks'
|
||||
import {
|
||||
Button,
|
||||
|
@ -16,6 +17,7 @@ import Personnummer from 'personnummer'
|
|||
import React, { useContext, useEffect, useState } from 'react'
|
||||
import {
|
||||
Image,
|
||||
ImageProps,
|
||||
Linking,
|
||||
Platform,
|
||||
TouchableWithoutFeedback,
|
||||
|
@ -43,18 +45,13 @@ const BankId = () => (
|
|||
accessibilityIgnoresInvertColors
|
||||
/>
|
||||
)
|
||||
|
||||
interface Logins {
|
||||
BANKID_SAME_DEVICE: number
|
||||
BANKID_ANOTHER_DEVICE: number
|
||||
TEST_USER: number
|
||||
}
|
||||
|
||||
const LoginMethods: Logins = {
|
||||
BANKID_SAME_DEVICE: 0,
|
||||
BANKID_ANOTHER_DEVICE: 2,
|
||||
TEST_USER: 3,
|
||||
}
|
||||
const FrejaEid = () => (
|
||||
<Image
|
||||
style={themedStyles.icon}
|
||||
source={require('../assets/freja_eid_logo.png')}
|
||||
accessibilityIgnoresInvertColors
|
||||
/>
|
||||
)
|
||||
|
||||
export const Login = () => {
|
||||
const { api } = useApi()
|
||||
|
@ -66,6 +63,7 @@ export const Login = () => {
|
|||
const [showSchoolPlatformPicker, setShowSchoolPlatformPicker] =
|
||||
useState(false)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
const [loginStatusText, setLoginStatusText] = useState('')
|
||||
const [personalIdNumber, setPersonalIdNumber] = useSettingsStorage(
|
||||
'cachedPersonalIdentityNumber'
|
||||
)
|
||||
|
@ -74,6 +72,7 @@ export const Login = () => {
|
|||
const loginBankIdSameDeviceWithoutId = useFeature(
|
||||
'LOGIN_BANK_ID_SAME_DEVICE_WITHOUT_ID'
|
||||
)
|
||||
const loginWithFrejaEnabled = useFeature('LOGIN_FREJA_EID')
|
||||
const { currentSchoolPlatform, changeSchoolPlatform } = useContext(
|
||||
SchoolPlatformContext
|
||||
)
|
||||
|
@ -85,22 +84,34 @@ export const Login = () => {
|
|||
const loginMethods = [
|
||||
{ id: 'thisdevice', title: t('auth.bankid.OpenOnThisDevice') },
|
||||
{ id: 'otherdevice', title: t('auth.bankid.OpenOnAnotherDevice') },
|
||||
{ id: 'freja', title: t('auth.freja.OpenOnThisDevice') },
|
||||
{ id: 'testuser', title: t('auth.loginAsTestUser') },
|
||||
] as const
|
||||
|
||||
const loginHandler = async () => {
|
||||
const user = await api.getUser()
|
||||
await AppStorage.clearPersonalData(user)
|
||||
showModal(false)
|
||||
if (loginMethodId === 'freja' && !loginWithFrejaEnabled) {
|
||||
setLoginMethodId('thisdevice')
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const loginHandler = async () => {
|
||||
console.debug('Runnning loginHandler')
|
||||
const user = await api.getUser()
|
||||
await AppStorage.clearPersonalData(user)
|
||||
showModal(false)
|
||||
}
|
||||
|
||||
api.on('login', loginHandler)
|
||||
return () => {
|
||||
api.off('login', loginHandler)
|
||||
}
|
||||
}, [api])
|
||||
|
||||
const LoginProviderImage = () => {
|
||||
//if(loginMethodId == 'testuser') return undefined
|
||||
if (loginMethodId === 'freja') return FrejaEid()
|
||||
return BankId()
|
||||
}
|
||||
|
||||
const getSchoolPlatformName = () => {
|
||||
return schoolPlatforms.find((item) => item.id === currentSchoolPlatform)
|
||||
?.displayName
|
||||
|
@ -120,12 +131,47 @@ export const Login = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const openFreja = (token: string) => {
|
||||
try {
|
||||
const originAppScheme = encodeURIComponent(schema)
|
||||
const frejaUrl =
|
||||
Platform.OS === 'ios'
|
||||
? `${token}&originAppScheme=${originAppScheme}`
|
||||
: `${token}`
|
||||
Linking.openURL(frejaUrl)
|
||||
} catch (err) {
|
||||
setError(t('auth.freja.OpenManually'))
|
||||
}
|
||||
}
|
||||
|
||||
const isUsingPersonalIdNumber =
|
||||
loginMethodId === 'otherdevice' ||
|
||||
(loginMethodId === 'thisdevice' && !loginBankIdSameDeviceWithoutId)
|
||||
|
||||
const startLogin = async (text: string) => {
|
||||
if (loginMethodId === 'thisdevice' || loginMethodId === 'otherdevice') {
|
||||
if (loginMethodId === 'freja') {
|
||||
setLoginStatusText(t('auth.freja.Waiting'))
|
||||
showModal(true)
|
||||
const status = await api.loginFreja()
|
||||
setCancelLoginRequest(() => () => status.cancel())
|
||||
openFreja(status.token)
|
||||
status.on('STARTED', () => console.log('Freja eID app not yet opened'))
|
||||
status.on('DELIVERED_TO_MOBILE', () =>
|
||||
console.log('Freja eID app is open')
|
||||
)
|
||||
status.on('CANCELLED', () => {
|
||||
console.log('User pressed cancel in Freja eID')
|
||||
showModal(false)
|
||||
})
|
||||
status.on('APPROVED', () => {
|
||||
console.log('Freja eID ok')
|
||||
setLoginStatusText(t('auth.loginSuccessful'))
|
||||
})
|
||||
} else if (
|
||||
loginMethodId === 'thisdevice' ||
|
||||
loginMethodId === 'otherdevice'
|
||||
) {
|
||||
setLoginStatusText(t('auth.bankid.Waiting'))
|
||||
showModal(true)
|
||||
|
||||
let ssn
|
||||
|
@ -150,7 +196,10 @@ export const Login = () => {
|
|||
setError(t('auth.loginFailed'))
|
||||
showModal(false)
|
||||
})
|
||||
status.on('OK', () => console.log('BankID ok'))
|
||||
status.on('OK', () => {
|
||||
console.log('BankID ok')
|
||||
setLoginStatusText(t('auth.loginSuccessful'))
|
||||
})
|
||||
} else {
|
||||
await api.login('201212121212')
|
||||
}
|
||||
|
@ -200,7 +249,7 @@ export const Login = () => {
|
|||
appearance="ghost"
|
||||
disabled={isUsingPersonalIdNumber && !valid}
|
||||
status="primary"
|
||||
accessoryLeft={BankId}
|
||||
accessoryLeft={LoginProviderImage}
|
||||
size="medium"
|
||||
>
|
||||
{currentLoginMethod.title}
|
||||
|
@ -245,7 +294,11 @@ export const Login = () => {
|
|||
{t('auth.chooseLoginMethod')}
|
||||
</Text>
|
||||
<List
|
||||
data={loginMethods}
|
||||
data={
|
||||
loginWithFrejaEnabled
|
||||
? loginMethods
|
||||
: loginMethods.filter((f) => f.id !== 'freja')
|
||||
}
|
||||
ItemSeparatorComponent={Divider}
|
||||
renderItem={({ item, index }) => (
|
||||
<ListItem
|
||||
|
@ -279,8 +332,7 @@ export const Login = () => {
|
|||
backdropStyle={styles.backdrop}
|
||||
>
|
||||
<Card disabled>
|
||||
<Text style={styles.bankIdLoading}>{t('auth.bankid.Waiting')}</Text>
|
||||
|
||||
<Text style={styles.bankIdLoading}>{loginStatusText}</Text>
|
||||
<Button
|
||||
status="primary"
|
||||
accessible={true}
|
||||
|
|
|
@ -9,7 +9,13 @@ import {
|
|||
} from '@ui-kitten/components'
|
||||
import 'moment/locale/sv'
|
||||
import React from 'react'
|
||||
import { Image, ImageStyle, ListRenderItemInfo, View } from 'react-native'
|
||||
import {
|
||||
Image,
|
||||
ImageStyle,
|
||||
ListRenderItemInfo,
|
||||
RefreshControl,
|
||||
View,
|
||||
} from 'react-native'
|
||||
import { Layout as LayoutStyle, Sizing, Typography } from '../styles'
|
||||
import { translate } from '../utils/translation'
|
||||
import { useChild } from './childContext.component'
|
||||
|
@ -18,7 +24,7 @@ import { MenuListItem } from './menuListItem.component'
|
|||
export const Menu = () => {
|
||||
const styles = useStyleSheet(themedStyles)
|
||||
const child = useChild()
|
||||
const { data } = useMenu(child)
|
||||
const { data, status, reload } = useMenu(child)
|
||||
|
||||
return (
|
||||
<List
|
||||
|
@ -42,6 +48,9 @@ export const Menu = () => {
|
|||
<MenuListItem key={item.title} item={item} />
|
||||
)}
|
||||
style={styles.container}
|
||||
refreshControl={
|
||||
<RefreshControl refreshing={status === 'loading'} onRefresh={reload} />
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { NavigationContainer } from '@react-navigation/native'
|
||||
import { createNativeStackNavigator } from '@react-navigation/native-stack'
|
||||
import {
|
||||
Child as ChildType,
|
||||
NewsItem as NewsItemType,
|
||||
|
@ -8,7 +9,6 @@ import { useTheme } from '@ui-kitten/components'
|
|||
import { Library } from 'libraries.json'
|
||||
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,
|
||||
|
@ -44,7 +44,7 @@ import {
|
|||
export type RootStackParamList = {
|
||||
Login: undefined
|
||||
Children: undefined
|
||||
Settings: undefined
|
||||
Settings: { rand?: number } | undefined
|
||||
SettingsAppearance: undefined
|
||||
SettingsAppearanceTheme: undefined
|
||||
SettingsLicenses: undefined
|
||||
|
|
|
@ -19,7 +19,11 @@ export const NavigationTitle = ({ title, subtitle }: NavigationTitleProps) => {
|
|||
{title}
|
||||
</Text>
|
||||
)}
|
||||
<Text style={styles.subtitle}>{subtitle}</Text>
|
||||
{subtitle && (
|
||||
<Text style={styles.subtitle}>
|
||||
{subtitle.substring(0, subtitle.indexOf(' '))}
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
@ -32,5 +36,5 @@ const styles = StyleSheet.create({
|
|||
...fontSize.sm,
|
||||
fontWeight: '500',
|
||||
},
|
||||
subtitle: { ...fontSize.xxs },
|
||||
subtitle: { ...fontSize.base },
|
||||
})
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
import { RouteProp } from '@react-navigation/native'
|
||||
import { NativeStackNavigationOptions } from '@react-navigation/native-stack'
|
||||
import { StackNavigationProp } from '@react-navigation/stack'
|
||||
import { useNewsDetails } from '@skolplattformen/hooks'
|
||||
import { StyleService, Text, useStyleSheet } from '@ui-kitten/components'
|
||||
import moment from 'moment'
|
||||
import 'moment/locale/sv'
|
||||
import React from 'react'
|
||||
import { Dimensions, ImageStyle, ScrollView, View } from 'react-native'
|
||||
import { NativeStackNavigationOptions } from 'react-native-screens/native-stack'
|
||||
import {
|
||||
Dimensions,
|
||||
ImageStyle,
|
||||
RefreshControl,
|
||||
ScrollView,
|
||||
View,
|
||||
} from 'react-native'
|
||||
import { defaultStackStyling } from '../design/navigationThemes'
|
||||
import { Layout, Sizing, Typography } from '../styles'
|
||||
import { studentName } from '../utils/peopleHelpers'
|
||||
|
@ -37,16 +43,13 @@ export const newsItemRouteOptions =
|
|||
const { child } = route.params
|
||||
return {
|
||||
...defaultStackStyling(darkMode),
|
||||
headerCenter: () => (
|
||||
<NavigationTitle subtitle={studentName(child?.name)} />
|
||||
),
|
||||
headerLargeTitle: false,
|
||||
headerTitle: () => <NavigationTitle title={studentName(child?.name)} />,
|
||||
}
|
||||
}
|
||||
|
||||
export const NewsItem = ({ route }: NewsItemProps) => {
|
||||
const { newsItem, child } = route.params
|
||||
const { data } = useNewsDetails(child, newsItem)
|
||||
const { data, status, reload } = useNewsDetails(child, newsItem)
|
||||
const styles = useStyleSheet(themedStyles)
|
||||
const stylesMarkdown = useStyleSheet(themedStylesMarkdown)
|
||||
|
||||
|
@ -54,6 +57,9 @@ export const NewsItem = ({ route }: NewsItemProps) => {
|
|||
<ScrollView
|
||||
contentContainerStyle={styles.article}
|
||||
style={styles.scrollView}
|
||||
refreshControl={
|
||||
<RefreshControl refreshing={status === 'loading'} onRefresh={reload} />
|
||||
}
|
||||
>
|
||||
<Text maxFontSizeMultiplier={2} style={styles.title}>
|
||||
{newsItem.header}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { useNews } from '@skolplattformen/hooks'
|
||||
import { Input, List, StyleService, useStyleSheet } from '@ui-kitten/components'
|
||||
import React, { useMemo, useState } from 'react'
|
||||
import { TouchableOpacity, View } from 'react-native'
|
||||
import { TouchableOpacity, View, RefreshControl } from 'react-native'
|
||||
import { Sizing } from '../styles'
|
||||
import {
|
||||
renderSearchResultPreview,
|
||||
|
@ -15,7 +15,7 @@ import { NewsListItem } from './newsListItem.component'
|
|||
export const NewsList = () => {
|
||||
const styles = useStyleSheet(themedStyles)
|
||||
const child = useChild()
|
||||
const { data } = useNews(child)
|
||||
const { data, status, reload } = useNews(child)
|
||||
|
||||
const [searchQuery, setSearchQuery] = useState('')
|
||||
const searchResults = useNewsListSearchResults(searchQuery)
|
||||
|
@ -62,6 +62,13 @@ export const NewsList = () => {
|
|||
{renderSearchResultPreview(searchResult)}
|
||||
</NewsListItem>
|
||||
)}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
refreshing={status === 'loading'}
|
||||
onRefresh={reload}
|
||||
tintColor={'color-basic-100'}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
@ -74,6 +81,13 @@ export const NewsList = () => {
|
|||
data={data}
|
||||
ListHeaderComponent={header}
|
||||
renderItem={({ item }) => <NewsListItem key={item.id} item={item} />}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
refreshing={status === 'loading'}
|
||||
onRefresh={reload}
|
||||
tintColor={'color-basic-100'}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { useNotifications } from '@skolplattformen/hooks'
|
||||
import { List, StyleService, useStyleSheet } from '@ui-kitten/components'
|
||||
import React from 'react'
|
||||
import { RefreshControl } from 'react-native'
|
||||
import { Sizing } from '../styles'
|
||||
import { useChild } from './childContext.component'
|
||||
import { Notification } from './notification.component'
|
||||
|
@ -8,7 +9,7 @@ import { Notification } from './notification.component'
|
|||
export const NotificationsList = () => {
|
||||
const styles = useStyleSheet(themedStyles)
|
||||
const child = useChild()
|
||||
const { data } = useNotifications(child)
|
||||
const { data, status, reload } = useNotifications(child)
|
||||
|
||||
return (
|
||||
<List
|
||||
|
@ -18,6 +19,9 @@ export const NotificationsList = () => {
|
|||
renderItem={(info) => (
|
||||
<Notification key={info.item.id} item={info.item} />
|
||||
)}
|
||||
refreshControl={
|
||||
<RefreshControl refreshing={status === 'loading'} onRefresh={reload} />
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { useNavigation } from '@react-navigation/native'
|
||||
import { NavigationProp, useNavigation } from '@react-navigation/native'
|
||||
import { NativeStackNavigationOptions } from '@react-navigation/native-stack'
|
||||
import {
|
||||
Button,
|
||||
ButtonGroup,
|
||||
|
@ -10,11 +11,11 @@ import { View } from 'react-native'
|
|||
import { ScrollView } 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 { languages, translate } from '../utils/translation'
|
||||
import { RootStackParamList } from './navigation.component'
|
||||
import {
|
||||
SettingGroup,
|
||||
SettingListItemSelectable,
|
||||
|
@ -25,7 +26,7 @@ export const setLanguageRouteOptions = (): NativeStackNavigationOptions => ({
|
|||
})
|
||||
|
||||
export const SetLanguage = () => {
|
||||
const navigation = useNavigation()
|
||||
const navigation = useNavigation<NavigationProp<RootStackParamList>>()
|
||||
const styles = useStyleSheet(themedStyles)
|
||||
|
||||
const currentLanguage = LanguageService.getLanguageCode()
|
||||
|
|
|
@ -2,7 +2,7 @@ import { NavigationProp, useNavigation } from '@react-navigation/core'
|
|||
import { useApi, useUser } from '@skolplattformen/hooks'
|
||||
import React, { useCallback } from 'react'
|
||||
import { ScrollView } from 'react-native'
|
||||
import { NativeStackNavigationOptions } from 'react-native-screens/native-stack'
|
||||
import { NativeStackNavigationOptions } from '@react-navigation/native-stack'
|
||||
import useSettingsStorage from '../hooks/useSettingsStorage'
|
||||
import AppStorage from '../services/appStorage'
|
||||
import { LanguageService } from '../services/languageService'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { NavigationProp, useNavigation } from '@react-navigation/core'
|
||||
import React from 'react'
|
||||
import { ScrollView, StyleSheet, Switch } from 'react-native'
|
||||
import { NativeStackNavigationOptions } from 'react-native-screens/native-stack'
|
||||
import { NativeStackNavigationOptions } from '@react-navigation/native-stack'
|
||||
import useSettingsStorage from '../hooks/useSettingsStorage'
|
||||
import { Layout as LayoutStyle, Sizing } from '../styles'
|
||||
import { translate } from '../utils/translation'
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react'
|
||||
import { ScrollView, StyleSheet, View } from 'react-native'
|
||||
import { NativeStackNavigationOptions } from 'react-native-screens/native-stack'
|
||||
import { NativeStackNavigationOptions } from '@react-navigation/native-stack'
|
||||
import useSettingsStorage from '../hooks/useSettingsStorage'
|
||||
import { Layout as LayoutStyle, Sizing } from '../styles'
|
||||
import { translate } from '../utils/translation'
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react'
|
||||
import { NativeStackNavigationOptions } from 'react-native-screens/native-stack'
|
||||
import { NativeStackNavigationOptions } from '@react-navigation/native-stack'
|
||||
import libraries from '../libraries.json'
|
||||
import { translate } from '../utils/translation'
|
||||
import { LibraryList } from './libraryList.component'
|
||||
|
|
|
@ -16,6 +16,8 @@ import { View } from 'react-native'
|
|||
import { LanguageService } from '../services/languageService'
|
||||
import { Sizing, Typography } from '../styles'
|
||||
import { TransitionView } from './transitionView.component'
|
||||
import { getMeaningfulStartingDate } from '../utils/calendarHelpers'
|
||||
import { translate } from '../utils/translation'
|
||||
|
||||
interface WeekProps {
|
||||
child: Child
|
||||
|
@ -107,17 +109,29 @@ export const Day = ({ weekDay, lunch, lessons }: DayProps) => {
|
|||
export const Week = ({ child }: WeekProps) => {
|
||||
moment.locale(LanguageService.getLocale())
|
||||
const days = moment.weekdaysShort().slice(1, 6)
|
||||
const currentDayIndex = Math.min(moment().isoWeekday() - 1, 5)
|
||||
const displayDate = getMeaningfulStartingDate(moment())
|
||||
|
||||
const currentDayIndex = Math.min(moment(displayDate).isoWeekday() - 1, 5)
|
||||
const [selectedIndex, setSelectedIndex] = useState(currentDayIndex)
|
||||
const [showSchema, setShowSchema] = useState(false)
|
||||
const [year, week] = [moment().isoWeekYear(), moment().isoWeek()]
|
||||
const [year, week] = [displayDate.isoWeekYear(), displayDate.isoWeek()]
|
||||
const { data: lessons } = useTimetable(
|
||||
child,
|
||||
week,
|
||||
year,
|
||||
LanguageService.getLanguageCode()
|
||||
)
|
||||
const { data: menu } = useMenu(child)
|
||||
let { data: menu } = useMenu(child)
|
||||
|
||||
// Hide menu if we want to show next week but it is not monday yet.
|
||||
// The menu for next week is not available until monday
|
||||
const currentDate = moment()
|
||||
const shouldShowLunchMenu =
|
||||
menu[displayDate.isoWeekday() - 1] &&
|
||||
!(displayDate.isoWeekday() === 1 && currentDate.isoWeekday() !== 1)
|
||||
if (!shouldShowLunchMenu) {
|
||||
menu = []
|
||||
}
|
||||
|
||||
const styles = useStyleSheet(themedStyles)
|
||||
|
||||
|
@ -126,15 +140,33 @@ export const Week = ({ child }: WeekProps) => {
|
|||
setShowSchema(shouldShowSchema)
|
||||
}, [lessons])
|
||||
|
||||
const getWeekText = (date = moment()) => {
|
||||
return `${translate('schedule.week')} ${date.isoWeek()}`
|
||||
}
|
||||
|
||||
return showSchema ? (
|
||||
<TransitionView style={styles.view} animation={'fadeInDown'}>
|
||||
<TransitionView style={styles.innerView} animation={'fadeIn'}>
|
||||
<Text style={styles.weekNumber}>{getWeekText(displayDate)}</Text>
|
||||
<TabBar
|
||||
selectedIndex={selectedIndex}
|
||||
onSelect={(index) => setSelectedIndex(index)}
|
||||
>
|
||||
{days.map((weekDay) => (
|
||||
<Tab key={weekDay} title={weekDay} />
|
||||
{days.map((weekDay, index) => (
|
||||
<Tab
|
||||
key={weekDay}
|
||||
title={(_) => (
|
||||
<>
|
||||
<Text style={styles.tabTitle}>{weekDay}</Text>
|
||||
<Text style={styles.tabTitleDate}>
|
||||
{displayDate
|
||||
.startOf('isoWeek')
|
||||
.add(index, 'day')
|
||||
.format('D')}
|
||||
</Text>
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
))}
|
||||
</TabBar>
|
||||
|
||||
|
@ -150,7 +182,7 @@ export const Week = ({ child }: WeekProps) => {
|
|||
lunch={menu[index] || {}}
|
||||
lessons={lessons
|
||||
.filter((lesson) => days[lesson.dayOfWeek - 1] === weekDay)
|
||||
.sort((a, b) => a.dateStart.localeCompare(b.dateStart))}
|
||||
.sort((a, b) => a.timeStart.localeCompare(b.timeStart))}
|
||||
/>
|
||||
))}
|
||||
</ViewPager>
|
||||
|
@ -162,12 +194,12 @@ export const Week = ({ child }: WeekProps) => {
|
|||
const themedStyles = StyleService.create({
|
||||
view: {
|
||||
backgroundColor: 'background-basic-color-1',
|
||||
maxHeight: '60%',
|
||||
maxHeight: '65%',
|
||||
paddingBottom: 0,
|
||||
margin: 0,
|
||||
},
|
||||
innerView: {
|
||||
paddingBottom: 60,
|
||||
paddingBottom: 170,
|
||||
margin: 0,
|
||||
},
|
||||
part: {
|
||||
|
@ -229,4 +261,15 @@ const themedStyles = StyleService.create({
|
|||
lesson: {
|
||||
flexDirection: 'column',
|
||||
},
|
||||
weekNumber: {
|
||||
marginLeft: 10,
|
||||
marginTop: 10,
|
||||
...Typography.fontWeight.bold,
|
||||
},
|
||||
tabTitle: {
|
||||
textAlign: 'center',
|
||||
},
|
||||
tabTitleDate: {
|
||||
textAlign: 'center',
|
||||
},
|
||||
})
|
||||
|
|
|
@ -9,13 +9,13 @@ import initSkolplattformen, {
|
|||
export const schoolPlatforms = [
|
||||
{
|
||||
id: 'stockholm-skolplattformen',
|
||||
displayName: 'Stockholm stad (Skolplattformen)',
|
||||
displayName: 'Stockholms stad (Skolplattformen)',
|
||||
api: initSkolplattformen(fetch as any, CookieManager),
|
||||
features: featuresSkolPlattformen,
|
||||
},
|
||||
{
|
||||
id: 'goteborg-hjarntorget',
|
||||
displayName: 'Göteborg stad (Hjärntorget)',
|
||||
displayName: 'Göteborgs Stad (Hjärntorget)',
|
||||
api: initHjarntorget(fetch as any, CookieManager),
|
||||
features: featuresHjarntorget,
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { DarkTheme, DefaultTheme, Theme } from '@react-navigation/native'
|
||||
import { NativeStackNavigationOptions } from 'react-native-screens/native-stack'
|
||||
import { NativeStackNavigationOptions } from '@react-navigation/native-stack'
|
||||
import { darkTheme, lightTheme } from './themes'
|
||||
|
||||
export const darkNavigationTheme: Theme = {
|
||||
|
|
|
@ -2,16 +2,23 @@ import { useCallback } from 'react'
|
|||
import { proxy, subscribe, useSnapshot } from 'valtio'
|
||||
import AppStorage from '../services/appStorage'
|
||||
|
||||
export type ChildPersonalNumbers = Record<string, string>
|
||||
|
||||
export const settingsState = proxy({
|
||||
hydrated: false,
|
||||
settings: {
|
||||
loginMethodId: 'thisdevice' as 'thisdevice' | 'otherdevice' | 'testuser',
|
||||
loginMethodId: 'thisdevice' as
|
||||
| 'thisdevice'
|
||||
| 'otherdevice'
|
||||
| 'testuser'
|
||||
| 'freja',
|
||||
usingSystemTheme: true,
|
||||
theme: 'light',
|
||||
cachedPersonalIdentityNumber: '',
|
||||
currentSchoolPlatform: 'stockholm-skolplattformen' as
|
||||
| 'stockholm-skolplattformen'
|
||||
| 'goteborg-hjarntorget',
|
||||
childPersonalIdentityNumber: {} as ChildPersonalNumbers,
|
||||
},
|
||||
})
|
||||
|
||||
|
|
|
@ -1,4 +1,17 @@
|
|||
import 'react-native-gesture-handler'
|
||||
import '@formatjs/intl-getcanonicallocales/polyfill'
|
||||
import '@formatjs/intl-locale/polyfill'
|
||||
import '@formatjs/intl-numberformat/polyfill'
|
||||
import '@formatjs/intl-numberformat/locale-data/en'
|
||||
import '@formatjs/intl-numberformat/locale-data/sv'
|
||||
import '@formatjs/intl-pluralrules/polyfill'
|
||||
import '@formatjs/intl-pluralrules/locale-data/en'
|
||||
import '@formatjs/intl-pluralrules/locale-data/sv'
|
||||
import '@formatjs/intl-datetimeformat/polyfill'
|
||||
import '@formatjs/intl-datetimeformat/locale-data/en'
|
||||
import '@formatjs/intl-datetimeformat/locale-data/sv'
|
||||
import '@formatjs/intl-datetimeformat/add-all-tz'
|
||||
|
||||
import { AppRegistry } from 'react-native'
|
||||
import App from './App'
|
||||
import { name as appName } from './app.json'
|
||||
|
|
|
@ -23,6 +23,7 @@ target 'app' do
|
|||
|
||||
post_install do |installer|
|
||||
react_native_post_install(installer)
|
||||
__apply_Xcode_12_5_M1_post_install_workaround(installer)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
PODS:
|
||||
- boost-for-react-native (1.63.0)
|
||||
- boost (1.76.0)
|
||||
- CocoaAsyncSocket (7.6.5)
|
||||
- DoubleConversion (1.1.6)
|
||||
- FBLazyVector (0.65.1)
|
||||
- FBReactNativeSpec (0.65.1):
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- RCTRequired (= 0.65.1)
|
||||
- RCTTypeSafety (= 0.65.1)
|
||||
- React-Core (= 0.65.1)
|
||||
- React-jsi (= 0.65.1)
|
||||
- ReactCommon/turbomodule/core (= 0.65.1)
|
||||
- Flipper (0.93.0):
|
||||
- FBLazyVector (0.66.4)
|
||||
- FBReactNativeSpec (0.66.4):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTRequired (= 0.66.4)
|
||||
- RCTTypeSafety (= 0.66.4)
|
||||
- React-Core (= 0.66.4)
|
||||
- React-jsi (= 0.66.4)
|
||||
- ReactCommon/turbomodule/core (= 0.66.4)
|
||||
- Flipper (0.99.0):
|
||||
- Flipper-Folly (~> 2.6)
|
||||
- Flipper-RSocket (~> 1.4)
|
||||
- Flipper-Boost-iOSX (1.76.0.1.11)
|
||||
|
@ -27,266 +27,269 @@ PODS:
|
|||
- Flipper-PeerTalk (0.0.4)
|
||||
- Flipper-RSocket (1.4.3):
|
||||
- Flipper-Folly (~> 2.6)
|
||||
- FlipperKit (0.93.0):
|
||||
- FlipperKit/Core (= 0.93.0)
|
||||
- FlipperKit/Core (0.93.0):
|
||||
- Flipper (~> 0.93.0)
|
||||
- FlipperKit (0.99.0):
|
||||
- FlipperKit/Core (= 0.99.0)
|
||||
- FlipperKit/Core (0.99.0):
|
||||
- Flipper (~> 0.99.0)
|
||||
- FlipperKit/CppBridge
|
||||
- FlipperKit/FBCxxFollyDynamicConvert
|
||||
- FlipperKit/FBDefines
|
||||
- FlipperKit/FKPortForwarding
|
||||
- FlipperKit/CppBridge (0.93.0):
|
||||
- Flipper (~> 0.93.0)
|
||||
- FlipperKit/FBCxxFollyDynamicConvert (0.93.0):
|
||||
- FlipperKit/CppBridge (0.99.0):
|
||||
- Flipper (~> 0.99.0)
|
||||
- FlipperKit/FBCxxFollyDynamicConvert (0.99.0):
|
||||
- Flipper-Folly (~> 2.6)
|
||||
- FlipperKit/FBDefines (0.93.0)
|
||||
- FlipperKit/FKPortForwarding (0.93.0):
|
||||
- FlipperKit/FBDefines (0.99.0)
|
||||
- FlipperKit/FKPortForwarding (0.99.0):
|
||||
- CocoaAsyncSocket (~> 7.6)
|
||||
- Flipper-PeerTalk (~> 0.0.4)
|
||||
- FlipperKit/FlipperKitHighlightOverlay (0.93.0)
|
||||
- FlipperKit/FlipperKitLayoutHelpers (0.93.0):
|
||||
- FlipperKit/FlipperKitHighlightOverlay (0.99.0)
|
||||
- FlipperKit/FlipperKitLayoutHelpers (0.99.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitHighlightOverlay
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable
|
||||
- FlipperKit/FlipperKitLayoutIOSDescriptors (0.93.0):
|
||||
- FlipperKit/FlipperKitLayoutIOSDescriptors (0.99.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitHighlightOverlay
|
||||
- FlipperKit/FlipperKitLayoutHelpers
|
||||
- YogaKit (~> 1.18)
|
||||
- FlipperKit/FlipperKitLayoutPlugin (0.93.0):
|
||||
- FlipperKit/FlipperKitLayoutPlugin (0.99.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitHighlightOverlay
|
||||
- FlipperKit/FlipperKitLayoutHelpers
|
||||
- FlipperKit/FlipperKitLayoutIOSDescriptors
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable
|
||||
- YogaKit (~> 1.18)
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable (0.93.0)
|
||||
- FlipperKit/FlipperKitNetworkPlugin (0.93.0):
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable (0.99.0)
|
||||
- FlipperKit/FlipperKitNetworkPlugin (0.99.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitReactPlugin (0.93.0):
|
||||
- FlipperKit/FlipperKitReactPlugin (0.99.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitUserDefaultsPlugin (0.93.0):
|
||||
- FlipperKit/FlipperKitUserDefaultsPlugin (0.99.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/SKIOSNetworkPlugin (0.93.0):
|
||||
- FlipperKit/SKIOSNetworkPlugin (0.99.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitNetworkPlugin
|
||||
- fmt (6.2.1)
|
||||
- glog (0.3.5)
|
||||
- hermes-engine (0.8.1)
|
||||
- hermes-engine (0.9.0)
|
||||
- libevent (2.1.12)
|
||||
- OpenSSL-Universal (1.1.180)
|
||||
- RCT-Folly (2021.04.26.00):
|
||||
- boost-for-react-native
|
||||
- RCT-Folly (2021.06.28.00-v2):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fmt (~> 6.2.1)
|
||||
- glog
|
||||
- RCT-Folly/Default (= 2021.04.26.00)
|
||||
- RCT-Folly/Default (2021.04.26.00):
|
||||
- boost-for-react-native
|
||||
- RCT-Folly/Default (= 2021.06.28.00-v2)
|
||||
- RCT-Folly/Default (2021.06.28.00-v2):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fmt (~> 6.2.1)
|
||||
- glog
|
||||
- RCT-Folly/Futures (2021.04.26.00):
|
||||
- boost-for-react-native
|
||||
- RCT-Folly/Futures (2021.06.28.00-v2):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fmt (~> 6.2.1)
|
||||
- glog
|
||||
- libevent
|
||||
- RCTRequired (0.65.1)
|
||||
- RCTTypeSafety (0.65.1):
|
||||
- FBLazyVector (= 0.65.1)
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- RCTRequired (= 0.65.1)
|
||||
- React-Core (= 0.65.1)
|
||||
- React (0.65.1):
|
||||
- React-Core (= 0.65.1)
|
||||
- React-Core/DevSupport (= 0.65.1)
|
||||
- React-Core/RCTWebSocket (= 0.65.1)
|
||||
- React-RCTActionSheet (= 0.65.1)
|
||||
- React-RCTAnimation (= 0.65.1)
|
||||
- React-RCTBlob (= 0.65.1)
|
||||
- React-RCTImage (= 0.65.1)
|
||||
- React-RCTLinking (= 0.65.1)
|
||||
- React-RCTNetwork (= 0.65.1)
|
||||
- React-RCTSettings (= 0.65.1)
|
||||
- React-RCTText (= 0.65.1)
|
||||
- React-RCTVibration (= 0.65.1)
|
||||
- React-callinvoker (0.65.1)
|
||||
- React-Core (0.65.1):
|
||||
- RCTRequired (0.66.4)
|
||||
- RCTTypeSafety (0.66.4):
|
||||
- FBLazyVector (= 0.66.4)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTRequired (= 0.66.4)
|
||||
- React-Core (= 0.66.4)
|
||||
- React (0.66.4):
|
||||
- React-Core (= 0.66.4)
|
||||
- React-Core/DevSupport (= 0.66.4)
|
||||
- React-Core/RCTWebSocket (= 0.66.4)
|
||||
- React-RCTActionSheet (= 0.66.4)
|
||||
- React-RCTAnimation (= 0.66.4)
|
||||
- React-RCTBlob (= 0.66.4)
|
||||
- React-RCTImage (= 0.66.4)
|
||||
- React-RCTLinking (= 0.66.4)
|
||||
- React-RCTNetwork (= 0.66.4)
|
||||
- React-RCTSettings (= 0.66.4)
|
||||
- React-RCTText (= 0.66.4)
|
||||
- React-RCTVibration (= 0.66.4)
|
||||
- React-callinvoker (0.66.4)
|
||||
- React-Core (0.66.4):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- React-Core/Default (= 0.65.1)
|
||||
- React-cxxreact (= 0.65.1)
|
||||
- React-jsi (= 0.65.1)
|
||||
- React-jsiexecutor (= 0.65.1)
|
||||
- React-perflogger (= 0.65.1)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default (= 0.66.4)
|
||||
- React-cxxreact (= 0.66.4)
|
||||
- React-jsi (= 0.66.4)
|
||||
- React-jsiexecutor (= 0.66.4)
|
||||
- React-perflogger (= 0.66.4)
|
||||
- Yoga
|
||||
- React-Core/CoreModulesHeaders (0.65.1):
|
||||
- React-Core/CoreModulesHeaders (0.66.4):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.65.1)
|
||||
- React-jsi (= 0.65.1)
|
||||
- React-jsiexecutor (= 0.65.1)
|
||||
- React-perflogger (= 0.65.1)
|
||||
- React-cxxreact (= 0.66.4)
|
||||
- React-jsi (= 0.66.4)
|
||||
- React-jsiexecutor (= 0.66.4)
|
||||
- React-perflogger (= 0.66.4)
|
||||
- Yoga
|
||||
- React-Core/Default (0.65.1):
|
||||
- React-Core/Default (0.66.4):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- React-cxxreact (= 0.65.1)
|
||||
- React-jsi (= 0.65.1)
|
||||
- React-jsiexecutor (= 0.65.1)
|
||||
- React-perflogger (= 0.65.1)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-cxxreact (= 0.66.4)
|
||||
- React-jsi (= 0.66.4)
|
||||
- React-jsiexecutor (= 0.66.4)
|
||||
- React-perflogger (= 0.66.4)
|
||||
- Yoga
|
||||
- React-Core/DevSupport (0.65.1):
|
||||
- React-Core/DevSupport (0.66.4):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- React-Core/Default (= 0.65.1)
|
||||
- React-Core/RCTWebSocket (= 0.65.1)
|
||||
- React-cxxreact (= 0.65.1)
|
||||
- React-jsi (= 0.65.1)
|
||||
- React-jsiexecutor (= 0.65.1)
|
||||
- React-jsinspector (= 0.65.1)
|
||||
- React-perflogger (= 0.65.1)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default (= 0.66.4)
|
||||
- React-Core/RCTWebSocket (= 0.66.4)
|
||||
- React-cxxreact (= 0.66.4)
|
||||
- React-jsi (= 0.66.4)
|
||||
- React-jsiexecutor (= 0.66.4)
|
||||
- React-jsinspector (= 0.66.4)
|
||||
- React-perflogger (= 0.66.4)
|
||||
- Yoga
|
||||
- React-Core/RCTActionSheetHeaders (0.65.1):
|
||||
- React-Core/RCTActionSheetHeaders (0.66.4):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.65.1)
|
||||
- React-jsi (= 0.65.1)
|
||||
- React-jsiexecutor (= 0.65.1)
|
||||
- React-perflogger (= 0.65.1)
|
||||
- React-cxxreact (= 0.66.4)
|
||||
- React-jsi (= 0.66.4)
|
||||
- React-jsiexecutor (= 0.66.4)
|
||||
- React-perflogger (= 0.66.4)
|
||||
- Yoga
|
||||
- React-Core/RCTAnimationHeaders (0.65.1):
|
||||
- React-Core/RCTAnimationHeaders (0.66.4):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.65.1)
|
||||
- React-jsi (= 0.65.1)
|
||||
- React-jsiexecutor (= 0.65.1)
|
||||
- React-perflogger (= 0.65.1)
|
||||
- React-cxxreact (= 0.66.4)
|
||||
- React-jsi (= 0.66.4)
|
||||
- React-jsiexecutor (= 0.66.4)
|
||||
- React-perflogger (= 0.66.4)
|
||||
- Yoga
|
||||
- React-Core/RCTBlobHeaders (0.65.1):
|
||||
- React-Core/RCTBlobHeaders (0.66.4):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.65.1)
|
||||
- React-jsi (= 0.65.1)
|
||||
- React-jsiexecutor (= 0.65.1)
|
||||
- React-perflogger (= 0.65.1)
|
||||
- React-cxxreact (= 0.66.4)
|
||||
- React-jsi (= 0.66.4)
|
||||
- React-jsiexecutor (= 0.66.4)
|
||||
- React-perflogger (= 0.66.4)
|
||||
- Yoga
|
||||
- React-Core/RCTImageHeaders (0.65.1):
|
||||
- React-Core/RCTImageHeaders (0.66.4):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.65.1)
|
||||
- React-jsi (= 0.65.1)
|
||||
- React-jsiexecutor (= 0.65.1)
|
||||
- React-perflogger (= 0.65.1)
|
||||
- React-cxxreact (= 0.66.4)
|
||||
- React-jsi (= 0.66.4)
|
||||
- React-jsiexecutor (= 0.66.4)
|
||||
- React-perflogger (= 0.66.4)
|
||||
- Yoga
|
||||
- React-Core/RCTLinkingHeaders (0.65.1):
|
||||
- React-Core/RCTLinkingHeaders (0.66.4):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.65.1)
|
||||
- React-jsi (= 0.65.1)
|
||||
- React-jsiexecutor (= 0.65.1)
|
||||
- React-perflogger (= 0.65.1)
|
||||
- React-cxxreact (= 0.66.4)
|
||||
- React-jsi (= 0.66.4)
|
||||
- React-jsiexecutor (= 0.66.4)
|
||||
- React-perflogger (= 0.66.4)
|
||||
- Yoga
|
||||
- React-Core/RCTNetworkHeaders (0.65.1):
|
||||
- React-Core/RCTNetworkHeaders (0.66.4):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.65.1)
|
||||
- React-jsi (= 0.65.1)
|
||||
- React-jsiexecutor (= 0.65.1)
|
||||
- React-perflogger (= 0.65.1)
|
||||
- React-cxxreact (= 0.66.4)
|
||||
- React-jsi (= 0.66.4)
|
||||
- React-jsiexecutor (= 0.66.4)
|
||||
- React-perflogger (= 0.66.4)
|
||||
- Yoga
|
||||
- React-Core/RCTSettingsHeaders (0.65.1):
|
||||
- React-Core/RCTSettingsHeaders (0.66.4):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.65.1)
|
||||
- React-jsi (= 0.65.1)
|
||||
- React-jsiexecutor (= 0.65.1)
|
||||
- React-perflogger (= 0.65.1)
|
||||
- React-cxxreact (= 0.66.4)
|
||||
- React-jsi (= 0.66.4)
|
||||
- React-jsiexecutor (= 0.66.4)
|
||||
- React-perflogger (= 0.66.4)
|
||||
- Yoga
|
||||
- React-Core/RCTTextHeaders (0.65.1):
|
||||
- React-Core/RCTTextHeaders (0.66.4):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.65.1)
|
||||
- React-jsi (= 0.65.1)
|
||||
- React-jsiexecutor (= 0.65.1)
|
||||
- React-perflogger (= 0.65.1)
|
||||
- React-cxxreact (= 0.66.4)
|
||||
- React-jsi (= 0.66.4)
|
||||
- React-jsiexecutor (= 0.66.4)
|
||||
- React-perflogger (= 0.66.4)
|
||||
- Yoga
|
||||
- React-Core/RCTVibrationHeaders (0.65.1):
|
||||
- React-Core/RCTVibrationHeaders (0.66.4):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.65.1)
|
||||
- React-jsi (= 0.65.1)
|
||||
- React-jsiexecutor (= 0.65.1)
|
||||
- React-perflogger (= 0.65.1)
|
||||
- React-cxxreact (= 0.66.4)
|
||||
- React-jsi (= 0.66.4)
|
||||
- React-jsiexecutor (= 0.66.4)
|
||||
- React-perflogger (= 0.66.4)
|
||||
- Yoga
|
||||
- React-Core/RCTWebSocket (0.65.1):
|
||||
- React-Core/RCTWebSocket (0.66.4):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- React-Core/Default (= 0.65.1)
|
||||
- React-cxxreact (= 0.65.1)
|
||||
- React-jsi (= 0.65.1)
|
||||
- React-jsiexecutor (= 0.65.1)
|
||||
- React-perflogger (= 0.65.1)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default (= 0.66.4)
|
||||
- React-cxxreact (= 0.66.4)
|
||||
- React-jsi (= 0.66.4)
|
||||
- React-jsiexecutor (= 0.66.4)
|
||||
- React-perflogger (= 0.66.4)
|
||||
- Yoga
|
||||
- React-CoreModules (0.65.1):
|
||||
- FBReactNativeSpec (= 0.65.1)
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- RCTTypeSafety (= 0.65.1)
|
||||
- React-Core/CoreModulesHeaders (= 0.65.1)
|
||||
- React-jsi (= 0.65.1)
|
||||
- React-RCTImage (= 0.65.1)
|
||||
- ReactCommon/turbomodule/core (= 0.65.1)
|
||||
- React-cxxreact (0.65.1):
|
||||
- boost-for-react-native (= 1.63.0)
|
||||
- React-CoreModules (0.66.4):
|
||||
- FBReactNativeSpec (= 0.66.4)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.66.4)
|
||||
- React-Core/CoreModulesHeaders (= 0.66.4)
|
||||
- React-jsi (= 0.66.4)
|
||||
- React-RCTImage (= 0.66.4)
|
||||
- ReactCommon/turbomodule/core (= 0.66.4)
|
||||
- React-cxxreact (0.66.4):
|
||||
- boost (= 1.76.0)
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- React-callinvoker (= 0.65.1)
|
||||
- React-jsi (= 0.65.1)
|
||||
- React-jsinspector (= 0.65.1)
|
||||
- React-perflogger (= 0.65.1)
|
||||
- React-runtimeexecutor (= 0.65.1)
|
||||
- React-hermes (0.65.1):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-callinvoker (= 0.66.4)
|
||||
- React-jsi (= 0.66.4)
|
||||
- React-jsinspector (= 0.66.4)
|
||||
- React-logger (= 0.66.4)
|
||||
- React-perflogger (= 0.66.4)
|
||||
- React-runtimeexecutor (= 0.66.4)
|
||||
- React-hermes (0.66.4):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- hermes-engine
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- RCT-Folly/Futures (= 2021.04.26.00)
|
||||
- React-cxxreact (= 0.65.1)
|
||||
- React-jsi (= 0.65.1)
|
||||
- React-jsiexecutor (= 0.65.1)
|
||||
- React-jsinspector (= 0.65.1)
|
||||
- React-perflogger (= 0.65.1)
|
||||
- React-jsi (0.65.1):
|
||||
- boost-for-react-native (= 1.63.0)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCT-Folly/Futures (= 2021.06.28.00-v2)
|
||||
- React-cxxreact (= 0.66.4)
|
||||
- React-jsi (= 0.66.4)
|
||||
- React-jsiexecutor (= 0.66.4)
|
||||
- React-jsinspector (= 0.66.4)
|
||||
- React-perflogger (= 0.66.4)
|
||||
- React-jsi (0.66.4):
|
||||
- boost (= 1.76.0)
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- React-jsi/Default (= 0.65.1)
|
||||
- React-jsi/Default (0.65.1):
|
||||
- boost-for-react-native (= 1.63.0)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-jsi/Default (= 0.66.4)
|
||||
- React-jsi/Default (0.66.4):
|
||||
- boost (= 1.76.0)
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- React-jsiexecutor (0.65.1):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-jsiexecutor (0.66.4):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- React-cxxreact (= 0.65.1)
|
||||
- React-jsi (= 0.65.1)
|
||||
- React-perflogger (= 0.65.1)
|
||||
- React-jsinspector (0.65.1)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-cxxreact (= 0.66.4)
|
||||
- React-jsi (= 0.66.4)
|
||||
- React-perflogger (= 0.66.4)
|
||||
- React-jsinspector (0.66.4)
|
||||
- React-logger (0.66.4):
|
||||
- glog
|
||||
- react-native-cookies (6.0.11):
|
||||
- React-Core
|
||||
- react-native-restart (0.0.22):
|
||||
|
@ -296,81 +299,82 @@ PODS:
|
|||
- react-native-simple-toast (1.1.3):
|
||||
- React-Core
|
||||
- Toast (~> 4.0.0)
|
||||
- react-native-webview (11.4.2):
|
||||
- react-native-webview (12.4.0):
|
||||
- React-Core
|
||||
- React-perflogger (0.65.1)
|
||||
- React-RCTActionSheet (0.65.1):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.65.1)
|
||||
- React-RCTAnimation (0.65.1):
|
||||
- FBReactNativeSpec (= 0.65.1)
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- RCTTypeSafety (= 0.65.1)
|
||||
- React-Core/RCTAnimationHeaders (= 0.65.1)
|
||||
- React-jsi (= 0.65.1)
|
||||
- ReactCommon/turbomodule/core (= 0.65.1)
|
||||
- React-RCTBlob (0.65.1):
|
||||
- FBReactNativeSpec (= 0.65.1)
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- React-Core/RCTBlobHeaders (= 0.65.1)
|
||||
- React-Core/RCTWebSocket (= 0.65.1)
|
||||
- React-jsi (= 0.65.1)
|
||||
- React-RCTNetwork (= 0.65.1)
|
||||
- ReactCommon/turbomodule/core (= 0.65.1)
|
||||
- React-RCTImage (0.65.1):
|
||||
- FBReactNativeSpec (= 0.65.1)
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- RCTTypeSafety (= 0.65.1)
|
||||
- React-Core/RCTImageHeaders (= 0.65.1)
|
||||
- React-jsi (= 0.65.1)
|
||||
- React-RCTNetwork (= 0.65.1)
|
||||
- ReactCommon/turbomodule/core (= 0.65.1)
|
||||
- React-RCTLinking (0.65.1):
|
||||
- FBReactNativeSpec (= 0.65.1)
|
||||
- React-Core/RCTLinkingHeaders (= 0.65.1)
|
||||
- React-jsi (= 0.65.1)
|
||||
- ReactCommon/turbomodule/core (= 0.65.1)
|
||||
- React-RCTNetwork (0.65.1):
|
||||
- FBReactNativeSpec (= 0.65.1)
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- RCTTypeSafety (= 0.65.1)
|
||||
- React-Core/RCTNetworkHeaders (= 0.65.1)
|
||||
- React-jsi (= 0.65.1)
|
||||
- ReactCommon/turbomodule/core (= 0.65.1)
|
||||
- React-RCTSettings (0.65.1):
|
||||
- FBReactNativeSpec (= 0.65.1)
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- RCTTypeSafety (= 0.65.1)
|
||||
- React-Core/RCTSettingsHeaders (= 0.65.1)
|
||||
- React-jsi (= 0.65.1)
|
||||
- ReactCommon/turbomodule/core (= 0.65.1)
|
||||
- React-RCTText (0.65.1):
|
||||
- React-Core/RCTTextHeaders (= 0.65.1)
|
||||
- React-RCTVibration (0.65.1):
|
||||
- FBReactNativeSpec (= 0.65.1)
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- React-Core/RCTVibrationHeaders (= 0.65.1)
|
||||
- React-jsi (= 0.65.1)
|
||||
- ReactCommon/turbomodule/core (= 0.65.1)
|
||||
- React-runtimeexecutor (0.65.1):
|
||||
- React-jsi (= 0.65.1)
|
||||
- ReactCommon/turbomodule/core (0.65.1):
|
||||
- React-perflogger (0.66.4)
|
||||
- React-RCTActionSheet (0.66.4):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.66.4)
|
||||
- React-RCTAnimation (0.66.4):
|
||||
- FBReactNativeSpec (= 0.66.4)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.66.4)
|
||||
- React-Core/RCTAnimationHeaders (= 0.66.4)
|
||||
- React-jsi (= 0.66.4)
|
||||
- ReactCommon/turbomodule/core (= 0.66.4)
|
||||
- React-RCTBlob (0.66.4):
|
||||
- FBReactNativeSpec (= 0.66.4)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/RCTBlobHeaders (= 0.66.4)
|
||||
- React-Core/RCTWebSocket (= 0.66.4)
|
||||
- React-jsi (= 0.66.4)
|
||||
- React-RCTNetwork (= 0.66.4)
|
||||
- ReactCommon/turbomodule/core (= 0.66.4)
|
||||
- React-RCTImage (0.66.4):
|
||||
- FBReactNativeSpec (= 0.66.4)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.66.4)
|
||||
- React-Core/RCTImageHeaders (= 0.66.4)
|
||||
- React-jsi (= 0.66.4)
|
||||
- React-RCTNetwork (= 0.66.4)
|
||||
- ReactCommon/turbomodule/core (= 0.66.4)
|
||||
- React-RCTLinking (0.66.4):
|
||||
- FBReactNativeSpec (= 0.66.4)
|
||||
- React-Core/RCTLinkingHeaders (= 0.66.4)
|
||||
- React-jsi (= 0.66.4)
|
||||
- ReactCommon/turbomodule/core (= 0.66.4)
|
||||
- React-RCTNetwork (0.66.4):
|
||||
- FBReactNativeSpec (= 0.66.4)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.66.4)
|
||||
- React-Core/RCTNetworkHeaders (= 0.66.4)
|
||||
- React-jsi (= 0.66.4)
|
||||
- ReactCommon/turbomodule/core (= 0.66.4)
|
||||
- React-RCTSettings (0.66.4):
|
||||
- FBReactNativeSpec (= 0.66.4)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.66.4)
|
||||
- React-Core/RCTSettingsHeaders (= 0.66.4)
|
||||
- React-jsi (= 0.66.4)
|
||||
- ReactCommon/turbomodule/core (= 0.66.4)
|
||||
- React-RCTText (0.66.4):
|
||||
- React-Core/RCTTextHeaders (= 0.66.4)
|
||||
- React-RCTVibration (0.66.4):
|
||||
- FBReactNativeSpec (= 0.66.4)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/RCTVibrationHeaders (= 0.66.4)
|
||||
- React-jsi (= 0.66.4)
|
||||
- ReactCommon/turbomodule/core (= 0.66.4)
|
||||
- React-runtimeexecutor (0.66.4):
|
||||
- React-jsi (= 0.66.4)
|
||||
- ReactCommon/turbomodule/core (0.66.4):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.04.26.00)
|
||||
- React-callinvoker (= 0.65.1)
|
||||
- React-Core (= 0.65.1)
|
||||
- React-cxxreact (= 0.65.1)
|
||||
- React-jsi (= 0.65.1)
|
||||
- React-perflogger (= 0.65.1)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-callinvoker (= 0.66.4)
|
||||
- React-Core (= 0.66.4)
|
||||
- React-cxxreact (= 0.66.4)
|
||||
- React-jsi (= 0.66.4)
|
||||
- React-logger (= 0.66.4)
|
||||
- React-perflogger (= 0.66.4)
|
||||
- RNCalendarEvents (2.2.0):
|
||||
- React
|
||||
- RNCAsyncStorage (1.15.9):
|
||||
- RNCAsyncStorage (1.15.14):
|
||||
- React-Core
|
||||
- RNCMaskedView (0.1.11):
|
||||
- React
|
||||
- RNDateTimePicker (3.4.3):
|
||||
- RNDateTimePicker (3.5.2):
|
||||
- React-Core
|
||||
- RNDeviceInfo (8.4.0):
|
||||
- RNDeviceInfo (8.4.8):
|
||||
- React-Core
|
||||
- RNDevMenu (4.0.2):
|
||||
- React-Core
|
||||
|
@ -380,36 +384,7 @@ PODS:
|
|||
- React-Core
|
||||
- RNLocalize (2.1.5):
|
||||
- React-Core
|
||||
- RNReanimated (2.2.2):
|
||||
- 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.8.0):
|
||||
- RNScreens (3.10.1):
|
||||
- React-Core
|
||||
- React-RCTImage
|
||||
- RNSVG (12.1.1):
|
||||
|
@ -420,10 +395,11 @@ PODS:
|
|||
- Yoga (~> 1.14)
|
||||
|
||||
DEPENDENCIES:
|
||||
- boost (from `../../../node_modules/react-native/third-party-podspecs/boost.podspec`)
|
||||
- DoubleConversion (from `../../../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
|
||||
- FBLazyVector (from `../../../node_modules/react-native/Libraries/FBLazyVector`)
|
||||
- FBReactNativeSpec (from `../../../node_modules/react-native/React/FBReactNativeSpec`)
|
||||
- Flipper (= 0.93.0)
|
||||
- Flipper (= 0.99.0)
|
||||
- Flipper-Boost-iOSX (= 1.76.0.1.11)
|
||||
- Flipper-DoubleConversion (= 3.1.7)
|
||||
- Flipper-Fmt (= 7.1.7)
|
||||
|
@ -431,21 +407,21 @@ DEPENDENCIES:
|
|||
- Flipper-Glog (= 0.3.6)
|
||||
- Flipper-PeerTalk (= 0.0.4)
|
||||
- Flipper-RSocket (= 1.4.3)
|
||||
- FlipperKit (= 0.93.0)
|
||||
- FlipperKit/Core (= 0.93.0)
|
||||
- FlipperKit/CppBridge (= 0.93.0)
|
||||
- FlipperKit/FBCxxFollyDynamicConvert (= 0.93.0)
|
||||
- FlipperKit/FBDefines (= 0.93.0)
|
||||
- FlipperKit/FKPortForwarding (= 0.93.0)
|
||||
- FlipperKit/FlipperKitHighlightOverlay (= 0.93.0)
|
||||
- FlipperKit/FlipperKitLayoutPlugin (= 0.93.0)
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable (= 0.93.0)
|
||||
- FlipperKit/FlipperKitNetworkPlugin (= 0.93.0)
|
||||
- FlipperKit/FlipperKitReactPlugin (= 0.93.0)
|
||||
- FlipperKit/FlipperKitUserDefaultsPlugin (= 0.93.0)
|
||||
- FlipperKit/SKIOSNetworkPlugin (= 0.93.0)
|
||||
- FlipperKit (= 0.99.0)
|
||||
- FlipperKit/Core (= 0.99.0)
|
||||
- FlipperKit/CppBridge (= 0.99.0)
|
||||
- FlipperKit/FBCxxFollyDynamicConvert (= 0.99.0)
|
||||
- FlipperKit/FBDefines (= 0.99.0)
|
||||
- FlipperKit/FKPortForwarding (= 0.99.0)
|
||||
- FlipperKit/FlipperKitHighlightOverlay (= 0.99.0)
|
||||
- FlipperKit/FlipperKitLayoutPlugin (= 0.99.0)
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable (= 0.99.0)
|
||||
- FlipperKit/FlipperKitNetworkPlugin (= 0.99.0)
|
||||
- FlipperKit/FlipperKitReactPlugin (= 0.99.0)
|
||||
- FlipperKit/FlipperKitUserDefaultsPlugin (= 0.99.0)
|
||||
- FlipperKit/SKIOSNetworkPlugin (= 0.99.0)
|
||||
- glog (from `../../../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
||||
- hermes-engine (~> 0.8.1)
|
||||
- hermes-engine (~> 0.9.0)
|
||||
- libevent (~> 2.1.12)
|
||||
- RCT-Folly (from `../../../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
|
||||
- RCTRequired (from `../../../node_modules/react-native/Libraries/RCTRequired`)
|
||||
|
@ -461,6 +437,7 @@ DEPENDENCIES:
|
|||
- React-jsi (from `../../../node_modules/react-native/ReactCommon/jsi`)
|
||||
- React-jsiexecutor (from `../../../node_modules/react-native/ReactCommon/jsiexecutor`)
|
||||
- React-jsinspector (from `../../../node_modules/react-native/ReactCommon/jsinspector`)
|
||||
- React-logger (from `../../../node_modules/react-native/ReactCommon/logger`)
|
||||
- "react-native-cookies (from `../../../node_modules/@react-native-cookies/cookies`)"
|
||||
- react-native-restart (from `../../../node_modules/react-native-restart`)
|
||||
- react-native-safe-area-context (from `../../../node_modules/react-native-safe-area-context`)
|
||||
|
@ -486,14 +463,12 @@ DEPENDENCIES:
|
|||
- RNDevMenu (from `../../../node_modules/react-native-dev-menu`)
|
||||
- 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`)
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- boost-for-react-native
|
||||
- CocoaAsyncSocket
|
||||
- Flipper
|
||||
- Flipper-Boost-iOSX
|
||||
|
@ -512,6 +487,8 @@ SPEC REPOS:
|
|||
- YogaKit
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
boost:
|
||||
:podspec: "../../../node_modules/react-native/third-party-podspecs/boost.podspec"
|
||||
DoubleConversion:
|
||||
:podspec: "../../../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
|
||||
FBLazyVector:
|
||||
|
@ -544,6 +521,8 @@ EXTERNAL SOURCES:
|
|||
:path: "../../../node_modules/react-native/ReactCommon/jsiexecutor"
|
||||
React-jsinspector:
|
||||
:path: "../../../node_modules/react-native/ReactCommon/jsinspector"
|
||||
React-logger:
|
||||
:path: "../../../node_modules/react-native/ReactCommon/logger"
|
||||
react-native-cookies:
|
||||
:path: "../../../node_modules/@react-native-cookies/cookies"
|
||||
react-native-restart:
|
||||
|
@ -594,8 +573,6 @@ 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:
|
||||
|
@ -604,12 +581,12 @@ EXTERNAL SOURCES:
|
|||
:path: "../../../node_modules/react-native/ReactCommon/yoga"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
|
||||
boost: a7c83b31436843459a1961bfd74b96033dc77234
|
||||
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
|
||||
DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662
|
||||
FBLazyVector: 33c82491102f20ecddb6c6a2c273696ace3191e0
|
||||
FBReactNativeSpec: df8f81d2a7541ee6755a047b398a5cb5a72acd0e
|
||||
Flipper: b1fddf9a17c32097b2b4c806ad158b2f36bb2692
|
||||
FBLazyVector: e5569e42a1c79ca00521846c223173a57aca1fe1
|
||||
FBReactNativeSpec: fe08c1cd7e2e205718d77ad14b34957cce949b58
|
||||
Flipper: 30e8eeeed6abdc98edaf32af0cda2f198be4b733
|
||||
Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c
|
||||
Flipper-DoubleConversion: 57ffbe81ef95306cc9e69c4aa3aeeeeb58a6a28c
|
||||
Flipper-Fmt: 60cbdd92fc254826e61d669a5d87ef7015396a9b
|
||||
|
@ -617,56 +594,56 @@ SPEC CHECKSUMS:
|
|||
Flipper-Glog: 1dfd6abf1e922806c52ceb8701a3599a79a200a6
|
||||
Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9
|
||||
Flipper-RSocket: d9d9ade67cbecf6ac10730304bf5607266dd2541
|
||||
FlipperKit: aec2d931adeee48a07bab1ea8bcc8a6bb87dfce4
|
||||
FlipperKit: d8d346844eca5d9120c17d441a2f38596e8ed2b9
|
||||
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
|
||||
glog: 5337263514dd6f09803962437687240c5dc39aa4
|
||||
hermes-engine: 7dcd1dbd908e6353bd7e4a4add72dba7bf76bf84
|
||||
hermes-engine: bf7577d12ac6ccf53ab8b5af3c6ccf0dd8458c5c
|
||||
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
|
||||
OpenSSL-Universal: 1aa4f6a6ee7256b83db99ec1ccdaa80d10f9af9b
|
||||
RCT-Folly: 0dd9e1eb86348ecab5ba76f910b56f4b5fef3c46
|
||||
RCTRequired: 6cf071ab2adfd769014b3d94373744ee6e789530
|
||||
RCTTypeSafety: b829c59453478bb5b02487b8de3336386ab93ab1
|
||||
React: 29d8a785041b96a2754c25cc16ddea57b7a618ce
|
||||
React-callinvoker: 2857b61132bd7878b736e282581f4b42fd93002b
|
||||
React-Core: 001e21bad5ca41e59e9d90df5c0b53da04c3ce8e
|
||||
React-CoreModules: 0a0410ab296a62ab38e2f8d321e822d1fcc2fe49
|
||||
React-cxxreact: 8d904967134ae8ff0119c5357c42eaae976806f8
|
||||
React-hermes: ae17bfbf550cefc6331b9544f00b66ad1d9b9d99
|
||||
React-jsi: 12913c841713a15f64eabf5c9ad98592c0ec5940
|
||||
React-jsiexecutor: 43f2542aed3c26e42175b339f8d37fe3dd683765
|
||||
React-jsinspector: 41e58e5b8e3e0bf061fdf725b03f2144014a8fb0
|
||||
RCT-Folly: a21c126816d8025b547704b777a2ba552f3d9fa9
|
||||
RCTRequired: 4bf86c70714490bca4bf2696148638284622644b
|
||||
RCTTypeSafety: c475a7059eb77935fa53d2c17db299893f057d5d
|
||||
React: f64af14e3f2c50f6f2c91a5fd250e4ff1b3c3459
|
||||
React-callinvoker: b74e4ae80287780dcdf0cab262bcb581eeef56e7
|
||||
React-Core: 3eb7432bad96ff1d25aebc1defbae013fee2fd0e
|
||||
React-CoreModules: ad9e1fd5650e16666c57a08328df86fd7e480cb9
|
||||
React-cxxreact: 02633ff398cf7e91a2c1e12590d323c4a4b8668a
|
||||
React-hermes: 7b4c6617b4d4c880d0f44e629651810bf3417440
|
||||
React-jsi: 805c41a927d6499fb811772acb971467d9204633
|
||||
React-jsiexecutor: 94ce921e1d8ce7023366873ec371f3441383b396
|
||||
React-jsinspector: d0374f7509d407d2264168b6d0fad0b54e300b85
|
||||
React-logger: 933f80c97c633ee8965d609876848148e3fef438
|
||||
react-native-cookies: cd92f3824ed1e32a20802e8185101e14bb5b76da
|
||||
react-native-restart: 733a51ad137f15b0f8dc34c4082e55af7da00979
|
||||
react-native-safe-area-context: 584dc04881deb49474363f3be89e4ca0e854c057
|
||||
react-native-simple-toast: bf002828cf816775a6809f7a9ec3907509bce11f
|
||||
react-native-webview: 4c85a3e5de574ee8c2c0985b4bebbdd240f49304
|
||||
React-perflogger: fd28ee1f2b5b150b00043f0301d96bd417fdc339
|
||||
React-RCTActionSheet: 7f3fa0855c346aa5d7c60f9ced16e067db6d29fa
|
||||
React-RCTAnimation: 2119a18ee26159004b001bc56404ca5dbaae6077
|
||||
React-RCTBlob: a493cc306deeaba0c0efa8ecec2da154afd3a798
|
||||
React-RCTImage: 54999ddc896b7db6650af5760607aaebdf30425c
|
||||
React-RCTLinking: 7fb3fa6397d3700c69c3d361870a299f04f1a2e6
|
||||
React-RCTNetwork: 329ee4f75bd2deb8cf6c4b14231b5bb272cbd9af
|
||||
React-RCTSettings: 1a659d58e45719bc77c280dbebce6a5a5a2733f5
|
||||
React-RCTText: e12d7aae2a038be9ae72815436677a7c6549dd26
|
||||
React-RCTVibration: 92d41c2442e5328cc4d342cd7f78e5876b68bae5
|
||||
React-runtimeexecutor: 85187f19dd9c47a7c102f9994f9d14e4dc2110de
|
||||
ReactCommon: eafed38eec7b591c31751bfa7494801618460459
|
||||
react-native-webview: 65f1143983cfeaedf02fd25b2621d3f4a37075de
|
||||
React-perflogger: 93075d8931c32cd1fce8a98c15d2d5ccc4d891bd
|
||||
React-RCTActionSheet: 7d3041e6761b4f3044a37079ddcb156575fb6d89
|
||||
React-RCTAnimation: 743e88b55ac62511ae5c2e22803d4f503f2a3a13
|
||||
React-RCTBlob: bee3a2f98fa7fc25c957c8643494244f74bea0a0
|
||||
React-RCTImage: 19fc9e29b06cc38611c553494f8d3040bf78c24e
|
||||
React-RCTLinking: dc799503979c8c711126d66328e7ce8f25c2848f
|
||||
React-RCTNetwork: 417e4e34cf3c19eaa5fd4e9eb20180d662a799ce
|
||||
React-RCTSettings: 4df89417265af26501a7e0e9192a34d3d9848dff
|
||||
React-RCTText: f8a21c3499ab322326290fa9b701ae29aa093aa5
|
||||
React-RCTVibration: e3ffca672dd3772536cb844274094b0e2c31b187
|
||||
React-runtimeexecutor: dec32ee6f2e2a26e13e58152271535fadff5455a
|
||||
ReactCommon: 57b69f6383eafcbd7da625bfa6003810332313c4
|
||||
RNCalendarEvents: 7e65eb4a94f53c1744d1e275f7fafcfaa619f7a3
|
||||
RNCAsyncStorage: 26f25150da507524a7815f2ada06ca0967f65633
|
||||
RNCAsyncStorage: ea6b5c280997b2b32a587793163b1f10e580c4f7
|
||||
RNCMaskedView: 0e1bc4bfa8365eba5fbbb71e07fbdc0555249489
|
||||
RNDateTimePicker: d943800c936fb01c352fcfb70439550d2cb57092
|
||||
RNDeviceInfo: 8a06046616c6b5c03787b04f265fa3b52b37c80b
|
||||
RNDateTimePicker: 7658208086d86d09e1627b5c34ba0cf237c60140
|
||||
RNDeviceInfo: 0400a6d0c94186d1120c3cbd97b23abc022187a9
|
||||
RNDevMenu: fd325b5554b61fe7f48d9205a3877cf5ee88cd7c
|
||||
RNGestureHandler: a479ebd5ed4221a810967000735517df0d2db211
|
||||
RNLocalize: 74b82db20cc3895ccc25af992c644879bcec2815
|
||||
RNReanimated: ad24db8af24e3fe1b5c462785bc3db8d5baae2ee
|
||||
RNScreens: 6e1ea5787989f92b0671049b808aef64fa1ef98c
|
||||
RNScreens: 522705f2e5c9d27efb17f24aceb2bf8335bc7b8e
|
||||
RNSVG: 551acb6562324b1d52a4e0758f7ca0ec234e278f
|
||||
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
|
||||
Yoga: aa0cb45287ebe1004c02a13f279c55a95f1572f4
|
||||
Yoga: e7dc4e71caba6472ff48ad7d234389b91dadc280
|
||||
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
|
||||
|
||||
PODFILE CHECKSUM: 85f5a2dfa1de342b427eecb6e9652410ad153247
|
||||
PODFILE CHECKSUM: f4a92b32cc4938e15ad7ccfefe9898548670abed
|
||||
|
||||
COCOAPODS: 1.11.2
|
||||
COCOAPODS: 1.14.2
|
||||
|
|
|
@ -18,16 +18,17 @@
|
|||
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 */; };
|
||||
396C853D94F21C9E71483239 /* libPods-app.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 21034B85416DDF53CD4A00FA /* libPods-app.a */; };
|
||||
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 */; };
|
||||
4B6D9413033C6B65C597B819 /* libPods-app-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CA8A8BD6F8C7BC6366166C15 /* libPods-app-tvOS.a */; };
|
||||
4BB26748C145FA87530C159D /* libPods-app-tvOSTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A67482C4D50CE862D4EC4B2D /* libPods-app-tvOSTests.a */; };
|
||||
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 */; };
|
||||
66A70BA94C13C762C2FC5598 /* libPods-app-appTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B46437C19062013F6FD7F8DF /* libPods-app-appTests.a */; };
|
||||
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 */; };
|
||||
74DBFC87140229C837878334 /* libPods-app.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E9B636E3ED8EC4AE22911F88 /* libPods-app.a */; };
|
||||
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 */; };
|
||||
|
@ -35,9 +36,8 @@
|
|||
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 */; };
|
||||
AC5E863985C04D72B5806B58 /* Poppins-Thin.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 02B78F6C72354B2D8171239D /* Poppins-Thin.ttf */; };
|
||||
BB2CC29458B6EBEA4EC8507D /* libPods-app-appTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 877C88C7EC6AD818C99BCB01 /* libPods-app-appTests.a */; };
|
||||
BB34E03413EB4CDFA59766B1 /* Poppins-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = EB6EB5293E4C48098CBD53C2 /* Poppins-Regular.ttf */; };
|
||||
DBED7279FA83AE4A79481FC9 /* libPods-app-tvOSTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ABEF12A4A3B3A2C7329D1ED0 /* libPods-app-tvOSTests.a */; };
|
||||
D9A688C68D71990DBF425FA2 /* libPods-app-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27818727F387611C0C8951E2 /* libPods-app-tvOS.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
|
@ -70,36 +70,36 @@
|
|||
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = app/Images.xcassets; sourceTree = "<group>"; };
|
||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = app/Info.plist; sourceTree = "<group>"; };
|
||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = app/main.m; sourceTree = "<group>"; };
|
||||
21034B85416DDF53CD4A00FA /* libPods-app.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-app.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
22E5888AE757447912CDB7D9 /* 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>"; };
|
||||
2297ED9A3C8497165F09C27E /* 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>"; };
|
||||
231B760691854EBCA7ECD80E /* Poppins-Light.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-Light.ttf"; path = "../assets/fonts/Poppins-Light.ttf"; sourceTree = "<group>"; };
|
||||
2C758CF60717F789E215351B /* 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>"; };
|
||||
27818727F387611C0C8951E2 /* libPods-app-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-app-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
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; };
|
||||
3505CFF0878CC2BFDF1B381B /* 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>"; };
|
||||
35E90F515AEBDD6DCB442FD0 /* 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>"; };
|
||||
3CBFE8DBE8994C1FAF939519 /* Poppins-MediumItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-MediumItalic.ttf"; path = "../assets/fonts/Poppins-MediumItalic.ttf"; sourceTree = "<group>"; };
|
||||
4EB754103D4A239F3D98709A /* 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>"; };
|
||||
480F15B3D99E8341B00E86B0 /* 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 = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-Bold.ttf"; path = "../assets/fonts/Poppins-Bold.ttf"; sourceTree = "<group>"; };
|
||||
6A54524E854BB9CE89DC6EA4 /* 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>"; };
|
||||
7AF5677EA52D44EE97668E7A /* Poppins-Medium.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-Medium.ttf"; path = "../assets/fonts/Poppins-Medium.ttf"; sourceTree = "<group>"; };
|
||||
7C6621BA350DC8DD8E6E0D1F /* 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>"; };
|
||||
7CEBAD12E8E5471AA962262A /* Poppins-LightItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; 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>"; };
|
||||
877C88C7EC6AD818C99BCB01 /* libPods-app-appTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-app-appTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
89E628D70CB48A53EF3F0503 /* 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>"; };
|
||||
8E2BDC4163F1467E94E5D34C /* Poppins-BoldItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; 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 = 9; 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 = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-ExtraLightItalic.ttf"; path = "../assets/fonts/Poppins-ExtraLightItalic.ttf"; sourceTree = "<group>"; };
|
||||
964D41355E5C9FDD3B6D2D48 /* 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>"; };
|
||||
977D264ECA05485EA89A2F13 /* Poppins-Italic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-Italic.ttf"; path = "../assets/fonts/Poppins-Italic.ttf"; sourceTree = "<group>"; };
|
||||
99074C304C5170EE3D76AC01 /* 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>"; };
|
||||
9A9C27037F0F4AF2A4CBAE78 /* Poppins-ExtraBold.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; 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 = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-ExtraBoldItalic.ttf"; path = "../assets/fonts/Poppins-ExtraBoldItalic.ttf"; sourceTree = "<group>"; };
|
||||
A67482C4D50CE862D4EC4B2D /* libPods-app-tvOSTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-app-tvOSTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A9CB7679337840D3BD256A13 /* Poppins-SemiBoldItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-SemiBoldItalic.ttf"; path = "../assets/fonts/Poppins-SemiBoldItalic.ttf"; sourceTree = "<group>"; };
|
||||
ABEF12A4A3B3A2C7329D1ED0 /* libPods-app-tvOSTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-app-tvOSTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
AF5E4A097A8E6764B413FA6A /* 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>"; };
|
||||
B1A304CF782943E19F93DFD6 /* Poppins-Black.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-Black.ttf"; path = "../assets/fonts/Poppins-Black.ttf"; sourceTree = "<group>"; };
|
||||
B46437C19062013F6FD7F8DF /* libPods-app-appTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-app-appTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
C9AC377D6B7744ECBBEA0A8A /* Poppins-ExtraLight.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-ExtraLight.ttf"; path = "../assets/fonts/Poppins-ExtraLight.ttf"; sourceTree = "<group>"; };
|
||||
CA8A8BD6F8C7BC6366166C15 /* libPods-app-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-app-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
CD38F02B81696E6FDD220929 /* 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>"; };
|
||||
DABA3CEEE3E409DF2F75F8E2 /* 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>"; };
|
||||
D8118F8211409B6E89A7CF5C /* 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>"; };
|
||||
E251C7BB03F74441B4357419 /* Poppins-ThinItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Poppins-ThinItalic.ttf"; path = "../assets/fonts/Poppins-ThinItalic.ttf"; sourceTree = "<group>"; };
|
||||
E9B636E3ED8EC4AE22911F88 /* libPods-app.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-app.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
EB6EB5293E4C48098CBD53C2 /* Poppins-Regular.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; 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; };
|
||||
|
@ -110,7 +110,7 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
BB2CC29458B6EBEA4EC8507D /* libPods-app-appTests.a in Frameworks */,
|
||||
66A70BA94C13C762C2FC5598 /* libPods-app-appTests.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -118,7 +118,7 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
396C853D94F21C9E71483239 /* libPods-app.a in Frameworks */,
|
||||
74DBFC87140229C837878334 /* libPods-app.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -126,7 +126,7 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
4B6D9413033C6B65C597B819 /* libPods-app-tvOS.a in Frameworks */,
|
||||
D9A688C68D71990DBF425FA2 /* libPods-app-tvOS.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -134,7 +134,7 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
DBED7279FA83AE4A79481FC9 /* libPods-app-tvOSTests.a in Frameworks */,
|
||||
4BB26748C145FA87530C159D /* libPods-app-tvOSTests.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -177,10 +177,10 @@
|
|||
children = (
|
||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
|
||||
ED2971642150620600B7C4FE /* JavaScriptCore.framework */,
|
||||
21034B85416DDF53CD4A00FA /* libPods-app.a */,
|
||||
877C88C7EC6AD818C99BCB01 /* libPods-app-appTests.a */,
|
||||
CA8A8BD6F8C7BC6366166C15 /* libPods-app-tvOS.a */,
|
||||
ABEF12A4A3B3A2C7329D1ED0 /* libPods-app-tvOSTests.a */,
|
||||
E9B636E3ED8EC4AE22911F88 /* libPods-app.a */,
|
||||
B46437C19062013F6FD7F8DF /* libPods-app-appTests.a */,
|
||||
27818727F387611C0C8951E2 /* libPods-app-tvOS.a */,
|
||||
A67482C4D50CE862D4EC4B2D /* libPods-app-tvOSTests.a */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
|
@ -188,14 +188,14 @@
|
|||
678C13018B6095451BF5FE91 /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
AF5E4A097A8E6764B413FA6A /* Pods-app.debug.xcconfig */,
|
||||
22E5888AE757447912CDB7D9 /* Pods-app.release.xcconfig */,
|
||||
6A54524E854BB9CE89DC6EA4 /* Pods-app-appTests.debug.xcconfig */,
|
||||
4EB754103D4A239F3D98709A /* Pods-app-appTests.release.xcconfig */,
|
||||
7C6621BA350DC8DD8E6E0D1F /* Pods-app-tvOS.debug.xcconfig */,
|
||||
CD38F02B81696E6FDD220929 /* Pods-app-tvOS.release.xcconfig */,
|
||||
2C758CF60717F789E215351B /* Pods-app-tvOSTests.debug.xcconfig */,
|
||||
DABA3CEEE3E409DF2F75F8E2 /* Pods-app-tvOSTests.release.xcconfig */,
|
||||
35E90F515AEBDD6DCB442FD0 /* Pods-app.debug.xcconfig */,
|
||||
2297ED9A3C8497165F09C27E /* Pods-app.release.xcconfig */,
|
||||
89E628D70CB48A53EF3F0503 /* Pods-app-appTests.debug.xcconfig */,
|
||||
D8118F8211409B6E89A7CF5C /* Pods-app-appTests.release.xcconfig */,
|
||||
3505CFF0878CC2BFDF1B381B /* Pods-app-tvOS.debug.xcconfig */,
|
||||
964D41355E5C9FDD3B6D2D48 /* Pods-app-tvOS.release.xcconfig */,
|
||||
480F15B3D99E8341B00E86B0 /* Pods-app-tvOSTests.debug.xcconfig */,
|
||||
99074C304C5170EE3D76AC01 /* Pods-app-tvOSTests.release.xcconfig */,
|
||||
);
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
|
@ -266,12 +266,12 @@
|
|||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "appTests" */;
|
||||
buildPhases = (
|
||||
17CBB087351FE0C9C0D79621 /* [CP] Check Pods Manifest.lock */,
|
||||
E621AE2A6DC50308E77A360C /* [CP] Check Pods Manifest.lock */,
|
||||
00E356EA1AD99517003FC87E /* Sources */,
|
||||
00E356EB1AD99517003FC87E /* Frameworks */,
|
||||
00E356EC1AD99517003FC87E /* Resources */,
|
||||
C58D5F8233E8DDBE21C88441 /* [CP] Embed Pods Frameworks */,
|
||||
E2F9EE5B9DA43CE520BE51D9 /* [CP] Copy Pods Resources */,
|
||||
9A78978E978BDD0B2A2A5182 /* [CP] Embed Pods Frameworks */,
|
||||
CA136FCDFCFF83364CA590B8 /* [CP] Copy Pods Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
|
@ -287,14 +287,14 @@
|
|||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "app" */;
|
||||
buildPhases = (
|
||||
4DE98BA6A020DE0B45B7087E /* [CP] Check Pods Manifest.lock */,
|
||||
62F3CB512A74524FEBA1B91C /* [CP] Check Pods Manifest.lock */,
|
||||
FD10A7F022414F080027D42C /* Start Packager */,
|
||||
13B07F871A680F5B00A75B9A /* Sources */,
|
||||
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
|
||||
761DD61FA10ADE9ED4804000 /* [CP] Embed Pods Frameworks */,
|
||||
E317D40B738F0883A7F3BF92 /* [CP] Copy Pods Resources */,
|
||||
D906F806C07FB1841A6CA9EC /* [CP] Embed Pods Frameworks */,
|
||||
C412CA7FABDF37E4FC1F0226 /* [CP] Copy Pods Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
|
@ -309,7 +309,7 @@
|
|||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "app-tvOS" */;
|
||||
buildPhases = (
|
||||
3146D9392EF677DBBE6B9223 /* [CP] Check Pods Manifest.lock */,
|
||||
BF6AB0357F369E40AED7D871 /* [CP] Check Pods Manifest.lock */,
|
||||
FD10A7F122414F3F0027D42C /* Start Packager */,
|
||||
2D02E4771E0B4A5D006451C7 /* Sources */,
|
||||
2D02E4781E0B4A5D006451C7 /* Frameworks */,
|
||||
|
@ -329,7 +329,7 @@
|
|||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "app-tvOSTests" */;
|
||||
buildPhases = (
|
||||
0D9913ADEC9198115BFBE990 /* [CP] Check Pods Manifest.lock */,
|
||||
82304D3A429EA83518C55FD9 /* [CP] Check Pods Manifest.lock */,
|
||||
2D02E48C1E0B4A5D006451C7 /* Sources */,
|
||||
2D02E48D1E0B4A5D006451C7 /* Frameworks */,
|
||||
2D02E48E1E0B4A5D006451C7 /* Resources */,
|
||||
|
@ -383,6 +383,7 @@
|
|||
pl,
|
||||
ar,
|
||||
so,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 83CBB9F61A601CBA00E9B192;
|
||||
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
|
||||
|
@ -464,50 +465,6 @@
|
|||
shellPath = /bin/sh;
|
||||
shellScript = "export NODE_BINARY=node\nexport ENTRY_FILE=index.js\nexport EXTRA_PACKAGER_ARGS=\"--entry-file apps/skolplattformen-app/index.js\"\n../node_modules/react-native/scripts/react-native-xcode.sh\n";
|
||||
};
|
||||
0D9913ADEC9198115BFBE990 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-app-tvOSTests-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
17CBB087351FE0C9C0D79621 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-app-appTests-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
2D02E4CB1E0B4B27006451C7 /* Bundle React Native Code And Images */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -522,29 +479,7 @@
|
|||
shellPath = /bin/sh;
|
||||
shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh";
|
||||
};
|
||||
3146D9392EF677DBBE6B9223 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-app-tvOS-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
4DE98BA6A020DE0B45B7087E /* [CP] Check Pods Manifest.lock */ = {
|
||||
62F3CB512A74524FEBA1B91C /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
|
@ -566,29 +501,29 @@
|
|||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
761DD61FA10ADE9ED4804000 /* [CP] Embed Pods Frameworks */ = {
|
||||
82304D3A429EA83518C55FD9 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-app/Pods-app-frameworks.sh",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/double-conversion/double-conversion.framework/double-conversion",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL/OpenSSL.framework/OpenSSL",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes/hermes.framework/hermes",
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/double-conversion.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
|
||||
"$(DERIVED_FILE_DIR)/Pods-app-tvOSTests-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-app/Pods-app-frameworks.sh\"\n";
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
C58D5F8233E8DDBE21C88441 /* [CP] Embed Pods Frameworks */ = {
|
||||
9A78978E978BDD0B2A2A5182 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
|
@ -610,7 +545,47 @@
|
|||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-app-appTests/Pods-app-appTests-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
E2F9EE5B9DA43CE520BE51D9 /* [CP] Copy Pods Resources */ = {
|
||||
BF6AB0357F369E40AED7D871 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-app-tvOS-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
C412CA7FABDF37E4FC1F0226 /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-app/Pods-app-resources.sh",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-app/Pods-app-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
CA136FCDFCFF83364CA590B8 /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
|
@ -628,22 +603,48 @@
|
|||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-app-appTests/Pods-app-appTests-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
E317D40B738F0883A7F3BF92 /* [CP] Copy Pods Resources */ = {
|
||||
D906F806C07FB1841A6CA9EC /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-app/Pods-app-resources.sh",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
|
||||
"${PODS_ROOT}/Target Support Files/Pods-app/Pods-app-frameworks.sh",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/double-conversion/double-conversion.framework/double-conversion",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL/OpenSSL.framework/OpenSSL",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes/hermes.framework/hermes",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/double-conversion.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-app/Pods-app-resources.sh\"\n";
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-app/Pods-app-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
E621AE2A6DC50308E77A360C /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-app-appTests-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
FD10A7F022414F080027D42C /* Start Packager */ = {
|
||||
|
@ -739,7 +740,7 @@
|
|||
/* Begin XCBuildConfiguration section */
|
||||
00E356F61AD99517003FC87E /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 6A54524E854BB9CE89DC6EA4 /* Pods-app-appTests.debug.xcconfig */;
|
||||
baseConfigurationReference = 89E628D70CB48A53EF3F0503 /* Pods-app-appTests.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
|
@ -762,7 +763,7 @@
|
|||
};
|
||||
00E356F71AD99517003FC87E /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 4EB754103D4A239F3D98709A /* Pods-app-appTests.release.xcconfig */;
|
||||
baseConfigurationReference = D8118F8211409B6E89A7CF5C /* Pods-app-appTests.release.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
|
@ -782,7 +783,7 @@
|
|||
};
|
||||
13B07F941A680F5B00A75B9A /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = AF5E4A097A8E6764B413FA6A /* Pods-app.debug.xcconfig */;
|
||||
baseConfigurationReference = 35E90F515AEBDD6DCB442FD0 /* Pods-app.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
|
@ -793,7 +794,7 @@
|
|||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = app/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
MARKETING_VERSION = 3.0.1;
|
||||
MARKETING_VERSION = 3.0.10;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
|
@ -811,7 +812,7 @@
|
|||
};
|
||||
13B07F951A680F5B00A75B9A /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 22E5888AE757447912CDB7D9 /* Pods-app.release.xcconfig */;
|
||||
baseConfigurationReference = 2297ED9A3C8497165F09C27E /* Pods-app.release.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
|
@ -822,7 +823,7 @@
|
|||
DEVELOPMENT_TEAM = "";
|
||||
INFOPLIST_FILE = app/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
MARKETING_VERSION = 3.0.1;
|
||||
MARKETING_VERSION = 3.0.10;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
|
@ -839,7 +840,7 @@
|
|||
};
|
||||
2D02E4971E0B4A5E006451C7 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 7C6621BA350DC8DD8E6E0D1F /* Pods-app-tvOS.debug.xcconfig */;
|
||||
baseConfigurationReference = 3505CFF0878CC2BFDF1B381B /* Pods-app-tvOS.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
|
||||
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
|
||||
|
@ -867,7 +868,7 @@
|
|||
};
|
||||
2D02E4981E0B4A5E006451C7 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = CD38F02B81696E6FDD220929 /* Pods-app-tvOS.release.xcconfig */;
|
||||
baseConfigurationReference = 964D41355E5C9FDD3B6D2D48 /* Pods-app-tvOS.release.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
|
||||
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
|
||||
|
@ -895,7 +896,7 @@
|
|||
};
|
||||
2D02E4991E0B4A5E006451C7 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 2C758CF60717F789E215351B /* Pods-app-tvOSTests.debug.xcconfig */;
|
||||
baseConfigurationReference = 480F15B3D99E8341B00E86B0 /* Pods-app-tvOSTests.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
|
@ -922,7 +923,7 @@
|
|||
};
|
||||
2D02E49A1E0B4A5E006451C7 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = DABA3CEEE3E409DF2F75F8E2 /* Pods-app-tvOSTests.release.xcconfig */;
|
||||
baseConfigurationReference = 99074C304C5170EE3D76AC01 /* Pods-app-tvOSTests.release.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
|
@ -998,10 +999,10 @@
|
|||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"\"$(SDKROOT)/usr/lib/swift\"",
|
||||
"\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
|
||||
"\"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)\"",
|
||||
"\"$(inherited)\"",
|
||||
"\"$(SDKROOT)/usr/lib/swift\"",
|
||||
);
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
|
|
|
@ -60,7 +60,6 @@
|
|||
"react-native-localize": "*",
|
||||
"react-native-markdown-display": "7.0.*",
|
||||
"react-native-modal-datetime-picker": "*",
|
||||
"react-native-reanimated": "*",
|
||||
"react-native-restart": "*",
|
||||
"react-native-safe-area-context": "*",
|
||||
"react-native-screens": "*",
|
||||
|
@ -75,7 +74,16 @@
|
|||
"regenerator-runtime": "*",
|
||||
"tough-cookie": "*",
|
||||
"valtio": "*",
|
||||
"yup": "*"
|
||||
"yup": "*",
|
||||
"@react-navigation/native-stack": "*",
|
||||
"@formatjs/intl-getcanonicallocales": "*",
|
||||
"@formatjs/intl-locale": "*",
|
||||
"@formatjs/intl-numberformat": "*",
|
||||
"@formatjs/intl-pluralrules": "*",
|
||||
"@formatjs/intl-datetimeformat": "*",
|
||||
"jest": "*",
|
||||
"react-native-clean-project": "*",
|
||||
"mockdate": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"react-native-clean-project": "*"
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
{
|
||||
"root": "apps/skolplattformen-app",
|
||||
"sourceRoot": "apps/skolplattformen-app/src",
|
||||
"projectType": "application",
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@nrwl/react-native:bundle",
|
||||
"outputs": ["apps/skolplattformen-app/build"],
|
||||
"options": {
|
||||
"entryFile": "apps/skolplattformen-app/index.js",
|
||||
"platform": "ios",
|
||||
"bundleOutput": "dist/apps/skolplattformen-app/ios/main.jsbundle"
|
||||
}
|
||||
},
|
||||
"start": {
|
||||
"executor": "@nrwl/react-native:start",
|
||||
"options": {
|
||||
"port": 8081
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"executor": "@nrwl/workspace:run-commands",
|
||||
"options": {
|
||||
"command": "nx start skolplattformen"
|
||||
}
|
||||
},
|
||||
"run-ios": {
|
||||
"executor": "@nrwl/react-native:run-ios",
|
||||
"options": {}
|
||||
},
|
||||
"bundle-ios": {
|
||||
"executor": "@nrwl/react-native:bundle",
|
||||
"outputs": ["apps/skolplattformen-app/build"],
|
||||
"options": {
|
||||
"entryFile": "apps/skolplattformen-app/index.js",
|
||||
"platform": "ios",
|
||||
"bundleOutput": "dist/apps/skolplattformen-app/ios/main.jsbundle"
|
||||
}
|
||||
},
|
||||
"run-android": {
|
||||
"executor": "@nrwl/react-native:run-android",
|
||||
"options": {}
|
||||
},
|
||||
"build-android": {
|
||||
"executor": "@nrwl/react-native:build-android",
|
||||
"outputs": [
|
||||
"apps/skolplattformen-app/android/app/build/outputs/bundle",
|
||||
"apps/skolplattformen-app/android/app/build/outputs/apk"
|
||||
],
|
||||
"options": {}
|
||||
},
|
||||
"bundle-android": {
|
||||
"executor": "@nrwl/react-native:bundle",
|
||||
"options": {
|
||||
"entryFile": "apps/skolplattformen-app/index.js",
|
||||
"platform": "android",
|
||||
"bundleOutput": "dist/apps/skolplattformen-app/android/main.jsbundle"
|
||||
}
|
||||
},
|
||||
"sync-deps": {
|
||||
"executor": "@nrwl/react-native:sync-deps",
|
||||
"options": {}
|
||||
},
|
||||
"ensure-symlink": {
|
||||
"executor": "@nrwl/react-native:ensure-symlink",
|
||||
"options": {}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nrwl/linter:eslint",
|
||||
"outputs": ["{options.outputFile}"],
|
||||
"options": {
|
||||
"lintFilePatterns": ["apps/skolplattformen-app/**/*.{ts,tsx,js,jsx}"]
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"executor": "@nrwl/jest:jest",
|
||||
"outputs": ["coverage/apps/skolplattformen-app"],
|
||||
"options": {
|
||||
"jestConfig": "apps/skolplattformen-app/jest.config.js",
|
||||
"passWithNoTests": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [],
|
||||
"implicitDependencies": [
|
||||
"api-skolplattformen",
|
||||
"api-hjarntorget",
|
||||
"api",
|
||||
"hooks",
|
||||
"curriculum"
|
||||
]
|
||||
}
|
|
@ -14,6 +14,8 @@ import 'moment/locale/pl'
|
|||
import 'moment/locale/pt'
|
||||
import 'moment/locale/ru'
|
||||
import 'moment/locale/sv'
|
||||
import 'moment/locale/th'
|
||||
import 'moment/locale/uk'
|
||||
import 'moment/locale/zh-cn'
|
||||
import { I18nManager } from 'react-native'
|
||||
import { languages } from '../utils/translation'
|
||||
|
|
|
@ -11,19 +11,6 @@ jest.mock('@skolplattformen/hooks')
|
|||
// Silence useNativeDriver error
|
||||
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper')
|
||||
|
||||
jest.mock('react-native-reanimated', () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
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 = () => {
|
||||
// noop
|
||||
}
|
||||
|
||||
return Reanimated
|
||||
})
|
||||
|
||||
jest.mock('@react-navigation/native')
|
||||
jest.mock('@react-navigation/core')
|
||||
jest.mock('react-native-localize')
|
||||
|
|
|
@ -13,13 +13,14 @@
|
|||
"selectAbscenseEndTime": "Endzeit wählen",
|
||||
"selectAbscenseStartTime": "Startzeit wählen",
|
||||
"startTime": "Startzeit",
|
||||
"title": "Abwesenheit anmelden"
|
||||
"title": "Abwesenheit anmelden",
|
||||
"childsPersonalNumber": "Personenkennziffer des Kindes"
|
||||
},
|
||||
"auth": {
|
||||
"bankid": {
|
||||
"OpenManually": "BankID manuell öffnen",
|
||||
"OpenOnAnotherDevice": "BankID auf einem anderen Gerät benutzen",
|
||||
"OpenOnThisDevice": "BankID auf diesem Gerät benutzen",
|
||||
"OpenOnAnotherDevice": "BankID auf einem anderen Gerät öffnen",
|
||||
"OpenOnThisDevice": "BankID auf diesem Gerät öffnen",
|
||||
"Waiting": "Wartet auf BankID…"
|
||||
},
|
||||
"chooseLoginMethod": "Anmeldemethode auswählen",
|
||||
|
@ -49,14 +50,23 @@
|
|||
"a11y_select_login_method": "Wähle die Anmeldemethode",
|
||||
"a11y_clear_social_security_input_field": "Personenkennziffer-Feld löschen",
|
||||
"a11y_image_two_boys": "Bild von zwei Personen, die ihre Mobiltelefon überprüfen",
|
||||
"a11y_change_language": "Wähle deine Sprache"
|
||||
"a11y_change_language": "Wähle deine Sprache",
|
||||
"chooseSchoolPlatform": "Plattform wählen",
|
||||
"freja": {
|
||||
"Waiting": "Wartet auf Freja eID+…",
|
||||
"OpenManually": "Freja eID+ manuell öffnen",
|
||||
"OpenOnThisDevice": "Freja eID+ auf diesem Gerät öffnen"
|
||||
},
|
||||
"loginSuccessful": "Eingeloggt, wird geladen…"
|
||||
},
|
||||
"calender": {
|
||||
"approveAccessToCalender": "Du musst Zugriff auf deinen Kalender erlauben",
|
||||
"saveToCalender": "Im Kalender speichern",
|
||||
"saveToCalenderError": "Ein Fehler ist aufgetreten",
|
||||
"saveToCalenderSuccess": "✔️ Im Kalender gespeichert",
|
||||
"showCalenderActions": "Kalender-Actions zeigen"
|
||||
"showCalenderActions": "Kalender-Actions zeigen",
|
||||
"emptyHeadline": "Der Kalender sieht leer aus",
|
||||
"emptyText": "Nichts wurde gefunden"
|
||||
},
|
||||
"children": {
|
||||
"loadingErrorHeading": "Hoppla!",
|
||||
|
@ -78,7 +88,8 @@
|
|||
"title": "Öppna skolplattformen",
|
||||
"cancel": "Abbrechen",
|
||||
"logoutAndClearPersonalData": "Ausloggen und persönliche Daten löschen",
|
||||
"logoutAndClearAllDataInclSettings": "Ausloggen und alle Daten inkl. Einstellungen löschen"
|
||||
"logoutAndClearAllDataInclSettings": "Ausloggen und alle Daten inkl. Einstellungen löschen",
|
||||
"tomorrow": "Morgen"
|
||||
},
|
||||
"language": {
|
||||
"changeLanguage": "Sprache ändern",
|
||||
|
@ -113,7 +124,8 @@
|
|||
"gymBag": "Turnbeutel",
|
||||
"lunch": "Mittagessen",
|
||||
"end": "Ende",
|
||||
"start": "Anfang"
|
||||
"start": "Anfang",
|
||||
"week": "Woche"
|
||||
},
|
||||
"contact": {
|
||||
"a11y_show_contact_info_button_hint": "Zeigt Kontaktinformation an",
|
||||
|
|
|
@ -23,10 +23,16 @@
|
|||
"OpenOnThisDevice": "Open BankID on this device",
|
||||
"Waiting": "Waiting for BankID…"
|
||||
},
|
||||
"freja": {
|
||||
"OpenManually": "Open Freja eID+ manually",
|
||||
"OpenOnThisDevice": "Open Freja eID+ on this device",
|
||||
"Waiting": "Waiting for Freja eID+…"
|
||||
},
|
||||
"chooseLoginMethod": "Choose login method",
|
||||
"chooseSchoolPlatform": "Choose platform",
|
||||
"loginAsTestUser": "Log in as a test user",
|
||||
"loginFailed": "Could not log in. Please try again.",
|
||||
"loginSuccessful": "Login successful, loading…",
|
||||
"placeholder_SocialSecurityNumber": "Your personal identity number",
|
||||
"subtitle": "The {{word}} alternative",
|
||||
"words": {
|
||||
|
@ -58,7 +64,9 @@
|
|||
"saveToCalender": "Save in calendar",
|
||||
"saveToCalenderError": "Something went wrong",
|
||||
"saveToCalenderSuccess": "✔️ Saved in calendar",
|
||||
"showCalenderActions": "Show calendar actions"
|
||||
"showCalenderActions": "Show calendar actions",
|
||||
"emptyHeadline": "The calendar looks kinda empty",
|
||||
"emptyText": "Couldn't find anything to show"
|
||||
},
|
||||
"children": {
|
||||
"loadingErrorHeading": "Oops!",
|
||||
|
@ -80,7 +88,8 @@
|
|||
"send": "Send",
|
||||
"settings": "Settings",
|
||||
"socialSecurityNumber": "Personal identity number",
|
||||
"title": "Öppna skolplattformen"
|
||||
"title": "Öppna skolplattformen",
|
||||
"tomorrow": "Tomorrow"
|
||||
},
|
||||
"language": {
|
||||
"changeLanguage": "Change language",
|
||||
|
@ -128,7 +137,8 @@
|
|||
"start": "Start",
|
||||
"end": "End",
|
||||
"lunch": "Lunch",
|
||||
"gymBag": "Gym bag"
|
||||
"gymBag": "Gym bag",
|
||||
"week": "Week"
|
||||
},
|
||||
"classmates": {
|
||||
"class": "Class",
|
||||
|
|
|
@ -4,13 +4,18 @@
|
|||
"noNewNewsItemsThisWeek": "No hay noticias nuevas esta semana.",
|
||||
"backToChild": "Volver al niño",
|
||||
"title": "Noticias de Skolplattformen",
|
||||
"published": "Publicada"
|
||||
"published": "Publicada",
|
||||
"updated": "Actualizado",
|
||||
"search": {
|
||||
"placeholder": "Buscar en las noticias…"
|
||||
}
|
||||
},
|
||||
"navigation": {
|
||||
"notifications": "Notificaciones",
|
||||
"news": "Noticias",
|
||||
"calender": "Calendario",
|
||||
"menu": "Menú"
|
||||
"menu": "Menú",
|
||||
"classmates": "Compañeros de clase"
|
||||
},
|
||||
"language": {
|
||||
"changeLanguage": "Cambiar idioma",
|
||||
|
@ -25,20 +30,28 @@
|
|||
"loading": "Cargando…",
|
||||
"confirm": "Confirmar",
|
||||
"title": "Öppna skolplattformen",
|
||||
"cancel": "Anular"
|
||||
"cancel": "Anular",
|
||||
"tomorrow": "Mañana",
|
||||
"logoutAndClearPersonalData": "Cierre la sesión y borre sus datos personales",
|
||||
"logoutAndClearAllDataInclSettings": "Cierre la sesión y borre todos sus datos incluyendo sus configuraciones"
|
||||
},
|
||||
"children": {
|
||||
"viewStatus": "Ver estado en skolplattformen.org",
|
||||
"tryAgain": "Intentar otra vez",
|
||||
"title": "Tus hijos",
|
||||
"noKids_title": "Sin niños"
|
||||
"noKids_title": "Sin niños",
|
||||
"loadingErrorHeading": "¡Ahijoles!",
|
||||
"loadingErrorInformationText": "La página no pudo ser cargada. Intente de nuevo o mire su estado actual en skolplattformen.org.",
|
||||
"noKids_description": "No hay infantes registrados en la ciudad de Estocolmo con su número de identificación personal"
|
||||
},
|
||||
"calender": {
|
||||
"showCalenderActions": "Mostrar acciones de calendario",
|
||||
"saveToCalenderSuccess": "✔️ Guardado en el calendario",
|
||||
"saveToCalenderError": "Algo salió mal",
|
||||
"saveToCalender": "Guardar en calendario",
|
||||
"approveAccessToCalender": "Tienes que aprobar el acceso a tu calendario"
|
||||
"approveAccessToCalender": "Tienes que aprobar el acceso a tu calendario",
|
||||
"emptyText": "No hay algo que mostrar",
|
||||
"emptyHeadline": "El calendario está un poco vacío"
|
||||
},
|
||||
"auth": {
|
||||
"words": {
|
||||
|
@ -56,10 +69,12 @@
|
|||
"cheap": "barato",
|
||||
"better": "mejor",
|
||||
"homemade": "artesanal",
|
||||
"open": "abierto"
|
||||
"open": "abierto",
|
||||
"fast": "rápida",
|
||||
"fun": "divertido"
|
||||
},
|
||||
"subtitle": "La alternativa {{word}}",
|
||||
"placeholder_SocialSecurityNumber": "Tu personnummer",
|
||||
"subtitle": "La alternativa de {{word}}",
|
||||
"placeholder_SocialSecurityNumber": "Tu número de identidad personal",
|
||||
"loginFailed": "No se pudo iniciar sesión. Vuelva a intentarlo.",
|
||||
"chooseLoginMethod": "Elija el método de inicio de sesión",
|
||||
"bankid": {
|
||||
|
@ -70,17 +85,27 @@
|
|||
},
|
||||
"loginAsTestUser": "Inicie sesión como usuario de pruebas",
|
||||
"a11y_change_language": "Elija su idioma",
|
||||
"a11y_image_two_boys": "Fotografia de dos personas mirando su telefono movil"
|
||||
"a11y_image_two_boys": "Fotografia de dos personas mirando su telefono movil",
|
||||
"chooseSchoolPlatform": "Elija la plataforma",
|
||||
"a11y_clear_social_security_input_field": "Borrar el campo del número de identificación personal",
|
||||
"loginSuccessful": "Se ha iniciado la sesión correctamente, cargando…",
|
||||
"freja": {
|
||||
"OpenManually": "Abrir Freja eID+ manualmente",
|
||||
"OpenOnThisDevice": "Abrir Freja eID+ en este dispositivo",
|
||||
"Waiting": "Esperando a Freja eID+…"
|
||||
},
|
||||
"a11y_select_login_method": "Seleccione el metodo para iniciar sesión"
|
||||
},
|
||||
"abscense": {
|
||||
"title": "Informar ausencia",
|
||||
"startTime": "hora de inicio",
|
||||
"selectAbscenseStartTime": "Elige la hora de inicio",
|
||||
"personalNumberMissing": "Falta el personnummer",
|
||||
"invalidPersonalNumber": "El personnumer no es válido",
|
||||
"personalNumberMissing": "Falta el número personal",
|
||||
"invalidPersonalNumber": "Número personal inválido",
|
||||
"entireDay": "Día completo",
|
||||
"endTime": "hora de finalización",
|
||||
"selectAbscenseEndTime": "Elige la hora de finalización"
|
||||
"selectAbscenseEndTime": "Elige hora de finalización",
|
||||
"childsPersonalNumber": "Numero de identificación del infante (personnummer)"
|
||||
},
|
||||
"abbrevations": {
|
||||
"upperSecondarySchool": "Escuela Secundaria Obligatoria",
|
||||
|
@ -90,5 +115,42 @@
|
|||
},
|
||||
"notifications": {
|
||||
"notificationTitle": "Notificación: {{message}} ({{dateCreated}})"
|
||||
},
|
||||
"contact": {
|
||||
"home": "Dirección",
|
||||
"email": "Correo electrónico",
|
||||
"call": "Llamar",
|
||||
"a11y_show_contact_info_button_label": "Mostrar información de contacto",
|
||||
"a11y_show_contact_info_button_hint": "Muestra información de contacto",
|
||||
"sms": "Mensaje de texto"
|
||||
},
|
||||
"settings": {
|
||||
"language": "Idioma",
|
||||
"useSystemTheme": "Use el aspecto claro/oscuro dispositivo",
|
||||
"licenses": "Licencias",
|
||||
"themeAuto": "Automático",
|
||||
"appearance": "Diseño",
|
||||
"theme": "Aspecto",
|
||||
"settings": "Configuraciones"
|
||||
},
|
||||
"themes": {
|
||||
"dark": "Oscuro",
|
||||
"light": "Claro"
|
||||
},
|
||||
"menu": {
|
||||
"emptyText": "No hay nada para esta semana",
|
||||
"emptyHeadline": "El menu del almuerzo se ve algo vacio"
|
||||
},
|
||||
"classmates": {
|
||||
"class": "Clase",
|
||||
"child": "Infante",
|
||||
"contactsForGuardiansFor": "Información de contacto de los tutores de"
|
||||
},
|
||||
"schedule": {
|
||||
"gymBag": "Mochila de gimnasio",
|
||||
"end": "Termina",
|
||||
"start": "Inicia",
|
||||
"lunch": "Almuerzo",
|
||||
"week": "Semana"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
"changeLanguage": "Changer de langue",
|
||||
"cancel": "Annuler",
|
||||
"logoutAndClearPersonalData": "Se déconnecter et effacer les données personnelles",
|
||||
"logoutAndClearAllDataInclSettings": "Se déconnecter et effacer toutes les données, y compris les paramètres"
|
||||
"logoutAndClearAllDataInclSettings": "Se déconnecter et effacer toutes les données, y compris les paramètres",
|
||||
"tomorrow": "Demain"
|
||||
},
|
||||
"calender": {
|
||||
"saveToCalenderError": "Un problème est survenu",
|
||||
|
@ -53,7 +54,8 @@
|
|||
"a11y_select_login_method": "Sélectionnez la méthode de connexion",
|
||||
"a11y_clear_social_security_input_field": "Effacer le champ du numéro national d’identité",
|
||||
"a11y_image_two_boys": "Photo de deux personnes consultant leur téléphone portable",
|
||||
"a11y_change_language": "Sélectionnez votre langue"
|
||||
"a11y_change_language": "Sélectionnez votre langue",
|
||||
"chooseSchoolPlatform": "Choisir la plateforme"
|
||||
},
|
||||
"abscense": {
|
||||
"startTime": "Heure de début",
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
"navigation": {
|
||||
"notifications": "通知",
|
||||
"menu": "メニュー",
|
||||
"calender": "カレンダー"
|
||||
"calender": "カレンダー",
|
||||
"classmates": "同級生",
|
||||
"news": "ニュース"
|
||||
},
|
||||
"abscense": {
|
||||
"endTime": "終了時間",
|
||||
|
@ -12,7 +14,8 @@
|
|||
"title": "不在を報告する",
|
||||
"selectAbscenseEndTime": "終了時間を選択します",
|
||||
"selectAbscenseStartTime": "開始時間を選択します",
|
||||
"startTime": "開始時間"
|
||||
"startTime": "開始時間",
|
||||
"childsPersonalNumber": "子供の個人識別番号"
|
||||
},
|
||||
"abbrevations": {
|
||||
"upperSecondarySchool": "ギムナジウム",
|
||||
|
@ -21,11 +24,16 @@
|
|||
"compulsorySchool": "基礎学校"
|
||||
},
|
||||
"general": {
|
||||
"settings": "設定"
|
||||
"settings": "設定",
|
||||
"tomorrow": "明日"
|
||||
},
|
||||
"children": {
|
||||
"tryAgain": "やり直してください",
|
||||
"title": "あなたの子供"
|
||||
"title": "あなたの子供",
|
||||
"noKids_title": "子供のない",
|
||||
"loadingErrorHeading": "おっと!",
|
||||
"loadingErrorInformationText": "このページを読み込むことができません。もう一度してみるか、skolplattformen.orgで現在のステータスを調べてください。",
|
||||
"noKids_description": "ストックホルム市にその個人識別番号で登録された子供はいません"
|
||||
},
|
||||
"auth": {
|
||||
"a11y_image_two_boys": "自分の携帯電話を見ている二人",
|
||||
|
@ -50,15 +58,41 @@
|
|||
"awaited": "待ち受ける"
|
||||
},
|
||||
"subtitle": "{{word}}の選択肢",
|
||||
"chooseLoginMethod": "ログイン方法を選択してください",
|
||||
"chooseLoginMethod": "ログイン方法を選んでください",
|
||||
"loginAsTestUser": "テスト・ユーザーでログインしてください",
|
||||
"bankid": {
|
||||
"OpenManually": "BankIDを手動で開く",
|
||||
"OpenManually": "手動でBankIDを開ける",
|
||||
"OpenOnAnotherDevice": "別のデバイスでBankIDを使用する",
|
||||
"Waiting": "BankIDを待っています…",
|
||||
"OpenOnThisDevice": "このデバイスでBankIDを使用する"
|
||||
},
|
||||
"loginFailed": "ログインできませんでした。再試行してください。",
|
||||
"placeholder_SocialSecurityNumber": "あなたの個人番号"
|
||||
"placeholder_SocialSecurityNumber": "あなたの個人番号",
|
||||
"freja": {
|
||||
"OpenOnThisDevice": "このデバイスで Freja eID+を使用する",
|
||||
"OpenManually": "手動でFreja eID+を開ける",
|
||||
"Waiting": "Freja eID+を待っています…"
|
||||
},
|
||||
"a11y_clear_social_security_input_field": "個人識別番号のフィールドを空にする",
|
||||
"chooseSchoolPlatform": "ログイン方法を選んでください",
|
||||
"loginSuccessful": "ログインは完成した、よみこんでいる。。。",
|
||||
"a11y_select_login_method": "ログインする方法を選ぶ"
|
||||
},
|
||||
"language": {
|
||||
"changeLanguage": "他の言語を選択"
|
||||
},
|
||||
"contact": {
|
||||
"home": "住所"
|
||||
},
|
||||
"calender": {
|
||||
"approveAccessToCalender": "カレンダーのアクセスを許可する必要があります",
|
||||
"saveToCalenderError": "エラーが発生しました",
|
||||
"saveToCalender": "カレンダーに保存する",
|
||||
"saveToCalenderSuccess": "✔️ カレンダーへに保存しました",
|
||||
"emptyHeadline": "カレンダーがなんか空っぽになりそう",
|
||||
"emptyText": "表示するものが見つかりませんでした"
|
||||
},
|
||||
"classmates": {
|
||||
"child": "子供"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,36 +4,43 @@
|
|||
"loginFailed": "Nomen dare non possibilis erat. Denuo conare.",
|
||||
"chooseLoginMethod": "Methodum nomen dare legere",
|
||||
"bankid": {
|
||||
"Waiting": "Pro BankID exspectans…",
|
||||
"Waiting": "BankID exspectans…",
|
||||
"OpenOnThisDevice": "In hac machina BankID aperire",
|
||||
"OpenOnAnotherDevice": "In machina differenti BankID aperire",
|
||||
"OpenManually": "Manu BankID aperire"
|
||||
"OpenManually": "Manualiter BankID aperire"
|
||||
},
|
||||
"words": {
|
||||
"awaited": "exspectatus",
|
||||
"awaited": "exspectata",
|
||||
"agile": "agilis",
|
||||
"better": "melior",
|
||||
"cheap": "vilis",
|
||||
"cooler": "amatior",
|
||||
"working": "operans",
|
||||
"simple": "simplus",
|
||||
"simple": "simplex",
|
||||
"rebellious": "rebellis",
|
||||
"open": "apertus",
|
||||
"imperfect": "imperfectus",
|
||||
"open": "aperta",
|
||||
"imperfect": "imperfecta",
|
||||
"fun": "oblectans",
|
||||
"free": "liber",
|
||||
"fast": "celer",
|
||||
"fantastic": "mirificus",
|
||||
"enlightened": "illuminatus",
|
||||
"first": "primus",
|
||||
"homemade": "domi factus"
|
||||
"free": "libera",
|
||||
"fast": "celeris",
|
||||
"fantastic": "mirifica",
|
||||
"enlightened": "illuminata",
|
||||
"first": "prima",
|
||||
"homemade": "domi facta"
|
||||
},
|
||||
"subtitle": "Optio {{word}}",
|
||||
"loginAsTestUser": "In parte investigatoris nomen dare",
|
||||
"a11y_select_login_method": "Methodum nomen dare legere",
|
||||
"a11y_change_language": "Linguam legere",
|
||||
"a11y_image_two_boys": "Pictura duobus hominibus telephona sua specientibus",
|
||||
"a11y_clear_social_security_input_field": "Cellam numeri personalis vacuare"
|
||||
"a11y_clear_social_security_input_field": "Cellam numeri personalis vacuare",
|
||||
"chooseSchoolPlatform": "Rostra legere",
|
||||
"loginSuccessful": "Nomen tuum datum est, carricans…",
|
||||
"freja": {
|
||||
"OpenManually": "Manualiter Freja eID+ aperire",
|
||||
"Waiting": "Freja eID+ exspectans…",
|
||||
"OpenOnThisDevice": "In hac machina Freja eID+ aperire"
|
||||
}
|
||||
},
|
||||
"abscense": {
|
||||
"title": "Absentiam referre",
|
||||
|
@ -43,7 +50,8 @@
|
|||
"personalNumberMissing": "Numerus personalis absens est",
|
||||
"invalidPersonalNumber": "Numerus personalis irritus est",
|
||||
"entireDay": "Totus dies",
|
||||
"endTime": "Hora terminalis"
|
||||
"endTime": "Hora terminalis",
|
||||
"childsPersonalNumber": "Numerus personalis filii"
|
||||
},
|
||||
"abbrevations": {
|
||||
"upperSecondarySchool": "Lyceum superius",
|
||||
|
@ -58,14 +66,16 @@
|
|||
"tryAgain": "Denuo conare",
|
||||
"title": "Filii tui",
|
||||
"noKids_title": "Nulli filii",
|
||||
"noKids_description": "Nulli filii pro numero personali tuo in Urbe Holmiente censi sunt"
|
||||
"noKids_description": "Nulli filii pro numero personali tuo in Urbe Holmiense censi sunt"
|
||||
},
|
||||
"calender": {
|
||||
"showCalenderActions": "Actiones calendarii exhibere",
|
||||
"saveToCalenderSuccess": "✔️ In calendarium servatus",
|
||||
"saveToCalender": "In calendarium servare",
|
||||
"approveAccessToCalender": "Aditum in calendarium approbare debes",
|
||||
"saveToCalenderError": "Aliquis deerat"
|
||||
"saveToCalenderError": "Aliquis deerat",
|
||||
"emptyHeadline": "Calendarium vacuum videtur",
|
||||
"emptyText": "Nihil invenitur ostendere"
|
||||
},
|
||||
"menu": {
|
||||
"emptyText": "Hac septimana nihil invenire poterat",
|
||||
|
@ -86,7 +96,7 @@
|
|||
"notificationTitle": "Nuntius: {{message}} ({{dateCreated}})"
|
||||
},
|
||||
"navigation": {
|
||||
"notifications": "Nuntii",
|
||||
"notifications": "Eventa",
|
||||
"news": "Nuntii",
|
||||
"menu": "Charta",
|
||||
"calender": "Calendarium",
|
||||
|
@ -105,13 +115,17 @@
|
|||
"loading": "Carricans…",
|
||||
"confirm": "Confirmare",
|
||||
"changeLanguage": "Linguam permutare",
|
||||
"cancel": "Rescindere"
|
||||
"cancel": "Rescindere",
|
||||
"tomorrow": "Cras",
|
||||
"logoutAndClearPersonalData": "Secedere et informationes personales purgare",
|
||||
"logoutAndClearAllDataInclSettings": "Secedere et omnes informationes configurationesque purgare"
|
||||
},
|
||||
"schedule": {
|
||||
"start": "Exordium",
|
||||
"gymBag": "Saccus gymnasticus",
|
||||
"lunch": "Prandium",
|
||||
"end": "Finis"
|
||||
"end": "Finis",
|
||||
"week": "Septimana"
|
||||
},
|
||||
"contact": {
|
||||
"a11y_show_contact_info_button_hint": "Notationes contactus exhibet",
|
||||
|
@ -125,5 +139,18 @@
|
|||
"contactsForGuardiansFor": "Notationes contactus custodum",
|
||||
"child": "Filius",
|
||||
"class": "Classis"
|
||||
},
|
||||
"settings": {
|
||||
"licenses": "Licentiae",
|
||||
"appearance": "Species",
|
||||
"language": "Lingua",
|
||||
"themeAuto": "Automato",
|
||||
"useSystemTheme": "Themate lucido/obscuro systemae uti",
|
||||
"settings": "Configurationes",
|
||||
"theme": "Thema"
|
||||
},
|
||||
"themes": {
|
||||
"light": "Lucidus",
|
||||
"dark": "Obscurus"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,9 @@
|
|||
"saveToCalenderSuccess": "✔️ Lagret i kalender",
|
||||
"showCalenderActions": "Vis kalenderhandlinger",
|
||||
"saveToCalenderError": "Noe gikk galt",
|
||||
"approveAccessToCalender": "Du må innvilge tilgang til kalenderen din"
|
||||
"approveAccessToCalender": "Du må innvilge tilgang til kalenderen din",
|
||||
"emptyHeadline": "Kalenderen ser tom ut",
|
||||
"emptyText": "Ingenting å vise"
|
||||
},
|
||||
"general": {
|
||||
"loading": "Laster inn …",
|
||||
|
@ -63,7 +65,8 @@
|
|||
"send": "Send",
|
||||
"cancel": "Avbryt",
|
||||
"logoutAndClearPersonalData": "Logg ut og tøm personlig data",
|
||||
"logoutAndClearAllDataInclSettings": "Logg ut og tøm all data, inkludert innstillinger"
|
||||
"logoutAndClearAllDataInclSettings": "Logg ut og tøm all data, inkludert innstillinger",
|
||||
"tomorrow": "I morgen"
|
||||
},
|
||||
"news": {
|
||||
"updated": "Oppdatert",
|
||||
|
@ -115,7 +118,8 @@
|
|||
"gymBag": "Gym-bag",
|
||||
"lunch": "Lunsj",
|
||||
"end": "Slutt",
|
||||
"start": "Start"
|
||||
"start": "Start",
|
||||
"week": "Uke"
|
||||
},
|
||||
"contact": {
|
||||
"a11y_show_contact_info_button_hint": "Vis kontaktinfo",
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
"socialSecurityNumber": "Burgerservicenummer",
|
||||
"cancel": "Annuleren",
|
||||
"logoutAndClearAllDataInclSettings": "Log uit en wis alle gegevens inclusief instellingen",
|
||||
"logoutAndClearPersonalData": "Uitloggen en persoonlijke gegevens wissen"
|
||||
"logoutAndClearPersonalData": "Uitloggen en persoonlijke gegevens wissen",
|
||||
"tomorrow": "Morgen"
|
||||
},
|
||||
"auth": {
|
||||
"placeholder_SocialSecurityNumber": "Jouw burgerservicenummer",
|
||||
|
@ -46,7 +47,14 @@
|
|||
"a11y_select_login_method": "Selecteer de inlogmethode",
|
||||
"a11y_clear_social_security_input_field": "Wis het veld voor het burgerservicenummer",
|
||||
"a11y_image_two_boys": "Foto van twee mensen die naar hun mobiele telefoons kijken",
|
||||
"a11y_change_language": "Selecteer je taal"
|
||||
"a11y_change_language": "Selecteer je taal",
|
||||
"chooseSchoolPlatform": "Platform kiezen",
|
||||
"freja": {
|
||||
"OpenManually": "Freja eID+ handmatig openen",
|
||||
"Waiting": "Wachten op Freja eID+…",
|
||||
"OpenOnThisDevice": "Freja eID+ openen op dit apparaat"
|
||||
},
|
||||
"loginSuccessful": "Inloggen gelukt, laden…"
|
||||
},
|
||||
"abbrevations": {
|
||||
"preSchool": "Peuterschool",
|
||||
|
@ -98,7 +106,9 @@
|
|||
"approveAccessToCalender": "Je moet de toegang tot je agenda goedkeuren",
|
||||
"saveToCalenderError": "Er is iets fout gegaan",
|
||||
"saveToCalenderSuccess": "✔️ Opgeslagen in kalender",
|
||||
"saveToCalender": "Opslaan in kalender"
|
||||
"saveToCalender": "Opslaan in kalender",
|
||||
"emptyHeadline": "De kalender ziet er nogal leeg uit",
|
||||
"emptyText": "Kon niets vinden om te laten zien"
|
||||
},
|
||||
"notifications": {
|
||||
"notificationTitle": "Melding: {{message}} ({{dateCreated}})"
|
||||
|
@ -114,10 +124,11 @@
|
|||
"end": "Eind",
|
||||
"gymBag": "Sporttas",
|
||||
"lunch": "Middageten",
|
||||
"start": "Start"
|
||||
"start": "Start",
|
||||
"week": "Week"
|
||||
},
|
||||
"contact": {
|
||||
"a11y_show_contact_info_button_hint": "Toon contactgegevens",
|
||||
"a11y_show_contact_info_button_hint": "Toont contactgegevens",
|
||||
"email": "E-mail",
|
||||
"home": "Adres",
|
||||
"call": "Telefoongesprek",
|
||||
|
|
|
@ -23,6 +23,11 @@
|
|||
"OpenOnThisDevice": "Otwórz BankID na tym urządzeniu",
|
||||
"Waiting": "Oczekiwanie na BankID…"
|
||||
},
|
||||
"freja": {
|
||||
"OpenManually": "Otwórz Freja eID+ manualnie",
|
||||
"OpenOnThisDevice": "Otwórz Freja eID+ na tym urządzeniu",
|
||||
"Waiting": "Oczekiwanie na Freja eID+…"
|
||||
},
|
||||
"chooseLoginMethod": "Wybierz sposób logowania",
|
||||
"loginAsTestUser": "Zaloguj się jako użytkownik testowy",
|
||||
"loginFailed": "Logowanie nie powiodło się. Spróbuj ponownie.",
|
||||
|
@ -50,14 +55,18 @@
|
|||
"a11y_select_login_method": "Wybierz metodę logowania",
|
||||
"a11y_clear_social_security_input_field": "Wyczyść pole z personnumerem",
|
||||
"a11y_image_two_boys": "Ilustracja: dwie osoby patrzą w telefony komórkowe",
|
||||
"a11y_change_language": "Wybierz język"
|
||||
"a11y_change_language": "Wybierz język",
|
||||
"chooseSchoolPlatform": "Wybierz platformę",
|
||||
"loginSuccessful": "Logowanie powiodło się. Trwa ładowanie…"
|
||||
},
|
||||
"calender": {
|
||||
"approveAccessToCalender": "Musisz zatwierdzić dostęp do kalendarza",
|
||||
"saveToCalender": "Zapisz w kalendarzu",
|
||||
"saveToCalenderError": "Coś poszło nie tak",
|
||||
"saveToCalenderSuccess": "✔️ Zapisano w kalendarzu",
|
||||
"showCalenderActions": "Pokaż opcje kalendarza"
|
||||
"showCalenderActions": "Pokaż opcje kalendarza",
|
||||
"emptyHeadline": "Kalendarz jest pusty",
|
||||
"emptyText": "Nie znaleziono nic do pokazania"
|
||||
},
|
||||
"children": {
|
||||
"loadingErrorHeading": "Oj!",
|
||||
|
@ -79,7 +88,8 @@
|
|||
"title": "Öppna skolplattformen",
|
||||
"cancel": "Anuluj",
|
||||
"logoutAndClearPersonalData": "Wyloguj i skasuj dane osobowe",
|
||||
"logoutAndClearAllDataInclSettings": "Wyloguj i skasuj wszystkie dane łącznie z ustawieniami"
|
||||
"logoutAndClearAllDataInclSettings": "Wyloguj i skasuj wszystkie dane łącznie z ustawieniami",
|
||||
"tomorrow": "Jutro"
|
||||
},
|
||||
"language": {
|
||||
"changeLanguage": "Zmień język",
|
||||
|
@ -114,11 +124,12 @@
|
|||
"gymBag": "Ubrania do WF",
|
||||
"lunch": "Lunch",
|
||||
"end": "Kończy",
|
||||
"start": "Zaczyna"
|
||||
"start": "Zaczyna",
|
||||
"week": "Tydzień"
|
||||
},
|
||||
"contact": {
|
||||
"a11y_show_contact_info_button_hint": "Pokazuje dane kontaktowe",
|
||||
"home": "Dom",
|
||||
"home": "Adres",
|
||||
"email": "E-mail",
|
||||
"sms": "SMS",
|
||||
"call": "Zadzwoń",
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
"selectAbscenseEndTime": "Indique a hora de fim",
|
||||
"endTime": "Hora de fim",
|
||||
"invalidPersonalNumber": "Número de identidade pessoal inválido",
|
||||
"personalNumberMissing": "Falta o número de identidade pessoal"
|
||||
"personalNumberMissing": "Falta o número de identidade pessoal",
|
||||
"childsPersonalNumber": "Número de identidade pessoal da criança"
|
||||
},
|
||||
"auth": {
|
||||
"bankid": {
|
||||
|
@ -43,7 +44,8 @@
|
|||
"a11y_image_two_boys": "Fotografia de duas pessoas a verem os seus telemóveis",
|
||||
"a11y_clear_social_security_input_field": "Limpar o campo do número de identificação pessoal",
|
||||
"chooseLoginMethod": "Escolha o método de autenticação",
|
||||
"a11y_select_login_method": "Selecione o método de autenticação"
|
||||
"a11y_select_login_method": "Selecione o método de autenticação",
|
||||
"chooseSchoolPlatform": "Escolha a plataforma"
|
||||
},
|
||||
"abbrevations": {
|
||||
"compulsorySchool": "Escola primária / secundária inferior",
|
||||
|
@ -56,7 +58,9 @@
|
|||
"saveToCalenderError": "Algo correu mal",
|
||||
"saveToCalenderSuccess": "✔️ Guardado no calendário",
|
||||
"approveAccessToCalender": "Tem de autorizar o acesso ao seu calendário",
|
||||
"saveToCalender": "Guardar no calendário"
|
||||
"saveToCalender": "Guardar no calendário",
|
||||
"emptyHeadline": "O calendário parece um pouco vazio",
|
||||
"emptyText": "Não encontrei nada para mostrar"
|
||||
},
|
||||
"children": {
|
||||
"loadingErrorHeading": "Ups!",
|
||||
|
@ -78,7 +82,8 @@
|
|||
"title": "Öppna skolplattformen",
|
||||
"logoutAndClearPersonalData": "Sair e limpar dados pessoais",
|
||||
"cancel": "Cancelar",
|
||||
"settings": "Configurações"
|
||||
"settings": "Configurações",
|
||||
"tomorrow": "Amanhã"
|
||||
},
|
||||
"language": {
|
||||
"changeLanguage": "Alterar idioma",
|
||||
|
@ -123,7 +128,8 @@
|
|||
"start": "Início",
|
||||
"end": "Fim",
|
||||
"lunch": "Almoço",
|
||||
"gymBag": "Saco de ginástica"
|
||||
"gymBag": "Saco de ginástica",
|
||||
"week": "Semana"
|
||||
},
|
||||
"classmates": {
|
||||
"class": "Turma",
|
||||
|
|
|
@ -23,10 +23,16 @@
|
|||
"OpenOnThisDevice": "Logga in med BankID",
|
||||
"Waiting": "Väntar på BankID…"
|
||||
},
|
||||
"freja": {
|
||||
"OpenManually": "Öppna Freja eID+ manuellt",
|
||||
"OpenOnThisDevice": "Logga in med Freja eID+",
|
||||
"Waiting": "Väntar på Freja eID+…"
|
||||
},
|
||||
"chooseLoginMethod": "Välj inloggningsmetod",
|
||||
"chooseSchoolPlatform": "Välj plattform",
|
||||
"loginAsTestUser": "Logga in som testanvändare",
|
||||
"loginFailed": "Inloggningen misslyckades, försök igen!",
|
||||
"loginSuccessful": "Du är inloggad! - laddar…",
|
||||
"placeholder_SocialSecurityNumber": "Ditt personnummer",
|
||||
"subtitle": "Det {{word}} alternativet",
|
||||
"words": {
|
||||
|
@ -58,7 +64,9 @@
|
|||
"saveToCalender": "Spara till kalender",
|
||||
"saveToCalenderError": "Något gick fel",
|
||||
"saveToCalenderSuccess": "✔️ Sparad till kalender",
|
||||
"showCalenderActions": "Visa kalenderfunktioner"
|
||||
"showCalenderActions": "Visa kalenderfunktioner",
|
||||
"emptyText": "Hittade ingenting att visa",
|
||||
"emptyHeadline": "Det ser lite tomt ut i kalendern"
|
||||
},
|
||||
"children": {
|
||||
"loadingErrorHeading": "Hoppsan!",
|
||||
|
@ -80,7 +88,8 @@
|
|||
"title": "Öppna skolplattformen",
|
||||
"cancel": "Avbryt",
|
||||
"logoutAndClearAllDataInclSettings": "Logga ut och rensa all sparad data inkl inställningar",
|
||||
"logoutAndClearPersonalData": "Logga ut och rensa all personlig data"
|
||||
"logoutAndClearPersonalData": "Logga ut och rensa all personlig data",
|
||||
"tomorrow": "Imorgon"
|
||||
},
|
||||
"language": {
|
||||
"changeLanguage": "Byt språk",
|
||||
|
@ -128,7 +137,8 @@
|
|||
"start": "Börjar",
|
||||
"end": "Slutar",
|
||||
"lunch": "Lunch",
|
||||
"gymBag": "Gympapåse"
|
||||
"gymBag": "Gympapåse",
|
||||
"week": "Vecka"
|
||||
},
|
||||
"classmates": {
|
||||
"class": "Klass",
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
{
|
||||
"abscense": {
|
||||
"entireDay": "ทั้งวัน",
|
||||
"childsPersonalNumber": "เลขบัตรประจำตัวประชาชนของลูก",
|
||||
"invalidPersonalNumber": "เลขบัตรประจำตัวประชาชนผิด",
|
||||
"personalNumberMissing": "เลขบัตรประจำตัวประชาชนหายไป"
|
||||
},
|
||||
"abbrevations": {
|
||||
"preSchool": "อนุบาล",
|
||||
"upperSecondarySchool": "มัธยมปลาย",
|
||||
"compulsorySchool": "ประถม/มัธยมต้น"
|
||||
},
|
||||
"auth": {
|
||||
"bankid": {
|
||||
"OpenOnAnotherDevice": "เปิด BankID ในเครื่องอื่น",
|
||||
"OpenOnThisDevice": "เปิด BankID ในเครื่องนี้",
|
||||
"Waiting": "กำลังรอ BankID…"
|
||||
},
|
||||
"words": {
|
||||
"cooler": "เจ๋งขึ้น",
|
||||
"fast": "เร็ว",
|
||||
"first": "แรก",
|
||||
"free": "ฟรี",
|
||||
"fun": "สนุก",
|
||||
"imperfect": "ไม่สมบูรณ์",
|
||||
"open": "เปิด",
|
||||
"better": "ดีกว่า",
|
||||
"cheap": "ถูก",
|
||||
"simple": "ง่าย",
|
||||
"fantastic": "ดีเยี่ยม",
|
||||
"agile": "เปรียว",
|
||||
"working": "ใช้งานได้"
|
||||
},
|
||||
"loginFailed": "เข้าสู่ระบบไม่ได้ กรุณาลองใหม่อีกครั้ง",
|
||||
"subtitle": "ทางเลือกที่{{word}}",
|
||||
"placeholder_SocialSecurityNumber": "เลขบัตรประจำตัวประชาชนของคุณ",
|
||||
"a11y_change_language": "เลือกภาษา",
|
||||
"a11y_select_login_method": "เลือกวิธีการเข้าสู่ระบบ",
|
||||
"freja": {
|
||||
"Waiting": "กำลังรอ Freja eID+…"
|
||||
}
|
||||
},
|
||||
"language": {
|
||||
"changeLanguageButton": "บันทึก",
|
||||
"changeLanguage": "เปลี่ยนภาษา"
|
||||
},
|
||||
"navigation": {
|
||||
"calender": "ปฏิทิน",
|
||||
"news": "ข่าวใหม่",
|
||||
"notifications": "การแจ้งเตือน",
|
||||
"classmates": "เพื่อนร่วมชั้น",
|
||||
"menu": "อาหารเที่ยง"
|
||||
},
|
||||
"general": {
|
||||
"send": "ส่ง",
|
||||
"cancel": "ยกเลิก",
|
||||
"loading": "กำลังโหลด…",
|
||||
"settings": "การตั้งค่า",
|
||||
"title": "Öppna skolplattformen",
|
||||
"socialSecurityNumber": "เลขบัตรประจำตัวประชาชน",
|
||||
"tomorrow": "พรุ่งนี้",
|
||||
"confirm": "ยืนยัน",
|
||||
"changeLanguage": "เปลี่ยนภาษา",
|
||||
"logout": "ออกจากระบบ"
|
||||
},
|
||||
"children": {
|
||||
"title": "ลูกของคุณ",
|
||||
"tryAgain": "ลองอีกครั้ง",
|
||||
"noKids_title": "ไม่มีลูก",
|
||||
"viewStatus": "ดูสถานะบน skolplattformen.org"
|
||||
},
|
||||
"settings": {
|
||||
"settings": "การตั้งค่า",
|
||||
"language": "ภาษา",
|
||||
"themeAuto": "อัตโนมัติ",
|
||||
"licenses": "ได้รับอนุญาต"
|
||||
},
|
||||
"contact": {
|
||||
"email": "อีเมล",
|
||||
"call": "โทร",
|
||||
"sms": "ข้อความ",
|
||||
"home": "ที่อยู่",
|
||||
"a11y_show_contact_info_button_hint": "แสดงข้อมูลการติดต่อ",
|
||||
"a11y_show_contact_info_button_label": "แสดงข้อมูลการติดต่อ"
|
||||
},
|
||||
"themes": {
|
||||
"dark": "มืด",
|
||||
"light": "แสงสว่าง"
|
||||
},
|
||||
"news": {
|
||||
"noNewNewsItemsThisWeek": "อาทิตย์นี้ไม่มีข่าว",
|
||||
"notificationTitle": "ข่าว: {{header}} ({{published}})",
|
||||
"title": "ข่าวจาก Skolplattformen",
|
||||
"search": {
|
||||
"placeholder": "ค้นหาข่าวต่างๆๆ…"
|
||||
},
|
||||
"backToChild": "กลับไปหน้าหลักของลูก",
|
||||
"published": "สิ่งที่ตีพิมพ์"
|
||||
},
|
||||
"schedule": {
|
||||
"week": "อาทิตย์",
|
||||
"lunch": "อาหารเที่ยง",
|
||||
"start": "เริ่มต้น",
|
||||
"end": "สิ้นสุด"
|
||||
},
|
||||
"classmates": {
|
||||
"child": "ลูก",
|
||||
"class": "ชั้นเรียน"
|
||||
},
|
||||
"notifications": {
|
||||
"notificationTitle": "การแจ้งเตือน: {{message}} ({{dateCreated}})"
|
||||
},
|
||||
"calender": {
|
||||
"saveToCalender": "บันทึกไว้ในปฏิทิน"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
{
|
||||
"abbrevations": {
|
||||
"preSchool": "дитячий сад",
|
||||
"upperSecondarySchool": "Старша школа",
|
||||
"compulsorySchool": "Молодша/середня школа",
|
||||
"leisureTimeCentre": "Група продовженого дня (\"Продленка\")"
|
||||
},
|
||||
"abscense": {
|
||||
"entireDay": "Цілий день",
|
||||
"childsPersonalNumber": "Ідентифікаційний номер дитини",
|
||||
"endTime": "час закінчення",
|
||||
"invalidPersonalNumber": "Невірний ідентифікаційний номер",
|
||||
"personalNumberMissing": "Ідентифікаційний код відсутній",
|
||||
"startTime": "Час початку",
|
||||
"title": "Додати відсутність",
|
||||
"selectAbscenseEndTime": "Виберіть кінцевий час",
|
||||
"selectAbscenseStartTime": "Виберіть час початку"
|
||||
},
|
||||
"auth": {
|
||||
"bankid": {
|
||||
"OpenManually": "Відкрити BankID власноруч",
|
||||
"OpenOnAnotherDevice": "Відкрити BankID на іншому пристрої",
|
||||
"OpenOnThisDevice": "Відкрити BankID на цьому пристрої",
|
||||
"Waiting": "Очікую на BankID…"
|
||||
},
|
||||
"chooseLoginMethod": "Оберіть як увійти",
|
||||
"chooseSchoolPlatform": "Оберіть платформу",
|
||||
"loginFailed": "Не зміг увійти. Спробуйте ще раз.",
|
||||
"placeholder_SocialSecurityNumber": "Ваш ідентифікаційний номер",
|
||||
"loginAsTestUser": "Увійти як тестовий користувач",
|
||||
"subtitle": "{{word}} альтернатива",
|
||||
"words": {
|
||||
"agile": "Гнучка",
|
||||
"awaited": "Очікувана",
|
||||
"better": "Краща",
|
||||
"cheap": "Дешева",
|
||||
"cooler": "Крутіша",
|
||||
"enlightened": "Освічена",
|
||||
"fantastic": "Фантастична",
|
||||
"fast": "Швидка",
|
||||
"first": "Перша",
|
||||
"free": "Безкоштовна",
|
||||
"fun": "Весела",
|
||||
"homemade": "Домашня",
|
||||
"imperfect": "Недосконала",
|
||||
"open": "Відкрита",
|
||||
"rebellious": "Бунтівна",
|
||||
"simple": "Проста",
|
||||
"working": "Робоча"
|
||||
},
|
||||
"a11y_change_language": "Оберіть вашу мову",
|
||||
"a11y_image_two_boys": "Зображення двох людей, які перевіряють свої телефони",
|
||||
"a11y_clear_social_security_input_field": "Очистити поле вводу ідентифікаційного номера",
|
||||
"a11y_select_login_method": "Оберіть як увійти",
|
||||
"freja": {
|
||||
"Waiting": "Очікую на Freja eID+…",
|
||||
"OpenManually": "Відкрити Freja eID+ власноруч",
|
||||
"OpenOnThisDevice": "Відкрити Freja eID+ на цьому пристрої"
|
||||
}
|
||||
},
|
||||
"calender": {
|
||||
"approveAccessToCalender": "Вам потрібно дозволити доступ до вашого календаря",
|
||||
"saveToCalender": "Зберегти у каледарі",
|
||||
"saveToCalenderError": "Помилка збереження у календарі",
|
||||
"saveToCalenderSuccess": "✔️ Збережено у календарі",
|
||||
"showCalenderActions": "Показати дії у календарі",
|
||||
"emptyHeadline": "У вашому календарі немає записів",
|
||||
"emptyText": "Нічого показати"
|
||||
},
|
||||
"children": {
|
||||
"loadingErrorHeading": "Помилка!",
|
||||
"loadingErrorInformationText": "Неможливо завантажити цю сторінку. Спробуйте ще раз або дізнайтеся статус на skolplattformen.org.",
|
||||
"noKids_description": "На ваш ідентифікаційний номер не зареєстровано жодної дитини в Стокгольмі",
|
||||
"noKids_title": "Немає дітей",
|
||||
"title": "Ваші діти",
|
||||
"tryAgain": "Спробуйте ще",
|
||||
"viewStatus": "Дізнайтеся статус на skolplattformen.org"
|
||||
},
|
||||
"general": {
|
||||
"cancel": "Скасувати",
|
||||
"changeLanguage": "Змінити мову",
|
||||
"confirm": "Підтвердити",
|
||||
"loading": "Завантаження…",
|
||||
"logout": "Вийти",
|
||||
"logoutAndClearPersonalData": "Вийти та очистити персональні дані",
|
||||
"send": "Відправити",
|
||||
"settings": "Налаштування",
|
||||
"socialSecurityNumber": "Ідентифікаційний номер",
|
||||
"title": "Відкрити skolplattformen",
|
||||
"tomorrow": "Завтра",
|
||||
"logoutAndClearAllDataInclSettings": "Вийти та очистити дані, включаючи налаштування"
|
||||
},
|
||||
"language": {
|
||||
"changeLanguage": "Змінити мову",
|
||||
"changeLanguageButton": "Зберегти"
|
||||
},
|
||||
"menu": {
|
||||
"emptyHeadline": "Нічого немає в меню на обід",
|
||||
"emptyText": "На цьому тижні нічого немає"
|
||||
},
|
||||
"navigation": {
|
||||
"calender": "Календар",
|
||||
"menu": "Обід",
|
||||
"news": "Новини",
|
||||
"notifications": "Повідомлення",
|
||||
"classmates": "Однокласники"
|
||||
},
|
||||
"settings": {
|
||||
"settings": "Налаштування",
|
||||
"appearance": "Зовнішній вигляд",
|
||||
"theme": "Тема",
|
||||
"licenses": "Ліцензії",
|
||||
"language": "Мова",
|
||||
"themeAuto": "Автоматично",
|
||||
"useSystemTheme": "Використати системну світлу/темну тему"
|
||||
},
|
||||
"themes": {
|
||||
"light": "Світла",
|
||||
"dark": "Темна"
|
||||
},
|
||||
"news": {
|
||||
"backToChild": "Назад до дитини",
|
||||
"noNewNewsItemsThisWeek": "Цього тижня новин немає.",
|
||||
"notificationTitle": "Новини: {{header}} ({{published}})",
|
||||
"published": "Опубліковано",
|
||||
"title": "Новини від Skolplattformen",
|
||||
"updated": "Оновлено",
|
||||
"search": {
|
||||
"placeholder": "Шукати у новинах…"
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
"notificationTitle": "Повідомлення: {{message}} ({{dateCreated}})"
|
||||
},
|
||||
"schedule": {
|
||||
"start": "Початок",
|
||||
"end": "Кінець",
|
||||
"lunch": "Обід",
|
||||
"week": "Тиждень",
|
||||
"gymBag": "Спортивна сумка"
|
||||
},
|
||||
"classmates": {
|
||||
"class": "Клас",
|
||||
"child": "Дитина",
|
||||
"contactsForGuardiansFor": "Контактна інформація для опікунів для"
|
||||
},
|
||||
"contact": {
|
||||
"a11y_show_contact_info_button_hint": "Показує контактну інформацію",
|
||||
"a11y_show_contact_info_button_label": "Показати контактну інформацію",
|
||||
"call": "Дзвінок",
|
||||
"sms": "СМС",
|
||||
"email": "Е-мейл",
|
||||
"home": "Адреса"
|
||||
}
|
||||
}
|
|
@ -13,7 +13,8 @@
|
|||
"title": "报告缺席情况",
|
||||
"invalidPersonalNumber": "个人身份号码无效",
|
||||
"personalNumberMissing": "缺少个人身份号码",
|
||||
"startTime": "开始时间"
|
||||
"startTime": "开始时间",
|
||||
"childsPersonalNumber": "孩子的个人身份号码"
|
||||
},
|
||||
"auth": {
|
||||
"bankid": {
|
||||
|
@ -49,14 +50,23 @@
|
|||
"chooseLoginMethod": "选择登录方式",
|
||||
"a11y_change_language": "选择您的语言",
|
||||
"a11y_image_two_boys": "两个人看手机的图片",
|
||||
"a11y_select_login_method": "选择登录方式"
|
||||
"a11y_select_login_method": "选择登录方式",
|
||||
"chooseSchoolPlatform": "选择平台",
|
||||
"freja": {
|
||||
"OpenManually": "手动打开 Freja eID+",
|
||||
"OpenOnThisDevice": "在此设备上打开 Freja eID+",
|
||||
"Waiting": "正在等待 Freja eID+ 响应…"
|
||||
},
|
||||
"loginSuccessful": "登录成功,正在加载…"
|
||||
},
|
||||
"calender": {
|
||||
"saveToCalender": "保存到日历中",
|
||||
"saveToCalenderError": "出了点问题",
|
||||
"saveToCalenderSuccess": "✔️ 已保存到日历中",
|
||||
"showCalenderActions": "显示日历操作",
|
||||
"approveAccessToCalender": "您必须允许访问日历"
|
||||
"approveAccessToCalender": "您必须允许访问日历",
|
||||
"emptyHeadline": "日历看起来有点空",
|
||||
"emptyText": "找不到任何可以显示的东西"
|
||||
},
|
||||
"children": {
|
||||
"loadingErrorHeading": "啊噢!",
|
||||
|
@ -78,7 +88,8 @@
|
|||
"send": "发送",
|
||||
"socialSecurityNumber": "个人身份号码",
|
||||
"title": "开放学校平台",
|
||||
"settings": "设置"
|
||||
"settings": "设置",
|
||||
"tomorrow": "明天"
|
||||
},
|
||||
"language": {
|
||||
"changeLanguage": "更改语言",
|
||||
|
@ -126,7 +137,8 @@
|
|||
"start": "开始",
|
||||
"end": "结束",
|
||||
"lunch": "午餐",
|
||||
"gymBag": "健身袋"
|
||||
"gymBag": "健身袋",
|
||||
"week": "星期"
|
||||
},
|
||||
"classmates": {
|
||||
"class": "课堂",
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
import moment from 'moment'
|
||||
import { getMeaningfulStartingDate } from '../calendarHelpers'
|
||||
|
||||
const tuesdayMorning = moment('2021-11-30T08:20:00+0100')
|
||||
const tuesdayEvening = moment('2021-11-30T19:20:26+0100')
|
||||
const wednesdayEvening = moment('2021-12-01T19:20:26+0100')
|
||||
const fridayEvening = moment('2021-12-03T19:20:26+0100')
|
||||
const saturdayEvening = moment('2021-12-04T19:20:26+0100')
|
||||
const sundayEvening = moment('2021-12-05T19:20:26+0100')
|
||||
const mondayEvening = moment('2021-12-06T19:20:26+0100')
|
||||
|
||||
describe('getMeaningfulStartingDate should not touch inputdate', () => {
|
||||
const origDate = moment()
|
||||
const origDateClone = origDate.clone()
|
||||
getMeaningfulStartingDate(origDate)
|
||||
|
||||
expect(origDate).toEqual(origDateClone)
|
||||
})
|
||||
|
||||
describe('getMeaningfulStartingDate on weekends', () => {
|
||||
it('should give next monday if on friday evening', () => {
|
||||
const startDate = getMeaningfulStartingDate(fridayEvening)
|
||||
expect(startDate.toISOString()).toEqual(mondayEvening.toISOString())
|
||||
})
|
||||
|
||||
it('should give next monday if on saturday', () => {
|
||||
const startDate = getMeaningfulStartingDate(saturdayEvening)
|
||||
expect(startDate.toISOString()).toEqual(mondayEvening.toISOString())
|
||||
})
|
||||
|
||||
it('should give next monday if on sunday', () => {
|
||||
const startDate = getMeaningfulStartingDate(sundayEvening)
|
||||
expect(startDate.toISOString()).toEqual(mondayEvening.toISOString())
|
||||
})
|
||||
})
|
||||
|
||||
describe('getMeaningfulStartingDate on weekdays', () => {
|
||||
it('should give next day if on tuesday evening', () => {
|
||||
const startDate = getMeaningfulStartingDate(tuesdayEvening)
|
||||
expect(startDate.toISOString()).toEqual(wednesdayEvening.toISOString())
|
||||
})
|
||||
|
||||
it('should give same day if on tuesday morning', () => {
|
||||
const startDate = getMeaningfulStartingDate(tuesdayMorning)
|
||||
expect(startDate.toISOString()).toEqual(tuesdayMorning.toISOString())
|
||||
})
|
||||
})
|
|
@ -0,0 +1,18 @@
|
|||
import moment from 'moment'
|
||||
|
||||
export const getMeaningfulStartingDate = (date = moment()) => {
|
||||
const originalDate = date.clone()
|
||||
let returnDate = date.clone()
|
||||
// are we on the evening?
|
||||
if (date.hour() > 17) returnDate.add('1', 'day')
|
||||
// are we on the weekend
|
||||
if (returnDate.isoWeekday() > 5) {
|
||||
returnDate = returnDate.add(5, 'days').startOf('isoWeek')
|
||||
returnDate
|
||||
.hour(originalDate.hour())
|
||||
.minute(originalDate.minute())
|
||||
.second(originalDate.second())
|
||||
}
|
||||
|
||||
return returnDate
|
||||
}
|
|
@ -2,8 +2,9 @@ import { Guardian } from '@skolplattformen/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 sortByFirstName = <T extends { firstname: string }>(
|
||||
data: T[]
|
||||
): T[] => data.sort((a, b) => a.firstname.localeCompare(b.firstname))
|
||||
|
||||
export const guardians = (data: Guardian[]) =>
|
||||
sortByFirstName(data).map(fullName).join(', ')
|
||||
|
|
|
@ -137,6 +137,20 @@ export const languages: Language[] = [
|
|||
locale: 'es',
|
||||
active: true,
|
||||
},
|
||||
{
|
||||
langCode: 'th',
|
||||
languageName: 'Thai',
|
||||
languageLocalName: 'ไทย',
|
||||
locale: 'th',
|
||||
active: true,
|
||||
},
|
||||
{
|
||||
langCode: 'uk',
|
||||
languageName: 'Ukrainian',
|
||||
languageLocalName: 'український',
|
||||
locale: 'uk',
|
||||
active: true,
|
||||
},
|
||||
]
|
||||
|
||||
export const translations = {
|
||||
|
@ -156,6 +170,8 @@ export const translations = {
|
|||
ru: require('../translations/ru.json'),
|
||||
so: require('../translations/so.json'),
|
||||
sv: require('../translations/sv.json'),
|
||||
th: require('../translations/th.json'),
|
||||
uk: require('../translations/uk.json'),
|
||||
zh_Hans: require('../translations/zh_Hans.json'),
|
||||
zh_Hant: require('../translations/zh_Hant.json'),
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,2 @@
|
|||
k8s
|
||||
k8s
|
|
@ -0,0 +1,44 @@
|
|||
# Install dependencies only when needed
|
||||
FROM node:16-alpine AS builder
|
||||
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
|
||||
RUN apk add --no-cache libc6-compat autoconf automake build-base curl git libtool make nodejs npm pkgconf nasm yasm optipng
|
||||
WORKDIR /app
|
||||
COPY package.json yarn.lock ./
|
||||
RUN yarn install --frozen-lockfile
|
||||
|
||||
COPY . .
|
||||
ENV NEXT_TELEMETRY_DISABLED 1
|
||||
|
||||
RUN yarn build
|
||||
|
||||
# Production image, copy all the files and run next
|
||||
FROM node:16-alpine AS runner
|
||||
WORKDIR /app
|
||||
|
||||
ENV NODE_ENV production
|
||||
|
||||
RUN addgroup -g 1001 -S nodejs
|
||||
RUN adduser -S nextjs -u 1001
|
||||
|
||||
# You only need to copy next.config.js if you are NOT using the default configuration
|
||||
# COPY --from=builder /app/next.config.js ./
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
COPY --from=builder /app/package.json ./package.json
|
||||
COPY --from=builder /app/next.* ./
|
||||
COPY --from=builder /app/*.js ./
|
||||
COPY --from=builder /app/*.ts ./
|
||||
COPY --from=builder /app/public ./public
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
|
||||
|
||||
USER nextjs
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
ENV PORT 3000
|
||||
|
||||
# Next.js collects completely anonymous telemetry data about general usage.
|
||||
# Learn more here: https://nextjs.org/telemetry
|
||||
# Uncomment the following line in case you want to disable telemetry.
|
||||
ENV NEXT_TELEMETRY_DISABLED 1
|
||||
|
||||
CMD ["yarn", "start"]
|
|
@ -5,7 +5,6 @@ const team = [
|
|||
{ name: 'Christian Landgren', twitter: 'landgren' },
|
||||
{ name: 'Erik Hellman', twitter: 'erikhellman' },
|
||||
{ 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' },
|
||||
|
@ -57,6 +56,11 @@ const Footer = () => {
|
|||
Integritetspolicy
|
||||
</Link.Internal>
|
||||
</li>
|
||||
<li>
|
||||
<Link.Internal href="/integritetspolicy-elevapp">
|
||||
Integritetspolicy ElevApp
|
||||
</Link.Internal>
|
||||
</li>
|
||||
<li>
|
||||
<Link.Internal href="/qa">Frågor och svar</Link.Internal>
|
||||
</li>
|
||||
|
|
|
@ -3,7 +3,7 @@ import DownloadButtons from './DownloadButtons'
|
|||
import Icon from './Icon'
|
||||
import SectionTitle from './SectionTitle'
|
||||
|
||||
export const price = 11
|
||||
export const price = 0
|
||||
|
||||
const baseFeatures = [
|
||||
{
|
||||
|
|
|
@ -2,8 +2,7 @@ import { formatPrice } from '../utils/intl'
|
|||
import DownloadButtons from './DownloadButtons'
|
||||
import Icon from './Icon'
|
||||
import SectionTitle from './SectionTitle'
|
||||
|
||||
const price = 12
|
||||
import { price } from './Pricing'
|
||||
|
||||
const baseFeatures = [
|
||||
{
|
||||
|
@ -18,6 +17,14 @@ const baseFeatures = [
|
|||
included: true,
|
||||
title: 'Se notifieringar',
|
||||
},
|
||||
{
|
||||
included: true,
|
||||
title: 'Se klasslista',
|
||||
},
|
||||
{
|
||||
included: true,
|
||||
title: 'Se schema',
|
||||
},
|
||||
{
|
||||
included: false,
|
||||
title: 'Gratis support',
|
||||
|
@ -33,17 +40,12 @@ const Pricing = () => {
|
|||
<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="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 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!
|
||||
`}
|
||||
title="Appen är Gratis,"
|
||||
text={`samtidigt, för att kunna fortsätta utveckla och bibehålla appens kvalitet så länge som möjligt, skulle vi uppskatta mycket om du bidrar på Patreon!`}
|
||||
/>
|
||||
</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">Just nu</h3>
|
||||
<div className="mt-5 text-6xl text-pink-500">
|
||||
{formatPrice(price)}
|
||||
</div>
|
||||
|
|
|
@ -9,7 +9,7 @@ const Privacy = () => {
|
|||
<p>
|
||||
"Öppna Skolplattformen", hädanefter "appen", byggs av "Not free beer
|
||||
AB" som en kommersiell app. Appen hämtar all information från
|
||||
Stockholms stads skolplattform, hädanefter Skolplattformen, efter
|
||||
respektive skolplattform, hädanefter Skolplattformen, efter
|
||||
inloggning via BankID. Appens funktion är därmed direkt knuten till
|
||||
att Skolplattformen fungerar. Vi kan endast ta ansvar för att vår kod
|
||||
fungerar – inte deras.
|
||||
|
@ -87,7 +87,7 @@ const Privacy = () => {
|
|||
<p>
|
||||
Denna integritetspolicy gäller fr.o.m. 2021-09-13. Ändringar i denna
|
||||
policy finns dokumenterade på vår{' '}
|
||||
<Link.External href="https://github.com/kolplattformen/skolplattformen-app/">
|
||||
<Link.External href="https://github.com/kolplattformen/skolplattformen/">
|
||||
GitHub
|
||||
</Link.External>
|
||||
.
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
import Link from './Link'
|
||||
|
||||
const PrivacyElevApp = () => {
|
||||
return (
|
||||
<div>
|
||||
<div className="max-w-6xl mx-auto px-5 md:px-0 my-5 md:my-24 prose dark:prose-dark">
|
||||
<h1>Öppna Elevappen</h1>
|
||||
<h2>Integritetspolicy</h2>
|
||||
<p>
|
||||
"Öppna Elevappen", hädanefter "appen", byggs av "Not free beer
|
||||
AB" som en kommersiell app. Appen hämtar all information från
|
||||
respektive skolplattform, hädanefter Skolplattformen, efter
|
||||
inloggning via respektive plattforms inloggningsmetod. Appens funktion är därmed direkt knuten till
|
||||
att Skolplattformen fungerar. Vi kan endast ta ansvar för att vår kod
|
||||
fungerar – inte deras.
|
||||
</p>
|
||||
<p>
|
||||
Denna sida är till för att informera våra besökare och användare om
|
||||
våra policies gällande insamling och hantering av personlig
|
||||
information från användare av tjänsten.
|
||||
</p>
|
||||
<h3>TLDR (~kort sammanfattning på ren svenska)</h3>
|
||||
<p>
|
||||
All information i appen kommer från Skolplattformen. Informationen
|
||||
lämnar aldrig din telefon. Vi är snudd på integritetsfanatiker och
|
||||
skulle aldrig drömma om att samla in information om dig eller dina
|
||||
barn. Det enda som lagras är sånt som lagras i din telefon för att det
|
||||
ska gå snabbare att använda appen. Om vi börjar samla loggar för att
|
||||
lättare kunna lösa eventuella buggar kommer vi se till att de inte
|
||||
innehåller någon som helst information om dig - bara om koden.
|
||||
</p>
|
||||
<h3>Insamling och användning av personlig information</h3>
|
||||
<p>
|
||||
All information som hämtas visas endast för inloggad användare.
|
||||
Informationen cacheas på den mobila enheten. Ingen information skickas
|
||||
från den mobila enheten eller lagras, analyseras eller processas någon
|
||||
annanstans.
|
||||
</p>
|
||||
<p>
|
||||
Inga tredjepartssystem har tillgång till någon del av informationen.
|
||||
</p>
|
||||
<h3>Loggning av data</h3>
|
||||
<p>
|
||||
För närvarande sker ingen loggning av data. Detta kan komma att
|
||||
ändras. Om så sker kommer loggad data att vara strikt begränsad till
|
||||
systeminformation såsom namn på mobil enhet och operativsystemversion
|
||||
samt information om eventuella fel som uppstått i användningen. Ingen
|
||||
personlig information härrörande från Skolplattformen kommer att
|
||||
samlas in.
|
||||
</p>
|
||||
<h3>Cookies</h3>
|
||||
<p>
|
||||
Cookies är filer med små mängder data som används för att identifiera
|
||||
användaren. Dessa används av Skolplattformen och skickas endast dit.
|
||||
Cookies sparas lokalt i enheten och rensas när en inloggad session
|
||||
avslutas.
|
||||
</p>
|
||||
<h3>Säkerhet</h3>
|
||||
<p>
|
||||
Vi har gjort vårt yttersta för att säkerställa säkerheten för din
|
||||
information. Detta innebär i praktiken att vi aldrig skickar vidare
|
||||
någon personlig data från din mobila enhet. All personlig information
|
||||
levereras från Skolplattformen och därmed är du i slutänden hänvisad
|
||||
till att lita på säkerheten i det systemet. I fall då vi, i arbetet
|
||||
med att bygga denna app, har upptäckt potentiella svagheter i
|
||||
Skolplattformen har vi vidtagit steg för att rapportera detta på ett
|
||||
ansvarsfullt sätt. Detta kommer vi göra även fortsättningsvis. Kom
|
||||
ihåg att elektronisk lagring och överföring över Internet aldrig kan
|
||||
garanteras vara 100% säker.
|
||||
</p>
|
||||
<h3>Integritet för barn</h3>
|
||||
<p>
|
||||
Appen läser information från system som hanterar barn under 13 år.
|
||||
Oavsett barnets ålder skickar vi ingen information vidare från din
|
||||
enhet. Den information du får tillgång via appen är samma som du når
|
||||
via Skolplattformen.
|
||||
</p>
|
||||
<h3>Förändringar av integritetspolicyn</h3>
|
||||
<p>
|
||||
Denna integritetspolicy kan komma att uppdateras. Eftersom vi inte
|
||||
samlar in någon information om våra användare kan vi tyvärr inte
|
||||
kontakta dig om så sker. Vi kommer dock informera om det i appen. Om
|
||||
du vill vara på den säkra sidan kan du återbesöka den här sidan då och
|
||||
då.
|
||||
</p>
|
||||
<p>
|
||||
Denna integritetspolicy gäller fr.o.m. 2024-04-29. Ändringar i denna
|
||||
policy finns dokumenterade på vår{' '}
|
||||
<Link.External href="https://github.com/kolplattformen/skolplattformen/">
|
||||
GitHub
|
||||
</Link.External>
|
||||
.
|
||||
</p>
|
||||
<h3>Kontakta oss</h3>
|
||||
<p>
|
||||
Tveka inte att kontakta oss om du har några frågor eller förslag till
|
||||
förbättringar av denna integritetspolicy. Skicka ett mail till{' '}
|
||||
<a href="mailto:dev@skolplattformen.org">dev@skolplattformen.org</a>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default PrivacyElevApp
|
|
@ -251,13 +251,11 @@ const QA = () => {
|
|||
de?
|
||||
</h3>
|
||||
<p>
|
||||
Appen kostar {price} kronor. Intäkten registreras i aktiebolaget Not Free
|
||||
Beer som ägs av tre av utvecklarna och går till att täcka kostnader
|
||||
för inköp. Det täcker inte på långa vägar den tid vi lagt ner. Med en
|
||||
låg engångskostnad ökar vi chansen att vi orkar syssla med underhåll
|
||||
och uppdateringar. Vi vill ju ha en stabil lösning som håller. Just nu
|
||||
jobbar vi på egen fritid med något som förbättrar det kommunen lagt en
|
||||
miljard av allmänna medel på.
|
||||
Vi har en Patreon där summan är synlig. Intäkten registreras i
|
||||
aktiebolaget Not Free Beer som ägs av tre av utvecklarna och går till
|
||||
att täcka kostnader för inköp. Det täcker inte på långa vägar den tid
|
||||
vi lagt ner. Just nu jobbar vi på egen fritid med något som förbättrar
|
||||
det kommunen lagt en miljard av allmänna medel på.
|
||||
</p>
|
||||
<h3>
|
||||
Är det moraliskt att tjäna pengar på något som kommunen borde erbjuda
|
||||
|
@ -280,7 +278,7 @@ const QA = () => {
|
|||
satsar mycket på att så snabbt som möjligt fixa de saker som dyker
|
||||
upp. För att få lite ordning så försöker vi samla alla buggar och
|
||||
önskemål på samma ställe, Github.{' '}
|
||||
<Link.External href="https://github.com/kolplattformen/skolplattformen-app/issues">
|
||||
<Link.External href="https://github.com/kolplattformen/skolplattformen/issues">
|
||||
Klicka här
|
||||
</Link.External>{' '}
|
||||
för att se vilka funktioner och buggar vi redan har tagit emot och
|
||||
|
@ -311,13 +309,13 @@ const QA = () => {
|
|||
Det är en anspelning på hur GNU-projektet beskriver fri programvara:
|
||||
To understand the concept, you should think of “free” as in “free
|
||||
speech,” not as in “free beer”. Då vi har valt att tillgängliggöra all
|
||||
kod som öppen källkod (Apache 2.0) men ändå ta betalt för appen,
|
||||
tyckte vi att namnet var passande.
|
||||
kod som öppen källkod (Apache 2.0), tyckte vi att namnet var passande.
|
||||
</p>
|
||||
<h3>Kontakta oss</h3>
|
||||
<p>
|
||||
Tveka inte att kontakta oss. Skicka ett mail till{' '}
|
||||
<a href="mailto:info@skolplattformen.org">info@skolplattformen.org</a>.
|
||||
<a href="mailto:info@skolplattformen.org">info@skolplattformen.org</a>
|
||||
.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -16,13 +16,13 @@ const Status = () => {
|
|||
<ul>
|
||||
<li>Skicka en tweet 🥉</li>
|
||||
<li>
|
||||
<a href="https://github.com/kolplattformen/skolplattformen-app/issues">
|
||||
<a href="https://github.com/kolplattformen/skolplattformen/issues">
|
||||
Lägg en buggrapport här
|
||||
</a>{' '}
|
||||
🥈
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://github.com/kolplattformen/skolplattformen-app/pulls">
|
||||
<a href="https://github.com/kolplattformen/skolplattformen/pulls">
|
||||
Skicka en PR
|
||||
</a>{' '}
|
||||
🥇
|
||||
|
|
|
@ -66,7 +66,7 @@ export const FEATURES_DATA = [
|
|||
{
|
||||
title: 'Kan byggas ut till fler skolsystem',
|
||||
text:
|
||||
'Just nu stöds bara Stockholm Stads skolplattform men med din hjälp kan fler skolplattformar integreras så att du slipper logga in i flera appar om du har barn i olika skolor.',
|
||||
'Just nu stöds Stockholms och Göteborgs stads skolplattformar. Med din hjälp kan fler integreras så att du slipper använda flera appar om du har barn i olika skolor.',
|
||||
image: (
|
||||
<svg
|
||||
className="fill-current"
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- web.yaml
|
|
@ -0,0 +1,93 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: skolplattformen-web
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: skolplattformen-web
|
||||
namespace: skolplattformen-web
|
||||
spec:
|
||||
ports:
|
||||
- port: 3000
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app: skolplattformen-web
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: skolplattformen-web
|
||||
namespace: skolplattformen-web
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: skolplattformen-web
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: skolplattformen-web
|
||||
spec:
|
||||
containers:
|
||||
- name: skolplattformen-web
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 100Mi
|
||||
image: ghcr.io/kolplattformen/skolplattformen
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 3000
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 3000
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: skolplattformen-web
|
||||
namespace: skolplattformen-web
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: 'letsencrypt-prod'
|
||||
nginx.ingress.kubernetes.io/from-to-www-redirect: 'true'
|
||||
nginx.ingress.kubernetes.io/http2-push-preload: 'true'
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: '500m'
|
||||
nginx.ingress.kubernetes.io/proxy-pass-headers: 'Location'
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
more_set_headers "X-Content-Type-Options: nosniff";
|
||||
more_set_headers "X-Frame-Options: DENY";
|
||||
more_set_headers "X-Xss-Protection: 0";
|
||||
more_set_headers "Strict-Transport-Security: max-age=31536000; includeSubDomains; preload";
|
||||
more_set_headers "Cross-Origin-Resource-Policy: same-site";
|
||||
more_set_headers "Referrer-Policy strict-origin";
|
||||
external-dns.alpha.kubernetes.io/hostname: new.skolplattformen.org.
|
||||
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
tls:
|
||||
- hosts:
|
||||
- skolplattformen.org
|
||||
- www.skolplattformen.org
|
||||
secretName: web-secret-tls
|
||||
rules:
|
||||
- host: skolplattformen.org
|
||||
http:
|
||||
paths:
|
||||
- pathType: Prefix
|
||||
path: '/'
|
||||
backend:
|
||||
service:
|
||||
name: skolplattformen-web
|
||||
port:
|
||||
number: 3000
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "skolplattformen-site",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.4",
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
import { NextPage } from 'next'
|
||||
import PrivacyElevApp from '../components/PrivacyElevApp'
|
||||
|
||||
const IntegrityElevAppPage: NextPage = () => {
|
||||
return <PrivacyElevApp />
|
||||
}
|
||||
|
||||
export default IntegrityElevAppPage
|
|
@ -0,0 +1,13 @@
|
|||
apiVersion: skaffold/v4beta1
|
||||
kind: Config
|
||||
metadata:
|
||||
name: skolplattformen-web
|
||||
build:
|
||||
artifacts:
|
||||
- image: skolplattformen/web
|
||||
context: .
|
||||
manifests:
|
||||
rawYaml:
|
||||
- k8s/web.yaml
|
||||
deploy:
|
||||
kubectl: {}
|
|
@ -49,7 +49,7 @@ For more information, please visit [CocoaPods Getting Started guide](https://gui
|
|||
|
||||
### Running on a device
|
||||
|
||||
The above command will automatically run your app on the iOS Simulator by default. If you want to run the app on an actual physical iOS device, please follow the instructions [here](https://reactnative.dev/docs/running-on-device.
|
||||
The above command will automatically run your app on the iOS Simulator by default. If you want to run the app on an actual physical iOS device, please follow the instructions [here](https://reactnative.dev/docs/running-on-device).
|
||||
|
||||
## Running the app
|
||||
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'jsdom',
|
||||
transform: {
|
||||
'.(ts|tsx)': 'ts-jest',
|
||||
},
|
||||
testRegex: '(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$',
|
||||
moduleFileExtensions: ['ts', 'tsx', 'js'],
|
||||
displayName: 'api-hjarntorget',
|
||||
resolver: '@nrwl/jest/plugins/resolver',
|
||||
moduleFileExtensions: ['ts', 'js', 'html', 'tsx', 'jsx'],
|
||||
setupFilesAfterEnv: ['<rootDir>/test-setup.ts'],
|
||||
}
|
||||
|
|
|
@ -1,222 +1,248 @@
|
|||
import { ApiHjarntorget } from './apiHjarntorget'
|
||||
import { checkStatus } from './loginStatus'
|
||||
import { wrapToughCookie } from '@skolplattformen/api'
|
||||
import { CookieJar } from 'tough-cookie'
|
||||
import { ApiHjarntorget } from './apiHjarntorget'
|
||||
|
||||
const setupSuccessfullLoginInitiation = (fetcherMock: jest.Mock) => {
|
||||
// 'begin-login'
|
||||
fetcherMock.mockReturnValueOnce(Promise.resolve({
|
||||
url: "some url with url encoded at the end?return=hello"
|
||||
}))
|
||||
// 'begin-login'
|
||||
fetcherMock.mockReturnValueOnce(
|
||||
Promise.resolve({
|
||||
url: 'some url with url encoded at the end?return=hello',
|
||||
})
|
||||
)
|
||||
|
||||
// 'init-shibboleth-login'
|
||||
fetcherMock.mockReturnValueOnce(Promise.resolve({
|
||||
url: "some url with url encoded at the end?Target=hello"
|
||||
}))
|
||||
// 'init-shibboleth-login'
|
||||
fetcherMock.mockReturnValueOnce(
|
||||
Promise.resolve({
|
||||
url: 'some url with url encoded at the end?Target=hello',
|
||||
})
|
||||
)
|
||||
|
||||
// 'init-bankId'
|
||||
fetcherMock.mockReturnValueOnce(Promise.resolve({
|
||||
text: jest.fn().mockReturnValue(Promise.resolve(`
|
||||
// 'init-bankId'
|
||||
fetcherMock.mockReturnValueOnce(
|
||||
Promise.resolve({
|
||||
text: jest.fn().mockReturnValue(
|
||||
Promise.resolve(`
|
||||
<html>
|
||||
<body>
|
||||
<input name="RelayState" value="aUUID"></input>
|
||||
<input name="SAMLRequest" value="somebase64value"></input>
|
||||
</body>
|
||||
</html>`))
|
||||
}))
|
||||
</html>`)
|
||||
),
|
||||
})
|
||||
)
|
||||
|
||||
// 'pick-mvghost'
|
||||
fetcherMock.mockReturnValueOnce(Promise.resolve({
|
||||
url: "some url to a mvghost"
|
||||
}))
|
||||
// 'pick-mvghost'
|
||||
fetcherMock.mockReturnValueOnce(
|
||||
Promise.resolve({
|
||||
url: 'some url to a mvghost',
|
||||
})
|
||||
)
|
||||
|
||||
// 'start-bankId'
|
||||
fetcherMock.mockReturnValueOnce(Promise.resolve({
|
||||
url: "some base url to a mvghost to use when polling status"
|
||||
}))
|
||||
// 'start-bankId'
|
||||
fetcherMock.mockReturnValueOnce(
|
||||
Promise.resolve({
|
||||
url: 'some base url to a mvghost to use when polling status',
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
const setupSuccessfullBankIdLogin = (fetcherMock: jest.Mock) => {
|
||||
// 'poll-bankid-status'
|
||||
fetcherMock.mockReturnValueOnce(Promise.resolve({
|
||||
json: jest.fn().mockReturnValue(Promise.resolve({
|
||||
infotext: "",
|
||||
location: "an url to go to confirm the login"
|
||||
}))
|
||||
}))
|
||||
// 'poll-bankid-status'
|
||||
fetcherMock.mockReturnValueOnce(
|
||||
Promise.resolve({
|
||||
json: jest.fn().mockReturnValue(
|
||||
Promise.resolve({
|
||||
infotext: '',
|
||||
location: 'an url to go to confirm the login',
|
||||
})
|
||||
),
|
||||
})
|
||||
)
|
||||
|
||||
// 'confirm-signature-redirect'
|
||||
fetcherMock.mockReturnValueOnce(Promise.resolve({
|
||||
text: jest.fn().mockReturnValue(Promise.resolve(`
|
||||
// 'confirm-signature-redirect'
|
||||
fetcherMock.mockReturnValueOnce(
|
||||
Promise.resolve({
|
||||
text: jest.fn().mockReturnValue(
|
||||
Promise.resolve(`
|
||||
<html>
|
||||
<body>
|
||||
<textarea name="RelayState">relay state probably same uuid as before</textarea>
|
||||
<textarea name="SAMLResponse">base64 encoded saml response</textarea>
|
||||
</body>
|
||||
</html>`))
|
||||
}))
|
||||
</html>`)
|
||||
),
|
||||
})
|
||||
)
|
||||
|
||||
// 'authgbg-saml-login'
|
||||
fetcherMock.mockReturnValueOnce(Promise.resolve({
|
||||
text: jest.fn().mockReturnValue(Promise.resolve(`
|
||||
// 'authgbg-saml-login'
|
||||
fetcherMock.mockReturnValueOnce(
|
||||
Promise.resolve({
|
||||
text: jest.fn().mockReturnValue(
|
||||
Promise.resolve(`
|
||||
<html>
|
||||
<body>
|
||||
<input name="RelayState" value="aUUID"></input>
|
||||
<input name="SAMLResponse" value="somebase64value"></input>
|
||||
</body>
|
||||
</html>`))
|
||||
}))
|
||||
</html>`)
|
||||
),
|
||||
})
|
||||
)
|
||||
|
||||
// 'hjarntorget-saml-login'
|
||||
fetcherMock.mockReturnValueOnce(Promise.resolve({ status: 200 }))
|
||||
// 'hjarntorget-saml-login'
|
||||
fetcherMock.mockReturnValueOnce(Promise.resolve({ status: 200 }))
|
||||
}
|
||||
|
||||
describe('api', () => {
|
||||
let fetcherMock: jest.Mock
|
||||
let api: ApiHjarntorget
|
||||
let fetcherMock: jest.Mock
|
||||
let api: ApiHjarntorget
|
||||
|
||||
beforeEach(() => {
|
||||
const fetcher = jest.fn()
|
||||
fetcherMock = fetcher as jest.Mock
|
||||
|
||||
const cookieManager = wrapToughCookie(new CookieJar())
|
||||
cookieManager.clearAll();
|
||||
api = new ApiHjarntorget(jest.fn(), cookieManager)
|
||||
api.replaceFetcher(fetcher)
|
||||
})
|
||||
// describe('#login', () => {
|
||||
// it('goes through single sing-on steps', async (done) => {
|
||||
// setupSuccessfullLoginInitiation(fetcherMock)
|
||||
// setupSuccessfullBankIdLogin(fetcherMock)
|
||||
// const personalNumber = 'my personal number'
|
||||
beforeEach(() => {
|
||||
const fetcher = jest.fn()
|
||||
fetcherMock = fetcher as jest.Mock
|
||||
|
||||
// const loginComplete = new Promise((resolve, reject) => {
|
||||
// api.on('login', () => done())
|
||||
// });
|
||||
// await api.login(personalNumber)
|
||||
// })
|
||||
// it('checker emits PENDING', async (done) => {
|
||||
// // 'poll-bankid-status'
|
||||
// fetcherMock.mockReturnValueOnce(Promise.resolve({
|
||||
// json: jest.fn().mockReturnValue(Promise.resolve({
|
||||
// infotext: "some prompt to do signing in app",
|
||||
// location: ""
|
||||
// }))
|
||||
// }))
|
||||
const cookieManager = wrapToughCookie(new CookieJar())
|
||||
cookieManager.clearAll()
|
||||
api = new ApiHjarntorget(jest.fn(), cookieManager)
|
||||
api.replaceFetcher(fetcher)
|
||||
})
|
||||
it('works', () => {
|
||||
expect(1 + 1).toBe(2)
|
||||
})
|
||||
// describe('#login', () => {
|
||||
// it('goes through single sing-on steps', async (done) => {
|
||||
// setupSuccessfullLoginInitiation(fetcherMock)
|
||||
// setupSuccessfullBankIdLogin(fetcherMock)
|
||||
// const personalNumber = 'my personal number'
|
||||
|
||||
// const status = checkStatus(fetcherMock, "some url")
|
||||
// status.on('PENDING', () => {
|
||||
// status.cancel()
|
||||
// done()
|
||||
// })
|
||||
// })
|
||||
// it('checker emits ERROR', async (done) => {
|
||||
// // 'poll-bankid-status'
|
||||
// fetcherMock.mockReturnValueOnce(Promise.resolve({
|
||||
// json: jest.fn().mockReturnValue(Promise.resolve({
|
||||
// infotext: "some prompt to do signing in app",
|
||||
// location: "url with error in the name"
|
||||
// }))
|
||||
// }))
|
||||
// const loginComplete = new Promise((resolve, reject) => {
|
||||
// api.on('login', () => done())
|
||||
// });
|
||||
// await api.login(personalNumber)
|
||||
// })
|
||||
// it('checker emits PENDING', async (done) => {
|
||||
// // 'poll-bankid-status'
|
||||
// fetcherMock.mockReturnValueOnce(Promise.resolve({
|
||||
// json: jest.fn().mockReturnValue(Promise.resolve({
|
||||
// infotext: "some prompt to do signing in app",
|
||||
// location: ""
|
||||
// }))
|
||||
// }))
|
||||
|
||||
// const status = checkStatus(fetcherMock, "some url")
|
||||
// status.on('ERROR', () => {
|
||||
// status.cancel()
|
||||
// done()
|
||||
// })
|
||||
// })
|
||||
// it('checker emits ERROR when an exception occurs', async (done) => {
|
||||
// // 'poll-bankid-status'
|
||||
// fetcherMock.mockReturnValueOnce(Promise.resolve({
|
||||
// json: jest.fn().mockReturnValue(Promise.resolve({
|
||||
// infotext: undefined,
|
||||
// location: undefined
|
||||
// }))
|
||||
// }))
|
||||
// const status = checkStatus(fetcherMock, "some url")
|
||||
// status.on('PENDING', () => {
|
||||
// status.cancel()
|
||||
// done()
|
||||
// })
|
||||
// })
|
||||
// it('checker emits ERROR', async (done) => {
|
||||
// // 'poll-bankid-status'
|
||||
// fetcherMock.mockReturnValueOnce(Promise.resolve({
|
||||
// json: jest.fn().mockReturnValue(Promise.resolve({
|
||||
// infotext: "some prompt to do signing in app",
|
||||
// location: "url with error in the name"
|
||||
// }))
|
||||
// }))
|
||||
|
||||
// const status = checkStatus(fetcherMock, "some url")
|
||||
// status.on('ERROR', () => {
|
||||
// status.cancel()
|
||||
// done()
|
||||
// })
|
||||
// })
|
||||
// it('remembers used personal number', async (done) => {
|
||||
// setupSuccessfullLoginInitiation(fetcherMock)
|
||||
// setupSuccessfullBankIdLogin(fetcherMock)
|
||||
// const personalNumber = 'my personal number'
|
||||
// await api.login(personalNumber)
|
||||
// api.on('login', () => {
|
||||
// expect(api.getPersonalNumber()).toEqual(personalNumber)
|
||||
// done()
|
||||
// })
|
||||
// })
|
||||
// it('forgets used personal number if sign in is unsuccessful', async (done) => {
|
||||
// setupSuccessfullLoginInitiation(fetcherMock)
|
||||
// // 'poll-bankid-status'
|
||||
// fetcherMock.mockReturnValueOnce(Promise.resolve({
|
||||
// json: jest.fn().mockReturnValue(Promise.resolve({
|
||||
// infotext: "",
|
||||
// location: "an url to go to confirm the login"
|
||||
// }))
|
||||
// }))
|
||||
// // 'confirm-signature-redirect'
|
||||
// fetcherMock.mockReturnValueOnce(Promise.resolve({
|
||||
// text: Promise.resolve("some error occured")
|
||||
// }))
|
||||
// const status = checkStatus(fetcherMock, "some url")
|
||||
// status.on('ERROR', () => {
|
||||
// status.cancel()
|
||||
// done()
|
||||
// })
|
||||
// })
|
||||
// it('checker emits ERROR when an exception occurs', async (done) => {
|
||||
// // 'poll-bankid-status'
|
||||
// fetcherMock.mockReturnValueOnce(Promise.resolve({
|
||||
// json: jest.fn().mockReturnValue(Promise.resolve({
|
||||
// infotext: undefined,
|
||||
// location: undefined
|
||||
// }))
|
||||
// }))
|
||||
|
||||
// const personalNumber = 'my personal number'
|
||||
// const status = await api.login(personalNumber)
|
||||
// const status = checkStatus(fetcherMock, "some url")
|
||||
// status.on('ERROR', () => {
|
||||
// status.cancel()
|
||||
// done()
|
||||
// })
|
||||
// })
|
||||
// it('remembers used personal number', async (done) => {
|
||||
// setupSuccessfullLoginInitiation(fetcherMock)
|
||||
// setupSuccessfullBankIdLogin(fetcherMock)
|
||||
// const personalNumber = 'my personal number'
|
||||
// await api.login(personalNumber)
|
||||
// api.on('login', () => {
|
||||
// expect(api.getPersonalNumber()).toEqual(personalNumber)
|
||||
// done()
|
||||
// })
|
||||
// })
|
||||
// it('forgets used personal number if sign in is unsuccessful', async (done) => {
|
||||
// setupSuccessfullLoginInitiation(fetcherMock)
|
||||
// // 'poll-bankid-status'
|
||||
// fetcherMock.mockReturnValueOnce(Promise.resolve({
|
||||
// json: jest.fn().mockReturnValue(Promise.resolve({
|
||||
// infotext: "",
|
||||
// location: "an url to go to confirm the login"
|
||||
// }))
|
||||
// }))
|
||||
// // 'confirm-signature-redirect'
|
||||
// fetcherMock.mockReturnValueOnce(Promise.resolve({
|
||||
// text: Promise.resolve("some error occured")
|
||||
// }))
|
||||
|
||||
// status.on('ERROR', () => {
|
||||
// expect(api.getPersonalNumber()).toEqual(undefined)
|
||||
// done()
|
||||
// })
|
||||
// })
|
||||
// const personalNumber = 'my personal number'
|
||||
// const status = await api.login(personalNumber)
|
||||
|
||||
// // TODO: Possibly rewrite the mocking so we mock the responses more properly,
|
||||
// // that way it would be possible to implement a throwIfNotOk wrapper for the
|
||||
// // fetch calls.
|
||||
// // it('throws error on external api error', async () => {
|
||||
// // const personalNumber = 'my personal number'
|
||||
// // try {
|
||||
// // await api.login(personalNumber)
|
||||
// // } catch (error: any) {
|
||||
// // expect(error.message).toEqual(expect.stringContaining('Server Error'))
|
||||
// // }
|
||||
// // })
|
||||
// })
|
||||
// describe('#logout', () => {
|
||||
// // it('clears session', async () => {
|
||||
// // await api.logout()
|
||||
// // const session = await api.getSession('')
|
||||
// // expect(session).toEqual({
|
||||
// // headers: {
|
||||
// // cookie: '',
|
||||
// // },
|
||||
// // })
|
||||
// // })
|
||||
// it('emits logout event', async () => {
|
||||
// const listener = jest.fn()
|
||||
// api.on('logout', listener)
|
||||
// await api.logout()
|
||||
// expect(listener).toHaveBeenCalled()
|
||||
// })
|
||||
// it('sets .isLoggedIn', async () => {
|
||||
// api.isLoggedIn = true
|
||||
// await api.logout()
|
||||
// expect(api.isLoggedIn).toBe(false)
|
||||
// })
|
||||
// it('forgets personalNumber', async () => {
|
||||
// // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
// (api as any).personalNumber = 'my personal number'
|
||||
// api.isLoggedIn = true
|
||||
// status.on('ERROR', () => {
|
||||
// expect(api.getPersonalNumber()).toEqual(undefined)
|
||||
// done()
|
||||
// })
|
||||
// })
|
||||
|
||||
// await api.logout()
|
||||
// // TODO: Possibly rewrite the mocking so we mock the responses more properly,
|
||||
// // that way it would be possible to implement a throwIfNotOk wrapper for the
|
||||
// // fetch calls.
|
||||
// // it('throws error on external api error', async () => {
|
||||
// // const personalNumber = 'my personal number'
|
||||
// // try {
|
||||
// // await api.login(personalNumber)
|
||||
// // } catch (error: any) {
|
||||
// // expect(error.message).toEqual(expect.stringContaining('Server Error'))
|
||||
// // }
|
||||
// // })
|
||||
// })
|
||||
// describe('#logout', () => {
|
||||
// // it('clears session', async () => {
|
||||
// // await api.logout()
|
||||
// // const session = await api.getSession('')
|
||||
// // expect(session).toEqual({
|
||||
// // headers: {
|
||||
// // cookie: '',
|
||||
// // },
|
||||
// // })
|
||||
// // })
|
||||
// it('emits logout event', async () => {
|
||||
// const listener = jest.fn()
|
||||
// api.on('logout', listener)
|
||||
// await api.logout()
|
||||
// expect(listener).toHaveBeenCalled()
|
||||
// })
|
||||
// it('sets .isLoggedIn', async () => {
|
||||
// api.isLoggedIn = true
|
||||
// await api.logout()
|
||||
// expect(api.isLoggedIn).toBe(false)
|
||||
// })
|
||||
// it('forgets personalNumber', async () => {
|
||||
// // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
// (api as any).personalNumber = 'my personal number'
|
||||
// api.isLoggedIn = true
|
||||
|
||||
// expect(api.getPersonalNumber()).toEqual(undefined)
|
||||
// })
|
||||
// })
|
||||
/*
|
||||
// await api.logout()
|
||||
|
||||
// expect(api.getPersonalNumber()).toEqual(undefined)
|
||||
// })
|
||||
// })
|
||||
/*
|
||||
describe('fake', () => {
|
||||
it('sets fake mode for the correct pnr:s', async () => {
|
||||
let status
|
||||
|
|
|
@ -8,12 +8,15 @@ import {
|
|||
Fetch,
|
||||
Fetcher,
|
||||
FetcherOptions,
|
||||
FrejaLoginStatusChecker,
|
||||
LoginStatusChecker,
|
||||
MenuItem,
|
||||
NewsItem,
|
||||
Notification,
|
||||
ScheduleItem,
|
||||
SchoolContact,
|
||||
Skola24Child,
|
||||
Teacher,
|
||||
TimetableEntry,
|
||||
toMarkdown,
|
||||
URLSearchParams,
|
||||
|
@ -49,6 +52,7 @@ import {
|
|||
verifyUrlBase,
|
||||
wallMessagesUrl,
|
||||
} from './routes'
|
||||
import parse from '@skolplattformen/curriculum'
|
||||
|
||||
function getDateOfISOWeek(week: number, year: number) {
|
||||
const simple = new Date(year, 0, 1 + (week - 1) * 7)
|
||||
|
@ -147,13 +151,8 @@ export class ApiHjarntorget extends EventEmitter implements Api {
|
|||
}
|
||||
|
||||
async setSessionCookie(sessionCookie: string): Promise<void> {
|
||||
await this.fetch('login-cookie', hjarntorgetUrl, {
|
||||
headers: {
|
||||
cookie: sessionCookie,
|
||||
},
|
||||
redirect: 'manual',
|
||||
})
|
||||
|
||||
this.cookieManager.setCookieString(sessionCookie, hjarntorgetUrl)
|
||||
|
||||
const user = await this.getUser()
|
||||
if (!user.isAuthenticated) {
|
||||
throw new Error('Session cookie is expired')
|
||||
|
@ -253,6 +252,21 @@ export class ApiHjarntorget extends EventEmitter implements Api {
|
|||
return Promise.resolve([])
|
||||
}
|
||||
|
||||
public async getTeachers(child: EtjanstChild): Promise<Teacher[]> {
|
||||
if (!this.isLoggedIn) {
|
||||
throw new Error('Not logged in...')
|
||||
}
|
||||
return Promise.resolve([])
|
||||
}
|
||||
|
||||
public async getSchoolContacts(child: EtjanstChild): Promise<SchoolContact[]> {
|
||||
if (!this.isLoggedIn) {
|
||||
throw new Error('Not logged in...')
|
||||
}
|
||||
return Promise.resolve([])
|
||||
}
|
||||
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
async getNews(_child: EtjanstChild): Promise<NewsItem[]> {
|
||||
if (!this.isLoggedIn) {
|
||||
|
@ -458,9 +472,8 @@ export class ApiHjarntorget extends EventEmitter implements Api {
|
|||
zone: FixedOffsetZone.instance(l.endDate.timezoneOffsetMinutes),
|
||||
})
|
||||
return {
|
||||
...parse(l.title, _lang),
|
||||
id: l.id,
|
||||
code: l.title,
|
||||
name: l.title,
|
||||
teacher: l.bookedTeacherNames && l.bookedTeacherNames[0],
|
||||
location: l.location,
|
||||
timeStart: start.toISOTime().substring(0, 5),
|
||||
|
@ -468,7 +481,7 @@ export class ApiHjarntorget extends EventEmitter implements Api {
|
|||
dayOfWeek: start.toJSDate().getDay(),
|
||||
blockName: l.title,
|
||||
dateStart: start.toISODate(),
|
||||
dateEnd: start.toISODate(),
|
||||
dateEnd: end.toISODate(),
|
||||
} as TimetableEntry
|
||||
})
|
||||
}
|
||||
|
@ -591,4 +604,8 @@ export class ApiHjarntorget extends EventEmitter implements Api {
|
|||
emitter.token = 'fake'
|
||||
return emitter
|
||||
}
|
||||
|
||||
async loginFreja(): Promise<FrejaLoginStatusChecker> {
|
||||
throw new Error('Not implemented...')
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,22 @@
|
|||
import { toNamespacedPath } from "path";
|
||||
|
||||
// TODO: fix the startDate/endDate of all lessons
|
||||
export const lessons_133700_goteborgsstad = () => {
|
||||
const baseTime = 1636357800000;
|
||||
const baseDate = new Date(baseTime)
|
||||
const today = new Date()
|
||||
const currentHour = today.getHours()
|
||||
today.setHours(baseDate.getHours())
|
||||
today.setMinutes(baseDate.getMinutes())
|
||||
today.setSeconds(0)
|
||||
|
||||
const offset = Math.abs(baseTime - today.getTime())
|
||||
let offset = Math.abs(baseTime - today.getTime())
|
||||
const weekDay = today.getDay()
|
||||
|
||||
if(weekDay == 6 || (weekDay == 5 && currentHour >= 18)) offset = offset + 2 * 86400000
|
||||
if(weekDay == 0) offset = offset + 86400000
|
||||
if(weekDay > 0 && weekDay < 6 && currentHour >= 18) offset = offset + 86400000
|
||||
|
||||
return {
|
||||
"url": "https://hjarntorget.goteborg.se/api/schema/lessons?forUser=133700_goteborgsstad&startDateIso=2021-11-01&endDateIso=2021-11-08",
|
||||
"headers": {
|
||||
|
@ -206,14 +215,21 @@ export const lessons_133700_goteborgsstad = () => {
|
|||
}
|
||||
|
||||
export const lessons_123456_goteborgsstad = () => {
|
||||
const baseTime = 1636355400000;
|
||||
const baseTime = 1636357800000;
|
||||
const baseDate = new Date(baseTime)
|
||||
const today = new Date()
|
||||
const currentHour = today.getHours()
|
||||
today.setHours(baseDate.getHours())
|
||||
today.setMinutes(baseDate.getMinutes())
|
||||
today.setSeconds(0)
|
||||
|
||||
const offset = Math.abs(baseTime - today.getTime())
|
||||
|
||||
let offset = Math.abs(baseTime - today.getTime())
|
||||
const weekDay = today.getDay()
|
||||
|
||||
if(weekDay == 6 || (weekDay == 5 && currentHour >= 18)) offset = offset + 2 * 86400000
|
||||
if(weekDay == 0) offset = offset + 86400000
|
||||
if(weekDay > 0 && weekDay < 6 && currentHour >= 18) offset = offset + 86400000
|
||||
|
||||
return {
|
||||
"url": "https://hjarntorget.goteborg.se/api/schema/lessons?forUser=123456_goteborgsstad&startDateIso=2021-11-01&endDateIso=2021-11-08",
|
||||
"headers": {
|
||||
|
|
|
@ -2,6 +2,7 @@ import { Features } from '@skolplattformen/api'
|
|||
|
||||
export const features: Features = {
|
||||
LOGIN_BANK_ID_SAME_DEVICE_WITHOUT_ID: false,
|
||||
LOGIN_FREJA_EID: false,
|
||||
FOOD_MENU: false,
|
||||
CLASS_LIST: false,
|
||||
}
|
||||
|
|
|
@ -17,44 +17,5 @@
|
|||
"prepare": "yarn build",
|
||||
"run-dev": "yarn run build && node run",
|
||||
"publish-package": "npm publish --access public"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@skolplattformen/curriculum": "^1.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@react-native-cookies/cookies": "^6.0.7",
|
||||
"@skolplattformen/curriculum": "^1.4.2",
|
||||
"@types/base-64": "^1.0.0",
|
||||
"@types/he": "^1.1.1",
|
||||
"@types/jest": "^26.0.22",
|
||||
"@types/luxon": "^1.26.4",
|
||||
"@types/node-fetch": "^2.5.10",
|
||||
"@types/tough-cookie": "^4.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^4.22.0",
|
||||
"@typescript-eslint/parser": "^4.22.0",
|
||||
"eslint": "^7.24.0",
|
||||
"eslint-config-airbnb-typescript": "^12.3.1",
|
||||
"eslint-config-prettier": "^8.2.0",
|
||||
"eslint-plugin-import": "^2.22.1",
|
||||
"eslint-plugin-prettier": "^3.4.0",
|
||||
"fetch-cookie": "^0.11.0",
|
||||
"https-proxy-agent": "^5.0.0",
|
||||
"jest": "^26.6.3",
|
||||
"node-blob": "^0.0.2",
|
||||
"node-fetch": "^2.6.1",
|
||||
"prettier": "^2.2.1",
|
||||
"tough-cookie": "^4.0.0",
|
||||
"ts-jest": "^26.5.5",
|
||||
"typescript": "^4.2.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"camelcase-keys": "^6.2.2",
|
||||
"change-case": "^4.1.2",
|
||||
"events": "^3.3.0",
|
||||
"h2m": "^0.7.0",
|
||||
"he": "^1.2.0",
|
||||
"js-htmlencode": "^0.3.0",
|
||||
"luxon": "^1.26.0",
|
||||
"node-html-parser": "^2.1.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"root": "libs/api-hjarntorget",
|
||||
"sourceRoot": "libs/api-hjarntorget/src",
|
||||
"projectType": "library",
|
||||
"targets": {
|
||||
"lint": {
|
||||
"executor": "@nrwl/linter:eslint",
|
||||
"outputs": ["{options.outputFile}"],
|
||||
"options": {
|
||||
"lintFilePatterns": ["libs/api-hjarntorget/**/*.{ts,tsx,js,jsx}"]
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"executor": "@nrwl/jest:jest",
|
||||
"outputs": ["coverage/libs/api-hjarntorget"],
|
||||
"options": {
|
||||
"jestConfig": "libs/api-hjarntorget/jest.config.js",
|
||||
"passWithNoTests": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
import '@testing-library/jest-native/extend-expect'
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"module": "commonjs",
|
||||
"types": ["jest", "node"],
|
||||
"composite": true
|
||||
},
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.spec.tsx",
|
||||
"**/*.spec.js",
|
||||
"**/*.spec.jsx",
|
||||
"**/*.test.ts",
|
||||
"**/*.test.tsx",
|
||||
"**/*.test.js",
|
||||
"**/*.test.jsx",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": ["plugin:@nrwl/nx/react", "../../.eslintrc.json"],
|
||||
"extends": ["@react-native-community","plugin:@nrwl/nx/react", "../../.eslintrc.json"],
|
||||
"ignorePatterns": ["!**/*", "public", ".cache", "node_modules"],
|
||||
"overrides": [
|
||||
{
|
||||
|
|
|
@ -1,13 +1,6 @@
|
|||
module.exports = {
|
||||
displayName: 'api-skolplattformen',
|
||||
preset: 'react-native',
|
||||
resolver: '@nrwl/jest/plugins/resolver',
|
||||
moduleFileExtensions: ['ts', 'js', 'html', 'tsx', 'jsx'],
|
||||
setupFilesAfterEnv: ['<rootDir>/test-setup.ts'],
|
||||
transform: {
|
||||
'\\.(js|ts|tsx)$': require.resolve('react-native/jest/preprocessor.js'),
|
||||
'^.+\\.(bmp|gif|jpg|jpeg|mp4|png|psd|svg|webp)$': require.resolve(
|
||||
'react-native/jest/assetFileTransformer.js'
|
||||
),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue