feat: add app config from server
This commit is contained in:
parent
d27091ae67
commit
a24343a18e
@ -5,6 +5,7 @@ import {
|
||||
Element,
|
||||
Elements,
|
||||
AuthTokens,
|
||||
Apps,
|
||||
Assets,
|
||||
AssetCategories,
|
||||
DailyForecasts,
|
||||
@ -17,6 +18,7 @@ import {
|
||||
|
||||
const api = {
|
||||
auth: createMethod<AuthTokens.Payload, AuthTokens.Response>(AuthTokens.createRequest),
|
||||
getAppConfig: createMethod<Apps.Payload, Apps.Response>(Apps.createRequest),
|
||||
getElement: createMethod<Element.Payload, Element.Response>(Element.createRequest),
|
||||
getElements: createMethod<Elements.Payload, Elements.Response>(Elements.createRequest),
|
||||
getUser: createMethod<User.GetPayload, User.Response>(User.createGetRequest),
|
||||
|
||||
63
src/api/resources/Apps.ts
Normal file
63
src/api/resources/Apps.ts
Normal file
@ -0,0 +1,63 @@
|
||||
import routes from '../../routes'
|
||||
import { getBaseHeaders } from '../utils'
|
||||
|
||||
export interface Payload {
|
||||
bundleId: 'com.life.aura' | 'com.life.gusebamps' | 'auraweb'
|
||||
}
|
||||
|
||||
export interface Response {
|
||||
data: {
|
||||
subscription_popup: boolean
|
||||
locale: string
|
||||
alerts: Alert
|
||||
active_iaps: ActiveIAps[]
|
||||
version: string
|
||||
apple_music_api: AppleMusicApi
|
||||
chargebee: ChargebeeConfig
|
||||
first_open_subscription_popup: boolean
|
||||
runs_before_subscription_popup: number
|
||||
appirater_alerts: AppiraterAlertAppiraterAlert[]
|
||||
}
|
||||
}
|
||||
|
||||
export interface ActiveIAps {
|
||||
bundle_id: string
|
||||
active: boolean
|
||||
subscription_type: 'trial' | 'monthly' | 'yearly'
|
||||
}
|
||||
|
||||
export interface AppiraterAlertAppiraterAlert {
|
||||
id: string
|
||||
type: string
|
||||
body: string
|
||||
label: string
|
||||
cancel: string
|
||||
title: string
|
||||
uses_until_prompt: string
|
||||
days_until_prompt: string
|
||||
time_before_reminding: string
|
||||
significant_events_until_prompt: string
|
||||
show: boolean
|
||||
apple_id: string
|
||||
appirater_link: string
|
||||
appirater_pro_link: string
|
||||
}
|
||||
|
||||
export interface Alert {
|
||||
description: string
|
||||
}
|
||||
|
||||
export interface AppleMusicApi {
|
||||
jwt: string
|
||||
}
|
||||
|
||||
export interface ChargebeeConfig {
|
||||
site: string
|
||||
publishableKey: string
|
||||
gatewayAccountId: string
|
||||
}
|
||||
|
||||
export const createRequest = ({ bundleId }: Payload): Request => {
|
||||
const url = new URL(routes.server.apps(bundleId))
|
||||
return new Request(url, { method: 'GET', headers: getBaseHeaders() })
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
export * as Assets from './Assets'
|
||||
export * as AssetCategories from './AssetCategories'
|
||||
export * as Apps from './Apps'
|
||||
export * as User from './User'
|
||||
export * as DailyForecasts from './UserDailyForecasts'
|
||||
export * as Auras from './Auras'
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useCallback, useEffect, useId } from 'react'
|
||||
import { useCallback, useEffect } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { PaymentIntent } from '@chargebee/chargebee-js-types'
|
||||
import { useApi, useApiCall, extractErrorMessage, SubscriptionReceipts } from '../../../../api'
|
||||
@ -17,7 +17,7 @@ interface ApplePayButtonProps {
|
||||
|
||||
export function ApplePayButton({ onSuccess, onError }: ApplePayButtonProps): JSX.Element {
|
||||
const api = useApi()
|
||||
const buttonId = useId()
|
||||
const buttonId = 'apple-pay-btn'
|
||||
const { i18n } = useTranslation()
|
||||
const { token } = useAuth()
|
||||
const { applePay } = usePayment()
|
||||
@ -49,7 +49,7 @@ export function ApplePayButton({ onSuccess, onError }: ApplePayButtonProps): JSX
|
||||
}, [data, applePay, buttonId, i18n.language, api, token, onSuccess, onError])
|
||||
|
||||
return isPending ? <Loader /> : (
|
||||
<div id={buttonId} style={{ height: 60 }}>{
|
||||
<div id={buttonId} className='pay-btn'>{
|
||||
error ? <ErrorText message={extractErrorMessage(error)} isShown={true} size='large'/> : null
|
||||
}</div>
|
||||
)
|
||||
|
||||
@ -77,7 +77,7 @@ export function CardModal({ open, onClose, onSuccess, onError }: CardModalProps)
|
||||
setStatus('subscribing')
|
||||
cardRef.current?.tokenize({})
|
||||
.then((result: ChargebeeTokenizeResult) => {
|
||||
return api.createSubscriptionReceipt({ token, itemPriceId, gwToken: result.token })
|
||||
return api.createSubscriptionReceipt({ token, itemPriceId, gwToken: result.vaultToken })
|
||||
})
|
||||
.then(({ subscription_receipt }: SubscriptionReceipts.Response) => {
|
||||
setStatus('success')
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useCallback, useEffect, useId } from 'react'
|
||||
import { useCallback, useEffect } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { PaymentIntent } from '@chargebee/chargebee-js-types'
|
||||
import { SubscriptionReceipts, extractErrorMessage, useApi, useApiCall } from '../../../../api'
|
||||
@ -17,7 +17,7 @@ interface GooglePayButtonProps {
|
||||
|
||||
export function GooglePayButton({ onSuccess, onError }: GooglePayButtonProps): JSX.Element {
|
||||
const api = useApi()
|
||||
const buttonId = useId()
|
||||
const buttonId = 'google-pay-btn'
|
||||
const { i18n } = useTranslation()
|
||||
const { token } = useAuth()
|
||||
const { googlePay } = usePayment()
|
||||
@ -49,7 +49,7 @@ export function GooglePayButton({ onSuccess, onError }: GooglePayButtonProps): J
|
||||
}, [data, googlePay, buttonId, i18n.language, onSuccess, onError])
|
||||
|
||||
return isPending ? <Loader /> : (
|
||||
<div id={buttonId} style={{ height: 60 }}>{
|
||||
<div id={buttonId} className='pay-btn'>{
|
||||
error ? <ErrorText message={extractErrorMessage(error)} isShown={true} size='large'/> : null
|
||||
}</div>
|
||||
)
|
||||
|
||||
@ -98,4 +98,16 @@
|
||||
padding-left: 12px;
|
||||
line-height: 1.5;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.pay-btn {
|
||||
min-height: 60px;
|
||||
max-width: 400px;
|
||||
min-width: 250px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.pay-btn .gpay-button {
|
||||
min-height: 60px;
|
||||
border-radius: 20px;
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
const config = {
|
||||
chargebee: {
|
||||
site: 'kefirapp-test',
|
||||
publishableKey: 'test_VtWSamZEfP175nqGZhkD0uvoouHieElv',
|
||||
},
|
||||
}
|
||||
|
||||
export default config
|
||||
13
src/init.tsx
13
src/init.tsx
@ -10,15 +10,18 @@ import { ApiContext, createApi } from './api'
|
||||
import { LegalContext, buildLegal } from './legal'
|
||||
import { PaymentContext } from './payment'
|
||||
import { getClientLocale, buildResources, fallbackLng } from './locales'
|
||||
import type { AppConfig } from './types'
|
||||
import App from './components/App'
|
||||
|
||||
const init = async (config: AppConfig) => {
|
||||
const init = async () => {
|
||||
const api = createApi()
|
||||
const lng = getClientLocale()
|
||||
const response = await api.getElements({ locale: lng })
|
||||
const resources = buildResources(response)
|
||||
const legal = buildLegal(response)
|
||||
const [elementsResponse, configResponse] = await Promise.all([
|
||||
api.getElements({ locale: lng }),
|
||||
api.getAppConfig({ bundleId: 'auraweb' }),
|
||||
])
|
||||
const resources = buildResources(elementsResponse)
|
||||
const legal = buildLegal(elementsResponse)
|
||||
const config = configResponse.data
|
||||
const i18nextInstance = i18next.createInstance()
|
||||
const options = { lng, resources, fallbackLng, postProcess: [ `reactPostprocessor` ] }
|
||||
await i18nextInstance.use(initReactI18next).use(new ReactPostprocessor()).init(options)
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import ReactDOM from 'react-dom/client'
|
||||
import config from './config'
|
||||
import init from './init'
|
||||
import 'react-circular-progressbar/dist/styles.css'
|
||||
import './fonts.css'
|
||||
@ -18,7 +17,7 @@ const getRootElement = (id: string): HTMLElement => {
|
||||
}
|
||||
|
||||
const startApp = async () => {
|
||||
const vdom = await init(config)
|
||||
const vdom = await init()
|
||||
const rootElement = getRootElement('root')
|
||||
|
||||
ReactDOM.createRoot(rootElement).render(vdom)
|
||||
|
||||
@ -22,6 +22,7 @@ const routes = {
|
||||
token: () => [apiHost, prefix, 'auth', 'token.json'].join('/'),
|
||||
elements: () => [apiHost, prefix, 'elements.json'].join('/'),
|
||||
element: (type: string) => [apiHost, prefix, 'elements', `${type}.json`].join('/'),
|
||||
apps: (bundleId: string) => [apiHost, prefix, 'apps', `${bundleId}.json`].join('/'),
|
||||
assets: (category: string) => [apiHost, prefix, 'assets', 'categories', `${category}.json`].join('/'),
|
||||
assetCategories: () => [apiHost, prefix, 'assets', 'categories.json'].join('/'),
|
||||
dailyForecasts: () => [apiHost, prefix, 'user', 'daily_forecast.json'].join('/'),
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import { Chargebee } from '@chargebee/chargebee-js-types'
|
||||
import config from './config'
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
@ -22,5 +21,4 @@ export interface SignupForm {
|
||||
birthtime: string
|
||||
}
|
||||
|
||||
export type AppConfig = typeof config
|
||||
export type UserStatus = 'lead' | 'registred' | 'subscribed' | 'unsubscribed'
|
||||
|
||||
Loading…
Reference in New Issue
Block a user