Skip to content

feat: Remove watermarks #2017

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Feb 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions src/components/customerPortal/common/CustomerPortalSections.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,35 @@ import PortalCustomerInfos from '~/components/customerPortal/PortalCustomerInfos
import PortalInvoicesList from '~/components/customerPortal/PortalInvoicesList'
import UsageSection from '~/components/customerPortal/usage/UsageSection'
import WalletSection from '~/components/customerPortal/wallet/WalletSection'
import { PremiumIntegrationTypeEnum, useGetPortalOrgaInfosQuery } from '~/generated/graphql'
import Logo from '~/public/images/logo/lago-logo-grey.svg'

const CustomerPortalSections = () => {
const { translate } = useCustomerPortalTranslate()

const { data: portalOrgaInfosData } = useGetPortalOrgaInfosQuery()

const { viewWallet, viewSubscription, viewEditInformation } = useCustomerPortalNavigation()

const showPoweredBy =
!portalOrgaInfosData?.customerPortalOrganization?.premiumIntegrations?.includes(
PremiumIntegrationTypeEnum.RemoveBrandingWatermark,
)

return (
<div className="flex flex-col gap-12">
<WalletSection viewWallet={viewWallet} />
<UsageSection viewSubscription={viewSubscription} />
<PortalCustomerInfos viewEditInformation={viewEditInformation} />
<PortalInvoicesList />

<div className="my-8 flex justify-center gap-2 md:hidden">
<div className="text-sm text-grey-600">{translate('text_6419c64eace749372fc72b03')}</div>
{showPoweredBy && (
<div className="my-8 flex justify-center gap-2 md:hidden">
<div className="text-sm text-grey-600">{translate('text_6419c64eace749372fc72b03')}</div>

<Logo width="40px" />
</div>
<Logo width="40px" />
</div>
)}
</div>
)
}
Expand Down
16 changes: 10 additions & 6 deletions src/components/customerPortal/common/CustomerPortalSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ type CustomerPortalSidebarProps = {
organizationLogoUrl?: string | null
isLoading?: boolean
isError?: ApolloError
showPoweredBy?: boolean
}

const CustomerPortalSidebar = ({
organizationName,
organizationLogoUrl,
isLoading,
showPoweredBy,
}: CustomerPortalSidebarProps) => {
const { translate } = useCustomerPortalTranslate()

Expand Down Expand Up @@ -50,13 +52,15 @@ const CustomerPortalSidebar = ({
</Typography>
)}

<div className="flex items-center gap-1">
<Typography className="text-xs font-normal text-grey-600">
{translate('text_6419c64eace749372fc72b03')}
</Typography>
{showPoweredBy && (
<div className="flex items-center gap-1">
<Typography className="text-xs font-normal text-grey-600">
{translate('text_6419c64eace749372fc72b03')}
</Typography>

<Logo width="40px" />
</div>
<Logo width="40px" />
</div>
)}
</div>

<div className="mb-4 flex w-full items-center justify-center bg-grey-100 px-5 py-8 md:hidden">
Expand Down
34 changes: 22 additions & 12 deletions src/components/settings/PreviewEmailLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import { FC, PropsWithChildren, useRef } from 'react'

import { Avatar, Button, Skeleton, Tooltip, Typography } from '~/components/designSystem'
import { LocaleEnum } from '~/core/translations'
import { PremiumIntegrationTypeEnum } from '~/generated/graphql'
import { useContextualLocale } from '~/hooks/core/useContextualLocale'
import { useInternationalization } from '~/hooks/core/useInternationalization'
import { useEmailConfig } from '~/hooks/useEmailConfig'
import { useOrganizationInfos } from '~/hooks/useOrganizationInfos'
import Logo from '~/public/images/logo/lago-logo-grey.svg'

import {
Expand Down Expand Up @@ -35,6 +37,12 @@ export const PreviewEmailLayout: FC<PreviewEmailLayoutProps> = ({

const { logoUrl, name } = useEmailConfig()

const { hasOrganizationPremiumAddon } = useOrganizationInfos()

const showPoweredBy = !hasOrganizationPremiumAddon(
PremiumIntegrationTypeEnum.RemoveBrandingWatermark,
)

return (
<>
<div>
Expand Down Expand Up @@ -109,18 +117,20 @@ export const PreviewEmailLayout: FC<PreviewEmailLayoutProps> = ({
{children}
</section>

<div className="mb-20 flex items-center justify-center [&>svg]:mx-1">
{isLoading ? (
<Skeleton color="dark" variant="text" className="w-55" />
) : (
<>
<Typography variant="note" color="grey500">
{translateWithContextualLocal('text_64188b3d9735d5007d712278')}
</Typography>
<Logo height="12px" />
</>
)}
</div>
{showPoweredBy && (
<div className="mb-20 flex items-center justify-center [&>svg]:mx-1">
{isLoading ? (
<Skeleton color="dark" variant="text" className="w-55" />
) : (
<>
<Typography variant="note" color="grey500">
{translateWithContextualLocal('text_64188b3d9735d5007d712278')}
</Typography>
<Logo height="12px" />
</>
)}
</div>
)}
</div>
</div>
<UpdateOrganizationLogoDialog ref={updateLogoDialogRef} />
Expand Down
23 changes: 17 additions & 6 deletions src/components/settings/invoices/PreviewCustomSectionDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import { forwardRef, useImperativeHandle, useRef, useState } from 'react'
import { Button, Drawer, DrawerRef, Typography } from '~/components/designSystem'
import {
CreateInvoiceCustomSectionInput,
PremiumIntegrationTypeEnum,
useGetOrganizationCustomFooterForInvoiceLazyQuery,
} from '~/generated/graphql'
import { useInternationalization } from '~/hooks/core/useInternationalization'
import { useOrganizationInfos } from '~/hooks/useOrganizationInfos'
import Logo from '~/public/images/logo/lago-logo-grey.svg'

gql`
Expand Down Expand Up @@ -57,6 +59,12 @@ export const PreviewCustomSectionDrawer = forwardRef<PreviewCustomSectionDrawerR

const hasLocalData = localData?.displayName || localData?.details

const { hasOrganizationPremiumAddon } = useOrganizationInfos()

const showPoweredBy = !hasOrganizationPremiumAddon(
PremiumIntegrationTypeEnum.RemoveBrandingWatermark,
)

return (
<Drawer
ref={drawerRef}
Expand Down Expand Up @@ -94,12 +102,15 @@ export const PreviewCustomSectionDrawer = forwardRef<PreviewCustomSectionDrawerR
<Typography variant="caption" className="py-6">
{localData?.invoiceFooter}
</Typography>
<div className="ml-auto flex flex-row items-center gap-1">
<Typography className="font-email text-xs font-normal" color="grey500">
{translate('text_6419c64eace749372fc72b03')}
</Typography>
<Logo height="12px" />
</div>

{showPoweredBy && (
<div className="ml-auto flex flex-row items-center gap-1">
<Typography className="font-email text-xs font-normal" color="grey500">
{translate('text_6419c64eace749372fc72b03')}
</Typography>
<Logo height="12px" />
</div>
)}
</div>
</div>
</Drawer>
Expand Down
5 changes: 5 additions & 0 deletions src/generated/graphql.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2181,6 +2181,7 @@ export type DataExportCreditNoteFiltersInput = {
reason?: InputMaybe<Array<CreditNoteReasonEnum>>;
refundStatus?: InputMaybe<Array<CreditNoteRefundStatusEnum>>;
searchTerm?: InputMaybe<Scalars['String']['input']>;
selfBilled?: InputMaybe<Scalars['Boolean']['input']>;
};

export enum DataExportFormatTypeEnum {
Expand All @@ -2200,6 +2201,7 @@ export type DataExportInvoiceFiltersInput = {
paymentOverdue?: InputMaybe<Scalars['Boolean']['input']>;
paymentStatus?: InputMaybe<Array<InvoicePaymentStatusTypeEnum>>;
searchTerm?: InputMaybe<Scalars['String']['input']>;
selfBilled?: InputMaybe<Scalars['Boolean']['input']>;
status?: InputMaybe<Array<InvoiceStatusTypeEnum>>;
};

Expand Down Expand Up @@ -2899,6 +2901,7 @@ export enum IntegrationTypeEnum {
Netsuite = 'netsuite',
Okta = 'okta',
ProgressiveBilling = 'progressive_billing',
RemoveBrandingWatermark = 'remove_branding_watermark',
RevenueAnalytics = 'revenue_analytics',
RevenueShare = 'revenue_share',
Salesforce = 'salesforce',
Expand Down Expand Up @@ -3099,6 +3102,7 @@ export enum InvoiceStatusTypeEnum {

export type InvoiceSubscription = {
__typename?: 'InvoiceSubscription';
acceptNewChargeFees: Scalars['Boolean']['output'];
chargeAmountCents: Scalars['BigInt']['output'];
chargesFromDatetime?: Maybe<Scalars['ISO8601DateTime']['output']>;
chargesToDatetime?: Maybe<Scalars['ISO8601DateTime']['output']>;
Expand Down Expand Up @@ -4468,6 +4472,7 @@ export enum PremiumIntegrationTypeEnum {
Netsuite = 'netsuite',
Okta = 'okta',
ProgressiveBilling = 'progressive_billing',
RemoveBrandingWatermark = 'remove_branding_watermark',
RevenueAnalytics = 'revenue_analytics',
RevenueShare = 'revenue_share',
Salesforce = 'salesforce',
Expand Down
6 changes: 6 additions & 0 deletions src/hooks/useOrganizationInfos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { formatDateToTZ, TimezoneConfigObject, TimeZonesConfig } from '~/core/ti
import {
MainOrganizationInfosFragment,
OrganizationForDatePickerFragmentDoc,
PremiumIntegrationTypeEnum,
TimezoneEnum,
useGetOrganizationInfosQuery,
} from '~/generated/graphql'
Expand Down Expand Up @@ -35,6 +36,7 @@ type UseOrganizationInfos = () => {
timezone: TimezoneEnum
timezoneConfig: TimezoneConfigObject
formatTimeOrgaTZ: (date: string, format?: string) => string
hasOrganizationPremiumAddon: (integration: PremiumIntegrationTypeEnum) => boolean
}

export const useOrganizationInfos: UseOrganizationInfos = () => {
Expand All @@ -47,12 +49,16 @@ export const useOrganizationInfos: UseOrganizationInfos = () => {
const orgaTimezone = data?.organization?.timezone || TimezoneEnum.TzUtc
const timezoneConfig = TimeZonesConfig[orgaTimezone]

const premiumIntegrations = data?.organization?.premiumIntegrations

return {
loading,
organization: data?.organization || undefined,
timezone: orgaTimezone || TimezoneEnum.TzUtc,
timezoneConfig,
formatTimeOrgaTZ: (date, format) =>
formatDateToTZ(date, orgaTimezone, format || 'LLL. dd, yyyy'),
hasOrganizationPremiumAddon: (integration: PremiumIntegrationTypeEnum) =>
!!premiumIntegrations?.includes(integration),
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import {
DunningEmailProps,
DunningEmailSkeleton,
} from '~/components/emails/DunningEmail'
import { PremiumIntegrationTypeEnum } from '~/generated/graphql'
import { useContextualLocale } from '~/hooks/core/useContextualLocale'
import { useOrganizationInfos } from '~/hooks/useOrganizationInfos'
import Logo from '~/public/images/logo/lago-logo-grey.svg'

interface EmailPreviewProps extends DunningEmailProps {
Expand All @@ -24,6 +26,12 @@ export const EmailPreview: FC<EmailPreviewProps> = ({
}) => {
const { translateWithContextualLocal: translate } = useContextualLocale(locale)

const { hasOrganizationPremiumAddon } = useOrganizationInfos()

const showPoweredBy = !hasOrganizationPremiumAddon(
PremiumIntegrationTypeEnum.RemoveBrandingWatermark,
)

if (isLoading) {
return (
<div className="mx-auto flex max-w-150 flex-col items-center gap-8">
Expand Down Expand Up @@ -70,12 +78,15 @@ export const EmailPreview: FC<EmailPreviewProps> = ({
organization={organization}
/>
</Card>
<div className="mx-auto flex flex-row items-center gap-1">
<Typography className="font-email text-xs font-normal" color="grey500">
{translate('text_6419c64eace749372fc72b03')}
</Typography>
<Logo height="12px" />
</div>

{showPoweredBy && (
<div className="mx-auto flex flex-row items-center gap-1">
<Typography className="font-email text-xs font-normal" color="grey500">
{translate('text_6419c64eace749372fc72b03')}
</Typography>
<Logo height="12px" />
</div>
)}
</div>
)
}
8 changes: 7 additions & 1 deletion src/pages/customerPortal/CustomerPortal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
import SectionTitle from '~/components/customerPortal/common/SectionTitle'
import useCustomerPortalTranslate from '~/components/customerPortal/common/useCustomerPortalTranslate'
import { hasDefinedGQLError } from '~/core/apolloClient'
import { useGetPortalOrgaInfosQuery } from '~/generated/graphql'
import { PremiumIntegrationTypeEnum, useGetPortalOrgaInfosQuery } from '~/generated/graphql'
import { tw } from '~/styles/utils'

gql`
Expand Down Expand Up @@ -66,6 +66,11 @@ const CustomerPortal = () => {

const pageContainerClassName = tw(showSidebar && 'max-w-2xl')

const showPoweredBy =
!portalOrgaInfosData?.customerPortalOrganization?.premiumIntegrations?.includes(
PremiumIntegrationTypeEnum.RemoveBrandingWatermark,
)

useEffect(() => {
customerPortalContentRef.current?.scrollTo?.(0, 0)
}, [pathname])
Expand All @@ -77,6 +82,7 @@ const CustomerPortal = () => {
<CustomerPortalSidebar
organizationName={portalOrgaInfosData?.customerPortalOrganization?.name}
organizationLogoUrl={portalOrgaInfosData?.customerPortalOrganization?.logoUrl}
showPoweredBy={showPoweredBy}
isLoading={portalOrgasInfoLoading}
isError={portalOrgasInfoError}
/>
Expand Down
Loading