Compare commits

...
39 changed files with 1712 additions and 133 deletions
File diff suppressed because one or more lines are too long
+344
View File
@@ -0,0 +1,344 @@
'use client'
import type { BasicPlan, BillingInterval } from '@/app/components/billing/type'
import { Avatar } from '@langgenius/dify-ui/avatar'
import { Button } from '@langgenius/dify-ui/button'
import { Checkbox } from '@langgenius/dify-ui/checkbox'
import { cn } from '@langgenius/dify-ui/cn'
import { FieldControl, FieldLabel, FieldRoot } from '@langgenius/dify-ui/field'
import { Form } from '@langgenius/dify-ui/form'
import { RadioControl, RadioGroup, RadioItem } from '@langgenius/dify-ui/radio'
import { toast } from '@langgenius/dify-ui/toast'
import { useId, useState } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import DifyLogo from '@/app/components/base/logo/dify-logo'
import { ALL_PLANS } from '@/app/components/billing/config'
import { Professional, Sandbox, Team } from '@/app/components/billing/pricing/assets'
import { Plan } from '@/app/components/billing/type'
import { useAppContext } from '@/context/app-context'
import { useProviderContext } from '@/context/provider-context'
import { useRouter, useSearchParams } from '@/next/navigation'
import { BillingPermission, hasPermission } from '@/utils/permission'
import { InvoiceRequestGridTexture } from './invoice-request-grid-texture'
const INVOICE_INTERVALS: BillingInterval[] = ['year', 'month']
const INVOICE_ICON_MAP = {
[Plan.sandbox]: <Sandbox />,
[Plan.professional]: <Professional />,
[Plan.team]: <Team />,
}
const isInvoicePlan = (value: string | null): value is BasicPlan => {
return value === Plan.professional || value === Plan.team
}
const normalizePlan = (value: string | null): BasicPlan => {
return isInvoicePlan(value) ? value : Plan.professional
}
const normalizeInterval = (value: string | null): BillingInterval => {
return value === 'year' || value === 'month' ? value : 'month'
}
const getPrice = (plan: BasicPlan, interval: BillingInterval) => {
const monthlyPrice = ALL_PLANS[plan].price
return interval === 'year' ? monthlyPrice * 10 : monthlyPrice
}
type InvoiceRequestFormValues = {
company_name: string
country: string
address_line1: string
address_line2?: string
city: string
state_or_province: string
postal_code: string
invoice_recipient_email: string
}
function InvoiceTermsLink({ href, children }: { href: string, children?: React.ReactNode }) {
return (
<a
href={href}
target="_blank"
rel="noopener noreferrer"
onClick={event => event.stopPropagation()}
className="system-sm-semibold underline underline-offset-2 hover:text-text-primary focus-visible:ring-1 focus-visible:ring-state-accent-solid focus-visible:outline-hidden"
>
{children}
</a>
)
}
export default function InvoiceRequestPage() {
const { t } = useTranslation()
const router = useRouter()
const searchParams = useSearchParams()
const { isCurrentWorkspaceManager, userProfile, workspacePermissionKeys } = useAppContext()
const { plan: currentPlan } = useProviderContext()
const [submittedEmail, setSubmittedEmail] = useState('')
const [billingActionClicked, setBillingActionClicked] = useState(false)
const [logoutActionClicked, setLogoutActionClicked] = useState(false)
const [termsAccepted, setTermsAccepted] = useState(false)
const invoiceTermsCheckboxId = useId()
const invoiceTermsTextId = useId()
const plan = normalizePlan(searchParams.get('plan'))
const interval = normalizeInterval(searchParams.get('cycle'))
const canRequestInvoice = isCurrentWorkspaceManager && hasPermission(workspacePermissionKeys, BillingPermission.Manage)
const isInvoiceFlowLocked = !!currentPlan.invoiceFlow?.locked
const price = getPrice(plan, interval)
const invoiceTermsLabel = t('invoice.form.terms', { ns: 'billing' }).replace(/<[^>]+>/g, '')
const handleBack = () => {
router.back()
}
const handleLogout = () => {
setLogoutActionClicked(true)
}
const updateInterval = (nextInterval: BillingInterval) => {
const params = new URLSearchParams(searchParams.toString())
params.set('plan', plan)
params.set('cycle', nextInterval)
router.replace(`/billing/invoice-request?${params.toString()}`)
}
const handleOpenBillingSettings = () => {
setBillingActionClicked(true)
}
const handleSubmit = (formValues: InvoiceRequestFormValues) => {
if (!canRequestInvoice) {
toast.error(t('invoice.permissionDeniedTooltip', { ns: 'billing' }))
return
}
if (isInvoiceFlowLocked) {
toast.error(t('invoice.lockedTip', { ns: 'billing' }))
return
}
if (!termsAccepted) {
toast.error(t('invoice.form.termsRequired', { ns: 'billing' }))
return
}
setSubmittedEmail(formValues.invoice_recipient_email)
}
if (submittedEmail) {
return (
<div className="min-h-dvh overflow-y-auto bg-background-default p-6">
<div className="mx-auto flex min-h-[calc(100dvh-48px)] w-full items-center justify-center">
<div className="relative flex min-h-[373px] w-full max-w-150 flex-col gap-3 overflow-hidden rounded-[20px] border-[0.5px] border-components-panel-border-subtle bg-background-section p-8">
<InvoiceRequestGridTexture />
<div className="relative flex w-full justify-end pb-2">
<DifyLogo size="large" />
</div>
<div className="relative flex size-13 items-center justify-center rounded-xl border-[0.5px] border-components-panel-border-subtle bg-background-default-lighter text-saas-dify-blue-accessible shadow-lg backdrop-blur-[5px]">
<span className="i-ri-mail-send-fill size-6" aria-hidden="true" />
</div>
<div className="relative flex w-full flex-col gap-1 pt-1 break-words">
<h1 className="title-2xl-semi-bold text-text-primary">{t('invoice.requestReceived.title', { ns: 'billing' })}</h1>
<p className="system-md-regular text-text-secondary">
<Trans
i18nKey="invoice.requestReceived.description"
ns="billing"
values={{ email: submittedEmail }}
components={{
email: <span className="system-md-semibold text-text-secondary" />,
day: <span className="system-md-semibold text-text-secondary" />,
}}
/>
</p>
</div>
<div className="relative flex w-full flex-col gap-2 pt-2 pb-3">
<p className="system-xs-regular text-text-tertiary">
{t('invoice.requestReceived.statusTip', { ns: 'billing' })}
</p>
<p className="system-xs-regular text-text-tertiary">
{t('invoice.requestReceived.renewalTip', { ns: 'billing' })}
</p>
</div>
<Button
size="medium"
variant="primary"
data-local-clicked={billingActionClicked || undefined}
className="relative gap-0.5 self-start border-[0.5px] px-3"
onClick={handleOpenBillingSettings}
>
<span>{t('invoice.requestReceived.goToBilling', { ns: 'billing' })}</span>
<span className="i-ri-arrow-right-line size-4" aria-hidden="true" />
</Button>
</div>
</div>
</div>
)
}
return (
<div className="min-h-dvh bg-background-default">
<div className="grid min-h-dvh grid-cols-1 lg:grid-cols-[minmax(360px,724px)_minmax(560px,1fr)]">
<aside className="flex min-h-dvh justify-center bg-background-section-burn px-6 py-10 lg:justify-end lg:px-10">
<div className="relative flex w-full max-w-80 flex-col">
<button
type="button"
aria-label={t('operation.back', { ns: 'common' })}
className="absolute -top-px -left-13 hidden size-8 items-center justify-center rounded-full border border-divider-subtle bg-background-default text-text-secondary shadow-xs hover:bg-state-base-hover focus-visible:ring-2 focus-visible:ring-state-accent-solid focus-visible:outline-hidden lg:flex"
onClick={handleBack}
>
<span aria-hidden="true" className="i-ri-arrow-left-line size-4" />
</button>
<div className="flex items-start gap-6">
<div className="flex h-9 pt-1">
<DifyLogo size="large" />
</div>
<div className="min-w-0">
<div className="title-xl-semi-bold text-text-primary">{t('invoice.summary.title', { ns: 'billing' })}</div>
<div className="mt-1 system-sm-regular text-text-tertiary">{t('invoice.summary.subtitle', { ns: 'billing' })}</div>
</div>
</div>
<div className="mt-8 rounded-lg border border-effects-highlight bg-background-default-subtle p-6 shadow-xs">
<div className="flex size-10 items-center justify-center [&_svg]:size-10">
{INVOICE_ICON_MAP[plan]}
</div>
<h1 className="mt-5 title-2xl-semi-bold text-text-primary">{t(`plans.${plan}.name`, { ns: 'billing' })}</h1>
<div className="mt-5 flex items-end gap-1.5">
<span className="title-2xl-semi-bold text-text-primary">
$
{price}
</span>
<span className="pb-0.5 system-sm-regular text-text-tertiary">
{t('plansCommon.priceTip', { ns: 'billing' })}
{t(`plansCommon.${interval}`, { ns: 'billing' })}
</span>
</div>
<RadioGroup<BillingInterval>
className="mt-5 flex-col items-stretch gap-2"
value={interval}
onValueChange={(nextInterval) => {
if (nextInterval)
updateInterval(nextInterval)
}}
aria-label={t('invoice.summary.billingCycle', { ns: 'billing' })}
>
{INVOICE_INTERVALS.map(item => (
<RadioItem<BillingInterval>
key={item}
value={item}
className="flex h-9 cursor-pointer items-center justify-between rounded-lg border border-components-option-card-option-border bg-components-option-card-option-bg px-2 text-text-secondary outline-hidden hover:bg-state-base-hover focus-visible:ring-2 focus-visible:ring-state-accent-solid data-checked:border-state-accent-solid data-checked:text-text-primary"
>
<span className="flex h-7 items-center gap-2 px-1">
<RadioControl aria-hidden="true" />
<span className="system-sm-medium">{t(`invoice.summary.${item}`, { ns: 'billing' })}</span>
</span>
{item === 'year' && (
<span className="rounded border border-state-accent-solid px-1 system-2xs-semibold-uppercase text-text-accent">
{t('invoice.summary.saveAnnual', { ns: 'billing', percent: 17 })}
</span>
)}
</RadioItem>
))}
</RadioGroup>
</div>
<div className="mt-auto hidden border-t border-divider-subtle pt-4 lg:flex">
<div className="flex min-w-0 flex-1 items-center gap-3">
<Avatar avatar={userProfile.avatar_url} name={userProfile.name} />
<div className="min-w-0">
<div className="truncate system-sm-medium text-text-primary">{userProfile.name}</div>
<div className="truncate system-xs-regular text-text-tertiary">{userProfile.email}</div>
</div>
</div>
<button
type="button"
disabled={logoutActionClicked}
className={cn(
'system-sm-regular text-text-secondary hover:text-text-primary focus-visible:ring-2 focus-visible:ring-state-accent-solid focus-visible:outline-hidden',
logoutActionClicked && 'cursor-not-allowed text-text-disabled hover:text-text-disabled',
)}
onClick={handleLogout}
>
{t('userProfile.logout', { ns: 'common' })}
</button>
</div>
</div>
</aside>
<main className="bg-background-default px-6 py-10 lg:px-10">
<div className="w-full max-w-120">
<div className="mb-6">
<h2 className="title-xl-semi-bold text-text-primary">{t('invoice.form.title', { ns: 'billing' })}</h2>
<p className="mt-1 system-sm-regular text-text-tertiary">{t('invoice.form.description', { ns: 'billing' })}</p>
</div>
<Form<InvoiceRequestFormValues> className="grid gap-6" onFormSubmit={handleSubmit}>
<FieldRoot name="company_name">
<FieldLabel>{t('invoice.form.companyName', { ns: 'billing' })}</FieldLabel>
<FieldControl required size="large" autoComplete="organization" placeholder={t('invoice.form.placeholder.companyName', { ns: 'billing' })} />
</FieldRoot>
<FieldRoot name="country">
<FieldLabel>{t('invoice.form.country', { ns: 'billing' })}</FieldLabel>
<FieldControl required size="large" autoComplete="country-name" placeholder={t('invoice.form.placeholder.country', { ns: 'billing' })} />
</FieldRoot>
<FieldRoot name="address_line1">
<FieldLabel>{t('invoice.form.addressLine1', { ns: 'billing' })}</FieldLabel>
<FieldControl required size="large" autoComplete="address-line1" placeholder={t('invoice.form.placeholder.addressLine1', { ns: 'billing' })} />
</FieldRoot>
<FieldRoot name="address_line2">
<FieldLabel>{t('invoice.form.addressLine2', { ns: 'billing' })}</FieldLabel>
<FieldControl size="large" autoComplete="address-line2" placeholder={t('invoice.form.placeholder.addressLine2', { ns: 'billing' })} />
</FieldRoot>
<div className="grid grid-cols-1 gap-4 md:grid-cols-3">
<FieldRoot name="city">
<FieldLabel>{t('invoice.form.city', { ns: 'billing' })}</FieldLabel>
<FieldControl required size="large" autoComplete="address-level2" placeholder={t('invoice.form.placeholder.city', { ns: 'billing' })} />
</FieldRoot>
<FieldRoot name="state_or_province">
<FieldLabel>{t('invoice.form.stateOrProvince', { ns: 'billing' })}</FieldLabel>
<FieldControl required size="large" autoComplete="address-level1" placeholder={t('invoice.form.placeholder.stateOrProvince', { ns: 'billing' })} />
</FieldRoot>
<FieldRoot name="postal_code">
<FieldLabel>{t('invoice.form.postalCode', { ns: 'billing' })}</FieldLabel>
<FieldControl required size="large" autoComplete="postal-code" placeholder={t('invoice.form.placeholder.postalCode', { ns: 'billing' })} />
</FieldRoot>
</div>
<FieldRoot name="invoice_recipient_email">
<FieldLabel>{t('invoice.form.invoiceEmail', { ns: 'billing' })}</FieldLabel>
<FieldControl required size="large" type="email" autoComplete="email" placeholder={t('invoice.form.placeholder.invoiceEmail', { ns: 'billing' })} />
</FieldRoot>
<label htmlFor={invoiceTermsCheckboxId} className="flex min-h-22 cursor-pointer items-start gap-2 py-2">
<Checkbox
id={invoiceTermsCheckboxId}
checked={termsAccepted}
onCheckedChange={checked => setTermsAccepted(checked === true)}
aria-label={invoiceTermsLabel}
aria-describedby={invoiceTermsTextId}
/>
<span id={invoiceTermsTextId} className="system-sm-regular text-text-secondary">
<Trans
i18nKey="invoice.form.terms"
ns="billing"
components={{
terms: <InvoiceTermsLink href="https://dify.ai/terms" />,
privacy: <InvoiceTermsLink href="https://dify.ai/privacy" />,
}}
/>
</span>
</label>
<Button
type="submit"
variant="primary"
size="large"
disabled={!termsAccepted}
className="w-full"
>
{t('invoice.form.submit', { ns: 'billing' })}
</Button>
</Form>
</div>
</main>
</div>
</div>
)
}
@@ -0,0 +1,41 @@
import * as React from 'react'
import { CommonLayoutHydrationBoundary } from '@/app/(commonLayout)/hydration-boundary'
import AmplitudeProvider from '@/app/components/base/amplitude'
import { GoogleAnalyticsScripts } from '@/app/components/base/ga'
import Zendesk from '@/app/components/base/zendesk'
import { EducationVerifyActionRecorder } from '@/app/components/education-verify-action-recorder'
import MaintenanceNotice from '@/app/components/header/maintenance-notice'
import { NextRouteStateBridge } from '@/app/components/next-route-state'
import { OAuthRegistrationAnalytics } from '@/app/components/oauth-registration-analytics'
import { AppContextProvider } from '@/context/app-context-provider'
import { EventEmitterContextProvider } from '@/context/event-emitter-provider'
import { ModalContextProvider } from '@/context/modal-context-provider'
import { ProviderContextProvider } from '@/context/provider-context-provider'
export default async function Layout({ children }: { children: React.ReactNode }) {
return (
<React.Fragment>
<GoogleAnalyticsScripts />
<AmplitudeProvider />
<OAuthRegistrationAnalytics />
<EducationVerifyActionRecorder />
<CommonLayoutHydrationBoundary>
<NextRouteStateBridge>
<div className="min-h-full bg-background-default">
<MaintenanceNotice />
<AppContextProvider>
<EventEmitterContextProvider>
<ProviderContextProvider>
<ModalContextProvider>
{children}
</ModalContextProvider>
</ProviderContextProvider>
</EventEmitterContextProvider>
</AppContextProvider>
</div>
</NextRouteStateBridge>
</CommonLayoutHydrationBoundary>
<Zendesk />
</React.Fragment>
)
}
+25
View File
@@ -0,0 +1,25 @@
'use client'
import { useEffect } from 'react'
import InvoiceRequestPage from '@/app/billing/invoice-request-page'
import { FullScreenLoading } from '@/app/components/full-screen-loading'
import { useProviderContext } from '@/context/provider-context'
import { useRouter } from '@/next/navigation'
export default function BillingInvoiceRequest() {
const router = useRouter()
const { enableBilling, isFetchedPlanInfo } = useProviderContext()
useEffect(() => {
if (!isFetchedPlanInfo)
return
if (!enableBilling)
router.replace('/')
}, [enableBilling, isFetchedPlanInfo, router])
if (!isFetchedPlanInfo || !enableBilling)
return <FullScreenLoading />
return <InvoiceRequestPage />
}
@@ -63,33 +63,42 @@ describe('Billing', () => {
refetchMock.mockResolvedValue({ data: 'https://billing' })
})
it('keeps the plan card and billing row in one content column', () => {
const { container } = render(<Billing />)
expect(container.firstElementChild)!.toHaveClass('flex', 'flex-col', 'gap-3', 'pt-4')
expect(screen.getByTestId('plan-component'))!.toHaveAttribute('data-loc', 'billing-page')
expect(screen.getByText('billing.viewBillingTitle')).toBeInTheDocument()
expect(screen.getByRole('button', { name: /billing\.viewBillingAction/ }))!.not.toHaveClass('mt-3')
})
it('hides the billing action when subscription management permission is granted without manager role', () => {
isManager = false
render(<Billing />)
expect(screen.queryByRole('button', { name: /billing\.viewBillingTitle/ })).not.toBeInTheDocument()
expect(screen.queryByRole('button', { name: /billing\.viewBillingAction/ })).not.toBeInTheDocument()
expect(billingUrlEnabled).toBe(false)
})
it('hides the billing action when subscription management permission is missing or billing is disabled', () => {
workspacePermissionKeys = []
render(<Billing />)
expect(screen.queryByRole('button', { name: /billing\.viewBillingTitle/ })).not.toBeInTheDocument()
expect(screen.queryByRole('button', { name: /billing\.viewBillingAction/ })).not.toBeInTheDocument()
expect(billingUrlEnabled).toBe(false)
vi.clearAllMocks()
workspacePermissionKeys = ['billing.subscription.manage']
enableBilling = false
render(<Billing />)
expect(screen.queryByRole('button', { name: /billing\.viewBillingTitle/ })).not.toBeInTheDocument()
expect(screen.queryByRole('button', { name: /billing\.viewBillingAction/ })).not.toBeInTheDocument()
expect(billingUrlEnabled).toBe(false)
})
it('opens the billing window with the immediate url when the button is clicked', async () => {
render(<Billing />)
const actionButton = screen.getByRole('button', { name: /billing\.viewBillingTitle/ })
const actionButton = screen.getByRole('button', { name: /billing\.viewBillingAction/ })
fireEvent.click(actionButton)
await waitFor(() => expect(openAsyncWindowMock).toHaveBeenCalled())
@@ -105,7 +114,7 @@ describe('Billing', () => {
refetchMock.mockResolvedValue({ data: newUrl })
render(<Billing />)
const actionButton = screen.getByRole('button', { name: /billing\.viewBillingTitle/ })
const actionButton = screen.getByRole('button', { name: /billing\.viewBillingAction/ })
fireEvent.click(actionButton)
await waitFor(() => expect(openAsyncWindowMock).toHaveBeenCalled())
@@ -121,7 +130,7 @@ describe('Billing', () => {
refetchMock.mockResolvedValue({ data: null })
render(<Billing />)
const actionButton = screen.getByRole('button', { name: /billing\.viewBillingTitle/ })
const actionButton = screen.getByRole('button', { name: /billing\.viewBillingAction/ })
fireEvent.click(actionButton)
await waitFor(() => expect(openAsyncWindowMock).toHaveBeenCalled())
@@ -136,7 +145,7 @@ describe('Billing', () => {
const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {})
render(<Billing />)
const actionButton = screen.getByRole('button', { name: /billing\.viewBillingTitle/ })
const actionButton = screen.getByRole('button', { name: /billing\.viewBillingAction/ })
fireEvent.click(actionButton)
await waitFor(() => expect(openAsyncWindowMock).toHaveBeenCalled())
@@ -154,7 +163,7 @@ describe('Billing', () => {
fetching = true
render(<Billing />)
const actionButton = screen.getByRole('button', { name: /billing\.viewBillingTitle/ })
const actionButton = screen.getByRole('button', { name: /billing\.viewBillingAction/ })
expect(actionButton)!.toBeDisabled()
})
})
@@ -1,5 +1,6 @@
'use client'
import type { FC } from 'react'
import { Button } from '@langgenius/dify-ui/button'
import * as React from 'react'
import { useTranslation } from 'react-i18next'
import { useAppContext } from '@/context/app-context'
@@ -33,24 +34,26 @@ const Billing: FC = () => {
}
return (
<div>
<div className="flex flex-col gap-3 pt-4">
<PlanComp loc="billing-page" />
{enableBilling && canManageBillingSubscription && (
<button
type="button"
className="mt-3 flex w-full items-center justify-between rounded-xl bg-background-section-burn px-4 py-3"
onClick={handleOpenBilling}
disabled={isFetching}
>
<div className="flex w-full items-center justify-between rounded-xl bg-background-section-burn px-4 py-3">
<div className="flex flex-col gap-0.5 text-left">
<div className="system-md-semibold text-text-primary">{t('viewBillingTitle', { ns: 'billing' })}</div>
<div className="system-sm-regular text-text-secondary">{t('viewBillingDescription', { ns: 'billing' })}</div>
</div>
<span className="inline-flex h-8 w-24 items-center justify-center gap-0.5 rounded-lg border-[0.5px] border-components-button-secondary-border bg-components-button-secondary-bg px-3 py-2 text-saas-dify-blue-accessible shadow-[0_1px_2px_rgba(9,9,11,0.05)] backdrop-blur-[5px]">
<Button
type="button"
variant="secondary-accent"
size="medium"
className="gap-0.5 px-3"
onClick={handleOpenBilling}
disabled={isFetching}
>
<span className="system-sm-medium leading-none">{t('viewBillingAction', { ns: 'billing' })}</span>
<span className="i-ri-arrow-right-up-line size-4" />
</span>
</button>
</Button>
</div>
)}
</div>
)
+1
View File
@@ -91,4 +91,5 @@ export const defaultPlan = {
apiRateLimit: null,
triggerEvents: null,
},
invoiceFlow: null,
}
+86 -83
View File
@@ -91,93 +91,96 @@ const PlanComp: FC<Props> = ({
if (path.startsWith('/education-apply'))
setShowAccountSettingModal(null)
}, [path, setShowAccountSettingModal])
return (
<div className="relative rounded-2xl border-[0.5px] border-effects-highlight-lightmode-off bg-background-section-burn">
<div className="p-6 pb-2">
{plan.type === Plan.sandbox && (
<Sandbox />
)}
{plan.type === Plan.professional && (
<Professional />
)}
{plan.type === Plan.team && (
<Team />
)}
{isEnterprisePlan && (
<Enterprise />
)}
<div className="mt-1 flex items-center">
<div className="grow">
<div className="mb-1 flex items-center gap-1">
<div className="system-md-semibold-uppercase text-text-primary">{t(`plans.${type}.name`, { ns: 'billing' })}</div>
<>
<div className="relative rounded-2xl border-[0.5px] border-effects-highlight-lightmode-off bg-background-section-burn">
<div className="p-6 pb-2">
{plan.type === Plan.sandbox && (
<Sandbox />
)}
{plan.type === Plan.professional && (
<Professional />
)}
{plan.type === Plan.team && (
<Team />
)}
{isEnterprisePlan && (
<Enterprise />
)}
<div className="mt-1 flex items-center">
<div className="grow">
<div className="mb-1 flex items-center gap-1">
<div className="system-md-semibold-uppercase text-text-primary">{t(`plans.${type}.name`, { ns: 'billing' })}</div>
</div>
<div className="system-xs-regular text-util-colors-gray-gray-600">{t(`plans.${type}.for`, { ns: 'billing' })}</div>
</div>
<div className="flex shrink-0 items-center gap-1">
{IS_CLOUD_EDITION && enableEducationPlan && (!isEducationAccount || isAboutToExpire) && (
<Button variant="ghost" onClick={handleVerify} disabled={isPending}>
<span className="mr-1 i-ri-graduation-cap-line size-4" />
{t('toVerified', { ns: 'education' })}
{isPending && <Loading className="ml-1 animate-spin-slow" />}
</Button>
)}
{IS_CLOUD_EDITION && enableEducationPlan && isEducationAccount && type === Plan.sandbox && canManageBilling && (
<Button variant="ghost" onClick={handleEducationDiscount} disabled={isEducationDiscountLoading}>
<span className="mr-1 i-ri-graduation-cap-line size-4" />
{t('useEducationDiscount', { ns: 'education' })}
{isEducationDiscountLoading && <Loading className="ml-1 animate-spin-slow" />}
</Button>
)}
{IS_CLOUD_EDITION && !isEnterprisePlan && (
<UpgradeBtn
className="shrink-0"
isPlain={type === Plan.team}
isShort
loc={loc}
/>
)}
</div>
<div className="system-xs-regular text-util-colors-gray-gray-600">{t(`plans.${type}.for`, { ns: 'billing' })}</div>
</div>
<div className="flex shrink-0 items-center gap-1">
{IS_CLOUD_EDITION && enableEducationPlan && (!isEducationAccount || isAboutToExpire) && (
<Button variant="ghost" onClick={handleVerify} disabled={isPending}>
<span className="mr-1 i-ri-graduation-cap-line size-4" />
{t('toVerified', { ns: 'education' })}
{isPending && <Loading className="ml-1 animate-spin-slow" />}
</Button>
)}
{IS_CLOUD_EDITION && enableEducationPlan && isEducationAccount && type === Plan.sandbox && canManageBilling && (
<Button variant="ghost" onClick={handleEducationDiscount} disabled={isEducationDiscountLoading}>
<span className="mr-1 i-ri-graduation-cap-line size-4" />
{t('useEducationDiscount', { ns: 'education' })}
{isEducationDiscountLoading && <Loading className="ml-1 animate-spin-slow" />}
</Button>
)}
{IS_CLOUD_EDITION && !isEnterprisePlan && (
<UpgradeBtn
className="shrink-0"
isPlain={type === Plan.team}
isShort
loc={loc}
/>
)}
</div>
</div>
</div>
{/* Plan detail */}
<div className="grid grid-cols-3 content-start gap-1 p-2">
<AppsInfo />
<UsageInfo
Icon={RiGroupLine}
name={t('usagePage.teamMembers', { ns: 'billing' })}
usage={usage.teamMembers}
total={total.teamMembers}
/>
<UsageInfo
Icon={RiBook2Line}
name={t('usagePage.documentsUploadQuota', { ns: 'billing' })}
usage={usage.documentsUploadQuota}
total={total.documentsUploadQuota}
/>
<VectorSpaceInfo />
<UsageInfo
Icon={RiFileEditLine}
name={t('usagePage.annotationQuota', { ns: 'billing' })}
usage={usage.annotatedResponse}
total={total.annotatedResponse}
/>
<UsageInfo
Icon={TriggerAll}
name={t('usagePage.triggerEvents', { ns: 'billing' })}
usage={usage.triggerEvents}
total={total.triggerEvents}
tooltip={t('plansCommon.triggerEvents.tooltip', { ns: 'billing' }) as string}
resetInDays={triggerEventsResetInDays}
/>
<UsageInfo
Icon={ApiAggregate}
name={t('plansCommon.apiRateLimit', { ns: 'billing' })}
usage={usage.apiRateLimit}
total={total.apiRateLimit}
tooltip={total.apiRateLimit === NUM_INFINITE ? undefined : t('plansCommon.apiRateLimitTooltip', { ns: 'billing' }) as string}
resetInDays={apiRateLimitResetInDays}
/>
{/* Plan detail */}
<div className="grid grid-cols-3 content-start gap-1 p-2">
<AppsInfo />
<UsageInfo
Icon={RiGroupLine}
name={t('usagePage.teamMembers', { ns: 'billing' })}
usage={usage.teamMembers}
total={total.teamMembers}
/>
<UsageInfo
Icon={RiBook2Line}
name={t('usagePage.documentsUploadQuota', { ns: 'billing' })}
usage={usage.documentsUploadQuota}
total={total.documentsUploadQuota}
/>
<VectorSpaceInfo />
<UsageInfo
Icon={RiFileEditLine}
name={t('usagePage.annotationQuota', { ns: 'billing' })}
usage={usage.annotatedResponse}
total={total.annotatedResponse}
/>
<UsageInfo
Icon={TriggerAll}
name={t('usagePage.triggerEvents', { ns: 'billing' })}
usage={usage.triggerEvents}
total={total.triggerEvents}
tooltip={t('plansCommon.triggerEvents.tooltip', { ns: 'billing' }) as string}
resetInDays={triggerEventsResetInDays}
/>
<UsageInfo
Icon={ApiAggregate}
name={t('plansCommon.apiRateLimit', { ns: 'billing' })}
usage={usage.apiRateLimit}
total={total.apiRateLimit}
tooltip={total.apiRateLimit === NUM_INFINITE ? undefined : t('plansCommon.apiRateLimitTooltip', { ns: 'billing' }) as string}
resetInDays={apiRateLimitResetInDays}
/>
</div>
</div>
<VerifyStateModal
showLink
@@ -188,7 +191,7 @@ const PlanComp: FC<Props> = ({
onConfirm={() => setShowModal(false)}
onCancel={() => setShowModal(false)}
/>
</div>
</>
)
}
export default React.memo(PlanComp)
@@ -152,6 +152,33 @@ describe('CloudPlanItem', () => {
expect(screen.getByText('billing.plansCommon.mostPopular'))!.toBeInTheDocument()
})
it('should show pay by invoice link for paid plans', () => {
render(
<CloudPlanItem
plan={Plan.professional}
currentPlan={Plan.sandbox}
planRange={PlanRange.yearly}
canPay
/>,
)
expect(screen.getByRole('link', { name: 'billing.invoice.payByInvoice' }))!
.toHaveAttribute('href', '/billing/invoice-request?plan=professional&cycle=year')
})
it('should not show pay by invoice link for sandbox plan', () => {
render(
<CloudPlanItem
plan={Plan.sandbox}
currentPlan={Plan.sandbox}
planRange={PlanRange.monthly}
canPay
/>,
)
expect(screen.queryByText('billing.invoice.payByInvoice')).not.toBeInTheDocument()
})
it('should not show "most popular" badge for non-professional plans', () => {
render(
<CloudPlanItem
@@ -178,6 +205,27 @@ describe('CloudPlanItem', () => {
const button = screen.getByRole('button', { name: 'billing.plansCommon.startBuilding' })
expect(button)!.toBeDisabled()
})
it('should disable card checkout and pay by invoice when invoice flow is locked', () => {
render(
<CloudPlanItem
plan={Plan.professional}
currentPlan={Plan.sandbox}
planRange={PlanRange.monthly}
canPay
invoiceFlow={{
status: 'invoice_sent',
locked: true,
plan: Plan.professional,
interval: 'month',
}}
/>,
)
expect(screen.getByRole('button', { name: 'billing.invoice.status.awaitingPayment' }))!.toBeDisabled()
expect(screen.queryByRole('link', { name: 'billing.invoice.payByInvoice' })).not.toBeInTheDocument()
expect(screen.getByText('billing.invoice.payByInvoice')!.closest('[aria-disabled="true"]')).not.toBeNull()
})
})
// Payment actions triggered from the CTA
@@ -203,6 +251,44 @@ describe('CloudPlanItem', () => {
expect(mockFetchSubscriptionUrls).not.toHaveBeenCalled()
})
it('should disable pay by invoice when current user is not workspace manager', () => {
mockUseAppContext.mockReturnValue({
isCurrentWorkspaceManager: false,
workspacePermissionKeys: ['billing.manage'],
})
render(
<CloudPlanItem
plan={Plan.professional}
currentPlan={Plan.sandbox}
planRange={PlanRange.monthly}
canPay
/>,
)
expect(screen.queryByRole('link', { name: 'billing.invoice.payByInvoice' })).not.toBeInTheDocument()
expect(screen.getByText('billing.invoice.payByInvoice')!.closest('[aria-disabled="true"]')).not.toBeNull()
})
it('should disable pay by invoice when current user cannot manage billing', () => {
mockUseAppContext.mockReturnValue({
isCurrentWorkspaceManager: true,
workspacePermissionKeys: ['billing.view'],
})
render(
<CloudPlanItem
plan={Plan.professional}
currentPlan={Plan.sandbox}
planRange={PlanRange.monthly}
canPay
/>,
)
expect(screen.queryByRole('link', { name: 'billing.invoice.payByInvoice' })).not.toBeInTheDocument()
expect(screen.getByText('billing.invoice.payByInvoice')!.closest('[aria-disabled="true"]')).not.toBeNull()
})
it('should open billing portal when upgrading current paid plan', async () => {
const openWindow = vi.fn(async (cb: () => Promise<string>) => await cb())
mockUseAsyncWindowOpen.mockReturnValue(openWindow)
@@ -1,6 +1,5 @@
import type { BasicPlan } from '../../../type'
import { cn } from '@langgenius/dify-ui/cn'
import * as React from 'react'
import { Plan } from '../../../type'
const BUTTON_CLASSNAME = {
@@ -24,17 +23,19 @@ type ButtonProps = {
btnText: string
handleGetPayUrl: () => void
warningText?: string
className?: string
}
const Button = ({
function PlanButton({
plan,
isPlanDisabled,
btnText,
handleGetPayUrl,
warningText,
}: ButtonProps) => {
className,
}: ButtonProps) {
return (
<div className="relative">
<div className={cn('relative', className)}>
<button
type="button"
disabled={isPlanDisabled}
@@ -58,4 +59,4 @@ const Button = ({
)
}
export default React.memo(Button)
export default PlanButton
@@ -1,6 +1,5 @@
'use client'
import type { FC } from 'react'
import type { BasicPlan } from '../../../type'
import type { BasicPlan, InvoiceFlow, InvoiceFlowStatus } from '../../../type'
import { Button } from '@langgenius/dify-ui/button'
import {
Dialog,
@@ -10,12 +9,17 @@ import {
DialogTitle,
} from '@langgenius/dify-ui/dialog'
import { toast } from '@langgenius/dify-ui/toast'
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from '@langgenius/dify-ui/tooltip'
import * as React from 'react'
import { useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { useAppContext } from '@/context/app-context'
import { useProviderContext } from '@/context/provider-context'
import { useAsyncWindowOpen } from '@/hooks/use-async-window-open'
import Link from '@/next/link'
import { fetchSubscriptionUrls } from '@/service/billing'
import { consoleClient } from '@/service/client'
import { BillingPermission, hasPermission } from '@/utils/permission'
@@ -38,14 +42,30 @@ type CloudPlanItemProps = {
plan: BasicPlan
planRange: PlanRange
canPay: boolean
invoiceFlow?: InvoiceFlow | null
}
const CloudPlanItem: FC<CloudPlanItemProps> = ({
const INVOICE_FLOW_BUTTON_TEXT_KEY = {
request_processing: 'invoice.status.processing',
invoice_sent: 'invoice.status.awaitingPayment',
renewal_invoice_sent: 'invoice.status.awaitingPayment',
payment_confirming: 'invoice.status.confirmingPayment',
renewal_past_due: 'invoice.status.paymentOverdue',
} as const satisfies Partial<Record<InvoiceFlowStatus, string>>
type InvoiceFlowButtonStatus = keyof typeof INVOICE_FLOW_BUTTON_TEXT_KEY
const isInvoiceFlowButtonStatus = (status: InvoiceFlowStatus): status is InvoiceFlowButtonStatus => {
return status in INVOICE_FLOW_BUTTON_TEXT_KEY
}
function CloudPlanItem({
plan,
currentPlan,
planRange,
canPay,
}) => {
invoiceFlow,
}: CloudPlanItemProps) {
const { t } = useTranslation()
const [loading, setLoading] = React.useState(false)
const i18nPrefix = `plans.${plan}` as const
@@ -55,8 +75,13 @@ const CloudPlanItem: FC<CloudPlanItemProps> = ({
const isYear = planRange === PlanRange.yearly
const isCurrent = plan === currentPlan
const isCurrentPaidPlan = isCurrent && !isFreePlan
const isPlanDisabled = isCurrentPaidPlan ? false : planInfo.level <= ALL_PLANS[currentPlan].level
const { workspacePermissionKeys } = useAppContext()
const isInvoiceFlowLocked = !!invoiceFlow?.locked
const isInvoiceFlowPlan = invoiceFlow?.plan === plan
const invoiceFlowButtonTextKey = isInvoiceFlowPlan && invoiceFlow?.status && isInvoiceFlowButtonStatus(invoiceFlow.status)
? INVOICE_FLOW_BUTTON_TEXT_KEY[invoiceFlow.status]
: undefined
const isPlanDisabled = isInvoiceFlowLocked || (isCurrentPaidPlan ? false : planInfo.level <= ALL_PLANS[currentPlan].level)
const { isCurrentWorkspaceManager, workspacePermissionKeys } = useAppContext()
const canManageBilling = hasPermission(workspacePermissionKeys, BillingPermission.Manage)
const canManageBillingSubscription = hasPermission(workspacePermissionKeys, BillingPermission.SubscriptionManage)
const { enableEducationPlan, isEducationAccount } = useProviderContext()
@@ -68,20 +93,28 @@ const CloudPlanItem: FC<CloudPlanItemProps> = ({
const openAsyncWindow = useAsyncWindowOpen()
const { handleEducationDiscount, isEducationDiscountLoading } = useEducationDiscount()
const [showEducationPricingConfirm, setShowEducationPricingConfirm] = React.useState(false)
const canRequestInvoice = canPay && isCurrentWorkspaceManager && canManageBilling
const isPayByInvoiceVisible = !isFreePlan
const invoiceRequestUrl = `/billing/invoice-request?plan=${plan}&cycle=${isYear ? 'year' : 'month'}`
const isPayByInvoiceDisabled = !canRequestInvoice || isInvoiceFlowLocked
const btnText = useMemo(() => {
if (canPay && isEducationDiscountMode && isEducationDiscountSupportedPlan && !isCurrent)
return t('useEducationDiscount', { ns: 'education' })
if (isCurrent)
return t('plansCommon.currentPlan', { ns: 'billing' })
return ({
let btnText: string
if (invoiceFlowButtonTextKey) {
btnText = t(invoiceFlowButtonTextKey, { ns: 'billing' })
}
else if (canPay && isEducationDiscountMode && isEducationDiscountSupportedPlan && !isCurrent) {
btnText = t('useEducationDiscount', { ns: 'education' })
}
else if (isCurrent) {
btnText = t('plansCommon.currentPlan', { ns: 'billing' })
}
else {
btnText = ({
[Plan.sandbox]: t('plansCommon.startForFree', { ns: 'billing' }),
[Plan.professional]: t('plansCommon.startBuilding', { ns: 'billing' }),
[Plan.team]: t('plansCommon.getStarted', { ns: 'billing' }),
})[plan]
}, [canPay, isCurrent, isEducationDiscountMode, isEducationDiscountSupportedPlan, plan, t])
}
const handlePayCurrentPlan = async () => {
if (loading || isEducationDiscountLoading)
@@ -133,6 +166,9 @@ const CloudPlanItem: FC<CloudPlanItemProps> = ({
}
}
const handleGetPayUrl = async () => {
if (isInvoiceFlowLocked)
return
if (educationDiscountWarningText && !isPlanDisabled) {
setShowEducationPricingConfirm(true)
return
@@ -192,13 +228,23 @@ const CloudPlanItem: FC<CloudPlanItemProps> = ({
</>
)}
</div>
<PlanButton
plan={plan}
isPlanDisabled={isPlanDisabled}
btnText={btnText}
handleGetPayUrl={handleGetPayUrl}
warningText={educationDiscountWarningText}
/>
<div className="flex gap-2">
<PlanButton
plan={plan}
isPlanDisabled={isPlanDisabled}
btnText={btnText}
handleGetPayUrl={handleGetPayUrl}
warningText={educationDiscountWarningText}
className={isPayByInvoiceVisible ? 'min-w-0 flex-1' : undefined}
/>
{isPayByInvoiceVisible && (
<PayByInvoiceAction
href={invoiceRequestUrl}
disabled={isPayByInvoiceDisabled}
tooltip={canRequestInvoice ? undefined : t('invoice.permissionDeniedTooltip', { ns: 'billing' })}
/>
)}
</div>
</div>
<List plan={plan} />
<Dialog
@@ -247,4 +293,65 @@ const CloudPlanItem: FC<CloudPlanItemProps> = ({
</div>
)
}
export default React.memo(CloudPlanItem)
export default CloudPlanItem
type PayByInvoiceActionProps = {
href: string
disabled: boolean
tooltip?: string
}
function PayByInvoiceAction({
href,
disabled,
tooltip,
}: PayByInvoiceActionProps) {
const { t } = useTranslation()
const label = t('invoice.payByInvoice', { ns: 'billing' })
const className = 'flex min-h-12 min-w-0 flex-1 items-center gap-2 border border-components-panel-border bg-background-default py-3 pr-4 pl-5 system-xl-semibold text-text-secondary hover:bg-state-base-hover focus-visible:ring-2 focus-visible:ring-state-accent-solid focus-visible:outline-hidden'
const disabledClassName = 'flex min-h-12 min-w-0 flex-1 cursor-not-allowed items-center gap-2 border border-transparent bg-components-button-tertiary-bg-disabled py-3 pr-4 pl-5 system-xl-semibold text-text-disabled'
if (!disabled) {
return (
<Link
href={href}
className={className}
>
<span className="min-w-0 grow truncate text-start">{label}</span>
<span aria-hidden="true" className="i-ri-arrow-right-line size-5 shrink-0" />
</Link>
)
}
const action = (
<span
aria-disabled="true"
className={disabledClassName}
>
<span className="min-w-0 grow truncate text-start">{label}</span>
</span>
)
if (!tooltip)
return action
return (
<Tooltip>
<TooltipTrigger
render={(
<button
type="button"
aria-disabled="true"
aria-label={tooltip}
className="flex min-w-0 flex-1 focus-visible:ring-2 focus-visible:ring-state-accent-solid focus-visible:outline-hidden"
>
{action}
</button>
)}
/>
<TooltipContent>
{tooltip}
</TooltipContent>
</Tooltip>
)
}
@@ -1,4 +1,4 @@
import type { BasicPlan, UsagePlanInfo } from '../../type'
import type { BasicPlan, InvoiceFlow, UsagePlanInfo } from '../../type'
import type { PlanRange } from '../plan-switcher/plan-range-switcher'
import Divider from '@/app/components/base/divider'
import { Plan, SelfHostedPlan } from '../../type'
@@ -10,6 +10,7 @@ type PlansProps = {
type: Plan
usage: UsagePlanInfo
total: UsagePlanInfo
invoiceFlow?: InvoiceFlow | null
}
currentPlan: string
planRange: PlanRange
@@ -34,6 +35,7 @@ const Plans = ({
plan={Plan.sandbox}
planRange={planRange}
canPay={canPay}
invoiceFlow={plan.invoiceFlow}
/>
<Divider type="vertical" className="mx-0 shrink-0 bg-divider-accent" />
<CloudPlanItem
@@ -41,6 +43,7 @@ const Plans = ({
plan={Plan.professional}
planRange={planRange}
canPay={canPay}
invoiceFlow={plan.invoiceFlow}
/>
<Divider type="vertical" className="mx-0 shrink-0 bg-divider-accent" />
<CloudPlanItem
@@ -48,6 +51,7 @@ const Plans = ({
plan={Plan.team}
planRange={planRange}
canPay={canPay}
invoiceFlow={plan.invoiceFlow}
/>
</>
)
+22
View File
@@ -11,6 +11,27 @@ export enum Priority {
}
export type BasicPlan = Plan.sandbox | Plan.professional | Plan.team
export type BillingInterval = 'month' | 'year'
export type InvoiceFlowStatus
= | 'request_processing'
| 'invoice_sent'
| 'payment_confirming'
| 'active'
| 'expired'
| 'renewal_invoice_sent'
| 'renewal_past_due'
| 'renewal_canceled'
export type InvoiceFlow = {
status: InvoiceFlowStatus
locked: boolean
plan?: BasicPlan | null
interval?: BillingInterval | null
hosted_invoice_url?: string | null
due_at?: number | null
recoverable_until?: number | null
}
export type PlanInfo = {
level: number
@@ -62,6 +83,7 @@ export type CurrentPlanInfoBackend = {
subscription: {
plan: BasicPlan
}
invoice_flow?: InvoiceFlow | null
}
members: {
size: number
@@ -115,5 +115,6 @@ export const parseCurrentPlan = (data: CurrentPlanInfoBackend) => {
apiRateLimit: getQuotaResetInDays(data.api_rate_limit),
triggerEvents: getQuotaResetInDays(data.trigger_event),
},
invoiceFlow: data.billing.invoice_flow ?? null,
}
}
@@ -254,7 +254,7 @@ export default function AccountSetting({
)}
</div>
</div>
<div className="px-4 pt-6 sm:px-8">
<div className={cn('px-4 sm:px-8', activeMenu === ACCOUNT_SETTING_TAB.BILLING ? 'pt-0' : 'pt-6')}>
{activeMenu === ACCOUNT_SETTING_TAB.PROVIDER && (
<ModelProviderPage
searchText={searchValue}
+2 -1
View File
@@ -1,6 +1,6 @@
'use client'
import type { Plan, UsagePlanInfo, UsageResetInfo } from '@/app/components/billing/type'
import type { InvoiceFlow, Plan, UsagePlanInfo, UsageResetInfo } from '@/app/components/billing/type'
import type { Model, ModelProvider } from '@/app/components/header/account-setting/model-provider-page/declarations'
import type { RETRIEVE_METHOD } from '@/types/app'
import { noop } from 'es-toolkit/function'
@@ -19,6 +19,7 @@ export type ProviderContextState = {
usage: UsagePlanInfo
total: UsagePlanInfo
reset: UsageResetInfo
invoiceFlow?: InvoiceFlow | null
}
isFetchedPlan: boolean
isFetchedPlanInfo: boolean
+39
View File
@@ -9,6 +9,45 @@
"apps.fullTip2des": "يوصى بتنظيف التطبيقات غير النشطة لتحرير الاستخدام، أو الاتصال بنا.",
"buyPermissionDeniedTip": "يرجى الاتصال بمسؤول المؤسسة للاشتراك",
"currentPlan": "الخطة الحالية",
"invoice.form.addressLine1": "Address line 1",
"invoice.form.addressLine2": "Address line 2 (optional)",
"invoice.form.city": "City",
"invoice.form.companyName": "Company name",
"invoice.form.country": "Country",
"invoice.form.description": "This information will appear on your invoice. Please ensure accuracy.",
"invoice.form.invoiceEmail": "Invoice recipient email",
"invoice.form.placeholder.addressLine1": "123 Main Street",
"invoice.form.placeholder.addressLine2": "Suite 400",
"invoice.form.placeholder.city": "San Francisco",
"invoice.form.placeholder.companyName": "Acme Inc.",
"invoice.form.placeholder.country": "Select a country",
"invoice.form.placeholder.invoiceEmail": "finance@example.com",
"invoice.form.placeholder.postalCode": "94103",
"invoice.form.placeholder.stateOrProvince": "CA",
"invoice.form.postalCode": "Postal code",
"invoice.form.stateOrProvince": "State / Province",
"invoice.form.submit": "إرسال الطلب",
"invoice.form.terms": "I agree to LangGenius, Inc.'s <terms>Terms of Service</terms> and <privacy>Privacy Policy</privacy>. I understand that renewal invoices will be sent automatically each billing cycle until I cancel, and payment must be completed manually each time. International wire transfer fees are my responsibility.",
"invoice.form.termsRequired": "Please agree to the invoice payment terms before submitting.",
"invoice.form.title": "Billing information",
"invoice.lockedTip": "An invoice payment flow is already active for this workspace.",
"invoice.payByInvoice": "الدفع عبر فاتورة",
"invoice.permissionDeniedTooltip": "Only the team owner and admins can manage subscriptions and billing.",
"invoice.requestReceived.description": "Your invoice will be sent to <email>{{email}}</email> within <day>1 business day</day>.",
"invoice.requestReceived.goToBilling": "Go to Billing",
"invoice.requestReceived.renewalTip": "After your first payment, new invoices are sent automatically before each billing cycle. You need to complete payment manually each time. Cancel anytime from your Billing page.",
"invoice.requestReceived.statusTip": "You can track the status from your Billing page. Once you receive the invoice, complete payment using your preferred method on the invoice page.",
"invoice.requestReceived.title": "تم استلام الطلب",
"invoice.status.awaitingPayment": "Awaiting payment",
"invoice.status.confirmingPayment": "Confirming payment",
"invoice.status.paymentOverdue": "Payment overdue",
"invoice.status.processing": "Processing",
"invoice.summary.billingCycle": "Billing cycle",
"invoice.summary.month": "شهري",
"invoice.summary.saveAnnual": "SAVE {{percent}}%",
"invoice.summary.subtitle": "Pay by invoice",
"invoice.summary.title": "Subscription Plan",
"invoice.summary.year": "سنوي",
"plans.community.btnText": "ابدأ الآن",
"plans.community.description": "للمتحمسين للمصادر المفتوحة، والمطورين الأفراد، والمشاريع غير التجارية",
"plans.community.features": [
+39
View File
@@ -9,6 +9,45 @@
"apps.fullTip2des": "Es wird empfohlen, inaktive Anwendungen zu bereinigen, um Speicherplatz freizugeben, oder uns zu kontaktieren.",
"buyPermissionDeniedTip": "Bitte kontaktieren Sie Ihren Unternehmensadministrator, um zu abonnieren",
"currentPlan": "Aktueller Tarif",
"invoice.form.addressLine1": "Adresszeile 1",
"invoice.form.addressLine2": "Adresszeile 2 (optional)",
"invoice.form.city": "Stadt",
"invoice.form.companyName": "Firmenname",
"invoice.form.country": "Land",
"invoice.form.description": "Diese Informationen erscheinen auf Ihrer Rechnung. Bitte prüfen Sie sie sorgfältig.",
"invoice.form.invoiceEmail": "E-Mail für Rechnungsempfang",
"invoice.form.placeholder.addressLine1": "123 Main Street",
"invoice.form.placeholder.addressLine2": "Suite 400",
"invoice.form.placeholder.city": "San Francisco",
"invoice.form.placeholder.companyName": "Acme Inc.",
"invoice.form.placeholder.country": "Select a country",
"invoice.form.placeholder.invoiceEmail": "finance@example.com",
"invoice.form.placeholder.postalCode": "94103",
"invoice.form.placeholder.stateOrProvince": "CA",
"invoice.form.postalCode": "Postleitzahl",
"invoice.form.stateOrProvince": "Bundesland / Provinz",
"invoice.form.submit": "Anfrage senden",
"invoice.form.terms": "Ich stimme den <terms>Nutzungsbedingungen</terms> und der <privacy>Datenschutzrichtlinie</privacy> von LangGenius, Inc. zu. Ich verstehe, dass Verlängerungsrechnungen bis zur Kündigung automatisch in jedem Abrechnungszyklus gesendet werden und jede Zahlung manuell abgeschlossen werden muss. Gebühren für internationale Überweisungen trage ich selbst.",
"invoice.form.termsRequired": "Bitte stimmen Sie den Rechnungszahlungsbedingungen vor dem Absenden zu.",
"invoice.form.title": "Rechnungsinformationen",
"invoice.lockedTip": "Für diesen Workspace ist bereits ein Rechnungszahlungsprozess aktiv.",
"invoice.payByInvoice": "Per Rechnung bezahlen",
"invoice.permissionDeniedTooltip": "Nur Teaminhaber und Administratoren können Abonnements und Abrechnung verwalten.",
"invoice.requestReceived.description": "Your invoice will be sent to <email>{{email}}</email> within <day>1 business day</day>.",
"invoice.requestReceived.goToBilling": "Go to Billing",
"invoice.requestReceived.renewalTip": "After your first payment, new invoices are sent automatically before each billing cycle. You need to complete payment manually each time. Cancel anytime from your Billing page.",
"invoice.requestReceived.statusTip": "You can track the status from your Billing page. Once you receive the invoice, complete payment using your preferred method on the invoice page.",
"invoice.requestReceived.title": "Anfrage erhalten",
"invoice.status.awaitingPayment": "Zahlung ausstehend",
"invoice.status.confirmingPayment": "Zahlung wird bestätigt",
"invoice.status.paymentOverdue": "Zahlung überfällig",
"invoice.status.processing": "Wird verarbeitet",
"invoice.summary.billingCycle": "Billing cycle",
"invoice.summary.month": "Monatlich",
"invoice.summary.saveAnnual": "SAVE {{percent}}%",
"invoice.summary.subtitle": "Pay by invoice",
"invoice.summary.title": "Subscription Plan",
"invoice.summary.year": "Jährlich",
"plans.community.btnText": "Beginnen Sie mit der Gemeinschaft",
"plans.community.description": "Für Einzelbenutzer, kleine Teams oder nicht-kommerzielle Projekte",
"plans.community.features": [
+39
View File
@@ -9,6 +9,45 @@
"apps.fullTip2des": "It is recommended to clean up inactive applications to free up usage, or contact us.",
"buyPermissionDeniedTip": "Please contact your enterprise administrator to subscribe",
"currentPlan": "Current Plan",
"invoice.form.addressLine1": "Address line 1",
"invoice.form.addressLine2": "Address line 2 (optional)",
"invoice.form.city": "City",
"invoice.form.companyName": "Company name",
"invoice.form.country": "Country",
"invoice.form.description": "This information will appear on your invoice. Please ensure accuracy.",
"invoice.form.invoiceEmail": "Invoice recipient email",
"invoice.form.placeholder.addressLine1": "123 Main Street",
"invoice.form.placeholder.addressLine2": "Suite 400",
"invoice.form.placeholder.city": "San Francisco",
"invoice.form.placeholder.companyName": "Acme Inc.",
"invoice.form.placeholder.country": "Select a country",
"invoice.form.placeholder.invoiceEmail": "finance@example.com",
"invoice.form.placeholder.postalCode": "94103",
"invoice.form.placeholder.stateOrProvince": "CA",
"invoice.form.postalCode": "Postal code",
"invoice.form.stateOrProvince": "State / Province",
"invoice.form.submit": "Submit request",
"invoice.form.terms": "I agree to LangGenius, Inc.'s <terms>Terms of Service</terms> and <privacy>Privacy Policy</privacy>. I understand that renewal invoices will be sent automatically each billing cycle until I cancel, and payment must be completed manually each time. International wire transfer fees are my responsibility.",
"invoice.form.termsRequired": "Please agree to the invoice payment terms before submitting.",
"invoice.form.title": "Billing information",
"invoice.lockedTip": "An invoice payment flow is already active for this workspace.",
"invoice.payByInvoice": "Pay by Invoice",
"invoice.permissionDeniedTooltip": "Only the team owner and admins can manage subscriptions and billing.",
"invoice.requestReceived.description": "Your invoice will be sent to <email>{{email}}</email> within <day>1 business day</day>.",
"invoice.requestReceived.goToBilling": "Go to Billing",
"invoice.requestReceived.renewalTip": "After your first payment, new invoices are sent automatically before each billing cycle. You need to complete payment manually each time. Cancel anytime from your Billing page.",
"invoice.requestReceived.statusTip": "You can track the status from your Billing page. Once you receive the invoice, complete payment using your preferred method on the invoice page.",
"invoice.requestReceived.title": "Request received",
"invoice.status.awaitingPayment": "Awaiting payment",
"invoice.status.confirmingPayment": "Confirming payment",
"invoice.status.paymentOverdue": "Payment overdue",
"invoice.status.processing": "Processing",
"invoice.summary.billingCycle": "Billing cycle",
"invoice.summary.month": "Monthly",
"invoice.summary.saveAnnual": "SAVE {{percent}}%",
"invoice.summary.subtitle": "Pay by invoice",
"invoice.summary.title": "Subscription Plan",
"invoice.summary.year": "Annual",
"plans.community.btnText": "Get Started",
"plans.community.description": "For open-source enthusiasts, individual developers, and non-commercial projects",
"plans.community.features": [
+39
View File
@@ -9,6 +9,45 @@
"apps.fullTip2des": "Se recomienda limpiar las aplicaciones inactivas para liberar espacio de uso, o contactarnos.",
"buyPermissionDeniedTip": "Por favor, contacta al administrador de tu empresa para suscribirte",
"currentPlan": "Plan Actual",
"invoice.form.addressLine1": "Dirección línea 1",
"invoice.form.addressLine2": "Dirección línea 2 (opcional)",
"invoice.form.city": "Ciudad",
"invoice.form.companyName": "Nombre de la empresa",
"invoice.form.country": "País",
"invoice.form.description": "Esta información aparecerá en tu factura. Comprueba que sea correcta.",
"invoice.form.invoiceEmail": "Correo para recibir la factura",
"invoice.form.placeholder.addressLine1": "123 Main Street",
"invoice.form.placeholder.addressLine2": "Suite 400",
"invoice.form.placeholder.city": "San Francisco",
"invoice.form.placeholder.companyName": "Acme Inc.",
"invoice.form.placeholder.country": "Select a country",
"invoice.form.placeholder.invoiceEmail": "finance@example.com",
"invoice.form.placeholder.postalCode": "94103",
"invoice.form.placeholder.stateOrProvince": "CA",
"invoice.form.postalCode": "Código postal",
"invoice.form.stateOrProvince": "Estado / Provincia",
"invoice.form.submit": "Enviar solicitud",
"invoice.form.terms": "Acepto los <terms>Términos de servicio</terms> y la <privacy>Política de privacidad</privacy> de LangGenius, Inc. Entiendo que las facturas de renovación se enviarán automáticamente en cada ciclo hasta que cancele y que cada pago debe completarse manualmente. Las comisiones de transferencias internacionales son mi responsabilidad.",
"invoice.form.termsRequired": "Acepta los términos de pago por factura antes de enviar.",
"invoice.form.title": "Información de facturación",
"invoice.lockedTip": "Ya hay un flujo de pago por factura activo para este espacio de trabajo.",
"invoice.payByInvoice": "Pagar por factura",
"invoice.permissionDeniedTooltip": "Solo el propietario y los administradores del equipo pueden gestionar suscripciones y facturación.",
"invoice.requestReceived.description": "Your invoice will be sent to <email>{{email}}</email> within <day>1 business day</day>.",
"invoice.requestReceived.goToBilling": "Go to Billing",
"invoice.requestReceived.renewalTip": "After your first payment, new invoices are sent automatically before each billing cycle. You need to complete payment manually each time. Cancel anytime from your Billing page.",
"invoice.requestReceived.statusTip": "You can track the status from your Billing page. Once you receive the invoice, complete payment using your preferred method on the invoice page.",
"invoice.requestReceived.title": "Solicitud recibida",
"invoice.status.awaitingPayment": "Esperando pago",
"invoice.status.confirmingPayment": "Confirmando pago",
"invoice.status.paymentOverdue": "Pago vencido",
"invoice.status.processing": "Procesando",
"invoice.summary.billingCycle": "Billing cycle",
"invoice.summary.month": "Mensual",
"invoice.summary.saveAnnual": "SAVE {{percent}}%",
"invoice.summary.subtitle": "Pay by invoice",
"invoice.summary.title": "Subscription Plan",
"invoice.summary.year": "Anual",
"plans.community.btnText": "Comienza con la Comunidad",
"plans.community.description": "Para usuarios individuales, pequeños equipos o proyectos no comerciales",
"plans.community.features": [
+39
View File
@@ -9,6 +9,45 @@
"apps.fullTip2des": "توصیه می‌شود برنامه‌های غیرفعال را پاک کنید تا فضای استفاده را آزاد کنید، یا با ما تماس بگیرید.",
"buyPermissionDeniedTip": "لطفاً با مدیر سازمان خود تماس بگیرید تا اشتراک تهیه کنید",
"currentPlan": "طرح فعلی",
"invoice.form.addressLine1": "Address line 1",
"invoice.form.addressLine2": "Address line 2 (optional)",
"invoice.form.city": "City",
"invoice.form.companyName": "Company name",
"invoice.form.country": "Country",
"invoice.form.description": "This information will appear on your invoice. Please ensure accuracy.",
"invoice.form.invoiceEmail": "Invoice recipient email",
"invoice.form.placeholder.addressLine1": "123 Main Street",
"invoice.form.placeholder.addressLine2": "Suite 400",
"invoice.form.placeholder.city": "San Francisco",
"invoice.form.placeholder.companyName": "Acme Inc.",
"invoice.form.placeholder.country": "Select a country",
"invoice.form.placeholder.invoiceEmail": "finance@example.com",
"invoice.form.placeholder.postalCode": "94103",
"invoice.form.placeholder.stateOrProvince": "CA",
"invoice.form.postalCode": "Postal code",
"invoice.form.stateOrProvince": "State / Province",
"invoice.form.submit": "ارسال درخواست",
"invoice.form.terms": "I agree to LangGenius, Inc.'s <terms>Terms of Service</terms> and <privacy>Privacy Policy</privacy>. I understand that renewal invoices will be sent automatically each billing cycle until I cancel, and payment must be completed manually each time. International wire transfer fees are my responsibility.",
"invoice.form.termsRequired": "Please agree to the invoice payment terms before submitting.",
"invoice.form.title": "Billing information",
"invoice.lockedTip": "An invoice payment flow is already active for this workspace.",
"invoice.payByInvoice": "پرداخت با فاکتور",
"invoice.permissionDeniedTooltip": "Only the team owner and admins can manage subscriptions and billing.",
"invoice.requestReceived.description": "Your invoice will be sent to <email>{{email}}</email> within <day>1 business day</day>.",
"invoice.requestReceived.goToBilling": "Go to Billing",
"invoice.requestReceived.renewalTip": "After your first payment, new invoices are sent automatically before each billing cycle. You need to complete payment manually each time. Cancel anytime from your Billing page.",
"invoice.requestReceived.statusTip": "You can track the status from your Billing page. Once you receive the invoice, complete payment using your preferred method on the invoice page.",
"invoice.requestReceived.title": "درخواست دریافت شد",
"invoice.status.awaitingPayment": "Awaiting payment",
"invoice.status.confirmingPayment": "Confirming payment",
"invoice.status.paymentOverdue": "Payment overdue",
"invoice.status.processing": "Processing",
"invoice.summary.billingCycle": "Billing cycle",
"invoice.summary.month": "ماهانه",
"invoice.summary.saveAnnual": "SAVE {{percent}}%",
"invoice.summary.subtitle": "Pay by invoice",
"invoice.summary.title": "Subscription Plan",
"invoice.summary.year": "سالانه",
"plans.community.btnText": "شروع کنید با جامعه",
"plans.community.description": "برای کاربران فردی، تیم‌های کوچک یا پروژه‌های غیر تجاری",
"plans.community.features": [
+39
View File
@@ -9,6 +9,45 @@
"apps.fullTip2des": "Il est recommandé de nettoyer les applications inactives pour libérer de l'espace d'utilisation, ou de nous contacter.",
"buyPermissionDeniedTip": "Veuillez contacter votre administrateur d'entreprise pour vous abonner",
"currentPlan": "Plan Actuel",
"invoice.form.addressLine1": "Adresse ligne 1",
"invoice.form.addressLine2": "Adresse ligne 2 (facultatif)",
"invoice.form.city": "Ville",
"invoice.form.companyName": "Nom de lentreprise",
"invoice.form.country": "Pays",
"invoice.form.description": "Ces informations apparaîtront sur votre facture. Veuillez vérifier leur exactitude.",
"invoice.form.invoiceEmail": "E-mail de réception de la facture",
"invoice.form.placeholder.addressLine1": "123 Main Street",
"invoice.form.placeholder.addressLine2": "Suite 400",
"invoice.form.placeholder.city": "San Francisco",
"invoice.form.placeholder.companyName": "Acme Inc.",
"invoice.form.placeholder.country": "Select a country",
"invoice.form.placeholder.invoiceEmail": "finance@example.com",
"invoice.form.placeholder.postalCode": "94103",
"invoice.form.placeholder.stateOrProvince": "CA",
"invoice.form.postalCode": "Code postal",
"invoice.form.stateOrProvince": "État / Province",
"invoice.form.submit": "Envoyer la demande",
"invoice.form.terms": "Jaccepte les <terms>Conditions dutilisation</terms> et la <privacy>Politique de confidentialité</privacy> de LangGenius, Inc. Je comprends que les factures de renouvellement seront envoyées automatiquement à chaque cycle jusqu’à annulation, et que chaque paiement doit être effectué manuellement. Les frais de virement international sont à ma charge.",
"invoice.form.termsRequired": "Veuillez accepter les conditions de paiement par facture avant denvoyer.",
"invoice.form.title": "Informations de facturation",
"invoice.lockedTip": "Un flux de paiement par facture est déjà actif pour cet espace de travail.",
"invoice.payByInvoice": "Payer par facture",
"invoice.permissionDeniedTooltip": "Seuls le propriétaire et les administrateurs de l’équipe peuvent gérer les abonnements et la facturation.",
"invoice.requestReceived.description": "Your invoice will be sent to <email>{{email}}</email> within <day>1 business day</day>.",
"invoice.requestReceived.goToBilling": "Go to Billing",
"invoice.requestReceived.renewalTip": "After your first payment, new invoices are sent automatically before each billing cycle. You need to complete payment manually each time. Cancel anytime from your Billing page.",
"invoice.requestReceived.statusTip": "You can track the status from your Billing page. Once you receive the invoice, complete payment using your preferred method on the invoice page.",
"invoice.requestReceived.title": "Demande reçue",
"invoice.status.awaitingPayment": "En attente de paiement",
"invoice.status.confirmingPayment": "Confirmation du paiement",
"invoice.status.paymentOverdue": "Paiement en retard",
"invoice.status.processing": "Traitement en cours",
"invoice.summary.billingCycle": "Billing cycle",
"invoice.summary.month": "Mensuel",
"invoice.summary.saveAnnual": "SAVE {{percent}}%",
"invoice.summary.subtitle": "Pay by invoice",
"invoice.summary.title": "Subscription Plan",
"invoice.summary.year": "Annuel",
"plans.community.btnText": "Commencez avec la communauté",
"plans.community.description": "Pour les utilisateurs individuels, les petites équipes ou les projets non commerciaux",
"plans.community.features": [
+39
View File
@@ -9,6 +9,45 @@
"apps.fullTip2des": "अचल अनुप्रयोगों को साफ करने की सिफारिश की जाती है ताकि उपयोग को मुक्त किया जा सके, या हमसे संपर्क करें।",
"buyPermissionDeniedTip": "सब्सक्राइब करने के लिए कृपया अपने एंटरप्राइज़ व्यवस्थापक से संपर्क करें",
"currentPlan": "वर्तमान योजना",
"invoice.form.addressLine1": "Address line 1",
"invoice.form.addressLine2": "Address line 2 (optional)",
"invoice.form.city": "City",
"invoice.form.companyName": "Company name",
"invoice.form.country": "Country",
"invoice.form.description": "This information will appear on your invoice. Please ensure accuracy.",
"invoice.form.invoiceEmail": "Invoice recipient email",
"invoice.form.placeholder.addressLine1": "123 Main Street",
"invoice.form.placeholder.addressLine2": "Suite 400",
"invoice.form.placeholder.city": "San Francisco",
"invoice.form.placeholder.companyName": "Acme Inc.",
"invoice.form.placeholder.country": "Select a country",
"invoice.form.placeholder.invoiceEmail": "finance@example.com",
"invoice.form.placeholder.postalCode": "94103",
"invoice.form.placeholder.stateOrProvince": "CA",
"invoice.form.postalCode": "Postal code",
"invoice.form.stateOrProvince": "State / Province",
"invoice.form.submit": "अनुरोध सबमिट करें",
"invoice.form.terms": "I agree to LangGenius, Inc.'s <terms>Terms of Service</terms> and <privacy>Privacy Policy</privacy>. I understand that renewal invoices will be sent automatically each billing cycle until I cancel, and payment must be completed manually each time. International wire transfer fees are my responsibility.",
"invoice.form.termsRequired": "Please agree to the invoice payment terms before submitting.",
"invoice.form.title": "Billing information",
"invoice.lockedTip": "An invoice payment flow is already active for this workspace.",
"invoice.payByInvoice": "इनवॉइस से भुगतान करें",
"invoice.permissionDeniedTooltip": "Only the team owner and admins can manage subscriptions and billing.",
"invoice.requestReceived.description": "Your invoice will be sent to <email>{{email}}</email> within <day>1 business day</day>.",
"invoice.requestReceived.goToBilling": "Go to Billing",
"invoice.requestReceived.renewalTip": "After your first payment, new invoices are sent automatically before each billing cycle. You need to complete payment manually each time. Cancel anytime from your Billing page.",
"invoice.requestReceived.statusTip": "You can track the status from your Billing page. Once you receive the invoice, complete payment using your preferred method on the invoice page.",
"invoice.requestReceived.title": "अनुरोध प्राप्त हुआ",
"invoice.status.awaitingPayment": "Awaiting payment",
"invoice.status.confirmingPayment": "Confirming payment",
"invoice.status.paymentOverdue": "Payment overdue",
"invoice.status.processing": "Processing",
"invoice.summary.billingCycle": "Billing cycle",
"invoice.summary.month": "मासिक",
"invoice.summary.saveAnnual": "SAVE {{percent}}%",
"invoice.summary.subtitle": "Pay by invoice",
"invoice.summary.title": "Subscription Plan",
"invoice.summary.year": "वार्षिक",
"plans.community.btnText": "समुदाय के साथ आरंभ करें",
"plans.community.description": "व्यक्तिगत उपयोगकर्ताओं, छोटे टीमों, या गैर-व्यावसायिक परियोजनाओं के लिए",
"plans.community.features": [
+39
View File
@@ -9,6 +9,45 @@
"apps.fullTip2des": "Disarankan untuk membersihkan aplikasi yang tidak aktif untuk mengosongkan penggunaan, atau hubungi kami.",
"buyPermissionDeniedTip": "Hubungi administrator perusahaan Anda untuk berlangganan",
"currentPlan": "Rencana Saat Ini",
"invoice.form.addressLine1": "Address line 1",
"invoice.form.addressLine2": "Address line 2 (optional)",
"invoice.form.city": "City",
"invoice.form.companyName": "Company name",
"invoice.form.country": "Country",
"invoice.form.description": "This information will appear on your invoice. Please ensure accuracy.",
"invoice.form.invoiceEmail": "Invoice recipient email",
"invoice.form.placeholder.addressLine1": "123 Main Street",
"invoice.form.placeholder.addressLine2": "Suite 400",
"invoice.form.placeholder.city": "San Francisco",
"invoice.form.placeholder.companyName": "Acme Inc.",
"invoice.form.placeholder.country": "Select a country",
"invoice.form.placeholder.invoiceEmail": "finance@example.com",
"invoice.form.placeholder.postalCode": "94103",
"invoice.form.placeholder.stateOrProvince": "CA",
"invoice.form.postalCode": "Postal code",
"invoice.form.stateOrProvince": "State / Province",
"invoice.form.submit": "Kirim permintaan",
"invoice.form.terms": "I agree to LangGenius, Inc.'s <terms>Terms of Service</terms> and <privacy>Privacy Policy</privacy>. I understand that renewal invoices will be sent automatically each billing cycle until I cancel, and payment must be completed manually each time. International wire transfer fees are my responsibility.",
"invoice.form.termsRequired": "Please agree to the invoice payment terms before submitting.",
"invoice.form.title": "Billing information",
"invoice.lockedTip": "An invoice payment flow is already active for this workspace.",
"invoice.payByInvoice": "Bayar dengan faktur",
"invoice.permissionDeniedTooltip": "Only the team owner and admins can manage subscriptions and billing.",
"invoice.requestReceived.description": "Your invoice will be sent to <email>{{email}}</email> within <day>1 business day</day>.",
"invoice.requestReceived.goToBilling": "Go to Billing",
"invoice.requestReceived.renewalTip": "After your first payment, new invoices are sent automatically before each billing cycle. You need to complete payment manually each time. Cancel anytime from your Billing page.",
"invoice.requestReceived.statusTip": "You can track the status from your Billing page. Once you receive the invoice, complete payment using your preferred method on the invoice page.",
"invoice.requestReceived.title": "Permintaan diterima",
"invoice.status.awaitingPayment": "Awaiting payment",
"invoice.status.confirmingPayment": "Confirming payment",
"invoice.status.paymentOverdue": "Payment overdue",
"invoice.status.processing": "Processing",
"invoice.summary.billingCycle": "Billing cycle",
"invoice.summary.month": "Bulanan",
"invoice.summary.saveAnnual": "SAVE {{percent}}%",
"invoice.summary.subtitle": "Pay by invoice",
"invoice.summary.title": "Subscription Plan",
"invoice.summary.year": "Tahunan",
"plans.community.btnText": "Mulai dengan Komunitas",
"plans.community.description": "Untuk Pengguna Individu, Tim Kecil, atau Proyek Non-Komersial",
"plans.community.features": [
+39
View File
@@ -9,6 +9,45 @@
"apps.fullTip2des": "Si consiglia di disinstallare le applicazioni inattive per liberare spazio, o contattarci.",
"buyPermissionDeniedTip": "Contatta l'amministratore della tua azienda per abbonarti",
"currentPlan": "Piano Attuale",
"invoice.form.addressLine1": "Indirizzo riga 1",
"invoice.form.addressLine2": "Indirizzo riga 2 (opzionale)",
"invoice.form.city": "Città",
"invoice.form.companyName": "Nome azienda",
"invoice.form.country": "Paese",
"invoice.form.description": "Queste informazioni appariranno sulla fattura. Verificane laccuratezza.",
"invoice.form.invoiceEmail": "Email destinatario fattura",
"invoice.form.placeholder.addressLine1": "123 Main Street",
"invoice.form.placeholder.addressLine2": "Suite 400",
"invoice.form.placeholder.city": "San Francisco",
"invoice.form.placeholder.companyName": "Acme Inc.",
"invoice.form.placeholder.country": "Select a country",
"invoice.form.placeholder.invoiceEmail": "finance@example.com",
"invoice.form.placeholder.postalCode": "94103",
"invoice.form.placeholder.stateOrProvince": "CA",
"invoice.form.postalCode": "Codice postale",
"invoice.form.stateOrProvince": "Stato / Provincia",
"invoice.form.submit": "Invia richiesta",
"invoice.form.terms": "Accetto i <terms>Termini di servizio</terms> e l<privacy>Informativa sulla privacy</privacy> di LangGenius, Inc. Comprendo che le fatture di rinnovo saranno inviate automaticamente a ogni ciclo fino allannullamento e che ogni pagamento deve essere completato manualmente. Le commissioni per bonifici internazionali sono a mio carico.",
"invoice.form.termsRequired": "Accetta i termini di pagamento tramite fattura prima di inviare.",
"invoice.form.title": "Informazioni di fatturazione",
"invoice.lockedTip": "Per questo workspace è già attivo un flusso di pagamento tramite fattura.",
"invoice.payByInvoice": "Paga tramite fattura",
"invoice.permissionDeniedTooltip": "Solo il proprietario e gli amministratori del team possono gestire abbonamenti e fatturazione.",
"invoice.requestReceived.description": "Your invoice will be sent to <email>{{email}}</email> within <day>1 business day</day>.",
"invoice.requestReceived.goToBilling": "Go to Billing",
"invoice.requestReceived.renewalTip": "After your first payment, new invoices are sent automatically before each billing cycle. You need to complete payment manually each time. Cancel anytime from your Billing page.",
"invoice.requestReceived.statusTip": "You can track the status from your Billing page. Once you receive the invoice, complete payment using your preferred method on the invoice page.",
"invoice.requestReceived.title": "Richiesta ricevuta",
"invoice.status.awaitingPayment": "In attesa di pagamento",
"invoice.status.confirmingPayment": "Conferma del pagamento",
"invoice.status.paymentOverdue": "Pagamento scaduto",
"invoice.status.processing": "In elaborazione",
"invoice.summary.billingCycle": "Billing cycle",
"invoice.summary.month": "Mensile",
"invoice.summary.saveAnnual": "SAVE {{percent}}%",
"invoice.summary.subtitle": "Pay by invoice",
"invoice.summary.title": "Subscription Plan",
"invoice.summary.year": "Annuale",
"plans.community.btnText": "Inizia con la comunità",
"plans.community.description": "Per utenti individuali, piccole squadre o progetti non commerciali",
"plans.community.features": [
+39
View File
@@ -9,6 +9,45 @@
"apps.fullTip2des": "非アクティブなアプリを削除するか、アップグレードプランをご検討ください。",
"buyPermissionDeniedTip": "サブスクリプションするには、エンタープライズ管理者に連絡してください",
"currentPlan": "現在のプラン",
"invoice.form.addressLine1": "住所 1",
"invoice.form.addressLine2": "住所 2(任意)",
"invoice.form.city": "市区町村",
"invoice.form.companyName": "会社名",
"invoice.form.country": "国 / 地域",
"invoice.form.description": "この情報は請求書に記載されます。正確であることをご確認ください。",
"invoice.form.invoiceEmail": "請求書の送付先メールアドレス",
"invoice.form.placeholder.addressLine1": "123 Main Street",
"invoice.form.placeholder.addressLine2": "Suite 400",
"invoice.form.placeholder.city": "San Francisco",
"invoice.form.placeholder.companyName": "Acme Inc.",
"invoice.form.placeholder.country": "国を選択",
"invoice.form.placeholder.invoiceEmail": "finance@example.com",
"invoice.form.placeholder.postalCode": "94103",
"invoice.form.placeholder.stateOrProvince": "CA",
"invoice.form.postalCode": "郵便番号",
"invoice.form.stateOrProvince": "都道府県 / 州",
"invoice.form.submit": "申請を送信",
"invoice.form.terms": "LangGenius, Inc. の<terms>利用規約</terms>および<privacy>プライバシーポリシー</privacy>に同意します。キャンセルするまで、各請求サイクルで更新請求書が自動送信され、毎回手動で支払いを完了する必要があることを理解しています。国際電信送金の手数料は私の負担となります。",
"invoice.form.termsRequired": "送信前に請求書払いの条件に同意してください。",
"invoice.form.title": "請求先情報",
"invoice.lockedTip": "このワークスペースでは請求書払いの処理がすでに進行中です。",
"invoice.payByInvoice": "請求書払い",
"invoice.permissionDeniedTooltip": "チームオーナーと管理者のみがサブスクリプションと請求を管理できます。",
"invoice.requestReceived.description": "Your invoice will be sent to <email>{{email}}</email> within <day>1 business day</day>.",
"invoice.requestReceived.goToBilling": "Go to Billing",
"invoice.requestReceived.renewalTip": "After your first payment, new invoices are sent automatically before each billing cycle. You need to complete payment manually each time. Cancel anytime from your Billing page.",
"invoice.requestReceived.statusTip": "You can track the status from your Billing page. Once you receive the invoice, complete payment using your preferred method on the invoice page.",
"invoice.requestReceived.title": "申請を受け付けました",
"invoice.status.awaitingPayment": "お振込みお待ち中",
"invoice.status.confirmingPayment": "入金確認中",
"invoice.status.paymentOverdue": "お支払い期限切れ",
"invoice.status.processing": "申請処理中",
"invoice.summary.billingCycle": "請求サイクル",
"invoice.summary.month": "月額",
"invoice.summary.saveAnnual": "{{percent}}% OFF",
"invoice.summary.subtitle": "請求書払い",
"invoice.summary.title": "サブスクリプションプラン",
"invoice.summary.year": "年額",
"plans.community.btnText": "コミュニティ版を始めましょう",
"plans.community.description": "オープンソース版の無料プラン",
"plans.community.features": [
+39
View File
@@ -9,6 +9,45 @@
"apps.fullTip2des": "비활성 애플리케이션을 정리하여 사용량을 줄이거나 저희에게 문의하는 것이 좋습니다.",
"buyPermissionDeniedTip": "구독하려면 엔터프라이즈 관리자에게 문의하세요",
"currentPlan": "현재 요금제",
"invoice.form.addressLine1": "Address line 1",
"invoice.form.addressLine2": "Address line 2 (optional)",
"invoice.form.city": "City",
"invoice.form.companyName": "Company name",
"invoice.form.country": "Country",
"invoice.form.description": "This information will appear on your invoice. Please ensure accuracy.",
"invoice.form.invoiceEmail": "Invoice recipient email",
"invoice.form.placeholder.addressLine1": "123 Main Street",
"invoice.form.placeholder.addressLine2": "Suite 400",
"invoice.form.placeholder.city": "San Francisco",
"invoice.form.placeholder.companyName": "Acme Inc.",
"invoice.form.placeholder.country": "Select a country",
"invoice.form.placeholder.invoiceEmail": "finance@example.com",
"invoice.form.placeholder.postalCode": "94103",
"invoice.form.placeholder.stateOrProvince": "CA",
"invoice.form.postalCode": "Postal code",
"invoice.form.stateOrProvince": "State / Province",
"invoice.form.submit": "요청 제출",
"invoice.form.terms": "I agree to LangGenius, Inc.'s <terms>Terms of Service</terms> and <privacy>Privacy Policy</privacy>. I understand that renewal invoices will be sent automatically each billing cycle until I cancel, and payment must be completed manually each time. International wire transfer fees are my responsibility.",
"invoice.form.termsRequired": "Please agree to the invoice payment terms before submitting.",
"invoice.form.title": "Billing information",
"invoice.lockedTip": "An invoice payment flow is already active for this workspace.",
"invoice.payByInvoice": "인보이스로 결제",
"invoice.permissionDeniedTooltip": "Only the team owner and admins can manage subscriptions and billing.",
"invoice.requestReceived.description": "Your invoice will be sent to <email>{{email}}</email> within <day>1 business day</day>.",
"invoice.requestReceived.goToBilling": "Go to Billing",
"invoice.requestReceived.renewalTip": "After your first payment, new invoices are sent automatically before each billing cycle. You need to complete payment manually each time. Cancel anytime from your Billing page.",
"invoice.requestReceived.statusTip": "You can track the status from your Billing page. Once you receive the invoice, complete payment using your preferred method on the invoice page.",
"invoice.requestReceived.title": "요청이 접수되었습니다",
"invoice.status.awaitingPayment": "Awaiting payment",
"invoice.status.confirmingPayment": "Confirming payment",
"invoice.status.paymentOverdue": "Payment overdue",
"invoice.status.processing": "Processing",
"invoice.summary.billingCycle": "Billing cycle",
"invoice.summary.month": "월간",
"invoice.summary.saveAnnual": "SAVE {{percent}}%",
"invoice.summary.subtitle": "Pay by invoice",
"invoice.summary.title": "Subscription Plan",
"invoice.summary.year": "연간",
"plans.community.btnText": "커뮤니티 시작하기",
"plans.community.description": "개인 사용자, 소규모 팀 또는 비상업적 프로젝트를 위한",
"plans.community.features": [
+39
View File
@@ -9,6 +9,45 @@
"apps.fullTip2des": "It is recommended to clean up inactive applications to free up usage, or contact us.",
"buyPermissionDeniedTip": "Please contact your enterprise administrator to subscribe",
"currentPlan": "Current Plan",
"invoice.form.addressLine1": "Address line 1",
"invoice.form.addressLine2": "Address line 2 (optional)",
"invoice.form.city": "City",
"invoice.form.companyName": "Company name",
"invoice.form.country": "Country",
"invoice.form.description": "This information will appear on your invoice. Please ensure accuracy.",
"invoice.form.invoiceEmail": "Invoice recipient email",
"invoice.form.placeholder.addressLine1": "123 Main Street",
"invoice.form.placeholder.addressLine2": "Suite 400",
"invoice.form.placeholder.city": "San Francisco",
"invoice.form.placeholder.companyName": "Acme Inc.",
"invoice.form.placeholder.country": "Select a country",
"invoice.form.placeholder.invoiceEmail": "finance@example.com",
"invoice.form.placeholder.postalCode": "94103",
"invoice.form.placeholder.stateOrProvince": "CA",
"invoice.form.postalCode": "Postal code",
"invoice.form.stateOrProvince": "State / Province",
"invoice.form.submit": "Verzoek indienen",
"invoice.form.terms": "I agree to LangGenius, Inc.'s <terms>Terms of Service</terms> and <privacy>Privacy Policy</privacy>. I understand that renewal invoices will be sent automatically each billing cycle until I cancel, and payment must be completed manually each time. International wire transfer fees are my responsibility.",
"invoice.form.termsRequired": "Please agree to the invoice payment terms before submitting.",
"invoice.form.title": "Billing information",
"invoice.lockedTip": "An invoice payment flow is already active for this workspace.",
"invoice.payByInvoice": "Betalen per factuur",
"invoice.permissionDeniedTooltip": "Only the team owner and admins can manage subscriptions and billing.",
"invoice.requestReceived.description": "Your invoice will be sent to <email>{{email}}</email> within <day>1 business day</day>.",
"invoice.requestReceived.goToBilling": "Go to Billing",
"invoice.requestReceived.renewalTip": "After your first payment, new invoices are sent automatically before each billing cycle. You need to complete payment manually each time. Cancel anytime from your Billing page.",
"invoice.requestReceived.statusTip": "You can track the status from your Billing page. Once you receive the invoice, complete payment using your preferred method on the invoice page.",
"invoice.requestReceived.title": "Verzoek ontvangen",
"invoice.status.awaitingPayment": "Awaiting payment",
"invoice.status.confirmingPayment": "Confirming payment",
"invoice.status.paymentOverdue": "Payment overdue",
"invoice.status.processing": "Processing",
"invoice.summary.billingCycle": "Billing cycle",
"invoice.summary.month": "Monthly",
"invoice.summary.saveAnnual": "SAVE {{percent}}%",
"invoice.summary.subtitle": "Pay by invoice",
"invoice.summary.title": "Subscription Plan",
"invoice.summary.year": "Yearly",
"plans.community.btnText": "Get Started",
"plans.community.description": "For open-source enthusiasts, individual developers, and non-commercial projects",
"plans.community.features": [
+39
View File
@@ -9,6 +9,45 @@
"apps.fullTip2des": "Zaleca się usunięcie nieaktywnych aplikacji, aby zwolnić miejsce, lub skontaktowanie się z nami.",
"buyPermissionDeniedTip": "Skontaktuj się z administratorem swojej firmy, aby zasubskrybować",
"currentPlan": "Obecny plan",
"invoice.form.addressLine1": "Address line 1",
"invoice.form.addressLine2": "Address line 2 (optional)",
"invoice.form.city": "City",
"invoice.form.companyName": "Company name",
"invoice.form.country": "Country",
"invoice.form.description": "This information will appear on your invoice. Please ensure accuracy.",
"invoice.form.invoiceEmail": "Invoice recipient email",
"invoice.form.placeholder.addressLine1": "123 Main Street",
"invoice.form.placeholder.addressLine2": "Suite 400",
"invoice.form.placeholder.city": "San Francisco",
"invoice.form.placeholder.companyName": "Acme Inc.",
"invoice.form.placeholder.country": "Select a country",
"invoice.form.placeholder.invoiceEmail": "finance@example.com",
"invoice.form.placeholder.postalCode": "94103",
"invoice.form.placeholder.stateOrProvince": "CA",
"invoice.form.postalCode": "Postal code",
"invoice.form.stateOrProvince": "State / Province",
"invoice.form.submit": "Prześlij wniosek",
"invoice.form.terms": "I agree to LangGenius, Inc.'s <terms>Terms of Service</terms> and <privacy>Privacy Policy</privacy>. I understand that renewal invoices will be sent automatically each billing cycle until I cancel, and payment must be completed manually each time. International wire transfer fees are my responsibility.",
"invoice.form.termsRequired": "Please agree to the invoice payment terms before submitting.",
"invoice.form.title": "Billing information",
"invoice.lockedTip": "An invoice payment flow is already active for this workspace.",
"invoice.payByInvoice": "Zapłać fakturą",
"invoice.permissionDeniedTooltip": "Only the team owner and admins can manage subscriptions and billing.",
"invoice.requestReceived.description": "Your invoice will be sent to <email>{{email}}</email> within <day>1 business day</day>.",
"invoice.requestReceived.goToBilling": "Go to Billing",
"invoice.requestReceived.renewalTip": "After your first payment, new invoices are sent automatically before each billing cycle. You need to complete payment manually each time. Cancel anytime from your Billing page.",
"invoice.requestReceived.statusTip": "You can track the status from your Billing page. Once you receive the invoice, complete payment using your preferred method on the invoice page.",
"invoice.requestReceived.title": "Otrzymano wniosek",
"invoice.status.awaitingPayment": "Awaiting payment",
"invoice.status.confirmingPayment": "Confirming payment",
"invoice.status.paymentOverdue": "Payment overdue",
"invoice.status.processing": "Processing",
"invoice.summary.billingCycle": "Billing cycle",
"invoice.summary.month": "Miesięczny",
"invoice.summary.saveAnnual": "SAVE {{percent}}%",
"invoice.summary.subtitle": "Pay by invoice",
"invoice.summary.title": "Subscription Plan",
"invoice.summary.year": "Roczny",
"plans.community.btnText": "Rozpocznij pracę z społecznością",
"plans.community.description": "Dla użytkowników indywidualnych, małych zespołów lub projektów niekomercyjnych",
"plans.community.features": [
+39
View File
@@ -9,6 +9,45 @@
"apps.fullTip2des": "É recomendado limpar aplicações inativas para liberar uso ou entrar em contato conosco.",
"buyPermissionDeniedTip": "Por favor, entre em contato com o administrador da sua empresa para assinar",
"currentPlan": "Plano Atual",
"invoice.form.addressLine1": "Endereço linha 1",
"invoice.form.addressLine2": "Endereço linha 2 (opcional)",
"invoice.form.city": "Cidade",
"invoice.form.companyName": "Nome da empresa",
"invoice.form.country": "País",
"invoice.form.description": "Essas informações aparecerão na sua invoice. Verifique se estão corretas.",
"invoice.form.invoiceEmail": "E-mail do destinatário da invoice",
"invoice.form.placeholder.addressLine1": "123 Main Street",
"invoice.form.placeholder.addressLine2": "Suite 400",
"invoice.form.placeholder.city": "San Francisco",
"invoice.form.placeholder.companyName": "Acme Inc.",
"invoice.form.placeholder.country": "Select a country",
"invoice.form.placeholder.invoiceEmail": "finance@example.com",
"invoice.form.placeholder.postalCode": "94103",
"invoice.form.placeholder.stateOrProvince": "CA",
"invoice.form.postalCode": "Código postal",
"invoice.form.stateOrProvince": "Estado / Província",
"invoice.form.submit": "Enviar solicitação",
"invoice.form.terms": "Aceito os <terms>Termos de Serviço</terms> e a <privacy>Política de Privacidade</privacy> da LangGenius, Inc. Entendo que invoices de renovação serão enviadas automaticamente a cada ciclo até o cancelamento e que cada pagamento deve ser concluído manualmente. Taxas de transferência internacional são de minha responsabilidade.",
"invoice.form.termsRequired": "Aceite os termos de pagamento por invoice antes de enviar.",
"invoice.form.title": "Informações de faturamento",
"invoice.lockedTip": "Já existe um fluxo de pagamento por invoice ativo para este workspace.",
"invoice.payByInvoice": "Pagar por invoice",
"invoice.permissionDeniedTooltip": "Somente o proprietário e os administradores da equipe podem gerenciar assinaturas e faturamento.",
"invoice.requestReceived.description": "Your invoice will be sent to <email>{{email}}</email> within <day>1 business day</day>.",
"invoice.requestReceived.goToBilling": "Go to Billing",
"invoice.requestReceived.renewalTip": "After your first payment, new invoices are sent automatically before each billing cycle. You need to complete payment manually each time. Cancel anytime from your Billing page.",
"invoice.requestReceived.statusTip": "You can track the status from your Billing page. Once you receive the invoice, complete payment using your preferred method on the invoice page.",
"invoice.requestReceived.title": "Solicitação recebida",
"invoice.status.awaitingPayment": "Aguardando pagamento",
"invoice.status.confirmingPayment": "Confirmando pagamento",
"invoice.status.paymentOverdue": "Pagamento vencido",
"invoice.status.processing": "Processando",
"invoice.summary.billingCycle": "Billing cycle",
"invoice.summary.month": "Mensalmente",
"invoice.summary.saveAnnual": "SAVE {{percent}}%",
"invoice.summary.subtitle": "Pay by invoice",
"invoice.summary.title": "Subscription Plan",
"invoice.summary.year": "Anualmente",
"plans.community.btnText": "Comece com a Comunidade",
"plans.community.description": "Para Usuários Individuais, Pequenas Equipes ou Projetos Não Comerciais",
"plans.community.features": [
+39
View File
@@ -9,6 +9,45 @@
"apps.fullTip2des": "Se recomandă curățarea aplicațiilor inactive pentru a elibera resurse, sau contactați-ne.",
"buyPermissionDeniedTip": "Vă rugăm să contactați administratorul dvs. de întreprindere pentru a vă abona",
"currentPlan": "Planul curent",
"invoice.form.addressLine1": "Address line 1",
"invoice.form.addressLine2": "Address line 2 (optional)",
"invoice.form.city": "City",
"invoice.form.companyName": "Company name",
"invoice.form.country": "Country",
"invoice.form.description": "This information will appear on your invoice. Please ensure accuracy.",
"invoice.form.invoiceEmail": "Invoice recipient email",
"invoice.form.placeholder.addressLine1": "123 Main Street",
"invoice.form.placeholder.addressLine2": "Suite 400",
"invoice.form.placeholder.city": "San Francisco",
"invoice.form.placeholder.companyName": "Acme Inc.",
"invoice.form.placeholder.country": "Select a country",
"invoice.form.placeholder.invoiceEmail": "finance@example.com",
"invoice.form.placeholder.postalCode": "94103",
"invoice.form.placeholder.stateOrProvince": "CA",
"invoice.form.postalCode": "Postal code",
"invoice.form.stateOrProvince": "State / Province",
"invoice.form.submit": "Trimite solicitarea",
"invoice.form.terms": "I agree to LangGenius, Inc.'s <terms>Terms of Service</terms> and <privacy>Privacy Policy</privacy>. I understand that renewal invoices will be sent automatically each billing cycle until I cancel, and payment must be completed manually each time. International wire transfer fees are my responsibility.",
"invoice.form.termsRequired": "Please agree to the invoice payment terms before submitting.",
"invoice.form.title": "Billing information",
"invoice.lockedTip": "An invoice payment flow is already active for this workspace.",
"invoice.payByInvoice": "Plătește prin factură",
"invoice.permissionDeniedTooltip": "Only the team owner and admins can manage subscriptions and billing.",
"invoice.requestReceived.description": "Your invoice will be sent to <email>{{email}}</email> within <day>1 business day</day>.",
"invoice.requestReceived.goToBilling": "Go to Billing",
"invoice.requestReceived.renewalTip": "After your first payment, new invoices are sent automatically before each billing cycle. You need to complete payment manually each time. Cancel anytime from your Billing page.",
"invoice.requestReceived.statusTip": "You can track the status from your Billing page. Once you receive the invoice, complete payment using your preferred method on the invoice page.",
"invoice.requestReceived.title": "Solicitare primită",
"invoice.status.awaitingPayment": "Awaiting payment",
"invoice.status.confirmingPayment": "Confirming payment",
"invoice.status.paymentOverdue": "Payment overdue",
"invoice.status.processing": "Processing",
"invoice.summary.billingCycle": "Billing cycle",
"invoice.summary.month": "Lunar",
"invoice.summary.saveAnnual": "SAVE {{percent}}%",
"invoice.summary.subtitle": "Pay by invoice",
"invoice.summary.title": "Subscription Plan",
"invoice.summary.year": "Anual",
"plans.community.btnText": "Începe cu Comunitatea",
"plans.community.description": "Pentru utilizatori individuali, echipe mici sau proiecte necomerciale",
"plans.community.features": [
+39
View File
@@ -9,6 +9,45 @@
"apps.fullTip2des": "Рекомендуется удалить неактивные приложения, чтобы освободить место, или свяжитесь с нами.",
"buyPermissionDeniedTip": "Пожалуйста, свяжитесь с администратором вашей организации, чтобы подписаться",
"currentPlan": "Текущий тарифный план",
"invoice.form.addressLine1": "Address line 1",
"invoice.form.addressLine2": "Address line 2 (optional)",
"invoice.form.city": "City",
"invoice.form.companyName": "Company name",
"invoice.form.country": "Country",
"invoice.form.description": "This information will appear on your invoice. Please ensure accuracy.",
"invoice.form.invoiceEmail": "Invoice recipient email",
"invoice.form.placeholder.addressLine1": "123 Main Street",
"invoice.form.placeholder.addressLine2": "Suite 400",
"invoice.form.placeholder.city": "San Francisco",
"invoice.form.placeholder.companyName": "Acme Inc.",
"invoice.form.placeholder.country": "Select a country",
"invoice.form.placeholder.invoiceEmail": "finance@example.com",
"invoice.form.placeholder.postalCode": "94103",
"invoice.form.placeholder.stateOrProvince": "CA",
"invoice.form.postalCode": "Postal code",
"invoice.form.stateOrProvince": "State / Province",
"invoice.form.submit": "Отправить запрос",
"invoice.form.terms": "I agree to LangGenius, Inc.'s <terms>Terms of Service</terms> and <privacy>Privacy Policy</privacy>. I understand that renewal invoices will be sent automatically each billing cycle until I cancel, and payment must be completed manually each time. International wire transfer fees are my responsibility.",
"invoice.form.termsRequired": "Please agree to the invoice payment terms before submitting.",
"invoice.form.title": "Billing information",
"invoice.lockedTip": "An invoice payment flow is already active for this workspace.",
"invoice.payByInvoice": "Оплатить по счету",
"invoice.permissionDeniedTooltip": "Only the team owner and admins can manage subscriptions and billing.",
"invoice.requestReceived.description": "Your invoice will be sent to <email>{{email}}</email> within <day>1 business day</day>.",
"invoice.requestReceived.goToBilling": "Go to Billing",
"invoice.requestReceived.renewalTip": "After your first payment, new invoices are sent automatically before each billing cycle. You need to complete payment manually each time. Cancel anytime from your Billing page.",
"invoice.requestReceived.statusTip": "You can track the status from your Billing page. Once you receive the invoice, complete payment using your preferred method on the invoice page.",
"invoice.requestReceived.title": "Запрос получен",
"invoice.status.awaitingPayment": "Awaiting payment",
"invoice.status.confirmingPayment": "Confirming payment",
"invoice.status.paymentOverdue": "Payment overdue",
"invoice.status.processing": "Processing",
"invoice.summary.billingCycle": "Billing cycle",
"invoice.summary.month": "Ежемесячно",
"invoice.summary.saveAnnual": "SAVE {{percent}}%",
"invoice.summary.subtitle": "Pay by invoice",
"invoice.summary.title": "Subscription Plan",
"invoice.summary.year": "Ежегодно",
"plans.community.btnText": "Начните с сообщества",
"plans.community.description": "Для отдельных пользователей, малых команд или некоммерческих проектов",
"plans.community.features": [
+39
View File
@@ -9,6 +9,45 @@
"apps.fullTip2des": "Priporočljivo je, da očistite neaktivne aplikacije, da sprostite prostor, ali nas kontaktirate.",
"buyPermissionDeniedTip": "Za naročnino kontaktirajte svojega skrbnika podjetja",
"currentPlan": "Trenutni načrt",
"invoice.form.addressLine1": "Address line 1",
"invoice.form.addressLine2": "Address line 2 (optional)",
"invoice.form.city": "City",
"invoice.form.companyName": "Company name",
"invoice.form.country": "Country",
"invoice.form.description": "This information will appear on your invoice. Please ensure accuracy.",
"invoice.form.invoiceEmail": "Invoice recipient email",
"invoice.form.placeholder.addressLine1": "123 Main Street",
"invoice.form.placeholder.addressLine2": "Suite 400",
"invoice.form.placeholder.city": "San Francisco",
"invoice.form.placeholder.companyName": "Acme Inc.",
"invoice.form.placeholder.country": "Select a country",
"invoice.form.placeholder.invoiceEmail": "finance@example.com",
"invoice.form.placeholder.postalCode": "94103",
"invoice.form.placeholder.stateOrProvince": "CA",
"invoice.form.postalCode": "Postal code",
"invoice.form.stateOrProvince": "State / Province",
"invoice.form.submit": "Pošlji zahtevo",
"invoice.form.terms": "I agree to LangGenius, Inc.'s <terms>Terms of Service</terms> and <privacy>Privacy Policy</privacy>. I understand that renewal invoices will be sent automatically each billing cycle until I cancel, and payment must be completed manually each time. International wire transfer fees are my responsibility.",
"invoice.form.termsRequired": "Please agree to the invoice payment terms before submitting.",
"invoice.form.title": "Billing information",
"invoice.lockedTip": "An invoice payment flow is already active for this workspace.",
"invoice.payByInvoice": "Plačilo po računu",
"invoice.permissionDeniedTooltip": "Only the team owner and admins can manage subscriptions and billing.",
"invoice.requestReceived.description": "Your invoice will be sent to <email>{{email}}</email> within <day>1 business day</day>.",
"invoice.requestReceived.goToBilling": "Go to Billing",
"invoice.requestReceived.renewalTip": "After your first payment, new invoices are sent automatically before each billing cycle. You need to complete payment manually each time. Cancel anytime from your Billing page.",
"invoice.requestReceived.statusTip": "You can track the status from your Billing page. Once you receive the invoice, complete payment using your preferred method on the invoice page.",
"invoice.requestReceived.title": "Zahteva prejeta",
"invoice.status.awaitingPayment": "Awaiting payment",
"invoice.status.confirmingPayment": "Confirming payment",
"invoice.status.paymentOverdue": "Payment overdue",
"invoice.status.processing": "Processing",
"invoice.summary.billingCycle": "Billing cycle",
"invoice.summary.month": "Mesečno",
"invoice.summary.saveAnnual": "SAVE {{percent}}%",
"invoice.summary.subtitle": "Pay by invoice",
"invoice.summary.title": "Subscription Plan",
"invoice.summary.year": "Letno",
"plans.community.btnText": "Začnite s skupnostjo",
"plans.community.description": "Za posamezne uporabnike, majhne skupine ali nekomercialne projekte",
"plans.community.features": [
+39
View File
@@ -9,6 +9,45 @@
"apps.fullTip2des": "แนะนำให้ทำความสะอาดแอปพลิเคชันที่ไม่ใช้งานเพื่อเพิ่มการใช้งาน หรือติดต่อเรา",
"buyPermissionDeniedTip": "โปรดติดต่อผู้ดูแลระบบองค์กรของคุณเพื่อสมัครสมาชิก",
"currentPlan": "แผนปัจจุบัน",
"invoice.form.addressLine1": "Address line 1",
"invoice.form.addressLine2": "Address line 2 (optional)",
"invoice.form.city": "City",
"invoice.form.companyName": "Company name",
"invoice.form.country": "Country",
"invoice.form.description": "This information will appear on your invoice. Please ensure accuracy.",
"invoice.form.invoiceEmail": "Invoice recipient email",
"invoice.form.placeholder.addressLine1": "123 Main Street",
"invoice.form.placeholder.addressLine2": "Suite 400",
"invoice.form.placeholder.city": "San Francisco",
"invoice.form.placeholder.companyName": "Acme Inc.",
"invoice.form.placeholder.country": "Select a country",
"invoice.form.placeholder.invoiceEmail": "finance@example.com",
"invoice.form.placeholder.postalCode": "94103",
"invoice.form.placeholder.stateOrProvince": "CA",
"invoice.form.postalCode": "Postal code",
"invoice.form.stateOrProvince": "State / Province",
"invoice.form.submit": "ส่งคำขอ",
"invoice.form.terms": "I agree to LangGenius, Inc.'s <terms>Terms of Service</terms> and <privacy>Privacy Policy</privacy>. I understand that renewal invoices will be sent automatically each billing cycle until I cancel, and payment must be completed manually each time. International wire transfer fees are my responsibility.",
"invoice.form.termsRequired": "Please agree to the invoice payment terms before submitting.",
"invoice.form.title": "Billing information",
"invoice.lockedTip": "An invoice payment flow is already active for this workspace.",
"invoice.payByInvoice": "ชำระเงินด้วยใบแจ้งหนี้",
"invoice.permissionDeniedTooltip": "Only the team owner and admins can manage subscriptions and billing.",
"invoice.requestReceived.description": "Your invoice will be sent to <email>{{email}}</email> within <day>1 business day</day>.",
"invoice.requestReceived.goToBilling": "Go to Billing",
"invoice.requestReceived.renewalTip": "After your first payment, new invoices are sent automatically before each billing cycle. You need to complete payment manually each time. Cancel anytime from your Billing page.",
"invoice.requestReceived.statusTip": "You can track the status from your Billing page. Once you receive the invoice, complete payment using your preferred method on the invoice page.",
"invoice.requestReceived.title": "ได้รับคำขอแล้ว",
"invoice.status.awaitingPayment": "Awaiting payment",
"invoice.status.confirmingPayment": "Confirming payment",
"invoice.status.paymentOverdue": "Payment overdue",
"invoice.status.processing": "Processing",
"invoice.summary.billingCycle": "Billing cycle",
"invoice.summary.month": "รายเดือน",
"invoice.summary.saveAnnual": "SAVE {{percent}}%",
"invoice.summary.subtitle": "Pay by invoice",
"invoice.summary.title": "Subscription Plan",
"invoice.summary.year": "รายปี",
"plans.community.btnText": "เริ่มต้นกับชุมชน",
"plans.community.description": "สำหรับผู้ใช้ส่วนบุคคล ทีมขนาดเล็ก หรือโครงการที่ไม่ใช่เชิงพาณิชย์",
"plans.community.features": [
+39
View File
@@ -9,6 +9,45 @@
"apps.fullTip2des": "Kullanımı serbest bırakmak için etkisiz uygulamaların temizlenmesi önerilir veya bizimle iletişime geçin.",
"buyPermissionDeniedTip": "Abone olmak için lütfen işletme yöneticinize başvurun",
"currentPlan": "Mevcut Plan",
"invoice.form.addressLine1": "Address line 1",
"invoice.form.addressLine2": "Address line 2 (optional)",
"invoice.form.city": "City",
"invoice.form.companyName": "Company name",
"invoice.form.country": "Country",
"invoice.form.description": "This information will appear on your invoice. Please ensure accuracy.",
"invoice.form.invoiceEmail": "Invoice recipient email",
"invoice.form.placeholder.addressLine1": "123 Main Street",
"invoice.form.placeholder.addressLine2": "Suite 400",
"invoice.form.placeholder.city": "San Francisco",
"invoice.form.placeholder.companyName": "Acme Inc.",
"invoice.form.placeholder.country": "Select a country",
"invoice.form.placeholder.invoiceEmail": "finance@example.com",
"invoice.form.placeholder.postalCode": "94103",
"invoice.form.placeholder.stateOrProvince": "CA",
"invoice.form.postalCode": "Postal code",
"invoice.form.stateOrProvince": "State / Province",
"invoice.form.submit": "Talep gönder",
"invoice.form.terms": "I agree to LangGenius, Inc.'s <terms>Terms of Service</terms> and <privacy>Privacy Policy</privacy>. I understand that renewal invoices will be sent automatically each billing cycle until I cancel, and payment must be completed manually each time. International wire transfer fees are my responsibility.",
"invoice.form.termsRequired": "Please agree to the invoice payment terms before submitting.",
"invoice.form.title": "Billing information",
"invoice.lockedTip": "An invoice payment flow is already active for this workspace.",
"invoice.payByInvoice": "Fatura ile öde",
"invoice.permissionDeniedTooltip": "Only the team owner and admins can manage subscriptions and billing.",
"invoice.requestReceived.description": "Your invoice will be sent to <email>{{email}}</email> within <day>1 business day</day>.",
"invoice.requestReceived.goToBilling": "Go to Billing",
"invoice.requestReceived.renewalTip": "After your first payment, new invoices are sent automatically before each billing cycle. You need to complete payment manually each time. Cancel anytime from your Billing page.",
"invoice.requestReceived.statusTip": "You can track the status from your Billing page. Once you receive the invoice, complete payment using your preferred method on the invoice page.",
"invoice.requestReceived.title": "Talep alındı",
"invoice.status.awaitingPayment": "Awaiting payment",
"invoice.status.confirmingPayment": "Confirming payment",
"invoice.status.paymentOverdue": "Payment overdue",
"invoice.status.processing": "Processing",
"invoice.summary.billingCycle": "Billing cycle",
"invoice.summary.month": "Aylık",
"invoice.summary.saveAnnual": "SAVE {{percent}}%",
"invoice.summary.subtitle": "Pay by invoice",
"invoice.summary.title": "Subscription Plan",
"invoice.summary.year": "Yıllık",
"plans.community.btnText": "Topluluğa Başlayın",
"plans.community.description": "Bireysel Kullanıcılar, Küçük Ekipler veya Ticari Olmayan Projeler İçin",
"plans.community.features": [
+39
View File
@@ -9,6 +9,45 @@
"apps.fullTip2des": "Рекомендується очистити неактивні програми, щоб звільнити місце, або зв'язатися з нами.",
"buyPermissionDeniedTip": "Зв'яжіться з адміністратором вашого підприємства, щоб оформити підписку",
"currentPlan": "Поточний план",
"invoice.form.addressLine1": "Address line 1",
"invoice.form.addressLine2": "Address line 2 (optional)",
"invoice.form.city": "City",
"invoice.form.companyName": "Company name",
"invoice.form.country": "Country",
"invoice.form.description": "This information will appear on your invoice. Please ensure accuracy.",
"invoice.form.invoiceEmail": "Invoice recipient email",
"invoice.form.placeholder.addressLine1": "123 Main Street",
"invoice.form.placeholder.addressLine2": "Suite 400",
"invoice.form.placeholder.city": "San Francisco",
"invoice.form.placeholder.companyName": "Acme Inc.",
"invoice.form.placeholder.country": "Select a country",
"invoice.form.placeholder.invoiceEmail": "finance@example.com",
"invoice.form.placeholder.postalCode": "94103",
"invoice.form.placeholder.stateOrProvince": "CA",
"invoice.form.postalCode": "Postal code",
"invoice.form.stateOrProvince": "State / Province",
"invoice.form.submit": "Надіслати запит",
"invoice.form.terms": "I agree to LangGenius, Inc.'s <terms>Terms of Service</terms> and <privacy>Privacy Policy</privacy>. I understand that renewal invoices will be sent automatically each billing cycle until I cancel, and payment must be completed manually each time. International wire transfer fees are my responsibility.",
"invoice.form.termsRequired": "Please agree to the invoice payment terms before submitting.",
"invoice.form.title": "Billing information",
"invoice.lockedTip": "An invoice payment flow is already active for this workspace.",
"invoice.payByInvoice": "Оплатити за рахунком",
"invoice.permissionDeniedTooltip": "Only the team owner and admins can manage subscriptions and billing.",
"invoice.requestReceived.description": "Your invoice will be sent to <email>{{email}}</email> within <day>1 business day</day>.",
"invoice.requestReceived.goToBilling": "Go to Billing",
"invoice.requestReceived.renewalTip": "After your first payment, new invoices are sent automatically before each billing cycle. You need to complete payment manually each time. Cancel anytime from your Billing page.",
"invoice.requestReceived.statusTip": "You can track the status from your Billing page. Once you receive the invoice, complete payment using your preferred method on the invoice page.",
"invoice.requestReceived.title": "Запит отримано",
"invoice.status.awaitingPayment": "Awaiting payment",
"invoice.status.confirmingPayment": "Confirming payment",
"invoice.status.paymentOverdue": "Payment overdue",
"invoice.status.processing": "Processing",
"invoice.summary.billingCycle": "Billing cycle",
"invoice.summary.month": "Щомісяця",
"invoice.summary.saveAnnual": "SAVE {{percent}}%",
"invoice.summary.subtitle": "Pay by invoice",
"invoice.summary.title": "Subscription Plan",
"invoice.summary.year": "Щорічно",
"plans.community.btnText": "Розпочніть з громади",
"plans.community.description": "Для індивідуальних користувачів, малих команд або некомерційних проектів",
"plans.community.features": [
+39
View File
@@ -9,6 +9,45 @@
"apps.fullTip2des": "Chúng tôi khuyên bạn nên xóa các ứng dụng không hoạt động để giải phóng dung lượng, hoặc liên hệ với chúng tôi.",
"buyPermissionDeniedTip": "Vui lòng liên hệ với quản trị viên doanh nghiệp của bạn để đăng ký",
"currentPlan": "Kế hoạch Hiện tại",
"invoice.form.addressLine1": "Address line 1",
"invoice.form.addressLine2": "Address line 2 (optional)",
"invoice.form.city": "City",
"invoice.form.companyName": "Company name",
"invoice.form.country": "Country",
"invoice.form.description": "This information will appear on your invoice. Please ensure accuracy.",
"invoice.form.invoiceEmail": "Invoice recipient email",
"invoice.form.placeholder.addressLine1": "123 Main Street",
"invoice.form.placeholder.addressLine2": "Suite 400",
"invoice.form.placeholder.city": "San Francisco",
"invoice.form.placeholder.companyName": "Acme Inc.",
"invoice.form.placeholder.country": "Select a country",
"invoice.form.placeholder.invoiceEmail": "finance@example.com",
"invoice.form.placeholder.postalCode": "94103",
"invoice.form.placeholder.stateOrProvince": "CA",
"invoice.form.postalCode": "Postal code",
"invoice.form.stateOrProvince": "State / Province",
"invoice.form.submit": "Gửi yêu cầu",
"invoice.form.terms": "I agree to LangGenius, Inc.'s <terms>Terms of Service</terms> and <privacy>Privacy Policy</privacy>. I understand that renewal invoices will be sent automatically each billing cycle until I cancel, and payment must be completed manually each time. International wire transfer fees are my responsibility.",
"invoice.form.termsRequired": "Please agree to the invoice payment terms before submitting.",
"invoice.form.title": "Billing information",
"invoice.lockedTip": "An invoice payment flow is already active for this workspace.",
"invoice.payByInvoice": "Thanh toán bằng hóa đơn",
"invoice.permissionDeniedTooltip": "Only the team owner and admins can manage subscriptions and billing.",
"invoice.requestReceived.description": "Your invoice will be sent to <email>{{email}}</email> within <day>1 business day</day>.",
"invoice.requestReceived.goToBilling": "Go to Billing",
"invoice.requestReceived.renewalTip": "After your first payment, new invoices are sent automatically before each billing cycle. You need to complete payment manually each time. Cancel anytime from your Billing page.",
"invoice.requestReceived.statusTip": "You can track the status from your Billing page. Once you receive the invoice, complete payment using your preferred method on the invoice page.",
"invoice.requestReceived.title": "Đã nhận yêu cầu",
"invoice.status.awaitingPayment": "Awaiting payment",
"invoice.status.confirmingPayment": "Confirming payment",
"invoice.status.paymentOverdue": "Payment overdue",
"invoice.status.processing": "Processing",
"invoice.summary.billingCycle": "Billing cycle",
"invoice.summary.month": "Hàng tháng",
"invoice.summary.saveAnnual": "SAVE {{percent}}%",
"invoice.summary.subtitle": "Pay by invoice",
"invoice.summary.title": "Subscription Plan",
"invoice.summary.year": "Hàng năm",
"plans.community.btnText": "Bắt đầu với Cộng đồng",
"plans.community.description": "Dành cho người dùng cá nhân, nhóm nhỏ hoặc các dự án phi thương mại",
"plans.community.features": [
+39
View File
@@ -9,6 +9,45 @@
"apps.fullTip2des": "推荐您清理不活跃的应用或者联系我们",
"buyPermissionDeniedTip": "请联系企业管理员订阅",
"currentPlan": "当前套餐",
"invoice.form.addressLine1": "地址行 1",
"invoice.form.addressLine2": "地址行 2(选填)",
"invoice.form.city": "城市",
"invoice.form.companyName": "公司名称",
"invoice.form.country": "国家 / 地区",
"invoice.form.description": "这些信息将显示在你的 Invoice 上,请确认准确无误。",
"invoice.form.invoiceEmail": "Invoice 接收邮箱",
"invoice.form.placeholder.addressLine1": "123 Main Street",
"invoice.form.placeholder.addressLine2": "Suite 400",
"invoice.form.placeholder.city": "San Francisco",
"invoice.form.placeholder.companyName": "Acme Inc.",
"invoice.form.placeholder.country": "选择国家 / 地区",
"invoice.form.placeholder.invoiceEmail": "finance@example.com",
"invoice.form.placeholder.postalCode": "94103",
"invoice.form.placeholder.stateOrProvince": "CA",
"invoice.form.postalCode": "邮政编码",
"invoice.form.stateOrProvince": "州 / 省",
"invoice.form.submit": "提交申请",
"invoice.form.terms": "我同意 LangGenius, Inc. 的<terms>服务条款</terms>和<privacy>隐私政策</privacy>。我了解在取消前,系统会在每个计费周期自动发送续期 Invoice,且每次都需要手动完成付款。国际电汇产生的手续费由我承担。",
"invoice.form.termsRequired": "提交前请先同意 Invoice 付款条款。",
"invoice.form.title": "账单信息",
"invoice.lockedTip": "当前工作空间已有进行中的 Invoice 付款流程。",
"invoice.payByInvoice": "通过 Invoice 付款",
"invoice.permissionDeniedTooltip": "只有团队所有者和管理员可以管理订阅和账单。",
"invoice.requestReceived.description": "你的 Invoice 会在 <day>1 个工作日</day>内发送至 <email>{{email}}</email>。",
"invoice.requestReceived.goToBilling": "前往 Billing",
"invoice.requestReceived.renewalTip": "首次付款后,新的 Invoice 会在每个账单周期前自动发送。你需要每次手动完成付款,并可随时在 Billing 页面取消。",
"invoice.requestReceived.statusTip": "你可以在 Billing 页面跟踪状态。收到 Invoice 后,请在 Invoice 页面使用你偏好的付款方式完成支付。",
"invoice.requestReceived.title": "申请已收到",
"invoice.status.awaitingPayment": "等待汇款中",
"invoice.status.confirmingPayment": "入款确认中",
"invoice.status.paymentOverdue": "付款已逾期",
"invoice.status.processing": "申请处理中",
"invoice.summary.billingCycle": "计费周期",
"invoice.summary.month": "按月",
"invoice.summary.saveAnnual": "省 {{percent}}%",
"invoice.summary.subtitle": "通过 Invoice 付款",
"invoice.summary.title": "订阅套餐",
"invoice.summary.year": "按年",
"plans.community.btnText": "开始使用",
"plans.community.description": "适用于开源爱好者、个人开发者以及非商业项目",
"plans.community.features": [
+39
View File
@@ -9,6 +9,45 @@
"apps.fullTip2des": "建議清除不活躍的應用程式以釋放使用空間,或聯繫我們。",
"buyPermissionDeniedTip": "請聯絡企業管理員訂閱",
"currentPlan": "當前套餐",
"invoice.form.addressLine1": "地址行 1",
"invoice.form.addressLine2": "地址行 2(選填)",
"invoice.form.city": "城市",
"invoice.form.companyName": "公司名稱",
"invoice.form.country": "國家 / 地區",
"invoice.form.description": "這些資訊將顯示在你的 Invoice 上,請確認準確無誤。",
"invoice.form.invoiceEmail": "Invoice 接收信箱",
"invoice.form.placeholder.addressLine1": "123 Main Street",
"invoice.form.placeholder.addressLine2": "Suite 400",
"invoice.form.placeholder.city": "San Francisco",
"invoice.form.placeholder.companyName": "Acme Inc.",
"invoice.form.placeholder.country": "選擇國家 / 地區",
"invoice.form.placeholder.invoiceEmail": "finance@example.com",
"invoice.form.placeholder.postalCode": "94103",
"invoice.form.placeholder.stateOrProvince": "CA",
"invoice.form.postalCode": "郵遞區號",
"invoice.form.stateOrProvince": "州 / 省",
"invoice.form.submit": "提交申請",
"invoice.form.terms": "我同意 LangGenius, Inc. 的<terms>服務條款</terms>和<privacy>隱私權政策</privacy>。我了解在取消前,系統會在每個計費週期自動寄送續期 Invoice,且每次都需要手動完成付款。國際電匯產生的手續費由我承擔。",
"invoice.form.termsRequired": "提交前請先同意 Invoice 付款條款。",
"invoice.form.title": "帳單資訊",
"invoice.lockedTip": "目前工作區已有進行中的 Invoice 付款流程。",
"invoice.payByInvoice": "透過 Invoice 付款",
"invoice.permissionDeniedTooltip": "只有團隊擁有者和管理員可以管理訂閱和帳單。",
"invoice.requestReceived.description": "你的 Invoice 會在 <day>1 個工作日</day>內傳送至 <email>{{email}}</email>。",
"invoice.requestReceived.goToBilling": "前往 Billing",
"invoice.requestReceived.renewalTip": "首次付款後,新的 Invoice 會在每個帳單週期前自動傳送。你需要每次手動完成付款,並可隨時在 Billing 頁面取消。",
"invoice.requestReceived.statusTip": "你可以在 Billing 頁面追蹤狀態。收到 Invoice 後,請在 Invoice 頁面使用你偏好的付款方式完成付款。",
"invoice.requestReceived.title": "申請已收到",
"invoice.status.awaitingPayment": "等待匯款中",
"invoice.status.confirmingPayment": "入款確認中",
"invoice.status.paymentOverdue": "付款已逾期",
"invoice.status.processing": "申請處理中",
"invoice.summary.billingCycle": "計費週期",
"invoice.summary.month": "按月",
"invoice.summary.saveAnnual": "省 {{percent}}%",
"invoice.summary.subtitle": "透過 Invoice 付款",
"invoice.summary.title": "訂閱方案",
"invoice.summary.year": "按年",
"plans.community.btnText": "開始使用社區",
"plans.community.description": "適用於個別用戶、小型團隊或非商業項目",
"plans.community.features": [