@notionhive/footers 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. package/bin/footers.js +16 -0
  2. package/category.config.json +7 -0
  3. package/package.json +24 -0
  4. package/registry/footer-01.json +6 -0
  5. package/registry/footer-02.json +9 -0
  6. package/registry/footer-03.json +9 -0
  7. package/registry/footer-04.json +9 -0
  8. package/registry/footer-05.json +9 -0
  9. package/registry/footer-06.json +7 -0
  10. package/registry/footer-07.json +9 -0
  11. package/registry/footer-08.json +9 -0
  12. package/registry/footer-09.json +9 -0
  13. package/registry/footer-10.json +9 -0
  14. package/registry/footer-11.json +7 -0
  15. package/registry/footer-12.json +9 -0
  16. package/registry/footer-13.json +9 -0
  17. package/registry/footer-14.json +9 -0
  18. package/registry/footer-15.json +9 -0
  19. package/registry/footer-16.json +9 -0
  20. package/registry/footer-17.json +9 -0
  21. package/registry/footer-18.json +9 -0
  22. package/registry/footer-19.json +9 -0
  23. package/registry/footer-20.json +9 -0
  24. package/registry/footer-21.json +9 -0
  25. package/registry/footer-22.json +9 -0
  26. package/registry/footer-23.json +9 -0
  27. package/registry/footer-24.json +9 -0
  28. package/registry/footer-25.json +9 -0
  29. package/registry/footer-26.json +9 -0
  30. package/registry/footer-27.json +9 -0
  31. package/registry/footer-28.json +9 -0
  32. package/registry/footer-29.json +6 -0
  33. package/registry/footer-30.json +6 -0
  34. package/registry/index.json +263 -0
  35. package/templates/components/atoms/SafeImage/SafeImage.jsx +101 -0
  36. package/templates/components/atoms/SafeImage/index.js +1 -0
  37. package/templates/components/organisms/Footer01/Footer01.jsx +142 -0
  38. package/templates/components/organisms/Footer01/Footer01.propTypes.js +110 -0
  39. package/templates/components/organisms/Footer01/index.js +1 -0
  40. package/templates/components/organisms/Footer02/Footer02.jsx +136 -0
  41. package/templates/components/organisms/Footer02/Footer02.propTypes.js +112 -0
  42. package/templates/components/organisms/Footer02/index.js +1 -0
  43. package/templates/components/organisms/Footer03/Footer03.jsx +162 -0
  44. package/templates/components/organisms/Footer03/Footer03.propTypes.js +73 -0
  45. package/templates/components/organisms/Footer03/index.js +1 -0
  46. package/templates/components/organisms/Footer04/Footer04.jsx +128 -0
  47. package/templates/components/organisms/Footer04/Footer04.propTypes.js +93 -0
  48. package/templates/components/organisms/Footer04/index.js +1 -0
  49. package/templates/components/organisms/Footer05/Footer05.jsx +101 -0
  50. package/templates/components/organisms/Footer05/Footer05.propTypes.js +42 -0
  51. package/templates/components/organisms/Footer05/index.js +1 -0
  52. package/templates/components/organisms/Footer06/Footer06.jsx +170 -0
  53. package/templates/components/organisms/Footer06/Footer06.propTypes.js +53 -0
  54. package/templates/components/organisms/Footer06/index.js +1 -0
  55. package/templates/components/organisms/Footer07/Footer07.jsx +253 -0
  56. package/templates/components/organisms/Footer07/Footer07.propTypes.js +83 -0
  57. package/templates/components/organisms/Footer07/index.js +1 -0
  58. package/templates/components/organisms/Footer08/Footer08.jsx +183 -0
  59. package/templates/components/organisms/Footer08/Footer08.propTypes.js +92 -0
  60. package/templates/components/organisms/Footer08/index.js +1 -0
  61. package/templates/components/organisms/Footer09/Footer09.jsx +199 -0
  62. package/templates/components/organisms/Footer09/Footer09.propTypes.js +76 -0
  63. package/templates/components/organisms/Footer09/index.js +1 -0
  64. package/templates/components/organisms/Footer10/Footer10.jsx +172 -0
  65. package/templates/components/organisms/Footer10/Footer10.propTypes.js +38 -0
  66. package/templates/components/organisms/Footer10/index.js +1 -0
  67. package/templates/components/organisms/Footer11/Footer11.jsx +107 -0
  68. package/templates/components/organisms/Footer11/Footer11.propTypes.js +64 -0
  69. package/templates/components/organisms/Footer11/index.js +1 -0
  70. package/templates/components/organisms/Footer12/Footer12.jsx +122 -0
  71. package/templates/components/organisms/Footer12/Footer12.propTypes.js +94 -0
  72. package/templates/components/organisms/Footer12/index.js +1 -0
  73. package/templates/components/organisms/Footer13/Footer13.jsx +156 -0
  74. package/templates/components/organisms/Footer13/Footer13.propTypes.js +80 -0
  75. package/templates/components/organisms/Footer13/index.js +1 -0
  76. package/templates/components/organisms/Footer14/Footer14.jsx +157 -0
  77. package/templates/components/organisms/Footer14/Footer14.propTypes.js +60 -0
  78. package/templates/components/organisms/Footer14/index.js +1 -0
  79. package/templates/components/organisms/Footer15/Footer15.jsx +184 -0
  80. package/templates/components/organisms/Footer15/Footer15.propTypes.js +58 -0
  81. package/templates/components/organisms/Footer15/index.js +1 -0
  82. package/templates/components/organisms/Footer16/Footer16.jsx +87 -0
  83. package/templates/components/organisms/Footer16/Footer16.propTypes.js +73 -0
  84. package/templates/components/organisms/Footer16/index.js +1 -0
  85. package/templates/components/organisms/Footer17/Footer17.jsx +176 -0
  86. package/templates/components/organisms/Footer17/Footer17.propTypes.js +117 -0
  87. package/templates/components/organisms/Footer17/index.js +1 -0
  88. package/templates/components/organisms/Footer18/Footer18.jsx +236 -0
  89. package/templates/components/organisms/Footer18/Footer18.propTypes.js +92 -0
  90. package/templates/components/organisms/Footer18/index.js +1 -0
  91. package/templates/components/organisms/Footer19/Footer19.jsx +287 -0
  92. package/templates/components/organisms/Footer19/Footer19.propTypes.js +116 -0
  93. package/templates/components/organisms/Footer19/index.js +1 -0
  94. package/templates/components/organisms/Footer20/Footer20.jsx +201 -0
  95. package/templates/components/organisms/Footer20/Footer20.propTypes.js +70 -0
  96. package/templates/components/organisms/Footer20/index.js +1 -0
  97. package/templates/components/organisms/Footer21/Footer21.jsx +134 -0
  98. package/templates/components/organisms/Footer21/Footer21.propTypes.js +122 -0
  99. package/templates/components/organisms/Footer21/index.js +1 -0
  100. package/templates/components/organisms/Footer22/Footer22.jsx +136 -0
  101. package/templates/components/organisms/Footer22/Footer22.propTypes.js +58 -0
  102. package/templates/components/organisms/Footer22/index.js +1 -0
  103. package/templates/components/organisms/Footer23/Footer23.jsx +177 -0
  104. package/templates/components/organisms/Footer23/Footer23.propTypes.js +97 -0
  105. package/templates/components/organisms/Footer23/index.js +1 -0
  106. package/templates/components/organisms/Footer24/Footer24.jsx +192 -0
  107. package/templates/components/organisms/Footer24/Footer24.propTypes.js +132 -0
  108. package/templates/components/organisms/Footer24/index.js +1 -0
  109. package/templates/components/organisms/Footer25/Footer25.jsx +135 -0
  110. package/templates/components/organisms/Footer25/Footer25.propTypes.js +124 -0
  111. package/templates/components/organisms/Footer25/index.js +1 -0
  112. package/templates/components/organisms/Footer26/Footer26.jsx +167 -0
  113. package/templates/components/organisms/Footer26/Footer26.propTypes.js +54 -0
  114. package/templates/components/organisms/Footer26/index.js +1 -0
  115. package/templates/components/organisms/Footer27/Footer27.jsx +171 -0
  116. package/templates/components/organisms/Footer27/Footer27.propTypes.js +105 -0
  117. package/templates/components/organisms/Footer27/index.js +1 -0
  118. package/templates/components/organisms/Footer28/Footer28.jsx +98 -0
  119. package/templates/components/organisms/Footer28/Footer28.propTypes.js +96 -0
  120. package/templates/components/organisms/Footer28/index.js +1 -0
  121. package/templates/components/organisms/Footer29/Footer29.jsx +118 -0
  122. package/templates/components/organisms/Footer29/Footer29.propTypes.js +68 -0
  123. package/templates/components/organisms/Footer29/index.js +1 -0
  124. package/templates/components/organisms/Footer30/Footer30.jsx +92 -0
  125. package/templates/components/organisms/Footer30/Footer30.propTypes.js +51 -0
  126. package/templates/components/organisms/Footer30/index.js +1 -0
  127. package/templates/public/footer/footer02/payment-01.png +0 -0
  128. package/templates/public/footer/footer02/payment-02.png +0 -0
  129. package/templates/public/footer/footer02/payment-03.png +0 -0
  130. package/templates/public/footer/footer02/payment-04.png +0 -0
  131. package/templates/public/footer/footer02/payment-05.png +0 -0
  132. package/templates/public/footer/footer02/payment-06.png +0 -0
  133. package/templates/public/footer/footer02/payment-07.png +0 -0
  134. package/templates/public/footer/footer02/payment-08.png +0 -0
  135. package/templates/public/footer/footer02/payment-09.svg +5 -0
  136. package/templates/public/footer/footer02/payment-10.svg +11 -0
  137. package/templates/public/footer/footer02/payment-11.svg +22 -0
  138. package/templates/public/footer/footer02/payment-12.svg +25 -0
  139. package/templates/public/footer/footer02/payment-13.svg +10 -0
  140. package/templates/public/footer/footer02/payment-14.svg +36 -0
  141. package/templates/public/footer/footer02/payment-15.svg +18 -0
  142. package/templates/public/footer/footer02/payment-sprite-01.png +0 -0
  143. package/templates/public/footer/footer02/payment-sprite-02.png +0 -0
  144. package/templates/public/footer/footer02/payment-sprite-03.png +0 -0
  145. package/templates/public/footer/footer02/payment-sprite-04.png +0 -0
  146. package/templates/public/footer/footer02/payment-sprite-05.png +0 -0
  147. package/templates/public/footer/footer02/payment-sprite-06.png +0 -0
  148. package/templates/public/footer/footer03/logo-mask.png +0 -0
  149. package/templates/public/footer/footer03/logo.png +0 -0
  150. package/templates/public/footer/footer04/logo.svg +45 -0
  151. package/templates/public/footer/footer05/brand-watermark.png +0 -0
  152. package/templates/public/footer/footer07/logo.png +0 -0
  153. package/templates/public/footer/footer07/watch-hero.png +0 -0
  154. package/templates/public/footer/footer07/watch-overlay.png +0 -0
  155. package/templates/public/footer/footer08/logo.png +0 -0
  156. package/templates/public/footer/footer08/logo.svg +3 -0
  157. package/templates/public/footer/footer09/logo.svg +13 -0
  158. package/templates/public/footer/footer10/hero-image.png +0 -0
  159. package/templates/public/footer/footer10/hero-mask-download.svg +3 -0
  160. package/templates/public/footer/footer10/hero-mask.svg +3 -0
  161. package/templates/public/footer/footer12/logo-icon.svg +3 -0
  162. package/templates/public/footer/footer12/refugee-logo.png +0 -0
  163. package/templates/public/footer/footer13/logo.png +0 -0
  164. package/templates/public/footer/footer14/logo.png +0 -0
  165. package/templates/public/footer/footer15/logo.svg +19 -0
  166. package/templates/public/footer/footer16/logo.svg +6 -0
  167. package/templates/public/footer/footer17/logo-left.svg +11 -0
  168. package/templates/public/footer/footer17/logo-right.svg +36 -0
  169. package/templates/public/footer/footer18/logo.png +108 -0
  170. package/templates/public/footer/footer18/logo.svg +108 -0
  171. package/templates/public/footer/footer19/logo.png +0 -0
  172. package/templates/public/footer/footer19/payment-bkash.png +0 -0
  173. package/templates/public/footer/footer19/payment-mastercard.svg +12 -0
  174. package/templates/public/footer/footer19/payment-nagad.png +0 -0
  175. package/templates/public/footer/footer19/payment-nexus.png +0 -0
  176. package/templates/public/footer/footer19/payment-rocket.png +0 -0
  177. package/templates/public/footer/footer19/payment-upay.png +0 -0
  178. package/templates/public/footer/footer19/payment-visa.svg +6 -0
  179. package/templates/public/footer/footer20/bg.png +0 -0
  180. package/templates/public/footer/footer20/logo.png +0 -0
  181. package/templates/public/footer/footer21/logo.png +0 -0
  182. package/templates/public/footer/footer22/logo-icon.svg +10 -0
  183. package/templates/public/footer/footer22/logo-name.svg +5 -0
  184. package/templates/public/footer/footer22/logo-tagline.svg +5 -0
  185. package/templates/public/footer/footer23/logo-icon.svg +10 -0
  186. package/templates/public/footer/footer23/logo-name.svg +20 -0
  187. package/templates/public/footer/footer23/logo-tagline.svg +17 -0
  188. package/templates/public/footer/footer24/logo.svg +46 -0
  189. package/templates/public/footer/footer24/map.png +0 -0
  190. package/templates/public/footer/footer25/logo-icon.svg +15 -0
  191. package/templates/public/footer/footer25/logo-text.svg +42 -0
  192. package/templates/public/footer/footer25/map-pin.svg +7 -0
  193. package/templates/public/footer/footer25/map.png +0 -0
  194. package/templates/public/footer/footer26/logo-jpl.svg +5 -0
  195. package/templates/public/footer/footer26/logo.png +0 -0
  196. package/templates/public/footer/footer27/logo.png +0 -0
  197. package/templates/public/footer/footer28/logo.png +0 -0
@@ -0,0 +1,170 @@
1
+ "use client";
2
+
3
+ import {
4
+ footer06DefaultProps,
5
+ footer06PropTypes,
6
+ } from "./Footer06.propTypes";
7
+
8
+ function LinkedinIcon({ className = "" }) {
9
+ return (
10
+ <svg viewBox="0 0 24 24" fill="none" aria-hidden="true" className={className}>
11
+ <rect x="3" y="9" width="4" height="12" fill="currentColor" />
12
+ <circle cx="5" cy="5" r="2" fill="currentColor" />
13
+ <path
14
+ d="M11 9h3.8v1.6c.7-1.1 2-1.8 3.5-1.8 3.4 0 4 2.2 4 5.1V21H18v-5.2c0-1.2 0-2.8-1.7-2.8-1.7 0-2 1.3-2 2.6V21h-3.2V9z"
15
+ fill="currentColor"
16
+ />
17
+ </svg>
18
+ );
19
+ }
20
+
21
+ function FacebookIcon({ className = "" }) {
22
+ return (
23
+ <svg viewBox="0 0 24 24" fill="none" aria-hidden="true" className={className}>
24
+ <path
25
+ d="M14 8.5h2.5V5h-2.5C11.5 5 10 6.8 10 9v2.5H7.5V15H10v6h4v-6h3l.5-3.5H14V9.5c0-.8.2-1 1-1z"
26
+ fill="currentColor"
27
+ />
28
+ </svg>
29
+ );
30
+ }
31
+
32
+ function XIcon({ className = "" }) {
33
+ return (
34
+ <svg viewBox="0 0 24 24" fill="none" aria-hidden="true" className={className}>
35
+ <path
36
+ d="M4 4l7.2 9.6L4.3 20h2.4l5.4-6.2 4.4 6.2H20l-7.5-10L19.4 4h-2.4l-5 5.7L8.4 4H4z"
37
+ fill="currentColor"
38
+ />
39
+ </svg>
40
+ );
41
+ }
42
+
43
+ function InstagramIcon({ className = "" }) {
44
+ return (
45
+ <svg viewBox="0 0 24 24" fill="none" aria-hidden="true" className={className}>
46
+ <rect x="3" y="3" width="18" height="18" rx="5" stroke="currentColor" strokeWidth="1.5" />
47
+ <circle cx="12" cy="12" r="4" stroke="currentColor" strokeWidth="1.5" />
48
+ <circle cx="17.5" cy="6.5" r="1" fill="currentColor" />
49
+ </svg>
50
+ );
51
+ }
52
+
53
+ function YoutubeIcon({ className = "" }) {
54
+ return (
55
+ <svg viewBox="0 0 24 24" fill="none" aria-hidden="true" className={className}>
56
+ <path
57
+ d="M21.6 7.2a2.5 2.5 0 00-1.8-1.8C17.9 5 12 5 12 5s-5.9 0-7.8.4A2.5 2.5 0 002.4 7.2 26 26 0 002 12a26 26 0 00.4 4.8 2.5 2.5 0 001.8 1.8C6.1 19 12 19 12 19s5.9 0 7.8-.4a2.5 2.5 0 001.8-1.8A26 26 0 0022 12a26 26 0 00-.4-4.8zM10 15.5v-7l6 3.5-6 3.5z"
58
+ fill="currentColor"
59
+ />
60
+ </svg>
61
+ );
62
+ }
63
+
64
+ const SOCIAL_ICONS = {
65
+ linkedin: LinkedinIcon,
66
+ facebook: FacebookIcon,
67
+ x: XIcon,
68
+ instagram: InstagramIcon,
69
+ youtube: YoutubeIcon,
70
+ };
71
+
72
+ function Dot() {
73
+ return <span className="text-[#c6cad0]" aria-hidden="true">•</span>;
74
+ }
75
+
76
+ function LinkRow({ links, className = "" }) {
77
+ return (
78
+ <nav
79
+ className={[
80
+ "flex flex-wrap items-center justify-center gap-x-3 gap-y-2 text-center sm:gap-x-4",
81
+ className,
82
+ ].join(" ")}
83
+ >
84
+ {links.map((link, index) => (
85
+ <span key={`${link.label}-${index}`} className="inline-flex items-center gap-3 sm:gap-4">
86
+ {index > 0 ? <Dot /> : null}
87
+ <a
88
+ href={link.href ?? "#"}
89
+ className="transition-colors duration-200 ease-out hover:text-[#010623] focus-visible:outline-2 focus-visible:outline-offset-2"
90
+ >
91
+ {link.label}
92
+ </a>
93
+ </span>
94
+ ))}
95
+ </nav>
96
+ );
97
+ }
98
+
99
+ /**
100
+ * Footer06 — Brac EPL centered link rows footer.
101
+ * Figma node 32:20237 at 1920px.
102
+ */
103
+ export function Footer06({
104
+ primaryLinks = footer06DefaultProps.primaryLinks,
105
+ secondaryLinks = footer06DefaultProps.secondaryLinks,
106
+ socialLinks = footer06DefaultProps.socialLinks,
107
+ copyright = footer06DefaultProps.copyright,
108
+ siteByLabel = footer06DefaultProps.siteByLabel,
109
+ siteByHref = footer06DefaultProps.siteByHref,
110
+ className = "",
111
+ }) {
112
+ return (
113
+ <footer
114
+ className={["relative w-full overflow-hidden border-t border-[#edeef0] bg-white", className]
115
+ .filter(Boolean)
116
+ .join(" ")}
117
+ data-footer="footer06"
118
+ >
119
+ <div className="mx-auto flex w-full max-w-[1920px] flex-col items-center gap-8 px-4 py-12 sm:px-6 md:gap-10 md:px-10 lg:px-20 lg:py-16 xl:gap-12 xl:px-[240px] xl:py-20">
120
+ <div className="flex flex-wrap items-center justify-center gap-3 sm:gap-4">
121
+ {socialLinks.map((social, index) => {
122
+ const Icon = SOCIAL_ICONS[social.icon] ?? LinkedinIcon;
123
+ return (
124
+ <span key={social.label} className="inline-flex items-center gap-3 sm:gap-4">
125
+ {index > 0 ? <Dot /> : null}
126
+ <a
127
+ href={social.href ?? "#"}
128
+ aria-label={social.label}
129
+ className="text-[#272e39] transition-colors duration-200 ease-out hover:text-[#010623] focus-visible:outline-2 focus-visible:outline-offset-2"
130
+ >
131
+ <Icon className="size-6" />
132
+ </a>
133
+ </span>
134
+ );
135
+ })}
136
+ </div>
137
+
138
+ <div className="h-px w-full bg-[#edeef0]" />
139
+
140
+ <LinkRow
141
+ links={primaryLinks}
142
+ className="font-serif text-lg text-[#010623] sm:text-xl lg:text-[22px]"
143
+ />
144
+
145
+ <div className="h-px w-full bg-[#edeef0]" />
146
+
147
+ <LinkRow
148
+ links={secondaryLinks}
149
+ className="text-sm text-[#272e39]/60 sm:text-base"
150
+ />
151
+
152
+ <div className="h-px w-full bg-[#edeef0]" />
153
+
154
+ <p className="text-center text-sm text-[#272e39]/60 sm:text-base">
155
+ {copyright} Site by{" "}
156
+ <a
157
+ href={siteByHref ?? "#"}
158
+ className="underline transition-colors duration-200 ease-out hover:text-[#272e39] focus-visible:outline-2 focus-visible:outline-offset-2"
159
+ >
160
+ {siteByLabel}
161
+ </a>
162
+ </p>
163
+ </div>
164
+ </footer>
165
+ );
166
+ }
167
+
168
+ Footer06.propTypes = footer06PropTypes;
169
+
170
+ export default Footer06;
@@ -0,0 +1,53 @@
1
+ import PropTypes from "prop-types";
2
+
3
+ const linkShape = PropTypes.shape({
4
+ label: PropTypes.string.isRequired,
5
+ href: PropTypes.string,
6
+ });
7
+
8
+ const socialShape = PropTypes.shape({
9
+ label: PropTypes.string.isRequired,
10
+ href: PropTypes.string,
11
+ icon: PropTypes.oneOf(["linkedin", "facebook", "x", "instagram", "youtube"]),
12
+ });
13
+
14
+ export const footer06PropTypes = {
15
+ primaryLinks: PropTypes.arrayOf(linkShape),
16
+ secondaryLinks: PropTypes.arrayOf(linkShape),
17
+ socialLinks: PropTypes.arrayOf(socialShape),
18
+ copyright: PropTypes.string,
19
+ siteByLabel: PropTypes.string,
20
+ siteByHref: PropTypes.string,
21
+ className: PropTypes.string,
22
+ };
23
+
24
+ export const footer06DefaultProps = {
25
+ primaryLinks: [
26
+ { label: "Products & Services", href: "#" },
27
+ { label: "Offshore Invest", href: "#" },
28
+ { label: "BESL Research", href: "#" },
29
+ { label: "About Us", href: "#" },
30
+ { label: "Information Hub", href: "#" },
31
+ { label: "Contact us", href: "#" },
32
+ ],
33
+ secondaryLinks: [
34
+ { label: "Set up a BO account", href: "#" },
35
+ { label: "Management Team", href: "#" },
36
+ { label: "Market News", href: "#" },
37
+ { label: "Set up a BO account", href: "#" },
38
+ { label: "Careers", href: "#" },
39
+ { label: "Terms & Conditions", href: "#" },
40
+ { label: "Privacy Policies", href: "#" },
41
+ ],
42
+ socialLinks: [
43
+ { label: "LinkedIn", href: "#", icon: "linkedin" },
44
+ { label: "Facebook", href: "#", icon: "facebook" },
45
+ { label: "X", href: "#", icon: "x" },
46
+ { label: "Instagram", href: "#", icon: "instagram" },
47
+ { label: "YouTube", href: "#", icon: "youtube" },
48
+ ],
49
+ copyright: "© 2025 Brac EPL. All rights reserved.",
50
+ siteByLabel: "Notionhive.",
51
+ siteByHref: "#",
52
+ className: "",
53
+ };
@@ -0,0 +1 @@
1
+ export { Footer06, default } from "./Footer06";
@@ -0,0 +1,253 @@
1
+ "use client";
2
+
3
+ import { useState } from "react";
4
+ import { SafeImage } from "../../atoms/SafeImage";
5
+ import {
6
+ footer07DefaultProps,
7
+ footer07PropTypes,
8
+ } from "./Footer07.propTypes";
9
+
10
+ function ArrowUpRightIcon({ className = "" }) {
11
+ return (
12
+ <svg viewBox="0 0 20 20" fill="none" aria-hidden="true" className={className}>
13
+ <path
14
+ d="M5 15L15 5M15 5H7M15 5V13"
15
+ stroke="currentColor"
16
+ strokeWidth="1.5"
17
+ strokeLinecap="round"
18
+ strokeLinejoin="round"
19
+ />
20
+ </svg>
21
+ );
22
+ }
23
+
24
+ function FacebookIcon({ className = "" }) {
25
+ return (
26
+ <svg viewBox="0 0 34 34" fill="none" aria-hidden="true" className={className}>
27
+ <circle cx="17" cy="17" r="17" fill="currentColor" />
28
+ <path
29
+ d="M18.5 10h-2a2 2 0 00-2 2v2h-2v3h2v7h3v-7h2.5l.5-3h-3v-2c0-.55.45-1 1-1h2V10z"
30
+ fill="white"
31
+ />
32
+ </svg>
33
+ );
34
+ }
35
+
36
+ function YoutubeIcon({ className = "" }) {
37
+ return (
38
+ <svg viewBox="0 0 34 34" fill="none" aria-hidden="true" className={className}>
39
+ <circle cx="17" cy="17" r="17" fill="currentColor" />
40
+ <path
41
+ d="M24 12.5a2 2 0 00-1.4-1.4C21 11 17 11 17 11s-4 0-5.6.1A2 2 0 0010 12.5 21 21 0 009 17a21 21 0 00.9 4.5 2 2 0 001.4 1.4C13 23 17 23 17 23s4 0 5.6-.1a2 2 0 001.4-1.4A21 21 0 0025 17a21 21 0 00-1-4.5zM14.5 19.5v-5L19 17l-4.5 2.5z"
42
+ fill="white"
43
+ />
44
+ </svg>
45
+ );
46
+ }
47
+
48
+ function InstagramIcon({ className = "" }) {
49
+ return (
50
+ <svg viewBox="0 0 34 34" fill="none" aria-hidden="true" className={className}>
51
+ <circle cx="17" cy="17" r="17" fill="currentColor" />
52
+ <rect x="11" y="11" width="12" height="12" rx="3" stroke="white" strokeWidth="1.2" />
53
+ <circle cx="17" cy="17" r="3" stroke="white" strokeWidth="1.2" />
54
+ <circle cx="20.5" cy="13.5" r="0.8" fill="white" />
55
+ </svg>
56
+ );
57
+ }
58
+
59
+ const SOCIAL_ICONS = {
60
+ facebook: FacebookIcon,
61
+ youtube: YoutubeIcon,
62
+ instagram: InstagramIcon,
63
+ };
64
+
65
+ function LinkColumn({ column, twoColumn = false, policyLinks = [] }) {
66
+ if (twoColumn) {
67
+ return (
68
+ <div className="flex min-w-0 flex-col gap-14">
69
+ <p className="text-xl leading-[1.2] text-[#5a5a5a]">{column.title}</p>
70
+ <div className="flex flex-col gap-8 sm:flex-row sm:gap-0">
71
+ <ul className="flex w-full flex-col gap-4 sm:w-[232px]">
72
+ {column.links.map((link) => (
73
+ <li key={link.label}>
74
+ <a
75
+ href={link.href ?? "#"}
76
+ className="text-base font-light text-[#5a5a5a] transition-colors duration-200 ease-out hover:text-black focus-visible:outline-2 focus-visible:outline-offset-2"
77
+ >
78
+ {link.label}
79
+ </a>
80
+ </li>
81
+ ))}
82
+ </ul>
83
+ <ul className="flex w-full flex-col gap-4 sm:w-[232px]">
84
+ {policyLinks.map((link) => (
85
+ <li key={link.label}>
86
+ <a
87
+ href={link.href ?? "#"}
88
+ className="text-base font-light text-[#5a5a5a] transition-colors duration-200 ease-out hover:text-black focus-visible:outline-2 focus-visible:outline-offset-2"
89
+ >
90
+ {link.label}
91
+ </a>
92
+ </li>
93
+ ))}
94
+ </ul>
95
+ </div>
96
+ </div>
97
+ );
98
+ }
99
+
100
+ return (
101
+ <div className="flex min-w-0 flex-1 flex-col gap-14">
102
+ <p className="text-xl leading-[1.2] text-[#5a5a5a]">{column.title}</p>
103
+ <ul className="flex flex-col gap-4">
104
+ {column.links.map((link) => (
105
+ <li key={link.label}>
106
+ <a
107
+ href={link.href ?? "#"}
108
+ className="text-base font-light text-[#5a5a5a] transition-colors duration-200 ease-out hover:text-black focus-visible:outline-2 focus-visible:outline-offset-2"
109
+ >
110
+ {link.label}
111
+ </a>
112
+ </li>
113
+ ))}
114
+ </ul>
115
+ </div>
116
+ );
117
+ }
118
+
119
+ /**
120
+ * Footer07 — ZEIT luxury watch footer with hero image + newsletter.
121
+ * Figma node 32:20239 at 1920px.
122
+ */
123
+ export function Footer07({
124
+ newsletterTitle = footer07DefaultProps.newsletterTitle,
125
+ emailPlaceholder = footer07DefaultProps.emailPlaceholder,
126
+ email: controlledEmail,
127
+ onEmailChange,
128
+ onNewsletterSubmit,
129
+ linkColumns = footer07DefaultProps.linkColumns,
130
+ policyLinks = footer07DefaultProps.policyLinks,
131
+ copyright = footer07DefaultProps.copyright,
132
+ socialLinks = footer07DefaultProps.socialLinks,
133
+ className = "",
134
+ }) {
135
+ const [internalEmail, setInternalEmail] = useState("");
136
+ const email = controlledEmail ?? internalEmail;
137
+
138
+ const handleEmailChange = (event) => {
139
+ onEmailChange?.(event.target.value);
140
+ if (controlledEmail === undefined) setInternalEmail(event.target.value);
141
+ };
142
+
143
+ const handleSubmit = (event) => {
144
+ event.preventDefault();
145
+ onNewsletterSubmit?.(email);
146
+ };
147
+
148
+ const mainColumns = linkColumns.filter((col) => col.title !== "Quick Links");
149
+ const quickLinksColumn = linkColumns.find((col) => col.title === "Quick Links");
150
+
151
+ return (
152
+ <footer
153
+ className={["relative w-full overflow-hidden bg-white", className]
154
+ .filter(Boolean)
155
+ .join(" ")}
156
+ data-footer="footer07"
157
+ >
158
+ <div className="relative mx-auto w-full max-w-[1920px]">
159
+ <div className="relative flex flex-col items-center pt-12 sm:pt-16 xl:pt-[100px]">
160
+ <div className="relative mb-[-80px] w-full sm:mb-[-120px] xl:mb-[-200px]">
161
+ <div className="relative aspect-[1920/528] w-full overflow-hidden">
162
+ <SafeImage
163
+ src="/footer/footer07/watch-hero.png"
164
+ alt=""
165
+ fill
166
+ className="object-cover object-center"
167
+ />
168
+ <SafeImage
169
+ src="/footer/footer07/watch-overlay.png"
170
+ alt=""
171
+ fill
172
+ className="object-cover object-center"
173
+ />
174
+ </div>
175
+ <div className="absolute inset-x-0 bottom-0 flex justify-center">
176
+ <SafeImage
177
+ src="/footer/footer07/logo.png"
178
+ alt="ZEIT"
179
+ width={665}
180
+ height={200}
181
+ className="h-16 w-auto sm:h-24 md:h-32 xl:h-[200px] xl:w-[665px]"
182
+ />
183
+ </div>
184
+ </div>
185
+
186
+ <div className="relative z-10 flex w-full flex-col gap-[140px] bg-white px-4 sm:px-6 md:px-10 lg:px-20 xl:px-[80px] xl:pt-[140px]">
187
+ <div className="flex flex-col gap-12 xl:flex-row xl:items-start xl:justify-between">
188
+ <form onSubmit={handleSubmit} className="w-full max-w-[466px]">
189
+ <p className="mb-14 text-xl leading-[1.2] text-[#5a5a5a]">
190
+ Sign up to our
191
+ <br />
192
+ Newsletter
193
+ </p>
194
+ <div className="flex items-center gap-2.5 border-b border-black pb-4">
195
+ <input
196
+ type="email"
197
+ value={email}
198
+ onChange={handleEmailChange}
199
+ placeholder={emailPlaceholder}
200
+ className="min-w-0 flex-1 bg-transparent text-base font-light leading-none text-[#5a5a5a] outline-none placeholder:text-[#5a5a5a]/60"
201
+ />
202
+ <button
203
+ type="submit"
204
+ aria-label="Subscribe"
205
+ className="shrink-0 text-[#5a5a5a] transition-opacity duration-200 ease-out hover:opacity-70 focus-visible:outline-2 focus-visible:outline-offset-2"
206
+ >
207
+ <ArrowUpRightIcon className="size-5" />
208
+ </button>
209
+ </div>
210
+ </form>
211
+
212
+ <div className="flex w-full max-w-[1090px] flex-col gap-10 sm:flex-row sm:flex-wrap sm:gap-12 xl:gap-12">
213
+ {mainColumns.map((column) => (
214
+ <LinkColumn key={column.title} column={column} />
215
+ ))}
216
+ {quickLinksColumn ? (
217
+ <LinkColumn
218
+ column={quickLinksColumn}
219
+ twoColumn
220
+ policyLinks={policyLinks}
221
+ />
222
+ ) : null}
223
+ </div>
224
+ </div>
225
+
226
+ <div className="flex flex-col gap-6 border-t border-[#101214]/10 px-0 py-6 sm:flex-row sm:items-center sm:justify-between xl:py-6">
227
+ <p className="text-base font-light leading-none text-[#5a5a5a]">{copyright}</p>
228
+ <div className="flex items-center gap-1.5">
229
+ {socialLinks.map((social) => {
230
+ const Icon = SOCIAL_ICONS[social.icon] ?? FacebookIcon;
231
+ return (
232
+ <a
233
+ key={social.label}
234
+ href={social.href ?? "#"}
235
+ aria-label={social.label}
236
+ className="text-black transition-opacity duration-200 ease-out hover:opacity-80 focus-visible:outline-2 focus-visible:outline-offset-2"
237
+ >
238
+ <Icon className="size-[34px]" />
239
+ </a>
240
+ );
241
+ })}
242
+ </div>
243
+ </div>
244
+ </div>
245
+ </div>
246
+ </div>
247
+ </footer>
248
+ );
249
+ }
250
+
251
+ Footer07.propTypes = footer07PropTypes;
252
+
253
+ export default Footer07;
@@ -0,0 +1,83 @@
1
+ import PropTypes from "prop-types";
2
+
3
+ const linkShape = PropTypes.shape({
4
+ label: PropTypes.string.isRequired,
5
+ href: PropTypes.string,
6
+ });
7
+
8
+ const columnShape = PropTypes.shape({
9
+ title: PropTypes.string.isRequired,
10
+ links: PropTypes.arrayOf(linkShape),
11
+ });
12
+
13
+ const socialShape = PropTypes.shape({
14
+ label: PropTypes.string.isRequired,
15
+ href: PropTypes.string,
16
+ icon: PropTypes.oneOf(["facebook", "youtube", "instagram"]),
17
+ });
18
+
19
+ export const footer07PropTypes = {
20
+ newsletterTitle: PropTypes.string,
21
+ emailPlaceholder: PropTypes.string,
22
+ email: PropTypes.string,
23
+ onEmailChange: PropTypes.func,
24
+ onNewsletterSubmit: PropTypes.func,
25
+ linkColumns: PropTypes.arrayOf(columnShape),
26
+ policyLinks: PropTypes.arrayOf(linkShape),
27
+ copyright: PropTypes.string,
28
+ socialLinks: PropTypes.arrayOf(socialShape),
29
+ className: PropTypes.string,
30
+ };
31
+
32
+ export const footer07DefaultProps = {
33
+ newsletterTitle: "Sign up to our Newsletter",
34
+ emailPlaceholder: "Email Address",
35
+ email: "",
36
+ linkColumns: [
37
+ {
38
+ title: "Catalog",
39
+ links: [
40
+ { label: "Men's", href: "#" },
41
+ { label: "Women's", href: "#" },
42
+ { label: "Youtube", href: "#" },
43
+ ],
44
+ },
45
+ {
46
+ title: "Series",
47
+ links: [
48
+ { label: "Prime Series", href: "#" },
49
+ { label: "Chrono", href: "#" },
50
+ ],
51
+ },
52
+ {
53
+ title: "Accessories",
54
+ links: [
55
+ { label: "Battery", href: "#" },
56
+ { label: "Watch Gift Box", href: "#" },
57
+ { label: "Watch Straps", href: "#" },
58
+ ],
59
+ },
60
+ {
61
+ title: "Quick Links",
62
+ links: [
63
+ { label: "About Us", href: "#" },
64
+ { label: "Contact Us", href: "#" },
65
+ { label: "Service Center", href: "#" },
66
+ { label: "Shop", href: "#" },
67
+ ],
68
+ },
69
+ ],
70
+ policyLinks: [
71
+ { label: "Return & Refund Policy", href: "#" },
72
+ { label: "Terms & Conditions", href: "#" },
73
+ { label: "Privacy Policy", href: "#" },
74
+ { label: "FAQs", href: "#" },
75
+ ],
76
+ copyright: "©2026 ZEIT. All rights reserved.",
77
+ socialLinks: [
78
+ { label: "Facebook", href: "#", icon: "facebook" },
79
+ { label: "YouTube", href: "#", icon: "youtube" },
80
+ { label: "Instagram", href: "#", icon: "instagram" },
81
+ ],
82
+ className: "",
83
+ };
@@ -0,0 +1 @@
1
+ export { Footer07, default } from "./Footer07";