Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion adopter/web/components/dashboard/DemoBanner.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { getAdopterConfig } from '@beakerstack/shared/config/adopterRuntime';
import { landingConfig } from '@adopter/config/landing';
import { ExternalLink } from 'lucide-react';

export function DemoBanner() {
Expand All @@ -24,7 +25,7 @@ export function DemoBanner() {
</div>
<div className='flex flex-wrap gap-3 shrink-0'>
<a
href='https://github.com/Artificer-Innovations/BeakerStack'
href={landingConfig.finalCta.secondaryCta?.href}
target='_blank'
rel='noopener noreferrer'
className='inline-flex items-center gap-1.5 rounded-md bg-white/10 hover:bg-white/20 px-4 py-2 text-sm font-medium text-white transition-colors'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { useAuthContext } from '@beakerstack/shared/contexts/AuthContext';
import { BillingOverviewScreen } from '../../../src/screens/billing/BillingOverviewScreen';
import { BillingUsageScreen } from '../../../src/screens/billing/BillingUsageScreen';
import { useDemoCollectionCount } from '@adopter/mobile/billing/useDemoCollectionCount';
import { branding } from '@adopter/config/branding';

jest.mock('@react-navigation/native', () => {
const actual = jest.requireActual('@react-navigation/native');
Expand Down Expand Up @@ -240,7 +241,9 @@ describe('BillingOverviewScreen', () => {
const { getByText } = renderWithNav(<BillingOverviewScreen />);
expect(getByText('Payment problem')).toBeTruthy();
expect(getByText(/Your last payment did not go through/i)).toBeTruthy();
expect(getByText(/Beaker Stack web app/i)).toBeTruthy();
expect(
getByText(`${branding.displayName} web app`, { exact: false })
).toBeTruthy();
Comment thread
ZappoMan marked this conversation as resolved.
});

it('shows downgrade pending banner with target plan name from catalog', () => {
Expand Down
9 changes: 3 additions & 6 deletions apps/mobile/src/screens/billing/BillingOverviewScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ import {
import { formatMonthYear } from '@beakerstack/billing/presentation';
import { useAuthContext } from '@beakerstack/shared/contexts/AuthContext';
import { getAdopterConfig } from '@beakerstack/shared/config/adopterRuntime';
import {
billingConfig,
BEAKERSTACK_METER_AI_SUMMARIZE,
} from '@adopter/config/billing';
import { billingConfig, METER_AI_SUMMARIZE } from '@adopter/config/billing';
import { numericPlanFeature } from '../../billing/planFeatureValue';
import { useDemoCollectionCount } from '@adopter/mobile/billing/useDemoCollectionCount';
import { BillingLayout } from './BillingLayout';
Expand Down Expand Up @@ -139,8 +136,8 @@ export function BillingOverviewScreen(): ReactElement {
used,
limit,
loading: usageLoad,
} = useUsage<typeof billingConfig, typeof BEAKERSTACK_METER_AI_SUMMARIZE>(
BEAKERSTACK_METER_AI_SUMMARIZE
} = useUsage<typeof billingConfig, typeof METER_AI_SUMMARIZE>(
METER_AI_SUMMARIZE
);
const {
count: colCount,
Expand Down
4 changes: 2 additions & 2 deletions apps/mobile/src/screens/billing/BillingUsageScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
} from '@beakerstack/billing/presentation';
import {
billingConfig as adopterBillingConfig,
BEAKERSTACK_METER_AI_SUMMARIZE,
METER_AI_SUMMARIZE,
} from '@adopter/config/billing';
import { numericPlanFeature } from '../../billing/planFeatureValue';
import { useDemoCollectionCount } from '@adopter/mobile/billing/useDemoCollectionCount';
Expand Down Expand Up @@ -143,7 +143,7 @@ export function BillingUsageScreen(): ReactElement {
{Object.keys(plan.usage_limits).map(m => (
<View key={m} style={billingStyles.meterBlock}>
<UsageIndicator<typeof billingConfig>
meter={m as typeof BEAKERSTACK_METER_AI_SUMMARIZE}
meter={m as typeof METER_AI_SUMMARIZE}
variant='expanded'
label={meterCopy[m]?.label ?? m}
description={meterCopy[m]?.description}
Expand Down
3 changes: 2 additions & 1 deletion apps/web/src/admin/__tests__/adminUsageColumns.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { describe, expect, it } from 'vitest';
import { adminProductId, getAdminUsageMeterKeys } from '../adminUsageColumns';
import { billingConfig } from '@adopter/config/billing';

describe('adminUsageColumns', () => {
it('exports product id from billing config', () => {
expect(adminProductId).toBe('beakerstack');
expect(adminProductId).toBe(billingConfig.productId);
});

it('collects usage meter keys from all plans', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import { describe, expect, it } from 'vitest';
import {
BEAKERSTACK_METER_AI_SUMMARIZE,
billingConfig,
} from '@adopter/config/billing';
import { METER_AI_SUMMARIZE, billingConfig } from '@adopter/config/billing';

describe('billingConfig', () => {
it('defines a parsed product with public plans', () => {
Expand All @@ -13,6 +10,6 @@ describe('billingConfig', () => {
});

it('exposes meter key constant for AI usage', () => {
expect(BEAKERSTACK_METER_AI_SUMMARIZE).toBe('ai_summarize');
expect(METER_AI_SUMMARIZE).toBe('ai_summarize');
});
});
7 changes: 4 additions & 3 deletions apps/web/src/billing/__tests__/useDemoCollections.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { act, renderHook, waitFor } from '@testing-library/react';
import { useDemoCollections } from '@adopter/web/billing/useDemoCollections';
import { appIdentity } from '@adopter/config/app-identity';

const { rpc, mockClient } = vi.hoisted(() => {
const rpc = vi.fn();
Expand Down Expand Up @@ -113,7 +114,7 @@ describe('useDemoCollections', () => {
});
expect(rpc).toHaveBeenCalledWith(
'billing_demo_add_collection',
expect.objectContaining({ p_product_id: 'beakerstack' })
expect.objectContaining({ p_product_id: appIdentity.productId })
);
});

Expand All @@ -138,7 +139,7 @@ describe('useDemoCollections', () => {
expect(rpc).toHaveBeenCalledWith(
'billing_demo_delete_collection',
expect.objectContaining({
p_product_id: 'beakerstack',
p_product_id: appIdentity.productId,
p_collection_id: 'x',
})
);
Expand Down Expand Up @@ -168,7 +169,7 @@ describe('useDemoCollections', () => {
expect(rpc).toHaveBeenCalledWith(
'billing_demo_add_item',
expect.objectContaining({
p_product_id: 'beakerstack',
p_product_id: appIdentity.productId,
p_collection_id: 'col',
})
);
Expand Down
4 changes: 3 additions & 1 deletion apps/web/src/pages/__tests__/DashboardPage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { ProfileProvider } from '@beakerstack/shared/contexts/ProfileContext';
import { getAdopterConfig } from '@beakerstack/shared/config/adopterRuntime';
import { brandNameRegex } from '@adopter/config/branding';
import { billingConfig } from '@adopter/config/billing';
import { landingConfig } from '@adopter/config/landing';
import { supabase } from '@/lib/supabase';

const mockNavigate = vi.fn();
Expand Down Expand Up @@ -222,9 +223,10 @@ describe('DashboardPage', () => {
it('links to GitHub repo from demo banner', async () => {
await renderWithAuth(<DashboardPage />);
const link = screen.getByRole('link', { name: /view on github/i });
expect(landingConfig.finalCta.secondaryCta?.href).toBeDefined();
expect(link).toHaveAttribute(
'href',
'https://github.com/Artificer-Innovations/BeakerStack'
landingConfig.finalCta.secondaryCta?.href
);
Comment thread
ZappoMan marked this conversation as resolved.
});

Expand Down
3 changes: 2 additions & 1 deletion apps/web/src/pages/__tests__/SignupInvitePage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { MemoryRouter } from 'react-router-dom';
import { billingConfig } from '@adopter/config/billing';
import SignupInvitePage, {
finalizeInviteSignup,
getInviteTokenFromHash,
Expand Down Expand Up @@ -111,7 +112,7 @@ describe('SignupInvitePage helpers', () => {
body: expect.objectContaining({
action: 'consume',
token: 'tok',
productId: 'beakerstack',
productId: billingConfig.productId,
}),
})
);
Expand Down
9 changes: 3 additions & 6 deletions apps/web/src/pages/billing/BillingOverviewPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@ import {
type BillingUiStateKind,
} from '@beakerstack/billing';
import { useAuthContext } from '@beakerstack/shared/contexts/AuthContext';
import {
billingConfig,
BEAKERSTACK_METER_AI_SUMMARIZE,
} from '@adopter/config/billing';
import { billingConfig, METER_AI_SUMMARIZE } from '@adopter/config/billing';
import { formatMonthYear } from '@beakerstack/billing/presentation';
import { useDemoCollectionCount } from '@adopter/web/billing/useDemoCollectionCount';
import { Banner } from '../../components/billing/Banner.web';
Expand Down Expand Up @@ -43,8 +40,8 @@ export default function BillingOverviewPage() {
used,
limit,
loading: usageLoad,
} = useUsage<typeof billingConfig, typeof BEAKERSTACK_METER_AI_SUMMARIZE>(
BEAKERSTACK_METER_AI_SUMMARIZE
} = useUsage<typeof billingConfig, typeof METER_AI_SUMMARIZE>(
METER_AI_SUMMARIZE
);
const { items: invoices, loading: invLoad } = useInvoices<
typeof billingConfig
Expand Down
9 changes: 3 additions & 6 deletions apps/web/src/pages/billing/BillingPlansPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ import {
} from '@beakerstack/billing';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import {
billingConfig,
BEAKERSTACK_METER_AI_SUMMARIZE,
} from '@adopter/config/billing';
import { billingConfig, METER_AI_SUMMARIZE } from '@adopter/config/billing';
import {
annualListCentsFromSync,
computeDowngradeBlockers,
Expand Down Expand Up @@ -61,8 +58,8 @@ export default function BillingPlansPage() {
} = useBillingStripeActions<typeof billingConfig>();
const { used: aiUsed } = useUsage<
typeof billingConfig,
typeof BEAKERSTACK_METER_AI_SUMMARIZE
>(BEAKERSTACK_METER_AI_SUMMARIZE);
typeof METER_AI_SUMMARIZE
>(METER_AI_SUMMARIZE);
const { count: colCount = 0, maxItemsInAnyCollection = 0 } =
useDemoCollectionCount();

Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/pages/billing/BillingUsagePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
import { UsageIndicator } from '@beakerstack/billing/web';
import {
billingConfig as adopterBillingConfig,
BEAKERSTACK_METER_AI_SUMMARIZE,
METER_AI_SUMMARIZE,
} from '@adopter/config/billing';
import {
booleanFeatureLabel,
Expand Down Expand Up @@ -74,7 +74,7 @@ export default function BillingUsagePage() {
{Object.keys(plan.usage_limits).map(m => (
<div key={m} className='mt-3'>
<UsageIndicator<typeof billingConfig>
meter={m as typeof BEAKERSTACK_METER_AI_SUMMARIZE}
meter={m as typeof METER_AI_SUMMARIZE}
variant='expanded'
label={meterCopy[m]?.label ?? m}
description={meterCopy[m]?.description}
Expand Down
Loading