blocks-dusted 0.1.11 → 0.1.13

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 (161) hide show
  1. package/package.json +5 -2
  2. package/src/cli.js +39 -3
  3. package/src/commands/shop.js +59 -0
  4. package/src/commands/warehouse.js +73 -0
  5. package/src/installers/patchRenderBlocks.js +1 -1
  6. package/src/registry/validateTemplateManifest.js +2 -1
  7. package/templates/blocks/BannerDD790432/Component.tsx +63 -0
  8. package/templates/blocks/BannerDD790432/config.ts +54 -0
  9. package/templates/blocks/BannerDD790432/manifest.json +80 -0
  10. package/templates/blocks/Button47/Component.tsx +124 -0
  11. package/templates/blocks/Button47/config.ts +75 -0
  12. package/templates/blocks/Button47/link.ts +22 -0
  13. package/templates/blocks/Button47/manifest.json +105 -0
  14. package/templates/blocks/Button47/styles.module.scss +75 -0
  15. package/templates/blocks/DD-Accordion/Component.tsx +55 -36
  16. package/templates/blocks/DD-Accordion/config.ts +71 -59
  17. package/templates/blocks/DD-AnimText/Component.tsx +50 -32
  18. package/templates/blocks/DD-AnimText/config.ts +296 -295
  19. package/templates/blocks/DD-AsideNav/Component.tsx +323 -319
  20. package/templates/blocks/DD-Banner/Component.tsx +54 -51
  21. package/templates/blocks/DD-BookCall/Component.tsx +10 -9
  22. package/templates/blocks/DD-ButtonPop/Component.tsx +118 -117
  23. package/templates/blocks/DD-Card/Component.tsx +4 -4
  24. package/templates/blocks/DD-CardTemplate01/Component.tsx +5 -5
  25. package/templates/blocks/DD-CardsWithVariantV3/Component.tsx +472 -0
  26. package/templates/blocks/DD-CardsWithVariantV3/ElectricBorder/index.tsx +203 -0
  27. package/templates/blocks/DD-CardsWithVariantV3/ElectricBorder/styles.ts +87 -0
  28. package/templates/blocks/DD-CardsWithVariantV3/ElectricBorder/useInjectStyle.ts +39 -0
  29. package/templates/blocks/DD-CardsWithVariantV3/config.ts +326 -0
  30. package/templates/blocks/DD-CardsWithVariantV3/manifest.json +110 -0
  31. package/templates/blocks/DD-Carousel-A/Component.tsx +251 -249
  32. package/templates/blocks/DD-Carousel-B/Component.tsx +405 -403
  33. package/templates/blocks/DD-Chip/Component.tsx +14 -14
  34. package/templates/blocks/DD-ComparisonTable/Component.tsx +255 -256
  35. package/templates/blocks/DD-Contact/Component.tsx +433 -434
  36. package/templates/blocks/DD-Counter/Component.tsx +18 -13
  37. package/templates/blocks/DD-DeliCard/Component.tsx +303 -0
  38. package/templates/blocks/DD-DeliCard/config.ts +186 -0
  39. package/templates/blocks/DD-DeliCard/manifest.json +94 -0
  40. package/templates/blocks/DD-FeatCat/Component.tsx +302 -302
  41. package/templates/blocks/DD-FeatProd/CircularGallery.tsx +1179 -0
  42. package/templates/blocks/DD-FeatProd/Component.tsx +484 -0
  43. package/templates/blocks/DD-FeatProd/config.ts +173 -0
  44. package/templates/blocks/DD-FeatProd/manifest.json +93 -0
  45. package/templates/blocks/DD-FeatServ/Component.tsx +607 -0
  46. package/templates/blocks/DD-FeatServ/config.ts +213 -0
  47. package/templates/blocks/DD-FeatServ/manifest.json +113 -0
  48. package/templates/blocks/DD-FeatStrip/Component.tsx +584 -585
  49. package/templates/blocks/DD-FluidBtn/ButtonsEyeCatching.tsx +627 -628
  50. package/templates/blocks/DD-FluidBtn/Component.tsx +46 -43
  51. package/templates/blocks/DD-GooeyInfo/Component.tsx +150 -149
  52. package/templates/blocks/DD-GooeyInfo/config.ts +136 -135
  53. package/templates/blocks/DD-Hero/Component.tsx +16 -40
  54. package/templates/blocks/DD-HeroPlas/Component.tsx +50 -0
  55. package/templates/blocks/DD-HeroPlas/ThreeScene.tsx +109 -0
  56. package/templates/blocks/DD-HeroPlas/config.ts +33 -0
  57. package/templates/blocks/DD-HeroPlas/manifest.json +88 -0
  58. package/templates/blocks/DD-HorizontalScroll/Component.tsx +4 -5
  59. package/templates/blocks/DD-Icon/Component.tsx +46 -81
  60. package/templates/blocks/DD-IconButton/Component.tsx +13 -20
  61. package/templates/blocks/DD-IdTag/Component.tsx +22 -21
  62. package/templates/blocks/DD-IframeMedia/Component.tsx +14 -10
  63. package/templates/blocks/DD-LineAnim/Component.tsx +42 -36
  64. package/templates/blocks/DD-LogoMarq/Component.tsx +38 -48
  65. package/templates/blocks/DD-Lottie/Component.tsx +11 -3
  66. package/templates/blocks/DD-MasonaryMedia/Component.tsx +544 -547
  67. package/templates/blocks/DD-MasonaryMedia/config.ts +389 -389
  68. package/templates/blocks/DD-Masonry/Component.tsx +654 -644
  69. package/templates/blocks/DD-Masonry/config.ts +475 -475
  70. package/templates/blocks/DD-MaterialSwatches/Component.tsx +85 -0
  71. package/templates/blocks/DD-MaterialSwatches/config.ts +232 -0
  72. package/templates/blocks/DD-MaterialSwatches/manifest.json +84 -0
  73. package/templates/blocks/DD-MaterialSwatches/material.ts +107 -0
  74. package/templates/blocks/DD-NineCanvas/Component.tsx +129 -0
  75. package/templates/blocks/DD-NineCanvas/RenderBlocks.tsx +244 -0
  76. package/templates/blocks/DD-NineCanvas/allowedCanvasBlocks.ts +6 -0
  77. package/templates/blocks/DD-NineCanvas/blockComponents.tsx +8 -0
  78. package/templates/blocks/DD-NineCanvas/canvas/CanvasGrid.tsx +316 -0
  79. package/templates/blocks/DD-NineCanvas/canvas/RadialNav.tsx +432 -0
  80. package/templates/blocks/DD-NineCanvas/canvas/canvas-panels.css +889 -0
  81. package/templates/blocks/DD-NineCanvas/canvas/icons/custom-icons.tsx +364 -0
  82. package/templates/blocks/DD-NineCanvas/config.ts +61 -0
  83. package/templates/blocks/DD-NineCanvas/manifest.json +165 -0
  84. package/templates/blocks/DD-NineCanvas/styles.scss +152 -0
  85. package/templates/blocks/DD-NineCanvas/tooltip/get-strict-context.tsx +26 -0
  86. package/templates/blocks/DD-NineCanvas/tooltip/primitives.tsx +178 -0
  87. package/templates/blocks/DD-NineCanvas/tooltip/tooltip.tsx +71 -0
  88. package/templates/blocks/DD-NineCanvas/tooltip/use-controlled-state.tsx +33 -0
  89. package/templates/blocks/DD-NineCanvas/utilities/FadeOnScroll.tsx +68 -0
  90. package/templates/blocks/DD-NineCanvas/utilities/ParallaxWrapper.tsx +157 -0
  91. package/templates/blocks/DD-NineCanvas/utilities/renderCustomCSS.ts +5 -0
  92. package/templates/blocks/DD-NineCanvas/utilities/webglCleanup.ts +27 -0
  93. package/templates/blocks/DD-PayloadAIAssistant/Component.tsx +78 -0
  94. package/templates/blocks/DD-PayloadAIAssistant/DustedBot.tsx +590 -0
  95. package/templates/blocks/DD-PayloadAIAssistant/config.ts +37 -0
  96. package/templates/blocks/DD-PayloadAIAssistant/demo.css +125 -0
  97. package/templates/blocks/DD-PayloadAIAssistant/manifest.json +93 -0
  98. package/templates/blocks/DD-PayloadAIAssistant/source-defaults.ts +17 -0
  99. package/templates/blocks/DD-PayloadAIAssistant/styles.ts +306 -0
  100. package/templates/blocks/DD-Pricing/Component.tsx +368 -372
  101. package/templates/blocks/DD-Pricing/config.ts +215 -215
  102. package/templates/blocks/DD-Process/Component.tsx +147 -149
  103. package/templates/blocks/DD-Progress/Component.tsx +156 -141
  104. package/templates/blocks/DD-ProjHeader/Component.tsx +93 -91
  105. package/templates/blocks/DD-ProjSlider/Component.tsx +1 -1
  106. package/templates/blocks/DD-ProjSlider/config.ts +2 -2
  107. package/templates/blocks/DD-Section/Component.tsx +265 -266
  108. package/templates/blocks/DD-Separator/Component.tsx +66 -66
  109. package/templates/blocks/DD-Services/Component.tsx +176 -176
  110. package/templates/blocks/DD-ShowcaseGrid/Component.tsx +306 -307
  111. package/templates/blocks/DD-Slider-A/Component.tsx +237 -237
  112. package/templates/blocks/DD-StackCards/Component.tsx +474 -473
  113. package/templates/blocks/DD-Team/Component.tsx +247 -247
  114. package/templates/blocks/DD-TeamCards/Component.tsx +251 -251
  115. package/templates/blocks/DD-TechStack/Component.tsx +161 -168
  116. package/templates/blocks/DD-TestMarq/Component.tsx +158 -132
  117. package/templates/blocks/DD-Testim/Component.tsx +247 -247
  118. package/templates/blocks/DD-Testim2/Component.tsx +265 -256
  119. package/templates/blocks/DD-Testimonials/Component.tsx +139 -147
  120. package/templates/blocks/DD-TextMarq/Component.tsx +157 -157
  121. package/templates/blocks/DD-Thanks/Component.tsx +501 -500
  122. package/templates/blocks/DD-Work/Component.tsx +315 -315
  123. package/templates/blocks/DD-Work-B/Component.tsx +294 -294
  124. package/templates/blocks/DDHG-CTASection2/Component.tsx +183 -184
  125. package/templates/blocks/DDHG-HighlightArc/Component.tsx +246 -243
  126. package/templates/blocks/DDHG-LogoMarquee/Component.tsx +180 -93
  127. package/templates/blocks/DDHG-LogoMarquee/config.ts +154 -66
  128. package/templates/blocks/DDHG-NavCodeGrid/Component.tsx +225 -213
  129. package/templates/blocks/DDHG-ProcessSec/Component.tsx +38 -39
  130. package/templates/blocks/DDHG-ServiceDetails/Component.tsx +11 -11
  131. package/templates/blocks/DDHG-ServiceDetails/ServiceDetailCard.tsx +30 -47
  132. package/templates/blocks/DDHG-ServiceHero/Component.tsx +10 -10
  133. package/templates/blocks/DDHG-ServiceOverview/Component.tsx +23 -23
  134. package/templates/blocks/DDHG-StatsFAQ/Component.tsx +40 -40
  135. package/templates/blocks/DDHG-TeamCards/Component.tsx +140 -131
  136. package/templates/blocks/Form/Checkbox/index.tsx +45 -0
  137. package/templates/blocks/Form/Component.tsx +163 -0
  138. package/templates/blocks/Form/Country/index.tsx +65 -0
  139. package/templates/blocks/Form/Country/options.ts +982 -0
  140. package/templates/blocks/Form/Email/index.tsx +38 -0
  141. package/templates/blocks/Form/Error/index.tsx +15 -0
  142. package/templates/blocks/Form/Message/index.tsx +13 -0
  143. package/templates/blocks/Form/Number/index.tsx +36 -0
  144. package/templates/blocks/Form/Select/index.tsx +63 -0
  145. package/templates/blocks/Form/State/index.tsx +64 -0
  146. package/templates/blocks/Form/State/options.ts +52 -0
  147. package/templates/blocks/Form/Text/index.tsx +32 -0
  148. package/templates/blocks/Form/Textarea/index.tsx +40 -0
  149. package/templates/blocks/Form/Width/index.tsx +13 -0
  150. package/templates/blocks/Form/config.ts +51 -0
  151. package/templates/blocks/Form/fields.tsx +21 -0
  152. package/templates/blocks/Form/manifest.json +168 -0
  153. package/templates/blocks/MediaBlock/Component.tsx +67 -0
  154. package/templates/blocks/MediaBlock/config.ts +14 -0
  155. package/templates/blocks/MediaBlock/manifest.json +92 -0
  156. package/templates/blocks/TransitionsDustedShowcase/Component.tsx +9 -0
  157. package/templates/blocks/TransitionsDustedShowcase/config.ts +13 -0
  158. package/templates/blocks/TransitionsDustedShowcase/manifest.json +80 -0
  159. package/templates/blocks/rawHtml/Component.tsx +25 -0
  160. package/templates/blocks/rawHtml/config.ts +56 -0
  161. package/templates/blocks/rawHtml/manifest.json +80 -0
@@ -1,256 +1,265 @@
1
- 'use client'
2
-
3
- import React, { useRef } from 'react'
4
- import { Swiper, SwiperSlide } from 'swiper/react'
5
- import { Navigation } from 'swiper/modules'
6
- import type { Swiper as SwiperInstance } from 'swiper'
7
- import { cn } from '@/utilities/ui'
8
- import { Media } from '@/components/Media'
9
- import RichText from '@/components/RichText'
10
- import type { Testimonial } from '@/payload-types'
11
- import 'swiper/css'
12
- import 'swiper/css/navigation'
13
-
14
- export interface Testimonial2BlockProps {
15
- awardsTitle?: string
16
- testimonialsTitle?: string
17
- features?: Array<{
18
- title: string
19
- company?: string
20
- year?: string
21
- category?: string
22
- link?: string
23
- id?: string
24
- }>
25
- testimonials?: Array<Testimonial | string | number>
26
- containerClass?: string
27
- }
28
-
29
- export const DDTestim2: React.FC<Testimonial2BlockProps> = ({
30
- awardsTitle = '',
31
- testimonialsTitle = '',
32
- features = [],
33
- testimonials = [],
34
- containerClass = ''
35
- }) => {
36
- // Filter and type-guard testimonials
37
- const validTestimonials = testimonials?.filter(
38
- (t): t is Testimonial => typeof t === 'object' && t !== null
39
- )
40
-
41
- const prevButtonRef = useRef(null)
42
- const nextButtonRef = useRef(null)
43
- const swiperRef = useRef<SwiperInstance | null>(null)
44
-
45
- const swiperOptions = {
46
- spaceBetween: 30,
47
- slidesPerView: 1,
48
- loop: true,
49
- modules: [Navigation],
50
- navigation: {
51
- prevEl: '.custom-swiper-button-prev',
52
- nextEl: '.custom-swiper-button-next'
53
- },
54
- onSwiper: (swiper: SwiperInstance) => {
55
- swiperRef.current = swiper
56
- }
57
- }
58
-
59
- return (
60
- <section
61
- className={cn(
62
- 'half-block sub-bg max-w-none mx-0 md:mx-auto prose md:prose-md dark:prose-invert m-0 p-[15px]',
63
- containerClass
64
- )}
65
- id="testimonial2-block"
66
- >
67
- <div className="w-full max-w-[1500px] mx-auto px-4">
68
- <div className="w-full flex flex-wrap lg:flex-nowrap px-0">
69
- {/* Awards Section */}
70
- {features && features.length > 0 && (
71
- <div className="w-full lg:w-1/2 pt-10 pb-10 pl-10 md:pt-[30px] md:pb-[30px] md:pl-5">
72
- <div className="mr-0 md:mr-5">
73
- <div className="mb-20">
74
- <h3 className="uppercase tracking-[1px]">{awardsTitle}</h3>
75
- </div>
76
- <div className="flex flex-wrap -mx-[15px] py-[25px] px-[15px] border-b border-white/50">
77
- <div className="w-full md:w-[58.333333%] px-[15px]">
78
- <div className="p-0">
79
- <h6 className="text-sm uppercase tracking-[2px]">Featured Projects</h6>
80
- </div>
81
- </div>
82
- <div className="w-full md:w-[25%] px-[15px]">
83
- <div className="p-0">
84
- <h6 className="text-sm uppercase tracking-[2px]">Category</h6>
85
- </div>
86
- </div>
87
- </div>
88
-
89
- {features.map((feature, index) => (
90
- <div
91
- key={feature.id || index}
92
- className="group flex flex-wrap -mx-[15px] py-[25px] px-[15px] border-b border-white/[0.08] relative transition-all duration-400 z-[3] hover:after:h-full after:content-[''] after:absolute after:bottom-0 after:left-0 after:w-full after:h-0 after:bg-[#fdfdfd29] after:transition-all after:duration-400 after:z-[-1]"
93
- >
94
- <div className="w-full md:w-[58.333333%] px-[15px]">
95
- <div className="p-0 flex justify-start">
96
- <h6 className="text-stone-200 dark:text-stone-200 transition-all duration-400 dark:group-hover:text-white light:group-hover:text-[#0c0c0c]">
97
- {feature.title}
98
- {feature.title.length < 25 && <br />}
99
- <span className="text-sm opacity-70 ml-[15px]">
100
- {feature.company} <span>{feature.year}</span>
101
- </span>
102
- </h6>
103
- </div>
104
- </div>
105
- <div className="w-full flex md:w-[25%] px-[15px]">
106
- <div className="p-0 flex justify-end mr-1 scale-90 origin-right">
107
- <h6 className="text-stone-200 dark:text-stone-200 transition-all duration-400">
108
- {feature.category}
109
- </h6>
110
- <a href={feature.link} className="ml-2 mt-2 inline-block scale-110">
111
- <svg
112
- width="18"
113
- height="18"
114
- viewBox="0 0 18 18"
115
- fill="none"
116
- xmlns="http://www.w3.org/2000/svg"
117
- className="transition-transform duration-300 ease-in-out group-hover:translate-x-[3px] group-hover:-translate-y-[3px]"
118
- >
119
- <path
120
- d="M13.922 4.5V11.8125C13.922 11.9244 13.8776 12.0317 13.7985 12.1108C13.7193 12.1899 13.612 12.2344 13.5002 12.2344C13.3883 12.2344 13.281 12.1899 13.2018 12.1108C13.1227 12.0317 13.0783 11.9244 13.0783 11.8125V5.51953L4.79547 13.7953C4.71715 13.8736 4.61092 13.9176 4.50015 13.9176C4.38939 13.9176 4.28316 13.8736 4.20484 13.7953C4.12652 13.717 4.08252 13.6108 4.08252 13.5C4.08252 13.3892 4.12652 13.283 4.20484 13.2047L12.4806 4.92188H6.18765C6.07577 4.92188 5.96846 4.87743 5.88934 4.79831C5.81023 4.71919 5.76578 4.61189 5.76578 4.5C5.76578 4.38811 5.81023 4.28081 5.88934 4.20169C5.96846 4.12257 6.07577 4.07813 6.18765 4.07812H13.5002C13.612 4.07813 13.7193 4.12257 13.7985 4.20169C13.8776 4.28081 13.922 4.38811 13.922 4.5Z"
121
- fill="currentColor"
122
- ></path>
123
- </svg>
124
- </a>
125
- </div>
126
- </div>
127
- {/* <div className="w-full md:w-[16.666667%] px-[15px]"></div> */}
128
- </div>
129
- ))}
130
- </div>
131
- </div>
132
- )}
133
-
134
- {/* Testimonials Section */}
135
- {validTestimonials && validTestimonials.length > 0 && (
136
- <div className="w-full lg:w-1/2 pr-0 mr-0">
137
- <div className="testim-crev">
138
- <div className="p-4 my-4">
139
- <h3 className="uppercase tracking-[1px]">{testimonialsTitle}</h3>
140
- </div>
141
- <div className="testim-swiper bg-lines pb-16 px-0 -ml-1 rounded-3xl">
142
- <Swiper
143
- id="content-carousel-container-unq-testim"
144
- className="swiper-container"
145
- {...swiperOptions}
146
- >
147
- {validTestimonials.map((testimonial, index) => (
148
- <SwiperSlide
149
- key={testimonial.id || index}
150
- style={{ left: '20px', marginRight: '50px' }}
151
- >
152
- <div className="container item sub-background border-t border-l border-b mb-4 -ml-4 pt-12 pb-10 px-10 rounded-[40px_0px_0px_40px] relative md:pt-[30px] md:pb-0 md:px-5">
153
- <div className="w-full">
154
- <div className="flex items-center">
155
- <div className="ml-auto">
156
- <svg
157
- xmlns="http://www.w3.org/2000/svg"
158
- width="256.721"
159
- height="208.227"
160
- viewBox="0 0 256.721 208.227"
161
- className="w-[100px] h-20 mb-10 scale-[4] opacity-10 mr-44 md:w-[110px] md:h-[110px] md:pt-4 md:-mb-16"
162
- >
163
- <path
164
- d="M-23.723-530.169v97.327H-121.05v-68.7q0-40.076,13.359-73.472T-62.845-639.9l36.259,28.625Q-63.8-570.244-68.57-530.169Zm158.395,0v97.327H37.345v-68.7q0-40.076,13.359-73.472T95.55-639.9l36.259,28.625Q94.6-570.244,89.825-530.169Z"
165
- transform="translate(121.55 640.568)"
166
- fill="none"
167
- stroke="#fff"
168
- strokeWidth="1"
169
- opacity="0.322"
170
- ></path>
171
- </svg>
172
- </div>
173
- </div>
174
- <div className="text">
175
- {testimonial.content && (
176
- <RichText
177
- data={testimonial.content}
178
- enableGutter={false}
179
- className=" text-stone-200 dark:text-stone-200"
180
- />
181
- )}
182
- </div>
183
- <div className="flex items-center mt-10 md:-ml-5">
184
- <div className="relative p-5 rounded-[0_30px_0_0] w-20 h-20 overflow-hidden md:mb-0 md:p-0 md:flex md:w-auto">
185
- <div className="w-full h-full rounded-full overflow-hidden invert-[0.8] dark:invert-[0] object-cover">
186
- {testimonial.companyLogo &&
187
- typeof testimonial.companyLogo === 'object' ? (
188
- <Media
189
- resource={testimonial.companyLogo}
190
- imgClassName="object-cover"
191
- />
192
- ) : (
193
- <svg
194
- className="w-full h-full opacity-20"
195
- viewBox="0 0 24 24"
196
- fill="none"
197
- xmlns="http://www.w3.org/2000/svg"
198
- >
199
- <path
200
- d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z"
201
- fill="currentColor"
202
- />
203
- </svg>
204
- )}
205
- </div>
206
- </div>
207
- <div className="text-left ml-[30px] md:ml-0 md:mt-0 md:max-w-[55vw]">
208
- {testimonial.clientName && (
209
- <RichText
210
- data={testimonial.clientName}
211
- enableGutter={false}
212
- className=" text-stone-200 dark:text-stone-200"
213
- />
214
- )}
215
- {testimonial.company && (
216
- <div
217
- className="text-alt scale-95 origin-top-left opacity-100"
218
- style={{ maxWidth: '280px', marginTop: '-8px' }}
219
- >
220
- <RichText
221
- data={testimonial.company}
222
- enableGutter={false}
223
- className="text-sm"
224
- />
225
- </div>
226
- )}
227
- </div>
228
- </div>
229
- </div>
230
- </div>
231
- </SwiperSlide>
232
- ))}
233
- </Swiper>
234
-
235
- {/* Navigation Buttons */}
236
- <div className="flex gap-12 justify-start mt-8 ml-8">
237
- <div
238
- ref={prevButtonRef}
239
- className="swiper-button-prev custom-swiper-button-prev relative w-[20px] h-[20px] rounded-full flex items-center justify-center cursor-pointer transition-all duration-300 bg-transparent hover:border-white/50 hover:bg-white/5 disabled:opacity-30 disabled:cursor-not-allowed"
240
- ></div>
241
- <div
242
- ref={nextButtonRef}
243
- className="swiper-button-next custom-swiper-button-next relative w-[20px] h-[20px] rounded-full flex items-center justify-center cursor-pointer transition-all duration-300 bg-transparent hover:border-white/50 hover:bg-white/5 disabled:opacity-30 disabled:cursor-not-allowed"
244
- ></div>
245
- </div>
246
- </div>
247
- </div>
248
- </div>
249
- )}
250
- </div>
251
- </div>
252
- </section>
253
- )
254
- }
255
-
256
- export default DDTestim2
1
+ 'use client'
2
+
3
+ import React, { useRef } from 'react'
4
+ import { Swiper, SwiperSlide } from 'swiper/react'
5
+ import { Navigation } from 'swiper/modules'
6
+ import type { Swiper as SwiperInstance } from 'swiper'
7
+ import { cn } from '@/utilities/ui'
8
+ import { Media } from '@/components/Media'
9
+ import RichText from '@/components/RichText'
10
+ import type { Testimonial } from '@/payload-types'
11
+ import 'swiper/css'
12
+ import 'swiper/css/navigation'
13
+
14
+ export interface Testimonial2BlockProps {
15
+ awardsTitle?: string
16
+ testimonialsTitle?: string
17
+ features?: Array<{
18
+ title: string
19
+ company?: string
20
+ year?: string
21
+ category?: string
22
+ link?: string
23
+ id?: string
24
+ }>
25
+ testimonials?: Array<Testimonial | string | number>
26
+ containerClass?: string
27
+ }
28
+
29
+ export const DDTestim2: React.FC<Testimonial2BlockProps> = ({
30
+ awardsTitle = '',
31
+ testimonialsTitle = '',
32
+ features = [],
33
+ testimonials = [],
34
+ containerClass = '',
35
+ }) => {
36
+ // Filter and type-guard testimonials
37
+ const validTestimonials = testimonials?.filter(
38
+ (t): t is Testimonial => typeof t === 'object' && t !== null,
39
+ )
40
+
41
+ const prevButtonRef = useRef(null)
42
+ const nextButtonRef = useRef(null)
43
+ const swiperRef = useRef<SwiperInstance | null>(null)
44
+
45
+ const swiperOptions = {
46
+ spaceBetween: 30,
47
+ slidesPerView: 1,
48
+ loop: true,
49
+ modules: [Navigation],
50
+ navigation: {
51
+ prevEl: '.custom-swiper-button-prev',
52
+ nextEl: '.custom-swiper-button-next',
53
+ },
54
+ onSwiper: (swiper: SwiperInstance) => {
55
+ swiperRef.current = swiper
56
+ },
57
+ }
58
+
59
+ return (
60
+ <section
61
+ className={cn(
62
+ 'half-block sub-bg relative w-screen max-w-none prose md:prose-md dark:prose-invert m-0 p-[15px]',
63
+ containerClass,
64
+ )}
65
+ id="testimonial2-block"
66
+ style={{ left: '50%', marginLeft: '-50vw', width: '100vw', maxWidth: 'none' }}
67
+ >
68
+ <div className="w-full max-w-none px-0">
69
+ <div className="w-full flex flex-wrap lg:flex-nowrap px-0">
70
+ {/* Awards Section */}
71
+ {features && features.length > 0 && (
72
+ <div className="w-full lg:w-1/2 pt-10 pb-10 pl-10 md:pt-[30px] md:pb-[30px] md:pl-5">
73
+ <div className="mr-0 md:mr-5">
74
+ <div className="mb-20">
75
+ <h3 className="uppercase tracking-[1px] text-stone-900 dark:text-stone-100">
76
+ {awardsTitle}
77
+ </h3>
78
+ </div>
79
+ <div className="flex flex-wrap -mx-[15px] py-[25px] px-[15px] border-b border-stone-300 dark:border-white/20">
80
+ <div className="w-full md:w-[58.333333%] px-[15px]">
81
+ <div className="p-0">
82
+ <h6 className="text-sm uppercase tracking-[2px] text-stone-900 dark:text-stone-100">
83
+ Featured Projects
84
+ </h6>
85
+ </div>
86
+ </div>
87
+ <div className="w-full md:w-[25%] px-[15px]">
88
+ <div className="p-0">
89
+ <h6 className="text-sm uppercase tracking-[2px] text-stone-900 dark:text-stone-100">
90
+ Category
91
+ </h6>
92
+ </div>
93
+ </div>
94
+ </div>
95
+
96
+ {features.map((feature, index) => (
97
+ <div
98
+ key={feature.id || index}
99
+ className="group flex flex-wrap -mx-[15px] py-[25px] px-[15px] border-b border-stone-300 dark:border-white/10 relative transition-all duration-400 z-[3] hover:after:h-full after:content-[''] after:absolute after:bottom-0 after:left-0 after:w-full after:h-0 after:bg-[#fdfdfd29] after:transition-all after:duration-400 after:z-[-1]"
100
+ >
101
+ <div className="w-full md:w-[58.333333%] px-[15px]">
102
+ <div className="p-0 flex justify-start">
103
+ <h6 className="text-stone-800 transition-all duration-400 group-hover:!text-stone-950 dark:text-stone-200 dark:group-hover:!text-white">
104
+ {feature.title}
105
+ {feature.title.length < 25 && <br />}
106
+ <span className="text-sm opacity-70 ml-[15px]">
107
+ {feature.company} <span>{feature.year}</span>
108
+ </span>
109
+ </h6>
110
+ </div>
111
+ </div>
112
+ <div className="w-full flex md:w-[25%] px-[15px]">
113
+ <div className="p-0 flex justify-end mr-1 scale-90 origin-right">
114
+ <h6 className="text-stone-800 transition-all duration-400 group-hover:!text-stone-950 dark:text-stone-200 dark:group-hover:!text-white">
115
+ {feature.category}
116
+ </h6>
117
+ <a href={feature.link} className="ml-2 mt-2 inline-block scale-110">
118
+ <svg
119
+ width="18"
120
+ height="18"
121
+ viewBox="0 0 18 18"
122
+ fill="none"
123
+ xmlns="http://www.w3.org/2000/svg"
124
+ className="transition-transform duration-300 ease-in-out group-hover:translate-x-[3px] group-hover:-translate-y-[3px]"
125
+ >
126
+ <path
127
+ d="M13.922 4.5V11.8125C13.922 11.9244 13.8776 12.0317 13.7985 12.1108C13.7193 12.1899 13.612 12.2344 13.5002 12.2344C13.3883 12.2344 13.281 12.1899 13.2018 12.1108C13.1227 12.0317 13.0783 11.9244 13.0783 11.8125V5.51953L4.79547 13.7953C4.71715 13.8736 4.61092 13.9176 4.50015 13.9176C4.38939 13.9176 4.28316 13.8736 4.20484 13.7953C4.12652 13.717 4.08252 13.6108 4.08252 13.5C4.08252 13.3892 4.12652 13.283 4.20484 13.2047L12.4806 4.92188H6.18765C6.07577 4.92188 5.96846 4.87743 5.88934 4.79831C5.81023 4.71919 5.76578 4.61189 5.76578 4.5C5.76578 4.38811 5.81023 4.28081 5.88934 4.20169C5.96846 4.12257 6.07577 4.07813 6.18765 4.07812H13.5002C13.612 4.07813 13.7193 4.12257 13.7985 4.20169C13.8776 4.28081 13.922 4.38811 13.922 4.5Z"
128
+ fill="currentColor"
129
+ ></path>
130
+ </svg>
131
+ </a>
132
+ </div>
133
+ </div>
134
+ {/* <div className="w-full md:w-[16.666667%] px-[15px]"></div> */}
135
+ </div>
136
+ ))}
137
+ </div>
138
+ </div>
139
+ )}
140
+
141
+ {/* Testimonials Section */}
142
+ {validTestimonials && validTestimonials.length > 0 && (
143
+ <div className="w-full lg:w-1/2 pr-0 mr-0">
144
+ <div className="testim-crev">
145
+ <div className="p-4 my-4">
146
+ <h3 className="uppercase tracking-[1px] text-stone-900 dark:text-stone-100">
147
+ {testimonialsTitle}
148
+ </h3>
149
+ </div>
150
+ <div className="testim-swiper bg-lines px-0 -ml-1 rounded-3xl">
151
+ <Swiper
152
+ id="content-carousel-container-unq-testim"
153
+ className="swiper-container"
154
+ {...swiperOptions}
155
+ >
156
+ {validTestimonials.map((testimonial, index) => (
157
+ <SwiperSlide
158
+ key={testimonial.id || index}
159
+ style={{ left: '20px', marginRight: '50px' }}
160
+ >
161
+ <div className="container item sub-background border-t border-l border-b border-stone-300 hover:border-stone-400 dark:border-stone-700 dark:hover:border-stone-600 mb-4 -ml-4 pt-12 pb-10 pl-10 !pr-0 shadow-lg rounded-[40px_0px_0px_40px] relative md:pt-[30px] md:pb-0 md:pl-5 md:!pr-0">
162
+ <div className="w-full">
163
+ <div className="flex items-center">
164
+ <div className="ml-auto">
165
+ <svg
166
+ xmlns="http://www.w3.org/2000/svg"
167
+ width="256.721"
168
+ height="208.227"
169
+ viewBox="0 0 256.721 208.227"
170
+ className="w-[100px] h-20 mb-10 scale-[4] opacity-10 mr-44 md:w-[110px] md:h-[110px] md:pt-4 md:-mb-16"
171
+ >
172
+ <path
173
+ d="M-23.723-530.169v97.327H-121.05v-68.7q0-40.076,13.359-73.472T-62.845-639.9l36.259,28.625Q-63.8-570.244-68.57-530.169Zm158.395,0v97.327H37.345v-68.7q0-40.076,13.359-73.472T95.55-639.9l36.259,28.625Q94.6-570.244,89.825-530.169Z"
174
+ transform="translate(121.55 640.568)"
175
+ fill="none"
176
+ stroke="#fff"
177
+ strokeWidth="1"
178
+ opacity="0.322"
179
+ ></path>
180
+ </svg>
181
+ </div>
182
+ </div>
183
+ <div className="text">
184
+ {testimonial.content && (
185
+ <RichText
186
+ data={testimonial.content}
187
+ enableGutter={false}
188
+ className="!text-stone-900 [&_.payload-richtext]:!text-stone-900 [&_.payload-richtext_*]:!text-stone-900 dark:!text-stone-100 dark:[&_.payload-richtext]:!text-stone-100 dark:[&_.payload-richtext_*]:!text-stone-100"
189
+ />
190
+ )}
191
+ </div>
192
+ <div className="flex items-center mt-10 md:-ml-5">
193
+ <div className="relative p-5 rounded-[0_30px_0_0] w-20 h-20 overflow-hidden md:mb-0 md:p-0 md:flex md:w-auto">
194
+ <div className="w-full h-full rounded-full overflow-hidden invert-[0.8] dark:invert-[0] object-cover">
195
+ {testimonial.companyLogo &&
196
+ typeof testimonial.companyLogo === 'object' ? (
197
+ <Media
198
+ resource={testimonial.companyLogo}
199
+ imgClassName="object-cover"
200
+ />
201
+ ) : (
202
+ <svg
203
+ className="w-full h-full opacity-20"
204
+ viewBox="0 0 24 24"
205
+ fill="none"
206
+ xmlns="http://www.w3.org/2000/svg"
207
+ >
208
+ <path
209
+ d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z"
210
+ fill="currentColor"
211
+ />
212
+ </svg>
213
+ )}
214
+ </div>
215
+ </div>
216
+ <div className="text-left ml-[30px] md:ml-0 md:mt-0 md:max-w-[55vw0] gap-4">
217
+ {testimonial.clientName && (
218
+ <RichText
219
+ data={testimonial.clientName}
220
+ enableGutter={false}
221
+ className="!text-stone-900 [&_.payload-richtext]:!text-stone-900 [&_.payload-richtext_*]:!text-stone-900 dark:!text-stone-100 dark:[&_.payload-richtext]:!text-stone-100 dark:[&_.payload-richtext_*]:!text-stone-100"
222
+ />
223
+ )}
224
+ {testimonial.company && (
225
+ <div
226
+ className="text-alt scale-95 origin-top-left opacity-100 pt-2"
227
+ style={{ maxWidth: '280px', marginTop: '-8px' }}
228
+ >
229
+ <RichText
230
+ data={testimonial.company}
231
+ enableGutter={false}
232
+ className="text-sm !text-stone-900 [&_.payload-richtext]:!text-stone-900 [&_.payload-richtext_*]:!text-stone-900 dark:!text-stone-100 dark:[&_.payload-richtext]:!text-stone-100 dark:[&_.payload-richtext_*]:!text-stone-100"
233
+ />
234
+ </div>
235
+ )}
236
+ </div>
237
+ </div>
238
+ </div>
239
+ </div>
240
+ </SwiperSlide>
241
+ ))}
242
+ </Swiper>
243
+
244
+ {/* Navigation Buttons */}
245
+ <div className="pointer-events-none flex min-h-14 items-center justify-between px-4 py-3">
246
+ <div
247
+ ref={prevButtonRef}
248
+ className="swiper-button-prev custom-swiper-button-prev pointer-events-auto !relative !inset-auto !m-0 !h-5 !w-5 rounded-full flex items-center justify-center cursor-pointer transition-all duration-300 bg-transparent hover:border-white/50 hover:bg-white/5 disabled:opacity-30 disabled:cursor-not-allowed after:!text-[8px]"
249
+ ></div>
250
+ <div
251
+ ref={nextButtonRef}
252
+ className="swiper-button-next custom-swiper-button-next pointer-events-auto !relative !inset-auto !m-0 !h-5 !w-5 rounded-full flex items-center justify-center cursor-pointer transition-all duration-300 bg-transparent hover:border-white/50 hover:bg-white/5 disabled:opacity-30 disabled:cursor-not-allowed after:!text-[8px]"
253
+ ></div>
254
+ </div>
255
+ </div>
256
+ </div>
257
+ </div>
258
+ )}
259
+ </div>
260
+ </div>
261
+ </section>
262
+ )
263
+ }
264
+
265
+ export default DDTestim2