@opensite/ui 0.1.2 → 0.1.4
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/dist/components.cjs +1511 -3
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.cts +13 -0
- package/dist/components.d.ts +13 -0
- package/dist/components.js +1499 -4
- package/dist/components.js.map +1 -1
- package/dist/footer-animated-social.cjs +272 -0
- package/dist/footer-animated-social.cjs.map +1 -0
- package/dist/footer-animated-social.d.cts +41 -0
- package/dist/footer-animated-social.d.ts +41 -0
- package/dist/footer-animated-social.js +250 -0
- package/dist/footer-animated-social.js.map +1 -0
- package/dist/footer-background-card.cjs +149 -0
- package/dist/footer-background-card.cjs.map +1 -0
- package/dist/footer-background-card.d.cts +74 -0
- package/dist/footer-background-card.d.ts +74 -0
- package/dist/footer-background-card.js +147 -0
- package/dist/footer-background-card.js.map +1 -0
- package/dist/footer-brand-description.cjs +244 -0
- package/dist/footer-brand-description.cjs.map +1 -0
- package/dist/footer-brand-description.d.cts +65 -0
- package/dist/footer-brand-description.d.ts +65 -0
- package/dist/footer-brand-description.js +222 -0
- package/dist/footer-brand-description.js.map +1 -0
- package/dist/footer-contact-card.cjs +238 -0
- package/dist/footer-contact-card.cjs.map +1 -0
- package/dist/footer-contact-card.d.cts +65 -0
- package/dist/footer-contact-card.d.ts +65 -0
- package/dist/footer-contact-card.js +216 -0
- package/dist/footer-contact-card.js.map +1 -0
- package/dist/footer-cta-banner.cjs +282 -0
- package/dist/footer-cta-banner.cjs.map +1 -0
- package/dist/footer-cta-banner.d.cts +77 -0
- package/dist/footer-cta-banner.d.ts +77 -0
- package/dist/footer-cta-banner.js +260 -0
- package/dist/footer-cta-banner.js.map +1 -0
- package/dist/footer-cta-social.cjs +221 -0
- package/dist/footer-cta-social.cjs.map +1 -0
- package/dist/footer-cta-social.d.cts +45 -0
- package/dist/footer-cta-social.d.ts +45 -0
- package/dist/footer-cta-social.js +199 -0
- package/dist/footer-cta-social.js.map +1 -0
- package/dist/footer-links-grid.cjs +119 -0
- package/dist/footer-links-grid.cjs.map +1 -0
- package/dist/footer-links-grid.d.cts +54 -0
- package/dist/footer-links-grid.d.ts +54 -0
- package/dist/footer-links-grid.js +117 -0
- package/dist/footer-links-grid.js.map +1 -0
- package/dist/footer-nav-social.cjs +273 -0
- package/dist/footer-nav-social.cjs.map +1 -0
- package/dist/footer-nav-social.d.cts +72 -0
- package/dist/footer-nav-social.d.ts +72 -0
- package/dist/footer-nav-social.js +251 -0
- package/dist/footer-nav-social.js.map +1 -0
- package/dist/footer-newsletter-grid.cjs +271 -0
- package/dist/footer-newsletter-grid.cjs.map +1 -0
- package/dist/footer-newsletter-grid.d.cts +74 -0
- package/dist/footer-newsletter-grid.d.ts +74 -0
- package/dist/footer-newsletter-grid.js +249 -0
- package/dist/footer-newsletter-grid.js.map +1 -0
- package/dist/footer-newsletter-minimal.cjs +271 -0
- package/dist/footer-newsletter-minimal.cjs.map +1 -0
- package/dist/footer-newsletter-minimal.d.cts +57 -0
- package/dist/footer-newsletter-minimal.d.ts +57 -0
- package/dist/footer-newsletter-minimal.js +249 -0
- package/dist/footer-newsletter-minimal.js.map +1 -0
- package/dist/footer-simple-centered.cjs +101 -0
- package/dist/footer-simple-centered.cjs.map +1 -0
- package/dist/footer-simple-centered.d.cts +52 -0
- package/dist/footer-simple-centered.d.ts +52 -0
- package/dist/footer-simple-centered.js +99 -0
- package/dist/footer-simple-centered.js.map +1 -0
- package/dist/footer-social-apps.cjs +247 -0
- package/dist/footer-social-apps.cjs.map +1 -0
- package/dist/footer-social-apps.d.cts +75 -0
- package/dist/footer-social-apps.d.ts +75 -0
- package/dist/footer-social-apps.js +225 -0
- package/dist/footer-social-apps.js.map +1 -0
- package/dist/footer-social-newsletter.cjs +267 -0
- package/dist/footer-social-newsletter.cjs.map +1 -0
- package/dist/footer-social-newsletter.d.cts +68 -0
- package/dist/footer-social-newsletter.d.ts +68 -0
- package/dist/footer-social-newsletter.js +245 -0
- package/dist/footer-social-newsletter.js.map +1 -0
- package/dist/index.cjs +1511 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +1499 -4
- package/dist/index.js.map +1 -1
- package/dist/pressable.cjs +10 -3
- package/dist/pressable.cjs.map +1 -1
- package/dist/pressable.js +10 -3
- package/dist/pressable.js.map +1 -1
- package/dist/registry.cjs +1971 -1
- package/dist/registry.cjs.map +1 -1
- package/dist/registry.js +1971 -1
- package/dist/registry.js.map +1 -1
- package/dist/team-media-showcase.cjs +182 -0
- package/dist/team-media-showcase.cjs.map +1 -0
- package/dist/team-media-showcase.d.cts +145 -0
- package/dist/team-media-showcase.d.ts +145 -0
- package/dist/team-media-showcase.js +160 -0
- package/dist/team-media-showcase.js.map +1 -0
- package/package.json +71 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../lib/utils.ts","../components/ui/dynamic-icon.tsx","../components/blocks/footers/footer-animated-social.tsx"],"names":["iconName","jsx"],"mappings":"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","file":"footer-animated-social.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport * as React from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\ninterface DynamicIconProps {\n /**\n * Icon name in format: prefix/name or prefix:name\n * Examples: \"lucide/home\", \"mdi:account\", \"heroicons/check\"\n */\n name: string;\n /**\n * Icon size in pixels\n * @default 28\n */\n size?: number;\n /**\n * Icon color - accepts any valid CSS color\n * Note: When not specified, the icon inherits color from parent via CSS currentColor\n */\n color?: string;\n /**\n * Additional CSS classes\n */\n className?: string;\n /**\n * Alt text for accessibility\n */\n alt?: string;\n}\n\n// Simple in-memory cache for fetched SVGs\nconst svgCache = new Map<string, string>();\n\n/**\n * Lightweight icon component that dynamically loads SVG icons from icons.opensite.ai API.\n *\n * Features:\n * - Pulls SVGs from https://icons.opensite.ai API and inlines them for CSS color inheritance\n * - Supports currentColor - icons inherit color from parent element\n * - Accepts prefix/name or prefix:name format\n * - Customizable size and explicit color via props\n * - In-memory caching to prevent duplicate fetches\n *\n * @example\n * ```tsx\n * // Icon inherits color from parent (recommended for hover states, etc.)\n * <span className=\"text-white hover:text-red-500\">\n * <DynamicIcon name=\"lucide/home\" size={24} />\n * </span>\n *\n * // Icon with explicit color\n * <DynamicIcon name=\"mdi:account\" size={32} color=\"#ff0000\" />\n * ```\n */\nexport function DynamicIcon({\n name,\n size = 28,\n color,\n className,\n alt,\n}: DynamicIconProps) {\n const [svgContent, setSvgContent] = React.useState<string | null>(null);\n const [isLoading, setIsLoading] = React.useState(true);\n const [error, setError] = React.useState<string | null>(null);\n\n const { url, iconName } = React.useMemo(() => {\n const separator = name.includes(\"/\") ? \"/\" : \":\";\n const [prefix, iconName] = name.split(separator);\n // Don't pass color to API - we'll handle it via CSS\n const baseUrl = `https://icons.opensite.ai/api/icon/${prefix}/${iconName}?format=svg&width=${size}&height=${size}`;\n\n return {\n url: baseUrl,\n iconName,\n };\n }, [name, size]);\n\n React.useEffect(() => {\n let isMounted = true;\n\n const fetchSvg = async () => {\n // Check cache first\n const cached = svgCache.get(url);\n if (cached) {\n if (isMounted) {\n setSvgContent(cached);\n setIsLoading(false);\n }\n return;\n }\n\n try {\n setIsLoading(true);\n setError(null);\n\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to fetch icon: ${response.status}`);\n }\n\n let svg = await response.text();\n\n // Process SVG to ensure currentColor works:\n // 1. Replace any hardcoded colors with currentColor\n // 2. Ensure stroke/fill use currentColor where appropriate\n svg = processSvgForCurrentColor(svg);\n\n // Cache the processed SVG\n svgCache.set(url, svg);\n\n if (isMounted) {\n setSvgContent(svg);\n setIsLoading(false);\n }\n } catch (err) {\n if (isMounted) {\n setError(err instanceof Error ? err.message : \"Failed to load icon\");\n setIsLoading(false);\n }\n }\n };\n\n fetchSvg();\n\n return () => {\n isMounted = false;\n };\n }, [url]);\n\n // Loading state - show placeholder with same dimensions\n if (isLoading) {\n return (\n <span\n className={cn(\"inline-block\", className)}\n style={{ width: size, height: size }}\n aria-hidden=\"true\"\n />\n );\n }\n\n // Error state - show nothing or fallback\n if (error || !svgContent) {\n return (\n <span\n className={cn(\"inline-block\", className)}\n style={{ width: size, height: size }}\n role=\"img\"\n aria-label={alt || iconName}\n />\n );\n }\n\n // Render inline SVG\n // The color prop applies an explicit color, otherwise inherits from parent via currentColor\n return (\n <span\n className={cn(\"inline-flex items-center justify-center\", className)}\n style={{\n width: size,\n height: size,\n color: color || \"inherit\",\n }}\n role=\"img\"\n aria-label={alt || iconName}\n dangerouslySetInnerHTML={{ __html: svgContent }}\n />\n );\n}\n\n/**\n * Process SVG to ensure it uses currentColor for proper CSS inheritance.\n * This handles various icon libraries that may use different color approaches.\n */\nfunction processSvgForCurrentColor(svg: string): string {\n // Replace stroke=\"currentColor\" is already correct, but ensure fill also works\n // Some icons use fill=\"none\" with stroke, others use fill with no stroke\n\n // Ensure the SVG doesn't have hardcoded colors that should be currentColor\n // Common patterns to replace:\n // - stroke=\"#000\" or stroke=\"#000000\" or stroke=\"black\" -> stroke=\"currentColor\"\n // - fill=\"#000\" or fill=\"#000000\" or fill=\"black\" -> fill=\"currentColor\"\n\n let processed = svg;\n\n // Replace common black color values with currentColor for stroke\n processed = processed.replace(\n /stroke=[\"'](#000000|#000|black)[\"']/gi,\n 'stroke=\"currentColor\"'\n );\n\n // Replace common black color values with currentColor for fill\n // But be careful not to replace fill=\"none\"\n processed = processed.replace(\n /fill=[\"'](#000000|#000|black)[\"']/gi,\n 'fill=\"currentColor\"'\n );\n\n return processed;\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { motion } from \"framer-motion\";\nimport { cn } from \"../../../lib/utils\";\nimport { DynamicIcon } from \"../../ui/dynamic-icon\";\n\n/**\n * Social link configuration\n */\nexport interface FooterAnimatedSocialLink {\n /** Display name */\n name: string;\n /** Link URL */\n href: string;\n}\n\n/**\n * Props for the FooterAnimatedSocial component\n */\nexport interface FooterAnimatedSocialProps {\n /** Additional CSS classes */\n className?: string;\n /** Main heading text */\n heading?: string;\n /** Description text */\n description?: string;\n /** CTA button text */\n ctaText?: string;\n /** CTA button URL */\n ctaUrl?: string;\n /** Social media links */\n socialLinks?: FooterAnimatedSocialLink[];\n /** Copyright text */\n copyright?: string;\n}\n\nconst defaultSocialLinks: FooterAnimatedSocialLink[] = [\n { name: \"Instagram\", href: \"#\" },\n { name: \"X (Twitter)\", href: \"#\" },\n];\n\nconst containerVariants = {\n hidden: { opacity: 0 },\n visible: {\n opacity: 1,\n transition: {\n duration: 0.6,\n staggerChildren: 0.1,\n },\n },\n};\n\nconst itemVariants = {\n hidden: { opacity: 0, y: 20 },\n visible: {\n opacity: 1,\n y: 0,\n transition: { duration: 0.5 },\n },\n};\n\n/**\n * FooterAnimatedSocial - An animated footer with Framer Motion effects and social links.\n *\n * Features smooth entrance animations, a prominent heading with CTA button,\n * animated social links with hover effects, and a clean separator. Ideal for\n * modern websites, portfolios, and creative projects that want to add visual\n * polish and interactivity to their footer.\n */\nexport function FooterAnimatedSocial({\n className,\n heading = \"Connect with Me\",\n description = \"No commitments. Just a quick chat to see if we click.\",\n ctaText = \"Get in Touch\",\n ctaUrl = \"#\",\n socialLinks = defaultSocialLinks,\n copyright = `© Copyright ${new Date().getFullYear()}. All rights Reserved.`,\n}: FooterAnimatedSocialProps): React.JSX.Element {\n return (\n <section className={cn(\"py-32\", className)}>\n <div className=\"container\">\n <footer>\n <div>\n <motion.div\n variants={containerVariants}\n initial=\"hidden\"\n whileInView=\"visible\"\n viewport={{ once: true }}\n className=\"flex flex-col justify-between md:flex-row md:items-center\"\n >\n <div className=\"space-y-8\">\n <motion.div variants={itemVariants} className=\"space-y-6\">\n <h2 className=\"text-4xl leading-tight font-bold text-foreground lg:text-5xl\">\n {heading}\n </h2>\n <p className=\"max-w-md text-lg leading-relaxed text-muted-foreground\">\n {description}\n </p>\n </motion.div>\n\n <motion.div variants={itemVariants}>\n <a\n href={ctaUrl}\n className=\"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-11 px-8\"\n >\n {ctaText}\n </a>\n </motion.div>\n </div>\n\n <div className=\"mt-5 space-y-8 md:mt-0\">\n <motion.div variants={itemVariants}>\n <div className=\"space-y-6\">\n {socialLinks.map((link) => (\n <motion.div\n key={link.name}\n variants={itemVariants}\n whileHover={{ x: 4 }}\n transition={{\n type: \"spring\",\n stiffness: 300,\n damping: 20,\n }}\n >\n <a\n href={link.href}\n className=\"group flex items-center gap-2 py-2 text-foreground transition-colors hover:text-foreground/80\"\n >\n <span className=\"text-xl font-medium\">\n {link.name}\n </span>\n <DynamicIcon\n name=\"lucide/arrow-up-right\"\n size={24}\n className=\"transition-transform group-hover:translate-x-0.5 group-hover:-translate-y-0.5\"\n />\n </a>\n </motion.div>\n ))}\n </div>\n </motion.div>\n </div>\n </motion.div>\n\n <motion.div\n variants={containerVariants}\n initial=\"hidden\"\n whileInView=\"visible\"\n viewport={{ once: true }}\n className=\"mt-16\"\n >\n <motion.div variants={itemVariants}>\n <div className=\"mb-8 h-px w-full bg-border\" />\n </motion.div>\n\n <motion.div\n variants={itemVariants}\n className=\"flex flex-col items-start justify-between gap-4 sm:flex-row sm:items-center\"\n >\n <p className=\"text-sm text-muted-foreground\">{copyright}</p>\n\n <div className=\"flex items-center gap-6 text-sm\">\n <span className=\"text-muted-foreground\">\n <motion.a\n href=\"https://opensite.ai\"\n className=\"underline underline-offset-4 transition-colors hover:text-foreground\"\n whileHover={{ scale: 1.05 }}\n transition={{\n type: \"spring\",\n stiffness: 300,\n damping: 20,\n }}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n AI Website and Automation Platform by Opensite\n </motion.a>\n </span>\n </div>\n </motion.div>\n </motion.div>\n </div>\n </footer>\n </div>\n </section>\n );\n}\n"]}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var clsx = require('clsx');
|
|
5
|
+
var tailwindMerge = require('tailwind-merge');
|
|
6
|
+
var img = require('@page-speed/img');
|
|
7
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
8
|
+
|
|
9
|
+
// lib/utils.ts
|
|
10
|
+
function cn(...inputs) {
|
|
11
|
+
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
12
|
+
}
|
|
13
|
+
var defaultMenuItems = [
|
|
14
|
+
{
|
|
15
|
+
title: "Portfolio",
|
|
16
|
+
links: [
|
|
17
|
+
{ text: "Overview", url: "#" },
|
|
18
|
+
{ text: "Projects", url: "#" },
|
|
19
|
+
{ text: "Pricing", url: "#" },
|
|
20
|
+
{ text: "About", url: "#" }
|
|
21
|
+
]
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
title: "Social",
|
|
25
|
+
links: [
|
|
26
|
+
{ text: "Twitter", url: "#" },
|
|
27
|
+
{ text: "Instagram", url: "#" },
|
|
28
|
+
{ text: "LinkedIn", url: "#" }
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
];
|
|
32
|
+
var defaultContact = {
|
|
33
|
+
phone: "+1 (555) 123-4567",
|
|
34
|
+
email: "hello@opensite.ai",
|
|
35
|
+
location: "NYC",
|
|
36
|
+
timezone: "EST"
|
|
37
|
+
};
|
|
38
|
+
var defaultBottomLinks = [
|
|
39
|
+
{ text: "Terms and Conditions", url: "#" },
|
|
40
|
+
{ text: "Privacy Policy", url: "#" }
|
|
41
|
+
];
|
|
42
|
+
function FooterBackgroundCard({
|
|
43
|
+
logo = {
|
|
44
|
+
url: "https://opensite.ai",
|
|
45
|
+
src: "https://cdn.ing/assets/i/r/285975/eud79qeya11q5w6ueyhklueardyx/os-suircle-black-white.png",
|
|
46
|
+
alt: "Opensite AI",
|
|
47
|
+
title: "Opensite AI"
|
|
48
|
+
},
|
|
49
|
+
className,
|
|
50
|
+
backgroundImage = "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=1920&q=80",
|
|
51
|
+
profileImage = "https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=200&q=80",
|
|
52
|
+
tagline = "Let's Connect",
|
|
53
|
+
personalMessage = "I'm passionate about creating beautiful, functional components that make your projects shine. Let's work together to bring your vision to life.",
|
|
54
|
+
ctaText = "Schedule a call",
|
|
55
|
+
ctaUrl = "#",
|
|
56
|
+
contact = defaultContact,
|
|
57
|
+
menuItems = defaultMenuItems,
|
|
58
|
+
copyright = `\xA9 ${(/* @__PURE__ */ new Date()).getFullYear()} Opensite AI. All rights reserved.`,
|
|
59
|
+
bottomLinks = defaultBottomLinks,
|
|
60
|
+
optixFlowConfig
|
|
61
|
+
}) {
|
|
62
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
63
|
+
"section",
|
|
64
|
+
{
|
|
65
|
+
className: cn("bg-cover bg-center bg-no-repeat py-32", className),
|
|
66
|
+
style: {
|
|
67
|
+
backgroundImage: `url('${backgroundImage}')`
|
|
68
|
+
},
|
|
69
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "container", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto max-w-7xl rounded-lg bg-background p-8 shadow-lg md:p-12", children: [
|
|
70
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-8 md:grid-cols-2 lg:grid-cols-4 lg:gap-12", children: [
|
|
71
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "lg:col-span-1", children: [
|
|
72
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4 flex items-center gap-4", children: [
|
|
73
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
74
|
+
img.Img,
|
|
75
|
+
{
|
|
76
|
+
src: profileImage,
|
|
77
|
+
alt: "Profile",
|
|
78
|
+
className: "h-16 w-16 rounded-full object-cover",
|
|
79
|
+
optixFlowConfig
|
|
80
|
+
}
|
|
81
|
+
),
|
|
82
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-2xl font-medium", children: tagline })
|
|
83
|
+
] }),
|
|
84
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-6 text-sm leading-relaxed text-muted-foreground", children: personalMessage }),
|
|
85
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
86
|
+
"a",
|
|
87
|
+
{
|
|
88
|
+
href: ctaUrl,
|
|
89
|
+
className: "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-10 px-4 py-2",
|
|
90
|
+
children: ctaText
|
|
91
|
+
}
|
|
92
|
+
)
|
|
93
|
+
] }),
|
|
94
|
+
menuItems.map((menu, idx) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
95
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mb-4 text-sm font-medium tracking-wider text-primary uppercase", children: menu.title }),
|
|
96
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-3", children: menu.links.map((link, index) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
97
|
+
"a",
|
|
98
|
+
{
|
|
99
|
+
href: link.url,
|
|
100
|
+
className: "border-b border-transparent text-muted-foreground transition-all duration-300 ease-in-out hover:border-primary hover:text-primary",
|
|
101
|
+
children: link.text
|
|
102
|
+
}
|
|
103
|
+
) }, index)) })
|
|
104
|
+
] }, idx)),
|
|
105
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
106
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mb-4 text-sm font-medium tracking-wider text-primary uppercase", children: "Contact" }),
|
|
107
|
+
/* @__PURE__ */ jsxRuntime.jsxs("ul", { className: "space-y-3", children: [
|
|
108
|
+
/* @__PURE__ */ jsxRuntime.jsx("li", { className: "text-muted-foreground", children: contact.phone }),
|
|
109
|
+
/* @__PURE__ */ jsxRuntime.jsx("li", { className: "text-muted-foreground", children: contact.email }),
|
|
110
|
+
/* @__PURE__ */ jsxRuntime.jsxs("li", { className: "text-muted-foreground", children: [
|
|
111
|
+
contact.location,
|
|
112
|
+
" \u2022 ",
|
|
113
|
+
contact.timezone
|
|
114
|
+
] })
|
|
115
|
+
] })
|
|
116
|
+
] })
|
|
117
|
+
] }),
|
|
118
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-12 flex flex-col items-center justify-between gap-4 border-t border-border pt-8 md:flex-row", children: [
|
|
119
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 text-sm text-muted-foreground md:flex-row md:items-center md:gap-4", children: [
|
|
120
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { children: copyright }),
|
|
121
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
122
|
+
"a",
|
|
123
|
+
{
|
|
124
|
+
href: "https://opensite.ai",
|
|
125
|
+
className: "hover:text-primary",
|
|
126
|
+
target: "_blank",
|
|
127
|
+
rel: "noopener noreferrer",
|
|
128
|
+
children: "AI Website and Automation Platform by Opensite"
|
|
129
|
+
}
|
|
130
|
+
)
|
|
131
|
+
] }),
|
|
132
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-4", children: bottomLinks.map((link, idx) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
133
|
+
"a",
|
|
134
|
+
{
|
|
135
|
+
href: link.url,
|
|
136
|
+
className: "text-sm text-muted-foreground transition-colors hover:text-primary",
|
|
137
|
+
children: link.text
|
|
138
|
+
},
|
|
139
|
+
idx
|
|
140
|
+
)) })
|
|
141
|
+
] })
|
|
142
|
+
] }) })
|
|
143
|
+
}
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
exports.FooterBackgroundCard = FooterBackgroundCard;
|
|
148
|
+
//# sourceMappingURL=footer-background-card.cjs.map
|
|
149
|
+
//# sourceMappingURL=footer-background-card.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../lib/utils.ts","../components/blocks/footers/footer-background-card.tsx"],"names":["twMerge","clsx","jsx","jsxs","Img"],"mappings":"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","file":"footer-background-card.cjs","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../../../lib/utils\";\nimport { Img } from \"@page-speed/img\";\n\n/**\n * Menu item configuration\n */\nexport interface FooterBackgroundCardMenuItem {\n title: string;\n links: {\n text: string;\n url: string;\n }[];\n}\n\n/**\n * Contact information configuration\n */\nexport interface FooterBackgroundCardContact {\n phone: string;\n email: string;\n location: string;\n timezone: string;\n}\n\n/**\n * Props for the FooterBackgroundCard component\n */\nexport interface FooterBackgroundCardProps {\n /** Logo configuration */\n logo?: {\n url: string;\n src: string;\n alt: string;\n title: string;\n };\n /** Additional CSS classes */\n className?: string;\n /** Background image URL */\n backgroundImage?: string;\n /** Profile image URL */\n profileImage?: string;\n /** Tagline text */\n tagline?: string;\n /** Personal message text */\n personalMessage?: string;\n /** CTA button text */\n ctaText?: string;\n /** CTA button URL */\n ctaUrl?: string;\n /** Contact information */\n contact?: FooterBackgroundCardContact;\n /** Menu items */\n menuItems?: FooterBackgroundCardMenuItem[];\n /** Copyright text */\n copyright?: string;\n /** Bottom links */\n bottomLinks?: {\n text: string;\n url: string;\n }[];\n /** Optional Optix Flow configuration for @page-speed/img */\n optixFlowConfig?: {\n apiKey: string;\n compression?: number;\n };\n}\n\nconst defaultMenuItems: FooterBackgroundCardMenuItem[] = [\n {\n title: \"Portfolio\",\n links: [\n { text: \"Overview\", url: \"#\" },\n { text: \"Projects\", url: \"#\" },\n { text: \"Pricing\", url: \"#\" },\n { text: \"About\", url: \"#\" },\n ],\n },\n {\n title: \"Social\",\n links: [\n { text: \"Twitter\", url: \"#\" },\n { text: \"Instagram\", url: \"#\" },\n { text: \"LinkedIn\", url: \"#\" },\n ],\n },\n];\n\nconst defaultContact: FooterBackgroundCardContact = {\n phone: \"+1 (555) 123-4567\",\n email: \"hello@opensite.ai\",\n location: \"NYC\",\n timezone: \"EST\",\n};\n\nconst defaultBottomLinks = [\n { text: \"Terms and Conditions\", url: \"#\" },\n { text: \"Privacy Policy\", url: \"#\" },\n];\n\n/**\n * FooterBackgroundCard - A footer with background image and floating contact card.\n *\n * Features a full-width background image with a floating card containing profile image,\n * personal message, CTA button, navigation links, and contact information. Ideal for\n * creative professionals, agencies, portfolios, and businesses that want a visually\n * striking footer with a personal touch.\n */\nexport function FooterBackgroundCard({\n logo = {\n url: \"https://opensite.ai\",\n src: \"https://cdn.ing/assets/i/r/285975/eud79qeya11q5w6ueyhklueardyx/os-suircle-black-white.png\",\n alt: \"Opensite AI\",\n title: \"Opensite AI\",\n },\n className,\n backgroundImage = \"https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=1920&q=80\",\n profileImage = \"https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=200&q=80\",\n tagline = \"Let's Connect\",\n personalMessage = \"I'm passionate about creating beautiful, functional components that make your projects shine. Let's work together to bring your vision to life.\",\n ctaText = \"Schedule a call\",\n ctaUrl = \"#\",\n contact = defaultContact,\n menuItems = defaultMenuItems,\n copyright = `© ${new Date().getFullYear()} Opensite AI. All rights reserved.`,\n bottomLinks = defaultBottomLinks,\n optixFlowConfig,\n}: FooterBackgroundCardProps): React.JSX.Element {\n return (\n <section\n className={cn(\"bg-cover bg-center bg-no-repeat py-32\", className)}\n style={{\n backgroundImage: `url('${backgroundImage}')`,\n }}\n >\n <div className=\"container\">\n <div className=\"mx-auto max-w-7xl rounded-lg bg-background p-8 shadow-lg md:p-12\">\n <div className=\"grid grid-cols-1 gap-8 md:grid-cols-2 lg:grid-cols-4 lg:gap-12\">\n {/* Profile and CTA Section */}\n <div className=\"lg:col-span-1\">\n <div className=\"mb-4 flex items-center gap-4\">\n <Img\n src={profileImage}\n alt=\"Profile\"\n className=\"h-16 w-16 rounded-full object-cover\"\n optixFlowConfig={optixFlowConfig}\n />\n <h3 className=\"text-2xl font-medium\">{tagline}</h3>\n </div>\n <p className=\"mb-6 text-sm leading-relaxed text-muted-foreground\">\n {personalMessage}\n </p>\n <a\n href={ctaUrl}\n className=\"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-10 px-4 py-2\"\n >\n {ctaText}\n </a>\n </div>\n\n {/* Menu Sections */}\n {menuItems.map((menu, idx) => (\n <div key={idx}>\n <h3 className=\"mb-4 text-sm font-medium tracking-wider text-primary uppercase\">\n {menu.title}\n </h3>\n <ul className=\"space-y-3\">\n {menu.links.map((link, index) => (\n <li key={index}>\n <a\n href={link.url}\n className=\"border-b border-transparent text-muted-foreground transition-all duration-300 ease-in-out hover:border-primary hover:text-primary\"\n >\n {link.text}\n </a>\n </li>\n ))}\n </ul>\n </div>\n ))}\n\n {/* Contact Section */}\n <div>\n <h3 className=\"mb-4 text-sm font-medium tracking-wider text-primary uppercase\">\n Contact\n </h3>\n <ul className=\"space-y-3\">\n <li className=\"text-muted-foreground\">{contact.phone}</li>\n <li className=\"text-muted-foreground\">{contact.email}</li>\n <li className=\"text-muted-foreground\">\n {contact.location} • {contact.timezone}\n </li>\n </ul>\n </div>\n </div>\n\n {/* Bottom Section */}\n <div className=\"mt-12 flex flex-col items-center justify-between gap-4 border-t border-border pt-8 md:flex-row\">\n <div className=\"flex flex-col gap-2 text-sm text-muted-foreground md:flex-row md:items-center md:gap-4\">\n <p>{copyright}</p>\n <a\n href=\"https://opensite.ai\"\n className=\"hover:text-primary\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n AI Website and Automation Platform by Opensite\n </a>\n </div>\n <div className=\"flex gap-4\">\n {bottomLinks.map((link, idx) => (\n <a\n key={idx}\n href={link.url}\n className=\"text-sm text-muted-foreground transition-colors hover:text-primary\"\n >\n {link.text}\n </a>\n ))}\n </div>\n </div>\n </div>\n </div>\n </section>\n );\n}\n"]}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Menu item configuration
|
|
5
|
+
*/
|
|
6
|
+
interface FooterBackgroundCardMenuItem {
|
|
7
|
+
title: string;
|
|
8
|
+
links: {
|
|
9
|
+
text: string;
|
|
10
|
+
url: string;
|
|
11
|
+
}[];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Contact information configuration
|
|
15
|
+
*/
|
|
16
|
+
interface FooterBackgroundCardContact {
|
|
17
|
+
phone: string;
|
|
18
|
+
email: string;
|
|
19
|
+
location: string;
|
|
20
|
+
timezone: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Props for the FooterBackgroundCard component
|
|
24
|
+
*/
|
|
25
|
+
interface FooterBackgroundCardProps {
|
|
26
|
+
/** Logo configuration */
|
|
27
|
+
logo?: {
|
|
28
|
+
url: string;
|
|
29
|
+
src: string;
|
|
30
|
+
alt: string;
|
|
31
|
+
title: string;
|
|
32
|
+
};
|
|
33
|
+
/** Additional CSS classes */
|
|
34
|
+
className?: string;
|
|
35
|
+
/** Background image URL */
|
|
36
|
+
backgroundImage?: string;
|
|
37
|
+
/** Profile image URL */
|
|
38
|
+
profileImage?: string;
|
|
39
|
+
/** Tagline text */
|
|
40
|
+
tagline?: string;
|
|
41
|
+
/** Personal message text */
|
|
42
|
+
personalMessage?: string;
|
|
43
|
+
/** CTA button text */
|
|
44
|
+
ctaText?: string;
|
|
45
|
+
/** CTA button URL */
|
|
46
|
+
ctaUrl?: string;
|
|
47
|
+
/** Contact information */
|
|
48
|
+
contact?: FooterBackgroundCardContact;
|
|
49
|
+
/** Menu items */
|
|
50
|
+
menuItems?: FooterBackgroundCardMenuItem[];
|
|
51
|
+
/** Copyright text */
|
|
52
|
+
copyright?: string;
|
|
53
|
+
/** Bottom links */
|
|
54
|
+
bottomLinks?: {
|
|
55
|
+
text: string;
|
|
56
|
+
url: string;
|
|
57
|
+
}[];
|
|
58
|
+
/** Optional Optix Flow configuration for @page-speed/img */
|
|
59
|
+
optixFlowConfig?: {
|
|
60
|
+
apiKey: string;
|
|
61
|
+
compression?: number;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* FooterBackgroundCard - A footer with background image and floating contact card.
|
|
66
|
+
*
|
|
67
|
+
* Features a full-width background image with a floating card containing profile image,
|
|
68
|
+
* personal message, CTA button, navigation links, and contact information. Ideal for
|
|
69
|
+
* creative professionals, agencies, portfolios, and businesses that want a visually
|
|
70
|
+
* striking footer with a personal touch.
|
|
71
|
+
*/
|
|
72
|
+
declare function FooterBackgroundCard({ logo, className, backgroundImage, profileImage, tagline, personalMessage, ctaText, ctaUrl, contact, menuItems, copyright, bottomLinks, optixFlowConfig, }: FooterBackgroundCardProps): React.JSX.Element;
|
|
73
|
+
|
|
74
|
+
export { FooterBackgroundCard, type FooterBackgroundCardContact, type FooterBackgroundCardMenuItem, type FooterBackgroundCardProps };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Menu item configuration
|
|
5
|
+
*/
|
|
6
|
+
interface FooterBackgroundCardMenuItem {
|
|
7
|
+
title: string;
|
|
8
|
+
links: {
|
|
9
|
+
text: string;
|
|
10
|
+
url: string;
|
|
11
|
+
}[];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Contact information configuration
|
|
15
|
+
*/
|
|
16
|
+
interface FooterBackgroundCardContact {
|
|
17
|
+
phone: string;
|
|
18
|
+
email: string;
|
|
19
|
+
location: string;
|
|
20
|
+
timezone: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Props for the FooterBackgroundCard component
|
|
24
|
+
*/
|
|
25
|
+
interface FooterBackgroundCardProps {
|
|
26
|
+
/** Logo configuration */
|
|
27
|
+
logo?: {
|
|
28
|
+
url: string;
|
|
29
|
+
src: string;
|
|
30
|
+
alt: string;
|
|
31
|
+
title: string;
|
|
32
|
+
};
|
|
33
|
+
/** Additional CSS classes */
|
|
34
|
+
className?: string;
|
|
35
|
+
/** Background image URL */
|
|
36
|
+
backgroundImage?: string;
|
|
37
|
+
/** Profile image URL */
|
|
38
|
+
profileImage?: string;
|
|
39
|
+
/** Tagline text */
|
|
40
|
+
tagline?: string;
|
|
41
|
+
/** Personal message text */
|
|
42
|
+
personalMessage?: string;
|
|
43
|
+
/** CTA button text */
|
|
44
|
+
ctaText?: string;
|
|
45
|
+
/** CTA button URL */
|
|
46
|
+
ctaUrl?: string;
|
|
47
|
+
/** Contact information */
|
|
48
|
+
contact?: FooterBackgroundCardContact;
|
|
49
|
+
/** Menu items */
|
|
50
|
+
menuItems?: FooterBackgroundCardMenuItem[];
|
|
51
|
+
/** Copyright text */
|
|
52
|
+
copyright?: string;
|
|
53
|
+
/** Bottom links */
|
|
54
|
+
bottomLinks?: {
|
|
55
|
+
text: string;
|
|
56
|
+
url: string;
|
|
57
|
+
}[];
|
|
58
|
+
/** Optional Optix Flow configuration for @page-speed/img */
|
|
59
|
+
optixFlowConfig?: {
|
|
60
|
+
apiKey: string;
|
|
61
|
+
compression?: number;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* FooterBackgroundCard - A footer with background image and floating contact card.
|
|
66
|
+
*
|
|
67
|
+
* Features a full-width background image with a floating card containing profile image,
|
|
68
|
+
* personal message, CTA button, navigation links, and contact information. Ideal for
|
|
69
|
+
* creative professionals, agencies, portfolios, and businesses that want a visually
|
|
70
|
+
* striking footer with a personal touch.
|
|
71
|
+
*/
|
|
72
|
+
declare function FooterBackgroundCard({ logo, className, backgroundImage, profileImage, tagline, personalMessage, ctaText, ctaUrl, contact, menuItems, copyright, bottomLinks, optixFlowConfig, }: FooterBackgroundCardProps): React.JSX.Element;
|
|
73
|
+
|
|
74
|
+
export { FooterBackgroundCard, type FooterBackgroundCardContact, type FooterBackgroundCardMenuItem, type FooterBackgroundCardProps };
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { clsx } from 'clsx';
|
|
3
|
+
import { twMerge } from 'tailwind-merge';
|
|
4
|
+
import { Img } from '@page-speed/img';
|
|
5
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
// lib/utils.ts
|
|
8
|
+
function cn(...inputs) {
|
|
9
|
+
return twMerge(clsx(inputs));
|
|
10
|
+
}
|
|
11
|
+
var defaultMenuItems = [
|
|
12
|
+
{
|
|
13
|
+
title: "Portfolio",
|
|
14
|
+
links: [
|
|
15
|
+
{ text: "Overview", url: "#" },
|
|
16
|
+
{ text: "Projects", url: "#" },
|
|
17
|
+
{ text: "Pricing", url: "#" },
|
|
18
|
+
{ text: "About", url: "#" }
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
title: "Social",
|
|
23
|
+
links: [
|
|
24
|
+
{ text: "Twitter", url: "#" },
|
|
25
|
+
{ text: "Instagram", url: "#" },
|
|
26
|
+
{ text: "LinkedIn", url: "#" }
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
];
|
|
30
|
+
var defaultContact = {
|
|
31
|
+
phone: "+1 (555) 123-4567",
|
|
32
|
+
email: "hello@opensite.ai",
|
|
33
|
+
location: "NYC",
|
|
34
|
+
timezone: "EST"
|
|
35
|
+
};
|
|
36
|
+
var defaultBottomLinks = [
|
|
37
|
+
{ text: "Terms and Conditions", url: "#" },
|
|
38
|
+
{ text: "Privacy Policy", url: "#" }
|
|
39
|
+
];
|
|
40
|
+
function FooterBackgroundCard({
|
|
41
|
+
logo = {
|
|
42
|
+
url: "https://opensite.ai",
|
|
43
|
+
src: "https://cdn.ing/assets/i/r/285975/eud79qeya11q5w6ueyhklueardyx/os-suircle-black-white.png",
|
|
44
|
+
alt: "Opensite AI",
|
|
45
|
+
title: "Opensite AI"
|
|
46
|
+
},
|
|
47
|
+
className,
|
|
48
|
+
backgroundImage = "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=1920&q=80",
|
|
49
|
+
profileImage = "https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=200&q=80",
|
|
50
|
+
tagline = "Let's Connect",
|
|
51
|
+
personalMessage = "I'm passionate about creating beautiful, functional components that make your projects shine. Let's work together to bring your vision to life.",
|
|
52
|
+
ctaText = "Schedule a call",
|
|
53
|
+
ctaUrl = "#",
|
|
54
|
+
contact = defaultContact,
|
|
55
|
+
menuItems = defaultMenuItems,
|
|
56
|
+
copyright = `\xA9 ${(/* @__PURE__ */ new Date()).getFullYear()} Opensite AI. All rights reserved.`,
|
|
57
|
+
bottomLinks = defaultBottomLinks,
|
|
58
|
+
optixFlowConfig
|
|
59
|
+
}) {
|
|
60
|
+
return /* @__PURE__ */ jsx(
|
|
61
|
+
"section",
|
|
62
|
+
{
|
|
63
|
+
className: cn("bg-cover bg-center bg-no-repeat py-32", className),
|
|
64
|
+
style: {
|
|
65
|
+
backgroundImage: `url('${backgroundImage}')`
|
|
66
|
+
},
|
|
67
|
+
children: /* @__PURE__ */ jsx("div", { className: "container", children: /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-7xl rounded-lg bg-background p-8 shadow-lg md:p-12", children: [
|
|
68
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-8 md:grid-cols-2 lg:grid-cols-4 lg:gap-12", children: [
|
|
69
|
+
/* @__PURE__ */ jsxs("div", { className: "lg:col-span-1", children: [
|
|
70
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-4 flex items-center gap-4", children: [
|
|
71
|
+
/* @__PURE__ */ jsx(
|
|
72
|
+
Img,
|
|
73
|
+
{
|
|
74
|
+
src: profileImage,
|
|
75
|
+
alt: "Profile",
|
|
76
|
+
className: "h-16 w-16 rounded-full object-cover",
|
|
77
|
+
optixFlowConfig
|
|
78
|
+
}
|
|
79
|
+
),
|
|
80
|
+
/* @__PURE__ */ jsx("h3", { className: "text-2xl font-medium", children: tagline })
|
|
81
|
+
] }),
|
|
82
|
+
/* @__PURE__ */ jsx("p", { className: "mb-6 text-sm leading-relaxed text-muted-foreground", children: personalMessage }),
|
|
83
|
+
/* @__PURE__ */ jsx(
|
|
84
|
+
"a",
|
|
85
|
+
{
|
|
86
|
+
href: ctaUrl,
|
|
87
|
+
className: "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-10 px-4 py-2",
|
|
88
|
+
children: ctaText
|
|
89
|
+
}
|
|
90
|
+
)
|
|
91
|
+
] }),
|
|
92
|
+
menuItems.map((menu, idx) => /* @__PURE__ */ jsxs("div", { children: [
|
|
93
|
+
/* @__PURE__ */ jsx("h3", { className: "mb-4 text-sm font-medium tracking-wider text-primary uppercase", children: menu.title }),
|
|
94
|
+
/* @__PURE__ */ jsx("ul", { className: "space-y-3", children: menu.links.map((link, index) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
95
|
+
"a",
|
|
96
|
+
{
|
|
97
|
+
href: link.url,
|
|
98
|
+
className: "border-b border-transparent text-muted-foreground transition-all duration-300 ease-in-out hover:border-primary hover:text-primary",
|
|
99
|
+
children: link.text
|
|
100
|
+
}
|
|
101
|
+
) }, index)) })
|
|
102
|
+
] }, idx)),
|
|
103
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
104
|
+
/* @__PURE__ */ jsx("h3", { className: "mb-4 text-sm font-medium tracking-wider text-primary uppercase", children: "Contact" }),
|
|
105
|
+
/* @__PURE__ */ jsxs("ul", { className: "space-y-3", children: [
|
|
106
|
+
/* @__PURE__ */ jsx("li", { className: "text-muted-foreground", children: contact.phone }),
|
|
107
|
+
/* @__PURE__ */ jsx("li", { className: "text-muted-foreground", children: contact.email }),
|
|
108
|
+
/* @__PURE__ */ jsxs("li", { className: "text-muted-foreground", children: [
|
|
109
|
+
contact.location,
|
|
110
|
+
" \u2022 ",
|
|
111
|
+
contact.timezone
|
|
112
|
+
] })
|
|
113
|
+
] })
|
|
114
|
+
] })
|
|
115
|
+
] }),
|
|
116
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-12 flex flex-col items-center justify-between gap-4 border-t border-border pt-8 md:flex-row", children: [
|
|
117
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 text-sm text-muted-foreground md:flex-row md:items-center md:gap-4", children: [
|
|
118
|
+
/* @__PURE__ */ jsx("p", { children: copyright }),
|
|
119
|
+
/* @__PURE__ */ jsx(
|
|
120
|
+
"a",
|
|
121
|
+
{
|
|
122
|
+
href: "https://opensite.ai",
|
|
123
|
+
className: "hover:text-primary",
|
|
124
|
+
target: "_blank",
|
|
125
|
+
rel: "noopener noreferrer",
|
|
126
|
+
children: "AI Website and Automation Platform by Opensite"
|
|
127
|
+
}
|
|
128
|
+
)
|
|
129
|
+
] }),
|
|
130
|
+
/* @__PURE__ */ jsx("div", { className: "flex gap-4", children: bottomLinks.map((link, idx) => /* @__PURE__ */ jsx(
|
|
131
|
+
"a",
|
|
132
|
+
{
|
|
133
|
+
href: link.url,
|
|
134
|
+
className: "text-sm text-muted-foreground transition-colors hover:text-primary",
|
|
135
|
+
children: link.text
|
|
136
|
+
},
|
|
137
|
+
idx
|
|
138
|
+
)) })
|
|
139
|
+
] })
|
|
140
|
+
] }) })
|
|
141
|
+
}
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export { FooterBackgroundCard };
|
|
146
|
+
//# sourceMappingURL=footer-background-card.js.map
|
|
147
|
+
//# sourceMappingURL=footer-background-card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../lib/utils.ts","../components/blocks/footers/footer-background-card.tsx"],"names":[],"mappings":"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","file":"footer-background-card.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../../../lib/utils\";\nimport { Img } from \"@page-speed/img\";\n\n/**\n * Menu item configuration\n */\nexport interface FooterBackgroundCardMenuItem {\n title: string;\n links: {\n text: string;\n url: string;\n }[];\n}\n\n/**\n * Contact information configuration\n */\nexport interface FooterBackgroundCardContact {\n phone: string;\n email: string;\n location: string;\n timezone: string;\n}\n\n/**\n * Props for the FooterBackgroundCard component\n */\nexport interface FooterBackgroundCardProps {\n /** Logo configuration */\n logo?: {\n url: string;\n src: string;\n alt: string;\n title: string;\n };\n /** Additional CSS classes */\n className?: string;\n /** Background image URL */\n backgroundImage?: string;\n /** Profile image URL */\n profileImage?: string;\n /** Tagline text */\n tagline?: string;\n /** Personal message text */\n personalMessage?: string;\n /** CTA button text */\n ctaText?: string;\n /** CTA button URL */\n ctaUrl?: string;\n /** Contact information */\n contact?: FooterBackgroundCardContact;\n /** Menu items */\n menuItems?: FooterBackgroundCardMenuItem[];\n /** Copyright text */\n copyright?: string;\n /** Bottom links */\n bottomLinks?: {\n text: string;\n url: string;\n }[];\n /** Optional Optix Flow configuration for @page-speed/img */\n optixFlowConfig?: {\n apiKey: string;\n compression?: number;\n };\n}\n\nconst defaultMenuItems: FooterBackgroundCardMenuItem[] = [\n {\n title: \"Portfolio\",\n links: [\n { text: \"Overview\", url: \"#\" },\n { text: \"Projects\", url: \"#\" },\n { text: \"Pricing\", url: \"#\" },\n { text: \"About\", url: \"#\" },\n ],\n },\n {\n title: \"Social\",\n links: [\n { text: \"Twitter\", url: \"#\" },\n { text: \"Instagram\", url: \"#\" },\n { text: \"LinkedIn\", url: \"#\" },\n ],\n },\n];\n\nconst defaultContact: FooterBackgroundCardContact = {\n phone: \"+1 (555) 123-4567\",\n email: \"hello@opensite.ai\",\n location: \"NYC\",\n timezone: \"EST\",\n};\n\nconst defaultBottomLinks = [\n { text: \"Terms and Conditions\", url: \"#\" },\n { text: \"Privacy Policy\", url: \"#\" },\n];\n\n/**\n * FooterBackgroundCard - A footer with background image and floating contact card.\n *\n * Features a full-width background image with a floating card containing profile image,\n * personal message, CTA button, navigation links, and contact information. Ideal for\n * creative professionals, agencies, portfolios, and businesses that want a visually\n * striking footer with a personal touch.\n */\nexport function FooterBackgroundCard({\n logo = {\n url: \"https://opensite.ai\",\n src: \"https://cdn.ing/assets/i/r/285975/eud79qeya11q5w6ueyhklueardyx/os-suircle-black-white.png\",\n alt: \"Opensite AI\",\n title: \"Opensite AI\",\n },\n className,\n backgroundImage = \"https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=1920&q=80\",\n profileImage = \"https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=200&q=80\",\n tagline = \"Let's Connect\",\n personalMessage = \"I'm passionate about creating beautiful, functional components that make your projects shine. Let's work together to bring your vision to life.\",\n ctaText = \"Schedule a call\",\n ctaUrl = \"#\",\n contact = defaultContact,\n menuItems = defaultMenuItems,\n copyright = `© ${new Date().getFullYear()} Opensite AI. All rights reserved.`,\n bottomLinks = defaultBottomLinks,\n optixFlowConfig,\n}: FooterBackgroundCardProps): React.JSX.Element {\n return (\n <section\n className={cn(\"bg-cover bg-center bg-no-repeat py-32\", className)}\n style={{\n backgroundImage: `url('${backgroundImage}')`,\n }}\n >\n <div className=\"container\">\n <div className=\"mx-auto max-w-7xl rounded-lg bg-background p-8 shadow-lg md:p-12\">\n <div className=\"grid grid-cols-1 gap-8 md:grid-cols-2 lg:grid-cols-4 lg:gap-12\">\n {/* Profile and CTA Section */}\n <div className=\"lg:col-span-1\">\n <div className=\"mb-4 flex items-center gap-4\">\n <Img\n src={profileImage}\n alt=\"Profile\"\n className=\"h-16 w-16 rounded-full object-cover\"\n optixFlowConfig={optixFlowConfig}\n />\n <h3 className=\"text-2xl font-medium\">{tagline}</h3>\n </div>\n <p className=\"mb-6 text-sm leading-relaxed text-muted-foreground\">\n {personalMessage}\n </p>\n <a\n href={ctaUrl}\n className=\"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-10 px-4 py-2\"\n >\n {ctaText}\n </a>\n </div>\n\n {/* Menu Sections */}\n {menuItems.map((menu, idx) => (\n <div key={idx}>\n <h3 className=\"mb-4 text-sm font-medium tracking-wider text-primary uppercase\">\n {menu.title}\n </h3>\n <ul className=\"space-y-3\">\n {menu.links.map((link, index) => (\n <li key={index}>\n <a\n href={link.url}\n className=\"border-b border-transparent text-muted-foreground transition-all duration-300 ease-in-out hover:border-primary hover:text-primary\"\n >\n {link.text}\n </a>\n </li>\n ))}\n </ul>\n </div>\n ))}\n\n {/* Contact Section */}\n <div>\n <h3 className=\"mb-4 text-sm font-medium tracking-wider text-primary uppercase\">\n Contact\n </h3>\n <ul className=\"space-y-3\">\n <li className=\"text-muted-foreground\">{contact.phone}</li>\n <li className=\"text-muted-foreground\">{contact.email}</li>\n <li className=\"text-muted-foreground\">\n {contact.location} • {contact.timezone}\n </li>\n </ul>\n </div>\n </div>\n\n {/* Bottom Section */}\n <div className=\"mt-12 flex flex-col items-center justify-between gap-4 border-t border-border pt-8 md:flex-row\">\n <div className=\"flex flex-col gap-2 text-sm text-muted-foreground md:flex-row md:items-center md:gap-4\">\n <p>{copyright}</p>\n <a\n href=\"https://opensite.ai\"\n className=\"hover:text-primary\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n AI Website and Automation Platform by Opensite\n </a>\n </div>\n <div className=\"flex gap-4\">\n {bottomLinks.map((link, idx) => (\n <a\n key={idx}\n href={link.url}\n className=\"text-sm text-muted-foreground transition-colors hover:text-primary\"\n >\n {link.text}\n </a>\n ))}\n </div>\n </div>\n </div>\n </div>\n </section>\n );\n}\n"]}
|