@@ -22,13 +22,23 @@ import { withCart } from '@/hocs/withCart'
2222import { LoadingAndErrorComponent } from '@helpwave/common/components/LoadingAndErrorComponent'
2323import { useRouter } from 'next/router'
2424import { Modal } from '@helpwave/common/components/modals/Modal'
25- import { useState } from 'react'
25+ import { useEffect , useState } from 'react'
2626import { Input } from '@helpwave/common/components/user-input/Input'
2727import { VoucherAPI } from '@/api/services/voucher'
2828import type { Voucher } from '@/api/dataclasses/voucher'
2929import { Chip } from '@helpwave/common/components/ChipList'
3030import { useCustomerProductsCalculateQuery } from '@/api/mutations/customer_product_mutations'
3131import { defaultLocaleFormatters } from '@/utils/locale'
32+ import { ProductAPI } from '@/api/services/product'
33+ import { LoadingAnimation } from '@helpwave/common/components/LoadingAnimation'
34+
35+ type ReferralStatus = 'loading' | 'error'
36+ type ReferralData = {
37+ product : string ,
38+ plan : string ,
39+ voucher ?: string ,
40+ }
41+
3242
3343type CartOverviewTranslation = {
3444 removeFromCart : string ,
@@ -45,6 +55,8 @@ type CartOverviewTranslation = {
4555 redeemVoucherFor : ( name : string ) => string ,
4656 code : string ,
4757 invalidCode : string ,
58+ referral : string ,
59+ referralError : string ,
4860} & ProductPlanTranslation
4961
5062const defaultCartOverviewTranslations : Record < Languages , CartOverviewTranslation > = {
@@ -64,6 +76,8 @@ const defaultCartOverviewTranslations: Record<Languages, CartOverviewTranslation
6476 redeemVoucherFor : ( name : string ) => `Redeem Voucher for ${ name } ` ,
6577 code : 'Code' ,
6678 invalidCode : 'The provided Code is not valid (for this product), please try a different one.' ,
79+ referral : 'Referral' ,
80+ referralError : 'The Referral could not be processed.' ,
6781 } ,
6882 de : {
6983 ...defaultProductPlanTranslation . de ,
@@ -81,32 +95,104 @@ const defaultCartOverviewTranslations: Record<Languages, CartOverviewTranslation
8195 redeemVoucherFor : ( name : string ) => `Gutschein einlösen für ${ name } ` ,
8296 code : 'Code' ,
8397 invalidCode : 'Der eingegebenen Gutschein-Code ist nicht gültig (für dieses Produkt), versuchen Sie einen anderen.' ,
98+ referral : 'Überweisung' , // TODO fix translation
99+ referralError : 'Die Überweisung hat nicht funktioniert.' ,
84100 }
85101}
86102
87103
88104const CartOverview : NextPage = ( ) => {
89105 const translation = useTranslation ( defaultCartOverviewTranslations )
90106 const router = useRouter ( )
107+ const [ hasUsedReferral , setHasUsedReferral ] = useState < boolean > ( false )
91108 const { authHeader } = useAuth ( )
92- const { cart, removeItem, updateItem } = useCart ( )
109+ const [ referralStatus , setReferralStatus ] = useState < ReferralStatus > ( )
110+ const { cart, removeItem, updateItem, addItem, isLoading : cartIsLoading } = useCart ( )
93111 const [ productVoucherModalId , setProductVoucherModalId ] = useState < string > ( )
94112 const [ voucherCode , setVoucherCode ] = useState < string > ( '' )
95113 const [ redeemResponse , setRedeemResponse ] = useState < string > ( )
96114 const { data : products , isError : productsError , isLoading : productsLoading } = useProductsAllQuery ( )
97- const { data : prices , isError : pricesError , isLoading : pricesLoading } = useCustomerProductsCalculateQuery ( cart . map ( item => ( {
115+ const {
116+ data : prices ,
117+ isError : pricesError ,
118+ isLoading : pricesLoading ,
119+ isRefetching,
120+ refetch,
121+ } = useCustomerProductsCalculateQuery ( cart . map ( item => ( {
98122 productUuid : item . id ,
99123 productPlanUuid : item . plan . uuid ,
100124 voucherUuid : item . voucher ?. uuid
101125 } ) ) )
102126
103127 const localeTranslation = useTranslation ( defaultLocaleFormatters )
128+ useEffect ( ( ) => {
129+ refetch ( ) . catch ( console . error )
130+ } , [ cart ] )
131+
132+ useEffect ( ( ) => {
133+ if ( ! router . isReady || cartIsLoading || hasUsedReferral ) return
134+
135+ const referralParam = router . query [ 'referral' ]
136+
137+ if ( ! referralParam || typeof referralParam !== 'string' ) return
138+
139+ try {
140+ const decoded = atob ( referralParam )
141+ const parsed : ReferralData = JSON . parse ( decoded )
142+
143+ const check = async ( ) => {
144+ const products = await ProductAPI . getAvailable ( authHeader )
145+ const product = products . find ( value => value . uuid === parsed . product )
146+ const plan = product ?. plan . find ( value => value . uuid === parsed . plan )
147+
148+ // TODO try to parse voucher
149+
150+ if ( ! product || ! plan ) {
151+ setReferralStatus ( 'error' )
152+ setHasUsedReferral ( true )
153+ return
154+ }
155+
156+ if ( cart . find ( value => value . id === product ?. uuid ) ) {
157+ // TODO maybe show an additional dialog here
158+ updateItem ( { id : product ?. uuid , plan : plan , quantity : 1 } )
159+ } else {
160+ addItem ( { id : product ?. uuid , plan : plan , quantity : 1 } )
161+ }
162+ }
163+
164+ check ( ) . catch ( ( reason ) => {
165+ console . error ( reason )
166+ setReferralStatus ( 'error' )
167+ setHasUsedReferral ( true )
168+ } ) . then ( ( ) => {
169+ setReferralStatus ( undefined )
170+ setHasUsedReferral ( true )
171+ } )
172+ } catch ( err ) {
173+ console . error ( err )
174+ setReferralStatus ( 'error' )
175+ setHasUsedReferral ( true )
176+ }
177+ } , [ router , cart ] )
104178
105179 const isError = pricesError || productsError
106- const isLoading = pricesLoading || productsLoading || Object . keys ( prices ?. products ?? { } ) . length === 0
180+ const isLoading = pricesLoading || productsLoading || isRefetching
107181
108182 return (
109183 < Page pageTitle = { titleWrapper ( translation . overview ) } >
184+ < Modal
185+ id = "referral-modal"
186+ isOpen = { ! ! referralStatus }
187+ onBackgroundClick = { referralStatus === 'error' ? ( ) => setReferralStatus ( undefined ) : undefined }
188+ onCloseClick = { referralStatus === 'error' ? ( ) => setReferralStatus ( undefined ) : undefined }
189+ titleText = { translation . referral }
190+ modalClassName = { tw ( 'gap-y-2' ) }
191+ >
192+ { referralStatus === 'error' ? (
193+ < span className = { tw ( 'text-hw-negative-500' ) } > { translation . referralError } </ span >
194+ ) : ( < LoadingAnimation /> ) }
195+ </ Modal >
110196 < Modal
111197 id = "voucher-modal"
112198 isOpen = { ! ! productVoucherModalId }
0 commit comments