Skip to content

Commit

Permalink
Merged PR 32003: Stadspas ui verbeteringen
Browse files Browse the repository at this point in the history
- Na uitloggen blijft de knop om pas te laten zien op het home scherm staan (of komt dat om dat het uitloggen toch niet helemaal goed ging?) - gefixt
- Het scherm van Tegoed betalingen kan weer scrollen
- Passen tonen vanaf pashouder toont goede pas in pas swiper
- foutmeldingen op detailscherm staan op de goede plek
- pas-tonen knop kijkt zelf of die getoond moet worden en bepaalt aantal passen voor label
- componenten in mappen gezet voor beter overzicht

To do:
- Eerst bolletje wit maken wanneer eerste pas wordt getoond. Gaat wel goed wanneer start index anders dan 0 is.

Related work items: #124490
  • Loading branch information
frankfe-amsterdam committed Sep 3, 2024
2 parents 224ca0d + dafde78 commit c06d43e
Show file tree
Hide file tree
Showing 27 changed files with 253 additions and 149 deletions.
5 changes: 4 additions & 1 deletion src/hooks/secureStorage/useGetSecureItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ export const useGetSecureItem = (key: SecureItemKey) => {
setItem(secureItem)
setLoading(false)
})
.catch(() => setLoading(false))
.catch(() => {
setItem(null)
setLoading(false)
})
}, [key, secureItemUpdatedTimestamp])

return {item, isLoading}
Expand Down
55 changes: 29 additions & 26 deletions src/modules/city-pass/components/Budget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import {skipToken} from '@reduxjs/toolkit/query'
import {Box} from '@/components/ui/containers/Box'
import {PleaseWait} from '@/components/ui/feedback/PleaseWait'
import {Column} from '@/components/ui/layout/Column'
import {ScrollView} from '@/components/ui/layout/ScrollView'
import {Paragraph} from '@/components/ui/text/Paragraph'
import {Title} from '@/components/ui/text/Title'
import {useSetScreenTitle} from '@/hooks/navigation/useSetScreenTitle'
import {useGetSecureItem} from '@/hooks/secureStorage/useGetSecureItem'
import {BudgetTransactions} from '@/modules/city-pass/components/BudgetTransactions'
import {CityPassFullScreenError} from '@/modules/city-pass/components/CityPassFullScreenError'
import {CityPassFullScreenError} from '@/modules/city-pass/components/error/CityPassFullScreenError'
import {BudgetTransactions} from '@/modules/city-pass/components/transactions/BudgetTransactions'
import {useGetCityPassesQuery} from '@/modules/city-pass/service'
import {CityPass, CityPassBudget} from '@/modules/city-pass/types'
import {SecureItemKey} from '@/utils/secureStorage'
Expand Down Expand Up @@ -61,31 +62,33 @@ export const Budget = ({budgetCode, passNumber}: Props) => {
const {budgetBalanceFormatted, budgetAssignedFormatted, title} = budget ?? {}

return (
<Box>
<Column gutter="lg">
<Column
gutter="md"
halign="center">
<Title
testID="CityPassBalanceTitleLabel"
text={title}
textAlign="center"
/>
<Title
testID="CityPassBalanceTitleValue"
text={budgetBalanceFormatted}
/>
<Column halign="center">
<Paragraph>{`Was in het begin ${budgetAssignedFormatted}.`}</Paragraph>
<Paragraph>{`Geldig tot en met ${dateEndFormatted}.`}</Paragraph>
<ScrollView>
<Box>
<Column gutter="lg">
<Column
gutter="md"
halign="center">
<Title
testID="CityPassBalanceTitleLabel"
text={title}
textAlign="center"
/>
<Title
testID="CityPassBalanceTitleValue"
text={budgetBalanceFormatted}
/>
<Column halign="center">
<Paragraph>{`Was in het begin ${budgetAssignedFormatted}.`}</Paragraph>
<Paragraph>{`Geldig tot en met ${dateEndFormatted}.`}</Paragraph>
</Column>
</Column>
<BudgetTransactions
budgetCode={budgetCode}
dateEnd={dateEnd}
passNumber={passNumber}
/>
</Column>
<BudgetTransactions
budgetCode={budgetCode}
dateEnd={dateEnd}
passNumber={passNumber}
/>
</Column>
</Box>
</Box>
</ScrollView>
)
}
18 changes: 14 additions & 4 deletions src/modules/city-pass/components/PassOwners.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import {Title} from '@/components/ui/text/Title'
import {useOpenRedirect} from '@/hooks/linking/useOpenRedirect'
import {useNavigation} from '@/hooks/navigation/useNavigation'
import {useGetSecureItem} from '@/hooks/secureStorage/useGetSecureItem'
import {CityPassCard} from '@/modules/city-pass/components/CityPassCard'
import {ShowCityPassButton} from '@/modules/city-pass/components/ShowCityPassButton'
import {CityPassCard} from '@/modules/city-pass/components/card-display/CityPassCard'
import {SOMETHING_WENT_WRONG_TEXT} from '@/modules/city-pass/constants'
import {useSetSecureCityPasses} from '@/modules/city-pass/hooks/useSetSecureCityPasses'
import {CityPassRouteName} from '@/modules/city-pass/routes'
Expand Down Expand Up @@ -39,7 +39,17 @@ export const PassOwners = ({logout}: Props) => {
useSetSecureCityPasses(cityPasses)

if (isLoading) {
return <PleaseWait testID="CityPassDashboardPleaseWait" />
return (
<Box
insetBottom="xl"
insetHorizontal="md"
insetTop="md">
<Column gutter="md">
<PleaseWait testID="CityPassDashboardPleaseWait" />
<ShowCityPassButton />
</Column>
</Box>
)
}

if (isError || !cityPasses) {
Expand All @@ -60,7 +70,7 @@ export const PassOwners = ({logout}: Props) => {
insetTop="md">
{cityPasses.length ? (
<Column gutter="md">
<ShowCityPassButton passCount={cityPasses.length} />
<ShowCityPassButton />
<Gutter height="sm" />
{cityPasses.map(cityPass => {
const {id} = cityPass
Expand All @@ -71,7 +81,7 @@ export const PassOwners = ({logout}: Props) => {
key={id}
onPress={() =>
navigate(CityPassRouteName.cityPassDetails, {
cityPass,
passNumber: cityPass.passNumber,
})
}
testID={`CityPassOwnerButton-${id}`}
Expand Down
14 changes: 8 additions & 6 deletions src/modules/city-pass/components/ShowCityPassButton.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
import simplur from 'simplur'
import {Button} from '@/components/ui/buttons/Button'
import {useDispatch} from '@/hooks/redux/useDispatch'
import {useGetSecureCityPasses} from '@/modules/city-pass/hooks/useGetSecureCityPasses'
import {showCityPasses} from '@/modules/city-pass/slice'

type Props = {
passCount: number
index?: number
}

export const ShowCityPassButton = ({passCount}: Props) => {
export const ShowCityPassButton = ({index}: Props) => {
const dispatch = useDispatch()
const cityPasses = useGetSecureCityPasses()

return (
return cityPasses.length ? (
<Button
iconName="city-pass-pass"
label={simplur`Laat mijn [pas|passen] zien${[passCount]}`}
label={simplur`Laat mijn [pas|passen] zien${[cityPasses.length]}`}
onPress={() => {
dispatch(showCityPasses())
dispatch(showCityPasses(index))
}}
testID="CityPassLogoutButton"
/>
)
) : null
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {Paragraph} from '@/components/ui/text/Paragraph'
import {Phrase} from '@/components/ui/text/Phrase'
import {useAccessibilityAutoFocus} from '@/hooks/accessibility/useAccessibilityAutoFocus'
import Logo from '@/modules/city-pass/assets/logo.svg'
import {BarCode} from '@/modules/city-pass/components/BarCode'
import {BarCode} from '@/modules/city-pass/components/card-display/BarCode'
import {CITY_PASS_HEIGHT} from '@/modules/city-pass/constants'
import {CityPassPass} from '@/modules/city-pass/types'
import {getPassWidth} from '@/modules/city-pass/utils/getPassWidth'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {useDispatch} from '@/hooks/redux/useDispatch'
import {useSelector} from '@/hooks/redux/useSelector'
import {useBlockScreenshots} from '@/hooks/useBlockScreenshots'
import {useBrightScreen} from '@/hooks/useBrightScreen'
import {CityPassesSwiper} from '@/modules/city-pass/components/CityPassesSwiper'
import {CityPassesSwiper} from '@/modules/city-pass/components/card-display/CityPassesSwiper'
import {DEFAULT_PASS_WIDTH} from '@/modules/city-pass/constants'
import {
hideCityPasses,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import {StyleSheet, useWindowDimensions, View} from 'react-native'
import {useSharedValue} from 'react-native-reanimated'
import Carousel, {ICarouselInstance} from 'react-native-reanimated-carousel'
import type {CityPassPass} from '@/modules/city-pass/types'
import {CityPass} from '@/modules/city-pass/components/CityPass'
import {useSelector} from '@/hooks/redux/useSelector'
import {CityPass} from '@/modules/city-pass/components/card-display/CityPass'
import {Basic} from '@/modules/city-pass/components/pagination/PaginationBasic'
import {CITY_PASS_HEIGHT} from '@/modules/city-pass/constants'
import {NEXT_CARD_VISIBLE_FRACTION_Of_AVAILABLE_SPACE} from '@/modules/city-pass/constants'
import {useGetSecureCityPasses} from '@/modules/city-pass/hooks/useGetSecureCityPasses'
import {selectStartIndex} from '@/modules/city-pass/slice'
import {getParallaxScrollingOffset} from '@/modules/city-pass/utils/getParallaxScrollingOffset'
import {getPassWidth} from '@/modules/city-pass/utils/getPassWidth'
import {Theme} from '@/themes/themes'
Expand All @@ -27,6 +29,7 @@ export const CityPassesSwiper = () => {
const {width: windowWidth} = useWindowDimensions()
const ref = useRef<ICarouselInstance>(null)
const [currentIndex, setCurrentIndex] = useState<number>(initialPage)
const startIndex = useSelector(selectStartIndex)

const progress = useSharedValue<number>(initialPage)

Expand All @@ -47,6 +50,7 @@ export const CityPassesSwiper = () => {
<View style={styles.container}>
<Carousel
data={cityPasses}
defaultIndex={startIndex}
loop={false}
mode="parallax"
modeConfig={{
Expand Down Expand Up @@ -121,5 +125,4 @@ const createStyles = ({color, size}: Theme) =>
paginationItemActive: {
backgroundColor: color.pagination.item.active,
},
paginationItemInactive: {},
})
79 changes: 79 additions & 0 deletions src/modules/city-pass/components/details/CityPassDetails.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import {skipToken} from '@reduxjs/toolkit/query'
import {Box} from '@/components/ui/containers/Box'
import {PleaseWait} from '@/components/ui/feedback/PleaseWait'
import {SomethingWentWrong} from '@/components/ui/feedback/SomethingWentWrong'
import {Column} from '@/components/ui/layout/Column'
import {useGetSecureItem} from '@/hooks/secureStorage/useGetSecureItem'
import {BudgetBalanceButton} from '@/modules/city-pass/components/BudgetBalanceButton'
import {ShowCityPassButton} from '@/modules/city-pass/components/ShowCityPassButton'
import {CityPassDetailsInfo} from '@/modules/city-pass/components/details/CityPassDetailsInfo'
import {CityPassDetailsName} from '@/modules/city-pass/components/details/CityPassDetailsName'
import {DiscountTransactions} from '@/modules/city-pass/components/transactions/DiscountTransactions'
import {SOMETHING_WENT_WRONG_TEXT} from '@/modules/city-pass/constants'
import {useGetCityPassesQuery} from '@/modules/city-pass/service'
import {CityPass} from '@/modules/city-pass/types'
import {SecureItemKey} from '@/utils/secureStorage'

type Props = {
passNumber: CityPass['passNumber']
}

export const CityPassDetails = ({passNumber}: Props) => {
const {item: secureAccessToken} = useGetSecureItem(
SecureItemKey.cityPassAccessToken,
)

const {
data: cityPasses,
isLoading,
isError,
} = useGetCityPassesQuery(secureAccessToken ? secureAccessToken : skipToken)
const cityPass = cityPasses?.find(cp => cp.passNumber === passNumber)
const cityPassIndex = cityPasses?.findIndex(
cp => cp.passNumber === passNumber,
)

if (isLoading) {
return (
<Box grow>
<Column gutter="md">
<PleaseWait testID="CityPassDashboardPleaseWait" />
<ShowCityPassButton index={cityPassIndex} />
</Column>
</Box>
)
}

return (
<Box grow>
<Column gutter="lg">
{!!cityPass && <CityPassDetailsName cityPass={cityPass} />}
<ShowCityPassButton index={cityPassIndex} />
{!cityPass || isError ? (
<SomethingWentWrong
testID="CityPassDetailsSomethingWentWrong"
text={SOMETHING_WENT_WRONG_TEXT}
title=""
/>
) : (
<Column gutter="xl">
<Column gutter="lg">
<CityPassDetailsInfo cityPass={cityPass} />
{cityPass.budgets?.map(budget => (
<BudgetBalanceButton
budget={budget}
key={budget.code}
passNumber={passNumber}
/>
))}
</Column>
<DiscountTransactions
dateEnd={cityPass.dateEnd}
passNumber={passNumber}
/>
</Column>
)}
</Column>
</Box>
)
}
60 changes: 60 additions & 0 deletions src/modules/city-pass/components/details/CityPassDetailsInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import {HideFromAccessibility} from '@/components/features/accessibility/HideFromAccessibility'
import {Button} from '@/components/ui/buttons/Button'
import {SingleSelectable} from '@/components/ui/containers/SingleSelectable'
import {Column} from '@/components/ui/layout/Column'
import {Row} from '@/components/ui/layout/Row'
import {Phrase} from '@/components/ui/text/Phrase'
import {useNavigation} from '@/hooks/navigation/useNavigation'
import {CityPassDetailsPassNumber} from '@/modules/city-pass/components/details/CityPassDetailsPassNumber'
import {CityPassRouteName} from '@/modules/city-pass/routes'
import {CityPass} from '@/modules/city-pass/types'

type Props = {
cityPass: CityPass
}

export const CityPassDetailsInfo = ({cityPass}: Props) => {
const {navigate} = useNavigation()
const {dateEndFormatted, id, passNumberComplete, securityCode} = cityPass

return (
<Column gutter="md">
<CityPassDetailsPassNumber passNumberComplete={passNumberComplete} />
{!!securityCode && (
<Row
align="between"
gutter="md"
valign="center">
<HideFromAccessibility>
<Phrase testID="CityPassCityPassDetailsSecurityCodeLabel">
Beveiligingscode
</Phrase>
</HideFromAccessibility>
<Button
accessibilityLabel="Toon beveiligingscode"
label="Toon"
onPress={() => {
navigate(CityPassRouteName.securityCode, {id})
}}
testID="CityPassCityPassDetailsSecurityCodeButton"
variant="secondary"
/>
</Row>
)}
<SingleSelectable testID="CityPassCityPassDetailsExpiryDate">
<Row
align="between"
gutter="md">
<Phrase testID="CityPassCityPassDetailsExpiryDateLabel">
Geldig tot en met
</Phrase>
<Phrase
emphasis="strong"
testID="CityPassCityPassDetailsExpiryDateValue">
{dateEndFormatted}
</Phrase>
</Row>
</SingleSelectable>
</Column>
)
}
31 changes: 31 additions & 0 deletions src/modules/city-pass/components/details/CityPassDetailsName.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {SingleSelectable} from '@/components/ui/containers/SingleSelectable'
import {Column} from '@/components/ui/layout/Column'
import {Phrase} from '@/components/ui/text/Phrase'
import {Title} from '@/components/ui/text/Title'
import {CityPass} from '@/modules/city-pass/types'

type Props = {
cityPass: CityPass
}

export const CityPassDetailsName = ({cityPass}: Props) => {
const {firstname, infix, lastname} = cityPass.owner

return (
<Column halign="center">
<SingleSelectable testID="CityPassCityPassDetailsName">
<Title
testID="CityPassCityPassDetailsTitle"
text={firstname}
textAlign="center"
/>
<Phrase
emphasis="strong"
testID="CityPassCityPassDetailsSubtitle"
textAlign="center">
{`${infix ? infix + ' ' : ''}${lastname}`}
</Phrase>
</SingleSelectable>
</Column>
)
}
Loading

0 comments on commit c06d43e

Please sign in to comment.