@notionhive/testimonials 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 (139) hide show
  1. package/bin/testimonials.js +16 -0
  2. package/category.config.json +7 -0
  3. package/package.json +24 -0
  4. package/registry/index.json +174 -0
  5. package/registry/testimonial-01.json +10 -0
  6. package/registry/testimonial-02.json +10 -0
  7. package/registry/testimonial-03.json +10 -0
  8. package/registry/testimonial-04.json +10 -0
  9. package/registry/testimonial-05.json +9 -0
  10. package/registry/testimonial-06.json +10 -0
  11. package/registry/testimonial-07.json +10 -0
  12. package/registry/testimonial-08.json +10 -0
  13. package/registry/testimonial-09.json +10 -0
  14. package/registry/testimonial-10.json +10 -0
  15. package/registry/testimonial-11.json +10 -0
  16. package/registry/testimonial-12.json +10 -0
  17. package/registry/testimonial-13.json +10 -0
  18. package/registry/testimonial-14.json +9 -0
  19. package/registry/testimonial-15.json +10 -0
  20. package/registry/testimonial-16.json +10 -0
  21. package/registry/testimonial-17.json +10 -0
  22. package/templates/components/atoms/SafeImage/SafeImage.jsx +101 -0
  23. package/templates/components/atoms/SafeImage/index.js +1 -0
  24. package/templates/components/hooks/useCarousel.js +73 -0
  25. package/templates/components/organisms/Testimonial01/Testimonial01.jsx +171 -0
  26. package/templates/components/organisms/Testimonial01/Testimonial01.propTypes.js +82 -0
  27. package/templates/components/organisms/Testimonial01/index.js +1 -0
  28. package/templates/components/organisms/Testimonial02/Testimonial02.jsx +200 -0
  29. package/templates/components/organisms/Testimonial02/Testimonial02.propTypes.js +75 -0
  30. package/templates/components/organisms/Testimonial02/index.js +1 -0
  31. package/templates/components/organisms/Testimonial03/Testimonial03.jsx +208 -0
  32. package/templates/components/organisms/Testimonial03/Testimonial03.propTypes.js +90 -0
  33. package/templates/components/organisms/Testimonial03/index.js +1 -0
  34. package/templates/components/organisms/Testimonial04/Testimonial04.jsx +242 -0
  35. package/templates/components/organisms/Testimonial04/Testimonial04.propTypes.js +81 -0
  36. package/templates/components/organisms/Testimonial04/index.js +1 -0
  37. package/templates/components/organisms/Testimonial05/Testimonial05.jsx +88 -0
  38. package/templates/components/organisms/Testimonial05/Testimonial05.propTypes.js +29 -0
  39. package/templates/components/organisms/Testimonial05/index.js +1 -0
  40. package/templates/components/organisms/Testimonial06/Testimonial06.jsx +203 -0
  41. package/templates/components/organisms/Testimonial06/Testimonial06.propTypes.js +106 -0
  42. package/templates/components/organisms/Testimonial06/index.js +1 -0
  43. package/templates/components/organisms/Testimonial07/Testimonial07.jsx +245 -0
  44. package/templates/components/organisms/Testimonial07/Testimonial07.propTypes.js +80 -0
  45. package/templates/components/organisms/Testimonial07/index.js +1 -0
  46. package/templates/components/organisms/Testimonial08/Testimonial08.jsx +188 -0
  47. package/templates/components/organisms/Testimonial08/Testimonial08.propTypes.js +69 -0
  48. package/templates/components/organisms/Testimonial08/index.js +1 -0
  49. package/templates/components/organisms/Testimonial09/Testimonial09.jsx +214 -0
  50. package/templates/components/organisms/Testimonial09/Testimonial09.propTypes.js +105 -0
  51. package/templates/components/organisms/Testimonial09/index.js +1 -0
  52. package/templates/components/organisms/Testimonial10/Testimonial10.jsx +218 -0
  53. package/templates/components/organisms/Testimonial10/Testimonial10.propTypes.js +65 -0
  54. package/templates/components/organisms/Testimonial10/index.js +1 -0
  55. package/templates/components/organisms/Testimonial11/Testimonial11.jsx +242 -0
  56. package/templates/components/organisms/Testimonial11/Testimonial11.propTypes.js +73 -0
  57. package/templates/components/organisms/Testimonial11/index.js +1 -0
  58. package/templates/components/organisms/Testimonial12/Testimonial12.jsx +271 -0
  59. package/templates/components/organisms/Testimonial12/Testimonial12.propTypes.js +81 -0
  60. package/templates/components/organisms/Testimonial12/index.js +1 -0
  61. package/templates/components/organisms/Testimonial13/Testimonial13.jsx +206 -0
  62. package/templates/components/organisms/Testimonial13/Testimonial13.propTypes.js +87 -0
  63. package/templates/components/organisms/Testimonial13/index.js +1 -0
  64. package/templates/components/organisms/Testimonial14/Testimonial14.jsx +89 -0
  65. package/templates/components/organisms/Testimonial14/Testimonial14.propTypes.js +87 -0
  66. package/templates/components/organisms/Testimonial14/index.js +1 -0
  67. package/templates/components/organisms/Testimonial15/Testimonial15.jsx +201 -0
  68. package/templates/components/organisms/Testimonial15/Testimonial15.propTypes.js +89 -0
  69. package/templates/components/organisms/Testimonial15/index.js +1 -0
  70. package/templates/components/organisms/Testimonial16/Testimonial16.jsx +193 -0
  71. package/templates/components/organisms/Testimonial16/Testimonial16.propTypes.js +90 -0
  72. package/templates/components/organisms/Testimonial16/index.js +1 -0
  73. package/templates/components/organisms/Testimonial17/Testimonial17.jsx +236 -0
  74. package/templates/components/organisms/Testimonial17/Testimonial17.propTypes.js +98 -0
  75. package/templates/components/organisms/Testimonial17/index.js +1 -0
  76. package/templates/public/testimonials/testimonial01/avatar-marcus.jpg +0 -0
  77. package/templates/public/testimonials/testimonial01/avatar-wilma.jpg +0 -0
  78. package/templates/public/testimonials/testimonial01/company-logo-2.png +0 -0
  79. package/templates/public/testimonials/testimonial01/company-logo-icon-raw.png +0 -0
  80. package/templates/public/testimonials/testimonial01/company-logo-icon.png +0 -0
  81. package/templates/public/testimonials/testimonial01/desco-logo-export.png +0 -0
  82. package/templates/public/testimonials/testimonial01/desco-logo-raw1.png +0 -0
  83. package/templates/public/testimonials/testimonial01/desco-logo-raw2.png +0 -0
  84. package/templates/public/testimonials/testimonial01/desco-logo.png +0 -0
  85. package/templates/public/testimonials/testimonial02/avatar-julia.jpg +0 -0
  86. package/templates/public/testimonials/testimonial02/avatar-marie.jpg +0 -0
  87. package/templates/public/testimonials/testimonial02/avatar-mark.jpg +0 -0
  88. package/templates/public/testimonials/testimonial02/bg-gradient.png +0 -0
  89. package/templates/public/testimonials/testimonial03/avatar-david.jpg +0 -0
  90. package/templates/public/testimonials/testimonial03/globe-bg.png +0 -0
  91. package/templates/public/testimonials/testimonial04/avatar-carlos.jpg +0 -0
  92. package/templates/public/testimonials/testimonial04/avatar-john.jpg +0 -0
  93. package/templates/public/testimonials/testimonial04/avatar-sabbir.jpg +0 -0
  94. package/templates/public/testimonials/testimonial05/portrait.jpg +0 -0
  95. package/templates/public/testimonials/testimonial06/avatar-ahmed.jpg +0 -0
  96. package/templates/public/testimonials/testimonial06/avatar-danzel.jpg +0 -0
  97. package/templates/public/testimonials/testimonial06/avatar-lisa.jpg +0 -0
  98. package/templates/public/testimonials/testimonial06/avatar-maria.jpg +0 -0
  99. package/templates/public/testimonials/testimonial06/avatar-sarah.jpg +0 -0
  100. package/templates/public/testimonials/testimonial07/photo-2.jpg +0 -0
  101. package/templates/public/testimonials/testimonial07/photo-3.jpg +0 -0
  102. package/templates/public/testimonials/testimonial07/photo-alt.png +0 -0
  103. package/templates/public/testimonials/testimonial07/photo.jpg +0 -0
  104. package/templates/public/testimonials/testimonial07/slide-2.png +0 -0
  105. package/templates/public/testimonials/testimonial08/student-1.jpg +0 -0
  106. package/templates/public/testimonials/testimonial08/student-2.jpg +0 -0
  107. package/templates/public/testimonials/testimonial08/student-3.jpg +0 -0
  108. package/templates/public/testimonials/testimonial09/avatar-1.jpg +0 -0
  109. package/templates/public/testimonials/testimonial09/avatar-2.jpg +0 -0
  110. package/templates/public/testimonials/testimonial09/avatar-3.jpg +0 -0
  111. package/templates/public/testimonials/testimonial09/avatar-4.jpg +0 -0
  112. package/templates/public/testimonials/testimonial09/avatar-5.jpg +0 -0
  113. package/templates/public/testimonials/testimonial09/avatar-6.jpg +0 -0
  114. package/templates/public/testimonials/testimonial10/card-1.jpg +0 -0
  115. package/templates/public/testimonials/testimonial10/card-2.jpg +0 -0
  116. package/templates/public/testimonials/testimonial10/card-3.jpg +0 -0
  117. package/templates/public/testimonials/testimonial11/avatar-1.jpg +0 -0
  118. package/templates/public/testimonials/testimonial11/avatar-2.jpg +0 -0
  119. package/templates/public/testimonials/testimonial11/avatar-3.jpg +0 -0
  120. package/templates/public/testimonials/testimonial12/story-1.jpg +0 -0
  121. package/templates/public/testimonials/testimonial12/story-2.jpg +0 -0
  122. package/templates/public/testimonials/testimonial12/story-3.jpg +0 -0
  123. package/templates/public/testimonials/testimonial12/story-4.jpg +0 -0
  124. package/templates/public/testimonials/testimonial13/slide-1.jpg +0 -0
  125. package/templates/public/testimonials/testimonial13/slide-2.jpg +0 -0
  126. package/templates/public/testimonials/testimonial13/slide-3.jpg +0 -0
  127. package/templates/public/testimonials/testimonial13/slide-4.jpg +0 -0
  128. package/templates/public/testimonials/testimonial14/avatar-1.jpg +0 -0
  129. package/templates/public/testimonials/testimonial14/avatar-2.jpg +0 -0
  130. package/templates/public/testimonials/testimonial14/avatar-3.jpg +0 -0
  131. package/templates/public/testimonials/testimonial14/avatar-4.jpg +0 -0
  132. package/templates/public/testimonials/testimonial15/slide-1.jpg +0 -0
  133. package/templates/public/testimonials/testimonial15/slide-2.jpg +0 -0
  134. package/templates/public/testimonials/testimonial15/slide-3.jpg +0 -0
  135. package/templates/public/testimonials/testimonial16/avatar.jpg +0 -0
  136. package/templates/public/testimonials/testimonial16/featured.jpg +0 -0
  137. package/templates/public/testimonials/testimonial17/avatar-1.jpg +0 -0
  138. package/templates/public/testimonials/testimonial17/avatar-2.jpg +0 -0
  139. package/templates/public/testimonials/testimonial17/avatar-3.jpg +0 -0
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+
3
+ const path = require("path");
4
+ const categoryConfig = require("../category.config.json");
5
+
6
+ function loadCore() {
7
+ try {
8
+ return require("@notionhive/core");
9
+ } catch {
10
+ return require(path.join(__dirname, "../../core/lib"));
11
+ }
12
+ }
13
+
14
+ const { createCategoryCli } = loadCore();
15
+ const run = createCategoryCli(categoryConfig);
16
+ run(path.resolve(__dirname, ".."));
@@ -0,0 +1,7 @@
1
+ {
2
+ "packageName": "@notionhive/testimonials",
3
+ "binName": "testimonials",
4
+ "label": "testimonial section",
5
+ "labelPlural": "testimonial sections",
6
+ "exampleId": "testimonial-01"
7
+ }
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "@notionhive/testimonials",
3
+ "version": "0.1.0",
4
+ "description": "Add editable testimonial sections into your Next.js project.",
5
+ "license": "UNLICENSED",
6
+ "bin": {
7
+ "testimonials": "./bin/testimonials.js"
8
+ },
9
+ "files": [
10
+ "bin",
11
+ "registry",
12
+ "templates",
13
+ "category.config.json"
14
+ ],
15
+ "scripts": {
16
+ "prepublishOnly": "node ../../scripts/sync-templates.js"
17
+ },
18
+ "dependencies": {
19
+ "@notionhive/core": "0.1.0"
20
+ },
21
+ "engines": {
22
+ "node": ">=18"
23
+ }
24
+ }
@@ -0,0 +1,174 @@
1
+ {
2
+ "category": "testimonials",
3
+ "packageName": "@notionhive/testimonials",
4
+ "items": [
5
+ {
6
+ "id": "testimonial-01",
7
+ "exportName": "Testimonial01",
8
+ "folderName": "Testimonial01",
9
+ "shared": [
10
+ "atoms/SafeImage",
11
+ "hooks/useCarousel"
12
+ ],
13
+ "assets": "public/testimonials/testimonial01"
14
+ },
15
+ {
16
+ "id": "testimonial-02",
17
+ "exportName": "Testimonial02",
18
+ "folderName": "Testimonial02",
19
+ "shared": [
20
+ "atoms/SafeImage",
21
+ "hooks/useCarousel"
22
+ ],
23
+ "assets": "public/testimonials/testimonial02"
24
+ },
25
+ {
26
+ "id": "testimonial-03",
27
+ "exportName": "Testimonial03",
28
+ "folderName": "Testimonial03",
29
+ "shared": [
30
+ "atoms/SafeImage",
31
+ "hooks/useCarousel"
32
+ ],
33
+ "assets": "public/testimonials/testimonial03"
34
+ },
35
+ {
36
+ "id": "testimonial-04",
37
+ "exportName": "Testimonial04",
38
+ "folderName": "Testimonial04",
39
+ "shared": [
40
+ "atoms/SafeImage",
41
+ "hooks/useCarousel"
42
+ ],
43
+ "assets": "public/testimonials/testimonial04"
44
+ },
45
+ {
46
+ "id": "testimonial-05",
47
+ "exportName": "Testimonial05",
48
+ "folderName": "Testimonial05",
49
+ "shared": [
50
+ "atoms/SafeImage"
51
+ ],
52
+ "assets": "public/testimonials/testimonial05"
53
+ },
54
+ {
55
+ "id": "testimonial-06",
56
+ "exportName": "Testimonial06",
57
+ "folderName": "Testimonial06",
58
+ "shared": [
59
+ "atoms/SafeImage",
60
+ "hooks/useCarousel"
61
+ ],
62
+ "assets": "public/testimonials/testimonial06"
63
+ },
64
+ {
65
+ "id": "testimonial-07",
66
+ "exportName": "Testimonial07",
67
+ "folderName": "Testimonial07",
68
+ "shared": [
69
+ "atoms/SafeImage",
70
+ "hooks/useCarousel"
71
+ ],
72
+ "assets": "public/testimonials/testimonial07"
73
+ },
74
+ {
75
+ "id": "testimonial-08",
76
+ "exportName": "Testimonial08",
77
+ "folderName": "Testimonial08",
78
+ "shared": [
79
+ "atoms/SafeImage",
80
+ "hooks/useCarousel"
81
+ ],
82
+ "assets": "public/testimonials/testimonial08"
83
+ },
84
+ {
85
+ "id": "testimonial-09",
86
+ "exportName": "Testimonial09",
87
+ "folderName": "Testimonial09",
88
+ "shared": [
89
+ "atoms/SafeImage",
90
+ "hooks/useCarousel"
91
+ ],
92
+ "assets": "public/testimonials/testimonial09"
93
+ },
94
+ {
95
+ "id": "testimonial-10",
96
+ "exportName": "Testimonial10",
97
+ "folderName": "Testimonial10",
98
+ "shared": [
99
+ "atoms/SafeImage",
100
+ "hooks/useCarousel"
101
+ ],
102
+ "assets": "public/testimonials/testimonial10"
103
+ },
104
+ {
105
+ "id": "testimonial-11",
106
+ "exportName": "Testimonial11",
107
+ "folderName": "Testimonial11",
108
+ "shared": [
109
+ "atoms/SafeImage",
110
+ "hooks/useCarousel"
111
+ ],
112
+ "assets": "public/testimonials/testimonial11"
113
+ },
114
+ {
115
+ "id": "testimonial-12",
116
+ "exportName": "Testimonial12",
117
+ "folderName": "Testimonial12",
118
+ "shared": [
119
+ "atoms/SafeImage",
120
+ "hooks/useCarousel"
121
+ ],
122
+ "assets": "public/testimonials/testimonial12"
123
+ },
124
+ {
125
+ "id": "testimonial-13",
126
+ "exportName": "Testimonial13",
127
+ "folderName": "Testimonial13",
128
+ "shared": [
129
+ "atoms/SafeImage",
130
+ "hooks/useCarousel"
131
+ ],
132
+ "assets": "public/testimonials/testimonial13"
133
+ },
134
+ {
135
+ "id": "testimonial-14",
136
+ "exportName": "Testimonial14",
137
+ "folderName": "Testimonial14",
138
+ "shared": [
139
+ "atoms/SafeImage"
140
+ ],
141
+ "assets": "public/testimonials/testimonial14"
142
+ },
143
+ {
144
+ "id": "testimonial-15",
145
+ "exportName": "Testimonial15",
146
+ "folderName": "Testimonial15",
147
+ "shared": [
148
+ "atoms/SafeImage",
149
+ "hooks/useCarousel"
150
+ ],
151
+ "assets": "public/testimonials/testimonial15"
152
+ },
153
+ {
154
+ "id": "testimonial-16",
155
+ "exportName": "Testimonial16",
156
+ "folderName": "Testimonial16",
157
+ "shared": [
158
+ "atoms/SafeImage",
159
+ "hooks/useCarousel"
160
+ ],
161
+ "assets": "public/testimonials/testimonial16"
162
+ },
163
+ {
164
+ "id": "testimonial-17",
165
+ "exportName": "Testimonial17",
166
+ "folderName": "Testimonial17",
167
+ "shared": [
168
+ "atoms/SafeImage",
169
+ "hooks/useCarousel"
170
+ ],
171
+ "assets": "public/testimonials/testimonial17"
172
+ }
173
+ ]
174
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "id": "testimonial-01",
3
+ "exportName": "Testimonial01",
4
+ "folderName": "Testimonial01",
5
+ "shared": [
6
+ "atoms/SafeImage",
7
+ "hooks/useCarousel"
8
+ ],
9
+ "assets": "public/testimonials/testimonial01"
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "id": "testimonial-02",
3
+ "exportName": "Testimonial02",
4
+ "folderName": "Testimonial02",
5
+ "shared": [
6
+ "atoms/SafeImage",
7
+ "hooks/useCarousel"
8
+ ],
9
+ "assets": "public/testimonials/testimonial02"
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "id": "testimonial-03",
3
+ "exportName": "Testimonial03",
4
+ "folderName": "Testimonial03",
5
+ "shared": [
6
+ "atoms/SafeImage",
7
+ "hooks/useCarousel"
8
+ ],
9
+ "assets": "public/testimonials/testimonial03"
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "id": "testimonial-04",
3
+ "exportName": "Testimonial04",
4
+ "folderName": "Testimonial04",
5
+ "shared": [
6
+ "atoms/SafeImage",
7
+ "hooks/useCarousel"
8
+ ],
9
+ "assets": "public/testimonials/testimonial04"
10
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "id": "testimonial-05",
3
+ "exportName": "Testimonial05",
4
+ "folderName": "Testimonial05",
5
+ "shared": [
6
+ "atoms/SafeImage"
7
+ ],
8
+ "assets": "public/testimonials/testimonial05"
9
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "id": "testimonial-06",
3
+ "exportName": "Testimonial06",
4
+ "folderName": "Testimonial06",
5
+ "shared": [
6
+ "atoms/SafeImage",
7
+ "hooks/useCarousel"
8
+ ],
9
+ "assets": "public/testimonials/testimonial06"
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "id": "testimonial-07",
3
+ "exportName": "Testimonial07",
4
+ "folderName": "Testimonial07",
5
+ "shared": [
6
+ "atoms/SafeImage",
7
+ "hooks/useCarousel"
8
+ ],
9
+ "assets": "public/testimonials/testimonial07"
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "id": "testimonial-08",
3
+ "exportName": "Testimonial08",
4
+ "folderName": "Testimonial08",
5
+ "shared": [
6
+ "atoms/SafeImage",
7
+ "hooks/useCarousel"
8
+ ],
9
+ "assets": "public/testimonials/testimonial08"
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "id": "testimonial-09",
3
+ "exportName": "Testimonial09",
4
+ "folderName": "Testimonial09",
5
+ "shared": [
6
+ "atoms/SafeImage",
7
+ "hooks/useCarousel"
8
+ ],
9
+ "assets": "public/testimonials/testimonial09"
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "id": "testimonial-10",
3
+ "exportName": "Testimonial10",
4
+ "folderName": "Testimonial10",
5
+ "shared": [
6
+ "atoms/SafeImage",
7
+ "hooks/useCarousel"
8
+ ],
9
+ "assets": "public/testimonials/testimonial10"
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "id": "testimonial-11",
3
+ "exportName": "Testimonial11",
4
+ "folderName": "Testimonial11",
5
+ "shared": [
6
+ "atoms/SafeImage",
7
+ "hooks/useCarousel"
8
+ ],
9
+ "assets": "public/testimonials/testimonial11"
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "id": "testimonial-12",
3
+ "exportName": "Testimonial12",
4
+ "folderName": "Testimonial12",
5
+ "shared": [
6
+ "atoms/SafeImage",
7
+ "hooks/useCarousel"
8
+ ],
9
+ "assets": "public/testimonials/testimonial12"
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "id": "testimonial-13",
3
+ "exportName": "Testimonial13",
4
+ "folderName": "Testimonial13",
5
+ "shared": [
6
+ "atoms/SafeImage",
7
+ "hooks/useCarousel"
8
+ ],
9
+ "assets": "public/testimonials/testimonial13"
10
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "id": "testimonial-14",
3
+ "exportName": "Testimonial14",
4
+ "folderName": "Testimonial14",
5
+ "shared": [
6
+ "atoms/SafeImage"
7
+ ],
8
+ "assets": "public/testimonials/testimonial14"
9
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "id": "testimonial-15",
3
+ "exportName": "Testimonial15",
4
+ "folderName": "Testimonial15",
5
+ "shared": [
6
+ "atoms/SafeImage",
7
+ "hooks/useCarousel"
8
+ ],
9
+ "assets": "public/testimonials/testimonial15"
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "id": "testimonial-16",
3
+ "exportName": "Testimonial16",
4
+ "folderName": "Testimonial16",
5
+ "shared": [
6
+ "atoms/SafeImage",
7
+ "hooks/useCarousel"
8
+ ],
9
+ "assets": "public/testimonials/testimonial16"
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "id": "testimonial-17",
3
+ "exportName": "Testimonial17",
4
+ "folderName": "Testimonial17",
5
+ "shared": [
6
+ "atoms/SafeImage",
7
+ "hooks/useCarousel"
8
+ ],
9
+ "assets": "public/testimonials/testimonial17"
10
+ }
@@ -0,0 +1,101 @@
1
+ import Image from "next/image";
2
+
3
+ /**
4
+ * SafeImage — renders local /heroes/ assets reliably.
5
+ *
6
+ * Figma exports are often SVG content saved with .png extensions.
7
+ * Native img avoids next/image SVG restrictions and broken renders in Storybook.
8
+ *
9
+ * @param {object} props - Same as next/image (src, alt, fill, className, sizes, priority, width, height).
10
+ */
11
+ export function SafeImage({
12
+ src,
13
+ alt = "",
14
+ fill,
15
+ className = "",
16
+ sizes,
17
+ priority,
18
+ width,
19
+ height,
20
+ style,
21
+ ...rest
22
+ }) {
23
+ if (!src) return null;
24
+
25
+ const isLocalAsset =
26
+ src.startsWith("/heroes/") ||
27
+ src.startsWith("/menus/") ||
28
+ src.startsWith("/about/") ||
29
+ src.startsWith("/services/") ||
30
+ src.startsWith("/testimonials/") ||
31
+ src.startsWith("/cta/") ||
32
+ src.startsWith("/contact/") ||
33
+ src.startsWith("/footer/");
34
+ const isSvg = src.endsWith(".svg");
35
+
36
+ if (isLocalAsset || isSvg) {
37
+ if (fill) {
38
+ return (
39
+ // eslint-disable-next-line @next/next/no-img-element
40
+ <img
41
+ src={src}
42
+ alt={alt}
43
+ className={className}
44
+ style={{
45
+ ...style,
46
+ position: "absolute",
47
+ inset: 0,
48
+ width: "100%",
49
+ height: "100%",
50
+ objectFit: "cover",
51
+ }}
52
+ {...rest}
53
+ />
54
+ );
55
+ }
56
+
57
+ return (
58
+ // eslint-disable-next-line @next/next/no-img-element
59
+ <img
60
+ src={src}
61
+ alt={alt}
62
+ className={className}
63
+ width={width}
64
+ height={height}
65
+ style={style}
66
+ {...rest}
67
+ />
68
+ );
69
+ }
70
+
71
+ if (fill) {
72
+ return (
73
+ <Image
74
+ src={src}
75
+ alt={alt}
76
+ fill
77
+ className={className}
78
+ sizes={sizes}
79
+ priority={priority}
80
+ style={style}
81
+ {...rest}
82
+ />
83
+ );
84
+ }
85
+
86
+ return (
87
+ <Image
88
+ src={src}
89
+ alt={alt}
90
+ width={width}
91
+ height={height}
92
+ className={className}
93
+ sizes={sizes}
94
+ priority={priority}
95
+ style={style}
96
+ {...rest}
97
+ />
98
+ );
99
+ }
100
+
101
+ export default SafeImage;
@@ -0,0 +1 @@
1
+ export { SafeImage, default } from "./SafeImage";
@@ -0,0 +1,73 @@
1
+ "use client";
2
+
3
+ import { useCallback, useEffect, useState } from "react";
4
+
5
+ /**
6
+ * useCarousel — shared slide state for hero carousels and sliders.
7
+ *
8
+ * @param {object} options
9
+ * @param {number} [options.count=1] - Total slide count.
10
+ * @param {number} [options.initialIndex=0] - Starting slide.
11
+ * @param {boolean} [options.loop=false] - Wrap from last → first.
12
+ * @param {number} [options.autoPlayMs=0] - Auto-advance interval; 0 = off.
13
+ * @param {(index: number) => void} [options.onChange] - Called when slide changes.
14
+ * @returns {{ activeSlide: number, goTo: Function, next: Function, prev: Function, pause: Function, resume: Function, isPaused: boolean }}
15
+ */
16
+ export function useCarousel({
17
+ count = 1,
18
+ initialIndex = 0,
19
+ loop = false,
20
+ autoPlayMs = 0,
21
+ onChange,
22
+ } = {}) {
23
+ const maxIndex = Math.max(0, count - 1);
24
+ const [activeSlide, setActiveSlide] = useState(() =>
25
+ Math.min(Math.max(initialIndex, 0), maxIndex)
26
+ );
27
+ const [isPaused, setIsPaused] = useState(false);
28
+
29
+ const goTo = useCallback(
30
+ (index) => {
31
+ const next = loop
32
+ ? ((index % count) + count) % count
33
+ : Math.min(Math.max(index, 0), maxIndex);
34
+ setActiveSlide(next);
35
+ onChange?.(next);
36
+ },
37
+ [count, loop, maxIndex, onChange]
38
+ );
39
+
40
+ const next = useCallback(() => {
41
+ if (loop || activeSlide < maxIndex) goTo(activeSlide + 1);
42
+ }, [activeSlide, goTo, loop, maxIndex]);
43
+
44
+ const prev = useCallback(() => {
45
+ if (loop || activeSlide > 0) goTo(activeSlide - 1);
46
+ }, [activeSlide, goTo, loop]);
47
+
48
+ const pause = useCallback(() => setIsPaused(true), []);
49
+ const resume = useCallback(() => setIsPaused(false), []);
50
+
51
+ useEffect(() => {
52
+ if (!autoPlayMs || isPaused || count <= 1) return undefined;
53
+
54
+ const id = window.setInterval(next, autoPlayMs);
55
+ return () => window.clearInterval(id);
56
+ }, [autoPlayMs, count, isPaused, next]);
57
+
58
+ useEffect(() => {
59
+ setActiveSlide((current) => Math.min(Math.max(current, 0), maxIndex));
60
+ }, [maxIndex]);
61
+
62
+ return {
63
+ activeSlide,
64
+ goTo,
65
+ next,
66
+ prev,
67
+ pause,
68
+ resume,
69
+ isPaused,
70
+ };
71
+ }
72
+
73
+ export default useCarousel;