diff --git a/apps/native/app/package.json b/apps/native/app/package.json
index 6fdecceb6f9b..3e42a3ae7714 100644
--- a/apps/native/app/package.json
+++ b/apps/native/app/package.json
@@ -78,6 +78,7 @@
"react-native-interactable": "2.0.1",
"react-native-keyboard-manager": "6.5.4-3",
"react-native-keychain": "8.1.1",
+ "react-native-markdown-display": "7.0.2",
"react-native-mmkv-storage": "0.9.1",
"react-native-navigation": "7.40.0",
"react-native-navigation-hooks": "6.3.0",
diff --git a/apps/native/app/src/graphql/queries/health.graphql b/apps/native/app/src/graphql/queries/health.graphql
index 15106fbfb6df..850b10e951d6 100644
--- a/apps/native/app/src/graphql/queries/health.graphql
+++ b/apps/native/app/src/graphql/queries/health.graphql
@@ -49,3 +49,31 @@ query GetPaymentStatus {
maximumMonthlyPayment
}
}
+
+query GetVaccinations {
+ healthDirectorateVaccinations {
+ vaccinations {
+ id
+ name
+ description
+ isFeatured
+ status
+ statusName
+ statusColor
+ lastVaccinationDate
+ vaccinationsInfo {
+ id
+ name
+ date
+ age {
+ years
+ months
+ }
+ url
+ comment
+ rejected
+ }
+ comments
+ }
+ }
+}
diff --git a/apps/native/app/src/messages/en.ts b/apps/native/app/src/messages/en.ts
index e4f9b8d91e0e..26488788f35b 100644
--- a/apps/native/app/src/messages/en.ts
+++ b/apps/native/app/src/messages/en.ts
@@ -609,7 +609,7 @@ export const en: TranslatedMessages = {
'updateApp.button': 'Update',
'updateApp.buttonSkip': 'Skip',
- // health
+ // health - overview
'health.overview.screenTitle': 'Health',
'health.overview.title': 'My health',
'health.overview.description':
@@ -628,6 +628,7 @@ export const en: TranslatedMessages = {
'health.overview.paymentCredit': 'Credit',
'health.overview.paymentDebt': 'Debt',
'health.overview.therapy': 'Therapy',
+ 'health.overview.vaccinations': 'Vaccinations',
'health.overview.aidsAndNutrition': 'Aids and nutrition',
'health.overview.medicinePurchase': 'Medicine purchase',
'health.overview.period': 'Period',
@@ -635,4 +636,20 @@ export const en: TranslatedMessages = {
'health.overview.levelStatusValue': 'Level {level}, you pay {percentage}%',
'health.overview.medicinePurchaseNoActivePeriodWarning':
'A new payment period begins with the next medicine purchase',
+
+ // health - vaccinations
+ 'health.vaccinations.screenTitle': 'Vaccinations',
+ 'health.vaccinations.title': 'Vaccinations',
+ 'health.vaccinations.description':
+ 'Here you can see a list of vaccines you have received, vaccination status and other information.',
+ 'health.vaccinations.generalVaccinations': 'General vaccinations',
+ 'health.vaccinations.otherVaccinations': 'Other vaccinations',
+ 'health.vaccinations.number': 'No.',
+ 'health.vaccinations.date': 'Date',
+ 'health.vaccinations.age': 'Age',
+ 'health.vaccinations.vaccine': 'Vaccine',
+ 'health.vaccinations.noVaccinations': 'No vaccinations recorded',
+ 'health.vaccinations.noVaccinationsDescription':
+ 'If you believe you have data that should appear here, please contact service provider.',
+ 'health.vaccinations.directorateOfHealth': 'The directorate of Health',
}
diff --git a/apps/native/app/src/messages/is.ts b/apps/native/app/src/messages/is.ts
index 8feb23255970..9cc3d7391845 100644
--- a/apps/native/app/src/messages/is.ts
+++ b/apps/native/app/src/messages/is.ts
@@ -609,7 +609,7 @@ export const is = {
'updateApp.button': 'Uppfæra',
'updateApp.buttonSkip': 'Sleppa',
- // health
+ // health - overview
'health.overview.screenTitle': 'Heilsa',
'health.overview.title': 'Heilsan mín',
'health.overview.description':
@@ -628,6 +628,7 @@ export const is = {
'health.overview.paymentCredit': 'Inneign',
'health.overview.paymentDebt': 'Skuld',
'health.overview.therapy': 'Þjálfun',
+ 'health.overview.vaccinations': 'Bólusetningar',
'health.overview.aidsAndNutrition': 'Hjálpartæki og næring',
'health.overview.medicinePurchase': 'Lyfjakaup',
'health.overview.period': 'Tímabil',
@@ -636,4 +637,20 @@ export const is = {
'Greiðsluþrep {level}, þú greiðir {percentage}%',
'health.overview.medicinePurchaseNoActivePeriodWarning':
'Nýtt greiðslutímabil hefst við næstu lyfjakaup',
+
+ // health - vaccinations
+ 'health.vaccinations.screenTitle': 'Bólusetningar',
+ 'health.vaccinations.title': 'Bólusetningar',
+ 'health.vaccinations.description':
+ 'Hér getur þú séð lista yfir bóluefni sem þú hefur fengið, stöðu bólusetningar og aðrar upplýsingar.',
+ 'health.vaccinations.generalVaccinations': 'Almennar bólusetningar',
+ 'health.vaccinations.otherVaccinations': 'Aðrar bólusetningar',
+ 'health.vaccinations.number': 'Nr.',
+ 'health.vaccinations.date': 'Dags.',
+ 'health.vaccinations.age': 'Aldur',
+ 'health.vaccinations.vaccine': 'Bóluefni',
+ 'health.vaccinations.noVaccinations': 'Engar bólusetningar skráðar',
+ 'health.vaccinations.noVaccinationsDescription':
+ 'Ef þú telur þig eiga gögn sem ættu að birtast hér, vinsamlegast hafðu samband við þjónustuaðila.',
+ 'health.vaccinations.directorateOfHealth': 'Embætti landlæknis',
}
diff --git a/apps/native/app/src/screens/finance/components/finance-status-card-container.tsx b/apps/native/app/src/screens/finance/components/finance-status-card-container.tsx
deleted file mode 100644
index 23d40634ab1e..000000000000
--- a/apps/native/app/src/screens/finance/components/finance-status-card-container.tsx
+++ /dev/null
@@ -1,318 +0,0 @@
-import {
- FinanceStatusCard,
- Skeleton,
- Typography,
- blue400,
- dynamicColor,
-} from '@ui'
-import { useState } from 'react'
-import { FormattedMessage, useIntl } from 'react-intl'
-import { Image, Linking, Pressable, View } from 'react-native'
-import styled from 'styled-components/native'
-import chevronDown from '../../../assets/icons/chevron-down.png'
-import {
- ChargeType,
- GetFinanceStatusDetails,
- Organization,
-} from '../../../graphql/types/finance.types'
-import { useGetFinanceStatusDetailsQuery } from '../../../graphql/types/schema'
-import { navigateTo } from '../../../lib/deep-linking'
-import { showPicker } from '../../../lib/show-picker'
-import { LightButton } from './light-button'
-
-const Row = styled.View<{ border?: boolean }>`
- flex-direction: row;
- flex-wrap: wrap;
- margin-left: -8px;
- margin-right: -8px;
-
- border-bottom-color: ${dynamicColor(({ theme }) => ({
- light: theme.color.blue100,
- dark: theme.shades.dark.shade300,
- }))};
- border-bottom-width: ${({ border }) => (border ? 1 : 0)}px;
-`
-
-const Cell = styled.View`
- margin-right: 8px;
- margin-left: 8px;
- margin-top: 4px;
- margin-bottom: 4px;
-`
-
-const TouchableRow = styled.TouchableHighlight`
- flex-direction: row;
- flex-wrap: wrap;
- margin-left: -8px;
- margin-right: -8px;
- padding-top: 8px;
- padding-bottom: 8px;
- border-bottom-color: ${dynamicColor(({ theme }) => ({
- light: theme.color.blue100,
- dark: theme.shades.dark.shade300,
- }))};
- border-bottom-width: 1px;
-`
-
-const AboutBox = styled.View`
- padding: 16px;
- border-top-color: ${dynamicColor(({ theme }) => ({
- light: theme.color.blueberry200,
- dark: theme.shades.dark.shade300,
- }))};
- border-top-width: 1px;
- margin-top: 0px;
-`
-
-export function FinanceStatusCardContainer({
- chargeType,
- org,
-}: {
- chargeType: ChargeType
- org: Organization
-}) {
- const intl = useIntl()
- const [open, setOpen] = useState(false)
- const res = useGetFinanceStatusDetailsQuery({
- variables: {
- input: {
- orgID: org.id,
- chargeTypeID: chargeType.id,
- },
- },
- skip: !open,
- })
- const financeStatusDetails: GetFinanceStatusDetails | undefined =
- res.data?.getFinanceStatusDetails
-
- const chargeItemSubjects = [
- ...new Set(
- (financeStatusDetails?.chargeItemSubjects ?? []).map(
- (i) => i.chargeItemSubject,
- ),
- ),
- ]
- const [selectedChargeItemSubject, setSelectedChargeItemSubject] = useState(0)
-
- return (
-
- }
- value={`${intl.formatNumber(chargeType.totals)} kr.`}
- onPress={() => {
- setOpen((p) => !p)
- }}
- open={open}
- >
-
-
-
-
- {
- showPicker({
- title: intl.formatMessage({
- id: 'finance.statusCard.paymentBase',
- defaultMessage: 'Gjaldgrunnur',
- }),
- items: chargeItemSubjects.map((label, value) => ({
- label,
- value,
- id: String(value),
- })),
- selectedId: String(selectedChargeItemSubject),
- cancel: true,
- }).then((value) => {
- if (value.selectedItem) {
- setSelectedChargeItemSubject(Number(value.selectedItem.id))
- }
- })
- // void
- }}
- />
-
-
-
-
-
- |
-
-
-
-
- |
-
- {res.loading
- ? Array.from({ length: 3 }).map((_, index) => (
-
-
-
- |
-
- ))
- : financeStatusDetails?.chargeItemSubjects?.map((charge, index) => {
- if (
- charge.chargeItemSubject !==
- chargeItemSubjects[selectedChargeItemSubject]
- ) {
- return null
- }
- return (
- {
- navigateTo(
- `/finance/status/${org.id}/${chargeType.id}/${index}`,
- )
- }}
- >
- <>
-
- {charge.finalDueDate}
- |
-
-
- {intl.formatNumber(charge.totals)} kr.
-
- |
-
- >
-
- )
- })}
-
-
-
-
-
- {res.loading ? (
-
- ) : (
-
- {intl.formatNumber(chargeType.totals)} kr.
-
- )}
- |
-
-
-
-
-
-
- {res.loading ? (
- <>
-
-
- >
- ) : (
- {org.name}
- )}
-
- {org.homepage ? (
-
-
-
- :
-
-
- Linking.openURL(
- `https://${org.email.replace(/https?:\/\//, '')}`,
- )
- }
- >
-
- {org.homepage}
-
-
- |
- ) : null}
- {org.email ? (
-
-
-
- :
-
- Linking.openURL(`mailto:${org.email}`)}>
-
- {org.email}
-
-
- |
- ) : null}
- {org.phone ? (
-
-
-
- :
-
- Linking.openURL(`tel:${org.phone}`)}>
-
- {org.phone}
-
-
- |
- ) : null}
-
-
-
- )
-}
diff --git a/apps/native/app/src/screens/finance/components/finance-status-card.tsx b/apps/native/app/src/screens/finance/components/finance-status-card.tsx
new file mode 100644
index 000000000000..e8f884674ca8
--- /dev/null
+++ b/apps/native/app/src/screens/finance/components/finance-status-card.tsx
@@ -0,0 +1,380 @@
+import {
+ Skeleton,
+ Typography,
+ blue400,
+ dynamicColor,
+ ExpandableCard,
+} from '@ui'
+import { useState } from 'react'
+import { FormattedMessage, useIntl } from 'react-intl'
+import { Image, Linking, Pressable, View } from 'react-native'
+import styled, { useTheme } from 'styled-components/native'
+import chevronDown from '../../../assets/icons/chevron-down.png'
+import {
+ ChargeType,
+ GetFinanceStatusDetails,
+ Organization,
+} from '../../../graphql/types/finance.types'
+import { useGetFinanceStatusDetailsQuery } from '../../../graphql/types/schema'
+import { navigateTo } from '../../../lib/deep-linking'
+import { showPicker } from '../../../lib/show-picker'
+import { SelectButton } from './select-button'
+import { useBrowser } from '../../../lib/use-browser'
+
+const Row = styled.View<{ border?: boolean }>`
+ flex-direction: row;
+ flex-wrap: wrap;
+ border-bottom-color: ${dynamicColor(({ theme }) => ({
+ light: theme.color.blue100,
+ dark: theme.shades.dark.shade300,
+ }))};
+ border-bottom-width: ${({ border }) => (border ? 1 : 0)}px;
+`
+
+const Cell = styled.View`
+ margin-right: ${({ theme }) => theme.spacing[1]}px;
+ margin-left: ${({ theme }) => theme.spacing[1]}px;
+ margin-top: ${({ theme }) => theme.spacing.smallGutter}px;
+ margin-bottom: ${({ theme }) => theme.spacing.smallGutter}px;
+`
+
+const AboutItem = styled.View`
+ margin-top: ${({ theme }) => theme.spacing[2]}px;
+ min-width: 50%;
+ flex: 1;
+`
+
+const TouchableRow = styled.TouchableHighlight`
+ flex-direction: row;
+ flex-wrap: wrap;
+ padding-top: ${({ theme }) => theme.spacing[2]}px;
+ padding-bottom: ${({ theme }) => theme.spacing[2]}px;
+ border-bottom-color: ${dynamicColor(({ theme }) => ({
+ light: theme.color.blue200,
+ dark: theme.shades.dark.shade300,
+ }))};
+ border-bottom-width: 1px;
+`
+
+const AboutBox = styled.View`
+ padding: ${({ theme }) => theme.spacing[2]}px;
+ margin-top: 0px;
+`
+
+const RowItem = styled.View`
+ margin-right: ${({ theme }) => theme.spacing[1]}px;
+ margin-left: ${({ theme }) => theme.spacing[1]}px;
+ flex: 1;
+`
+
+const TableHeading = styled.View`
+ flex-direction: row;
+ flex: 1;
+ margin-top: ${({ theme }) => theme.spacing[1]}px;
+ padding-bottom: ${({ theme }) => theme.spacing[1]}px;
+ border-bottom-color: ${dynamicColor(({ theme }) => ({
+ light: theme.color.blue200,
+ dark: theme.shades.dark.shade300,
+ }))};
+ border-bottom-width: 1px;
+`
+
+const Total = styled(Typography)`
+ margin-top: ${({ theme }) => theme.spacing[1]}px;
+ margin-bottom: ${({ theme }) => theme.spacing.smallGutter}px;
+`
+
+export function FinanceStatusCard({
+ chargeType,
+ org,
+ componentId,
+}: {
+ chargeType: ChargeType
+ org: Organization
+ componentId: string
+}) {
+ const intl = useIntl()
+ const theme = useTheme()
+ const [open, setOpen] = useState(false)
+ const { openBrowser } = useBrowser()
+ const res = useGetFinanceStatusDetailsQuery({
+ variables: {
+ input: {
+ orgID: org.id,
+ chargeTypeID: chargeType.id,
+ },
+ },
+ skip: !open,
+ })
+ const financeStatusDetails: GetFinanceStatusDetails | undefined =
+ res.data?.getFinanceStatusDetails
+
+ const chargeItemSubjects = [
+ ...new Set(
+ (financeStatusDetails?.chargeItemSubjects ?? []).map(
+ (i) => i.chargeItemSubject,
+ ),
+ ),
+ ]
+ const [selectedChargeItemSubject, setSelectedChargeItemSubject] = useState(0)
+
+ const shouldShowAboutOrgBox =
+ org.homepage || org.email || org.phone || org.name
+
+ return (
+
+ }
+ value={`${intl.formatNumber(chargeType.totals)} kr.`}
+ onPress={() => {
+ setOpen((p) => !p)
+ }}
+ open={open}
+ >
+
+
+
+
+ {
+ showPicker({
+ title: intl.formatMessage({
+ id: 'finance.statusCard.paymentBase',
+ defaultMessage: 'Gjaldgrunnur',
+ }),
+ items: chargeItemSubjects.map((label, value) => ({
+ label,
+ value,
+ id: String(value),
+ })),
+ selectedId: String(selectedChargeItemSubject),
+ cancel: true,
+ }).then((value) => {
+ if (value.selectedItem) {
+ setSelectedChargeItemSubject(Number(value.selectedItem.id))
+ }
+ })
+ // void
+ }}
+ />
+
+
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+ {res.loading
+ ? Array.from({ length: 3 }).map((_, index) => (
+
+
+
+ |
+
+ ))
+ : financeStatusDetails?.chargeItemSubjects?.map((charge, index) => {
+ if (
+ charge.chargeItemSubject !==
+ chargeItemSubjects[selectedChargeItemSubject]
+ ) {
+ return null
+ }
+ return (
+ {
+ navigateTo(
+ `/finance/status/${org.id}/${chargeType.id}/${index}`,
+ )
+ }}
+ >
+ <>
+
+
+ {charge.finalDueDate}
+
+
+
+
+ {intl.formatNumber(charge.totals)} kr.
+
+
+
+ >
+
+ )
+ })}
+
+
+
+
+
+ {res.loading ? (
+
+ ) : (
+
+ {intl.formatNumber(chargeType.totals)} kr.
+
+ )}
+ |
+
+
+ {shouldShowAboutOrgBox && !res.loading && (
+
+
+
+
+ {res.loading ? (
+ <>
+
+
+ >
+ ) : (
+
+ {org.name}
+
+ )}
+
+ {org.homepage ? (
+
+
+
+ :
+
+
+ openBrowser(
+ `https://${org.email.replace(/https?:\/\//, '')}`,
+ componentId,
+ )
+ }
+ >
+
+ {org.homepage}
+
+
+
+ ) : null}
+ {org.email ? (
+
+
+
+ :
+
+ Linking.openURL(`mailto:${org.email}`)}
+ style={{ flexWrap: 'nowrap' }}
+ >
+
+ {org.email}
+
+
+
+ ) : null}
+ {org.phone ? (
+
+
+
+ :
+
+ Linking.openURL(`tel:${org.phone}`)}
+ style={{ flexWrap: 'nowrap' }}
+ >
+
+ {org.phone}
+
+
+
+ ) : null}
+
+
+ )}
+
+ )
+}
diff --git a/apps/native/app/src/screens/finance/components/light-button.tsx b/apps/native/app/src/screens/finance/components/select-button.tsx
similarity index 89%
rename from apps/native/app/src/screens/finance/components/light-button.tsx
rename to apps/native/app/src/screens/finance/components/select-button.tsx
index 9ae9d9a40545..c24ad5d71366 100644
--- a/apps/native/app/src/screens/finance/components/light-button.tsx
+++ b/apps/native/app/src/screens/finance/components/select-button.tsx
@@ -1,8 +1,8 @@
import { DynamicColorIOS, Platform } from 'react-native'
import { useTheme } from 'styled-components/native'
-import { Button, blue400 } from '../../../ui'
+import { Button, ButtonProps, blue400 } from '../../../ui'
-export const LightButton = (props: any) => {
+export const SelectButton = (props: ButtonProps) => {
const theme = useTheme()
return (