{
10 | domain(message: string): this
11 | }
12 | }
13 |
14 | export {}
15 |
--------------------------------------------------------------------------------
/src/hooks/auth/useIsAuthenticated.ts:
--------------------------------------------------------------------------------
1 | import { useReactiveVar } from '@apollo/client'
2 |
3 | import { authTokenVar, customerPortalTokenVar } from '~/core/apolloClient'
4 |
5 | type useIsAuthenticatedReturn = () => {
6 | isAuthenticated: boolean
7 | isPortalAuthenticated: boolean
8 | token?: string
9 | }
10 |
11 | export const useIsAuthenticated: useIsAuthenticatedReturn = () => {
12 | const token = useReactiveVar(authTokenVar)
13 | const portalToken = useReactiveVar(customerPortalTokenVar)
14 |
15 | return {
16 | isAuthenticated: !!token,
17 | isPortalAuthenticated: !!portalToken,
18 | token,
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/hooks/core/useInternationalization.ts:
--------------------------------------------------------------------------------
1 | import { useCallback } from 'react'
2 |
3 | import { updateIntlLocale, useInternationalizationVar } from '~/core/apolloClient'
4 | import { envGlobalVar } from '~/core/apolloClient'
5 | import { Locale, TranslateData, translateKey } from '~/core/translations'
6 |
7 | const { appEnv } = envGlobalVar()
8 |
9 | export type TranslateFunc = (key: string, data?: TranslateData, plural?: number) => string
10 |
11 | type UseInternationalization = () => {
12 | locale: Locale
13 | translate: TranslateFunc
14 | updateLocale: (locale: Locale) => void
15 | }
16 |
17 | export const useInternationalization: UseInternationalization = () => {
18 | const { translations, locale } = useInternationalizationVar()
19 |
20 | return {
21 | locale,
22 | translate: useCallback(
23 | (key, data, plural = 0) => {
24 | return translateKey({ translations, locale, appEnv }, key, data, plural)
25 | },
26 | [translations, locale],
27 | ),
28 | updateLocale: updateIntlLocale,
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/hooks/useSalesForceConfig.ts:
--------------------------------------------------------------------------------
1 | import { useSearchParams } from 'react-router-dom'
2 |
3 | type TEventData = {
4 | action: string
5 | rel: string
6 | [key: string]: string
7 | }
8 |
9 | type TUseSalesForceConfigReturn = {
10 | isRunningInSalesForceIframe: boolean
11 | emitSalesForceEvent: (data: TEventData) => void
12 | }
13 |
14 | export const useSalesForceConfig = (): TUseSalesForceConfigReturn => {
15 | const [searchParams] = useSearchParams()
16 |
17 | const isRunningInSalesForceIframe = !!searchParams.get('sfdc')
18 |
19 | const emitSalesForceEvent = (data: TEventData) => {
20 | window.parent.postMessage(JSON.stringify(data), '*')
21 | }
22 |
23 | return { isRunningInSalesForceIframe, emitSalesForceEvent }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main.css:
--------------------------------------------------------------------------------
1 | /* Import the design system styles */
2 | @import 'lago-design-system/style';
3 |
4 | /* Useful for components that are styled with tailwind in the app */
5 | @tailwind base;
6 | @tailwind components;
7 | @tailwind utilities;
8 |
9 | a {
10 | @apply text-blue no-underline visited:text-purple hover:underline focus:rounded focus:ring;
11 | }
12 |
--------------------------------------------------------------------------------
/src/pages/CustomerRequestOverduePayment/validateEmails.ts:
--------------------------------------------------------------------------------
1 | import { string } from 'yup'
2 |
3 | export const validateEmails = (emails: string): boolean => {
4 | const emailArray = emails.split(',').map((email) => email.trim())
5 |
6 | for (const email of emailArray) {
7 | if (!string().email().isValidSync(email)) {
8 | return false
9 | }
10 | }
11 | return true
12 | }
13 |
14 | export const serializeEmails = (emails: string): string => {
15 | return emails.replaceAll(' ', '')
16 | }
17 |
--------------------------------------------------------------------------------
/src/pages/Error404.tsx:
--------------------------------------------------------------------------------
1 | import { GenericPlaceholder } from '~/components/GenericPlaceholder'
2 | import { HOME_ROUTE } from '~/core/router'
3 | import { useInternationalization } from '~/hooks/core/useInternationalization'
4 | import { useLocationHistory } from '~/hooks/core/useLocationHistory'
5 | import ErrorImage from '~/public/images/maneki/error.svg'
6 |
7 | const Error404 = () => {
8 | const { translate } = useInternationalization()
9 | const { goBack } = useLocationHistory()
10 |
11 | return (
12 |
13 | }
15 | title={translate('text_62bac37900192b773560e82d')}
16 | subtitle={translate('text_62bac37900192b773560e82f')}
17 | buttonTitle={translate('text_62bac37900192b773560e831')}
18 | buttonAction={() => goBack(HOME_ROUTE, { previousCount: -2 })}
19 | />
20 |
21 | )
22 | }
23 |
24 | export default Error404
25 |
--------------------------------------------------------------------------------
/src/pages/Forbidden.tsx:
--------------------------------------------------------------------------------
1 | import { GenericPlaceholder } from '~/components/GenericPlaceholder'
2 | import { HOME_ROUTE } from '~/core/router'
3 | import { useInternationalization } from '~/hooks/core/useInternationalization'
4 | import { useLocationHistory } from '~/hooks/core/useLocationHistory'
5 | import ErrorImage from '~/public/images/maneki/error.svg'
6 |
7 | const Forbidden = () => {
8 | const { translate } = useInternationalization()
9 | const { goBack } = useLocationHistory()
10 |
11 | return (
12 |
13 | }
15 | title={translate('text_66474faf77c70900619567c7')}
16 | subtitle={translate('text_66474fb55f1b6901c7ac7683')}
17 | buttonTitle={translate('text_62bac37900192b773560e831')}
18 | buttonAction={() => goBack(HOME_ROUTE, { previousCount: -2 })}
19 | />
20 |
21 | )
22 | }
23 |
24 | export default Forbidden
25 |
--------------------------------------------------------------------------------
/src/pages/InvitationInit.tsx:
--------------------------------------------------------------------------------
1 | import { useApolloClient } from '@apollo/client'
2 | import { useEffect } from 'react'
3 | import { generatePath, Outlet, useNavigate, useParams } from 'react-router-dom'
4 |
5 | import { logOut } from '~/core/apolloClient'
6 | import { INVITATION_ROUTE_FORM } from '~/core/router'
7 | import { useIsAuthenticated } from '~/hooks/auth/useIsAuthenticated'
8 |
9 | const InvitationInit = () => {
10 | const { token } = useParams()
11 | const { isAuthenticated } = useIsAuthenticated()
12 | const navigate = useNavigate()
13 | const client = useApolloClient()
14 |
15 | useEffect(() => {
16 | const triggerLogout = async () => {
17 | await logOut(client, true)
18 | }
19 |
20 | triggerLogout()
21 |
22 | // We first logout the user and then redirect to the invitation form
23 | !isAuthenticated && navigate(generatePath(INVITATION_ROUTE_FORM, { token: token as string }))
24 | // eslint-disable-next-line react-hooks/exhaustive-deps
25 | }, [isAuthenticated])
26 |
27 | return
28 | }
29 |
30 | export default InvitationInit
31 |
--------------------------------------------------------------------------------
/src/pages/analytics/Usage.tsx:
--------------------------------------------------------------------------------
1 | import { useRef } from 'react'
2 |
3 | import UsageBreakdownSection from '~/components/analytics/usage/UsageBreakdownSection'
4 | import UsageOverviewSection from '~/components/analytics/usage/UsageOverviewSection'
5 | import { FullscreenPage } from '~/components/layouts/FullscreenPage'
6 | import { PremiumWarningDialog, PremiumWarningDialogRef } from '~/components/PremiumWarningDialog'
7 |
8 | const Usage = () => {
9 | const premiumWarningDialogRef = useRef(null)
10 |
11 | return (
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | )
20 | }
21 |
22 | export default Usage
23 |
--------------------------------------------------------------------------------
/src/pages/wallet/index.ts:
--------------------------------------------------------------------------------
1 | export { default as CreateWallet } from './CreateWallet'
2 | export { type TWalletDataForm } from './types'
3 |
--------------------------------------------------------------------------------
/src/pages/wallet/types.ts:
--------------------------------------------------------------------------------
1 | import { CreateCustomerWalletInput, UpdateCustomerWalletInput } from '~/generated/graphql'
2 |
3 | export type TWalletDataForm = Omit &
4 | Omit
5 |
--------------------------------------------------------------------------------
/src/public/icons/alphabet.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/apps.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/arrow-bottom.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/public/icons/arrow-down-circle-filled.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/arrow-indent.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/src/public/icons/arrow-left-right.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/arrow-left.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/public/icons/arrow-right.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/public/icons/arrow-top.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/public/icons/arrow-up-circle-filled.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/bell.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/bulb.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/burger.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/src/public/icons/chart-bar.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/src/public/icons/checkmark.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/chevron-down-filled.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/src/public/icons/chevron-down.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/public/icons/chevron-left.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/public/icons/chevron-right-filled.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/src/public/icons/chevron-right.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/public/icons/chevron-top.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/public/icons/clock.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/close-circle-filled.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/public/icons/close.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/public/icons/coin-dollar.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/src/public/icons/collect.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/company.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/condition.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/src/public/icons/content-left-align.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/document.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/duplicate.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/public/icons/error-filled.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/src/public/icons/error-unfilled.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/filter.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/flash-filled.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/flash.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/handle.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/heart.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/src/public/icons/id.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/src/public/icons/info-circle.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/key.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/keyboard-enter.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/laptop.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/src/public/icons/link.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/lock.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/micro.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/minus.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/public/icons/partially-filled.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/src/public/icons/pause-circle-filled.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/pen.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/play.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/plus.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/public/icons/processing.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/public/icons/pulse.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/src/public/icons/push.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/receipt.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/src/public/icons/schema.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/share.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/sparkles.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/src/public/icons/stop.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/public/icons/switch-off.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/switch.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/table-horizontale.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/table.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/target.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/text.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/trash.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/public/icons/validate-filled.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/validate-unfilled.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/icons/wallet.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/images/adyen.svg:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/src/public/images/airbyte.svg:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/src/public/images/anrok.svg:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/src/public/images/avalara.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/images/cashfree.svg:
--------------------------------------------------------------------------------
1 |
15 |
--------------------------------------------------------------------------------
/src/public/images/gocardless-large.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/images/gocardless.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/public/images/hightouch.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/src/public/images/moneyhash.svg:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/src/public/images/stripe.svg:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/src/styles/customer.tsx:
--------------------------------------------------------------------------------
1 | import { FC, PropsWithChildren } from 'react'
2 |
3 | import { Typography, TypographyProps } from '~/components/designSystem'
4 |
5 | import { tw } from './utils'
6 |
7 | export const SectionHeader: FC<
8 | PropsWithChildren<{ hideBottomShadow?: boolean } & TypographyProps>
9 | > = ({ children, hideBottomShadow, className, ...props }) => (
10 |
20 | {children}
21 |
22 | )
23 |
--------------------------------------------------------------------------------
/src/styles/designSystem/DrawerContent.tsx:
--------------------------------------------------------------------------------
1 | import { FC, PropsWithChildren } from 'react'
2 |
3 | import { tw } from '../utils'
4 |
5 | export const DrawerContent: FC> = ({
6 | children,
7 | className,
8 | }) => {children}
9 |
10 | export const DrawerTitle: FC = ({ children }) => (
11 | {children}
12 | )
13 |
14 | export const DrawerSubmitButton: FC = ({ children }) => (
15 | {children}
16 | )
17 |
--------------------------------------------------------------------------------
/src/styles/designSystem/MenuPopper.tsx:
--------------------------------------------------------------------------------
1 | import { FC, PropsWithChildren } from 'react'
2 |
3 | import { tw } from '~/styles/utils'
4 |
5 | export const MenuPopper: FC> = ({
6 | className,
7 | children,
8 | }) => {children}
9 |
--------------------------------------------------------------------------------
/src/styles/designSystem/index.ts:
--------------------------------------------------------------------------------
1 | export * from './DrawerContent'
2 | export * from './List'
3 | export * from './MenuPopper'
4 | export * from './PageHeader'
5 |
--------------------------------------------------------------------------------
/src/styles/index.ts:
--------------------------------------------------------------------------------
1 | export * from './muiTheme'
2 | export * from './colorsPalette'
3 | export * from './designSystem'
4 |
--------------------------------------------------------------------------------
/src/styles/utils.ts:
--------------------------------------------------------------------------------
1 | import { cx, CxOptions } from 'class-variance-authority'
2 | import { twMerge } from 'tailwind-merge'
3 |
4 | export const tw = (...inputs: CxOptions) => {
5 | return twMerge(cx(inputs))
6 | }
7 |
--------------------------------------------------------------------------------
/start.dev.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | pnpm install
4 | pnpm run dev
5 |
--------------------------------------------------------------------------------
/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import sharedConfig from 'lago-configs/tailwind'
2 | import { Config } from 'prettier'
3 |
4 | const config: Pick = {
5 | content: ['src/**/*.{js,ts,jsx,tsx}'],
6 | presets: [sharedConfig],
7 | }
8 |
9 | export default config
10 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": ["**/*.tsx", "**/*.ts", "**/*.d.ts"],
3 | "compilerOptions": {
4 | "outDir": "./dist",
5 | "baseUrl": "src",
6 | "paths": {
7 | "~/*": ["*"],
8 | "@mui/styled-engine": ["./node_modules/@mui/styled-engine-sc"]
9 | },
10 | },
11 | "exclude": ["node_modules", "cypress", "packages"],
12 | "extends": "lago-configs/tsconfig",
13 | }
--------------------------------------------------------------------------------
/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
--------------------------------------------------------------------------------