@levo-so/blocks 0.1.115 → 0.2.1

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/package.json CHANGED
@@ -1,23 +1,22 @@
1
1
  {
2
2
  "name": "@levo-so/blocks",
3
3
  "description": "Set of blocks for Levo studio",
4
- "version": "0.1.115",
4
+ "version": "0.2.1",
5
5
  "author": "Levo Engineering <devs@theinternetfolks.com>",
6
6
  "dependencies": {
7
7
  "dayjs": "1.11.13",
8
- "embla-carousel-auto-scroll": "8.6.0",
9
- "embla-carousel-react": "8.6.0",
10
8
  "lucide-react": "0.575.0",
11
- "use-debounce": "10.0.2"
9
+ "use-debounce": "10.0.2",
10
+ "@levo/utils": "0.0.0"
12
11
  },
13
12
  "devDependencies": {
14
13
  "@types/react": "19.2.14",
15
14
  "@types/react-dom": "19.2.3",
16
15
  "typescript": "5.9.3",
17
- "@levo-so/core": "0.1.113",
18
- "@levo-so/react": "0.1.113",
19
- "@levo-so/studio": "0.1.115",
20
- "@levo/ts-config": "0.0.0"
16
+ "@levo-so/core": "0.2.1",
17
+ "@levo-so/react": "0.2.1",
18
+ "@levo/ts-config": "0.0.0",
19
+ "@levo-so/studio": "0.2.1"
21
20
  },
22
21
  "exports": {
23
22
  ".": "./src/index.ts"
@@ -30,9 +29,9 @@
30
29
  "peerDependencies": {
31
30
  "react": ">=18",
32
31
  "react-dom": ">=18",
33
- "@levo-so/studio": "0.1.115",
34
- "@levo-so/core": "0.1.113",
35
- "@levo-so/react": "0.1.113"
32
+ "@levo-so/core": "0.2.1",
33
+ "@levo-so/studio": "0.2.1",
34
+ "@levo-so/react": "0.2.1"
36
35
  },
37
36
  "publishConfig": {
38
37
  "access": "public"
@@ -0,0 +1,635 @@
1
+ import type { IBlock } from "@levo-so/studio";
2
+
3
+ const DUMMY_IMAGE = {
4
+ kind: "icon",
5
+ data: {
6
+ id: "archive-minus",
7
+ label: "Archive Minus",
8
+ tags: ["archive", "custom", "directional", "minus"],
9
+ svgCode:
10
+ '<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n<path d="M14.5 11.4H9.5C9.09 11.4 8.75 11.06 8.75 10.65C8.75 10.24 9.09 9.90002 9.5 9.90002H14.5C14.91 9.90002 15.25 10.24 15.25 10.65C15.25 11.06 14.91 11.4 14.5 11.4Z" fill="var(--color-icon-primary)"/>\n<path d="M4.92957 22.75C4.50957 22.75 4.11957 22.65 3.76957 22.45C2.99957 22 2.55957 21.09 2.55957 19.96V5.86C2.55957 3.32 4.62957 1.25 7.16957 1.25H16.8196C19.3596 1.25 21.4296 3.32 21.4296 5.86V19.95C21.4296 21.08 20.9896 21.99 20.2196 22.44C19.4496 22.89 18.4396 22.84 17.4496 22.29L12.5696 19.58C12.2796 19.42 11.7096 19.42 11.4196 19.58L6.53957 22.29C5.99957 22.59 5.44957 22.75 4.92957 22.75ZM7.17957 2.75C5.46957 2.75 4.06957 4.15 4.06957 5.86V19.95C4.06957 20.54 4.23957 20.98 4.53957 21.15C4.83957 21.33 5.30957 21.27 5.81957 20.98L10.6996 18.27C11.4396 17.86 12.5596 17.86 13.2996 18.27L18.1796 20.98C18.6896 21.27 19.1596 21.33 19.4596 21.15C19.7596 20.97 19.9296 20.53 19.9296 19.95V5.86C19.9296 4.15 18.5296 2.75 16.8196 2.75H7.17957Z" fill="var(--color-icon-primary)"/>\n</svg>',
11
+ },
12
+ };
13
+
14
+ const CALENDAR_ICON = {
15
+ kind: "icon",
16
+ data: {
17
+ id: "calendar-1",
18
+ label: "Calendar 1",
19
+ tags: ["calendar", "custom", "time"],
20
+ svgCode:
21
+ '<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n<path d="M8 5.75C7.59 5.75 7.25 5.41 7.25 5V2C7.25 1.59 7.59 1.25 8 1.25C8.41 1.25 8.75 1.59 8.75 2V5C8.75 5.41 8.41 5.75 8 5.75Z" fill="var(--color-icon-primary)"/>\n<path d="M16 5.75C15.59 5.75 15.25 5.41 15.25 5V2C15.25 1.59 15.59 1.25 16 1.25C16.41 1.25 16.75 1.59 16.75 2V5C16.75 5.41 16.41 5.75 16 5.75Z" fill="var(--color-icon-primary)"/>\n<path d="M8.5 14.5001C8.37 14.5001 8.24 14.4701 8.12 14.4201C7.99 14.3701 7.89 14.3001 7.79 14.2101C7.61 14.0201 7.5 13.7701 7.5 13.5001C7.5 13.3701 7.53 13.2401 7.58 13.1201C7.63 13.0001 7.7 12.8901 7.79 12.7901C7.89 12.7001 7.99 12.6301 8.12 12.5801C8.48 12.4301 8.93 12.5101 9.21 12.7901C9.39 12.9801 9.5 13.2401 9.5 13.5001C9.5 13.5601 9.49 13.6301 9.48 13.7001C9.47 13.7601 9.45 13.8201 9.42 13.8801C9.4 13.9401 9.37 14.0001 9.33 14.0601C9.3 14.1101 9.25 14.1601 9.21 14.2101C9.02 14.3901 8.76 14.5001 8.5 14.5001Z" fill="var(--color-icon-primary)"/>\n<path d="M12 14.5C11.87 14.5 11.74 14.47 11.62 14.42C11.49 14.37 11.39 14.3 11.29 14.21C11.11 14.02 11 13.77 11 13.5C11 13.37 11.03 13.24 11.08 13.12C11.13 13 11.2 12.89 11.29 12.79C11.39 12.7 11.49 12.63 11.62 12.58C11.98 12.42 12.43 12.51 12.71 12.79C12.89 12.98 13 13.24 13 13.5C13 13.56 12.99 13.63 12.98 13.7C12.97 13.76 12.95 13.82 12.92 13.88C12.9 13.94 12.87 14 12.83 14.06C12.8 14.11 12.75 14.16 12.71 14.21C12.52 14.39 12.26 14.5 12 14.5Z" fill="var(--color-icon-primary)"/>\n<path d="M15.5 14.5C15.37 14.5 15.24 14.47 15.12 14.42C14.99 14.37 14.89 14.3 14.79 14.21C14.75 14.16 14.71 14.11 14.67 14.06C14.63 14 14.6 13.94 14.58 13.88C14.55 13.82 14.53 13.76 14.52 13.7C14.51 13.63 14.5 13.56 14.5 13.5C14.5 13.24 14.61 12.98 14.79 12.79C14.89 12.7 14.99 12.63 15.12 12.58C15.49 12.42 15.93 12.51 16.21 12.79C16.39 12.98 16.5 13.24 16.5 13.5C16.5 13.56 16.49 13.63 16.48 13.7C16.47 13.76 16.45 13.82 16.42 13.88C16.4 13.94 16.37 14 16.33 14.06C16.3 14.11 16.25 14.16 16.21 14.21C16.02 14.39 15.76 14.5 15.5 14.5Z" fill="var(--color-icon-primary)"/>\n<path d="M8.5 17.9999C8.37 17.9999 8.24 17.97 8.12 17.92C8 17.87 7.89 17.7999 7.79 17.7099C7.61 17.5199 7.5 17.2599 7.5 16.9999C7.5 16.8699 7.53 16.7399 7.58 16.6199C7.63 16.4899 7.7 16.38 7.79 16.29C8.16 15.92 8.84 15.92 9.21 16.29C9.39 16.48 9.5 16.7399 9.5 16.9999C9.5 17.2599 9.39 17.5199 9.21 17.7099C9.02 17.8899 8.76 17.9999 8.5 17.9999Z" fill="var(--color-icon-primary)"/>\n<path d="M12 17.9999C11.74 17.9999 11.48 17.8899 11.29 17.7099C11.11 17.5199 11 17.2599 11 16.9999C11 16.8699 11.03 16.7399 11.08 16.6199C11.13 16.4899 11.2 16.38 11.29 16.29C11.66 15.92 12.34 15.92 12.71 16.29C12.8 16.38 12.87 16.4899 12.92 16.6199C12.97 16.7399 13 16.8699 13 16.9999C13 17.2599 12.89 17.5199 12.71 17.7099C12.52 17.8899 12.26 17.9999 12 17.9999Z" fill="var(--color-icon-primary)"/>\n<path d="M15.5 18C15.24 18 14.98 17.89 14.79 17.71C14.7 17.62 14.63 17.51 14.58 17.38C14.53 17.26 14.5 17.13 14.5 17C14.5 16.87 14.53 16.74 14.58 16.62C14.63 16.49 14.7 16.38 14.79 16.29C15.02 16.06 15.37 15.95 15.69 16.02C15.76 16.03 15.82 16.05 15.88 16.08C15.94 16.1 16 16.13 16.06 16.17C16.11 16.2 16.16 16.25 16.21 16.29C16.39 16.48 16.5 16.74 16.5 17C16.5 17.26 16.39 17.52 16.21 17.71C16.02 17.89 15.76 18 15.5 18Z" fill="var(--color-icon-primary)"/>\n<path d="M20.5 9.83997H3.5C3.09 9.83997 2.75 9.49997 2.75 9.08997C2.75 8.67997 3.09 8.33997 3.5 8.33997H20.5C20.91 8.33997 21.25 8.67997 21.25 9.08997C21.25 9.49997 20.91 9.83997 20.5 9.83997Z" fill="var(--color-icon-primary)"/>\n<path d="M16 22.75H8C4.35 22.75 2.25 20.65 2.25 17V8.5C2.25 4.85 4.35 2.75 8 2.75H16C19.65 2.75 21.75 4.85 21.75 8.5V17C21.75 20.65 19.65 22.75 16 22.75ZM8 4.25C5.14 4.25 3.75 5.64 3.75 8.5V17C3.75 19.86 5.14 21.25 8 21.25H16C18.86 21.25 20.25 19.86 20.25 17V8.5C20.25 5.64 18.86 4.25 16 4.25H8Z" fill="var(--color-icon-primary)"/>\n</svg>',
22
+ },
23
+ };
24
+
25
+ const TIME_ICON = {
26
+ kind: "icon",
27
+ data: {
28
+ id: "clock",
29
+ label: "Clock",
30
+ tags: ["clock", "custom", "directional", "time"],
31
+ svgCode:
32
+ '<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n<path d="M12 22.75C6.07 22.75 1.25 17.93 1.25 12C1.25 6.07 6.07 1.25 12 1.25C17.93 1.25 22.75 6.07 22.75 12C22.75 17.93 17.93 22.75 12 22.75ZM12 2.75C6.9 2.75 2.75 6.9 2.75 12C2.75 17.1 6.9 21.25 12 21.25C17.1 21.25 21.25 17.1 21.25 12C21.25 6.9 17.1 2.75 12 2.75Z" fill="var(--color-icon-primary)"/>\n<path d="M15.7096 15.93C15.5796 15.93 15.4496 15.9 15.3296 15.82L12.2296 13.97C11.4596 13.51 10.8896 12.5 10.8896 11.61V7.51001C10.8896 7.10001 11.2296 6.76001 11.6396 6.76001C12.0496 6.76001 12.3896 7.10001 12.3896 7.51001V11.61C12.3896 11.97 12.6896 12.5 12.9996 12.68L16.0996 14.53C16.4596 14.74 16.5696 15.2 16.3596 15.56C16.2096 15.8 15.9596 15.93 15.7096 15.93Z" fill="var(--color-icon-primary)"/>\n</svg>',
33
+ },
34
+ };
35
+
36
+ const DEFAULT_CONTENT = {
37
+ layout: null,
38
+ container: null,
39
+ "main-wrapper": null,
40
+ "hero-card": null,
41
+ "hero-image": {
42
+ id: "event-hero-image",
43
+ location: "https://images.unsplash.com/photo-1540575467063-178a50c2df87?w=800&h=400&fit=crop",
44
+ kind: "image",
45
+ mimetype: "image/jpeg",
46
+ srcset: {
47
+ "320w": "https://images.unsplash.com/photo-1540575467063-178a50c2df87?w=320&h=200&fit=crop",
48
+ "640w": "https://images.unsplash.com/photo-1540575467063-178a50c2df87?w=640&h=320&fit=crop",
49
+ "800w": "https://images.unsplash.com/photo-1540575467063-178a50c2df87?w=800&h=400&fit=crop",
50
+ "1200w": "https://images.unsplash.com/photo-1540575467063-178a50c2df87?w=1200&h=600&fit=crop",
51
+ path: "https://images.unsplash.com/photo-1540575467063-178a50c2df87?w=320&h=200&fit=crop 320w, https://images.unsplash.com/photo-1540575467063-178a50c2df87?w=640&h=320&fit=crop 640w, https://images.unsplash.com/photo-1540575467063-178a50c2df87?w=800&h=400&fit=crop 800w, https://images.unsplash.com/photo-1540575467063-178a50c2df87?w=1200&h=600&fit=crop 1200w",
52
+ },
53
+ },
54
+ "hero-content": null,
55
+ title: "Annual Technology Summit 2024",
56
+ "event-info": null,
57
+ "start-date-wrapper": null,
58
+ "date-icon": CALENDAR_ICON,
59
+ "start-date": "March 15, 2024",
60
+ "end-date-wrapper": null,
61
+ "end-date-icon": CALENDAR_ICON,
62
+ "end-date": "March 15, 2024",
63
+ "time-wrapper": null,
64
+ "time-icon": TIME_ICON,
65
+ "time-range": "09:00 AM - 05:00 PM",
66
+ "kind-wrapper": null,
67
+ "kind-icon": DUMMY_IMAGE,
68
+ kind: "Conference",
69
+ "timing-wrapper": null,
70
+ "timing-icon": DUMMY_IMAGE,
71
+ timing: "Full Day",
72
+ "content-section": null,
73
+ "main-content": null,
74
+ "register-button": "Register Now",
75
+ "registration-ended": "The registration for this event has ended.",
76
+ event: null,
77
+ description:
78
+ "Join us for an exciting day of technology insights, networking opportunities, and industry expertise. Our annual summit brings together thought leaders, innovators, and professionals to explore the latest trends in digital transformation, artificial intelligence, and emerging technologies. Experience keynote presentations, interactive workshops, and valuable networking sessions designed to accelerate your professional growth.",
79
+ "contact-sidebar": null,
80
+ "contact-card": null,
81
+ "contact-title": "Event Contact",
82
+ "contact-details": null,
83
+ "name-field": null,
84
+ "name-label": "Name:",
85
+ "name-value": "Sarah Johnson",
86
+ "email-field": null,
87
+ "email-label": "Email:",
88
+ "email-value": "events@techsummit.com",
89
+ "phone-field": null,
90
+ "phone-label": "Phone:",
91
+ "phone-value": "+1 (555) 123-4567",
92
+ starts_at: "2024-03-15T09:00:00Z",
93
+ ends_at: "2024-03-15T17:00:00Z",
94
+ };
95
+
96
+ export type IEventDetailsContent = typeof DEFAULT_CONTENT & {
97
+ event?: {
98
+ ends_at?: string;
99
+ [key: string]: unknown;
100
+ } | null;
101
+ starts_at?: string;
102
+ ends_at?: string;
103
+ kind?: string;
104
+ timing?: string;
105
+ id?: string;
106
+ external_ticketing?: string;
107
+ };
108
+
109
+ export const EventDetails2: IBlock = {
110
+ category_id: "event",
111
+ title: "Event Details 2",
112
+ key: "event-details-2",
113
+ version: "v1",
114
+ prompt_description:
115
+ "Detailed event page featuring hero image, event information, registration button, event description, and contact details sidebar",
116
+ source: [{ required: true, module: "event", type: "page" }],
117
+ content_schema: [
118
+ {
119
+ key: "layout",
120
+ label: "Layout",
121
+ field_interface: "LayoutWidget",
122
+ hint: {
123
+ prompt_description:
124
+ "Defines the overall structure and layout of the Event Details block. No content generation required.",
125
+ },
126
+ },
127
+ {
128
+ key: "container",
129
+ label: "Container",
130
+ field_interface: "ContainerWidget",
131
+ hint: {
132
+ prompt_description:
133
+ "Contains the whole Event Details section, providing spacing and alignment. No content generation required.",
134
+ },
135
+ },
136
+ {
137
+ key: "hero-card",
138
+ label: "Hero Card",
139
+ field_interface: "BoxWidget",
140
+ hint: {
141
+ prompt_description:
142
+ "Card container for the hero section with image and basic event info. No content generation required.",
143
+ },
144
+ },
145
+ {
146
+ key: "hero-image",
147
+ label: "Hero Image",
148
+ field_interface: "ImageWidget",
149
+ hint: {
150
+ prompt_description: "Main event cover image showcasing the event theme or venue.",
151
+ },
152
+ options: {
153
+ module_field: {
154
+ module: "event",
155
+ key: "cover_image",
156
+ },
157
+ },
158
+ },
159
+ {
160
+ key: "hero-content",
161
+ label: "Hero Content",
162
+ field_interface: "BoxWidget",
163
+ hint: {
164
+ prompt_description:
165
+ "Container for hero text content including title and event info. No content generation required.",
166
+ },
167
+ },
168
+ {
169
+ key: "title",
170
+ label: "Event Title",
171
+ field_interface: "HeadingWidget",
172
+ hint: {
173
+ prompt_description: "Main event title that clearly describes the event name and purpose.",
174
+ min_characters: 20,
175
+ max_characters: 60,
176
+ },
177
+ options: {
178
+ module_field: {
179
+ module: "event",
180
+ key: "title",
181
+ },
182
+ },
183
+ },
184
+ {
185
+ key: "event-info",
186
+ label: "Event Info Container",
187
+ field_interface: "BoxWidget",
188
+ hint: {
189
+ prompt_description:
190
+ "Container for event metadata like date, time, type. No content generation required.",
191
+ },
192
+ },
193
+ {
194
+ key: "start-date-wrapper",
195
+ label: "Start Date Wrapper",
196
+ field_interface: "BoxWidget",
197
+ hint: {
198
+ prompt_description: "Container for start date information. No content generation required.",
199
+ },
200
+ },
201
+ {
202
+ key: "date-icon",
203
+ label: "Date Icon",
204
+ field_interface: "IconWidget",
205
+ hint: {
206
+ prompt_description: "Icon representing date/calendar information.",
207
+ },
208
+ },
209
+ {
210
+ key: "starts_at",
211
+ label: "Start Date",
212
+ field_interface: "TypographyWidget",
213
+ hint: {
214
+ prompt_description: "Event start date in readable format.",
215
+ },
216
+ options: {
217
+ module_field: {
218
+ module: "event",
219
+ key: "starts_at",
220
+ },
221
+ },
222
+ },
223
+ {
224
+ key: "id",
225
+ label: "Event ID",
226
+ field_interface: "TypographyWidget",
227
+ },
228
+ {
229
+ key: "external_ticketing",
230
+ label: "External Ticketing URL",
231
+ field_interface: "TypographyWidget",
232
+ },
233
+ {
234
+ key: "end-date-wrapper",
235
+ label: "End Date Wrapper",
236
+ field_interface: "BoxWidget",
237
+ hint: {
238
+ prompt_description: "Container for end date information. No content generation required.",
239
+ },
240
+ },
241
+ {
242
+ key: "end-date-icon",
243
+ label: "End Date Icon",
244
+ field_interface: "IconWidget",
245
+ hint: {
246
+ prompt_description: "Icon representing end date/calendar information.",
247
+ },
248
+ },
249
+ {
250
+ key: "ends_at",
251
+ label: "End Date",
252
+ field_interface: "TypographyWidget",
253
+ hint: {
254
+ prompt_description: "Event end date in readable format.",
255
+ },
256
+ options: {
257
+ module_field: {
258
+ module: "event",
259
+ key: "ends_at",
260
+ },
261
+ },
262
+ },
263
+ {
264
+ key: "time-wrapper",
265
+ label: "Time Wrapper",
266
+ field_interface: "BoxWidget",
267
+ hint: {
268
+ prompt_description: "Container for time range information. No content generation required.",
269
+ },
270
+ },
271
+ {
272
+ key: "time-icon",
273
+ label: "Time Icon",
274
+ field_interface: "IconWidget",
275
+ hint: {
276
+ prompt_description: "Icon representing time/clock information.",
277
+ },
278
+ },
279
+ {
280
+ key: "time-range",
281
+ label: "Time Range",
282
+ field_interface: "TypographyWidget",
283
+ hint: {
284
+ prompt_description: "Event time range from start to end time.",
285
+ },
286
+ options: {
287
+ module_field: {
288
+ module: "event",
289
+ key: "starts_at",
290
+ },
291
+ },
292
+ },
293
+ {
294
+ key: "platform-wrapper",
295
+ label: "Platform Wrapper",
296
+ field_interface: "BoxWidget",
297
+ hint: {
298
+ prompt_description: "Container for platform information. No content generation required.",
299
+ },
300
+ },
301
+ {
302
+ key: "platform-icon",
303
+ label: "Platform Icon",
304
+ field_interface: "IconWidget",
305
+ hint: {
306
+ prompt_description: "Icon representing platform/web information.",
307
+ },
308
+ },
309
+ {
310
+ key: "platform",
311
+ label: "Platform",
312
+ field_interface: "TypographyWidget",
313
+ hint: {
314
+ prompt_description: "Event platform information.",
315
+ },
316
+ },
317
+ {
318
+ key: "content-section",
319
+ label: "Content Section",
320
+ field_interface: "BoxWidget",
321
+ hint: {
322
+ prompt_description:
323
+ "Main content area containing description and contact sidebar. No content generation required.",
324
+ },
325
+ },
326
+ {
327
+ key: "main-content",
328
+ label: "Main Content",
329
+ field_interface: "BoxWidget",
330
+ hint: {
331
+ prompt_description:
332
+ "Primary content area with registration button and description. No content generation required.",
333
+ },
334
+ },
335
+ {
336
+ key: "register-button",
337
+ label: "Registration Button",
338
+ field_interface: "ButtonWidget",
339
+ hint: {
340
+ prompt_description:
341
+ "Call-to-action button for event registration. Should be compelling and action-oriented.",
342
+ min_characters: 8,
343
+ max_characters: 20,
344
+ },
345
+ },
346
+ {
347
+ key: "registration-ended",
348
+ label: "Registration Ended Message",
349
+ field_interface: "TypographyWidget",
350
+ hint: {
351
+ prompt_description: "Message shown when event registration has ended.",
352
+ min_characters: 20,
353
+ max_characters: 60,
354
+ },
355
+ },
356
+ {
357
+ key: "event",
358
+ label: "Event Object",
359
+ field_interface: "BoxWidget",
360
+ hint: {
361
+ prompt_description:
362
+ "Event data object for registration logic. No content generation required.",
363
+ },
364
+ },
365
+ {
366
+ key: "description",
367
+ label: "Event Description",
368
+ field_interface: "TypographyWidget",
369
+ hint: {
370
+ prompt_description:
371
+ "Detailed event description explaining what attendees can expect, key highlights, and benefits of attending.",
372
+ min_characters: 150,
373
+ max_characters: 400,
374
+ },
375
+ options: {
376
+ module_field: {
377
+ module: "event",
378
+ key: "description",
379
+ },
380
+ },
381
+ },
382
+ {
383
+ key: "contact-card",
384
+ label: "Contact Card",
385
+ field_interface: "BoxWidget",
386
+ hint: {
387
+ prompt_description:
388
+ "Card containing contact details for the event. No content generation required.",
389
+ },
390
+ },
391
+ {
392
+ key: "contact-title",
393
+ label: "Contact Title",
394
+ field_interface: "HeadingWidget",
395
+ hint: {
396
+ prompt_description:
397
+ "Title for the contact section, typically 'Contact Us' or 'Event Contact'.",
398
+ min_characters: 8,
399
+ max_characters: 20,
400
+ },
401
+ },
402
+ {
403
+ key: "contact-details",
404
+ label: "Contact Details Container",
405
+ field_interface: "BoxWidget",
406
+ hint: {
407
+ prompt_description:
408
+ "Container for all contact detail fields. No content generation required.",
409
+ },
410
+ },
411
+ {
412
+ key: "email-field",
413
+ label: "Email Field",
414
+ field_interface: "BoxWidget",
415
+ hint: {
416
+ prompt_description: "Container for email contact field. No content generation required.",
417
+ },
418
+ },
419
+ {
420
+ key: "email-label",
421
+ label: "Email Label",
422
+ field_interface: "TypographyWidget",
423
+ hint: {
424
+ prompt_description: "Label for email contact, typically 'Email:'.",
425
+ },
426
+ },
427
+ {
428
+ key: "email-value",
429
+ label: "Contact Email",
430
+ field_interface: "TypographyWidget",
431
+ hint: {
432
+ prompt_description: "Professional email address for event inquiries and contact.",
433
+ min_characters: 15,
434
+ max_characters: 40,
435
+ },
436
+ options: {
437
+ module_field: {
438
+ module: "event",
439
+ key: "contact_email",
440
+ },
441
+ },
442
+ },
443
+ ],
444
+ layouts: [
445
+ {
446
+ key: "default",
447
+ title: "Default",
448
+ styles: {
449
+ layout: {
450
+ "padding-top": "3xl",
451
+ "padding-bottom": "3xl",
452
+ "padding-left": "base",
453
+ "padding-right": "base",
454
+ },
455
+ container: {
456
+ "max-width": "1280px",
457
+ "margin-left": "auto",
458
+ "margin-right": "auto",
459
+ display: "flex",
460
+ "flex-direction": "column",
461
+ "row-gap": "xl",
462
+ },
463
+ "hero-card": {
464
+ display: "flex",
465
+ "flex-direction": "column",
466
+ "border-radius": "base",
467
+ "box-shadow": "default",
468
+ overflow: "hidden",
469
+ },
470
+ "hero-image": {
471
+ width: "100%",
472
+ height: "400px",
473
+ "object-fit": "cover",
474
+ "border-radius": "base",
475
+ mobile: {
476
+ height: "250px",
477
+ },
478
+ },
479
+ "hero-content": {
480
+ "padding-top": "lg",
481
+ "padding-bottom": "lg",
482
+ "padding-left": "lg",
483
+ "padding-right": "lg",
484
+ },
485
+ title: {
486
+ color: "text-1",
487
+ "margin-bottom": "base",
488
+ },
489
+ "event-info": {
490
+ display: "flex",
491
+ "flex-wrap": "wrap",
492
+ "column-gap": "base",
493
+ "row-gap": "sm",
494
+ },
495
+ "start-date-wrapper": {
496
+ display: "flex",
497
+ "align-items": "center",
498
+ "column-gap": "xs",
499
+ },
500
+ "date-icon": {
501
+ width: "16px",
502
+ height: "16px",
503
+ },
504
+ "start-date": {
505
+ color: "text-2",
506
+ "text-transform": "capitalize",
507
+ },
508
+ starts_at: {
509
+ color: "text-2",
510
+ "text-transform": "capitalize",
511
+ },
512
+ "end-date-wrapper": {
513
+ display: "flex",
514
+ "align-items": "center",
515
+ "column-gap": "xs",
516
+ },
517
+ "end-date-icon": {
518
+ width: "16px",
519
+ height: "16px",
520
+ },
521
+ "end-date": {
522
+ color: "text-2",
523
+ "text-transform": "capitalize",
524
+ },
525
+ ends_at: {
526
+ color: "text-2",
527
+ "text-transform": "capitalize",
528
+ },
529
+ "time-wrapper": {
530
+ display: "flex",
531
+ "align-items": "center",
532
+ "column-gap": "xs",
533
+ },
534
+ "time-icon": {
535
+ width: "16px",
536
+ height: "16px",
537
+ },
538
+ "time-range": {
539
+ color: "text-2",
540
+ },
541
+ "content-section": {
542
+ display: "flex",
543
+ "column-gap": "2xl",
544
+ mobile: {
545
+ "flex-direction": "column",
546
+ "row-gap": "xl",
547
+ },
548
+ },
549
+ "main-content": {
550
+ "flex-basis": "66.67%",
551
+ display: "flex",
552
+ "flex-direction": "column",
553
+ "row-gap": "xl",
554
+ "border-radius": "base",
555
+ "box-shadow": "default",
556
+ "padding-top": "lg",
557
+ "padding-bottom": "lg",
558
+ "padding-left": "lg",
559
+ "padding-right": "lg",
560
+ mobile: {
561
+ "flex-basis": "100%",
562
+ },
563
+ },
564
+ "register-button": {
565
+ "background-color": "background-1",
566
+ color: "text-1",
567
+ "padding-top": "base",
568
+ "padding-bottom": "base",
569
+ "padding-left": "xl",
570
+ "padding-right": "xl",
571
+ "align-self": "flex-start",
572
+ },
573
+ "registration-ended": {
574
+ color: "text-2",
575
+ "padding-top": "base",
576
+ "padding-bottom": "base",
577
+ },
578
+ description: {
579
+ color: "text-2",
580
+ },
581
+ "contact-card": {
582
+ "flex-basis": "33.33%",
583
+ mobile: {
584
+ "flex-basis": "100%",
585
+ },
586
+ "border-radius": "base",
587
+ "box-shadow": "default",
588
+ "padding-top": "lg",
589
+ "padding-bottom": "lg",
590
+ "padding-left": "lg",
591
+ "padding-right": "lg",
592
+ },
593
+ "contact-title": {
594
+ color: "text-1",
595
+ "margin-bottom": "base",
596
+ },
597
+ "contact-details": {
598
+ display: "flex",
599
+ "flex-direction": "column",
600
+ "row-gap": "sm",
601
+ },
602
+ "email-field": {
603
+ display: "flex",
604
+ "flex-direction": "column",
605
+ "row-gap": "xs",
606
+ },
607
+ "email-label": {
608
+ color: "text-2",
609
+ },
610
+ "email-value": {
611
+ color: "text-1",
612
+ },
613
+ },
614
+ content: DEFAULT_CONTENT,
615
+ config: {
616
+ title: {
617
+ selectedVariants: {
618
+ Heading_Level: "H2",
619
+ },
620
+ heading: {
621
+ level: 2,
622
+ },
623
+ },
624
+ "contact-title": {
625
+ selectedVariants: {
626
+ Heading_Level: "H4",
627
+ },
628
+ heading: {
629
+ level: 2,
630
+ },
631
+ },
632
+ },
633
+ },
634
+ ],
635
+ };
@@ -0,0 +1,95 @@
1
+ import type { ILevoBlockBaseProps } from "@levo-so/studio";
2
+ import {
3
+ BlogContent,
4
+ Box,
5
+ Container,
6
+ Heading,
7
+ Icon,
8
+ Image,
9
+ RegisterModal,
10
+ Section,
11
+ Typography,
12
+ usePageContext,
13
+ } from "@levo-so/studio";
14
+ import dayjs from "dayjs";
15
+
16
+ import { ClientOnly } from "./ClientOnly";
17
+ import type { IEventDetailsContent } from "./event-details.schema";
18
+
19
+ const EventDetails2: React.FC<ILevoBlockBaseProps<IEventDetailsContent>> = () => {
20
+ const data = usePageContext("event");
21
+
22
+ return (
23
+ <Section elementKey="layout">
24
+ <Container elementKey="container">
25
+ <Box elementKey="hero-card">
26
+ <Image
27
+ elementKey="hero-image"
28
+ alt="Event cover image"
29
+ width={800}
30
+ height={400}
31
+ image={data?.cover_image}
32
+ />
33
+ <Box elementKey="hero-content">
34
+ <Heading elementKey="title">{data.title}</Heading>
35
+ <Box elementKey="event-info">
36
+ <Box elementKey="start-date-wrapper">
37
+ <Icon elementKey="date-icon" />
38
+ <ClientOnly>
39
+ <Typography elementKey="starts_at">
40
+ {dayjs(data?.starts_at).format("MMM D, YYYY")}
41
+ </Typography>
42
+ </ClientOnly>
43
+ </Box>
44
+ <Box elementKey="end-date-wrapper">
45
+ <Icon elementKey="end-date-icon" />
46
+ <ClientOnly>
47
+ <Typography elementKey="ends_at">
48
+ {dayjs(data?.ends_at).format("MMM D, YYYY")}
49
+ </Typography>
50
+ </ClientOnly>
51
+ </Box>
52
+ <Box elementKey="time-wrapper">
53
+ <Icon elementKey="time-icon" />
54
+ <ClientOnly>
55
+ <Typography elementKey="time-range">
56
+ {`${dayjs(data?.starts_at).format("hh:mm A")} - ${dayjs(data?.ends_at).format("hh:mm A")}`}
57
+ </Typography>
58
+ </ClientOnly>
59
+ </Box>
60
+ <Box elementKey="platform-wrapper">
61
+ <Icon elementKey="platform-icon" />
62
+ <Typography elementKey="platform">{data?.platform}</Typography>
63
+ </Box>
64
+ </Box>
65
+ </Box>
66
+ </Box>
67
+
68
+ <Box elementKey="content-section">
69
+ <Box elementKey="main-content">
70
+ {data?._id ? (
71
+ <RegisterModal
72
+ eventID={data?._id as string}
73
+ title={data?.title}
74
+ external={data?.external_ticketing}
75
+ />
76
+ ) : null}
77
+ <BlogContent elementKey="description" content={data?.description || ""} />
78
+ </Box>
79
+
80
+ <Box elementKey="contact-card">
81
+ <Heading elementKey="contact-title" />
82
+ <Box elementKey="contact-details">
83
+ <Box elementKey="email-field">
84
+ <Typography elementKey="email-label" />
85
+ <Typography elementKey="email-value">{data.contact_email}</Typography>
86
+ </Box>
87
+ </Box>
88
+ </Box>
89
+ </Box>
90
+ </Container>
91
+ </Section>
92
+ );
93
+ };
94
+
95
+ export default EventDetails2;
@@ -55,6 +55,7 @@ const EventListing2 = lazy(() => import("./event/event-listing-2"));
55
55
  const EventListing3 = lazy(() => import("./event/event-listing-3"));
56
56
  const EventListing4 = lazy(() => import("./event/event-listing-4"));
57
57
  const EventDetails = lazy(() => import("./event/event-details"));
58
+ const EventDetails2 = lazy(() => import("./event/event-details-2"));
58
59
  const Faq1 = lazy(() => import("./faq/faq-1"));
59
60
  const Faq2 = lazy(() => import("./faq/faq-2"));
60
61
  const Faq3 = lazy(() => import("./faq/faq-3"));
@@ -189,6 +190,7 @@ export const blocks: Record<string, React.LazyExoticComponent<React.ComponentTyp
189
190
  "event-listing-3:v1": EventListing3,
190
191
  "event-listing-4:v1": EventListing4,
191
192
  "event-details:v1": EventDetails,
193
+ "event-details-2:v1": EventDetails2,
192
194
  "faq-1:v1": Faq1,
193
195
  "faq-2:v1": Faq2,
194
196
  "faq-3:v1": Faq3,
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { cn } from "@levo-so/react";
3
+ import { cn } from "@levo/utils/cn";
4
4
  import type { ILevoBlockBaseProps } from "@levo-so/studio";
5
5
  import {
6
6
  Box,
@@ -1,4 +1,4 @@
1
- import { cn } from "@levo-so/react";
1
+ import { cn } from "@levo/utils/cn";
2
2
  import type { ILevoBlockBaseProps } from "@levo-so/studio";
3
3
  import {
4
4
  Box,
@@ -1,4 +1,4 @@
1
- import { cn } from "@levo-so/react";
1
+ import { cn } from "@levo/utils/cn";
2
2
  import type { ILevoBlockBaseProps } from "@levo-so/studio";
3
3
  import {
4
4
  Box,
@@ -1,4 +1,8 @@
1
- import { cn, errorToast, Spinner, successToast, useLevo } from "@levo-so/react";
1
+ import { useLevo, errorToast, successToast } from "@levo-so/react";
2
+
3
+ import { Spinner } from "../../components/Spinner";
4
+ import { cn } from "@levo/utils/cn";
5
+
2
6
  import {
3
7
  Box,
4
8
  Container,
@@ -1,4 +1,7 @@
1
- import { errorHandler, Spinner, successToast, useLevo } from "@levo-so/react";
1
+ import { errorHandler, useLevo, successToast } from "@levo-so/react";
2
+
3
+ import { Spinner } from "../../components/Spinner";
4
+
2
5
  import {
3
6
  Box,
4
7
  Button,
@@ -0,0 +1,9 @@
1
+ import { cn } from "@levo/utils/cn";
2
+ import { Loader2 } from "lucide-react";
3
+
4
+ /** Indeterminate loading spinner. */
5
+ export const Spinner = ({ className }: { className?: string }) => (
6
+ <Loader2 className={cn("h-8 w-8 animate-spin font-light", className)} />
7
+ );
8
+
9
+ export default Spinner;
@@ -57,6 +57,7 @@ import { Ecommerce5 } from "../blocks/ecommerce/ecommerce-5.schema";
57
57
  import { Embed1 } from "../blocks/embed/embed-1.schema";
58
58
  import { Embed2 } from "../blocks/embed/embed-2.schema";
59
59
  import { EventDetails } from "../blocks/event/event-details.schema";
60
+ import { EventDetails2 } from "../blocks/event/event-details-2.schema";
60
61
  import { EventListing } from "../blocks/event/event-listing.schema";
61
62
  import { EventListing2 } from "../blocks/event/event-listing-2.schema";
62
63
  import { EventListing3 } from "../blocks/event/event-listing-3.schema";
@@ -191,6 +192,7 @@ export const BlockList: IBlock[] = [
191
192
  Embed1,
192
193
  Embed2,
193
194
  EventDetails,
195
+ EventDetails2,
194
196
  EventListing,
195
197
  EventListing2,
196
198
  EventListing3,
@@ -1,16 +0,0 @@
1
- export const LEVO_DEFAULT_BLUE_IMAGE = {
2
- id: "7141014160938075687",
3
- location: "https://space.levo.so/WLZ1TXTD/defaultblue-tryFJ012mgyH.png",
4
- kind: "image",
5
- mimetype: "image/png",
6
- srcset: {
7
- "1080w": "https://space.levo.so/WLZ1TXTD/defaultblue-tryFJ012mgyH-1080w.webp",
8
- "1200w": "https://space.levo.so/WLZ1TXTD/defaultblue-tryFJ012mgyH-1200w.webp",
9
- "1920w": "https://space.levo.so/WLZ1TXTD/defaultblue-tryFJ012mgyH-1920w.webp",
10
- "320w": "https://space.levo.so/WLZ1TXTD/defaultblue-tryFJ012mgyH-320w.webp",
11
- "640w": "https://space.levo.so/WLZ1TXTD/defaultblue-tryFJ012mgyH-640w.webp",
12
- "750w": "https://space.levo.so/WLZ1TXTD/defaultblue-tryFJ012mgyH-750w.webp",
13
- "828w": "https://space.levo.so/WLZ1TXTD/defaultblue-tryFJ012mgyH-828w.webp",
14
- path: "https://space.levo.so/WLZ1TXTD/defaultblue-tryFJ012mgyH-640w.webp 640w, https://space.levo.so/WLZ1TXTD/defaultblue-tryFJ012mgyH-1080w.webp 1080w, https://space.levo.so/WLZ1TXTD/defaultblue-tryFJ012mgyH-1200w.webp 1200w, https://space.levo.so/WLZ1TXTD/defaultblue-tryFJ012mgyH-1920w.webp 1920w, https://space.levo.so/WLZ1TXTD/defaultblue-tryFJ012mgyH-320w.webp 320w, https://space.levo.so/WLZ1TXTD/defaultblue-tryFJ012mgyH-750w.webp 750w, https://space.levo.so/WLZ1TXTD/defaultblue-tryFJ012mgyH-828w.webp 828w",
15
- },
16
- };