@goldlabelapps/theme 3.2.0 → 3.5.6
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/README.md +2 -2
- package/dist/components/RenderMarkdown.d.ts +7 -0
- package/dist/components/RenderMarkdown.js +123 -0
- package/dist/components/download/DownloadBanner.js +1 -8
- package/dist/components/footer/Footer.js +6 -3
- package/dist/components/footer/FooterWrapper.d.ts +7 -0
- package/dist/components/footer/FooterWrapper.js +15 -0
- package/dist/components/footer/NXContactColumn.d.ts +13 -0
- package/dist/components/footer/NXContactColumn.js +32 -0
- package/dist/components/footer/NXLiveApps.d.ts +22 -0
- package/dist/components/footer/NXLiveApps.js +87 -0
- package/dist/components/footer/NXSocialColumn.d.ts +14 -0
- package/dist/components/footer/NXSocialColumn.js +17 -0
- package/dist/components/footer/NXTagsColumn.d.ts +14 -0
- package/dist/components/footer/NXTagsColumn.js +31 -0
- package/dist/components/footer/index.d.ts +6 -0
- package/dist/components/footer/index.js +6 -0
- package/dist/components/hero/HeroSection.js +1 -1
- package/dist/components/hero/VideoModal.js +1 -2
- package/dist/components/index.d.ts +11 -3
- package/dist/components/index.js +11 -3
- package/dist/components/layouts/GuideBreadcrumbs.d.ts +14 -0
- package/dist/components/layouts/GuideBreadcrumbs.js +15 -0
- package/dist/components/layouts/MarkdownContent.js +6 -0
- package/dist/components/layouts/Standard.d.ts +10 -0
- package/dist/components/layouts/Standard.js +7 -0
- package/dist/components/navigation/DropdownMenu.js +1 -1
- package/dist/components/navigation/Header.js +3 -6
- package/dist/components/navigation/LayoutActions.d.ts +7 -0
- package/dist/components/navigation/LayoutActions.js +12 -0
- package/dist/components/navigation/LogoContextMenu.d.ts +0 -1
- package/dist/components/navigation/LogoContextMenu.js +1 -2
- package/dist/components/navigation/MarkdownMenu.d.ts +9 -0
- package/dist/components/navigation/MarkdownMenu.js +12 -0
- package/dist/components/navigation/MobileMenu.js +16 -7
- package/dist/components/navigation/ShareMenu.d.ts +1 -1
- package/dist/components/navigation/ShareMenu.js +1 -2
- package/dist/components/navigation/Waiting.d.ts +10 -0
- package/dist/components/navigation/Waiting.js +45 -0
- package/dist/components/search/HeroSearchBar.d.ts +16 -0
- package/dist/components/search/HeroSearchBar.js +38 -0
- package/dist/components/search/SearchDialog.d.ts +11 -0
- package/dist/components/search/SearchDialog.js +69 -0
- package/dist/components/search/SearchIconButton.d.ts +10 -0
- package/dist/components/search/SearchIconButton.js +10 -0
- package/dist/components/search/SearchResultsList.d.ts +13 -0
- package/dist/components/search/SearchResultsList.js +18 -0
- package/dist/components/search/index.d.ts +5 -0
- package/dist/components/search/index.js +5 -0
- package/dist/components/search/useSearch.d.ts +54 -0
- package/dist/components/search/useSearch.js +106 -0
- package/dist/components/shortcodes/PageLinkShortcode.d.ts +15 -0
- package/dist/components/shortcodes/PageLinkShortcode.js +51 -0
- package/dist/components/showcase/BlogSection.js +2 -2
- package/dist/components/showcase/FeatureExplorer.js +2 -2
- package/dist/components/showcase/FeaturedCard.d.ts +13 -0
- package/dist/components/showcase/FeaturedCard.js +6 -0
- package/dist/components/showcase/SolutionsSection.js +2 -2
- package/dist/components/showcase/StatementSection.js +1 -1
- package/dist/components/showcase/VideoSection.js +2 -2
- package/dist/components/ui/Bash.d.ts +16 -0
- package/dist/components/ui/Bash.js +30 -0
- package/dist/components/ui/Button.js +1 -1
- package/dist/components/ui/Card.d.ts +2 -1
- package/dist/components/ui/Card.js +29 -7
- package/dist/components/ui/ThemeToggle.d.ts +5 -1
- package/dist/components/ui/ThemeToggle.js +32 -2
- package/dist/components/video/VideoLayout.js +2 -2
- package/dist/context/ConfigContext.js +1 -1
- package/dist/context/ThemeContext.d.ts +4 -0
- package/dist/context/ThemeContext.js +23 -18
- package/dist/data/og-images.json +530 -0
- package/dist/design-system/components/DesignSystemProvider/DesignSystemProvider.js +4 -9
- package/dist/design-system/components/buttons/Button/Button.js +6 -3
- package/dist/design-system/components/buttons/IconButton/IconButton.js +6 -3
- package/dist/design-system/components/feedback/Alert/Alert.js +45 -7
- package/dist/design-system/components/feedback/Card/Card.d.ts +1 -1
- package/dist/design-system/components/feedback/Card/Card.js +15 -9
- package/dist/design-system/components/headings/Heading/Heading.js +2 -1
- package/dist/design-system/components/icons/SVGIcons/BlokeyIcon.d.ts +2 -1
- package/dist/design-system/components/icons/SVGIcons/BlokeyIcon.js +1 -1
- package/dist/design-system/components/icons/SVGIcons/ChromeIcon.d.ts +2 -1
- package/dist/design-system/components/icons/SVGIcons/ChromeIcon.js +1 -1
- package/dist/design-system/components/icons/SVGIcons/DesktopIcon.d.ts +2 -1
- package/dist/design-system/components/icons/SVGIcons/DesktopIcon.js +1 -1
- package/dist/design-system/components/icons/SVGIcons/EdgeIcon.d.ts +2 -1
- package/dist/design-system/components/icons/SVGIcons/EdgeIcon.js +1 -1
- package/dist/design-system/components/icons/SVGIcons/FallmanagerIcon.d.ts +2 -1
- package/dist/design-system/components/icons/SVGIcons/FirefoxIcon.d.ts +2 -1
- package/dist/design-system/components/icons/SVGIcons/FirefoxIcon.js +1 -1
- package/dist/design-system/components/icons/SVGIcons/FlickrIcon.d.ts +2 -1
- package/dist/design-system/components/icons/SVGIcons/FlickrIcon.js +1 -1
- package/dist/design-system/components/icons/SVGIcons/GatsbyIcon.d.ts +2 -1
- package/dist/design-system/components/icons/SVGIcons/GoldenticketIcon.d.ts +2 -1
- package/dist/design-system/components/icons/SVGIcons/GoldenticketIcon.js +1 -1
- package/dist/design-system/components/icons/SVGIcons/GoldlabelOutlined.d.ts +2 -1
- package/dist/design-system/components/icons/SVGIcons/GraphqlIcon.d.ts +2 -1
- package/dist/design-system/components/icons/SVGIcons/GraphqlIcon.js +1 -1
- package/dist/design-system/components/icons/SVGIcons/IphoneIcon.d.ts +2 -1
- package/dist/design-system/components/icons/SVGIcons/IphoneIcon.js +1 -1
- package/dist/design-system/components/icons/SVGIcons/LinuxIcon.d.ts +2 -1
- package/dist/design-system/components/icons/SVGIcons/LinuxIcon.js +1 -1
- package/dist/design-system/components/icons/SVGIcons/MacIcon.d.ts +2 -1
- package/dist/design-system/components/icons/SVGIcons/MacIcon.js +1 -1
- package/dist/design-system/components/icons/SVGIcons/MacromediaIcon.d.ts +2 -1
- package/dist/design-system/components/icons/SVGIcons/MacromediaIcon.js +1 -1
- package/dist/design-system/components/icons/SVGIcons/OliverIcon.d.ts +2 -1
- package/dist/design-system/components/icons/SVGIcons/OpenAIIcon.d.ts +2 -1
- package/dist/design-system/components/icons/SVGIcons/PingpongballIcon.d.ts +2 -1
- package/dist/design-system/components/icons/SVGIcons/SafariIcon.d.ts +2 -1
- package/dist/design-system/components/icons/SVGIcons/SafariIcon.js +1 -1
- package/dist/design-system/components/icons/SVGIcons/WindowsIcon.d.ts +2 -1
- package/dist/design-system/components/icons/SVGIcons/WindowsIcon.js +1 -1
- package/dist/design-system/components/icons/SVGIcons/WordpressIcon.d.ts +2 -1
- package/dist/design-system/components/icons/SVGIcons/WordpressIcon.js +1 -1
- package/dist/design-system/components/icons/SVGIcons/XboxIcon.d.ts +2 -1
- package/dist/design-system/components/icons/SVGIcons/XboxIcon.js +1 -1
- package/dist/design-system/components/images/FeaturedImage/FeaturedImage.d.ts +1 -1
- package/dist/design-system/components/images/FeaturedImage/FeaturedImage.js +73 -25
- package/dist/design-system/components/images/FeaturedImage/types.d.ts +1 -1
- package/dist/design-system/components/layout/Footer/Footer.js +1 -1
- package/dist/design-system/components/layout/index.d.ts +1 -0
- package/dist/design-system/components/layout/index.js +1 -0
- package/dist/design-system/components/navigation/SiteNav/SiteNav.js +1 -1
- package/dist/design-system/components/nxStyle.d.ts +39 -0
- package/dist/design-system/components/nxStyle.js +40 -14
- package/dist/design-system/types.d.ts +1 -0
- package/dist/design-system/types.js +1 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.js +2 -0
- package/dist/styles/globals.css +150 -3
- package/dist/styles/site-layout.css +1 -1
- package/dist/styles/theme.js +106 -7
- package/dist/styles/tokens.css +65 -0
- package/dist/types/index.d.ts +220 -0
- package/package.json +5 -2
- package/dist/components/guide/GuideLayout.d.ts +0 -8
- package/dist/components/guide/GuideLayout.js +0 -12
- package/dist/components/guide/MarkdownContent.js +0 -6
- /package/dist/components/{guide → layouts}/MarkdownContent.d.ts +0 -0
package/README.md
CHANGED
|
@@ -43,13 +43,13 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
|
|
43
43
|
- **Hero & Canvas**: `HeroSection`, `ParticleCanvas`, `VideoModal`
|
|
44
44
|
- **Navigation & Footer**: `Header`, `Footer`, `DropdownMenu`, `MobileMenu`, `ShareMenu`, `BrandLogo`, `LogoContextMenu`
|
|
45
45
|
- **Showcase Blocks**: `FeatureExplorer`, `SolutionsSection`, `StatementSection`, `UseCaseSlider`, `VideoSection`, `BlogSection`
|
|
46
|
-
- **Lead Capture & Guides**: `DownloadBanner`, `
|
|
46
|
+
- **Lead Capture & Guides**: `DownloadBanner`, `Standard`, `MarkdownContent`, `VideoLayout`
|
|
47
47
|
- **Context & Config**: `ConfigProvider`, `useSiteConfig`, `ThemeProvider`, `useTheme`
|
|
48
48
|
- **Utilities & Types**: `cn`, `detectUserOS`, full TypeScript definitions (`SiteConfig`, `BrandConfig`, etc.)
|
|
49
49
|
|
|
50
50
|
## Reference Implementation
|
|
51
51
|
|
|
52
|
-
The [`apps/
|
|
52
|
+
The [`apps/goldlabel`](../../apps/goldlabel) application serves as the complete reference implementation demonstrating how to build a fully config-driven Next.js app using `@goldlabelapps/theme`.
|
|
53
53
|
|
|
54
54
|
## License
|
|
55
55
|
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import ReactMarkdown from 'react-markdown';
|
|
5
|
+
import { CleverTextShortcode, FlashMovieShortcode } from '@goldlabelapps/flash';
|
|
6
|
+
import PageLinkShortcode from './shortcodes/PageLinkShortcode';
|
|
7
|
+
export default function RenderMarkdown({ children = '', config, }) {
|
|
8
|
+
// --- Normalize children to array to prevent map errors ---
|
|
9
|
+
const normalizeChildren = (children) => Array.isArray(children) ? children : [children];
|
|
10
|
+
const isBlockLikeNode = (node) => {
|
|
11
|
+
if (!React.isValidElement(node))
|
|
12
|
+
return false;
|
|
13
|
+
if (node.type === React.Fragment)
|
|
14
|
+
return false;
|
|
15
|
+
if (typeof node.type !== 'string')
|
|
16
|
+
return true;
|
|
17
|
+
const inlineTags = new Set([
|
|
18
|
+
'a',
|
|
19
|
+
'abbr',
|
|
20
|
+
'b',
|
|
21
|
+
'bdi',
|
|
22
|
+
'bdo',
|
|
23
|
+
'br',
|
|
24
|
+
'cite',
|
|
25
|
+
'code',
|
|
26
|
+
'data',
|
|
27
|
+
'dfn',
|
|
28
|
+
'em',
|
|
29
|
+
'i',
|
|
30
|
+
'img',
|
|
31
|
+
'kbd',
|
|
32
|
+
'label',
|
|
33
|
+
'mark',
|
|
34
|
+
'q',
|
|
35
|
+
'ruby',
|
|
36
|
+
's',
|
|
37
|
+
'samp',
|
|
38
|
+
'small',
|
|
39
|
+
'span',
|
|
40
|
+
'strong',
|
|
41
|
+
'sub',
|
|
42
|
+
'sup',
|
|
43
|
+
'time',
|
|
44
|
+
'u',
|
|
45
|
+
'var',
|
|
46
|
+
'wbr',
|
|
47
|
+
]);
|
|
48
|
+
return !inlineTags.has(node.type);
|
|
49
|
+
};
|
|
50
|
+
const renderChildrenWithShortcodes = (children) => normalizeChildren(children).map((child, index) => {
|
|
51
|
+
const renderedChild = typeof child === 'string' ? renderShortcode(child) : child;
|
|
52
|
+
if (React.isValidElement(renderedChild)) {
|
|
53
|
+
return React.cloneElement(renderedChild, {
|
|
54
|
+
key: renderedChild.key ?? `md-${index}`,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return renderedChild;
|
|
58
|
+
});
|
|
59
|
+
// --- Shortcode parser ---
|
|
60
|
+
const renderShortcode = (text) => {
|
|
61
|
+
const parseShortcode = (regex, Component, extraProps = {}) => {
|
|
62
|
+
const match = text.match(regex);
|
|
63
|
+
if (!match)
|
|
64
|
+
return null;
|
|
65
|
+
const attrs = match[1];
|
|
66
|
+
const props = {};
|
|
67
|
+
const attrRegex = /(\w+)\s*=\s*(?:"([^"]*)"|'([^']*)')/g;
|
|
68
|
+
let attrMatch;
|
|
69
|
+
while ((attrMatch = attrRegex.exec(attrs)) !== null) {
|
|
70
|
+
let val = attrMatch[2] ?? attrMatch[3];
|
|
71
|
+
if (!isNaN(Number(val))) {
|
|
72
|
+
val = Number(val);
|
|
73
|
+
}
|
|
74
|
+
else if (val === 'true' || val === 'false') {
|
|
75
|
+
val = val === 'true';
|
|
76
|
+
}
|
|
77
|
+
props[attrMatch[1]] = val;
|
|
78
|
+
}
|
|
79
|
+
return _jsx(Component, { ...props, ...extraProps, config: config });
|
|
80
|
+
};
|
|
81
|
+
// CleverText
|
|
82
|
+
const cleverText = parseShortcode(/\[CleverText\s+(.*?)\]/, CleverTextShortcode);
|
|
83
|
+
if (cleverText)
|
|
84
|
+
return cleverText;
|
|
85
|
+
// FlashMovie
|
|
86
|
+
const flashMovie = parseShortcode(/\[FlashMovie\s+(.*?)\]/, FlashMovieShortcode);
|
|
87
|
+
if (flashMovie)
|
|
88
|
+
return flashMovie;
|
|
89
|
+
// PageLink
|
|
90
|
+
const pageLink = parseShortcode(/\[PageLink\s+([\s\S]*?)\]/, PageLinkShortcode);
|
|
91
|
+
if (pageLink)
|
|
92
|
+
return pageLink;
|
|
93
|
+
// fallback: simply return text
|
|
94
|
+
return text;
|
|
95
|
+
};
|
|
96
|
+
return (_jsx("div", { children: _jsx(ReactMarkdown, { components: {
|
|
97
|
+
h1: ({ children }) => _jsx("h1", { children: children }),
|
|
98
|
+
h2: ({ children }) => _jsx("h2", { children: children }),
|
|
99
|
+
h3: ({ children }) => _jsx("h3", { children: children }),
|
|
100
|
+
p: ({ children }) => {
|
|
101
|
+
const renderedChildren = renderChildrenWithShortcodes(children);
|
|
102
|
+
const hasBlockChild = renderedChildren.some(isBlockLikeNode);
|
|
103
|
+
if (hasBlockChild) {
|
|
104
|
+
return _jsx("div", { children: renderedChildren });
|
|
105
|
+
}
|
|
106
|
+
return _jsx("p", { children: renderedChildren });
|
|
107
|
+
},
|
|
108
|
+
li: ({ children }) => {
|
|
109
|
+
const renderedChildren = renderChildrenWithShortcodes(children);
|
|
110
|
+
const hasBlockChild = renderedChildren.some(isBlockLikeNode);
|
|
111
|
+
if (hasBlockChild) {
|
|
112
|
+
return _jsx("li", { children: renderedChildren });
|
|
113
|
+
}
|
|
114
|
+
return _jsx("li", { children: _jsx("span", { children: renderedChildren }) });
|
|
115
|
+
},
|
|
116
|
+
strong: ({ children }) => _jsx("span", { children: children }),
|
|
117
|
+
em: ({ children }) => _jsx("em", { children: children }),
|
|
118
|
+
a: ({ href = '', children }) => {
|
|
119
|
+
const isExternal = /^https?:\/\//.test(href);
|
|
120
|
+
return (_jsx("a", { href: href, target: isExternal ? '_blank' : '_self', rel: isExternal ? 'noopener noreferrer' : undefined, children: children }));
|
|
121
|
+
},
|
|
122
|
+
}, children: children }) }));
|
|
123
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useState } from "react";
|
|
4
|
-
import confetti from "canvas-confetti";
|
|
5
4
|
import { useSiteConfig } from "../../context/ConfigContext";
|
|
6
5
|
import { Button } from "../ui/Button";
|
|
7
6
|
import { Terminal, Copy, Check, Mail, CheckCircle2, } from "lucide-react";
|
|
@@ -15,12 +14,6 @@ export function DownloadBanner({ config }) {
|
|
|
15
14
|
e.preventDefault();
|
|
16
15
|
if (!email)
|
|
17
16
|
return;
|
|
18
|
-
confetti({
|
|
19
|
-
particleCount: 80,
|
|
20
|
-
spread: 70,
|
|
21
|
-
origin: { y: 0.85 },
|
|
22
|
-
colors: ["#012867", "#64748B", "#38BDF8", "#01358d", "#0F172A"],
|
|
23
|
-
});
|
|
24
17
|
setSubmitted(true);
|
|
25
18
|
};
|
|
26
19
|
const handleCopyCommand = async () => {
|
|
@@ -33,5 +26,5 @@ export function DownloadBanner({ config }) {
|
|
|
33
26
|
// ignore
|
|
34
27
|
}
|
|
35
28
|
};
|
|
36
|
-
return (_jsxs("section", { id: "download", className: "py-24 sm:py-36 relative bg-white overflow-hidden transition-colors duration-200", children: [_jsx("a", { id: "signup", "aria-hidden": "true", className: "sr-only", children: "Sign up" }), _jsx("div", { className: "pointer-events-none absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[700px] sm:w-[1000px] h-[500px] bg-gradient-to-tr from-[#012867]/15 via-slate-500/10 to-slate-400/10 rounded-full blur-3xl opacity-75" }), _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10", children: _jsxs("div", { className: "rounded-3xl sm:rounded-[40px] bg-gradient-to-b from-slate-50 via-white to-slate-50 border border-slate-200 p-8 sm:p-14 lg:p-20 shadow-2xl relative overflow-hidden text-center", children: [_jsx("div", { className: "inline-flex items-center gap-2 px-3.5 py-1 rounded-full bg-[#012867]/[0.06] border border-[#012867]/15 text-xs font-bold text-[#012867] mb-6 backdrop-blur-md", children: _jsx("span", { children: authCta.badge }) }), _jsx("h2", { className: "text-3xl sm:text-5xl lg:text-6xl font-
|
|
29
|
+
return (_jsxs("section", { id: "download", className: "py-24 sm:py-36 relative bg-white overflow-hidden transition-colors duration-200", children: [_jsx("a", { id: "signup", "aria-hidden": "true", className: "sr-only", children: "Sign up" }), _jsx("div", { className: "pointer-events-none absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[700px] sm:w-[1000px] h-[500px] bg-gradient-to-tr from-[#012867]/15 via-slate-500/10 to-slate-400/10 rounded-full blur-3xl opacity-75" }), _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10", children: _jsxs("div", { className: "rounded-3xl sm:rounded-[40px] bg-gradient-to-b from-slate-50 via-white to-slate-50 border border-slate-200 p-8 sm:p-14 lg:p-20 shadow-2xl relative overflow-hidden text-center", children: [_jsx("div", { className: "inline-flex items-center gap-2 px-3.5 py-1 rounded-full bg-[#012867]/[0.06] border border-[#012867]/15 text-xs font-bold text-[#012867] mb-6 backdrop-blur-md", children: _jsx("span", { children: authCta.badge }) }), _jsx("h2", { className: "text-3xl sm:text-5xl lg:text-6xl font-normal text-slate-900 tracking-tight max-w-3xl mx-auto leading-tight mb-4", children: authCta.title }), _jsx("p", { className: "text-base sm:text-lg text-slate-600 max-w-2xl mx-auto leading-relaxed mb-10", children: authCta.subtitle }), !submitted ? (_jsxs("form", { onSubmit: handleEmailSubmit, className: "max-w-md mx-auto mb-8 flex flex-col sm:flex-row gap-3", children: [_jsxs("div", { className: "relative flex-1", children: [_jsx(Mail, { className: "absolute left-4 top-1/2 -translate-y-1/2 h-4 w-4 text-slate-400" }), _jsx("input", { type: "email", required: true, value: email, onChange: (e) => setEmail(e.target.value), placeholder: "Enter your business email", className: "w-full pl-11 pr-4 py-3 rounded-full bg-white dark:bg-slate-800 border border-slate-300 dark:border-slate-700 text-slate-900 dark:text-slate-100 text-sm focus:outline-none focus:ring-2 focus:ring-[#012867] dark:focus:ring-blue-400 shadow-inner" })] }), _jsx(Button, { type: "submit", variant: "primary", size: "md", children: "Get Started" })] })) : (_jsxs("div", { className: "max-w-md mx-auto mb-8 p-4 rounded-2xl bg-emerald-50 border border-emerald-200 text-emerald-800 text-sm font-semibold flex items-center justify-center gap-2", children: [_jsx(CheckCircle2, { className: "h-5 w-5 text-emerald-600" }), _jsxs("span", { children: ["Setup guide & download dispatched to ", email] })] })), _jsxs("div", { className: "flex flex-wrap items-center justify-center gap-4 mb-8", children: [_jsx(Button, { href: authCta.primaryCta.href, variant: "primary", size: "lg", children: authCta.primaryCta.label }), _jsx(Button, { href: authCta.secondaryCta.href, variant: "secondary", size: "lg", children: authCta.secondaryCta.label })] }), authCta.cliQuickInstall && (_jsxs("div", { className: "inline-flex items-center gap-3 px-4 py-2 rounded-2xl bg-slate-900 text-slate-200 text-xs font-mono border border-slate-800 shadow-md", children: [_jsx(Terminal, { className: "h-4 w-4 text-emerald-400" }), _jsx("span", { children: authCta.cliQuickInstall.command }), _jsx("button", { type: "button", onClick: handleCopyCommand, className: "p-1 text-slate-400 hover:text-white transition-colors cursor-pointer", children: copied ? _jsx(Check, { className: "h-3.5 w-3.5 text-emerald-400" }) : _jsx(Copy, { className: "h-3.5 w-3.5" }) })] }))] }) })] }));
|
|
37
30
|
}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import Link from "
|
|
3
|
+
import { AppRouterLink as Link } from "@goldlabelapps/uberedux";
|
|
4
4
|
import { useSiteConfig } from "../../context/ConfigContext";
|
|
5
5
|
import { BrandLogo } from "../navigation/LogoContextMenu";
|
|
6
|
-
import {
|
|
6
|
+
import { NXLiveApps } from "./NXLiveApps";
|
|
7
|
+
import { NXTagsColumn } from "./NXTagsColumn";
|
|
8
|
+
import { NXSocialColumn } from "./NXSocialColumn";
|
|
9
|
+
import { NXContactColumn } from "./NXContactColumn";
|
|
7
10
|
export function Footer() {
|
|
8
11
|
const siteConfig = useSiteConfig();
|
|
9
|
-
return (_jsx("footer", { className: "bg-slate-50 border-t border-slate-200 text-slate-500 text-xs sm:text-sm transition-colors duration-200", children: _jsxs("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16 sm:py-20", children: [_jsxs("div", { className: "flex flex-col md:flex-row items-start md:items-center justify-between gap-6 pb-12 border-b border-slate-200", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx(BrandLogo, {}), _jsx("span", { className: "text-slate-300 font-mono text-xs", children: "\u2022" }), _jsx("span", { className: "text-slate-700 font-medium", children: siteConfig.footer.tagline })] }), _jsx("div", { className: "text-xs text-slate-500", children: siteConfig.footer.address || "Goldlabel Apps" })] }),
|
|
12
|
+
return (_jsx("footer", { className: "bg-slate-50 dark:bg-slate-900 border-t border-slate-200 dark:border-slate-800 text-slate-500 dark:text-slate-400 text-xs sm:text-sm transition-colors duration-200", children: _jsxs("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16 sm:py-20", children: [_jsxs("div", { className: "flex flex-col md:flex-row items-start md:items-center justify-between gap-6 pb-12 border-b border-slate-200 dark:border-slate-800", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx(BrandLogo, {}), _jsx("span", { className: "text-slate-300 dark:text-slate-600 font-mono text-xs", children: "\u2022" }), _jsx("span", { className: "text-slate-700 dark:text-slate-200 font-medium", children: siteConfig.footer.tagline })] }), _jsx("div", { className: "text-xs text-slate-500 dark:text-slate-400", children: siteConfig.footer.address || "Goldlabel Apps" })] }), _jsxs("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-8 py-12", children: [_jsx(NXLiveApps, {}), _jsx(NXTagsColumn, {}), _jsx(NXSocialColumn, { links: siteConfig.footer.socialLinks }), _jsx(NXContactColumn, {})] }), _jsxs("div", { className: "pt-8 border-t border-slate-200 dark:border-slate-800 flex flex-col md:flex-row items-center justify-between gap-4 text-xs text-slate-500 dark:text-slate-400", children: [_jsx("div", { className: "flex flex-wrap items-center gap-x-6 gap-y-2", children: siteConfig.footer.bottomLinks.map((item, idx) => (_jsx(Link, { href: item.href, className: "hover:text-[#012867] dark:hover:text-white transition-colors", children: item.label }, idx))) }), _jsx("div", { children: siteConfig.footer.copyright })] })] }) }));
|
|
10
13
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface FooterWrapperProps {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
hidePrefixes?: string[];
|
|
5
|
+
hideMatcher?: (pathname: string | null) => boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function FooterWrapper({ children, hidePrefixes, hideMatcher, }: FooterWrapperProps): React.JSX.Element | null;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { usePathname } from "next/navigation";
|
|
4
|
+
export function FooterWrapper({ children, hidePrefixes = ["/godmode"], hideMatcher, }) {
|
|
5
|
+
const pathname = usePathname();
|
|
6
|
+
if (pathname) {
|
|
7
|
+
if (hidePrefixes.some((prefix) => pathname.startsWith(prefix))) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
if (hideMatcher && hideMatcher(pathname)) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return _jsx(_Fragment, { children: children });
|
|
15
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface ContactLinkItem {
|
|
3
|
+
label: string;
|
|
4
|
+
href: string;
|
|
5
|
+
external?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare const DEFAULT_CONTACT_LINKS: ContactLinkItem[];
|
|
8
|
+
export interface NXContactColumnProps {
|
|
9
|
+
links?: ContactLinkItem[];
|
|
10
|
+
title?: string;
|
|
11
|
+
className?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function NXContactColumn({ links, title, className, }: NXContactColumnProps): React.JSX.Element;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { AppRouterLink as Link, setUbereduxKey, useDispatch } from "@goldlabelapps/uberedux";
|
|
4
|
+
export const DEFAULT_CONTACT_LINKS = [
|
|
5
|
+
{ label: "goldlabel.apps@gmail.com", href: "mailto:goldlabel.apps@gmail.com", external: true },
|
|
6
|
+
{ label: "+44 07745 763 122", href: "https://wa.me/447745763122", external: true },
|
|
7
|
+
{ label: "Get in touch", href: "/#contact" },
|
|
8
|
+
];
|
|
9
|
+
export function NXContactColumn({ links = DEFAULT_CONTACT_LINKS, title = "Contact", className = "", }) {
|
|
10
|
+
let dispatch = null;
|
|
11
|
+
try {
|
|
12
|
+
dispatch = useDispatch();
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
// Redux context not available
|
|
16
|
+
}
|
|
17
|
+
const handleLinkClick = (e) => {
|
|
18
|
+
if (e.defaultPrevented || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (dispatch) {
|
|
22
|
+
dispatch(setUbereduxKey({ key: "waiting", value: true }));
|
|
23
|
+
dispatch(setUbereduxKey({ key: "loadingOverlay", value: true }));
|
|
24
|
+
dispatch(setUbereduxKey({ key: "navigation.isNavigating", value: true }));
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const contactItems = links && links.length > 0 ? links : DEFAULT_CONTACT_LINKS;
|
|
28
|
+
return (_jsxs("div", { className: `space-y-3 ${className}`, children: [_jsx("h4", { className: "text-xs font-bold text-slate-900 dark:text-slate-200 uppercase tracking-wider", children: title }), _jsx("ul", { className: "space-y-2 text-xs sm:text-sm", children: contactItems.map((item, idx) => {
|
|
29
|
+
const isExternal = item.external || item.href.startsWith("http") || item.href.startsWith("mailto");
|
|
30
|
+
return (_jsx("li", { children: isExternal ? (_jsx("a", { href: item.href, target: item.href.startsWith("http") ? "_blank" : undefined, rel: item.href.startsWith("http") ? "noopener noreferrer" : undefined, className: "inline-flex items-center gap-1 text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white transition-colors", children: _jsx("span", { children: item.label }) })) : (_jsx(Link, { href: item.href, target: "_self", onClick: handleLinkClick, className: "inline-flex items-center gap-1 text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white transition-colors", children: _jsx("span", { children: item.label }) })) }, idx));
|
|
31
|
+
}) })] }));
|
|
32
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface LiveApp {
|
|
3
|
+
name?: string;
|
|
4
|
+
label?: string;
|
|
5
|
+
href?: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
dev?: {
|
|
8
|
+
url: string;
|
|
9
|
+
};
|
|
10
|
+
prod?: {
|
|
11
|
+
url: string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export declare const DEFAULT_LIVE_APPS: LiveApp[];
|
|
15
|
+
export interface NXLiveAppsProps {
|
|
16
|
+
apps?: LiveApp[];
|
|
17
|
+
title?: string;
|
|
18
|
+
className?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function isDevEnvironment(hostname?: string): boolean;
|
|
21
|
+
export declare function isCurrentApp(app: LiveApp, currentOrigin?: string): boolean;
|
|
22
|
+
export declare function NXLiveApps({ apps, title, className, }: NXLiveAppsProps): React.JSX.Element;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { AppRouterLink as Link, setUbereduxKey, useDispatch } from "@goldlabelapps/uberedux";
|
|
5
|
+
export const DEFAULT_LIVE_APPS = [
|
|
6
|
+
{
|
|
7
|
+
label: "NX°",
|
|
8
|
+
dev: { url: "http://localhost:4525" },
|
|
9
|
+
prod: { url: "https://nx.goldlabel.pro" },
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
label: "Goldlabel",
|
|
13
|
+
dev: { url: "http://localhost:4505" },
|
|
14
|
+
prod: { url: "https://goldlabel.pro" },
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
label: "NHTFS",
|
|
18
|
+
dev: { url: "http://localhost:4510" },
|
|
19
|
+
prod: { url: "https://notheretofuckspiders.art" },
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
label: "GpxRoute°",
|
|
23
|
+
dev: { url: "http://localhost:4520" },
|
|
24
|
+
prod: { url: "https://gpxroute.pro" },
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
label: "Ed Tech",
|
|
28
|
+
dev: { url: "http://localhost:4515" },
|
|
29
|
+
prod: { url: "https://ed-tech.co" },
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
label: "Listingslab",
|
|
33
|
+
dev: { url: "http://localhost:4530" },
|
|
34
|
+
prod: { url: "https://listingslab.com" },
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
export function isDevEnvironment(hostname) {
|
|
38
|
+
if (typeof window !== "undefined") {
|
|
39
|
+
const host = hostname ?? window.location.hostname;
|
|
40
|
+
return host === "localhost" || host === "127.0.0.1" || host.endsWith(".local");
|
|
41
|
+
}
|
|
42
|
+
return process.env.NODE_ENV === "development";
|
|
43
|
+
}
|
|
44
|
+
export function isCurrentApp(app, currentOrigin) {
|
|
45
|
+
if (!currentOrigin)
|
|
46
|
+
return false;
|
|
47
|
+
const normOrigin = currentOrigin.replace(/\/$/, "").toLowerCase();
|
|
48
|
+
const urls = [app.dev?.url, app.prod?.url, app.href].filter(Boolean);
|
|
49
|
+
return urls.some((u) => u.replace(/\/$/, "").toLowerCase() === normOrigin);
|
|
50
|
+
}
|
|
51
|
+
export function NXLiveApps({ apps = DEFAULT_LIVE_APPS, title = "Apps", className = "", }) {
|
|
52
|
+
let dispatch = null;
|
|
53
|
+
try {
|
|
54
|
+
dispatch = useDispatch();
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// Redux context not available
|
|
58
|
+
}
|
|
59
|
+
const [isDev, setIsDev] = useState(() => isDevEnvironment());
|
|
60
|
+
const [currentOrigin, setCurrentOrigin] = useState("");
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
setIsDev(isDevEnvironment());
|
|
63
|
+
if (typeof window !== "undefined") {
|
|
64
|
+
setCurrentOrigin(window.location.origin);
|
|
65
|
+
}
|
|
66
|
+
}, []);
|
|
67
|
+
const handleLinkClick = (e) => {
|
|
68
|
+
if (e.defaultPrevented || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (dispatch) {
|
|
72
|
+
dispatch(setUbereduxKey({ key: "waiting", value: true }));
|
|
73
|
+
dispatch(setUbereduxKey({ key: "loadingOverlay", value: true }));
|
|
74
|
+
dispatch(setUbereduxKey({ key: "navigation.isNavigating", value: true }));
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
const visibleApps = apps.filter((app) => !isCurrentApp(app, currentOrigin));
|
|
78
|
+
return (_jsxs("div", { className: `space-y-3 ${className}`, children: [_jsx("h4", { className: "text-xs font-bold text-slate-900 dark:text-slate-200 uppercase tracking-wider", children: title }), _jsx("ul", { className: "space-y-2 text-xs sm:text-sm", children: visibleApps.map((app, idx) => {
|
|
79
|
+
const appName = app.label || app.name || "";
|
|
80
|
+
const targetUrl = (isDev ? app.dev?.url : app.prod?.url) ||
|
|
81
|
+
app.href ||
|
|
82
|
+
app.prod?.url ||
|
|
83
|
+
app.dev?.url ||
|
|
84
|
+
"#";
|
|
85
|
+
return (_jsx("li", { children: _jsx(Link, { href: targetUrl, target: "_self", onClick: handleLinkClick, className: "inline-flex items-center gap-1 text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white transition-colors", children: _jsx("span", { children: appName }) }) }, idx));
|
|
86
|
+
}) })] }));
|
|
87
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface SocialLinkItem {
|
|
3
|
+
platform?: string;
|
|
4
|
+
label?: string;
|
|
5
|
+
href: string;
|
|
6
|
+
external?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare const DEFAULT_SOCIAL_LINKS: SocialLinkItem[];
|
|
9
|
+
export interface NXSocialColumnProps {
|
|
10
|
+
links?: SocialLinkItem[];
|
|
11
|
+
title?: string;
|
|
12
|
+
className?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function NXSocialColumn({ links, title, className, }: NXSocialColumnProps): React.JSX.Element;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ExternalLink } from "lucide-react";
|
|
4
|
+
export const DEFAULT_SOCIAL_LINKS = [
|
|
5
|
+
{ label: "GitHub", href: "https://github.com/goldlabelapps", external: true },
|
|
6
|
+
{ label: "LinkedIn", href: "https://www.linkedin.com/in/chris-dorward", external: true },
|
|
7
|
+
{ label: "Twitter / X", href: "https://x.com/goldlabelapps", external: true },
|
|
8
|
+
{ label: "YouTube", href: "https://www.youtube.com/@milkylackstoes", external: true },
|
|
9
|
+
];
|
|
10
|
+
export function NXSocialColumn({ links = DEFAULT_SOCIAL_LINKS, title = "Social", className = "", }) {
|
|
11
|
+
const socialItems = links && links.length > 0 ? links : DEFAULT_SOCIAL_LINKS;
|
|
12
|
+
return (_jsxs("div", { className: `space-y-3 ${className}`, children: [_jsx("h4", { className: "text-xs font-bold text-slate-900 dark:text-slate-200 uppercase tracking-wider", children: title }), _jsx("ul", { className: "space-y-2 text-xs sm:text-sm", children: socialItems.map((item, idx) => {
|
|
13
|
+
const itemLabel = item.label || item.platform || "Social Link";
|
|
14
|
+
const isExternal = item.external !== false;
|
|
15
|
+
return (_jsx("li", { children: _jsxs("a", { href: item.href, target: isExternal ? "_blank" : "_self", rel: isExternal ? "noopener noreferrer" : undefined, className: "inline-flex items-center gap-1 text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white transition-colors", children: [_jsx("span", { children: itemLabel }), isExternal && _jsx(ExternalLink, { className: "h-3 w-3 text-slate-400 dark:text-slate-500" })] }) }, idx));
|
|
16
|
+
}) })] }));
|
|
17
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface TagItem {
|
|
3
|
+
label: string;
|
|
4
|
+
slug: string;
|
|
5
|
+
count?: number;
|
|
6
|
+
}
|
|
7
|
+
export declare const DEFAULT_TOP_TAGS: TagItem[];
|
|
8
|
+
export interface NXTagsColumnProps {
|
|
9
|
+
tags?: TagItem[];
|
|
10
|
+
totalCount?: number;
|
|
11
|
+
title?: string;
|
|
12
|
+
className?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function NXTagsColumn({ tags, title, className, }: NXTagsColumnProps): React.JSX.Element;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { AppRouterLink as Link, setUbereduxKey, useDispatch } from "@goldlabelapps/uberedux";
|
|
4
|
+
export const DEFAULT_TOP_TAGS = [
|
|
5
|
+
{ label: "AI", slug: "ai", count: 18 },
|
|
6
|
+
{ label: "Next.js", slug: "nextjs", count: 14 },
|
|
7
|
+
{ label: "TypeScript", slug: "typescript", count: 12 },
|
|
8
|
+
{ label: "React", slug: "react", count: 10 },
|
|
9
|
+
{ label: "Node.js", slug: "nodejs", count: 8 },
|
|
10
|
+
];
|
|
11
|
+
export function NXTagsColumn({ tags = DEFAULT_TOP_TAGS, title = "Top 5 tags", className = "", }) {
|
|
12
|
+
let dispatch = null;
|
|
13
|
+
try {
|
|
14
|
+
dispatch = useDispatch();
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
// Redux context not available
|
|
18
|
+
}
|
|
19
|
+
const handleLinkClick = (e) => {
|
|
20
|
+
if (e.defaultPrevented || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (dispatch) {
|
|
24
|
+
dispatch(setUbereduxKey({ key: "waiting", value: true }));
|
|
25
|
+
dispatch(setUbereduxKey({ key: "loadingOverlay", value: true }));
|
|
26
|
+
dispatch(setUbereduxKey({ key: "navigation.isNavigating", value: true }));
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
const topFive = tags.slice(0, 5);
|
|
30
|
+
return (_jsxs("div", { className: `space-y-3 ${className}`, children: [_jsx("h4", { className: "text-xs font-bold text-slate-900 dark:text-slate-200 uppercase tracking-wider", children: title }), _jsx("ul", { className: "space-y-2 text-xs sm:text-sm", children: topFive.map((t, idx) => (_jsx("li", { children: _jsx(Link, { href: `/tag/${t.slug}`, target: "_self", onClick: handleLinkClick, className: "inline-flex items-center gap-1 text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white transition-colors", children: _jsxs("span", { children: [t.label, t.count !== undefined ? ` (${t.count})` : ""] }) }) }, idx))) })] }));
|
|
31
|
+
}
|
|
@@ -8,5 +8,5 @@ export function HeroSection({ config, badgeLabel }) {
|
|
|
8
8
|
const siteConfig = useSiteConfig();
|
|
9
9
|
const hero = config ? { ...siteConfig.hero, ...config } : siteConfig.hero;
|
|
10
10
|
const pillBadge = badgeLabel || siteConfig.statement.badge || "Modular Application Template";
|
|
11
|
-
return (_jsxs("section", { className: "relative min-h-[
|
|
11
|
+
return (_jsxs("section", { className: "relative min-h-[45vh] flex flex-col items-center justify-center pt-14 sm:pt-18 pb-8 overflow-hidden", children: [_jsx(ParticleCanvas, { config: hero.particleField }), _jsx("div", { className: "pointer-events-none absolute top-1/4 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[600px] sm:w-[900px] h-[400px] bg-gradient-to-tr from-[#012867]/15 via-slate-500/10 to-transparent rounded-full blur-3xl opacity-75" }), _jsxs("div", { className: "relative z-10 max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 text-center", children: [_jsxs("div", { className: "inline-flex items-center gap-2 px-3.5 py-1.5 rounded-full bg-[#012867]/[0.06] border border-[#012867]/15 text-xs font-semibold text-[#012867] backdrop-blur-md mb-8 hover:bg-[#012867]/10 transition-colors cursor-default shadow-sm", children: [_jsx(Rocket, { className: "h-3.5 w-3.5 text-[#012867]" }), _jsx("span", { children: pillBadge })] }), _jsx("h1", { className: "text-5xl sm:text-7xl lg:text-8xl font-normal tracking-tight text-slate-900 max-w-4xl mx-auto leading-[1.05]", children: _jsx("span", { className: "text-transparent bg-clip-text bg-gradient-to-r from-[#012867] via-[#01358d] to-[#011f52]", children: hero.headline }) }), _jsx("p", { className: "mt-6 text-base sm:text-lg lg:text-xl text-slate-600 max-w-2xl mx-auto leading-relaxed font-normal", children: hero.subheadline }), _jsxs("div", { className: "mt-8 sm:mt-10 flex flex-wrap items-center justify-center gap-3 sm:gap-4", children: [_jsx(Button, { href: hero.primaryCta.href, variant: "primary", size: "lg", className: "shadow-lg shadow-[#012867]/20 font-bold bg-[#012867] hover:bg-[#011f52] text-white", children: _jsx("span", { children: hero.primaryCta.label }) }), _jsx(Button, { href: hero.secondaryCta.href, variant: "secondary", size: "lg", className: "font-bold border-slate-300 hover:border-slate-400 text-slate-800 bg-slate-50 hover:bg-slate-100", children: _jsx("span", { children: hero.secondaryCta.label }) })] })] })] }));
|
|
12
12
|
}
|
|
@@ -27,7 +27,6 @@ export function VideoModal({ isOpen, onClose, videoUrl, title = "Video Preview",
|
|
|
27
27
|
aspectRatio === "9/16" ||
|
|
28
28
|
aspectRatio === "portrait" ||
|
|
29
29
|
videoUrl.toLowerCase().includes("portrait") ||
|
|
30
|
-
videoUrl.toLowerCase().includes("echopay.mp4") ||
|
|
31
30
|
videoUrl.toLowerCase().includes("two.mp4") ||
|
|
32
31
|
videoUrl.toLowerCase().includes("builders-merchant");
|
|
33
32
|
const isLocalMp4 = videoUrl.endsWith(".mp4") ||
|
|
@@ -35,7 +34,7 @@ export function VideoModal({ isOpen, onClose, videoUrl, title = "Video Preview",
|
|
|
35
34
|
(!videoUrl.startsWith("http://") && !videoUrl.startsWith("https://") && !videoUrl.includes("embed"));
|
|
36
35
|
const modalContent = (_jsxs("div", { "data-testid": "video-modal-overlay", className: "fixed inset-0 z-50 flex items-center justify-center p-3 sm:p-6 md:p-8 animate-in fade-in duration-200", children: [_jsx("div", { className: "fixed inset-0 bg-black/85 backdrop-blur-xl transition-opacity", onClick: onClose, "aria-hidden": "true", "data-testid": "video-modal-backdrop" }), _jsxs("div", { className: `relative z-10 w-full overflow-hidden rounded-3xl bg-[#111317] border border-white/15 shadow-2xl animate-in zoom-in-95 duration-200 flex flex-col ${isPortrait
|
|
37
36
|
? "max-w-[340px] sm:max-w-[380px] max-h-[90vh]"
|
|
38
|
-
: "max-w-4xl sm:max-w-5xl"}`, children: [_jsxs("div", { className: "flex items-center justify-between px-4 sm:px-6 py-3.5 border-b border-white/10 bg-[#16181e]/90 backdrop-blur-md shrink-0", children: [_jsxs("div", { className: "flex items-center gap-2 min-w-0 pr-2", children: [_jsx("span", { className: "h-2.5 w-2.5 rounded-full bg-slate-400 animate-pulse shrink-0" }), _jsxs("div", { className: "flex items-center gap-2 truncate", children: [isPortrait ? (_jsx(Smartphone, { className: "h-3.5 w-3.5 text-slate-400 shrink-0" })) : (_jsx(Monitor, { className: "h-3.5 w-3.5 text-[#38BDF8] shrink-0" })), _jsx("h3", { className: "text-xs sm:text-sm font-
|
|
37
|
+
: "max-w-4xl sm:max-w-5xl"}`, children: [_jsxs("div", { className: "flex items-center justify-between px-4 sm:px-6 py-3.5 border-b border-white/10 bg-[#16181e]/90 backdrop-blur-md shrink-0", children: [_jsxs("div", { className: "flex items-center gap-2 min-w-0 pr-2", children: [_jsx("span", { className: "h-2.5 w-2.5 rounded-full bg-slate-400 animate-pulse shrink-0" }), _jsxs("div", { className: "flex items-center gap-2 truncate", children: [isPortrait ? (_jsx(Smartphone, { className: "h-3.5 w-3.5 text-slate-400 shrink-0" })) : (_jsx(Monitor, { className: "h-3.5 w-3.5 text-[#38BDF8] shrink-0" })), _jsx("h3", { className: "text-xs sm:text-sm font-normal text-neutral-200 truncate", children: title })] }), badge && (_jsx("span", { className: "hidden sm:inline-flex items-center px-2 py-0.5 rounded-full text-[10px] font-bold bg-white/10 text-slate-300 border border-white/10 shrink-0", children: badge }))] }), _jsx("button", { onClick: onClose, className: "rounded-full p-1.5 text-neutral-400 hover:text-white hover:bg-white/10 transition-colors shrink-0 cursor-pointer", "aria-label": "Close modal", children: _jsx(X, { className: "h-5 w-5" }) })] }), _jsx("div", { className: `relative w-full bg-black flex items-center justify-center overflow-hidden ${isPortrait ? "aspect-[9/16] max-h-[75vh]" : "aspect-video"}`, children: isLocalMp4 ? (_jsx("video", { src: videoUrl, title: title, controls: true, autoPlay: true, playsInline: true, className: "w-full h-full object-contain bg-black", "data-testid": "local-video-player" })) : (_jsx("iframe", { src: videoUrl, title: title, className: "absolute inset-0 h-full w-full border-0", allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share", allowFullScreen: true })) })] })] }));
|
|
39
38
|
return mounted && typeof document !== "undefined"
|
|
40
39
|
? createPortal(modalContent, document.body)
|
|
41
40
|
: modalContent;
|
|
@@ -2,6 +2,7 @@ export * from "./ui/Button";
|
|
|
2
2
|
export * from "./ui/Card";
|
|
3
3
|
export * from "./ui/CustomCursor";
|
|
4
4
|
export * from "./ui/ThemeToggle";
|
|
5
|
+
export * from "./ui/Bash";
|
|
5
6
|
export * from "./hero/ParticleCanvas";
|
|
6
7
|
export * from "./hero/VideoModal";
|
|
7
8
|
export * from "./hero/HeroSection";
|
|
@@ -10,14 +11,21 @@ export * from "./navigation/MobileMenu";
|
|
|
10
11
|
export * from "./navigation/ShareMenu";
|
|
11
12
|
export * from "./navigation/LogoContextMenu";
|
|
12
13
|
export * from "./navigation/Header";
|
|
13
|
-
export * from "./
|
|
14
|
+
export * from "./navigation/LayoutActions";
|
|
15
|
+
export * from "./navigation/Waiting";
|
|
16
|
+
export * from "./navigation/MarkdownMenu";
|
|
17
|
+
export * from "./footer";
|
|
14
18
|
export * from "./showcase/FeatureExplorer";
|
|
15
19
|
export * from "./showcase/SolutionsSection";
|
|
16
20
|
export * from "./showcase/StatementSection";
|
|
17
21
|
export * from "./showcase/UseCaseSlider";
|
|
18
22
|
export * from "./showcase/VideoSection";
|
|
19
23
|
export * from "./showcase/BlogSection";
|
|
24
|
+
export * from "./showcase/FeaturedCard";
|
|
20
25
|
export * from "./download/DownloadBanner";
|
|
21
|
-
export * from "./
|
|
22
|
-
export * from "./
|
|
26
|
+
export * from "./layouts/MarkdownContent";
|
|
27
|
+
export * from "./layouts/Standard";
|
|
28
|
+
export * from "./layouts/GuideBreadcrumbs";
|
|
23
29
|
export * from "./video/VideoLayout";
|
|
30
|
+
export * from "./shortcodes/PageLinkShortcode";
|
|
31
|
+
export * from "./search";
|
package/dist/components/index.js
CHANGED
|
@@ -2,6 +2,7 @@ export * from "./ui/Button";
|
|
|
2
2
|
export * from "./ui/Card";
|
|
3
3
|
export * from "./ui/CustomCursor";
|
|
4
4
|
export * from "./ui/ThemeToggle";
|
|
5
|
+
export * from "./ui/Bash";
|
|
5
6
|
export * from "./hero/ParticleCanvas";
|
|
6
7
|
export * from "./hero/VideoModal";
|
|
7
8
|
export * from "./hero/HeroSection";
|
|
@@ -10,14 +11,21 @@ export * from "./navigation/MobileMenu";
|
|
|
10
11
|
export * from "./navigation/ShareMenu";
|
|
11
12
|
export * from "./navigation/LogoContextMenu";
|
|
12
13
|
export * from "./navigation/Header";
|
|
13
|
-
export * from "./
|
|
14
|
+
export * from "./navigation/LayoutActions";
|
|
15
|
+
export * from "./navigation/Waiting";
|
|
16
|
+
export * from "./navigation/MarkdownMenu";
|
|
17
|
+
export * from "./footer";
|
|
14
18
|
export * from "./showcase/FeatureExplorer";
|
|
15
19
|
export * from "./showcase/SolutionsSection";
|
|
16
20
|
export * from "./showcase/StatementSection";
|
|
17
21
|
export * from "./showcase/UseCaseSlider";
|
|
18
22
|
export * from "./showcase/VideoSection";
|
|
19
23
|
export * from "./showcase/BlogSection";
|
|
24
|
+
export * from "./showcase/FeaturedCard";
|
|
20
25
|
export * from "./download/DownloadBanner";
|
|
21
|
-
export * from "./
|
|
22
|
-
export * from "./
|
|
26
|
+
export * from "./layouts/MarkdownContent";
|
|
27
|
+
export * from "./layouts/Standard";
|
|
28
|
+
export * from "./layouts/GuideBreadcrumbs";
|
|
23
29
|
export * from "./video/VideoLayout";
|
|
30
|
+
export * from "./shortcodes/PageLinkShortcode";
|
|
31
|
+
export * from "./search";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface GuideBreadcrumbItem {
|
|
3
|
+
label: string;
|
|
4
|
+
href: string;
|
|
5
|
+
isLast?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface GuideBreadcrumbsProps {
|
|
8
|
+
items: GuideBreadcrumbItem[];
|
|
9
|
+
homeHref?: string;
|
|
10
|
+
homeLabel?: string;
|
|
11
|
+
className?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function GuideBreadcrumbs({ items, homeHref, homeLabel, className, }: GuideBreadcrumbsProps): React.JSX.Element | null;
|
|
14
|
+
export { GuideBreadcrumbs as GuideBreadcrumb };
|