@eventcatalog/core 2.30.8 → 2.31.0

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.
Files changed (49) hide show
  1. package/README.md +1 -1
  2. package/dist/analytics/analytics.cjs +1 -1
  3. package/dist/analytics/analytics.js +2 -2
  4. package/dist/analytics/log-build.cjs +9 -3
  5. package/dist/analytics/log-build.d.cts +4 -1
  6. package/dist/analytics/log-build.d.ts +4 -1
  7. package/dist/analytics/log-build.js +3 -3
  8. package/dist/{chunk-XJBJFIN7.js → chunk-4S3UNXH2.js} +1 -1
  9. package/dist/{chunk-D4IJRFPJ.js → chunk-D7LV5JLL.js} +9 -3
  10. package/dist/{chunk-NALVGTIE.js → chunk-I6OFOESY.js} +1 -1
  11. package/dist/{chunk-XMDPVKIJ.js → chunk-NJGR7XUU.js} +44 -1
  12. package/dist/constants.cjs +1 -1
  13. package/dist/constants.js +1 -1
  14. package/dist/eventcatalog.cjs +74 -14
  15. package/dist/eventcatalog.config.d.cts +28 -0
  16. package/dist/eventcatalog.config.d.ts +28 -0
  17. package/dist/eventcatalog.js +29 -16
  18. package/dist/features.cjs +46 -2
  19. package/dist/features.d.cts +2 -1
  20. package/dist/features.d.ts +2 -1
  21. package/dist/features.js +5 -3
  22. package/eventcatalog/public/images/custom-docs-placeholder.png +0 -0
  23. package/eventcatalog/src/components/MDX/NodeGraph/Nodes/Custom.tsx +0 -2
  24. package/eventcatalog/src/components/MDX/Steps/Step.astro +1 -1
  25. package/eventcatalog/src/components/MDX/Steps/Steps.astro +15 -0
  26. package/eventcatalog/src/components/SideNav/CustomDocsNav/CustomDocsNavWrapper.tsx +11 -0
  27. package/eventcatalog/src/components/SideNav/CustomDocsNav/components/NestedItem.tsx +183 -0
  28. package/eventcatalog/src/components/SideNav/CustomDocsNav/components/NoResultsFound.tsx +21 -0
  29. package/eventcatalog/src/components/SideNav/CustomDocsNav/index.tsx +250 -0
  30. package/eventcatalog/src/components/SideNav/CustomDocsNav/types.ts +29 -0
  31. package/eventcatalog/src/components/SideNav/CustomDocsNav.astro +9 -0
  32. package/eventcatalog/src/content.config.ts +15 -24
  33. package/eventcatalog/src/enterprise/collections/custom-pages.ts +19 -0
  34. package/eventcatalog/src/enterprise/custom-documentation/collection.ts +16 -0
  35. package/eventcatalog/src/enterprise/custom-documentation/components/CustomDocsNav/CustomDocsNavWrapper.tsx +11 -0
  36. package/eventcatalog/src/enterprise/custom-documentation/components/CustomDocsNav/components/NestedItem.tsx +183 -0
  37. package/eventcatalog/src/enterprise/custom-documentation/components/CustomDocsNav/components/NoResultsFound.tsx +21 -0
  38. package/eventcatalog/src/enterprise/custom-documentation/components/CustomDocsNav/index.tsx +250 -0
  39. package/eventcatalog/src/enterprise/custom-documentation/components/CustomDocsNav/types.ts +29 -0
  40. package/eventcatalog/src/enterprise/custom-documentation/pages/index.astro +389 -0
  41. package/eventcatalog/src/enterprise/custom-documentation/utils/custom-docs.ts +118 -0
  42. package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +58 -9
  43. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +117 -3
  44. package/eventcatalog/src/pages/docs/custom/[...path]/index.astro +260 -0
  45. package/eventcatalog/src/pages/pro/index.astro +272 -0
  46. package/eventcatalog/src/shared-collections.ts +25 -0
  47. package/eventcatalog/src/utils/eventcatalog-config/catalog.ts +12 -1
  48. package/eventcatalog/src/utils/feature.ts +5 -0
  49. package/package.json +1 -1
@@ -268,12 +268,126 @@ const pagefindAttributes =
268
268
  if (document.getElementsByClassName('mermaid').length > 0) {
269
269
  renderDiagrams(graphs);
270
270
  }
271
+
272
+ // Set up TOC highlighting and scrolling
273
+ setupTOCHighlighting();
271
274
  });
272
275
 
273
276
  /**
274
- * @params {HTMLCollectionOf<HTMLElement>} graphs
277
+ * Setup TOC highlighting and scrolling
278
+ */
279
+ function setupTOCHighlighting() {
280
+ // Check if there's a sidebar with navigation
281
+ const sidebarNav = document.querySelector('aside nav');
282
+ if (!sidebarNav) return;
283
+
284
+ const observerOptions = {
285
+ rootMargin: '0px 0px -40% 0px',
286
+ threshold: 0.1,
287
+ };
288
+
289
+ // Flag to temporarily disable observer after click
290
+ let observerPaused = false;
291
+
292
+ /**
293
+ * Highlights a TOC item and scrolls it into view
294
+ * @param {string} id - The ID of the heading to highlight in the TOC
295
+ */
296
+ function highlightTocItem(id) {
297
+ // Remove active class from all links
298
+ document.querySelectorAll('.active-toc-item').forEach((link) => {
299
+ link.classList.remove('active-toc-item', 'text-primary-600', 'font-medium');
300
+ link.classList.add('text-gray-400');
301
+ });
302
+
303
+ // Add active class to current link
304
+ const tocLink = document.querySelector(`aside nav a[href="#${id}"]`);
305
+ if (tocLink) {
306
+ tocLink.classList.add('active-toc-item', 'text-primary-600', 'font-medium');
307
+ tocLink.classList.remove('text-gray-400');
308
+
309
+ // Scroll the highlighted item into view with a small delay to ensure DOM updates first
310
+ setTimeout(() => {
311
+ tocLink.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' });
312
+ }, 10);
313
+ }
314
+ }
315
+
316
+ // Set up the intersection observer for scrolling
317
+ const observer = new IntersectionObserver((entries) => {
318
+ // If observer is paused, don't process entries
319
+ if (observerPaused) return;
320
+
321
+ entries.forEach((entry) => {
322
+ try {
323
+ const id = entry.target.getAttribute('id');
324
+ if (entry.isIntersecting && id) {
325
+ highlightTocItem(id);
326
+ }
327
+ } catch (entryError) {
328
+ console.error('Error processing intersection entry:', entryError);
329
+ }
330
+ });
331
+ }, observerOptions);
332
+
333
+ // Find all headings in the content area
334
+ const prose = document.querySelector('.prose');
335
+ if (!prose) return;
336
+
337
+ // First try to find headings with IDs
338
+ const headings = prose.querySelectorAll('h1[id], h2[id], h3[id]');
339
+
340
+ if (headings.length > 0) {
341
+ headings.forEach((heading) => {
342
+ observer.observe(heading);
343
+ });
344
+ } else {
345
+ // Fallback: If no headings with IDs found, attach IDs to them
346
+ const allHeadings = prose.querySelectorAll('h1, h2, h3');
347
+
348
+ allHeadings.forEach((heading) => {
349
+ // Only add ID if it doesn't exist
350
+ if (!heading.id) {
351
+ const text = heading.textContent || '';
352
+ const slug = text
353
+ .toLowerCase()
354
+ .replace(/[^\w\s-]/g, '')
355
+ .replace(/\s+/g, '-');
356
+ heading.id = slug;
357
+ }
358
+ observer.observe(heading);
359
+ });
360
+ }
361
+
362
+ // Add click event listeners to all TOC links
363
+ const tocLinks = document.querySelectorAll('aside nav a[href^="#"]');
364
+ tocLinks.forEach((link) => {
365
+ link.addEventListener('click', (e) => {
366
+ // Get the ID from the href attribute
367
+ const hrefAttr = link.getAttribute('href');
368
+ if (!hrefAttr) return;
369
+
370
+ const id = hrefAttr.substring(1);
371
+
372
+ // Highlight the clicked item
373
+ highlightTocItem(id);
374
+
375
+ // Temporarily pause the observer to prevent immediate highlighting changes
376
+ observerPaused = true;
377
+
378
+ // Resume the observer after a delay
379
+ setTimeout(() => {
380
+ observerPaused = false;
381
+ }, 500);
382
+ });
383
+ });
384
+ }
385
+
386
+ /**
387
+ * Renders mermaid diagrams in the page
388
+ * @param {HTMLCollectionOf<HTMLElement>} graphs - The collection of mermaid graph elements
275
389
  */
276
- async function renderDiagrams(graphs: any) {
390
+ async function renderDiagrams(graphs) {
277
391
  const { default: mermaid } = await import('mermaid');
278
392
 
279
393
  if (window.eventcatalog.mermaid) {
@@ -281,7 +395,7 @@ const pagefindAttributes =
281
395
  const { iconPacks = [] } = window.eventcatalog.mermaid ?? {};
282
396
 
283
397
  if (iconPacks.length > 0) {
284
- const iconPacksToRegister = iconPacks.map((name: string) => {
398
+ const iconPacksToRegister = iconPacks.map((name) => {
285
399
  return {
286
400
  name,
287
401
  icons,
@@ -0,0 +1,260 @@
1
+ ---
2
+ import CustomDocumentationPage from '@enterprise/custom-documentation/pages/index.astro';
3
+ import { getCollection } from 'astro:content';
4
+ import type { GetStaticPaths } from 'astro';
5
+ import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
6
+ import { Code } from 'astro-expressive-code/components';
7
+ import { isEventCatalogProEnabled } from '@utils/feature';
8
+ import path from 'node:path';
9
+ import fs from 'node:fs';
10
+
11
+ const PROJECT_DIR = path.resolve(process.env.PROJECT_DIR || process.cwd());
12
+ const CUSTOM_DOCS_DIR = path.resolve(PROJECT_DIR, 'docs/');
13
+ const directoryExists = fs.existsSync(CUSTOM_DOCS_DIR);
14
+
15
+ export const getStaticPaths = (async () => {
16
+ const docs = await getCollection('customPages');
17
+ const paths = docs.map((doc) => ({
18
+ params: { path: doc.id.replace('docs/', '') },
19
+ props: doc,
20
+ }));
21
+ console.log(
22
+ 'paths',
23
+ paths.map((path) => path.params.path)
24
+ );
25
+ return paths;
26
+ }) satisfies GetStaticPaths;
27
+
28
+ const props = Astro.props;
29
+
30
+ // Example for folder structure
31
+ const folderStructureExample = `my-catalog/
32
+ └── docs/
33
+ ├── getting-started/
34
+ │ ├── 01-introduction.mdx
35
+ │ └── 02-quick-start.mdx
36
+ ├── architecture-decisions/
37
+ │ ├── 01-what-are-architecture-decisions.mdx
38
+ │ ├── 02-how-to-create-architecture-decisions.mdx
39
+ │ ├── published/
40
+ │ │ ├── 01-adr-001-event-driven.mdx
41
+ │ │ └── 02-adr-002-api-first.mdx
42
+ │ └── drafts/
43
+ │ ├── 01-adr-003-microservices.mdx
44
+ │ └── 02-adr-004-monolith.mdx
45
+ └`;
46
+ // Example MDX file content
47
+ const mdxFileExample = `---
48
+ title: Getting Started
49
+ description: How to get started with our event-driven architecture
50
+ ---
51
+
52
+ # Getting Started with our Event-Driven Architecture
53
+
54
+ This guide will help you understand how our services communicate using events.
55
+
56
+ ## Prerequisites
57
+
58
+ - Understanding of basic messaging patterns
59
+ - Node.js installed on your machine
60
+
61
+ ## Key Concepts
62
+
63
+ Events are the backbone of our architecture. They represent facts that have happened in our system.
64
+ `;
65
+
66
+ // Example config file
67
+ const configExample = `// eventcatalog.config.js
68
+
69
+ module.exports = {
70
+ // Your existing config...
71
+
72
+ customDocs: {
73
+ sidebar: [
74
+ {
75
+ label: 'Getting Started',
76
+ badge: {
77
+ text: 'New', color: 'green'
78
+ },
79
+ collapsed: false,
80
+ items: [
81
+ { label: 'Introduction', slug: 'getting-started/01-introduction' },
82
+ { label: 'Quick Start', slug: 'getting-started/02-quick-start' }
83
+ ]
84
+ },
85
+ {
86
+ label: 'Architecture Decisions',
87
+ badge: {
88
+ text: 'New', color: 'green'
89
+ },
90
+ collapsed: true,
91
+ items: [
92
+ {
93
+ label: 'What are Architecture Decisions?',
94
+ slug: 'architecture-decisions/01-what-are-architecture-decisions'
95
+ },
96
+ {
97
+ label: 'How to Create Architecture Decisions',
98
+ slug: 'architecture-decisions/02-how-to-create-architecture-decisions'
99
+ },
100
+ {
101
+ label: 'Published ADRs',
102
+ autogenerated: {
103
+ directory: 'architecture-decisions/published',
104
+ collapsed: true
105
+ }
106
+ },
107
+ {
108
+ label: 'Draft ADRs',
109
+ autogenerated: {
110
+ directory: 'architecture-decisions/drafts',
111
+ collapsed: true
112
+ }
113
+ }
114
+ ]
115
+ }
116
+ ]
117
+ }
118
+ }`;
119
+ ---
120
+
121
+ {
122
+ directoryExists && isEventCatalogProEnabled() ? (
123
+ <CustomDocumentationPage {...props} />
124
+ ) : (
125
+ <VerticalSideBarLayout title="Custom Documentation">
126
+ <body class="min-h-screen font-inter">
127
+ <main class="container px-8 lg:px-8 mx-auto py-8 max-w-[80em]">
128
+ <div class="mb-12">
129
+ <div class="flex flex-col md:flex-row md:items-center md:justify-between gap-6">
130
+ <div>
131
+ <div class="flex flex-wrap items-center gap-3 mb-3">
132
+ <h1 class="text-4xl font-semibold text-gray-900 font-inter">Custom Documentation</h1>
133
+ <div class="inline-flex items-center px-3 py-1.5 rounded-full text-xs font-medium bg-purple-100 text-purple-800 border border-purple-200 shadow-sm">
134
+ Pro feature
135
+ </div>
136
+ </div>
137
+ <p class="text-base mb-0 text-gray-600 max-w-3xl">
138
+ Add custom documentation to EventCatalog to create a unified source of truth for your team. Document your
139
+ architecture decisions, patterns, and guidelines.
140
+ </p>
141
+ </div>
142
+ <div class="flex space-x-4 shrink-0">
143
+ <a
144
+ href="https://www.eventcatalog.dev/docs/custom-documentation"
145
+ class="inline-flex items-center justify-center px-5 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50"
146
+ >
147
+ Read documentation &rarr;
148
+ </a>
149
+ {!isEventCatalogProEnabled() && (
150
+ <a
151
+ href="https://www.eventcatalog.dev/pro/trial"
152
+ class="inline-flex items-center justify-center px-5 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-gradient-to-r from-purple-500 to-purple-700 hover:from-purple-600 hover:to-purple-800 shadow-sm"
153
+ >
154
+ Start 14-day trial
155
+ </a>
156
+ )}
157
+ </div>
158
+ </div>
159
+ </div>
160
+
161
+ <h2 class="text-2xl font-semibold mb-2 text-gray-900">Setup Guide</h2>
162
+ <p class="text-gray-600 mb-8 max-w-3xl">
163
+ Custom documentation let's you bring any documentation into EventCatalog. This is useful for documenting your
164
+ architecture decisions, patterns, and guidelines. Follow these steps to get started:
165
+ </p>
166
+
167
+ <div class="space-y-10 mb-12">
168
+ <div class="bg-white p-6 rounded-lg shadow-sm border border-gray-200">
169
+ <div class="flex items-start gap-4">
170
+ <div class="inline-flex items-center justify-center w-8 h-8 rounded-full bg-blue-100 text-blue-600 text-lg font-medium shrink-0 mt-1">
171
+ 1
172
+ </div>
173
+ <div class="w-full">
174
+ <h3 class="text-xl font-semibold text-gray-900 mb-3">Create the content structure</h3>
175
+ <p class="text-gray-600 mb-4">Create a folder structure in your directory to organize your documentation.</p>
176
+ <Code code={folderStructureExample} lang="bash" frame="terminal" />
177
+ </div>
178
+ </div>
179
+ </div>
180
+
181
+ <div class="bg-white p-6 rounded-lg shadow-sm border border-gray-200">
182
+ <div class="flex items-start gap-4">
183
+ <div class="inline-flex items-center justify-center w-8 h-8 rounded-full bg-blue-100 text-blue-600 text-lg font-medium shrink-0 mt-1">
184
+ 2
185
+ </div>
186
+ <div class="w-full">
187
+ <h3 class="text-xl font-semibold text-gray-900 mb-3">Add MDX files</h3>
188
+ <p class="text-gray-600 mb-4">Create MDX files with frontmatter and markdown content.</p>
189
+ <Code code={mdxFileExample} lang="mdx" frame="terminal" />
190
+ </div>
191
+ </div>
192
+ </div>
193
+
194
+ <div class="bg-white p-6 rounded-lg shadow-sm border border-gray-200">
195
+ <div class="flex items-start gap-4">
196
+ <div class="inline-flex items-center justify-center w-8 h-8 rounded-full bg-blue-100 text-blue-600 text-lg font-medium shrink-0 mt-1">
197
+ 3
198
+ </div>
199
+ <div class="w-full">
200
+ <h3 class="text-xl font-semibold text-gray-900 mb-3">Update your eventcatalog.config.js file</h3>
201
+ <p class="text-gray-600 mb-4">
202
+ Add the customDocs configuration to your eventcatalog.config.js file to define your sidebar structure.
203
+ </p>
204
+ <Code code={configExample} lang="js" frame="terminal" />
205
+ <p class="text-gray-600 mt-4">
206
+ This configuration defines the sidebar structure for your custom documentation:
207
+ </p>
208
+ <ul class="list-disc list-inside text-gray-600 mt-2 ml-2 space-y-1">
209
+ <li>
210
+ <strong>label</strong>: The display name for each sidebar section
211
+ </li>
212
+ <li>
213
+ <strong>badge</strong>: Optional badge to highlight new sections
214
+ </li>
215
+ <li>
216
+ <strong>collapsed</strong>: Whether the section is collapsed by default
217
+ </li>
218
+ <li>
219
+ <strong>autogenerated</strong>: Automatically generate sidebar items from a directory
220
+ </li>
221
+ <li>
222
+ <strong>slug</strong>: Direct link to a specific page
223
+ </li>
224
+ </ul>
225
+ </div>
226
+ </div>
227
+ </div>
228
+
229
+ <div class="bg-white p-6 rounded-lg shadow-sm border border-gray-200">
230
+ <div class="flex items-start gap-4">
231
+ <div class="inline-flex items-center justify-center w-8 h-8 rounded-full bg-blue-100 text-blue-600 text-lg font-medium shrink-0 mt-1">
232
+ 4
233
+ </div>
234
+ <div class="w-full">
235
+ <h3 class="text-xl font-semibold text-gray-900 mb-3">Restart EventCatalog</h3>
236
+ <p class="text-gray-600 mb-4">
237
+ After configuring your documentation, restart EventCatalog to see your custom documentation.
238
+ </p>
239
+ <div class="mb-4">
240
+ <Code code="npm run dev" lang="bash" frame="terminal" />
241
+ </div>
242
+ <p class="text-gray-600 mb-4">
243
+ Once restarted, you'll see your custom documentation displayed with the sidebar structure you defined:
244
+ </p>
245
+ <div class="border border-gray-200 rounded-lg overflow-hidden">
246
+ <img
247
+ src="/images/custom-docs-placeholder.png"
248
+ alt="Example of custom documentation interface"
249
+ class="w-full"
250
+ />
251
+ </div>
252
+ </div>
253
+ </div>
254
+ </div>
255
+ </div>
256
+ </main>
257
+ </body>
258
+ </VerticalSideBarLayout>
259
+ )
260
+ }
@@ -0,0 +1,272 @@
1
+ ---
2
+ import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
3
+ import { Star, Users, Bot, ScrollText, Component, PanelLeft, Cpu, Code, LifeBuoy, ExternalLink, Eye } from 'lucide-react';
4
+ import { buildUrl } from '@utils/url-builder';
5
+ ---
6
+
7
+ <VerticalSideBarLayout title="EventCatalog Pro">
8
+ <div class="min-h-[calc(100vh-60px)] bg-white">
9
+ {/* Hero section with solid purple background */}
10
+ <div class="bg-purple-600 pt-10 pb-20">
11
+ <div class="container px-8 lg:px-8 mx-auto max-w-[80em]">
12
+ <div class="flex flex-col pt-10">
13
+ <!-- <div class="mb-5">
14
+ <div class="inline-flex items-center px-3 py-1 rounded-full text-xs font-medium bg-white text-purple-700">
15
+ Premium Features
16
+ </div>
17
+ </div> -->
18
+
19
+ <div class="flex flex-col md:flex-row justify-between items-start">
20
+ <div class="md:w-1/2 mt-10 pr-10">
21
+ <h1 class="text-4xl md:text-5xl font-bold text-white mb-4">EventCatalog Pro</h1>
22
+ <h2 class="text-2xl font-normal text-white mb-4">Take your documentation to the next level</h2>
23
+ <p class="text-base text-white opacity-90 mb-10 max-w-2xl">
24
+ <!-- Unlock premium features to enhance your event catalog and streamline your architecture documentation. -->
25
+ Keep documentation up-to-date, reduce onboarding time, and make architectural decisions easy to find — all in one place
26
+ </p>
27
+
28
+ <div class="flex flex-col sm:flex-row gap-4">
29
+ <a
30
+ href="https://www.eventcatalog.dev/pricing"
31
+ class="inline-flex items-center justify-center px-6 py-2.5 bg-white text-purple-700 text-sm font-medium rounded transition-colors hover:bg-purple-50"
32
+ >
33
+ Upgrade to Pro
34
+ <ExternalLink className="w-4 h-4 ml-1.5" />
35
+ </a>
36
+ </div>
37
+ <span class="text-white text-[12px] mt-4 block"> Get 14 day trial - no credit card required </span>
38
+ </div>
39
+
40
+ <div class="md:w-1/2 flex justify-center md:justify-end items-center mt-10 md:mt-0">
41
+ <div class="flex flex-col items-center">
42
+ <img
43
+ src="/images/custom-docs-placeholder.png"
44
+ alt="EventCatalog Pro Features"
45
+ class="rounded-md shadow-md max-w-full h-auto w-full object-cover"
46
+ />
47
+ <p class="text-white text-xs block w-full mt-2 font-medium text-right">Custom documentation example</p>
48
+ </div>
49
+ </div>
50
+ </div>
51
+ </div>
52
+ </div>
53
+ </div>
54
+
55
+ <main class="container px-8 lg:px-8 mx-auto py-10 max-w-[80em]">
56
+ {/* Feature Section */}
57
+ <div class="mb-14">
58
+ <h2 class="text-2xl font-semibold mb-8 text-gray-900">Premium Features</h2>
59
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
60
+ {/* Custom Documentation */}
61
+ <div
62
+ class="bg-white rounded-lg border border-gray-200 overflow-hidden hover:border-purple-200 hover:shadow-md transition-all duration-200"
63
+ >
64
+ <div class="p-6">
65
+ <div class="flex items-start gap-3 mb-3">
66
+ <div class="p-2 bg-purple-100 rounded-lg flex-shrink-0">
67
+ <ScrollText className="w-5 h-5 text-purple-600" />
68
+ </div>
69
+ <div>
70
+ <h3 class="text-lg font-semibold text-gray-900">Custom Documentation</h3>
71
+ </div>
72
+ </div>
73
+ <p class="text-gray-600 text-sm mb-3">
74
+ Add any type of documentation such as ADRs, runbooks, and technical guidelines to create a centralized knowledge
75
+ hub.
76
+ </p>
77
+ <a href={buildUrl('/docs/custom')} class="text-sm text-purple-600 hover:text-purple-700 font-medium">
78
+ Learn more →
79
+ </a>
80
+ </div>
81
+ </div>
82
+
83
+ {/* AI Assistant */}
84
+ <div
85
+ class="bg-white rounded-lg border border-gray-200 overflow-hidden hover:border-blue-200 hover:shadow-md transition-all duration-200"
86
+ >
87
+ <div class="p-6">
88
+ <div class="flex items-start gap-3 mb-3">
89
+ <div class="p-2 bg-blue-100 rounded-lg flex-shrink-0">
90
+ <Bot className="w-5 h-5 text-blue-600" />
91
+ </div>
92
+ <div>
93
+ <h3 class="text-lg font-semibold text-gray-900">AI Assistant</h3>
94
+ </div>
95
+ </div>
96
+ <p class="text-gray-600 text-sm mb-3">
97
+ Chat with your catalog to quickly find information and get instant answers about your architecture.
98
+ </p>
99
+ <a href={buildUrl('/chat')} class="text-sm text-blue-600 hover:text-blue-700 font-medium"> Learn more → </a>
100
+ </div>
101
+ </div>
102
+
103
+ {/* EventCatalog Federation */}
104
+ <div
105
+ class="bg-white rounded-lg border border-gray-200 overflow-hidden hover:border-green-200 hover:shadow-md transition-all duration-200"
106
+ >
107
+ <div class="p-6">
108
+ <div class="flex items-start gap-3 mb-3">
109
+ <div class="p-2 bg-green-100 rounded-lg flex-shrink-0">
110
+ <Component className="w-5 h-5 text-green-600" />
111
+ </div>
112
+ <div>
113
+ <h3 class="text-lg font-semibold text-gray-900">Federation</h3>
114
+ </div>
115
+ </div>
116
+ <p class="text-gray-600 text-sm mb-3">
117
+ Connect 1-3 separate event catalogs into a unified view for centralized visibility across teams.
118
+ </p>
119
+ <a
120
+ href="https://www.eventcatalog.dev/features/federation"
121
+ class="text-sm text-green-600 hover:text-green-700 font-medium"
122
+ >
123
+ Learn more →
124
+ </a>
125
+ </div>
126
+ </div>
127
+
128
+ {/* IDE Integration */}
129
+ <div
130
+ class="bg-white rounded-lg border border-gray-200 overflow-hidden hover:border-indigo-200 hover:shadow-md transition-all duration-200"
131
+ >
132
+ <div class="p-6">
133
+ <div class="flex items-start gap-3 mb-3">
134
+ <div class="p-2 bg-indigo-100 rounded-lg flex-shrink-0">
135
+ <Code className="w-5 h-5 text-indigo-600" />
136
+ </div>
137
+ <div>
138
+ <h3 class="text-lg font-semibold text-gray-900">IDE Integration</h3>
139
+ </div>
140
+ </div>
141
+ <p class="text-gray-600 text-sm mb-3">
142
+ Access EventCatalog directly from your IDE for seamless documentation while coding.
143
+ </p>
144
+ <a
145
+ href="https://www.eventcatalog.dev/features/ide"
146
+ class="text-sm text-indigo-600 hover:text-indigo-700 font-medium"
147
+ >
148
+ Learn more →
149
+ </a>
150
+ </div>
151
+ </div>
152
+
153
+ {/* Automated Documentation */}
154
+ <div
155
+ class="bg-white rounded-lg border border-gray-200 overflow-hidden hover:border-yellow-200 hover:shadow-md transition-all duration-200"
156
+ >
157
+ <div class="p-6">
158
+ <div class="flex items-start gap-3 mb-3">
159
+ <div class="p-2 bg-yellow-100 rounded-lg flex-shrink-0">
160
+ <Cpu className="w-5 h-5 text-yellow-600" />
161
+ </div>
162
+ <div>
163
+ <h3 class="text-lg font-semibold text-gray-900">Automated Documentation</h3>
164
+ </div>
165
+ </div>
166
+ <p class="text-gray-600 text-sm mb-3">
167
+ Automate the generation and maintenance of your EventCatalog documentation with integrations (e.g generate
168
+ catalogs from AsyncAPI and OpenAPI)
169
+ </p>
170
+ <a
171
+ href="https://www.eventcatalog.dev/features/automation"
172
+ class="text-sm text-yellow-600 hover:text-yellow-700 font-medium"
173
+ >
174
+ Learn more →
175
+ </a>
176
+ </div>
177
+ </div>
178
+
179
+ {/* Priority Support */}
180
+ <div
181
+ class="bg-white rounded-lg border border-gray-200 overflow-hidden hover:border-red-200 hover:shadow-md transition-all duration-200"
182
+ >
183
+ <div class="p-6">
184
+ <div class="flex items-start gap-3 mb-3">
185
+ <div class="p-2 bg-red-100 rounded-lg flex-shrink-0">
186
+ <LifeBuoy className="w-5 h-5 text-red-600" />
187
+ </div>
188
+ <div>
189
+ <h3 class="text-lg font-semibold text-gray-900">Priority Support</h3>
190
+ </div>
191
+ </div>
192
+ <p class="text-gray-600 text-sm mb-3">Get priority email support and assistance from the EventCatalog team.</p>
193
+ <a href="https://www.eventcatalog.dev/support" class="text-sm text-red-600 hover:text-red-700 font-medium">
194
+ Learn more →
195
+ </a>
196
+ </div>
197
+ </div>
198
+ </div>
199
+ </div>
200
+
201
+ {/* Why Upgrade section - value bullet bar */}
202
+ <div class="mb-10 bg-gray-50 p-6 rounded-lg border border-gray-100">
203
+ <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
204
+ <div class="flex items-center">
205
+ <div class="p-2 bg-purple-100 rounded-lg mr-3 flex-shrink-0">
206
+ <ScrollText className="w-5 h-5 text-purple-600" />
207
+ </div>
208
+ <span class="text-sm font-medium text-gray-800">Automated documentation</span>
209
+ </div>
210
+ <div class="flex items-center">
211
+ <div class="p-2 bg-indigo-100 rounded-lg mr-3 flex-shrink-0">
212
+ <Code className="w-5 h-5 text-indigo-600" />
213
+ </div>
214
+ <span class="text-sm font-medium text-gray-800">Integrated with your IDE</span>
215
+ </div>
216
+ <div class="flex items-center">
217
+ <div class="p-2 bg-blue-100 rounded-lg mr-3 flex-shrink-0">
218
+ <Bot className="w-5 h-5 text-blue-600" />
219
+ </div>
220
+ <span class="text-sm font-medium text-gray-800">AI-powered search</span>
221
+ </div>
222
+ <div class="flex items-center">
223
+ <div class="p-2 bg-green-100 rounded-lg mr-3 flex-shrink-0">
224
+ <Component className="w-5 h-5 text-green-600" />
225
+ </div>
226
+ <span class="text-sm font-medium text-gray-800">Unified view across teams</span>
227
+ </div>
228
+ </div>
229
+ </div>
230
+
231
+ {/* Ready to upgrade section */}
232
+ <div class="mb-14">
233
+ <h2 class="text-2xl font-semibold mb-6 text-gray-900">Ready to upgrade?</h2>
234
+ <div class="flex flex-col md:flex-row justify-between md:items-center bg-gray-50 p-8 rounded-lg border border-gray-200">
235
+ <div class="mb-6 md:mb-0">
236
+ <p class="text-gray-700 mb-2">Get started with EventCatalog Pro today and unlock all premium features.</p>
237
+ </div>
238
+ <a
239
+ href="https://www.eventcatalog.dev/pricing"
240
+ class="flex items-center justify-center px-5 py-2.5 bg-purple-600 text-white text-sm font-medium rounded hover:bg-purple-700 transition-colors"
241
+ >
242
+ View pricing and plans
243
+ <ExternalLink className="w-4 h-4 ml-1.5" />
244
+ </a>
245
+ </div>
246
+ </div>
247
+
248
+ {/* Questions section */}
249
+ <div class="mb-14">
250
+ <h2 class="text-2xl font-semibold mb-6 text-gray-900">Questions about EventCatalog Pro?</h2>
251
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
252
+ <div class="bg-white p-6 rounded-lg border border-gray-200">
253
+ <h3 class="text-lg font-semibold text-gray-900 mb-3">Request a Demo</h3>
254
+ <p class="text-gray-600 text-sm mb-4">See EventCatalog Pro in action with a personalized demo from our team.</p>
255
+ <a href="https://www.eventcatalog.dev/demo" class="text-sm text-purple-600 hover:text-purple-700 font-medium">
256
+ Schedule a demo →
257
+ </a>
258
+ </div>
259
+ <div class="bg-white p-6 rounded-lg border border-gray-200">
260
+ <h3 class="text-lg font-semibold text-gray-900 mb-3">Contact Sales</h3>
261
+ <p class="text-gray-600 text-sm mb-4">
262
+ Have questions about pricing, features, or implementation? Our team is here to help.
263
+ </p>
264
+ <a href="mailto:sales@eventcatalog.dev" class="text-sm text-purple-600 hover:text-purple-700 font-medium">
265
+ Contact our sales team →
266
+ </a>
267
+ </div>
268
+ </div>
269
+ </div>
270
+ </main>
271
+ </div>
272
+ </VerticalSideBarLayout>