@lukoweb/apitogo-module-landing 0.2.23 → 0.2.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lukoweb/apitogo-module-landing",
3
- "version": "0.2.23",
3
+ "version": "0.2.24",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./src/index.tsx"
@@ -14,7 +14,7 @@
14
14
  "devDependencies": {
15
15
  "@types/react": "19.2.14",
16
16
  "@types/react-dom": "19.2.3",
17
- "@lukoweb/apitogo": "0.2.23",
17
+ "@lukoweb/apitogo": "0.2.24",
18
18
  "react": "19.2.4",
19
19
  "react-dom": "19.2.4",
20
20
  "typescript": "5.9.3"
@@ -1,51 +1,51 @@
1
- import type { ResolvedLandingContent } from "@lukoweb/apitogo";
2
- import { useZudoku } from "@lukoweb/apitogo/components";
3
- import { LandingShell } from "./LandingShell.js";
4
- import { ApiShowcaseSection } from "./sections/ApiShowcaseSection.js";
5
- import { FeaturesSection } from "./sections/FeaturesSection.js";
6
- import { HeroSection } from "./sections/HeroSection.js";
7
- import { PricingCtaSection } from "./sections/PricingCtaSection.js";
8
- import { TrustSection } from "./sections/TrustSection.js";
9
-
10
- export type DefaultLandingPageProps = {
11
- content: ResolvedLandingContent;
12
- };
13
-
14
- export const DefaultLandingPage = ({ content }: DefaultLandingPageProps) => {
15
- const { options } = useZudoku();
16
- const siteTitle =
17
- options.metadata?.applicationName ?? options.site?.title ?? "API ToGo";
18
-
19
- const hero = content.hero ?? { title: siteTitle };
20
- const title = hero.title ?? siteTitle;
21
- const description = hero.description;
22
-
23
- return (
24
- <LandingShell
25
- title={title}
26
- description={description}
27
- showPoweredBy={content.showPoweredBy !== false}
28
- >
29
- <HeroSection
30
- hero={{ ...hero, title }}
31
- primaryAction={content.primaryAction}
32
- secondaryAction={content.secondaryAction}
33
- />
34
-
35
- {content.trust ? <TrustSection trust={content.trust} /> : null}
36
- {content.features ? (
37
- <FeaturesSection
38
- features={content.features}
39
- section={content.featuresSection}
40
- />
41
- ) : null}
42
- {content.apiShowcase ? (
43
- <ApiShowcaseSection apiShowcase={content.apiShowcase} />
44
- ) : null}
45
- {content.pricingCta ? (
46
- <PricingCtaSection pricingCta={content.pricingCta} />
47
- ) : null}
48
- {/* content.footer renders portal-wide via the layout "footer" slot. */}
49
- </LandingShell>
50
- );
51
- };
1
+ import type { ResolvedLandingContent } from "@lukoweb/apitogo";
2
+ import { useZudoku } from "@lukoweb/apitogo/components";
3
+ import { LandingShell } from "./LandingShell.js";
4
+ import { ApiShowcaseSection } from "./sections/ApiShowcaseSection.js";
5
+ import { FeaturesSection } from "./sections/FeaturesSection.js";
6
+ import { HeroSection } from "./sections/HeroSection.js";
7
+ import { PricingCtaSection } from "./sections/PricingCtaSection.js";
8
+ import { TrustSection } from "./sections/TrustSection.js";
9
+
10
+ export type DefaultLandingPageProps = {
11
+ content: ResolvedLandingContent;
12
+ };
13
+
14
+ export const DefaultLandingPage = ({ content }: DefaultLandingPageProps) => {
15
+ const { options } = useZudoku();
16
+ const siteTitle =
17
+ options.metadata?.applicationName ?? options.site?.title ?? "API ToGo";
18
+
19
+ const hero = content.hero ?? { title: siteTitle };
20
+ const title = hero.title ?? siteTitle;
21
+ const description = hero.description;
22
+
23
+ return (
24
+ <LandingShell
25
+ title={title}
26
+ description={description}
27
+ showPoweredBy={content.showPoweredBy !== false}
28
+ >
29
+ <HeroSection
30
+ hero={{ ...hero, title }}
31
+ primaryAction={content.primaryAction}
32
+ secondaryAction={content.secondaryAction}
33
+ />
34
+
35
+ {content.trust ? <TrustSection trust={content.trust} /> : null}
36
+ {content.features ? (
37
+ <FeaturesSection
38
+ features={content.features}
39
+ section={content.featuresSection}
40
+ />
41
+ ) : null}
42
+ {content.apiShowcase ? (
43
+ <ApiShowcaseSection apiShowcase={content.apiShowcase} />
44
+ ) : null}
45
+ {content.pricingCta ? (
46
+ <PricingCtaSection pricingCta={content.pricingCta} />
47
+ ) : null}
48
+ {/* content.footer renders portal-wide via the layout "footer" slot. */}
49
+ </LandingShell>
50
+ );
51
+ };
@@ -1,21 +1,21 @@
1
- import type { ResolvedLandingContent } from "@lukoweb/apitogo";
2
- import type { ComponentType } from "react";
3
- import { FooterSection } from "./sections/FooterSection.js";
4
-
5
- export type LandingFooterSlotConfig = ResolvedLandingContent["footer"];
6
-
7
- /**
8
- * Builds a component for the layout "footer" slot so the landing footer
9
- * renders on every page (home, docs, API reference, pricing, auth).
10
- */
11
- export const createLandingFooterSlot = (
12
- footer: LandingFooterSlotConfig,
13
- ): ComponentType | undefined => {
14
- if (!footer || footer.enabled === false) {
15
- return undefined;
16
- }
17
-
18
- const LandingFooterSlot = () => <FooterSection footer={footer} />;
19
-
20
- return LandingFooterSlot;
21
- };
1
+ import type { ResolvedLandingContent } from "@lukoweb/apitogo";
2
+ import type { ComponentType } from "react";
3
+ import { FooterSection } from "./sections/FooterSection.js";
4
+
5
+ export type LandingFooterSlotConfig = ResolvedLandingContent["footer"];
6
+
7
+ /**
8
+ * Builds a component for the layout "footer" slot so the landing footer
9
+ * renders on every page (home, docs, API reference, pricing, auth).
10
+ */
11
+ export const createLandingFooterSlot = (
12
+ footer: LandingFooterSlotConfig,
13
+ ): ComponentType | undefined => {
14
+ if (!footer || footer.enabled === false) {
15
+ return undefined;
16
+ }
17
+
18
+ const LandingFooterSlot = () => <FooterSection footer={footer} />;
19
+
20
+ return LandingFooterSlot;
21
+ };
@@ -1,73 +1,73 @@
1
- import { cn } from "@lukoweb/apitogo";
2
- import { Head, useZudoku } from "@lukoweb/apitogo/components";
3
- import { Children, isValidElement, type ReactNode } from "react";
4
- import { FooterSection } from "./sections/FooterSection.js";
5
- import "./landing.css";
6
-
7
- /**
8
- * Detects a composed `FooterSection` in the element tree so the
9
- * "Built with API ToGo" line can be replaced by the real footer.
10
- */
11
- const containsFooterSection = (node: ReactNode): boolean =>
12
- Children.toArray(node).some((child) => {
13
- if (!isValidElement(child)) {
14
- return false;
15
- }
16
-
17
- if (child.type === FooterSection) {
18
- return true;
19
- }
20
-
21
- const { children } = child.props as { children?: ReactNode };
22
- return children ? containsFooterSection(children) : false;
23
- });
24
-
25
- export type LandingShellProps = {
26
- children: ReactNode;
27
- /** Page title for `<Head>`. Defaults to site title from config. */
28
- title?: string;
29
- /** Meta description for `<Head>`. */
30
- description?: string;
31
- /**
32
- * Show the "Built with API ToGo" line. Defaults to true.
33
- * Automatically hidden when a `FooterSection` is composed as a child or
34
- * a footer slot is configured (e.g. `modules.landing.content.footer`).
35
- */
36
- showPoweredBy?: boolean;
37
- };
38
-
39
- export const LandingShell = ({
40
- children,
41
- title,
42
- description,
43
- showPoweredBy = true,
44
- }: LandingShellProps) => {
45
- const { options } = useZudoku();
46
- const siteTitle =
47
- options.metadata?.applicationName ?? options.site?.title ?? "API ToGo";
48
- const pageTitle = title ?? siteTitle;
49
- const hasFooter =
50
- containsFooterSection(children) || Boolean(options.slots?.footer);
51
-
52
- return (
53
- <div className="relative overflow-hidden bg-background text-foreground">
54
- <Head>
55
- <title>{pageTitle}</title>
56
- {description ? <meta name="description" content={description} /> : null}
57
- </Head>
58
-
59
- {children}
60
-
61
- {showPoweredBy && !hasFooter ? (
62
- <div
63
- className={cn(
64
- "border-t border-border py-6 text-center text-xs text-muted-foreground/70",
65
- !options.site?.footer && "mb-8",
66
- )}
67
- >
68
- Built with API ToGo
69
- </div>
70
- ) : null}
71
- </div>
72
- );
73
- };
1
+ import { cn } from "@lukoweb/apitogo";
2
+ import { Head, useZudoku } from "@lukoweb/apitogo/components";
3
+ import { Children, isValidElement, type ReactNode } from "react";
4
+ import { FooterSection } from "./sections/FooterSection.js";
5
+ import "./landing.css";
6
+
7
+ /**
8
+ * Detects a composed `FooterSection` in the element tree so the
9
+ * "Built with API ToGo" line can be replaced by the real footer.
10
+ */
11
+ const containsFooterSection = (node: ReactNode): boolean =>
12
+ Children.toArray(node).some((child) => {
13
+ if (!isValidElement(child)) {
14
+ return false;
15
+ }
16
+
17
+ if (child.type === FooterSection) {
18
+ return true;
19
+ }
20
+
21
+ const { children } = child.props as { children?: ReactNode };
22
+ return children ? containsFooterSection(children) : false;
23
+ });
24
+
25
+ export type LandingShellProps = {
26
+ children: ReactNode;
27
+ /** Page title for `<Head>`. Defaults to site title from config. */
28
+ title?: string;
29
+ /** Meta description for `<Head>`. */
30
+ description?: string;
31
+ /**
32
+ * Show the "Built with API ToGo" line. Defaults to true.
33
+ * Automatically hidden when a `FooterSection` is composed as a child or
34
+ * a footer slot is configured (e.g. `modules.landing.content.footer`).
35
+ */
36
+ showPoweredBy?: boolean;
37
+ };
38
+
39
+ export const LandingShell = ({
40
+ children,
41
+ title,
42
+ description,
43
+ showPoweredBy = true,
44
+ }: LandingShellProps) => {
45
+ const { options } = useZudoku();
46
+ const siteTitle =
47
+ options.metadata?.applicationName ?? options.site?.title ?? "API ToGo";
48
+ const pageTitle = title ?? siteTitle;
49
+ const hasFooter =
50
+ containsFooterSection(children) || Boolean(options.slots?.footer);
51
+
52
+ return (
53
+ <div className="relative overflow-hidden bg-background text-foreground">
54
+ <Head>
55
+ <title>{pageTitle}</title>
56
+ {description ? <meta name="description" content={description} /> : null}
57
+ </Head>
58
+
59
+ {children}
60
+
61
+ {showPoweredBy && !hasFooter ? (
62
+ <div
63
+ className={cn(
64
+ "border-t border-border py-6 text-center text-xs text-muted-foreground/70",
65
+ !options.site?.footer && "mb-8",
66
+ )}
67
+ >
68
+ Built with API ToGo
69
+ </div>
70
+ ) : null}
71
+ </div>
72
+ );
73
+ };
@@ -1,131 +1,131 @@
1
- import type { ResolvedLandingContent } from "@lukoweb/apitogo";
2
- import { useAuth } from "@lukoweb/apitogo/hooks";
3
- import { type UseQueryResult, useQuery } from "@lukoweb/apitogo/react-query";
4
-
5
- declare const VITE_APITOGO_AUTHENTICATION_API_BASE_URL: string | undefined;
6
- declare const VITE_APITOGO_DEV_PORTAL_API_URL: string | undefined;
7
-
8
- type ApiShowcaseItem = NonNullable<
9
- NonNullable<ResolvedLandingContent["apiShowcase"]>["items"]
10
- >[number];
11
-
12
- const PLACEHOLDER_HOST = "dp-example.azurecontainerapps.io";
13
-
14
- /** One operation of your API, as synced by the dev portal backend from the gateway. */
15
- export type GatewayAction = {
16
- /** Stable key, e.g. `get:/orders/{id}`. */
17
- actionKey: string;
18
- /** Upper-case HTTP method, e.g. `GET`. */
19
- method: string;
20
- /** Path template, e.g. `/orders/{id}`. */
21
- path: string;
22
- /** True when the action can be called without an API key. */
23
- isPublic: boolean;
24
- };
25
-
26
- export type GatewayActionCatalog = {
27
- actions: GatewayAction[];
28
- lastSyncedAtUtc: string | null;
29
- };
30
-
31
- /** Server-side filters for `GET /api/v1/actions`. All filters are combined with AND. */
32
- export type GatewayActionFilters = {
33
- /** Only actions included in at least one active plan. */
34
- inPlan?: boolean;
35
- /** Only actions included in this plan SKU. */
36
- plan?: string;
37
- isPublic?: boolean;
38
- method?: string;
39
- pathPrefix?: string;
40
- /** Max number of actions (server caps at 500). */
41
- limit?: number;
42
- };
43
-
44
- export type UseGatewayActionsOptions = GatewayActionFilters & {
45
- /** Set to false to skip the request (e.g. behind a feature flag). */
46
- enabled?: boolean;
47
- };
48
-
49
- type DevPortalProviderData = { type?: string; apiBaseUrl?: string };
50
-
51
- const trimUrl = (url: string | undefined) =>
52
- url?.trim().replace(/\/+$/, "") || undefined;
53
-
54
- const resolveEnvApiBaseUrl = () =>
55
- trimUrl(
56
- (typeof VITE_APITOGO_AUTHENTICATION_API_BASE_URL === "string"
57
- ? VITE_APITOGO_AUTHENTICATION_API_BASE_URL
58
- : undefined) ||
59
- (typeof VITE_APITOGO_DEV_PORTAL_API_URL === "string"
60
- ? VITE_APITOGO_DEV_PORTAL_API_URL
61
- : undefined),
62
- );
63
-
64
- const toSearchParams = (filters: GatewayActionFilters) =>
65
- new URLSearchParams(
66
- Object.entries(filters).flatMap(([key, value]) =>
67
- value === undefined || value === "" ? [] : [[key, String(value)]],
68
- ),
69
- );
70
-
71
- /**
72
- * Loads your API's gateway actions from the dev portal backend (`GET /api/v1/actions`).
73
- *
74
- * Runs in the browser only, so prerendered pages never bake in a stale list. Disabled in
75
- * preview/demo mode or when no dev portal backend URL is configured — render a fallback
76
- * list while `data` is undefined.
77
- */
78
- export const useGatewayActions = ({
79
- enabled = true,
80
- ...filters
81
- }: UseGatewayActionsOptions = {}): UseQueryResult<GatewayActionCatalog> => {
82
- const auth = useAuth();
83
- const providerData = auth.providerData as DevPortalProviderData | null;
84
- const apiBaseUrl =
85
- (providerData?.type === "dev-portal"
86
- ? trimUrl(providerData.apiBaseUrl)
87
- : undefined) ?? resolveEnvApiBaseUrl();
88
-
89
- const isLive =
90
- Boolean(apiBaseUrl) &&
91
- !apiBaseUrl?.includes(PLACEHOLDER_HOST) &&
92
- auth.authMode !== "preview" &&
93
- auth.isBackendAvailable !== false &&
94
- auth.isDemoSession !== true;
95
-
96
- const search = toSearchParams(filters).toString();
97
-
98
- return useQuery<GatewayActionCatalog>({
99
- queryKey: ["dev-portal-gateway-actions", apiBaseUrl, search],
100
- enabled: enabled && isLive,
101
- staleTime: 5 * 60 * 1000,
102
- queryFn: async ({ signal }) => {
103
- const response = await fetch(
104
- `${apiBaseUrl}/api/v1/actions${search ? `?${search}` : ""}`,
105
- { headers: { Accept: "application/json" }, signal },
106
- );
107
-
108
- if (!response.ok) {
109
- throw new Error("Failed to load API actions.");
110
- }
111
-
112
- const body = (await response.json()) as Partial<GatewayActionCatalog>;
113
- return {
114
- actions: Array.isArray(body.actions) ? body.actions : [],
115
- lastSyncedAtUtc: body.lastSyncedAtUtc ?? null,
116
- };
117
- },
118
- });
119
- };
120
-
121
- /** Maps gateway actions to `ApiShowcaseSection` items. Pass `summaries` to label actions by key. */
122
- export const toApiShowcaseItems = (
123
- actions: GatewayAction[],
124
- summaries: Record<string, string> = {},
125
- ): ApiShowcaseItem[] =>
126
- actions.map((action) => ({
127
- name: summaries[action.actionKey] ?? `${action.method} ${action.path}`,
128
- method: action.method,
129
- path: action.path,
130
- summary: summaries[action.actionKey],
131
- }));
1
+ import type { ResolvedLandingContent } from "@lukoweb/apitogo";
2
+ import { useAuth } from "@lukoweb/apitogo/hooks";
3
+ import { type UseQueryResult, useQuery } from "@lukoweb/apitogo/react-query";
4
+
5
+ declare const VITE_APITOGO_AUTHENTICATION_API_BASE_URL: string | undefined;
6
+ declare const VITE_APITOGO_DEV_PORTAL_API_URL: string | undefined;
7
+
8
+ type ApiShowcaseItem = NonNullable<
9
+ NonNullable<ResolvedLandingContent["apiShowcase"]>["items"]
10
+ >[number];
11
+
12
+ const PLACEHOLDER_HOST = "dp-example.azurecontainerapps.io";
13
+
14
+ /** One operation of your API, as synced by the dev portal backend from the gateway. */
15
+ export type GatewayAction = {
16
+ /** Stable key, e.g. `get:/orders/{id}`. */
17
+ actionKey: string;
18
+ /** Upper-case HTTP method, e.g. `GET`. */
19
+ method: string;
20
+ /** Path template, e.g. `/orders/{id}`. */
21
+ path: string;
22
+ /** True when the action can be called without an API key. */
23
+ isPublic: boolean;
24
+ };
25
+
26
+ export type GatewayActionCatalog = {
27
+ actions: GatewayAction[];
28
+ lastSyncedAtUtc: string | null;
29
+ };
30
+
31
+ /** Server-side filters for `GET /api/v1/actions`. All filters are combined with AND. */
32
+ export type GatewayActionFilters = {
33
+ /** Only actions included in at least one active plan. */
34
+ inPlan?: boolean;
35
+ /** Only actions included in this plan SKU. */
36
+ plan?: string;
37
+ isPublic?: boolean;
38
+ method?: string;
39
+ pathPrefix?: string;
40
+ /** Max number of actions (server caps at 500). */
41
+ limit?: number;
42
+ };
43
+
44
+ export type UseGatewayActionsOptions = GatewayActionFilters & {
45
+ /** Set to false to skip the request (e.g. behind a feature flag). */
46
+ enabled?: boolean;
47
+ };
48
+
49
+ type DevPortalProviderData = { type?: string; apiBaseUrl?: string };
50
+
51
+ const trimUrl = (url: string | undefined) =>
52
+ url?.trim().replace(/\/+$/, "") || undefined;
53
+
54
+ const resolveEnvApiBaseUrl = () =>
55
+ trimUrl(
56
+ (typeof VITE_APITOGO_AUTHENTICATION_API_BASE_URL === "string"
57
+ ? VITE_APITOGO_AUTHENTICATION_API_BASE_URL
58
+ : undefined) ||
59
+ (typeof VITE_APITOGO_DEV_PORTAL_API_URL === "string"
60
+ ? VITE_APITOGO_DEV_PORTAL_API_URL
61
+ : undefined),
62
+ );
63
+
64
+ const toSearchParams = (filters: GatewayActionFilters) =>
65
+ new URLSearchParams(
66
+ Object.entries(filters).flatMap(([key, value]) =>
67
+ value === undefined || value === "" ? [] : [[key, String(value)]],
68
+ ),
69
+ );
70
+
71
+ /**
72
+ * Loads your API's gateway actions from the dev portal backend (`GET /api/v1/actions`).
73
+ *
74
+ * Runs in the browser only, so prerendered pages never bake in a stale list. Disabled in
75
+ * preview/demo mode or when no dev portal backend URL is configured — render a fallback
76
+ * list while `data` is undefined.
77
+ */
78
+ export const useGatewayActions = ({
79
+ enabled = true,
80
+ ...filters
81
+ }: UseGatewayActionsOptions = {}): UseQueryResult<GatewayActionCatalog> => {
82
+ const auth = useAuth();
83
+ const providerData = auth.providerData as DevPortalProviderData | null;
84
+ const apiBaseUrl =
85
+ (providerData?.type === "dev-portal"
86
+ ? trimUrl(providerData.apiBaseUrl)
87
+ : undefined) ?? resolveEnvApiBaseUrl();
88
+
89
+ const isLive =
90
+ Boolean(apiBaseUrl) &&
91
+ !apiBaseUrl?.includes(PLACEHOLDER_HOST) &&
92
+ auth.authMode !== "preview" &&
93
+ auth.isBackendAvailable !== false &&
94
+ auth.isDemoSession !== true;
95
+
96
+ const search = toSearchParams(filters).toString();
97
+
98
+ return useQuery<GatewayActionCatalog>({
99
+ queryKey: ["dev-portal-gateway-actions", apiBaseUrl, search],
100
+ enabled: enabled && isLive,
101
+ staleTime: 5 * 60 * 1000,
102
+ queryFn: async ({ signal }) => {
103
+ const response = await fetch(
104
+ `${apiBaseUrl}/api/v1/actions${search ? `?${search}` : ""}`,
105
+ { headers: { Accept: "application/json" }, signal },
106
+ );
107
+
108
+ if (!response.ok) {
109
+ throw new Error("Failed to load API actions.");
110
+ }
111
+
112
+ const body = (await response.json()) as Partial<GatewayActionCatalog>;
113
+ return {
114
+ actions: Array.isArray(body.actions) ? body.actions : [],
115
+ lastSyncedAtUtc: body.lastSyncedAtUtc ?? null,
116
+ };
117
+ },
118
+ });
119
+ };
120
+
121
+ /** Maps gateway actions to `ApiShowcaseSection` items. Pass `summaries` to label actions by key. */
122
+ export const toApiShowcaseItems = (
123
+ actions: GatewayAction[],
124
+ summaries: Record<string, string> = {},
125
+ ): ApiShowcaseItem[] =>
126
+ actions.map((action) => ({
127
+ name: summaries[action.actionKey] ?? `${action.method} ${action.path}`,
128
+ method: action.method,
129
+ path: action.path,
130
+ summary: summaries[action.actionKey],
131
+ }));
package/src/index.tsx CHANGED
@@ -1,42 +1,42 @@
1
- export { DefaultLandingPage } from "./DefaultLandingPage.js";
2
- export type { DefaultLandingPageProps } from "./DefaultLandingPage.js";
3
- export { LandingShell } from "./LandingShell.js";
4
- export type { LandingShellProps } from "./LandingShell.js";
5
- export { landingModule } from "./landingModule.js";
6
- export type { LandingModuleOptions } from "./landingModule.js";
7
- export { createLandingFooterSlot } from "./LandingFooterSlot.js";
8
- export type { LandingFooterSlotConfig } from "./LandingFooterSlot.js";
9
- export { HeroSection } from "./sections/HeroSection.js";
10
- export type { HeroSectionProps } from "./sections/HeroSection.js";
11
- export { TrustSection } from "./sections/TrustSection.js";
12
- export type { TrustSectionProps } from "./sections/TrustSection.js";
13
- export { FeaturesSection } from "./sections/FeaturesSection.js";
14
- export type { FeaturesSectionProps } from "./sections/FeaturesSection.js";
15
- export { StepsSection } from "./sections/StepsSection.js";
16
- export type {
17
- StepsSectionProps,
18
- StepsSectionStep,
19
- } from "./sections/StepsSection.js";
20
- export { ApiShowcaseSection } from "./sections/ApiShowcaseSection.js";
21
- export type { ApiShowcaseSectionProps } from "./sections/ApiShowcaseSection.js";
22
- export { PlansPreviewSection } from "./sections/PlansPreviewSection.js";
23
- export type {
24
- PlansPreviewPlan,
25
- PlansPreviewSectionProps,
26
- } from "./sections/PlansPreviewSection.js";
27
- export { PricingCtaSection } from "./sections/PricingCtaSection.js";
28
- export type { PricingCtaSectionProps } from "./sections/PricingCtaSection.js";
29
- export { FooterSection } from "./sections/FooterSection.js";
30
- export type { FooterSectionProps } from "./sections/FooterSection.js";
31
- export { CodeExampleCard } from "./sections/CodeExampleCard.js";
32
- export type { CodeExampleCardProps } from "./sections/CodeExampleCard.js";
33
- export {
34
- toApiShowcaseItems,
35
- useGatewayActions,
36
- } from "./hooks/useGatewayActions.js";
37
- export type {
38
- GatewayAction,
39
- GatewayActionCatalog,
40
- GatewayActionFilters,
41
- UseGatewayActionsOptions,
42
- } from "./hooks/useGatewayActions.js";
1
+ export { DefaultLandingPage } from "./DefaultLandingPage.js";
2
+ export type { DefaultLandingPageProps } from "./DefaultLandingPage.js";
3
+ export { LandingShell } from "./LandingShell.js";
4
+ export type { LandingShellProps } from "./LandingShell.js";
5
+ export { landingModule } from "./landingModule.js";
6
+ export type { LandingModuleOptions } from "./landingModule.js";
7
+ export { createLandingFooterSlot } from "./LandingFooterSlot.js";
8
+ export type { LandingFooterSlotConfig } from "./LandingFooterSlot.js";
9
+ export { HeroSection } from "./sections/HeroSection.js";
10
+ export type { HeroSectionProps } from "./sections/HeroSection.js";
11
+ export { TrustSection } from "./sections/TrustSection.js";
12
+ export type { TrustSectionProps } from "./sections/TrustSection.js";
13
+ export { FeaturesSection } from "./sections/FeaturesSection.js";
14
+ export type { FeaturesSectionProps } from "./sections/FeaturesSection.js";
15
+ export { StepsSection } from "./sections/StepsSection.js";
16
+ export type {
17
+ StepsSectionProps,
18
+ StepsSectionStep,
19
+ } from "./sections/StepsSection.js";
20
+ export { ApiShowcaseSection } from "./sections/ApiShowcaseSection.js";
21
+ export type { ApiShowcaseSectionProps } from "./sections/ApiShowcaseSection.js";
22
+ export { PlansPreviewSection } from "./sections/PlansPreviewSection.js";
23
+ export type {
24
+ PlansPreviewPlan,
25
+ PlansPreviewSectionProps,
26
+ } from "./sections/PlansPreviewSection.js";
27
+ export { PricingCtaSection } from "./sections/PricingCtaSection.js";
28
+ export type { PricingCtaSectionProps } from "./sections/PricingCtaSection.js";
29
+ export { FooterSection } from "./sections/FooterSection.js";
30
+ export type { FooterSectionProps } from "./sections/FooterSection.js";
31
+ export { CodeExampleCard } from "./sections/CodeExampleCard.js";
32
+ export type { CodeExampleCardProps } from "./sections/CodeExampleCard.js";
33
+ export {
34
+ toApiShowcaseItems,
35
+ useGatewayActions,
36
+ } from "./hooks/useGatewayActions.js";
37
+ export type {
38
+ GatewayAction,
39
+ GatewayActionCatalog,
40
+ GatewayActionFilters,
41
+ UseGatewayActionsOptions,
42
+ } from "./hooks/useGatewayActions.js";