@notionhive/contacts 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.
- package/bin/contacts.js +16 -0
- package/category.config.json +7 -0
- package/package.json +24 -0
- package/registry/contact-01.json +9 -0
- package/registry/contact-02.json +9 -0
- package/registry/contact-03.json +9 -0
- package/registry/contact-04.json +6 -0
- package/registry/contact-05.json +9 -0
- package/registry/contact-06.json +9 -0
- package/registry/contact-07.json +9 -0
- package/registry/contact-08.json +6 -0
- package/registry/contact-09.json +10 -0
- package/registry/contact-10.json +6 -0
- package/registry/index.json +88 -0
- package/templates/components/atoms/SafeImage/SafeImage.jsx +101 -0
- package/templates/components/atoms/SafeImage/index.js +1 -0
- package/templates/components/hooks/useCarousel.js +73 -0
- package/templates/components/organisms/Contact01/Contact01.jsx +363 -0
- package/templates/components/organisms/Contact01/Contact01.propTypes.js +105 -0
- package/templates/components/organisms/Contact01/index.js +1 -0
- package/templates/components/organisms/Contact02/Contact02.jsx +288 -0
- package/templates/components/organisms/Contact02/Contact02.propTypes.js +78 -0
- package/templates/components/organisms/Contact02/index.js +1 -0
- package/templates/components/organisms/Contact03/Contact03.jsx +94 -0
- package/templates/components/organisms/Contact03/Contact03.propTypes.js +25 -0
- package/templates/components/organisms/Contact03/index.js +1 -0
- package/templates/components/organisms/Contact04/Contact04.jsx +239 -0
- package/templates/components/organisms/Contact04/Contact04.propTypes.js +50 -0
- package/templates/components/organisms/Contact04/index.js +1 -0
- package/templates/components/organisms/Contact05/Contact05.jsx +272 -0
- package/templates/components/organisms/Contact05/Contact05.propTypes.js +49 -0
- package/templates/components/organisms/Contact05/index.js +1 -0
- package/templates/components/organisms/Contact06/Contact06.jsx +223 -0
- package/templates/components/organisms/Contact06/Contact06.propTypes.js +40 -0
- package/templates/components/organisms/Contact06/index.js +1 -0
- package/templates/components/organisms/Contact07/Contact07.jsx +348 -0
- package/templates/components/organisms/Contact07/Contact07.propTypes.js +92 -0
- package/templates/components/organisms/Contact07/index.js +1 -0
- package/templates/components/organisms/Contact08/Contact08.jsx +178 -0
- package/templates/components/organisms/Contact08/Contact08.propTypes.js +36 -0
- package/templates/components/organisms/Contact08/index.js +1 -0
- package/templates/components/organisms/Contact09/Contact09.jsx +345 -0
- package/templates/components/organisms/Contact09/Contact09.propTypes.js +96 -0
- package/templates/components/organisms/Contact09/index.js +1 -0
- package/templates/components/organisms/Contact10/Contact10.jsx +175 -0
- package/templates/components/organisms/Contact10/Contact10.propTypes.js +55 -0
- package/templates/components/organisms/Contact10/index.js +1 -0
- package/templates/public/contact/contact01/ellipse.svg +12 -0
- package/templates/public/contact/contact01/logo-accenture.svg +6 -0
- package/templates/public/contact/contact01/logo-amart.svg +12 -0
- package/templates/public/contact/contact01/logo-brand12.png +0 -0
- package/templates/public/contact/contact01/logo-brand5.png +0 -0
- package/templates/public/contact/contact01/logo-brand7.png +0 -0
- package/templates/public/contact/contact01/logo-brand9.svg +12 -0
- package/templates/public/contact/contact01/logo-great-eastern.png +0 -0
- package/templates/public/contact/contact01/logo-kenwood.png +0 -0
- package/templates/public/contact/contact01/logo-nissan.svg +12 -0
- package/templates/public/contact/contact01/logo-suncorp.png +0 -0
- package/templates/public/contact/contact01/logo-ticketmaster.png +0 -0
- package/templates/public/contact/contact01/logo-toyota.svg +5 -0
- package/templates/public/contact/contact02/map.jpg +0 -0
- package/templates/public/contact/contact03/bg.jpg +0 -0
- package/templates/public/contact/contact03/card-photo.jpg +0 -0
- package/templates/public/contact/contact05/hero.jpg +0 -0
- package/templates/public/contact/contact05/pattern.png +0 -0
- package/templates/public/contact/contact06/hero.jpg +0 -0
- package/templates/public/contact/contact07/hero.jpg +0 -0
- package/templates/public/contact/contact09/avatar.jpg +0 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import SafeImage from "../../atoms/SafeImage";
|
|
5
|
+
import {
|
|
6
|
+
contact02DefaultProps,
|
|
7
|
+
contact02PropTypes,
|
|
8
|
+
} from "./Contact02.propTypes";
|
|
9
|
+
|
|
10
|
+
function SearchPinIcon({ className = "" }) {
|
|
11
|
+
return (
|
|
12
|
+
<svg viewBox="0 0 18 18" fill="none" aria-hidden="true" className={className}>
|
|
13
|
+
<path
|
|
14
|
+
d="M9 1.5a5.25 5.25 0 00-5.25 5.25c0 3.938 5.25 9.75 5.25 9.75s5.25-5.812 5.25-9.75A5.25 5.25 0 009 1.5z"
|
|
15
|
+
stroke="currentColor"
|
|
16
|
+
strokeWidth="1.2"
|
|
17
|
+
strokeLinejoin="round"
|
|
18
|
+
/>
|
|
19
|
+
<circle cx="9" cy="6.75" r="1.75" fill="currentColor" />
|
|
20
|
+
</svg>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function LocationPinIcon({ active = false, index, className = "" }) {
|
|
25
|
+
return (
|
|
26
|
+
<div className={`relative size-7 shrink-0 ${className}`} aria-hidden="true">
|
|
27
|
+
<svg viewBox="0 0 24 24" fill="none" className="size-6">
|
|
28
|
+
<path
|
|
29
|
+
d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7z"
|
|
30
|
+
fill={active ? "#367c2b" : "#525252"}
|
|
31
|
+
/>
|
|
32
|
+
<circle cx="12" cy="9" r="2.5" fill="white" />
|
|
33
|
+
</svg>
|
|
34
|
+
{index != null ? (
|
|
35
|
+
<span className="absolute left-1/2 top-[9px] -translate-x-1/2 text-[10px] font-bold leading-none text-white">
|
|
36
|
+
{index}
|
|
37
|
+
</span>
|
|
38
|
+
) : null}
|
|
39
|
+
</div>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function PhoneIcon({ className = "" }) {
|
|
44
|
+
return (
|
|
45
|
+
<svg viewBox="0 0 18 18" fill="none" aria-hidden="true" className={className}>
|
|
46
|
+
<path
|
|
47
|
+
d="M4.5 2.25h2.25l.75 2.25-1.69 1.13a7.5 7.5 0 003.38 3.38L10.5 7.5l2.25.75V10.5a1.13 1.13 0 01-1.13 1.13A9.38 9.38 0 012.25 4.5a1.13 1.13 0 011.13-1.13z"
|
|
48
|
+
stroke="currentColor"
|
|
49
|
+
strokeWidth="1.2"
|
|
50
|
+
strokeLinecap="round"
|
|
51
|
+
strokeLinejoin="round"
|
|
52
|
+
/>
|
|
53
|
+
</svg>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function ComputerIcon({ className = "" }) {
|
|
58
|
+
return (
|
|
59
|
+
<svg viewBox="0 0 18 18" fill="none" aria-hidden="true" className={className}>
|
|
60
|
+
<rect x="2" y="3" width="14" height="9" rx="1" stroke="currentColor" strokeWidth="1.2" />
|
|
61
|
+
<path d="M6 15h6M9 12v3" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" />
|
|
62
|
+
</svg>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function ExternalLinkIcon({ className = "" }) {
|
|
67
|
+
return (
|
|
68
|
+
<svg viewBox="0 0 20 20" fill="none" aria-hidden="true" className={className}>
|
|
69
|
+
<path
|
|
70
|
+
d="M11 3h6v6M17 3L9 11M7 5H4a1 1 0 00-1 1v10a1 1 0 001 1h10a1 1 0 001-1v-3"
|
|
71
|
+
stroke="currentColor"
|
|
72
|
+
strokeWidth="1.2"
|
|
73
|
+
strokeLinecap="round"
|
|
74
|
+
strokeLinejoin="round"
|
|
75
|
+
/>
|
|
76
|
+
</svg>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function DirectionsIcon({ className = "" }) {
|
|
81
|
+
return (
|
|
82
|
+
<svg viewBox="0 0 18 18" fill="none" aria-hidden="true" className={className}>
|
|
83
|
+
<path
|
|
84
|
+
d="M3 15l4-12 4 4 4-4v12H3z"
|
|
85
|
+
stroke="currentColor"
|
|
86
|
+
strokeWidth="1.2"
|
|
87
|
+
strokeLinejoin="round"
|
|
88
|
+
/>
|
|
89
|
+
</svg>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function CollapseIcon({ className = "" }) {
|
|
94
|
+
return (
|
|
95
|
+
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true" className={className}>
|
|
96
|
+
<circle cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="1.2" />
|
|
97
|
+
<path d="M14 8l-4 4 4 4" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" strokeLinejoin="round" />
|
|
98
|
+
</svg>
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Contact02 — Dealer locator split with search, location list, and map.
|
|
104
|
+
* Figma node 26:15671 at 1920px.
|
|
105
|
+
*
|
|
106
|
+
* @param {object} props - See Contact02.propTypes.js.
|
|
107
|
+
*/
|
|
108
|
+
export function Contact02({
|
|
109
|
+
searchPlaceholder = contact02DefaultProps.searchPlaceholder,
|
|
110
|
+
findButtonText = contact02DefaultProps.findButtonText,
|
|
111
|
+
locationsTitle = contact02DefaultProps.locationsTitle,
|
|
112
|
+
locations = contact02DefaultProps.locations,
|
|
113
|
+
mapImage = contact02DefaultProps.mapImage,
|
|
114
|
+
mapAlt = contact02DefaultProps.mapAlt,
|
|
115
|
+
defaultActiveLocation = contact02DefaultProps.defaultActiveLocation,
|
|
116
|
+
activeLocation: controlledActive,
|
|
117
|
+
onLocationSelect,
|
|
118
|
+
onUseMyLocation,
|
|
119
|
+
onFindLocation,
|
|
120
|
+
className = "",
|
|
121
|
+
}) {
|
|
122
|
+
const [internalActive, setInternalActive] = useState(defaultActiveLocation);
|
|
123
|
+
|
|
124
|
+
const activeLocation = controlledActive ?? internalActive;
|
|
125
|
+
|
|
126
|
+
const selectLocation = (index) => {
|
|
127
|
+
onLocationSelect?.(index);
|
|
128
|
+
if (controlledActive === undefined) setInternalActive(index);
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
return (
|
|
132
|
+
<section
|
|
133
|
+
className={["relative w-full overflow-hidden bg-white", className]
|
|
134
|
+
.filter(Boolean)
|
|
135
|
+
.join(" ")}
|
|
136
|
+
data-contact="contact02"
|
|
137
|
+
>
|
|
138
|
+
<div className="relative mx-auto flex w-full max-w-[1920px] flex-col lg:min-h-[720px] lg:flex-row">
|
|
139
|
+
{/* Left — search + location list */}
|
|
140
|
+
<div className="flex w-full shrink-0 flex-col border border-[#e5e5e5] lg:w-[38.4%] lg:max-w-[738px] lg:min-h-[720px]">
|
|
141
|
+
{/* Search bar */}
|
|
142
|
+
<div className="border-b border-[#e5e5e5] bg-white px-4 py-5 sm:px-6 md:px-8 lg:px-8">
|
|
143
|
+
<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:gap-4">
|
|
144
|
+
<button
|
|
145
|
+
type="button"
|
|
146
|
+
onClick={onUseMyLocation}
|
|
147
|
+
className="flex min-h-[52px] flex-1 items-center gap-2.5 rounded-full border border-[#848484] bg-white px-4 py-3.5 text-left text-base text-[#848484] transition-colors duration-200 ease-out hover:border-[#525252] focus-visible:outline-2 focus-visible:outline-offset-2"
|
|
148
|
+
>
|
|
149
|
+
<SearchPinIcon className="size-[18px] shrink-0 text-[#848484]" />
|
|
150
|
+
<span>{searchPlaceholder}</span>
|
|
151
|
+
</button>
|
|
152
|
+
<div className="flex items-center gap-3">
|
|
153
|
+
<button
|
|
154
|
+
type="button"
|
|
155
|
+
onClick={onFindLocation}
|
|
156
|
+
className="shrink-0 rounded-full bg-[#367c2b] px-6 py-4 text-base font-bold text-white transition-colors duration-200 ease-out hover:opacity-90 focus-visible:outline-2 focus-visible:outline-offset-2 sm:px-8"
|
|
157
|
+
>
|
|
158
|
+
{findButtonText}
|
|
159
|
+
</button>
|
|
160
|
+
<button
|
|
161
|
+
type="button"
|
|
162
|
+
className="hidden shrink-0 text-[#525252] transition-opacity duration-200 hover:opacity-80 lg:block"
|
|
163
|
+
aria-label="Collapse panel"
|
|
164
|
+
>
|
|
165
|
+
<CollapseIcon className="size-6" />
|
|
166
|
+
</button>
|
|
167
|
+
</div>
|
|
168
|
+
</div>
|
|
169
|
+
</div>
|
|
170
|
+
|
|
171
|
+
{/* Location list */}
|
|
172
|
+
<div className="flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto px-4 py-4 sm:px-4 lg:max-h-[601px]">
|
|
173
|
+
<p className="text-lg font-bold leading-5 text-[#212121]">{locationsTitle}</p>
|
|
174
|
+
|
|
175
|
+
{locations.map((location, index) => {
|
|
176
|
+
const isActive = activeLocation === index;
|
|
177
|
+
return (
|
|
178
|
+
<div
|
|
179
|
+
key={location.id ?? index}
|
|
180
|
+
className={[
|
|
181
|
+
"flex flex-col gap-4 rounded px-4 pb-4 pt-4 transition-colors duration-200",
|
|
182
|
+
isActive ? "bg-[#f5f8f5]" : "bg-white",
|
|
183
|
+
].join(" ")}
|
|
184
|
+
>
|
|
185
|
+
<button
|
|
186
|
+
type="button"
|
|
187
|
+
onClick={() => selectLocation(index)}
|
|
188
|
+
className="flex w-full items-center justify-between gap-3 text-left"
|
|
189
|
+
>
|
|
190
|
+
<LocationPinIcon active={isActive} index={index + 1} />
|
|
191
|
+
<span
|
|
192
|
+
className={[
|
|
193
|
+
"min-w-0 flex-1 text-lg font-bold leading-5",
|
|
194
|
+
isActive ? "text-[#367c2b]" : "text-[#525252]",
|
|
195
|
+
].join(" ")}
|
|
196
|
+
>
|
|
197
|
+
{location.name}
|
|
198
|
+
</span>
|
|
199
|
+
{location.distance ? (
|
|
200
|
+
<span
|
|
201
|
+
className={[
|
|
202
|
+
"shrink-0 text-lg font-bold leading-5",
|
|
203
|
+
isActive ? "text-[#212121]" : "text-[#525252]",
|
|
204
|
+
].join(" ")}
|
|
205
|
+
>
|
|
206
|
+
{location.distance}
|
|
207
|
+
</span>
|
|
208
|
+
) : null}
|
|
209
|
+
</button>
|
|
210
|
+
|
|
211
|
+
<div className="flex items-end justify-between gap-3">
|
|
212
|
+
<div className="flex min-w-0 flex-1 flex-col gap-2">
|
|
213
|
+
{location.address ? (
|
|
214
|
+
<p className="text-base leading-6 text-[#525252]">{location.address}</p>
|
|
215
|
+
) : null}
|
|
216
|
+
{location.phone ? (
|
|
217
|
+
<div className="flex items-center gap-2 text-sm leading-5 text-[#525252]">
|
|
218
|
+
<PhoneIcon className="size-[18px] shrink-0" />
|
|
219
|
+
<span>{location.phone}</span>
|
|
220
|
+
</div>
|
|
221
|
+
) : null}
|
|
222
|
+
{location.website ? (
|
|
223
|
+
<div className="flex items-center gap-2 text-sm leading-5 text-[#525252]">
|
|
224
|
+
<ComputerIcon className="size-[18px] shrink-0" />
|
|
225
|
+
<a
|
|
226
|
+
href={
|
|
227
|
+
location.website.startsWith("http")
|
|
228
|
+
? location.website
|
|
229
|
+
: `https://${location.website}`
|
|
230
|
+
}
|
|
231
|
+
target="_blank"
|
|
232
|
+
rel="noopener noreferrer"
|
|
233
|
+
className="truncate transition-opacity duration-200 hover:opacity-80"
|
|
234
|
+
>
|
|
235
|
+
{location.website}
|
|
236
|
+
</a>
|
|
237
|
+
</div>
|
|
238
|
+
) : null}
|
|
239
|
+
{location.detailsHref ? (
|
|
240
|
+
<a
|
|
241
|
+
href={location.detailsHref}
|
|
242
|
+
className="inline-flex items-center gap-1 text-base leading-6 text-[#525252] transition-opacity duration-200 hover:opacity-80"
|
|
243
|
+
>
|
|
244
|
+
View Details
|
|
245
|
+
<ExternalLinkIcon className="size-5 -rotate-90" />
|
|
246
|
+
</a>
|
|
247
|
+
) : null}
|
|
248
|
+
</div>
|
|
249
|
+
{location.directionsHref ? (
|
|
250
|
+
<a
|
|
251
|
+
href={location.directionsHref}
|
|
252
|
+
target="_blank"
|
|
253
|
+
rel="noopener noreferrer"
|
|
254
|
+
aria-label={`Directions to ${location.name}`}
|
|
255
|
+
className="flex size-[42px] shrink-0 items-center justify-center rounded-full border border-[#525252] text-[#525252] transition-colors duration-200 ease-out hover:bg-[#f5f8f5] focus-visible:outline-2 focus-visible:outline-offset-2"
|
|
256
|
+
>
|
|
257
|
+
<DirectionsIcon className="size-[18px]" />
|
|
258
|
+
</a>
|
|
259
|
+
) : null}
|
|
260
|
+
</div>
|
|
261
|
+
|
|
262
|
+
{index < locations.length - 1 ? (
|
|
263
|
+
<div className="h-px w-full bg-[#e5e5e5]" aria-hidden="true" />
|
|
264
|
+
) : null}
|
|
265
|
+
</div>
|
|
266
|
+
);
|
|
267
|
+
})}
|
|
268
|
+
</div>
|
|
269
|
+
</div>
|
|
270
|
+
|
|
271
|
+
{/* Right — map */}
|
|
272
|
+
<div className="relative h-[50vh] w-full lg:h-auto lg:min-h-[720px] lg:flex-1">
|
|
273
|
+
<SafeImage
|
|
274
|
+
src={mapImage}
|
|
275
|
+
alt={mapAlt}
|
|
276
|
+
fill
|
|
277
|
+
className="object-cover object-center"
|
|
278
|
+
sizes="(max-width: 1024px) 100vw, 62vw"
|
|
279
|
+
/>
|
|
280
|
+
</div>
|
|
281
|
+
</div>
|
|
282
|
+
</section>
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
Contact02.propTypes = contact02PropTypes;
|
|
287
|
+
|
|
288
|
+
export default Contact02;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import PropTypes from "prop-types";
|
|
2
|
+
|
|
3
|
+
const locationShape = PropTypes.shape({
|
|
4
|
+
id: PropTypes.string,
|
|
5
|
+
name: PropTypes.string.isRequired,
|
|
6
|
+
distance: PropTypes.string,
|
|
7
|
+
address: PropTypes.string,
|
|
8
|
+
phone: PropTypes.string,
|
|
9
|
+
website: PropTypes.string,
|
|
10
|
+
detailsHref: PropTypes.string,
|
|
11
|
+
directionsHref: PropTypes.string,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export const contact02PropTypes = {
|
|
15
|
+
searchPlaceholder: PropTypes.string,
|
|
16
|
+
findButtonText: PropTypes.string,
|
|
17
|
+
locationsTitle: PropTypes.string,
|
|
18
|
+
locations: PropTypes.arrayOf(locationShape),
|
|
19
|
+
mapImage: PropTypes.string,
|
|
20
|
+
mapAlt: PropTypes.string,
|
|
21
|
+
defaultActiveLocation: PropTypes.number,
|
|
22
|
+
activeLocation: PropTypes.number,
|
|
23
|
+
onLocationSelect: PropTypes.func,
|
|
24
|
+
onUseMyLocation: PropTypes.func,
|
|
25
|
+
onFindLocation: PropTypes.func,
|
|
26
|
+
className: PropTypes.string,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const contact02DefaultProps = {
|
|
30
|
+
searchPlaceholder: "Use My Location",
|
|
31
|
+
findButtonText: "Find Location",
|
|
32
|
+
locationsTitle: "Nearest locations (15)",
|
|
33
|
+
mapImage: "/contact/contact02/map.jpg",
|
|
34
|
+
mapAlt: "Dealer locator map",
|
|
35
|
+
defaultActiveLocation: 0,
|
|
36
|
+
locations: [
|
|
37
|
+
{
|
|
38
|
+
id: "1",
|
|
39
|
+
name: "Koenig Equipment",
|
|
40
|
+
distance: "65.1 mi",
|
|
41
|
+
address: "1929 East Main Street Greenfield, IN, United States",
|
|
42
|
+
phone: "3178490810",
|
|
43
|
+
website: "www.koenigfarmequipment.com",
|
|
44
|
+
detailsHref: "#",
|
|
45
|
+
directionsHref: "#",
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
id: "2",
|
|
49
|
+
name: "Koenig Equipment",
|
|
50
|
+
distance: "65.1 mi",
|
|
51
|
+
address: "1929 East Main Street Greenfield, IN, United States",
|
|
52
|
+
phone: "3178490810",
|
|
53
|
+
website: "www.koenigfarmequipment.com",
|
|
54
|
+
detailsHref: "#",
|
|
55
|
+
directionsHref: "#",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
id: "3",
|
|
59
|
+
name: "Koenig Equipment",
|
|
60
|
+
distance: "65.1 mi",
|
|
61
|
+
address: "1929 East Main Street Greenfield, IN, United States",
|
|
62
|
+
phone: "3178490810",
|
|
63
|
+
website: "www.koenigfarmequipment.com",
|
|
64
|
+
detailsHref: "#",
|
|
65
|
+
directionsHref: "#",
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
id: "4",
|
|
69
|
+
name: "Koenig Equipment",
|
|
70
|
+
distance: "65.1 mi",
|
|
71
|
+
address: "1929 East Main Street Greenfield, IN, United States",
|
|
72
|
+
phone: "3178490810",
|
|
73
|
+
website: "www.koenigfarmequipment.com",
|
|
74
|
+
detailsHref: "#",
|
|
75
|
+
directionsHref: "#",
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Contact02, default } from "./Contact02";
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import SafeImage from "../../atoms/SafeImage";
|
|
4
|
+
import {
|
|
5
|
+
contact03DefaultProps,
|
|
6
|
+
contact03PropTypes,
|
|
7
|
+
} from "./Contact03.propTypes";
|
|
8
|
+
|
|
9
|
+
function ArrowIcon({ className = "" }) {
|
|
10
|
+
return (
|
|
11
|
+
<svg viewBox="0 0 64 64" fill="none" aria-hidden="true" className={className}>
|
|
12
|
+
<path
|
|
13
|
+
d="M16 32h32M40 20l12 12-12 12"
|
|
14
|
+
stroke="currentColor"
|
|
15
|
+
strokeWidth="2"
|
|
16
|
+
strokeLinecap="round"
|
|
17
|
+
strokeLinejoin="round"
|
|
18
|
+
/>
|
|
19
|
+
</svg>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Contact03 — Editorial contact card on full-bleed background.
|
|
25
|
+
* Figma node 26:15837 at 1920px.
|
|
26
|
+
*
|
|
27
|
+
* @param {object} props - See Contact03.propTypes.js.
|
|
28
|
+
*/
|
|
29
|
+
export function Contact03({
|
|
30
|
+
headline = contact03DefaultProps.headline,
|
|
31
|
+
description = contact03DefaultProps.description,
|
|
32
|
+
cardPhoto = contact03DefaultProps.cardPhoto,
|
|
33
|
+
cardPhotoAlt = contact03DefaultProps.cardPhotoAlt,
|
|
34
|
+
backgroundImage = contact03DefaultProps.backgroundImage,
|
|
35
|
+
backgroundAlt = contact03DefaultProps.backgroundAlt,
|
|
36
|
+
href = contact03DefaultProps.href,
|
|
37
|
+
ctaAriaLabel = contact03DefaultProps.ctaAriaLabel,
|
|
38
|
+
className = "",
|
|
39
|
+
}) {
|
|
40
|
+
return (
|
|
41
|
+
<section
|
|
42
|
+
className={["relative w-full overflow-hidden", className].filter(Boolean).join(" ")}
|
|
43
|
+
data-contact="contact03"
|
|
44
|
+
>
|
|
45
|
+
<div className="relative mx-auto w-full max-w-[1920px] min-h-[70vh] md:min-h-[80vh] lg:min-h-[900px]">
|
|
46
|
+
<SafeImage
|
|
47
|
+
src={backgroundImage}
|
|
48
|
+
alt={backgroundAlt}
|
|
49
|
+
fill
|
|
50
|
+
className="object-cover object-center"
|
|
51
|
+
sizes="100vw"
|
|
52
|
+
priority
|
|
53
|
+
/>
|
|
54
|
+
|
|
55
|
+
<div className="relative z-10 flex min-h-[70vh] items-center justify-center px-4 py-16 sm:px-6 md:min-h-[80vh] md:px-10 lg:min-h-[900px] lg:px-20 xl:px-[160px]">
|
|
56
|
+
<div className="w-max max-w-[calc(100%-2rem)] bg-[#fffbf5] p-6 sm:p-8 md:p-10 lg:p-10">
|
|
57
|
+
<div className="flex flex-col items-end gap-8 md:gap-10 lg:gap-12">
|
|
58
|
+
<h2 className="w-full min-w-full text-4xl font-normal leading-none tracking-[-0.02em] text-[#141313] sm:text-5xl md:text-6xl lg:text-7xl xl:text-[96px] xl:leading-[96px] xl:tracking-[-1.92px]">
|
|
59
|
+
{headline}
|
|
60
|
+
</h2>
|
|
61
|
+
|
|
62
|
+
<div className="relative h-[200px] w-[150px] shrink-0 self-end sm:h-[240px] sm:w-[180px] md:h-[300px] md:w-[225px]">
|
|
63
|
+
<SafeImage
|
|
64
|
+
src={cardPhoto}
|
|
65
|
+
alt={cardPhotoAlt}
|
|
66
|
+
fill
|
|
67
|
+
className="object-cover object-center"
|
|
68
|
+
sizes="(max-width: 768px) 150px, 225px"
|
|
69
|
+
/>
|
|
70
|
+
</div>
|
|
71
|
+
|
|
72
|
+
<div className="flex w-full flex-col items-start gap-6 sm:flex-row sm:items-center sm:justify-between sm:gap-10 lg:gap-20">
|
|
73
|
+
<p className="max-w-md text-base leading-7 text-[rgba(20,19,19,0.7)] sm:text-lg md:text-xl md:leading-7">
|
|
74
|
+
{description}
|
|
75
|
+
</p>
|
|
76
|
+
<a
|
|
77
|
+
href={href}
|
|
78
|
+
aria-label={ctaAriaLabel}
|
|
79
|
+
className="flex size-12 shrink-0 items-center justify-center text-[#141313] transition-opacity duration-200 ease-out hover:opacity-80 focus-visible:outline-2 focus-visible:outline-offset-2 sm:size-14 md:size-16"
|
|
80
|
+
>
|
|
81
|
+
<ArrowIcon className="-rotate-90 size-full" />
|
|
82
|
+
</a>
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
</section>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
Contact03.propTypes = contact03PropTypes;
|
|
93
|
+
|
|
94
|
+
export default Contact03;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import PropTypes from "prop-types";
|
|
2
|
+
|
|
3
|
+
export const contact03PropTypes = {
|
|
4
|
+
headline: PropTypes.string,
|
|
5
|
+
description: PropTypes.string,
|
|
6
|
+
cardPhoto: PropTypes.string,
|
|
7
|
+
cardPhotoAlt: PropTypes.string,
|
|
8
|
+
backgroundImage: PropTypes.string,
|
|
9
|
+
backgroundAlt: PropTypes.string,
|
|
10
|
+
href: PropTypes.string,
|
|
11
|
+
ctaAriaLabel: PropTypes.string,
|
|
12
|
+
className: PropTypes.string,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const contact03DefaultProps = {
|
|
16
|
+
headline: "Contact",
|
|
17
|
+
description:
|
|
18
|
+
"Reach out to our team for information about our products, business operations, or partnership opportunities.",
|
|
19
|
+
cardPhoto: "/contact/contact03/card-photo.jpg",
|
|
20
|
+
cardPhotoAlt: "Team member working on a laptop",
|
|
21
|
+
backgroundImage: "/contact/contact03/bg.jpg",
|
|
22
|
+
backgroundAlt: "Industrial manufacturing background",
|
|
23
|
+
href: "#",
|
|
24
|
+
ctaAriaLabel: "Contact us",
|
|
25
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Contact03, default } from "./Contact03";
|